Skip to content

Claude Code headless mode still denied by active PreToolUse formatter #979

Description

@movax01h

Summary

context-mode@1.0.169 still denies native-tool calls in Claude Code headless runs even though PR #380 added headless passthrough to hooks/formatters/claude-code.mjs. The active hooks/pretooluse.mjs entrypoint imports formatDecision from hooks/core/formatters.mjs, so the standalone formatter changed by #380 is not called.

Pristine reproduction

Using the published npm tarball (SHA-256 09c41e4cf77b21566c76b8ea2fdbd7f3d823055fee2f02c2166fd5bb575daf2c) and an isolated ready sentinel:

  • MCP unavailable: passthrough
  • MCP ready + interactive main agent: deny/redirect (expected)
  • MCP ready + fixed-tool subagent: passthrough
  • MCP ready + CLAUDE_CODE_HEADLESS=1: deny/redirect (unexpected)

Calling hooks/formatters/claude-code.mjs directly returns null for the headless row, while hooks/core/formatters.mjs returns the deny payload. Current main still has the same active import/call path.

Suggested compatible fix

  1. Apply the headless passthrough to the Claude deny, ask, and modify handlers in hooks/core/formatters.mjs (or route the active hook through the standalone Claude formatter).
  2. In hooks/pretooluse.mjs, create rejected/redirect accounting markers only when the formatted response is non-null. Otherwise a headless passthrough is incorrectly counted as a context-mode rejection/redirect.
  3. Add an active-entrypoint regression matrix for unavailable, interactive, fixed-tool subagent, and headless modes.

Related: #380.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions