hooks init generates settings.json with NO permissions.deny and --force overwrites existing rules; also wires PostToolUseFailure (not a hook event) and pre-command (which approves 'rm -fr /')
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 812
- Forks
- 175
- Avg merge
- 2m
- Merged PRs (30d)
- 3
Description
Summary
hooks init generates a .claude/settings.json that omits permissions.deny entirely, wires a hook event that does not exist, and installs commands that are known not to work. With --force — the documented way to re-run it — an existing project's deny rules are replaced by a config that has none.
Version: agentic-flow 2.1.2, Node v22.23.0, macOS 15. Run in an empty directory.
What it generates
✅ Hooks initialized!
📁 Created: .claude/settings.json
📊 Created: .claude/statusline.mjs
permissions.allow = ["Bash(npx:*)", "Bash(agentic-flow:*)", "Bash(npm run:*)",
"mcp__agentic-flow", "mcp__claude-flow", "mcp__ruv-swarm"]
permissions.deny = (absent)
hooks:
PreToolUse npx agentic-flow hooks pre-edit "$TOOL_INPUT_file_path"
PreToolUse npx agentic-flow hooks pre-command "$TOOL_INPUT_command"
PostToolUse npx agentic-flow hooks post-edit "$TOOL_INPUT_file_path" --success
PostToolUseFailure npx agentic-flow hooks post-edit "$TOOL_INPUT_file_path" --fail --error "$ERROR_MESSAGE"
SessionStart npx agentic-flow hooks intelligence stats
SessionStart npx agentic-flow workers status --active --json 2>/dev/null || true
SessionEnd npx agentic-flow workers cleanup --age 24 2>/dev/null || true
UserPromptSubmit npx agentic-flow hooks intelligence stats
UserPromptSubmit npx agentic-flow workers dispatch-prompt "$USER_PROMPT" --session "$SESSION_ID"
statusLine = node .claude/statusline.mjs
Concerns, in order of severity
1. No deny array, and --force overwrites. The generated file grants six allow entries including Bash(npx:*) and defines no denies. Re-running with --force in a project that has curated deny rules replaces them with a config that has none. Since --force is the documented way to re-initialise, the failure mode is a user re-running init and silently losing their guardrails. Suggested: merge rather than replace, or at minimum preserve permissions.deny and warn about what is being dropped.
2. PostToolUseFailure does not appear to be a hook event. It is not among the events a working project config uses (PreToolUse, PostToolUse, UserPromptSubmit, SessionStart, SessionEnd, Stop, PreCompact, SubagentStart, …). If it never fires, only successes are recorded — and since post-edit is what feeds the "Routing accuracy" figure (#201), that number would sit at 100% by construction rather than by measurement.
3. $TOOL_INPUT_file_path / $TOOL_INPUT_command / $ERROR_MESSAGE. Hook data arrives as JSON on stdin (tool_input.file_path). If those variables are not populated in the hook environment, pre-edit "" and post-edit "" run against an empty path and record nothing — silently, since both exit 0.
4. It installs commands with known defects. pre-command on every Bash call is the one I would flag hardest: it blocks rm -rf / but approves rm -fr /, rm -rf ~, find / -delete and a fork bomb (#197). Wiring it as a PreToolUse hook gives the appearance of a safety gate over whatever real permission rules the user had — which item 1 has just removed. Also installed: hooks intelligence stats twice per interaction (reports Patterns: 0 regardless — #204), workers dispatch-prompt on every prompt and workers cleanup at session end (workers are never actually spawned — #182).
5. statusLine: node .claude/statusline.mjs is a bare relative path with no ${CLAUDE_PROJECT_DIR}, so it depends on the working directory, and breaks on any project path containing a space.
Suggested fix
- Preserve
permissions.denyon--force, or refuse to overwrite a file containing one without an explicit second flag. - Drop
PostToolUseFailure, or document which host provides it. - Resolve the statusline path against
${CLAUDE_PROJECT_DIR}and quote it. - Consider generating only the hooks that currently function —
post-editandpost-commandboth record correctly in my testing; most of the rest do not.
Related
- #197 —
pre-commandapprovesrm -fr /,rm -rf ~,find / -delete, fork bomb. - #201 — "Routing accuracy" counts
post-editcalls, not routes. - #204 —
intelligence statsreportsPatterns: 0beside a populated store. - #182 — workers are never spawned;
dispatch-promptandcleanupare wired here regardless.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the hooks init entry point and inspect how it generates .claude/settings.json and .claude/statusline.mjs. Reproduce initialization and --force in a project with existing deny rules, then verify hook event names, stdin data handling, and statusline path behavior. Done means supported hooks work, existing deny rules are preserved, and generated paths remain valid.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, typescript
- Domain
- cli, security, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100