Automatic enforcement of APEX methodology and SOLID principles through Claude Code hooks.
The hooks system ensures that agents:
- Consult skills before writing code
- Follow APEX methodology (Analyze → Plan → Execute → eXamine)
- Respect SOLID principles (files < 100 lines, interfaces separated)
~/.claude/settings.json
│
▼
scripts/hooks-loader.ts ← Bun + SOLID (10x faster)
│
▼
plugins/*/hooks/hooks.json ← Auto-detected
│
▼
plugins/*/scripts/*.ts|*.sh ← Executed in parallel
~/.claude/plugins/marketplaces/fusengine-plugins/setup.sh~\.claude\plugins\marketplaces\fusengine-plugins\setup.ps1This installs:
- Hooks loader in
~/.claude/settings.json - API keys configuration (interactive prompts)
- Shell config (bash/zsh/fish/PowerShell)
All plugin hooks are automatically detected and loaded.
| Hook | Trigger | Purpose |
|---|---|---|
| SessionStart | Session starts | Load context, inject CLAUDE.md, cleanup states |
| UserPromptSubmit | User sends message | Detect project type, inject APEX instruction |
| PreToolUse | Before Write/Edit/Bash | Block if skill not consulted, validate git/install, enforce APEX phases |
| PostToolUse | After Write/Edit | Validate SOLID compliance, track changes, cache doc results |
| SubagentStart | Subagent starts | Inject cached context (explore, doc, lessons) |
| SubagentStop | Subagent completes | Track agent memory, cache lessons, cache docs from transcript |
| Stop | Claude finishes responding | Play completion sound notification |
| PermissionRequest | Permission dialog shown | Play sound for ALL permission prompts |
| Notification | Permission/idle/elicitation | Play sound alerts for user attention |
| PreCompact | Before context compression | Save APEX state, preserve task decisions |
| SessionEnd | Session closes | Cleanup temp files, save session stats |
| Setup | Plugin first-run | Validate API keys and dependencies |
| Plugin | PreToolUse | PostToolUse | UserPromptSubmit | SessionStart | SubagentStart | SubagentStop | Stop | Notification | PreCompact | SessionEnd | Setup |
|---|---|---|---|---|---|---|---|---|---|---|---|
| ai-pilot | APEX phases, APEX context | SOLID check, Doc tracking, Task sync | APEX injection | - | Context inject, Explore cache, Doc cache inject, Lessons inject, Test cache inject | Sniper lessons, Test results, Doc from transcript, SOLID from transcript | - | - | - | Analytics save | - |
| core-guards | Git, Install, Security, Pre-commit, Interfaces, File size, SOLID read | File size, Session tracking, Doc reads, SOLID reads, TS validation | CLAUDE.md injection | Context, Cleanup | - | Memory | Sound | Sounds | APEX state | Cleanup, Stats | API keys |
| react-expert | Block without skill | React SOLID validation | - | - | - | - | - | - | - | - | - |
| nextjs-expert | Block without skill | Next.js SOLID validation | - | - | - | - | - | - | - | - | - |
| laravel-expert | Block without skill | Laravel SOLID validation | - | - | - | - | - | - | - | - | - |
| swift-apple-expert | Block without skill | Swift SOLID validation | - | - | - | - | - | - | - | - | - |
| tailwindcss | Block without skill | Tailwind best practices | - | - | - | - | - | - | - | - | - |
| design-expert | Block without skill | Accessibility check | - | - | - | - | - | - | - | - | - |
scripts/
├── hooks-loader.ts ← Entry point
├── install-hooks.ts ← Installation + API keys
├── package.json
├── src/
│ ├── interfaces/
│ │ ├── hooks.ts ← Hook interfaces
│ │ └── env.ts ← EnvKey interface
│ ├── config/
│ │ └── api-keys.ts ← API keys configuration
│ ├── services/
│ │ ├── plugin-scanner.ts ← Scan plugins, extract hooks
│ │ ├── hook-executor.ts ← Execute hooks in PARALLEL
│ │ ├── settings-manager.ts← Manage settings.json
│ │ └── env-manager.ts ← API keys & shell config
│ └── __tests__/
│ ├── api-keys.test.ts
│ ├── env-manager.test.ts
│ ├── fs-helpers.test.ts
│ ├── hook-executor.test.ts
│ ├── install-hooks.test.ts
│ ├── plugin-scanner.test.ts
│ └── settings-manager.test.ts
└── env-shell/
├── claude-env.bash
├── claude-env.zsh
├── claude-env.fish
└── claude-env.ps1
bun test # Run 81 tests
bun test --watch # Watch mode| Version | Execution | Speed |
|---|---|---|
| v1.0 (bash+jq) | Sequential | 280ms |
| v2.0 (Bun) | Parallel | 100ms |
- Create the hooks directory:
mkdir -p plugins/my-plugin/hooks plugins/my-plugin/scripts- Create
hooks/hooks.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/my-check.sh"
}
]
}
]
}
}-
Create your script in
scripts/my-check.sh -
Make it executable:
chmod +x plugins/my-plugin/scripts/*.shThe hooks loader will automatically detect and load your new hooks.
Hooks receive JSON input via stdin:
{
"tool_name": "Write",
"tool_input": {
"file_path": "/path/to/file.tsx",
"content": "file content..."
}
}exit 0echo "Your blocking message here" >&2
exit 2echo '{"additionalContext": "Your context here"}'
exit 0# Check if hooks-loader.ts is in settings.json
cat ~/.claude/settings.json | jq '.hooks.PreToolUse'
# Re-run installation (macOS/Linux)
~/.claude/plugins/marketplaces/fusengine-plugins/setup.sh
# Re-run installation (Windows PowerShell)
~\.claude\plugins\marketplaces\fusengine-plugins\setup.ps1# Test the hook manually
echo '{"tool_name":"Write","tool_input":{"file_path":"test.tsx"}}' | \
bun ~/.claude/plugins/marketplaces/fusengine-plugins/scripts/hooks-loader.ts PreToolUseAdd to your hook script:
echo "[DEBUG] Hook triggered: $TOOL_NAME on $FILE_PATH" >&2