hooksmithcli
v0.1.0
Published
CLI for authoring, testing, and debugging Claude Code hooks
Readme
hooksmith
CLI for authoring, testing, and debugging Claude Code hooks.
Install
npm install -g hook-smithCommands
hooksmith list
Show all configured hooks from ~/.claude/settings.json.
hooksmith listPreToolUse
.* → command: ~/.claude/hooks/gate-exploration.sh
.* → http: http://localhost:9800/gate
PostToolUse
.* → http: http://localhost:9800/receipt
.* → command: ~/.claude/hooks/post-commit-reindex.sh
4 hooks across 2 eventshooksmith test <hook-file>
Test a hook against a sample payload.
# Quick payload builder
hooksmith test ~/.claude/hooks/gate.sh --tool Read --input '{"file_path": "/etc/passwd"}'
# Full payload from file
hooksmith test ~/.claude/hooks/gate.sh --payload payload.jsonOutput shows exit code, decision (allow/deny), timing, stdout, stderr, and parsed JSON output.
hooksmith validate
Validate all hook configurations in settings.json.
hooksmith validateChecks:
- Scripts exist and are executable
- Matcher regex patterns are valid
- Required fields present per hook type
Returns exit code 1 if any errors found.
hooksmith init
Scaffold a new hook from templates.
hooksmith initInteractive prompts for hook name, event type (PreToolUse/PostToolUse), and language (bash). Creates the script file at ~/.claude/hooks/ with the correct stdin/stdout/exit code patterns.
Hook Format
Claude Code hooks receive JSON on stdin and communicate decisions via exit codes.
PreToolUse (gating):
- Exit 0 = allow the tool call
- Exit 2 = deny the tool call (stderr = reason)
PostToolUse (logging):
- Exit 0 = acknowledged
Input payload:
{
"tool_name": "Read",
"tool_input": {
"file_path": "/home/user/project/src/index.ts"
}
}Example hook script:
#!/usr/bin/env bash
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // ""')
if [[ "$TOOL_NAME" == "Bash" ]]; then
echo "Bash not allowed in this state" >&2
exit 2
fi
exit 0Error Handling
All operations return Result<T, HooksmithError> from @valencets/resultkit. Error codes: IO_FAILED, PARSE_FAILED, SETTINGS_NOT_FOUND, INVALID_CONFIG, HOOK_TIMEOUT, HOOK_CRASHED, SPAWN_FAILED, SCRIPT_NOT_FOUND, SCRIPT_NOT_EXECUTABLE, INVALID_REGEX.
Requirements
- Node.js >= 22
- ESM only
License
MIT
