mirror of
https://github.com/ruvnet/ruflo.git
synced 2026-10-23 03:47:00 +09:00
* fix(#1921): plugin hooks invoke a resilient shim, not bare `npx @alpha` per fire Every PreToolUse/PostToolUse/Stop hook ran `npx <pkg>@alpha hooks …`, which (a) re-resolves the @alpha dist-tag from the registry on every fire and (b) re-installs from cold cache — and when that install crashes (an arborist `Invalid Version` on npm 10.8.x, deep in a transitive OTEL/grpc subtree) the user sees a hook error in Claude Code after every assistant turn, plus ~7s of wasted registry traffic per turn. Fix: each plugin (`.claude-plugin/`, `plugin/`, `plugins/ruflo-core/`) ships `scripts/ruflo-hook.sh` — prefers an already-installed `ruflo`/`claude-flow` binary, falls back to `npx --prefer-offline --yes ruflo@alpha`, and ALWAYS exits 0. hooks.json invokes `"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh" … || true` (the `|| true` covers the unset-$CLAUDE_PLUGIN_ROOT case). stdin (the hook event JSON) passes through unchanged; the stdin-jq-xargs shell-injection-safety pattern in plugin/hooks/hooks.json is preserved. This does NOT fix the underlying arborist crash (which needs the offending empty-`version` package pinned via `overrides` once it's identified on npm 10.8.2 — see the issue thread) — it makes a CLI/install failure invisible and cheap instead of a visible error every turn. CI guard: scripts/audit-hook-commands.mjs — fails CI if any hook `command` uses `npx` without `--prefer-offline`, or invokes the CLI without a non-fatal guard. Wired into v3-ci.yml as `hook-command-audit` (also bash-lints each ruflo-hook.sh and asserts it exits 0 with no CLI on PATH) + added to witness-verify needs[]. Path triggers updated to fire on `**/hooks/hooks.json`, `**/scripts/ruflo-hook.sh`, and `scripts/**`. Witness markers for #1921 + Co-Authored-By: RuFlo <ruv@ruv.net> * fix(#1921): make test-hooks.mjs shim-aware; fix shim-lint CI step; regen witness Rebasing #1921 onto main surfaced 3 CI failures: - plugin-hooks-smoke (ubuntu + macos): test-hooks.mjs substituted only `npx ruflo@alpha` → the local CLI, but the hooks.json now invokes `${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh <args>`. It now also substitutes the shim path → `<cli> hooks <args>` (bypassing the shim, so the test exercises the real CLI flag wiring) and strips the shim's trailing `|| true` so exit codes are still asserted. 7/7 pass. - hook-command-audit shim-lint step: `PATH="/nonexistent" bash "$sh"` set PATH to a dir with no `bash`, so `bash: command not found`. Now invokes bash by full path with `PATH=` empty: `PATH= "$BASH" "$sh"` — the shim's `command -v` is a builtin (works with empty PATH) and the npx fallback fails cleanly under `|| true` → exit 0. (resolved in v3-ci.yml during the rebase.) Witness manifest regenerated; #1862's marker refreshed to match the shim-relocated `post-edit -f "$FILE" -s true` (the documented-flag form is preserved). `ruflo verify` 0 regressed. Co-Authored-By: RuFlo <ruv@ruv.net> --------- Co-authored-by: Reuven <cohen@ruv-mac-mini.local>
This commit is contained in:
1 parent
95df0111e0
commit
f0ee0f9688
12 files changed
+349
-56
No files matched your search
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"_note": "#1921 — hook commands invoke scripts/ruflo-hook.sh (resilient shim): prefers a locally-installed `ruflo`/`claude-flow` binary, falls back to `npx --prefer-offline`, and always exits 0 so a CLI/install failure (e.g. arborist `Invalid Version` on npm 10.8.x) never surfaces an error in Claude Code or blocks a turn. The trailing `|| true` guards the case where $CLAUDE_PLUGIN_ROOT is unset (older Claude Code) — the hook then no-ops silently. DO NOT revert to a bare `npx <pkg>@alpha hooks …` per fire.",
|
||||
"hooks": {
|
||||
"PreToolUse": [
|
||||
{
|
||||
@@ -6,7 +7,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "cat | npx claude-flow@alpha hooks modify-bash"
|
||||
"command": "\"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" modify-bash || true"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -15,7 +16,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "cat | npx claude-flow@alpha hooks modify-file"
|
||||
"command": "\"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" modify-file || true"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -26,7 +27,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "cat | jq -r '.tool_input.command // empty' | tr '\\n' '\\0' | xargs -0 -I {} npx claude-flow@alpha hooks post-command --command '{}' --track-metrics true --store-results true"
|
||||
"command": "cat | jq -r '.tool_input.command // empty' | tr '\\n' '\\0' | xargs -0 -I {} \"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" post-command --command '{}' --track-metrics true --store-results true || true"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -35,7 +36,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "cat | jq -r '.tool_input.file_path // .tool_input.path // empty' | tr '\\n' '\\0' | xargs -0 -I {} npx claude-flow@alpha hooks post-edit --file '{}' --format true --update-memory true"
|
||||
"command": "cat | jq -r '.tool_input.file_path // .tool_input.path // empty' | tr '\\n' '\\0' | xargs -0 -I {} \"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" post-edit --file '{}' --format true --update-memory true || true"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -65,7 +66,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "npx claude-flow@alpha hooks session-end --generate-summary true --persist-state true --export-metrics true"
|
||||
"command": "\"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" session-end --generate-summary true --persist-state true --export-metrics true || true"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env bash
|
||||
# ruflo-hook.sh — resilient invoker for ruflo CLI hook subcommands (#1921).
|
||||
#
|
||||
# Hooks fire on EVERY PreToolUse / PostToolUse / Stop. A bare
|
||||
# `npx <pkg>@alpha hooks …` re-resolves the @alpha dist-tag and re-installs
|
||||
# from cold cache on every fire, and when the install crashes (e.g. an
|
||||
# arborist `Invalid Version` on npm 10.8.x) the user sees a hook error in
|
||||
# Claude Code after every turn. This shim:
|
||||
# 1. prefers an already-installed `ruflo` / `claude-flow` binary (no npx,
|
||||
# no install) — the common case for plugin users;
|
||||
# 2. falls back to `npx --prefer-offline` so a populated npx cache is
|
||||
# reused instead of a fresh registry resolve;
|
||||
# 3. ALWAYS exits 0 — hook subcommands are best-effort telemetry/learning;
|
||||
# a failure must never surface an error or block a turn.
|
||||
#
|
||||
# stdin (the hook event JSON) is passed through to the CLI unchanged.
|
||||
# Usage: ruflo-hook.sh <hook-subcommand> [args…] (the literal `hooks`
|
||||
# word is prepended here, so callers pass e.g. `post-edit -f "$FILE" -s true`).
|
||||
|
||||
# Swallow all diagnostics — nothing this script prints should reach Claude Code.
|
||||
exec 2>/dev/null
|
||||
|
||||
run() { "$@" || true; }
|
||||
|
||||
if command -v ruflo >/dev/null 2>&1; then
|
||||
run ruflo hooks "$@"
|
||||
elif command -v claude-flow >/dev/null 2>&1; then
|
||||
run claude-flow hooks "$@"
|
||||
else
|
||||
run npx --prefer-offline --yes ruflo@alpha hooks "$@"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
+47
-12
@@ -10,15 +10,21 @@ on:
|
||||
# path filter keeps CI in sync with their changes.
|
||||
- 'plugins/ruflo-core/scripts/witness/**'
|
||||
- 'plugins/ruflo-core/scripts/test-hooks.mjs'
|
||||
- 'plugins/ruflo-core/hooks/hooks.json'
|
||||
- 'verification/**'
|
||||
# scripts/*.mjs audits (tool-descriptions, plugin-packages, hook-commands)
|
||||
- 'scripts/**'
|
||||
# hook-command audit (#1921) — every plugin hooks.json + the ruflo-hook shims
|
||||
- '**/hooks/hooks.json'
|
||||
- '**/scripts/ruflo-hook.sh'
|
||||
pull_request:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'v3/**'
|
||||
- 'plugins/ruflo-core/scripts/witness/**'
|
||||
- 'plugins/ruflo-core/scripts/test-hooks.mjs'
|
||||
- 'plugins/ruflo-core/hooks/hooks.json'
|
||||
- 'scripts/**'
|
||||
- '**/hooks/hooks.json'
|
||||
- '**/scripts/ruflo-hook.sh'
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
@@ -475,12 +481,10 @@ jobs:
|
||||
plugin-package-audit:
|
||||
# Regression guard for #1902/#1903/#1904 — plugin package.json install
|
||||
# safety. Checks: (A) no unpublished @claude-flow/* hard dep / non-optional
|
||||
# peer (#1903 ruvector-upstream class), (B) no bare-stable peer range that
|
||||
# can't resolve a 3.x prerelease publish (#1902), (C) every main/module/
|
||||
# exports path is covered by `files`, (D) after building each plugin,
|
||||
# every main/module/exports path exists on disk (#1904 — exports.import →
|
||||
# ./dist/index.mjs but the build only emits .js/.cjs). The build step is
|
||||
# what makes check D live; without it the script does A/B/C only.
|
||||
# peer, (B) no bare-stable peer range that can't resolve a 3.x prerelease
|
||||
# publish, (C) every main/module/exports path is covered by `files`,
|
||||
# (D) after building each plugin, every main/module/exports path exists on
|
||||
# disk (#1904). The build step is what makes check D live.
|
||||
name: Plugin package install-safety (#1902/#1903/#1904)
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -505,9 +509,6 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
pnpm install --frozen-lockfile
|
||||
# Build each plugin that has a build script. --no-bail tolerates an
|
||||
# unrelated build failure; check D simply won't run for a plugin
|
||||
# whose dist/ is absent.
|
||||
for d in plugins/*/; do
|
||||
if [ -f "$d/package.json" ] && node -e "process.exit(require('./'+process.argv[1]+'package.json').scripts?.build?0:1)" "$d"; then
|
||||
echo "::group::build $d"
|
||||
@@ -520,6 +521,40 @@ jobs:
|
||||
shell: bash
|
||||
run: node scripts/audit-plugin-packages.mjs
|
||||
|
||||
hook-command-audit:
|
||||
# Regression guard for #1921 (and #1147) — plugin hooks.json must not
|
||||
# invoke a bare `npx <pkg>@alpha hooks …` per fire. The fix is
|
||||
# scripts/ruflo-hook.sh (prefers a local `ruflo`/`claude-flow` binary,
|
||||
# falls back to `npx --prefer-offline`, always exits 0).
|
||||
name: Hook-command install safety (#1921)
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '22'
|
||||
|
||||
- name: Run hook-command audit
|
||||
shell: bash
|
||||
run: node scripts/audit-hook-commands.mjs
|
||||
|
||||
- name: Lint the ruflo-hook shims
|
||||
shell: bash
|
||||
run: |
|
||||
# Every shim must be valid bash and exit 0 even when no CLI is
|
||||
# reachable (the #1921 contract). Probe with an empty PATH (invoke
|
||||
# bash by full path since PATH= can't find it otherwise).
|
||||
BASH="$(command -v bash)"
|
||||
for sh in $(git ls-files '**/scripts/ruflo-hook.sh'); do
|
||||
echo "checking $sh"
|
||||
bash -n "$sh"
|
||||
PATH= "$BASH" "$sh" modify-bash </dev/null || { echo "::error::$sh did not exit 0 with no CLI on PATH"; exit 1; }
|
||||
done
|
||||
|
||||
witness-verify:
|
||||
# Cryptographic regression guard: runs `ruflo verify --manifest` against
|
||||
# the local build to confirm every documented fix in verification.md.json
|
||||
@@ -546,7 +581,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
needs: [smoke-install-no-bsqlite, plugin-hooks-smoke, mcp-protocol-smoke, memory-import-smoke, tool-descriptions-audit, mcp-roundtrip-smoke, plugin-package-audit]
|
||||
needs: [smoke-install-no-bsqlite, plugin-hooks-smoke, mcp-protocol-smoke, memory-import-smoke, tool-descriptions-audit, mcp-roundtrip-smoke, plugin-package-audit, hook-command-audit]
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
|
||||
+16
-15
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"$schema": "https://code.claude.com/schemas/hooks.json",
|
||||
"description": "Claude Flow hooks configuration — uses stdin-jq-xargs pattern to prevent shell-injection when tool inputs contain quotes / redirects / special chars (#1747).",
|
||||
"_security_note": "All commands read the hook payload from stdin (Claude Code passes a JSON object), extract fields with jq, and pass them to npx as a single argv element via xargs -0. This bypasses shell re-parsing entirely. DO NOT inline $TOOL_INPUT_* / $PROMPT / $TOOL_NAME directly in a quoted command string — interpolation is not shell-safe (creates empty files at CWD when input contains '>' redirects).",
|
||||
"description": "Claude Flow hooks configuration — uses stdin-jq-xargs pattern to prevent shell-injection when tool inputs contain quotes / redirects / special chars (#1747). Hook subcommands run via scripts/ruflo-hook.sh (#1921).",
|
||||
"_security_note": "All commands read the hook payload from stdin (Claude Code passes a JSON object), extract fields with jq, and pass them to the CLI as a single argv element via xargs -0. This bypasses shell re-parsing entirely. DO NOT inline $TOOL_INPUT_* / $PROMPT / $TOOL_NAME directly in a quoted command string — interpolation is not shell-safe (creates empty files at CWD when input contains '>' redirects).",
|
||||
"_resilience_note": "#1921 — hook subcommands invoke scripts/ruflo-hook.sh (resilient shim): prefers a locally-installed `ruflo`/`claude-flow` binary, falls back to `npx --prefer-offline`, always exits 0. The trailing `|| true` on each pipeline guards the case where $CLAUDE_PLUGIN_ROOT is unset. DO NOT revert to a bare `npx <pkg>@alpha hooks …` per fire.",
|
||||
"hooks": {
|
||||
"PreToolUse": [
|
||||
{
|
||||
@@ -10,7 +11,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "cat | jq -r '.tool_input.file_path // .tool_input.path // empty' | tr '\\n' '\\0' | xargs -0 -I {} npx claude-flow@alpha hooks pre-edit --file '{}'",
|
||||
"command": "cat | jq -r '.tool_input.file_path // .tool_input.path // empty' | tr '\\n' '\\0' | xargs -0 -I {} \"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" pre-edit --file '{}' || true",
|
||||
"timeout": 5000,
|
||||
"continueOnError": true
|
||||
}
|
||||
@@ -22,7 +23,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "cat | jq -r '.tool_input.command // empty' | tr '\\n' '\\0' | xargs -0 -I {} npx claude-flow@alpha hooks pre-command --command '{}'",
|
||||
"command": "cat | jq -r '.tool_input.command // empty' | tr '\\n' '\\0' | xargs -0 -I {} \"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" pre-command --command '{}' || true",
|
||||
"timeout": 3000,
|
||||
"continueOnError": true
|
||||
}
|
||||
@@ -34,7 +35,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "cat | jq -r '.tool_input.description // empty | .[:200]' | tr '\\n' '\\0' | xargs -0 -I {} npx claude-flow@alpha hooks pre-task --description '{}'",
|
||||
"command": "cat | jq -r '.tool_input.description // empty | .[:200]' | tr '\\n' '\\0' | xargs -0 -I {} \"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" pre-task --description '{}' || true",
|
||||
"timeout": 5000,
|
||||
"continueOnError": true
|
||||
}
|
||||
@@ -46,7 +47,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "cat | jq -r '.tool_input.pattern // .tool_input.query // empty' | tr '\\n' '\\0' | xargs -0 -I {} npx claude-flow@alpha hooks pre-search --query '{}'",
|
||||
"command": "cat | jq -r '.tool_input.pattern // .tool_input.query // empty' | tr '\\n' '\\0' | xargs -0 -I {} \"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" pre-search --query '{}' || true",
|
||||
"timeout": 2000,
|
||||
"continueOnError": true
|
||||
}
|
||||
@@ -58,7 +59,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "cat | jq -r '.tool_name // empty' | tr '\\n' '\\0' | xargs -0 -I {} npx claude-flow@alpha hooks mcp-pre --tool '{}'",
|
||||
"command": "cat | jq -r '.tool_name // empty' | tr '\\n' '\\0' | xargs -0 -I {} \"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" mcp-pre --tool '{}' || true",
|
||||
"timeout": 3000,
|
||||
"continueOnError": true
|
||||
}
|
||||
@@ -72,7 +73,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "cat | jq -r '.tool_input.file_path // .tool_input.path // empty' | tr '\\n' '\\0' | xargs -0 -I {} npx claude-flow@alpha hooks post-edit --file '{}' --train-patterns",
|
||||
"command": "cat | jq -r '.tool_input.file_path // .tool_input.path // empty' | tr '\\n' '\\0' | xargs -0 -I {} \"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" post-edit --file '{}' --train-patterns || true",
|
||||
"timeout": 5000,
|
||||
"continueOnError": true
|
||||
}
|
||||
@@ -84,7 +85,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "cat | jq -r '.tool_input.command // empty' | tr '\\n' '\\0' | xargs -0 -I {} npx claude-flow@alpha hooks post-command --command '{}' --track-metrics true --store-results true",
|
||||
"command": "cat | jq -r '.tool_input.command // empty' | tr '\\n' '\\0' | xargs -0 -I {} \"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" post-command --command '{}' --track-metrics true --store-results true || true",
|
||||
"timeout": 3000,
|
||||
"continueOnError": true
|
||||
}
|
||||
@@ -96,7 +97,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "cat | jq -r '.tool_response.agent_id // .tool_response.task_id // empty' | tr '\\n' '\\0' | xargs -0 -I {} npx claude-flow@alpha hooks post-task --task-id '{}' --analyze-performance",
|
||||
"command": "cat | jq -r '.tool_response.agent_id // .tool_response.task_id // empty' | tr '\\n' '\\0' | xargs -0 -I {} \"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" post-task --task-id '{}' --analyze-performance || true",
|
||||
"timeout": 5000,
|
||||
"continueOnError": true
|
||||
}
|
||||
@@ -108,7 +109,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "cat | jq -r '.tool_input.pattern // .tool_input.query // empty' | tr '\\n' '\\0' | xargs -0 -I {} npx claude-flow@alpha hooks post-search --query '{}' --cache-results",
|
||||
"command": "cat | jq -r '.tool_input.pattern // .tool_input.query // empty' | tr '\\n' '\\0' | xargs -0 -I {} \"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" post-search --query '{}' --cache-results || true",
|
||||
"timeout": 2000,
|
||||
"continueOnError": true
|
||||
}
|
||||
@@ -120,7 +121,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "cat | jq -r '.tool_name // empty' | tr '\\n' '\\0' | xargs -0 -I {} npx claude-flow@alpha hooks mcp-post --tool '{}'",
|
||||
"command": "cat | jq -r '.tool_name // empty' | tr '\\n' '\\0' | xargs -0 -I {} \"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" mcp-post --tool '{}' || true",
|
||||
"timeout": 3000,
|
||||
"continueOnError": true
|
||||
}
|
||||
@@ -133,7 +134,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "cat | jq -r '.prompt // empty' | tr '\\n' '\\0' | xargs -0 -I {} npx claude-flow@alpha hooks route --task '{}' --include-explanation",
|
||||
"command": "cat | jq -r '.prompt // empty' | tr '\\n' '\\0' | xargs -0 -I {} \"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" route --task '{}' --include-explanation || true",
|
||||
"timeout": 5000,
|
||||
"continueOnError": true
|
||||
}
|
||||
@@ -146,7 +147,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "cat | jq -r '.session_id // empty' | tr '\\n' '\\0' | xargs -0 -I {} npx claude-flow@alpha hooks session-start --session-id '{}' --load-context",
|
||||
"command": "cat | jq -r '.session_id // empty' | tr '\\n' '\\0' | xargs -0 -I {} \"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" session-start --session-id '{}' --load-context || true",
|
||||
"timeout": 10000,
|
||||
"continueOnError": true
|
||||
}
|
||||
@@ -181,7 +182,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "cat | jq -r '.message // empty' | tr '\\n' '\\0' | xargs -0 -I {} npx claude-flow@alpha hooks notify --message '{}' --swarm-status",
|
||||
"command": "cat | jq -r '.message // empty' | tr '\\n' '\\0' | xargs -0 -I {} \"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" notify --message '{}' --swarm-status || true",
|
||||
"timeout": 3000,
|
||||
"continueOnError": true
|
||||
}
|
||||
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env bash
|
||||
# ruflo-hook.sh — resilient invoker for ruflo CLI hook subcommands (#1921).
|
||||
#
|
||||
# Hooks fire on EVERY PreToolUse / PostToolUse / Stop. A bare
|
||||
# `npx <pkg>@alpha hooks …` re-resolves the @alpha dist-tag and re-installs
|
||||
# from cold cache on every fire, and when the install crashes (e.g. an
|
||||
# arborist `Invalid Version` on npm 10.8.x) the user sees a hook error in
|
||||
# Claude Code after every turn. This shim:
|
||||
# 1. prefers an already-installed `ruflo` / `claude-flow` binary (no npx,
|
||||
# no install) — the common case for plugin users;
|
||||
# 2. falls back to `npx --prefer-offline` so a populated npx cache is
|
||||
# reused instead of a fresh registry resolve;
|
||||
# 3. ALWAYS exits 0 — hook subcommands are best-effort telemetry/learning;
|
||||
# a failure must never surface an error or block a turn.
|
||||
#
|
||||
# stdin (the hook event JSON) is passed through to the CLI unchanged.
|
||||
# Usage: ruflo-hook.sh <hook-subcommand> [args…] (the literal `hooks`
|
||||
# word is prepended here, so callers pass e.g. `post-edit -f "$FILE" -s true`).
|
||||
|
||||
# Swallow all diagnostics — nothing this script prints should reach Claude Code.
|
||||
exec 2>/dev/null
|
||||
|
||||
run() { "$@" || true; }
|
||||
|
||||
if command -v ruflo >/dev/null 2>&1; then
|
||||
run ruflo hooks "$@"
|
||||
elif command -v claude-flow >/dev/null 2>&1; then
|
||||
run claude-flow hooks "$@"
|
||||
else
|
||||
run npx --prefer-offline --yes ruflo@alpha hooks "$@"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"_note": "#1921 — hook commands invoke scripts/ruflo-hook.sh (resilient shim): prefers a locally-installed `ruflo`/`claude-flow` binary, falls back to `npx --prefer-offline`, and always exits 0 so a CLI/install failure (e.g. arborist `Invalid Version` on npm 10.8.x) never surfaces an error in Claude Code or blocks a turn. The trailing `|| true` guards the case where $CLAUDE_PLUGIN_ROOT is unset (older Claude Code) — the hook then no-ops silently. DO NOT revert to a bare `npx <pkg>@alpha hooks …` per fire.",
|
||||
"hooks": {
|
||||
"PreToolUse": [
|
||||
{
|
||||
@@ -6,7 +7,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "cat | npx ruflo@alpha hooks modify-bash"
|
||||
"command": "\"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" modify-bash || true"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -15,7 +16,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "cat | npx ruflo@alpha hooks modify-file"
|
||||
"command": "\"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" modify-file || true"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -26,7 +27,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "/bin/bash -c 'INPUT=$(cat); CMD=$(printf %s \"$INPUT\" | jq -r \".tool_input.command // empty\"); [ -z \"$CMD\" ] && exit 0; EXIT=$(printf %s \"$INPUT\" | jq -r \".tool_response.exit_code // 0\"); SUCCESS=$([ \"$EXIT\" = \"0\" ] && echo true || echo false); npx ruflo@alpha hooks post-command -c \"$CMD\" -s \"$SUCCESS\" -e \"$EXIT\"'"
|
||||
"command": "/bin/bash -c 'INPUT=$(cat); CMD=$(printf %s \"$INPUT\" | jq -r \".tool_input.command // empty\"); [ -z \"$CMD\" ] && exit 0; EXIT=$(printf %s \"$INPUT\" | jq -r \".tool_response.exit_code // 0\"); SUCCESS=$([ \"$EXIT\" = \"0\" ] && echo true || echo false); \"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" post-command -c \"$CMD\" -s \"$SUCCESS\" -e \"$EXIT\" || true'"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -35,7 +36,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "/bin/bash -c 'INPUT=$(cat); FILE=$(printf %s \"$INPUT\" | jq -r \".tool_input.file_path // .tool_input.path // empty\"); [ -z \"$FILE\" ] && exit 0; npx ruflo@alpha hooks post-edit -f \"$FILE\" -s true'"
|
||||
"command": "/bin/bash -c 'INPUT=$(cat); FILE=$(printf %s \"$INPUT\" | jq -r \".tool_input.file_path // .tool_input.path // empty\"); [ -z \"$FILE\" ] && exit 0; \"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" post-edit -f \"$FILE\" -s true || true'"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -65,7 +66,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "npx ruflo@alpha hooks session-end --generate-summary true --persist-state true --export-metrics true"
|
||||
"command": "\"${CLAUDE_PLUGIN_ROOT}/scripts/ruflo-hook.sh\" session-end --generate-summary true --persist-state true --export-metrics true || true"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env bash
|
||||
# ruflo-hook.sh — resilient invoker for ruflo CLI hook subcommands (#1921).
|
||||
#
|
||||
# Hooks fire on EVERY PreToolUse / PostToolUse / Stop. A bare
|
||||
# `npx <pkg>@alpha hooks …` re-resolves the @alpha dist-tag and re-installs
|
||||
# from cold cache on every fire, and when the install crashes (e.g. an
|
||||
# arborist `Invalid Version` on npm 10.8.x) the user sees a hook error in
|
||||
# Claude Code after every turn. This shim:
|
||||
# 1. prefers an already-installed `ruflo` / `claude-flow` binary (no npx,
|
||||
# no install) — the common case for plugin users;
|
||||
# 2. falls back to `npx --prefer-offline` so a populated npx cache is
|
||||
# reused instead of a fresh registry resolve;
|
||||
# 3. ALWAYS exits 0 — hook subcommands are best-effort telemetry/learning;
|
||||
# a failure must never surface an error or block a turn.
|
||||
#
|
||||
# stdin (the hook event JSON) is passed through to the CLI unchanged.
|
||||
# Usage: ruflo-hook.sh <hook-subcommand> [args…] (the literal `hooks`
|
||||
# word is prepended here, so callers pass e.g. `post-edit -f "$FILE" -s true`).
|
||||
|
||||
# Swallow all diagnostics — nothing this script prints should reach Claude Code.
|
||||
exec 2>/dev/null
|
||||
|
||||
run() { "$@" || true; }
|
||||
|
||||
if command -v ruflo >/dev/null 2>&1; then
|
||||
run ruflo hooks "$@"
|
||||
elif command -v claude-flow >/dev/null 2>&1; then
|
||||
run claude-flow hooks "$@"
|
||||
else
|
||||
run npx --prefer-offline --yes ruflo@alpha hooks "$@"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -47,7 +47,16 @@ const post = hooks.hooks?.PostToolUse ?? [];
|
||||
const findHook = (matcher) => {
|
||||
const hit = post.find(h => h.matcher === matcher);
|
||||
if (!hit) throw new Error(`No PostToolUse hook with matcher=${matcher}`);
|
||||
return hit.hooks[0].command.replace(/npx ruflo@alpha/g, cliInvoke);
|
||||
return hit.hooks[0].command
|
||||
// legacy form: `npx ruflo@alpha hooks …`
|
||||
.replace(/npx ruflo@alpha/g, cliInvoke)
|
||||
// #1921 form: hook subcommands go through scripts/ruflo-hook.sh (which
|
||||
// prepends `hooks`). Bypass the shim here and call the built CLI directly
|
||||
// so the test exercises the same flag wiring users hit, pinned to the
|
||||
// build under test. Also drop the shim's `|| true` so exit codes are
|
||||
// still asserted (the shim makes failures non-fatal in production).
|
||||
.replace(/"\$\{CLAUDE_PLUGIN_ROOT\}\/scripts\/ruflo-hook\.sh"/g, `${cliInvoke} hooks`)
|
||||
.replace(/\s*\|\|\s*true(\s*')/g, '$1');
|
||||
};
|
||||
|
||||
const cmdBash = findHook('Bash');
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Hook-command install-safety audit — regression guard for #1921 (and #1147).
|
||||
*
|
||||
* Hooks fire on EVERY PreToolUse / PostToolUse / Stop / etc. A hook `command`
|
||||
* that does a bare `npx <pkg>@alpha …` re-resolves the dist-tag and re-installs
|
||||
* from cold cache on every fire; when that install crashes (e.g. an arborist
|
||||
* `Invalid Version` on npm 10.8.x) the user sees a hook error in Claude Code
|
||||
* after every turn. The fix: invoke `scripts/ruflo-hook.sh` (prefers a locally-
|
||||
* installed `ruflo`/`claude-flow` binary, falls back to `npx --prefer-offline`,
|
||||
* always exits 0). This guard fails CI if any hook `command` regresses.
|
||||
*
|
||||
* Rules, per hook `command` string:
|
||||
* 1. If it invokes `npx`, it MUST also pass `--prefer-offline`.
|
||||
* 2. If it invokes `npx` or `scripts/ruflo-hook.sh`, it MUST be non-fatal:
|
||||
* end with `|| true` / `|| exit 0`, or the hook entry must set
|
||||
* `continueOnError: true`.
|
||||
*
|
||||
* Usage:
|
||||
* node scripts/audit-hook-commands.mjs # exit 1 on any violation
|
||||
* node scripts/audit-hook-commands.mjs --json # machine-readable report
|
||||
*/
|
||||
|
||||
import { readFileSync, readdirSync } from 'node:fs';
|
||||
import { join, relative } from 'node:path';
|
||||
|
||||
const REPO_ROOT = process.cwd();
|
||||
const JSON_OUT = process.argv.includes('--json');
|
||||
|
||||
function findHooksFiles(dir, out = []) {
|
||||
let entries;
|
||||
try { entries = readdirSync(dir, { withFileTypes: true }); } catch { return out; }
|
||||
for (const e of entries) {
|
||||
if (e.name === 'node_modules' || e.name === '.git') continue;
|
||||
const p = join(dir, e.name);
|
||||
if (e.isDirectory()) findHooksFiles(p, out);
|
||||
else if (e.isFile() && /[\\/]hooks[\\/]hooks\.json$/.test(p)) out.push(p);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function collectCommands(hooksJson) {
|
||||
const out = [];
|
||||
const root = hooksJson && hooksJson.hooks;
|
||||
if (!root || typeof root !== 'object') return out;
|
||||
for (const [event, entries] of Object.entries(root)) {
|
||||
if (!Array.isArray(entries)) continue;
|
||||
for (const entry of entries) {
|
||||
const matcher = entry && entry.matcher;
|
||||
const list = entry && Array.isArray(entry.hooks) ? entry.hooks : [];
|
||||
for (let idx = 0; idx < list.length; idx++) {
|
||||
const h = list[idx];
|
||||
if (h && h.type === 'command' && typeof h.command === 'string') {
|
||||
out.push({ event, matcher, idx, command: h.command, continueOnError: h.continueOnError === true });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
const NPX_RE = /(^|[\s;&|(])npx\b/;
|
||||
const PREFER_OFFLINE_RE = /--prefer-offline\b/;
|
||||
const SHIM_RE = /ruflo-hook\.sh/;
|
||||
const NONFATAL_RE = /\|\|\s*(true|exit\s+0)\b/;
|
||||
|
||||
const files = findHooksFiles(REPO_ROOT);
|
||||
const violations = [];
|
||||
|
||||
for (const file of files) {
|
||||
const rel = relative(REPO_ROOT, file);
|
||||
let parsed;
|
||||
try { parsed = JSON.parse(readFileSync(file, 'utf-8')); }
|
||||
catch (e) { violations.push({ file: rel, where: rel, reason: `invalid JSON: ${e.message}` }); continue; }
|
||||
|
||||
for (const { event, matcher, idx, command, continueOnError } of collectCommands(parsed)) {
|
||||
const where = `${rel} :: ${event}${matcher ? ` [${matcher}]` : ''} #${idx}`;
|
||||
const usesNpx = NPX_RE.test(command);
|
||||
const usesShim = SHIM_RE.test(command);
|
||||
|
||||
if (usesNpx && !PREFER_OFFLINE_RE.test(command)) {
|
||||
violations.push({
|
||||
file: rel, where,
|
||||
reason: 'invokes `npx` without `--prefer-offline` — re-resolves the dist-tag and re-installs from cold cache on every hook fire (#1921). Use scripts/ruflo-hook.sh, or add `--prefer-offline`.',
|
||||
command,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
if ((usesNpx || usesShim) && !NONFATAL_RE.test(command) && !continueOnError) {
|
||||
violations.push({
|
||||
file: rel, where,
|
||||
reason: 'invokes the CLI but is not non-fatal — a CLI/install failure surfaces a hook error in Claude Code (#1921). Append `|| true` (or set `continueOnError: true`).',
|
||||
command,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const report = { scannedFiles: files.length, violationCount: violations.length, violations };
|
||||
|
||||
if (JSON_OUT) {
|
||||
console.log(JSON.stringify(report, null, 2));
|
||||
} else {
|
||||
console.log(`hook-command audit — scanned ${files.length} hooks.json file(s)`);
|
||||
if (violations.length === 0) {
|
||||
console.log(' ✓ no install-safety violations');
|
||||
} else {
|
||||
for (const v of violations) {
|
||||
console.log(` ✗ ${v.where}`);
|
||||
console.log(` ${v.reason}`);
|
||||
if (v.command) console.log(` command: ${v.command.length > 200 ? v.command.slice(0, 200) + '…' : v.command}`);
|
||||
}
|
||||
console.log(`\n${violations.length} violation(s)`);
|
||||
}
|
||||
}
|
||||
|
||||
process.exit(violations.length > 0 ? 1 : 0);
|
||||
@@ -20,3 +20,5 @@
|
||||
{"v":1,"commit":"b680fca85aac08ec59880197f8f6af2042da8b6b","issuedAt":"2026-05-12T04:39:26.400Z","branch":"fix/1916-agent-logs-hive-resolution","os":"macos","manifestHash":"b4e846d271b190a65db53c38ddaf1e0984c01ac061f0b577020397736d394159","summary":{"totalFixes":108,"verified":107,"missing":0},"fixes":{"F1":{"sha256":"93f4d2f94710eed90e0bcc9b8823e91f1a4b894221fae1972c1f6745d90b622d","markerVerified":true},"F2":{"sha256":"93f4d2f94710eed90e0bcc9b8823e91f1a4b894221fae1972c1f6745d90b622d","markerVerified":true},"F3":{"sha256":"8482312f5b447ae6008d13b0873945f026bf540e559195cf961b948a94520678","markerVerified":true},"F4":{"sha256":"666141cf59c2e75c9f65fe50eff85076a96d820bddceaba79c0b67a4469b3bb5","markerVerified":true},"F5":{"sha256":"48032e13d70927a6448d75e04f8f055b0268aaada8bef3e6926bf3acafd493fd","markerVerified":true},"F6":{"sha256":"159365d8f876d52b94a3c1420e9ac3e6da442a4d0fa0bcd6de292b6282113cee","markerVerified":true},"F7":{"sha256":"ae4b5e05735741b01cbc6c9e4af3953a02b4ebf78faf78fe06f9130420f4f301","markerVerified":true},"F8":{"sha256":"8151d83f6b1abe7a9139db5c9d884c42c1b3faf986dc712c0fbd43a22af39f51","markerVerified":true},"F9":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"F10":{"sha256":"93f4d2f94710eed90e0bcc9b8823e91f1a4b894221fae1972c1f6745d90b622d","markerVerified":true},"F11":{"sha256":"acb66c459f9eb3a34686567b5d4f9bd834b4e874e9a1229256baebfd15c4ea5c","markerVerified":true},"F12":{"sha256":"0c68ebca896806de2aa052ef44a0de13e9df3becef44721857c7c99567403d80","markerVerified":true},"#1697":{"sha256":"14345e0180e5c4649b5a2169b094c8e05d97c54fe79902c8eef0ebf7c18715fb","markerVerified":true},"#1698":{"sha256":"2cb57b6fb38bb4722eebd169f4b6056f1b6f69ba0adde9978bcd9e03f83d43ab","markerVerified":true},"#1691":{"sha256":"8fe7b53ad914532474b77cf419b6e64ee60e12562062342e9cf9fd5eee8c8498","markerVerified":true},"#1721":{"sha256":"862f40e5c7b45a0ce35bbe438add312cf7d155e527ee49bed62ee9b58d0cd526","markerVerified":true},"ADR-094":{"sha256":"1d2225e7422f8a2d47d39100324d5e4ac2d29c55e8e72b02f5e4a7a113d45be2","markerVerified":true},"G1":{"sha256":"2bc49c38b14d43a0329bf5d84913528851ef1c48ab32b8c8c1c40f83c062fc7f","markerVerified":true},"G3":{"sha256":"442839dca2d6177f2567dccaf1f48306c304cbca0659c477501604289f7ad5a6","markerVerified":true},"G4":{"sha256":"12fce07f6458aff5db210b0ba50104fa9b2dd52c85b5e9071b48c2899451c631","markerVerified":true},"G6":{"sha256":"84a6159b384b8118f0beaa1089c417cab6d1116cd77d3882a607715ef7679ea8","markerVerified":true},"G7-gnn":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G7-rvf":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G7-mut":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G7-att":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G7-gvb":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G2":{"sha256":"9f751aaee838a85e7b2371bbd73dccb5cb89c6b7751496b18d33d8b8a559de19","markerVerified":true},"CAP-MCP-agent-tools":{"sha256":"a182a61809b5480e9eb4139ed8fa3b8e471201d338be4e086578b4e2e325302a","markerVerified":true},"CAP-MCP-agentdb-tools":{"sha256":"666141cf59c2e75c9f65fe50eff85076a96d820bddceaba79c0b67a4469b3bb5","markerVerified":true},"CAP-MCP-analyze-tools":{"sha256":"d665ca78dcb753e7803d37a331ae363ba5e4fea0c90e828171d264a425a638da","markerVerified":true},"CAP-MCP-autopilot-tools":{"sha256":"1f1dcf3c7660b9ab66df49bacfdf2c7f5a883554d98b416a2780d5226e643df2","markerVerified":true},"CAP-MCP-browser-tools":{"sha256":"5ea5f63c99ee22bccb6fbd4d872e44f47ec7f0ad14ceed4f18014b95f94f75f7","markerVerified":true},"CAP-MCP-claims-tools":{"sha256":"89908d601a21e1a0dca0bd611af61b1d2150010f6015216849122775e6940808","markerVerified":true},"CAP-MCP-config-tools":{"sha256":"0c68ebca896806de2aa052ef44a0de13e9df3becef44721857c7c99567403d80","markerVerified":true},"CAP-MCP-coordination-tools":{"sha256":"ae4b5e05735741b01cbc6c9e4af3953a02b4ebf78faf78fe06f9130420f4f301","markerVerified":true},"CAP-MCP-daa-tools":{"sha256":"2beb8ec07d784cf7f1a61b4cd2090a8e65934893c2a31a3afcd406774d2a8537","markerVerified":true},"CAP-MCP-embeddings-tools":{"sha256":"48032e13d70927a6448d75e04f8f055b0268aaada8bef3e6926bf3acafd493fd","markerVerified":true},"CAP-MCP-github-tools":{"sha256":"951b66082ba309505eaf4e3588104681f5581ec5e0c8d6daf6a7befac596db37","markerVerified":true},"CAP-MCP-guidance-tools":{"sha256":"856f7b0439a4dfdafab88589faf5cbe42c8fbd4004532fe507ec3e3e42af9e12","markerVerified":true},"CAP-MCP-hive-mind-tools":{"sha256":"8482312f5b447ae6008d13b0873945f026bf540e559195cf961b948a94520678","markerVerified":true},"CAP-MCP-hooks-tools":{"sha256":"93f4d2f94710eed90e0bcc9b8823e91f1a4b894221fae1972c1f6745d90b622d","markerVerified":true},"CAP-MCP-memory-tools":{"sha256":"37d929df892035fe94a48cd43a074c9c773e9dc031ab56d9Line truncated
|
||||
{"v":1,"commit":"b680fca85aac08ec59880197f8f6af2042da8b6b","issuedAt":"2026-05-12T04:39:59.412Z","branch":"fix/1916-agent-logs-hive-resolution","os":"macos","manifestHash":"867a536d3d605716484e79d49755eb9cd293694826d3b51e1190e90599107b61","summary":{"totalFixes":108,"verified":108,"missing":0},"fixes":{"F1":{"sha256":"93f4d2f94710eed90e0bcc9b8823e91f1a4b894221fae1972c1f6745d90b622d","markerVerified":true},"F2":{"sha256":"93f4d2f94710eed90e0bcc9b8823e91f1a4b894221fae1972c1f6745d90b622d","markerVerified":true},"F3":{"sha256":"8482312f5b447ae6008d13b0873945f026bf540e559195cf961b948a94520678","markerVerified":true},"F4":{"sha256":"666141cf59c2e75c9f65fe50eff85076a96d820bddceaba79c0b67a4469b3bb5","markerVerified":true},"F5":{"sha256":"48032e13d70927a6448d75e04f8f055b0268aaada8bef3e6926bf3acafd493fd","markerVerified":true},"F6":{"sha256":"159365d8f876d52b94a3c1420e9ac3e6da442a4d0fa0bcd6de292b6282113cee","markerVerified":true},"F7":{"sha256":"ae4b5e05735741b01cbc6c9e4af3953a02b4ebf78faf78fe06f9130420f4f301","markerVerified":true},"F8":{"sha256":"8151d83f6b1abe7a9139db5c9d884c42c1b3faf986dc712c0fbd43a22af39f51","markerVerified":true},"F9":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"F10":{"sha256":"93f4d2f94710eed90e0bcc9b8823e91f1a4b894221fae1972c1f6745d90b622d","markerVerified":true},"F11":{"sha256":"acb66c459f9eb3a34686567b5d4f9bd834b4e874e9a1229256baebfd15c4ea5c","markerVerified":true},"F12":{"sha256":"0c68ebca896806de2aa052ef44a0de13e9df3becef44721857c7c99567403d80","markerVerified":true},"#1697":{"sha256":"14345e0180e5c4649b5a2169b094c8e05d97c54fe79902c8eef0ebf7c18715fb","markerVerified":true},"#1698":{"sha256":"2cb57b6fb38bb4722eebd169f4b6056f1b6f69ba0adde9978bcd9e03f83d43ab","markerVerified":true},"#1691":{"sha256":"6b600ec62ef9a3898fd3c606c23034a10a005c0330d0dac43b29f6d2abc2ec8e","markerVerified":true},"#1721":{"sha256":"862f40e5c7b45a0ce35bbe438add312cf7d155e527ee49bed62ee9b58d0cd526","markerVerified":true},"ADR-094":{"sha256":"1d2225e7422f8a2d47d39100324d5e4ac2d29c55e8e72b02f5e4a7a113d45be2","markerVerified":true},"G1":{"sha256":"2bc49c38b14d43a0329bf5d84913528851ef1c48ab32b8c8c1c40f83c062fc7f","markerVerified":true},"G3":{"sha256":"442839dca2d6177f2567dccaf1f48306c304cbca0659c477501604289f7ad5a6","markerVerified":true},"G4":{"sha256":"12fce07f6458aff5db210b0ba50104fa9b2dd52c85b5e9071b48c2899451c631","markerVerified":true},"G6":{"sha256":"84a6159b384b8118f0beaa1089c417cab6d1116cd77d3882a607715ef7679ea8","markerVerified":true},"G7-gnn":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G7-rvf":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G7-mut":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G7-att":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G7-gvb":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G2":{"sha256":"9f751aaee838a85e7b2371bbd73dccb5cb89c6b7751496b18d33d8b8a559de19","markerVerified":true},"CAP-MCP-agent-tools":{"sha256":"a182a61809b5480e9eb4139ed8fa3b8e471201d338be4e086578b4e2e325302a","markerVerified":true},"CAP-MCP-agentdb-tools":{"sha256":"666141cf59c2e75c9f65fe50eff85076a96d820bddceaba79c0b67a4469b3bb5","markerVerified":true},"CAP-MCP-analyze-tools":{"sha256":"d665ca78dcb753e7803d37a331ae363ba5e4fea0c90e828171d264a425a638da","markerVerified":true},"CAP-MCP-autopilot-tools":{"sha256":"1f1dcf3c7660b9ab66df49bacfdf2c7f5a883554d98b416a2780d5226e643df2","markerVerified":true},"CAP-MCP-browser-tools":{"sha256":"5ea5f63c99ee22bccb6fbd4d872e44f47ec7f0ad14ceed4f18014b95f94f75f7","markerVerified":true},"CAP-MCP-claims-tools":{"sha256":"89908d601a21e1a0dca0bd611af61b1d2150010f6015216849122775e6940808","markerVerified":true},"CAP-MCP-config-tools":{"sha256":"0c68ebca896806de2aa052ef44a0de13e9df3becef44721857c7c99567403d80","markerVerified":true},"CAP-MCP-coordination-tools":{"sha256":"ae4b5e05735741b01cbc6c9e4af3953a02b4ebf78faf78fe06f9130420f4f301","markerVerified":true},"CAP-MCP-daa-tools":{"sha256":"2beb8ec07d784cf7f1a61b4cd2090a8e65934893c2a31a3afcd406774d2a8537","markerVerified":true},"CAP-MCP-embeddings-tools":{"sha256":"48032e13d70927a6448d75e04f8f055b0268aaada8bef3e6926bf3acafd493fd","markerVerified":true},"CAP-MCP-github-tools":{"sha256":"951b66082ba309505eaf4e3588104681f5581ec5e0c8d6daf6a7befac596db37","markerVerified":true},"CAP-MCP-guidance-tools":{"sha256":"856f7b0439a4dfdafab88589faf5cbe42c8fbd4004532fe507ec3e3e42af9e12","markerVerified":true},"CAP-MCP-hive-mind-tools":{"sha256":"8482312f5b447ae6008d13b0873945f026bf540e559195cf961b948a94520678","markerVerified":true},"CAP-MCP-hooks-tools":{"sha256":"93f4d2f94710eed90e0bcc9b8823e91f1a4b894221fae1972c1f6745d90b622d","markerVerified":true},"CAP-MCP-memory-tools":{"sha256":"37d929df892035fe94a48cd43a074c9c773e9dc031ab56d9Line truncated
|
||||
{"v":1,"commit":"31f22ff9a92154952b8d9e417a25034bdf08de08","issuedAt":"2026-05-12T04:44:05.086Z","branch":"HEAD","os":"macos","manifestHash":"a081f02f53f33c5a008cd06177cb1f8a4de08ac7183312877d57c0ca95018192","summary":{"totalFixes":110,"verified":110,"missing":0},"fixes":{"F1":{"sha256":"93f4d2f94710eed90e0bcc9b8823e91f1a4b894221fae1972c1f6745d90b622d","markerVerified":true},"F2":{"sha256":"93f4d2f94710eed90e0bcc9b8823e91f1a4b894221fae1972c1f6745d90b622d","markerVerified":true},"F3":{"sha256":"8482312f5b447ae6008d13b0873945f026bf540e559195cf961b948a94520678","markerVerified":true},"F4":{"sha256":"666141cf59c2e75c9f65fe50eff85076a96d820bddceaba79c0b67a4469b3bb5","markerVerified":true},"F5":{"sha256":"48032e13d70927a6448d75e04f8f055b0268aaada8bef3e6926bf3acafd493fd","markerVerified":true},"F6":{"sha256":"159365d8f876d52b94a3c1420e9ac3e6da442a4d0fa0bcd6de292b6282113cee","markerVerified":true},"F7":{"sha256":"ae4b5e05735741b01cbc6c9e4af3953a02b4ebf78faf78fe06f9130420f4f301","markerVerified":true},"F8":{"sha256":"8151d83f6b1abe7a9139db5c9d884c42c1b3faf986dc712c0fbd43a22af39f51","markerVerified":true},"F9":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"F10":{"sha256":"93f4d2f94710eed90e0bcc9b8823e91f1a4b894221fae1972c1f6745d90b622d","markerVerified":true},"F11":{"sha256":"acb66c459f9eb3a34686567b5d4f9bd834b4e874e9a1229256baebfd15c4ea5c","markerVerified":true},"F12":{"sha256":"0c68ebca896806de2aa052ef44a0de13e9df3becef44721857c7c99567403d80","markerVerified":true},"#1697":{"sha256":"14345e0180e5c4649b5a2169b094c8e05d97c54fe79902c8eef0ebf7c18715fb","markerVerified":true},"#1698":{"sha256":"2cb57b6fb38bb4722eebd169f4b6056f1b6f69ba0adde9978bcd9e03f83d43ab","markerVerified":true},"#1691":{"sha256":"6b600ec62ef9a3898fd3c606c23034a10a005c0330d0dac43b29f6d2abc2ec8e","markerVerified":true},"#1721":{"sha256":"862f40e5c7b45a0ce35bbe438add312cf7d155e527ee49bed62ee9b58d0cd526","markerVerified":true},"ADR-094":{"sha256":"1d2225e7422f8a2d47d39100324d5e4ac2d29c55e8e72b02f5e4a7a113d45be2","markerVerified":true},"G1":{"sha256":"2bc49c38b14d43a0329bf5d84913528851ef1c48ab32b8c8c1c40f83c062fc7f","markerVerified":true},"G3":{"sha256":"442839dca2d6177f2567dccaf1f48306c304cbca0659c477501604289f7ad5a6","markerVerified":true},"G4":{"sha256":"12fce07f6458aff5db210b0ba50104fa9b2dd52c85b5e9071b48c2899451c631","markerVerified":true},"G6":{"sha256":"84a6159b384b8118f0beaa1089c417cab6d1116cd77d3882a607715ef7679ea8","markerVerified":true},"G7-gnn":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G7-rvf":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G7-mut":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G7-att":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G7-gvb":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G2":{"sha256":"9f751aaee838a85e7b2371bbd73dccb5cb89c6b7751496b18d33d8b8a559de19","markerVerified":true},"CAP-MCP-agent-tools":{"sha256":"a182a61809b5480e9eb4139ed8fa3b8e471201d338be4e086578b4e2e325302a","markerVerified":true},"CAP-MCP-agentdb-tools":{"sha256":"666141cf59c2e75c9f65fe50eff85076a96d820bddceaba79c0b67a4469b3bb5","markerVerified":true},"CAP-MCP-analyze-tools":{"sha256":"d665ca78dcb753e7803d37a331ae363ba5e4fea0c90e828171d264a425a638da","markerVerified":true},"CAP-MCP-autopilot-tools":{"sha256":"1f1dcf3c7660b9ab66df49bacfdf2c7f5a883554d98b416a2780d5226e643df2","markerVerified":true},"CAP-MCP-browser-tools":{"sha256":"5ea5f63c99ee22bccb6fbd4d872e44f47ec7f0ad14ceed4f18014b95f94f75f7","markerVerified":true},"CAP-MCP-claims-tools":{"sha256":"89908d601a21e1a0dca0bd611af61b1d2150010f6015216849122775e6940808","markerVerified":true},"CAP-MCP-config-tools":{"sha256":"0c68ebca896806de2aa052ef44a0de13e9df3becef44721857c7c99567403d80","markerVerified":true},"CAP-MCP-coordination-tools":{"sha256":"ae4b5e05735741b01cbc6c9e4af3953a02b4ebf78faf78fe06f9130420f4f301","markerVerified":true},"CAP-MCP-daa-tools":{"sha256":"2beb8ec07d784cf7f1a61b4cd2090a8e65934893c2a31a3afcd406774d2a8537","markerVerified":true},"CAP-MCP-embeddings-tools":{"sha256":"48032e13d70927a6448d75e04f8f055b0268aaada8bef3e6926bf3acafd493fd","markerVerified":true},"CAP-MCP-github-tools":{"sha256":"951b66082ba309505eaf4e3588104681f5581ec5e0c8d6daf6a7befac596db37","markerVerified":true},"CAP-MCP-guidance-tools":{"sha256":"856f7b0439a4dfdafab88589faf5cbe42c8fbd4004532fe507ec3e3e42af9e12","markerVerified":true},"CAP-MCP-hive-mind-tools":{"sha256":"8482312f5b447ae6008d13b0873945f026bf540e559195cf961b948a94520678","markerVerified":true},"CAP-MCP-hooks-tools":{"sha256":"93f4d2f94710eed90e0bcc9b8823e91f1a4b894221fae1972c1f6745d90b622d","markerVerified":true},"CAP-MCP-memory-tools":{"sha256":"37d929df892035fe94a48cd43a074c9c773e9dc031ab56d9dd33cdbf21a87e39","markerVerifiLine truncated
|
||||
{"v":1,"commit":"95df0111e0dc749a8b79a859238a6d62b29102cf","issuedAt":"2026-05-12T04:48:07.079Z","branch":"HEAD","os":"macos","manifestHash":"3427c16ee9346f9ad29df4b62d9df0afe059addc10cae4e037d3e45e64713fff","summary":{"totalFixes":112,"verified":111,"missing":0},"fixes":{"F1":{"sha256":"93f4d2f94710eed90e0bcc9b8823e91f1a4b894221fae1972c1f6745d90b622d","markerVerified":true},"F2":{"sha256":"93f4d2f94710eed90e0bcc9b8823e91f1a4b894221fae1972c1f6745d90b622d","markerVerified":true},"F3":{"sha256":"8482312f5b447ae6008d13b0873945f026bf540e559195cf961b948a94520678","markerVerified":true},"F4":{"sha256":"666141cf59c2e75c9f65fe50eff85076a96d820bddceaba79c0b67a4469b3bb5","markerVerified":true},"F5":{"sha256":"48032e13d70927a6448d75e04f8f055b0268aaada8bef3e6926bf3acafd493fd","markerVerified":true},"F6":{"sha256":"159365d8f876d52b94a3c1420e9ac3e6da442a4d0fa0bcd6de292b6282113cee","markerVerified":true},"F7":{"sha256":"ae4b5e05735741b01cbc6c9e4af3953a02b4ebf78faf78fe06f9130420f4f301","markerVerified":true},"F8":{"sha256":"8151d83f6b1abe7a9139db5c9d884c42c1b3faf986dc712c0fbd43a22af39f51","markerVerified":true},"F9":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"F10":{"sha256":"93f4d2f94710eed90e0bcc9b8823e91f1a4b894221fae1972c1f6745d90b622d","markerVerified":true},"F11":{"sha256":"acb66c459f9eb3a34686567b5d4f9bd834b4e874e9a1229256baebfd15c4ea5c","markerVerified":true},"F12":{"sha256":"0c68ebca896806de2aa052ef44a0de13e9df3becef44721857c7c99567403d80","markerVerified":true},"#1697":{"sha256":"14345e0180e5c4649b5a2169b094c8e05d97c54fe79902c8eef0ebf7c18715fb","markerVerified":true},"#1698":{"sha256":"2cb57b6fb38bb4722eebd169f4b6056f1b6f69ba0adde9978bcd9e03f83d43ab","markerVerified":true},"#1691":{"sha256":"6b600ec62ef9a3898fd3c606c23034a10a005c0330d0dac43b29f6d2abc2ec8e","markerVerified":true},"#1721":{"sha256":"862f40e5c7b45a0ce35bbe438add312cf7d155e527ee49bed62ee9b58d0cd526","markerVerified":true},"ADR-094":{"sha256":"1d2225e7422f8a2d47d39100324d5e4ac2d29c55e8e72b02f5e4a7a113d45be2","markerVerified":true},"G1":{"sha256":"2bc49c38b14d43a0329bf5d84913528851ef1c48ab32b8c8c1c40f83c062fc7f","markerVerified":true},"G3":{"sha256":"442839dca2d6177f2567dccaf1f48306c304cbca0659c477501604289f7ad5a6","markerVerified":true},"G4":{"sha256":"12fce07f6458aff5db210b0ba50104fa9b2dd52c85b5e9071b48c2899451c631","markerVerified":true},"G6":{"sha256":"84a6159b384b8118f0beaa1089c417cab6d1116cd77d3882a607715ef7679ea8","markerVerified":true},"G7-gnn":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G7-rvf":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G7-mut":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G7-att":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G7-gvb":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G2":{"sha256":"9f751aaee838a85e7b2371bbd73dccb5cb89c6b7751496b18d33d8b8a559de19","markerVerified":true},"CAP-MCP-agent-tools":{"sha256":"a182a61809b5480e9eb4139ed8fa3b8e471201d338be4e086578b4e2e325302a","markerVerified":true},"CAP-MCP-agentdb-tools":{"sha256":"666141cf59c2e75c9f65fe50eff85076a96d820bddceaba79c0b67a4469b3bb5","markerVerified":true},"CAP-MCP-analyze-tools":{"sha256":"d665ca78dcb753e7803d37a331ae363ba5e4fea0c90e828171d264a425a638da","markerVerified":true},"CAP-MCP-autopilot-tools":{"sha256":"1f1dcf3c7660b9ab66df49bacfdf2c7f5a883554d98b416a2780d5226e643df2","markerVerified":true},"CAP-MCP-browser-tools":{"sha256":"5ea5f63c99ee22bccb6fbd4d872e44f47ec7f0ad14ceed4f18014b95f94f75f7","markerVerified":true},"CAP-MCP-claims-tools":{"sha256":"89908d601a21e1a0dca0bd611af61b1d2150010f6015216849122775e6940808","markerVerified":true},"CAP-MCP-config-tools":{"sha256":"0c68ebca896806de2aa052ef44a0de13e9df3becef44721857c7c99567403d80","markerVerified":true},"CAP-MCP-coordination-tools":{"sha256":"ae4b5e05735741b01cbc6c9e4af3953a02b4ebf78faf78fe06f9130420f4f301","markerVerified":true},"CAP-MCP-daa-tools":{"sha256":"2beb8ec07d784cf7f1a61b4cd2090a8e65934893c2a31a3afcd406774d2a8537","markerVerified":true},"CAP-MCP-embeddings-tools":{"sha256":"48032e13d70927a6448d75e04f8f055b0268aaada8bef3e6926bf3acafd493fd","markerVerified":true},"CAP-MCP-github-tools":{"sha256":"951b66082ba309505eaf4e3588104681f5581ec5e0c8d6daf6a7befac596db37","markerVerified":true},"CAP-MCP-guidance-tools":{"sha256":"856f7b0439a4dfdafab88589faf5cbe42c8fbd4004532fe507ec3e3e42af9e12","markerVerified":true},"CAP-MCP-hive-mind-tools":{"sha256":"8482312f5b447ae6008d13b0873945f026bf540e559195cf961b948a94520678","markerVerified":true},"CAP-MCP-hooks-tools":{"sha256":"93f4d2f94710eed90e0bcc9b8823e91f1a4b894221fae1972c1f6745d90b622d","markerVerified":true},"CAP-MCP-memory-tools":{"sha256":"37d929df892035fe94a48cd43a074c9c773e9dc031ab56d9dd33cdbf21a87e39","markerVerifiLine truncated
|
||||
{"v":1,"commit":"7633c2952b9ebdd771c1c93ec16bc6dac90dc1a8","issuedAt":"2026-05-12T04:50:17.791Z","branch":"fix/1921-hook-cli-resilience","os":"macos","manifestHash":"6350c72e79ca3eb38dac412fd254ba1e7230649f9031e899fd4c24310dbb69c8","summary":{"totalFixes":112,"verified":112,"missing":0},"fixes":{"F1":{"sha256":"93f4d2f94710eed90e0bcc9b8823e91f1a4b894221fae1972c1f6745d90b622d","markerVerified":true},"F2":{"sha256":"93f4d2f94710eed90e0bcc9b8823e91f1a4b894221fae1972c1f6745d90b622d","markerVerified":true},"F3":{"sha256":"8482312f5b447ae6008d13b0873945f026bf540e559195cf961b948a94520678","markerVerified":true},"F4":{"sha256":"666141cf59c2e75c9f65fe50eff85076a96d820bddceaba79c0b67a4469b3bb5","markerVerified":true},"F5":{"sha256":"48032e13d70927a6448d75e04f8f055b0268aaada8bef3e6926bf3acafd493fd","markerVerified":true},"F6":{"sha256":"159365d8f876d52b94a3c1420e9ac3e6da442a4d0fa0bcd6de292b6282113cee","markerVerified":true},"F7":{"sha256":"ae4b5e05735741b01cbc6c9e4af3953a02b4ebf78faf78fe06f9130420f4f301","markerVerified":true},"F8":{"sha256":"8151d83f6b1abe7a9139db5c9d884c42c1b3faf986dc712c0fbd43a22af39f51","markerVerified":true},"F9":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"F10":{"sha256":"93f4d2f94710eed90e0bcc9b8823e91f1a4b894221fae1972c1f6745d90b622d","markerVerified":true},"F11":{"sha256":"acb66c459f9eb3a34686567b5d4f9bd834b4e874e9a1229256baebfd15c4ea5c","markerVerified":true},"F12":{"sha256":"0c68ebca896806de2aa052ef44a0de13e9df3becef44721857c7c99567403d80","markerVerified":true},"#1697":{"sha256":"14345e0180e5c4649b5a2169b094c8e05d97c54fe79902c8eef0ebf7c18715fb","markerVerified":true},"#1698":{"sha256":"2cb57b6fb38bb4722eebd169f4b6056f1b6f69ba0adde9978bcd9e03f83d43ab","markerVerified":true},"#1691":{"sha256":"6b600ec62ef9a3898fd3c606c23034a10a005c0330d0dac43b29f6d2abc2ec8e","markerVerified":true},"#1721":{"sha256":"862f40e5c7b45a0ce35bbe438add312cf7d155e527ee49bed62ee9b58d0cd526","markerVerified":true},"ADR-094":{"sha256":"1d2225e7422f8a2d47d39100324d5e4ac2d29c55e8e72b02f5e4a7a113d45be2","markerVerified":true},"G1":{"sha256":"2bc49c38b14d43a0329bf5d84913528851ef1c48ab32b8c8c1c40f83c062fc7f","markerVerified":true},"G3":{"sha256":"442839dca2d6177f2567dccaf1f48306c304cbca0659c477501604289f7ad5a6","markerVerified":true},"G4":{"sha256":"12fce07f6458aff5db210b0ba50104fa9b2dd52c85b5e9071b48c2899451c631","markerVerified":true},"G6":{"sha256":"84a6159b384b8118f0beaa1089c417cab6d1116cd77d3882a607715ef7679ea8","markerVerified":true},"G7-gnn":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G7-rvf":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G7-mut":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G7-att":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G7-gvb":{"sha256":"12ca47650a812c66fb5efbbc3b6cdf527ca74ee787f27c9556514492de9d07cd","markerVerified":true},"G2":{"sha256":"9f751aaee838a85e7b2371bbd73dccb5cb89c6b7751496b18d33d8b8a559de19","markerVerified":true},"CAP-MCP-agent-tools":{"sha256":"a182a61809b5480e9eb4139ed8fa3b8e471201d338be4e086578b4e2e325302a","markerVerified":true},"CAP-MCP-agentdb-tools":{"sha256":"666141cf59c2e75c9f65fe50eff85076a96d820bddceaba79c0b67a4469b3bb5","markerVerified":true},"CAP-MCP-analyze-tools":{"sha256":"d665ca78dcb753e7803d37a331ae363ba5e4fea0c90e828171d264a425a638da","markerVerified":true},"CAP-MCP-autopilot-tools":{"sha256":"1f1dcf3c7660b9ab66df49bacfdf2c7f5a883554d98b416a2780d5226e643df2","markerVerified":true},"CAP-MCP-browser-tools":{"sha256":"5ea5f63c99ee22bccb6fbd4d872e44f47ec7f0ad14ceed4f18014b95f94f75f7","markerVerified":true},"CAP-MCP-claims-tools":{"sha256":"89908d601a21e1a0dca0bd611af61b1d2150010f6015216849122775e6940808","markerVerified":true},"CAP-MCP-config-tools":{"sha256":"0c68ebca896806de2aa052ef44a0de13e9df3becef44721857c7c99567403d80","markerVerified":true},"CAP-MCP-coordination-tools":{"sha256":"ae4b5e05735741b01cbc6c9e4af3953a02b4ebf78faf78fe06f9130420f4f301","markerVerified":true},"CAP-MCP-daa-tools":{"sha256":"2beb8ec07d784cf7f1a61b4cd2090a8e65934893c2a31a3afcd406774d2a8537","markerVerified":true},"CAP-MCP-embeddings-tools":{"sha256":"48032e13d70927a6448d75e04f8f055b0268aaada8bef3e6926bf3acafd493fd","markerVerified":true},"CAP-MCP-github-tools":{"sha256":"951b66082ba309505eaf4e3588104681f5581ec5e0c8d6daf6a7befac596db37","markerVerified":true},"CAP-MCP-guidance-tools":{"sha256":"856f7b0439a4dfdafab88589faf5cbe42c8fbd4004532fe507ec3e3e42af9e12","markerVerified":true},"CAP-MCP-hive-mind-tools":{"sha256":"8482312f5b447ae6008d13b0873945f026bf540e559195cf961b948a94520678","markerVerified":true},"CAP-MCP-hooks-tools":{"sha256":"93f4d2f94710eed90e0bcc9b8823e91f1a4b894221fae1972c1f6745d90b622d","markerVerified":true},"CAP-MCP-memory-tools":{"sha256":"37d929df892035fe94a48cd43a074c9c773e9dc031ab56d9dd33cdbLine truncated
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"manifest": {
|
||||
"schema": "ruflo-witness/v1",
|
||||
"issuedAt": "2026-05-12T04:44:05.086Z",
|
||||
"gitCommit": "31f22ff9a92154952b8d9e417a25034bdf08de08",
|
||||
"branch": "HEAD",
|
||||
"issuedAt": "2026-05-12T04:50:17.791Z",
|
||||
"gitCommit": "7633c2952b9ebdd771c1c93ec16bc6dac90dc1a8",
|
||||
"branch": "fix/1921-hook-cli-resilience",
|
||||
"os": "macos",
|
||||
"releases": {
|
||||
"ruflo": "3.7.0-alpha.26",
|
||||
@@ -12,8 +12,8 @@
|
||||
"@claude-flow/memory": "3.0.0-alpha.15"
|
||||
},
|
||||
"summary": {
|
||||
"totalFixes": 110,
|
||||
"verified": 110,
|
||||
"totalFixes": 112,
|
||||
"verified": 112,
|
||||
"missing": 0
|
||||
},
|
||||
"fixes": [
|
||||
@@ -657,14 +657,6 @@
|
||||
"marker": "ctx.flags.file || ctx.args[0]",
|
||||
"markerVerified": true
|
||||
},
|
||||
{
|
||||
"id": "#1862",
|
||||
"desc": "ruflo-core PostToolUse hooks call documented CLI flags (-c/-s/-e, -f/-s) instead of bogus --format true",
|
||||
"file": "plugins/ruflo-core/hooks/hooks.json",
|
||||
"sha256": "c74a26044c1d283589696590f652ef21f4c65613f9ff5eb015127b1819d37fe7",
|
||||
"marker": "hooks post-edit -f \\\"$FILE\\\" -s true",
|
||||
"markerVerified": true
|
||||
},
|
||||
{
|
||||
"id": "ADR-101-C",
|
||||
"desc": "Federation policy-engine wires claim-event + agent-handoff message types into CLAIMS_FOR_MESSAGE_TYPE (unblocked Build V3 after 3+ days of failures)",
|
||||
@@ -896,15 +888,39 @@
|
||||
"sha256": "e8bcf68635d45764e46be0c80647781134f8f437b395b949a95e56cce717a9e3",
|
||||
"marker": "formula: 'src/formula/index.ts'",
|
||||
"markerVerified": true
|
||||
},
|
||||
{
|
||||
"id": "#1921",
|
||||
"desc": "Plugin hooks no longer do a bare `npx <pkg>@alpha hooks …` on every PreToolUse/PostToolUse/Stop fire — they invoke scripts/ruflo-hook.sh, which prefers a locally-installed `ruflo`/`claude-flow` binary, falls back to `npx --prefer-offline`, and ALWAYS exits 0 so a CLI/install crash (e.g. arborist `Invalid Version` on npm 10.8.x) never surfaces a hook error in Claude Code or wastes a cold-cache reinstall per turn. CI guard: scripts/audit-hook-commands.mjs (fails on bare-npx-without-prefer-offline / non-guarded CLI invocation) wired into v3-ci.yml `hook-command-audit` + added to witness-verify needs[].",
|
||||
"file": "scripts/audit-hook-commands.mjs",
|
||||
"sha256": "6f2702c59f1cb2438533ee4e7b2648dc2c2076334c60e5ca4dc30db5a0c99c5b",
|
||||
"marker": "NONFATAL_RE",
|
||||
"markerVerified": true
|
||||
},
|
||||
{
|
||||
"id": "#1921-shim",
|
||||
"desc": "scripts/ruflo-hook.sh — resilient invoker shipped in each plugin (.claude-plugin/, plugin/, plugins/ruflo-core/): prefers a local `ruflo`/`claude-flow` binary, else `npx --prefer-offline --yes ruflo@alpha`, always `exit 0`. stdin (hook event JSON) passes through unchanged. Companion to #1921.",
|
||||
"file": "plugins/ruflo-core/scripts/ruflo-hook.sh",
|
||||
"sha256": "08d576ea4938dbb7ac6c5072b2463ddf3299802801cf1d0110a1244ebe0868ea",
|
||||
"marker": "npx --prefer-offline --yes ruflo@alpha hooks",
|
||||
"markerVerified": true
|
||||
},
|
||||
{
|
||||
"id": "#1862",
|
||||
"desc": "ruflo-core PostToolUse hooks call documented CLI flags (-c/-s/-e, -f/-s) instead of bogus --format true. (#1921 moved the invocation behind scripts/ruflo-hook.sh — the documented-flag form is preserved.)",
|
||||
"file": "plugins/ruflo-core/hooks/hooks.json",
|
||||
"sha256": "3c99ed6c845a3ff44d4e012081307a4d2af3aaf8a1025dcdb125bff1eab2a661",
|
||||
"marker": "post-edit -f \\\"$FILE\\\" -s true",
|
||||
"markerVerified": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"integrity": {
|
||||
"manifestHashAlgo": "sha256",
|
||||
"manifestHash": "a081f02f53f33c5a008cd06177cb1f8a4de08ac7183312877d57c0ca95018192",
|
||||
"manifestHash": "6350c72e79ca3eb38dac412fd254ba1e7230649f9031e899fd4c24310dbb69c8",
|
||||
"signatureAlgo": "ed25519",
|
||||
"publicKey": "1d90203273675541aa963e769617d91c6188b5d0d062b8caa0f48f886ba84cf8",
|
||||
"signature": "a470dd63ff659dcd2775a9bd932fecb67fb7c9b723d6ce2938b8c6f8e1eb37724f0bd073a0d14aa467e1dafc442ff9a179a3f8016df0aea11327b92a1ef01e05",
|
||||
"publicKey": "0a6f6225cf543ffefd2c273bb9a9689be54c4147c2d3ed5c8b2ebbabdfe4a1f2",
|
||||
"signature": "bb0a47361f77e47a26cf7722c25098b793a39e017733eaa9d0ed2890cf7cdbde35495c7933cc49e21006e23998a70a915a712266da2ab32f9af9d954d4c30e0b",
|
||||
"seedDerivation": "sha256(gitCommit + ':ruflo-witness/v1')"
|
||||
}
|
||||
}
|
||||
@@ -15,9 +15,9 @@
|
||||
},
|
||||
{
|
||||
"id": "#1862",
|
||||
"desc": "ruflo-core PostToolUse hooks call documented CLI flags (-c/-s/-e, -f/-s) instead of bogus --format true",
|
||||
"desc": "ruflo-core PostToolUse hooks call documented CLI flags (-c/-s/-e, -f/-s) instead of bogus --format true. (#1921 moved the invocation behind scripts/ruflo-hook.sh — the documented-flag form is preserved.)",
|
||||
"file": "plugins/ruflo-core/hooks/hooks.json",
|
||||
"marker": "hooks post-edit -f \\\"$FILE\\\" -s true"
|
||||
"marker": "post-edit -f \\\"$FILE\\\" -s true"
|
||||
},
|
||||
{
|
||||
"id": "ADR-101-C",
|
||||
@@ -192,6 +192,18 @@
|
||||
"desc": "plugin-gastown-bridge \u2014 package.json `exports` advertised ./dist/index.mjs (+ ./formula, ./convoy subpaths) that the build never emitted, so those import specifiers 404'd in the published tarball. Fix: tsup.config.ts builds the formula/convoy entries (previously commented out), and package.json exports/main/module point at the actually-emitted .js/.cjs filenames. Validated by the plugin-package-audit CI guard (check D).",
|
||||
"file": "v3/plugins/gastown-bridge/tsup.config.ts",
|
||||
"marker": "formula: 'src/formula/index.ts'"
|
||||
},
|
||||
{
|
||||
"id": "#1921",
|
||||
"desc": "Plugin hooks no longer do a bare `npx <pkg>@alpha hooks \u2026` on every PreToolUse/PostToolUse/Stop fire \u2014 they invoke scripts/ruflo-hook.sh, which prefers a locally-installed `ruflo`/`claude-flow` binary, falls back to `npx --prefer-offline`, and ALWAYS exits 0 so a CLI/install crash (e.g. arborist `Invalid Version` on npm 10.8.x) never surfaces a hook error in Claude Code or wastes a cold-cache reinstall per turn. CI guard: scripts/audit-hook-commands.mjs (fails on bare-npx-without-prefer-offline / non-guarded CLI invocation) wired into v3-ci.yml `hook-command-audit` + added to witness-verify needs[].",
|
||||
"file": "scripts/audit-hook-commands.mjs",
|
||||
"marker": "NONFATAL_RE"
|
||||
},
|
||||
{
|
||||
"id": "#1921-shim",
|
||||
"desc": "scripts/ruflo-hook.sh \u2014 resilient invoker shipped in each plugin (.claude-plugin/, plugin/, plugins/ruflo-core/): prefers a local `ruflo`/`claude-flow` binary, else `npx --prefer-offline --yes ruflo@alpha`, always `exit 0`. stdin (hook event JSON) passes through unchanged. Companion to #1921.",
|
||||
"file": "plugins/ruflo-core/scripts/ruflo-hook.sh",
|
||||
"marker": "npx --prefer-offline --yes ruflo@alpha hooks"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user