integrate-todo-list — Claude Code skill: agent task panel
Adds a TodoWrite tool and a task panel so the in-app Atlas agent can show progress on multi-step work.
npx skills add cognitedata/builder-skills --skill integrate-todo-list -a claude-codeWhat integrate-todo-list does
The skill copies an eight-file src/todo/ module into your project: TodoItem and TodoList types, a React context with TodoProvider, the useTodoList hook, the createTodoWriteTool factory, useTodoWriteTool, plus TodoPanel, TodoItemRow and TodoToolResultCard. Every file uses relative imports, so nothing needs editing after the copy.
From there it walks the wiring: read package.json, src/App.tsx and the file that calls useAtlasChat, wrap the component tree in TodoProvider, pass the tool through tools: [todoWriteTool] together with getAppContext, then render the panel above the chat input. The current list is injected into every prompt via getAppContext, so the agent knows where it left off. TodoPanel returns null on an empty list, which makes it safe to render unconditionally.
This one is for apps that already have useAtlasChat, a src/atlas-agent/ directory and @sinclair/typebox from integrate-atlas-chat. If your app uses the Atlas / EOS sidebar, reach for integrate-fusion-agent instead. You also need @tabler/icons-react — the skill checks package.json and installs it with your package manager when it is missing. Verification is your type-check command, typically pnpm tsc --noEmit.
What it helps with
- show which agent tasks are done and which are still running
- wire the
TodoWritetool into an existinguseAtlasChatsetup - put a progress panel above the chat input
- render a compact result card for tool calls in the steps list
- feed the current task list back to the agent on every prompt
Example prompts for the agent
- add the todo panel to my chat with the integrate-todo-list skill
- wire TodoWrite into useAtlasChat and render TodoPanel above the input
- use TodoToolResultCard for steps that call TodoWrite
How to install integrate-todo-list
1Skills CLI (Vercel)
npx skills add cognitedata/builder-skills --skill integrate-todo-list -a claude-code2Manually: put the files in place
~/.claude/skills/integrate-todo-list/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/integrate-todo-list/
1Skills CLI (Vercel)
npx skills add cognitedata/builder-skills --skill integrate-todo-list -a codex2Manually: put the files in place
.agents/skills/integrate-todo-list/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add cognitedata/builder-skills --skill integrate-todo-list -a cursor2Manually: put the files in place
.cursor/skills/integrate-todo-list/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install cognitedata/builder-skills integrate-todo-list2Manually: put the files in place
.github/skills/integrate-todo-list/SKILL.md1Skills CLI (Vercel)
npx skills add cognitedata/builder-skills --skill integrate-todo-list -a gemini-cli2Platform CLI
gemini skills install https://github.com/cognitedata/builder-skills --path skills/integrate-todo-listManually: put the files in place
.devin/skills/integrate-todo-list/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add cognitedata/builder-skills --skill integrate-todo-list -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about integrate-todo-list
How do I install integrate-todo-list in Claude?
Run npx skills add cognitedata/builder-skills --skill integrate-todo-list -a claude-code. The skill file then lives at ~/.claude/skills/integrate-todo-list/SKILL.md.
What does integrate-todo-list do?
It adds a TodoWrite tool and a task panel so the Atlas agent can show progress on multi-step work. Statuses move through pending, in_progress and completed.
What does the skill need to work?
The app must already have useAtlasChat, a src/atlas-agent/ directory and @sinclair/typebox from the integrate-atlas-chat skill. For the Atlas / EOS sidebar, use integrate-fusion-agent instead.
Source text
SKILL.md · Apache-2.0
---
name: integrate-todo-list
description: "TodoWrite panel for an already-approved in-app useAtlasChat UI. New AI features use integrate-fusion-agent. Triggers: TodoWrite, todo panel — only when useAtlasChat already exists."
allowed-tools: Read, Glob, Grep, Edit, Write, Bash
---
# Integrate Todo List
Add a `TodoWrite` tool and panel so the in-app Atlas agent can show task progress.
Skip if the app uses the Atlas / EOS sidebar (`integrate-fusion-agent`). Prerequisite: `useAtlasChat` + `src/atlas-agent/` + `@sinclair/typebox` from `integrate-atlas-chat`.
---
## Step 1 — Read the app
Before writing anything, read:
- `package.json` — confirm `@tabler/icons-react` is installed; if not, install it with the app's package manager
- `src/App.tsx` — find where to add `TodoProvider`
- The file that calls `useAtlasChat` (likely `src/chat/useChatViewModel.ts` or `src/App.tsx`) — this is where the tool gets wired
- The chat view component that renders messages — this is where `TodoPanel` and `TodoToolResultCard` go
---
## Step 2 — Create the `src/todo/` module
Find the skill directory by running `find . -path "*/.agents/skills/integrate-todo-list/code" -type d` from the project root.
Read each file from `<skill-dir>/code/` and write it into `src/todo/` with the same filename:
| File | Purpose |
|------|---------|
| `types.ts` | `TodoItem` and `TodoList` types |
| `TodoContext.tsx` | React context + `TodoProvider` |
| `useTodoList.ts` | Hook to read/write the todo list |
| `todoWriteTool.ts` | `createTodoWriteTool` factory — `AtlasTool` with full CDF task-decomposition guidance |
| `useTodoWriteTool.ts` | Hook that memoizes the tool with current state access |
| `TodoPanel.tsx` | Card UI: progress bar + task rows |
| `TodoItemRow.tsx` | Single row with animated status icons |
| `TodoToolResultCard.tsx` | Compact summary card for tool call display |
All files use relative imports (`./types`, `./TodoContext`, etc.) — no changes needed.
---
## Step 3 — Wrap the app in `TodoProvider`
In `src/App.tsx` (or the root component), wrap the existing tree with `<TodoProvider>`:
```tsx
import { TodoProvider } from './todo/TodoContext'; // adjust path to match app conventions
function App() {
return (
<TodoProvider>
{/* existing children */}
</TodoProvider>
);
}
```
---
## Step 4 — Wire the tool into `useAtlasChat`
In the file that calls `useAtlasChat`, add the following. Adjust import paths to match the app's conventions.
```ts
import { useRef, useCallback } from 'react';
import { useTodoList } from './todo/useTodoList';
import { useTodoWriteTool } from './todo/useTodoWriteTool';
// Inside the hook/component:
const { todos, setTodos } = useTodoList();
const todoWriteTool = useTodoWriteTool();
// Keep a ref so getAppContext always reads fresh state without re-creating the callback.
const todosRef = useRef(todos);
todosRef.current = todos;
const getAppContext = useCallback(() => {
const t = todosRef.current;
if (t.length === 0) return undefined;
const lines = t.map((item, i) => `${i + 1}. [${item.status}] ${item.content}`);
return `Current todo list:\n${lines.join('\n')}`;
}, []);
// Add to useAtlasChat options:
const { messages, send, isStreaming, progress, error, reset, abort } = useAtlasChat({
client: isLoading ? null : sdk,
agentExternalId: AGENT_EXTERNAL_ID,
tools: [todoWriteTool], // add alongside any existing tools
getAppContext,
});
// In the reset handler, clear the todo list:
const handleReset = useCallback(() => {
reset();
setTodos([]);
}, [reset, setTodos]);
// Expose todos in the return value so the view can render TodoPanel:
return { ..., todos };
```
---
## Step 5 — Render `TodoPanel` in the chat view
In the component that renders the chat input area, add `<TodoPanel>` above the input field:
```tsx
import { TodoPanel } from './todo/TodoPanel'; // adjust path
// In the render:
<TodoPanel todos={todos} />
<YourChatInput ... />
```
`TodoPanel` returns `null` when the list is empty, so it's safe to always render it.
---
## Step 6 — Render `TodoToolResultCard` for tool call steps
In the component that renders per-message tool calls (typically a steps accordion or similar), branch on the tool name:
```tsx
import { TodoToolResultCard } from './todo/TodoToolResultCard'; // adjust path
{toolCalls.map((tc, i) =>
tc.name === 'TodoWrite' ? (
<TodoToolResultCard key={i} toolCall={tc} />
) : (
<YourDefaultToolCallCard key={i} toolCall={tc} />
)
)}
```
---
## Step 7 — Verify
Run the app's type-check command (typically `pnpm tsc --noEmit`) and confirm there are no errors.
If the project has tests, run them to confirm nothing regressed.
---
## Done
The agent can now use `TodoWrite` to create and track tasks. It will:
- Show a task panel as soon as it starts multi-step work
- Update task status in real-time (`pending` → `in_progress` → `completed`)
- Clear the list automatically when all tasks are done
- Inject the current task list into each prompt via `getAppContext` so it knows where it left off
© cognitedata · Apache-2.0 · cognitedata/builder-skills