Skip to content

fix(hook): tolerate --hook-json flag from Claude Code harness - #180

Merged
Rome-1 merged 1 commit into
mainfrom
fix/hook-unknown-flag-2
Jun 21, 2026
Merged

fix(hook): tolerate --hook-json flag from Claude Code harness#180
Rome-1 merged 1 commit into
mainfrom
fix/hook-unknown-flag-2

Conversation

@Rome-1

@Rome-1 Rome-1 commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Claude Code now appends --hook-json <data> to hook commands at invocation; both CLIs were rejecting it as an unknown flag
  • Hook event data comes via stdin, not this flag, so it's safe to discard
  • Node.js: added .allowUnknownOption() to the pretool Commander subcommand
  • Python: added context_settings={"allow_extra_args": True, "ignore_unknown_options": True} to hook_app

Test plan

  • echo '{"tool_name":"Bash","tool_input":{"command":"ls"}}' | rafter hook pretool --hook-json '{}' — no error, returns allow decision
  • python -m rafter_cli hook pretool --hook-json '{}' <<< '{"tool_name":"Bash","tool_input":{"command":"ls"}}' — no error
  • Existing hook behavior unchanged (stdin JSON still drives decisions)

🤖 Generated with Claude Code

…son)

Claude Code appends `--hook-json <data>` to the hook command at invocation; both
CLIs rejected it as an unknown option and exited non-zero, breaking the hook.
Hook input comes from stdin, so the extra flag (and its value) is unused and
safe to discard.

- Node: `.allowUnknownOption()` + `.allowExcessArguments()` on BOTH the pretool
  and posttool Commander subcommands (the `<data>` value lands as an excess arg,
  so allowUnknownOption alone isn't enough).
- Python: `context_settings={allow_extra_args, ignore_unknown_options}` on the
  pretool/posttool `@hook_app.command(...)` decorators. (Setting it on the
  hook_app *group* — the prior approach — does NOT reach subcommand parsing, so
  `--hook-json` was still rejected; verified the group-only fix fails.)

Declared options like `--format` are still parsed normally. Adds Node + Python
regression tests covering: --hook-json tolerated on pretool & posttool, --format
still honored (not swallowed), and unchanged no-flag behavior. CLI_SPEC.md
documents the tolerance.

Supersedes the original #180 branch (which had no merge-base with main and
bundled an unrelated docs/vitest-upgrade history); re-applied cleanly on main.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Rome-1
Rome-1 force-pushed the fix/hook-unknown-flag-2 branch from c386497 to a82f4d5 Compare June 21, 2026 00:44
@Rome-1

Rome-1 commented Jun 21, 2026

Copy link
Copy Markdown
Collaborator Author

Rebuilt this branch so it's mergeable and the fix actually works.

Why a rebuild: the branch had no merge-base with main (it was rooted on an unrelated vitest v4 upgrade history and bundled a large docs: expand skill documentation commit), which is why GitHub showed it conflicting. I re-applied the fix cleanly on current main — the diff is now just the hook change + tests (125/3 instead of 416/272). The unrelated docs/vitest commits were dropped; if the skill-docs expansion is still wanted, it's better as its own PR.

Fixed a real bug in the Python side: the original change set context_settings on the hook_app group, which does not reach subcommand parsing — python -m rafter_cli hook pretool --hook-json '{}' still errored with "No such option: --hook-json" (verified). Moved it to the @hook_app.command(...) decorators for pretool and posttool, where it takes effect.

Also:

  • Node needed .allowExcessArguments() in addition to .allowUnknownOption() — the <data> value after --hook-json lands as an excess positional, which Commander rejects on its own.
  • Applied to both pretool and posttool (Python's app-level intent covered both; the original Node change only did pretool).
  • Added Node + Python regression tests: --hook-json tolerated on both subcommands, --format still honored (not swallowed), no-flag behavior unchanged. CLI_SPEC.md documents the tolerance.

Verified the original repro end-to-end in both languages (exit 0, correct decision). All hook suites green (Node 110, Python 76).

@Rome-1
Rome-1 merged commit da09382 into main Jun 21, 2026
4 checks passed
@Rome-1
Rome-1 deleted the fix/hook-unknown-flag-2 branch June 21, 2026 01:00
@Rome-1 Rome-1 mentioned this pull request Jun 28, 2026
Rome-1 added a commit that referenced this pull request Jun 28, 2026
Patch release bundling the unreleased changes on main since 0.8.9:
- Claude Code PostToolUse matcher narrowed .* -> Bash|Write|Edit|MultiEdit (#183)
- Hooks tolerate harness-appended flags, e.g. --hook-json (#180)
- Dependency CVE re-lock (axios, hono, tar, js-yaml, +transitives) and
  remote-skill tarball extraction hardening (#184)

Bumps node/package.json + python/pyproject.toml to 0.8.10 (parity), the
rafter-security skill resource version (node + python), and finalizes the
CHANGELOG 0.8.10 section.

Refs sable-ehb1

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant