Todo Lists

Tags

official-docs claude-code-cli

Content

Documentation Index

Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt Use this file to discover all available pages before exploring further.

Todo Lists

Track and display todos using the Claude Agent SDK for organized task management

Todo tracking provides a structured way to manage tasks and display progress to users. The Claude Agent SDK includes built-in todo functionality that helps organize complex workflows and keep users informed about task progression.

Todo Lifecycle

Todos follow a predictable lifecycle:

  1. Created as pending when tasks are identified
  2. Activated to in_progress when work begins
  3. Completed when the task finishes successfully
  4. Removed when all tasks in a group are completed

When Todos Are Used

The SDK automatically creates todos for:

Examples

Monitoring Todo Changes

```typescript TypeScript theme={null} import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({ prompt: "Optimize my React app performance and track progress with todos", options: { maxTurns: 15 } })) { // Todo updates are reflected in the message stream if (message.type === "assistant") { for (const block of message.message.content) { if (block.type === "tool_use" && block.name === "TodoWrite") { const todos = block.input.todos;

      console.log("Todo Status Update:");
      todos.forEach((todo, index) => {
        const status =
          todo.status === "completed" ? "✅" : todo.status === "in_progress" ? "🔧" : "❌";
        console.log(`${index + 1}. ${status} ${todo.content}`);
      });
    }
  }
}

} ```

```python Python theme={null} from claude_agent_sdk import query, AssistantMessage, ToolUseBlock

async for message in query( prompt="Optimize my React app performance and track progress with todos", options={"max_turns": 15}, ): # Todo updates are reflected in the message stream if isinstance(message, AssistantMessage): for block in message.content: if isinstance(block, ToolUseBlock) and block.name == "TodoWrite": todos = block.input["todos"]

              print("Todo Status Update:")
              for i, todo in enumerate(todos):
                  status = (
                      "✅"
                      if todo["status"] == "completed"
                      else "🔧"
                      if todo["status"] == "in_progress"
                      else "❌"
                  )
                  print(f"{i + 1}. {status} {todo['content']}")

```

Real-time Progress Display

```typescript TypeScript theme={null} import { query } from "@anthropic-ai/claude-agent-sdk";

class TodoTracker { private todos: any[] = [];

displayProgress() {
  if (this.todos.length === 0) return;

  const completed = this.todos.filter((t) => t.status === "completed").length;
  const inProgress = this.todos.filter((t) => t.status === "in_progress").length;
  const total = this.todos.length;

  console.log(`\nProgress: ${completed}/${total} completed`);
  console.log(`Currently working on: ${inProgress} task(s)\n`);

  this.todos.forEach((todo, index) => {
    const icon =
      todo.status === "completed" ? "✅" : todo.status === "in_progress" ? "🔧" : "❌";
    const text = todo.status === "in_progress" ? todo.activeForm : todo.content;
    console.log(`${index + 1}. ${icon} ${text}`);
  });
}

async trackQuery(prompt: string) {
  for await (const message of query({
    prompt,
    options: { maxTurns: 20 }
  })) {
    if (message.type === "assistant") {
      for (const block of message.message.content) {
        if (block.type === "tool_use" && block.name === "TodoWrite") {
          this.todos = block.input.todos;
          this.displayProgress();
        }
      }
    }
  }
}

}

// Usage const tracker = new TodoTracker(); await tracker.trackQuery("Build a complete authentication system with todos"); ```

```python Python theme={null} from claude_agent_sdk import query, AssistantMessage, ToolUseBlock from typing import List, Dict

class TodoTracker: def init(self): self.todos: List[Dict] = []

  def display_progress(self):
      if not self.todos:
          return

      completed = len([t for t in self.todos if t["status"] == "completed"])
      in_progress = len([t for t in self.todos if t["status"] == "in_progress"])
      total = len(self.todos)

      print(f"\nProgress: {completed}/{total} completed")
      print(f"Currently working on: {in_progress} task(s)\n")

      for i, todo in enumerate(self.todos):
          icon = (
              "✅"
              if todo["status"] == "completed"
              else "🔧"
              if todo["status"] == "in_progress"
              else "❌"
          )
          text = (
              todo["activeForm"]
              if todo["status"] == "in_progress"
              else todo["content"]
          )
          print(f"{i + 1}. {icon} {text}")

  async def track_query(self, prompt: str):
      async for message in query(prompt=prompt, options={"max_turns": 20}):
          if isinstance(message, AssistantMessage):
              for block in message.content:
                  if isinstance(block, ToolUseBlock) and block.name == "TodoWrite":
                      self.todos = block.input["todos"]
                      self.display_progress()

# Usage tracker = TodoTracker() await tracker.track_query("Build a complete authentication system with todos") ```