Commit Graph

1 Commits

Author SHA1 Message Date
rUv 3657a69366 fix(hooks): pre-bash TypeError + global-install MODULE_NOT_FOUND (#1944, #1943) (#1957)
Two critical hook regressions on a fresh `ruflo init` (alpha.27):

**#1944** — `helpers/hook-handler.cjs` builds the `prompt` string from a
`||` fallback chain whose third term is the normalised `toolInput` *object*
(`{command:"ls"}` etc.). The object is truthy so the chain stops there;
the next line calls `.toLowerCase()` on it and every `pre-bash` invocation
prints `[WARN] Hook pre-bash encountered an error: …toLowerCase is not a
function` — i.e. **every Bash tool call from Claude Code spams a TypeError**.

Fix: fall back to `toolInput.command` (the string) instead of `toolInput`
(the object). One-character change in three places — the deployed handler
(both tracked copies) and the template in `helpers-generator.ts` that
writes the user's `.claude/helpers/hook-handler.cjs` at init time.

Repro on the fixed file:
  echo '{"tool_input":{"command":"ls"},"tool_name":"Bash"}' \
    | node v3/@claude-flow/cli/.claude/helpers/hook-handler.cjs pre-bash
  → [OK] Command validated   (was: TypeError warning)

Dangerous-command guard still fires:
  echo '{"tool_input":{"command":"rm -rf /"},"tool_name":"Bash"}' | … pre-bash
  → [BLOCKED] Dangerous command detected: rm -rf /

**#1943** — `settings-generator.ts` writes hook command strings anchored at
`${CLAUDE_PROJECT_DIR:-.}/.claude/helpers/…`. That works when `ruflo init`
lands helpers project-locally, but breaks when init's settings end up in
`~/.claude/settings.json` (global install) with helpers at
`~/.claude/helpers/`: Claude Code still sets `CLAUDE_PROJECT_DIR` to the
*project* root, the path resolves there, finds nothing, and every Bash /
Edit / Session hook fires `MODULE_NOT_FOUND`.

Fix: replace the path expression with a POSIX `sh` probe that tries the
project-local path first and falls back to `$HOME` when it's missing —
project-local overrides still take precedence; global installs work; no
upgrade-skew. Windows gets the same probe via `cmd /c IF EXIST … ELSE …`.
Applied to both `hookCmd()` and `generateStatusLineConfig()` (the
statusline scaffolding had the same anchor bug).

**CI guard**: `scripts/audit-hook-handler-prompt.mjs` (new) — fails the
build if any `.cjs` handler / TS template falls back to a bare `toolInput`
(object) instead of `toolInput.command` (string). Catches the #1944
pattern exactly. Wired into the existing `hook-command-audit` job.
Verified to flag a deliberately-reverted regression (and clean on HEAD).

Resolves #1944, #1943.

Co-authored-by: Reuven <cohen@ruv-mac-mini.local>
2026-05-13 09:02:51 -04:00