Repository navigation
feat(cli): persist install hook opt-out - #1862
Andy11-cpu wants to merge 7 commits into
Conversation
|
Thanks for opening this — it has been seen, and it is queued. This note is automated, but it is not a brush-off: it exists so you know where your PR stands instead of having to guess from silence. Current review status: working through a backlog. What that means for this PR, concretely:
Things that will genuinely speed it up whenever review does happen:
If this fixes a bug, a reproduction we can run is worth more than a description of the symptom. Thanks for contributing, and sorry in advance for the wait. |
|
Thank you for implementing the previously discussed persistent hook opt-out and for preserving foreign hook state, dry-run behavior, and the remaining installer surfaces. The contribution queue is currently quite full, so the full review may take a little time. We have the PR routed and will come back with grounded feedback as soon as possible. |
|
Reviewed. The direction is settled — this implements the approved outcome from #753 — so this is about one build break, and it is a small one. The Windows failure is real, and it is a missing platform guardBoth The compiler's suggestion is a red herring. The existing call site already knows this. At #ifndef _WIN32
if (cbm_remove_gemini_coverage_hook(cp, installed_binary) != CLI_OK) {
...
}
#endifYour new call is not wrapped. Adding the same Why only Windows caught it: clang treats an implicit function declaration as an error, and the CLANG64 legs are the ones building with clang. On POSIX the function is present, so every other leg compiles cleanly and says nothing. Worth knowing, because a green Linux and macOS run tells you nothing about this class of mistake. One knock-on to check while you are there: The restThe shape is right: hooks stay enabled by default, Clearance is Also please rebase once the guard is in: |
Signed-off-by: Andy11-cpu <canada11@duck.com>
Signed-off-by: Andy11-cpu <canada11@duck.com>
Signed-off-by: Andy11-cpu <canada11@duck.com>
fc203c6 to
0e8fc16
Compare
Maintainer carry of DeusData#1862 (persistent install-hook opt-out, direction approved in DeusData#753). Main's current behaviour is kept everywhere; only the PR's intent -- persisting `install --no-hooks` / `--hooks` -- is re-applied on top of it. Textual conflicts: - docs/CONFIGURATION.md: both sides appended rows to the "Current keys" table. Kept main's `index_max_files` and `index_max_source_mb` rows unchanged, then added the PR's `install_hooks` row after them. The PR's explanatory paragraph follows the table, so the table stays one contiguous block. - src/main.c (print_help): main added a second `install` usage line for `[--clients=<tokens>]`; the PR appended `[--hooks|--no-hooks]` to the first line. Kept both: main's first line plus the PR's hook flags, followed by main's `--clients` line unchanged. Semantic conflicts (merged cleanly as text, wrong against main): - src/cli/cli.c, install_claude_code_config() --no-hooks branch: main now registers Claude hooks shell-free (DeusData#1733), as `<binary> hook-augment`, and changed cbm_remove_session_hooks() to take (settings_path, binary_path). The PR's disable path still called cbm_remove_session_hooks(settings_path), which no longer compiles, and used the NULL-binary cbm_remove_claude_hooks() / cbm_remove_claude_subagent_hooks() wrappers, which do not match the exec-form entries main installs. The disable path now calls the same binary-aware removers as main's uninstall_claude_code(): cbm_remove_claude_hooks_with_binary(), cbm_remove_session_hooks(..., binary_path) and cbm_remove_claude_subagent_hooks_with_binary(), all with the binary_path the install side registers. Legacy shell-form entries are still covered through those functions' old_commands lists. - tests/test_cli.c, cli_install_hooks_preference_persists_and_migrates_owned_state: the settings.json checks looked for "cbm-code-discovery-gate", but main no longer writes that name into settings.json (main's own cli_claude_hook_commands_use_exec_form_with_custom_config_dir asserts it is absent). The presence checks would be RED and the absence checks would pass without testing anything. They now use "hook-augment", the owned marker main's tests use. The script-file checks are unchanged, because main still writes the shim scripts. - scripts/smoke-test.sh 8e-i: same stale marker. The --no-hooks check now also rejects "hook-augment" in settings.json, and the --hooks check requires it. Both checks use "$GATE_SCRIPT" (set per platform in 8e) in place of the extensionless shim path, which on Windows (.cmd) could never exist and so checked nothing there. Everything else (cli.c hook gating, cli.h key, README, CONFIG_KEYS table, test registrations) auto-merged against main without change. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
|
Thanks again for the persistent hook opt-out. The recorded review asks remain the Windows guard around the Gemini helper call and a branch refresh, preserving the non-mutating plan/dry-run behavior. The smoke clearance mentioned above is a maintainer step, not something you need to change in the patch. Sorry for the delay on our smoke clearance; I’ll follow up on that soon. |
Maintainer refresh of DeusData#1862 (persistent install-hook opt-out, direction decided in DeusData#753) onto main a5b248f. The first refresh is 2577a86 and carries the semantic fixes for shell-free Claude hooks. Textual conflicts, all resolved by keeping both sides: - src/cli/cli.h: main added CBM_CONFIG_DOC_CANDIDATES on the line where the PR added CBM_CONFIG_INSTALL_HOOKS. Both defines are kept, in alphabetical order. - src/cli/cli.c CONFIG_KEYS[]: main added the watch_non_git row where the PR added install_hooks. Main row stays first, followed by the install_hooks row. - src/cli/cli.c Codex hook install: main (DeusData#2719) declared pretool_written in front of the hooks.json branch the PR prefixed with its --no-hooks removal branch. The declaration stays first, then the PR removal branch, then main hooks.json and config.toml upsert branches unchanged. Check: for every file the PR touches, the added and removed lines of the merged tree against main equal those of the PR against its old base. No compile-level semantic conflict: no function the PR calls changed its signature, and the PR re-signs no function main calls. The new Codex PreToolUse hook from DeusData#2719 is gated by the opt-out in the next commit. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Since DeusData#1180 a bare ~/.claude directory no longer counts as a Claude Code install. The fixture of cli_no_hooks_plan_covers_every_hook_installer_family now also writes .claude/settings.json. Without it claude-code drops out of agents_detected and the test fails on the tree merged with current main. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
…-out DeusData#2719 added a PreToolUse Bash hook for Codex after this opt-out was written. In config.toml it lives inside the managed block, which the opt-out already removes. In hooks.json it is a separate entry beside the lifecycle pair, and the opt-out removed only the pair, so after install --no-hooks, and on every later bare install or update that respects the stored preference, our PreToolUse hook stayed registered. The --no-hooks branch now also calls cbm_remove_codex_pretool_hooks_json, the exact-command remover that uninstall uses since DeusData#2719. A PreToolUse hook the user owns is left alone. Test: cli_no_hooks_removes_codex_pretool_hook drives the real install dispatch through both hook representations. A default install writes ours beside a foreign hook; --no-hooks and a bare install with the stored preference remove ours and keep the foreign hook and the MCP entry; and --hooks restores ours. Without the fix it fails: ours is still in hooks.json after --no-hooks. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
|
Thank you, @Andy11-cpu, for carrying this all the way from #753. You did the hard part well. The opt-out is exhaustive: every hook-capable installer family is gated, not just Claude Code. The choice persists in the existing config store, so bare installs and
Because the branch now has new commits from us, please pull before you push again. Thanks again for building an opt-out that keeps the graph-first default for everyone else. It is a real improvement for the people who need it. |
Fixes #1857
Supersedes #753.
What
install --no-hooksandinstall --hooks.Why
#753 established the performance cost of per-call hook process spawning. This implements the maintainer-approved direction from that discussion: retain graph-first defaults while giving users a persistent opt-out.
Verification
scripts/test.shscripts/lint.sh --ci CLANG_FORMAT=clang-format-20scripts/ci/lint-mem.sh clang-tidy-22make -f Makefile.cbm securitygit diff --checkAll pass locally.