PluginBench
Skill
Pass
Audit score 90

integrate-todo-list

cognitedata/builder-skills

Add a TodoWrite panel to show Atlas agent task progress in your chat UI.

What is integrate-todo-list?

Integrates a TodoWrite tool and visual task panel into an existing useAtlasChat-based app, allowing the AI agent to decompose work into tracked tasks and display progress in real-time. Use this when you have Atlas chat already set up and want agents to show structured task breakdowns.

  • Provides a TodoWrite tool that agents can call to create, update, and track tasks
  • Renders a TodoPanel UI component showing task progress with status indicators
  • Injects current todo list into agent context so it knows task state across prompts
  • Automatically clears completed tasks and manages todo lifecycle
  • Includes TodoToolResultCard for compact display of tool calls in message history

How to install integrate-todo-list

npx skills add https://github.com/cognitedata/builder-skills --skill integrate-todo-list
Prerequisites
  • Existing useAtlasChat integration in your app
  • src/atlas-agent/ directory present
  • @tabler/icons-react installed
  • @sinclair/typebox from integrate-atlas-chat
  • React 16.8+ (hooks support)
Claude Code
Cursor
Windsurf
Cline

How to use integrate-todo-list

  1. 1.Read package.json, src/App.tsx, and the file calling useAtlasChat to understand the app structure
  2. 2.Copy all files from the skill's code/ directory into src/todo/
  3. 3.Wrap your root component with <TodoProvider> in src/App.tsx
  4. 4.Import useTodoList and useTodoWriteTool, then add the tool to useAtlasChat's tools array and implement getAppContext callback
  5. 5.Add <TodoPanel todos={todos} /> above your chat input field
  6. 6.In your tool call renderer, branch on toolCall.name === 'TodoWrite' and render <TodoToolResultCard>
  7. 7.Run type-check (pnpm tsc --noEmit) to verify no errors

Use cases

Good for
  • Multi-step data analysis workflows where the agent breaks work into visible subtasks
  • Complex data transformation pipelines that benefit from progress tracking
  • Interactive chat sessions where users want to see what the agent is working on
  • Debugging agent behavior by observing task decomposition and status updates
Who it's for
  • Frontend developers integrating Atlas chat into React applications
  • Teams building AI-assisted data apps that need task visibility
  • Developers maintaining Cognite Data Fusion (CDF) integrations

integrate-todo-list FAQ

What if my app already uses integrate-fusion-agent?

Skip this skill entirely. The newer integrate-fusion-agent handles todo functionality automatically.

Do I need to install @tabler/icons-react separately?

Check package.json first. If it's not listed, install it with your app's package manager (npm, pnpm, yarn) before proceeding.

How does the agent know about the current todo list?

The getAppContext callback injects the current todo list as text into each prompt, so the agent can reference completed and pending tasks.

What happens when all tasks are completed?

TodoPanel automatically clears the list and returns null, so the UI disappears until new tasks are created.

Can I customize the TodoPanel styling?

The component files are copied into your src/todo/ directory, so you can edit TodoPanel.tsx and TodoItemRow.tsx to match your design system.

Full instructions (SKILL.md)

Source of truth, from cognitedata/builder-skills.


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:

FilePurpose
types.tsTodoItem and TodoList types
TodoContext.tsxReact context + TodoProvider
useTodoList.tsHook to read/write the todo list
todoWriteTool.tscreateTodoWriteTool factory — AtlasTool with full CDF task-decomposition guidance
useTodoWriteTool.tsHook that memoizes the tool with current state access
TodoPanel.tsxCard UI: progress bar + task rows
TodoItemRow.tsxSingle row with animated status icons
TodoToolResultCard.tsxCompact 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 getAppContext so it knows where it left off