feat(cli): shingan hook install/run — block agents on Critical workflow bugs in their edit loop#60
Open
hatyibei wants to merge 3 commits into
Open
feat(cli): shingan hook install/run — block agents on Critical workflow bugs in their edit loop#60hatyibei wants to merge 3 commits into
hatyibei wants to merge 3 commits into
Conversation
…ontent
Until now `--format` had to be passed explicitly (default "json"), which makes
an editor/agent hook awkward: a hook that fires on a saved file can't know
whether it's n8n, LangGraph, CrewAI, … up front. `--format auto` infers it from
the file extension plus a lightweight content sniff (import statements /
node-type signatures), so a hook can run `shingan analyze --format auto --input
<file>` on anything and skip cleanly when nothing matches.
Detection:
.py -> pydantic-graph | crewai | llamaindex | autogen | langgraph
.ts/.js/… -> mastra | openai-agents | langgraph-js
.go -> adk-go (google.golang.org/adk / LoopAgent signatures)
.json -> n8n (n8n-nodes-*/@n8n/* node types, robust even when the trailing
`connections` block sits past the 16KB sniff window) else json
Directories resolve to the most common framework; a generic json hit never
wins over a framework hit. Unrecognised input returns "" so the CLI errors
clearly ("pass --format explicitly") instead of mis-parsing.
Measured on 308 real n8n workflows: 307/308 auto-detected as n8n (the one miss
is a node-catalog file, not a workflow). Default stays "json" for backward
compatibility; "auto" is opt-in.
Tests: cli/detect_test.go (per-format files, large-export sniff-window case,
dir-prefers-framework, missing path). go test ./cli/ + go vet green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…gration
Turns the agent-hook play into a shipped feature. After an AI coding agent
writes or edits a workflow file, shingan analyzes it and BLOCKS on a Critical
finding so the agent self-corrects before the code ships — the run-before-it-
runs guardrail, inside the agent's own loop.
shingan hook install merge a PostToolUse hook into .claude/settings.json
(matcher Edit|Write, command "<bin> hook run").
Preserves all other keys/hooks; idempotent; --global
targets ~/.claude/settings.json; --bin sets the path.
shingan hook run hook body: reads the PostToolUse event JSON on stdin,
extracts tool_input.file_path, and re-invokes this
binary as `analyze --format auto` (no logic dup).
exit 2 + reason on stderr on Critical; warnings
surface but never block; non-workflow / unparseable /
malformed input never blocks.
No external script, jq or python dependency — the hook is the binary itself,
so it ships wherever shingan does. Relies on `--format auto` so the hook works
on any framework file the agent saves.
Tests: hook_run non-blocking on 5 junk inputs, criticalSection extraction,
installClaudeHook merge/preserve/idempotent + fresh-file creation. go test
./cli/ + go vet green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
|
ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR. |
Document shingan hook install / run next to the pre-commit hook: zero-config PostToolUse integration that blocks the agent on Critical workflow findings inside its edit loop. Same content in README.md and README.ja.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
|
ECC bundle files are already tracked in this repository. Skipping generation of another bundle PR. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The agent-hook play, shipped. After an AI coding agent writes/edits a workflow file, shingan analyzes it and blocks on a Critical finding so the agent self-corrects before the code ships — the run-before-it-runs guardrail, inside the agent's own loop. This is the natural next step after the pre-commit hook (ADR-019), one loop iteration earlier and zero-friction.
It only works because the FP/determinism cleanup (#56, #58) made findings trustworthy enough to put inside an agent's context — an FP-heavy linter on an auto-hook makes the agent thrash on false blocks.
What
Hook contract:
recursion_limit/max_iterations/ error-branch guard the suggestion names), then re-saves.No external script, jq, or python dependency — the hook is the binary, so it ships wherever shingan does (npm/Homebrew/GHCR). Self-contained.
Verified end-to-end
hook runagainst real inputs:demo.json(loop, no max_iterations)README.mdhook installagainst a settings.json with a pre-existingmodelkey and a Bash hook: both preserved, shingan appended, second run is a no-op (idempotent).Tests
cli/hook_test.go:runHooknon-blocking on 5 junk inputs,criticalSectionextraction,installClaudeHookmerge/preserve/idempotent + fresh-file creation.go test ./cli/+go vetgreen.Follow-ups (not here)
--agent cursor/ other agents (the install path is already factored for it)🤖 Generated with Claude Code