Skip to main content

Task Component

Not to be confused with db.tasks.*
  • <Task> component = Declarative UI element for displaying task progress in workflows (this page)
  • db.tasks.* = Internal API for tracking async component lifecycle (start/complete/fail)
Components like <Claude>, <Step>, and <Worktree> use db.tasks.start() and db.tasks.complete() internally to signal when they’re running. The <Task> component is purely presentational—it renders a checkbox-style task item.
The <Task> component represents a trackable task within a workflow. Tasks can be marked as done/not done to track progress through complex workflows.

Usage

import { Task, Phase, Step } from "smithers-orchestrator";

<Phase name="implementation">
  <Step name="tasks">
    <Task done={false}>Research existing patterns</Task>
    <Task done={true}>Design component API</Task>
    <Task done={false}>Implement component</Task>
    <Task done={false}>Write tests</Task>
  </Step>
</Phase>

Props

done
boolean
default:"false"
Whether the task is complete.
children
ReactNode
Description of the task.

Examples

Basic Task List

<SmithersProvider db={db} executionId={executionId}>
  <Phase name="setup">
    <Step name="tasks">
      <Task done={true}>Initialize project</Task>
      <Task done={true}>Configure TypeScript</Task>
      <Task done={false}>Set up testing framework</Task>
    </Step>
  </Phase>
</SmithersProvider>

Dynamic Task Tracking

function TaskTracker() {
  const { db } = useSmithers();
  
  const tasks = useQueryValue<Array<{id: number, name: string, done: boolean}>>(
    db.db,
    "SELECT value FROM state WHERE key = 'tasks'"
  ) ?? [
    { id: 1, name: "Research", done: false },
    { id: 2, name: "Design", done: false },
    { id: 3, name: "Implement", done: false },
    { id: 4, name: "Test", done: false },
  ];

  const markDone = (id: number) => {
    const updated = tasks.map(t =>
      t.id === id ? { ...t, done: true } : t
    );
    db.state.set('tasks', updated);
  };

  return (
    <Phase name="feature-development">
      <Step name="tasks">
        {tasks.map(task => (
          <Task key={task.id} done={task.done}>
            {task.name}
          </Task>
        ))}

        <Claude
          onFinished={() => markDone(getCurrentTaskId())}
        >
          Complete the next incomplete task.
        </Claude>
      </Step>
    </Phase>
  );
}

With Database Persistence

function PersistentTasks() {
  const { db } = useSmithers();
  
  const tasks = useQueryValue<Array<{name: string, done: boolean}>>(
    db.db,
    "SELECT value FROM state WHERE key = 'tasks'"
  ) ?? [];

  const completeTask = (index: number) => {
    const newTasks = [...tasks];
    newTasks[index].done = true;
    db.state.set("tasks", newTasks, "task-tracker");
  };

  return (
    <Phase name="tracked-work">
      <Step name="tasks">
        {tasks.map((task, i) => (
          <Task key={i} done={task.done}>
            {task.name}
          </Task>
        ))}
      </Step>
    </Phase>
  );
}

Task-Driven Workflow

function TaskDrivenWorkflow() {
  const { db } = useSmithers();
  
  const currentTaskIndex = useQueryValue<number>(
    db.db,
    "SELECT value FROM state WHERE key = 'currentTaskIndex'"
  ) ?? 0;

  const tasks = [
    "Analyze the current implementation",
    "Identify areas for improvement",
    "Refactor the component",
    "Update tests",
    "Document changes",
  ];

  return (
    <SmithersProvider db={db} executionId={executionId} maxIterations={tasks.length}>
      <Phase name="tasks">
        <Step name="tasks">
          {tasks.map((task, i) => (
            <Task key={i} done={i < currentTaskIndex}>
              {task}
            </Task>
          ))}
        </Step>
      </Phase>

      <If condition={currentTaskIndex < tasks.length}>
        <Claude
          onFinished={() => db.state.set('currentTaskIndex', currentTaskIndex + 1)}
        >
          Complete this task: {tasks[currentTaskIndex]}
        </Claude>
      </If>
    </SmithersProvider>
  );
}

Rendering

The Task component renders as a <task> element with a done attribute, which can be styled or processed by your workflow visualization:
<task done="true">Research existing patterns</task>
<task done="false">Implement component</task>

Best Practices

Each task should represent a single, well-defined action:
// Good - atomic tasks
<Task done={false}>Create user model</Task>
<Task done={false}>Add validation rules</Task>
<Task done={false}>Write migration</Task>

// Less effective - compound task
<Task done={false}>Create user model with validation and migration</Task>
Group related tasks within phases:
<Phase name="backend">
  <Step name="tasks">
    <Task done={true}>Create API endpoint</Task>
    <Task done={false}>Add authentication</Task>
  </Step>
</Phase>

<Phase name="frontend">
  <Step name="tasks">
    <Task done={false}>Create form component</Task>
    <Task done={false}>Add validation</Task>
  </Step>
</Phase>