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.
68
82%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
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.
Before writing anything, read:
package.json — confirm @tabler/icons-react is installed; if not, install it with the app's package managersrc/App.tsx — find where to add TodoProvideruseAtlasChat (likely src/chat/useChatViewModel.ts or src/App.tsx) — this is where the tool gets wiredTodoPanel and TodoToolResultCard gosrc/todo/ moduleFind 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.
TodoProviderIn 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>
);
}useAtlasChatIn 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 };TodoPanel in the chat viewIn 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.
TodoToolResultCard for tool call stepsIn 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} />
)
)}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.
The agent can now use TodoWrite to create and track tasks. It will:
pending → in_progress → completed)getAppContext so it knows where it left offc87160a
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.