[BUG] `claude -p` / `claude --print` exposes a different tool/default-prompt contract than TUI
Parent tracking issue: https://github.com/anthropics/claude-code/issues/59105
Context note: This is a frontend/product-boundary parity issue, not a criticism
of any individual implementation. Since -p / --print behavior is already a
known pain point, and upcoming mid-June frontend-facing changes may depend on
predictable CLI/TUI parity, this should be evaluated as a user-facing parity
risk. The goal is to reduce verification time and avoid customer-facing
regressions with potential business impact.
Summary
claude -p and the TUI expose different tool contracts and different default
system prompt instructions to the model. These are not harmless name changes.
They change the model's action space and guidance.
Observed tool delta
For the same prompt/model/config:
claude -p only:
GlobGrepTodoWrite
TUI only:
TaskCreateTaskGetTaskListTaskUpdate
Common tools: 20.
Rediscovery track
Capture a claude -p / claude --print request and the matching TUIsource=repl_main_thread request in the same state. Extract:
tools[].name, sorted by namesystem[].textblock count and first-line identity- user message block count, because tool filtering can add or remove reminder
blocks
For source inspection, search stable tool and entrypoint literals:TaskCreate, TaskGet, TaskList, TaskUpdate, TodoWrite, Glob, Grep,CLAUDE_CODE_ENTRYPOINT, sdk-cli, sdk-ts, and sdk-py.
These tools are not shape-compatible aliases
Glob and Grep are dedicated file discovery/search tools. The TUI does not
expose equivalent renamed tools in the captured request; its default prompt
instead tells the model to use Bash find/grep.
TodoWrite and TaskCreate/TaskGet/TaskList/TaskUpdate are related in
purpose, but they are different schemas:
TodoWrite: one bulk update tool accepting a fulltodosarray with
content, status, and activeForm
TaskCreate: creates one task withsubject,description, optional
activeForm, and metadata
TaskUpdate: updates a task bytaskId, including status, dependencies,
owner, and metadata
TaskGet/TaskList: read task state
The request includes input schemas, not an explicit output schema, but the input
schemas alone prove these are different action contracts.
Observed default-prompt delta
The third/default system block is also tool-aware.
-p prompt text instructs the model to prefer:
Read,Edit,Write,Glob,GrepTodoWrite
TUI prompt text instructs the model to prefer:
Read,Edit,WriteTaskCreate- Bash
find/grepfor broad exploration when not using an Agent
So even if a caller tried to patch tool names externally, the model would still
receive stale guidance unless the default prompt also converged.
Why this matters
Tool schemas are part of the model's control plane. Different tool contracts can
change:
- whether the model plans with a task database or a todo-list rewrite
- whether it searches through dedicated tools or Bash commands
- whether evals and CI jobs reproduce TUI behavior
- whether downstream failures are blamed on model behavior instead of scaffold
drift
This is a production parity issue, not just an implementation detail.
Expected
If claude -p is intended as non-interactive Claude Code, it should expose the
same tool/default-prompt contract as the TUI main-thread request unless a
difference is explicitly documented and intentionally selected.
Suggested fix
After fixing entrypoint classification:
- recapture
-pand TUI tool lists - confirm whether the tool/default-prompt deltas disappear
- if they remain, audit command/agent/tool loading for print-mode special cases
- ensure default prompt text is generated from the same tool profile that is
actually sent in the request
Related issues
- #18131 - print-mode-specific tool-use concurrency errors
- #20508 - duplicate tool_use IDs in
-p - #33343 -
--allowedToolsnot enforced in headless-p - #36570 / #44756 / #32184 - skill behavior diverges in print/headless mode
- #52917 / #56540 - Task/subagent behavior differs in print/headless mode
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗