mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-06-11 02:33:10 +08:00
Before this commit the dev-server-block hook ran the leading-command and dev-pattern check only against the top-level segments returned by `splitShellSegments`, which doesn't split on `$(...)`, backticks, or plain `(...)`. That left the policy bypassable by wrapping a dev command in any of those constructs: $(npm run dev) `npm run dev` echo $(npm run dev) (npm run dev) Each verified by piping a synthetic PreToolUse payload into the hook on this branch: every form above returned exit 0 (allow) where a plain `npm run dev` correctly returned exit 2 (block). Fix: expand the check space before running the leading-command rule. A small BFS walks the raw command, harvesting bodies from `extractCommandSubstitutions` (`$(...)` and backticks) and from `extractSubshellGroups` (plain `(...)`), then splits each harvested body through `splitShellSegments` and feeds the result into the existing `isBlockedDevSegment` check. This preserves every existing allow case (`tmux new-session -d -s dev "npm run dev"`, quoted-string mentions like `git commit -m "npm run dev fix"`, `echo hi`) because the leading-command rule is unchanged — only the set of segments it runs against grew. Known limitation, not fixed here: `eval "$(echo npm run dev)"` still slips through because the substitution body's leading command is `echo`, and statically modeling echo's output to recover the executed command is out of scope. The same class affects `gateguard-fact-force` (via `eval "$(echo rm -rf /)"` etc.) and is best addressed in both hooks together as a follow-up rather than as a one-off here.