integrate-todo-list
Original:🇺🇸 English
Translated
4 scriptsChecked / no sensitive code detected
MUST be used whenever adding a task/todo list feature to a Dune 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.
5installs
Sourcecognitedata/dune-skills
Added on
NPX Install
npx skill4agent add cognitedata/dune-skills integrate-todo-listTags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →Integrate Todo List
Add a structured task-tracking feature to this Dune app. The agent will use a 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.
TodoWritePrerequisite: must already be set up — must be wired and
, , , must be installed.
integrate-atlas-chatuseAtlasChat@cognite/dune-industrial-components@sinclair/typeboxajvajv-formatsStep 1 — Read the app
Before writing anything, read:
- — confirm
package.jsonis installed; if not, install it with the app's package manager@tabler/icons-react - — find where to add
src/App.tsxTodoProvider - The file that calls (likely
useAtlasChatorsrc/chat/useChatViewModel.ts) — this is where the tool gets wiredsrc/App.tsx - The chat view component that renders messages — this is where and
TodoPanelgoTodoToolResultCard
Step 2 — Create the src/todo/
module
src/todo/Find the skill directory by running from the project root.
find . -path "*/.agents/skills/integrate-todo-list/code" -type dRead each file from and write it into with the same filename:
<skill-dir>/code/src/todo/| File | Purpose |
|---|---|
| |
| React context + |
| Hook to read/write the todo list |
| |
| Hook that memoizes the tool with current state access |
| Card UI: progress bar + task rows |
| Single row with animated status icons |
| Compact summary card for tool call display |
All files use relative imports (, , etc.) — no changes needed.
./types./TodoContextStep 3 — Wrap the app in TodoProvider
TodoProviderIn (or the root component), wrap the existing tree with :
src/App.tsx<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
useAtlasChatIn the file that calls , add the following. Adjust import paths to match the app's conventions.
useAtlasChatts
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
TodoPanelIn the component that renders the chat input area, add above the input field:
<TodoPanel>tsx
import { TodoPanel } from './todo/TodoPanel'; // adjust path
// In the render:
<TodoPanel todos={todos} />
<YourChatInput ... />TodoPanelnullStep 6 — Render TodoToolResultCard
for tool call steps
TodoToolResultCardIn 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 ) and confirm there are no errors.
If the project has tests, run them to confirm nothing regressed.
pnpm tsc --noEmitDone
The agent can now use to create and track tasks. It will:
TodoWrite- 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 so it knows where it left off
getAppContext