shared: canonical ToolKind taxonomy mapped from both Anthropic + Cursor tool names #954
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Blocks
#957 agents: synthesize shell_output_delta for claude-code via container log stream
charles/claude-hooks
#959 dashboard: adopt ToolUIPart state enum on SSE wire (input-streaming → output-{available,error,denied})
charles/claude-hooks
Reference
charles/claude-hooks#954
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
User story
As a frontend engineer rendering the agent activity timeline, I want a stable provider-agnostic enum identifying what kind of tool a tool call invoked, so I can pick the right widget (file diff, shell pane, grep results, etc.) without conditioning on provider.
Context
Today each provider emits its own tool names:
Read,Write,Edit,Bash,Grep,Glob,WebFetch,WebSearch,Task,TodoWrite,NotebookEdit,mcp__forgejo__*etc.Edit,Write,Read,Shell,Grep,Glob,SemSearch,Ls,Mcp,Task,CreatePlan,UpdateTodos,Delete,ReadLints(typed viatool-call-types.d.ts).Frontend code currently can't render a "shell output" widget for cursor without knowing that cursor calls it
Shellwhile claude calls itBash. This grows fragile as more providers join (LangChain tool sets, OpenAI Responses tool calls).Acceptance criteria
@claude-hooks/sharedenum ToolKind(or string-literal union) with members:read,write,edit,deleteshell(any execute-command tool)grep,glob,sem_search,ls,read_lintsweb_fetch,web_searchmcp(any MCP-mounted tool — keep the original name in metadata)subagent_taskplan(CreatePlan-style)todos(UpdateTodos / TodoWrite)notebook_editunknown(catch-all; renders a generic JSON view)mapToolNameToKind(provider, name): ToolKind— pure function; covers every name in the matrix above with a fallback tounknown.ToolCallNormalizedtype —{ kind: ToolKind, providerName: string, args: unknown, result?: unknown, ok?: boolean }. Used in event-log payloads sent over SSE.Adapters
cursor-sdk-adapter.tsandsdk-adapter.ts(claude) populateToolCallNormalized.kindon every tool-related event they emit. The unmappedkindfor an unknown tool isunknownand theproviderNamecarries the original.Frontend
ToolKind:<EditToolCallView>— render unified diff (use diff-viewer lib of choice; new dep can be discussed in the widget issue itself)<WriteToolCallView>— file path + size + contents with syntax highlight<ReadToolCallView>— file path + line range + collapsed body<ShellToolCallView>— command line + live stdout pane<GrepToolCallView>— pattern + matches list (file:line:preview)<GlobToolCallView>/<LsToolCallView>— file list<SemSearchToolCallView>— query + ranked results<WebFetchToolCallView>/<WebSearchToolCallView>— URL + title + excerpt<McpToolCallView>— provider/tool + JSON payload (collapsible)<SubagentTaskView>— child agent dispatch (links to subagent timeline if available)<PlanView>— bullet list of plan items with checkbox state<TodosView>— todo list with status pills<UnknownToolCallView>— JSON tree fallbackToolCallNormalizedshape directly, not provider-specific shapes.Tests
mapToolNameToKindagainst a fixture matrix.Out of scope
task_historyalready stores tool calls in event JSON, no DDL needed; new fields land in event payload only.References
node_modules/.bun/@cursor+sdk@1.0.12/node_modules/@cursor/sdk/dist/cjs/types/tool-call-types.d.tsapps/server/src/infrastructure/agent/sdk-adapter.ts+Agent SDKdocs.