Skip to content

Stop hook starts node on every turn end even when the review gate is off — add a shell pre-gate #796

Open

Description

@amondnet

Summary

hooks/hooks.json registers node scripts/stop-review-gate-hook.mjs on every Stop. With the review gate off (the default, stopReviewGate: false) the script reads state.json, finds nothing to do, and exits. That still costs a full node start on every turn end. A small sh pre-gate could exit before node starts in that case and keep current behavior otherwise.

Measurement

macOS (Darwin 24.6), Claude Code 2.1.288, plugin 1.0.6. Gate off, no jobs. hyperfine -N, 30 runs, real Stop payload on stdin:

Command Mean
node scripts/stop-review-gate-hook.mjs (today) 182.6 ms ± 9.6 ms
sh pre-gate below (gate off, no live jobs) 14.7 ms ± 0.6 ms

Classic hooks on one event run in parallel, so this only shortens a turn when node is the slowest Stop hook. Every turn end still pays the CPU cost. #441 reports the same unconditional spawn on Windows, where it also flashes a console window each turn. A pre-gate addresses both without changing how the hook is registered.

Proposal

Point the Stop command at a POSIX sh wrapper. It hands off to node only when some workspace has the gate on or has a queued/running job. The live-job check keeps the "Codex task … is still running" note that main() prints even with the gate off.

#!/bin/sh
# Superset of "stop-review-gate-hook.mjs has work": any state.json with the gate on or a live job.
state_root="${CLAUDE_PLUGIN_DATA:+$CLAUDE_PLUGIN_DATA/state}"
grep -qsE '"stopReviewGate": *true|"status": *"(queued|running)"' \
  ${state_root:+"$state_root"/*/state.json} "${TMPDIR:-/tmp}/codex-companion"/*/state.json || exit 0
exec node "$CLAUDE_PLUGIN_ROOT/scripts/stop-review-gate-hook.mjs"

Design notes:

Context

We distribute this plugin through an internal marketplace as a git-subdir source pinned to this repository, so we cannot patch the hook on our side. We are moving our own per-turn Stop hooks off process spawns for the same reason.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions