integrate-todo-list
cognitedata/builder-skills
Add structured task tracking to Flows apps with Atlas chat integration.
What is integrate-todo-list?
Integrates a complete todo-list module into Flows apps using Atlas chat, enabling agents to create and update tasks in real-time via a TodoWrite tool. Provides state management, UI components, and full integration wiring. Requires integrate-atlas-chat to be set up first.
- Provides TodoContext, hooks, and UI components (TodoPanel, TodoItemRow, TodoToolResultCard) for task tracking
- Creates a TodoWrite tool that agents use to create, update, and track task status (pending → in_progress → completed)
- Injects current todo list into agent prompts via getAppContext so the agent knows task state
- Automatically clears completed tasks and manages todo state across chat sessions
- Includes animated status icons and progress visualization in the UI
How to install integrate-todo-list
npx skills add https://github.com/cognitedata/builder-skills --skill integrate-todo-list- integrate-atlas-chat skill must already be installed and configured
- @tabler/icons-react must be installed in the app
- @sinclair/typebox must be installed (from integrate-atlas-chat)
- useAtlasChat must be wired in the app
How to use integrate-todo-list
- 1.Read package.json, src/App.tsx, and the file calling useAtlasChat to understand the app structure
- 2.Copy all files from the skill's code/ directory into src/todo/ (types.ts, TodoContext.tsx, useTodoList.ts, todoWriteTool.ts, useTodoWriteTool.ts, TodoPanel.tsx, TodoItemRow.tsx, TodoToolResultCard.tsx)
- 3.Wrap your app root component with <TodoProvider> in src/App.tsx
- 4.In the file calling useAtlasChat, import useTodoList and useTodoWriteTool, add todoWriteTool to the tools array, and implement getAppContext to return the current todo list
- 5.Add <TodoPanel todos={todos} /> above your chat input field in the chat view component
- 6.In your tool call rendering logic, branch on toolCall.name === 'TodoWrite' and render <TodoToolResultCard> for those calls
- 7.Run type-check (pnpm tsc --noEmit) and tests to verify integration
Use cases
- Multi-step data analysis workflows where the agent breaks down complex queries into tracked subtasks
- CDF data exploration where users need real-time visibility into what the agent is processing
- Long-running agent operations where task progress tracking helps users understand agent reasoning
- Collaborative workflows where task lists serve as a shared record of agent work and decisions
- Flows app developers building multi-step agent workflows
- Teams using Atlas chat who need task visibility during agent execution
- Developers integrating CDF data exploration with progress tracking
integrate-todo-list FAQ
The skill will not work. integrate-atlas-chat must be installed first to provide useAtlasChat, the vendored atlas-agent sources, and @sinclair/typebox.
No. The skill provides all state management via TodoContext and useTodoList. Do not manually create todo state or tool definitions.
TodoPanel returns null when the list is empty. The list is cleared automatically when all tasks are completed, or manually via setTodos([]) in your reset handler.
The getAppContext callback injects the current todo list into each prompt as a formatted string, so the agent can reference completed and pending tasks.
The skill provides TodoPanel, TodoItemRow, and TodoToolResultCard components. You can modify these files after copying them into src/todo/, or wrap them with custom styling.
Full instructions (SKILL.md)
Source of truth, from cognitedata/builder-skills.
name: integrate-todo-list description: "MUST be used whenever adding a task/todo list feature to a Flows app with Atlas chat. Do NOT manually create todo state management or tool definitions — this skill handles the full module (context, provider, tool, hooks, UI components) and all integration wiring. Prerequisite: integrate-atlas-chat must already be set up. Triggers: todo list, task list, task tracking, TodoWrite, todo panel, task panel, progress tracking, add todos, add tasks." allowed-tools: Read, Glob, Grep, Edit, Write, Bash
Integrate Todo List
Add a structured task-tracking feature to this Flows app. The agent will use a TodoWrite tool
to create and update a task list as it works through multi-step queries, giving the user real-time
visibility into what the agent is doing and why.
Prerequisite: integrate-atlas-chat must already be complete — useAtlasChat must be wired (typically from ./atlas-agent/react), src/atlas-agent/ must contain the vendored atlas-agent sources, and @sinclair/typebox must be installed per that skill.
Step 1 — Read the app
Before writing anything, read:
package.json— confirm@tabler/icons-reactis installed; if not, install it with the app's package managersrc/App.tsx— find where to addTodoProvider- The file that calls
useAtlasChat(likelysrc/chat/useChatViewModel.tsorsrc/App.tsx) — this is where the tool gets wired - The chat view component that renders messages — this is where
TodoPanelandTodoToolResultCardgo
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>:
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.
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:
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:
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
getAppContextso it knows where it left off
Related skills
More from cognitedata/builder-skills and the wider catalog.

migrate-app-to-flows
Orchestrate full migration of legacy Dune apps to Flows app hosting infrastructure.

performance
Find and fix performance issues in Flows apps—re-renders, inefficient queries, pagination, and memory leaks.

pull-changes-resolve-conflicts
Safely integrate branch changes by analyzing conflicts before resolving, preserving intentional work.

reveal-3d
Embed interactive Cognite Reveal 3D CAD viewer in Flows apps with local bundled source.

security
Find and fix security issues in Flows apps before shipping—handles credentials, input validation, XSS, injection, and auth gaps.

setup-flows-auth
Wire a React app for Flows authentication to connect to CDF inside Fusion.