110b1e3d2d
* refactor(keyword-detector): split constants into domain-specific modules * feat(shared): add requiresAnyModel and isAnyFallbackModelAvailable * feat(config): add hephaestus to agent schemas * feat(agents): add Hephaestus autonomous deep worker * feat(cli): update model-fallback for hephaestus support * feat(plugin): add hephaestus to config handler with ordering * test(delegate-task): update tests for hephaestus agent * docs: update AGENTS.md files for hephaestus * docs: add hephaestus to READMEs * chore: regenerate config schema * fix(delegate-task): bypass requiresModel check when user provides explicit config * docs(hephaestus): add 4-part context structure for explore/librarian prompts * docs: fix review comments from cubic (non-breaking changes) - Move Hephaestus from Primary Agents to Subagents (uses own fallback chain) - Fix Hephaestus fallback chain documentation (claude-opus-4-5 → gemini-3-pro) - Add settings.local.json to claude-code-hooks config sources - Fix delegate_task parameters in ultrawork prompt (agent→subagent_type, background→run_in_background, add load_skills) - Update line counts in AGENTS.md (index.ts: 788, manager.ts: 1440) * docs: fix additional documentation inconsistencies from oracle review - Fix delegate_task parameters in Background Agents example (docs/features.md) - Fix Hephaestus fallback chain in root AGENTS.md to match model-requirements.ts * docs: clarify Hephaestus has no fallback (requires gpt-5.2-codex only) Hephaestus uses requiresModel constraint - it only activates when gpt-5.2-codex is available. The fallback chain in code is unreachable, so documentation should not mention fallbacks. * fix(hephaestus): remove unreachable fallback chain entries Hephaestus has requiresModel: gpt-5.2-codex which means the agent only activates when that specific model is available. The fallback entries (claude-opus-4-5, gemini-3-pro) were unreachable and misleading. --------- Co-authored-by: justsisyphus <justsisyphus@users.noreply.github.com>
4.7 KiB
4.7 KiB
HOOKS KNOWLEDGE BASE
OVERVIEW
34 lifecycle hooks intercepting/modifying agent behavior across 5 events.
Event Types:
UserPromptSubmit(chat.message) - Can blockPreToolUse(tool.execute.before) - Can blockPostToolUse(tool.execute.after) - Cannot blockStop(event: session.stop) - Cannot blockonSummarize(Compaction) - Cannot block
STRUCTURE
hooks/
├── atlas/ # Main orchestration (757 lines)
├── anthropic-context-window-limit-recovery/ # Auto-summarize
├── todo-continuation-enforcer.ts # Force TODO completion
├── ralph-loop/ # Self-referential dev loop
├── claude-code-hooks/ # settings.json compat layer - see AGENTS.md
├── comment-checker/ # Prevents AI slop
├── auto-slash-command/ # Detects /command patterns
├── rules-injector/ # Conditional rules
├── directory-agents-injector/ # Auto-injects AGENTS.md
├── directory-readme-injector/ # Auto-injects README.md
├── edit-error-recovery/ # Recovers from failures
├── thinking-block-validator/ # Ensures valid <thinking>
├── context-window-monitor.ts # Reminds of headroom
├── session-recovery/ # Auto-recovers from crashes
├── think-mode/ # Dynamic thinking budget
├── keyword-detector/ # ultrawork/search/analyze modes
├── background-notification/ # OS notification
├── prometheus-md-only/ # Planner read-only mode
├── agent-usage-reminder/ # Specialized agent hints
├── auto-update-checker/ # Plugin update check
├── tool-output-truncator.ts # Prevents context bloat
├── compaction-context-injector/ # Injects context on compaction
├── delegate-task-retry/ # Retries failed delegations
├── interactive-bash-session/ # Tmux session management
├── non-interactive-env/ # Non-TTY environment handling
├── start-work/ # Sisyphus work session starter
├── task-resume-info/ # Resume info for cancelled tasks
├── question-label-truncator/ # Auto-truncates question labels
├── category-skill-reminder/ # Reminds of category skills
├── empty-task-response-detector.ts # Detects empty responses
├── sisyphus-junior-notepad/ # Sisyphus Junior notepad
├── stop-continuation-guard/ # Guards stop continuation
├── subagent-question-blocker/ # Blocks subagent questions
└── index.ts # Hook aggregation + registration
HOOK EVENTS
| Event | Timing | Can Block | Use Case |
|---|---|---|---|
| UserPromptSubmit | chat.message |
Yes | Keyword detection, slash commands |
| PreToolUse | tool.execute.before |
Yes | Validate/modify inputs, inject context |
| PostToolUse | tool.execute.after |
No | Truncate output, error recovery |
| Stop | event (session.stop) |
No | Auto-continue, notifications |
| onSummarize | Compaction | No | Preserve state, inject summary context |
EXECUTION ORDER
- UserPromptSubmit: keywordDetector → claudeCodeHooks → autoSlashCommand → startWork
- PreToolUse: subagentQuestionBlocker → questionLabelTruncator → claudeCodeHooks → nonInteractiveEnv → commentChecker → directoryAgentsInjector → directoryReadmeInjector → rulesInjector → prometheusMdOnly → sisyphusJuniorNotepad → atlasHook
- PostToolUse: claudeCodeHooks → toolOutputTruncator → contextWindowMonitor → commentChecker → directoryAgentsInjector → directoryReadmeInjector → rulesInjector → emptyTaskResponseDetector → agentUsageReminder → interactiveBashSession → editErrorRecovery → delegateTaskRetry → atlasHook → taskResumeInfo
HOW TO ADD
- Create
src/hooks/name/withindex.tsexportingcreateMyHook(ctx) - Add hook name to
HookNameSchemainsrc/config/schema.ts - Register in
src/index.tsand add to relevant lifecycle methods
HOOK PATTERNS
Simple Single-Event:
export function createToolOutputTruncatorHook(ctx) {
return { "tool.execute.after": async (input, output) => { ... } }
}
Multi-Event with State:
export function createThinkModeHook() {
const state = new Map<string, ThinkModeState>()
return {
"chat.params": async (output, sessionID) => { ... },
"event": async ({ event }) => { /* cleanup */ }
}
}
ANTI-PATTERNS
- Blocking non-critical: Use PostToolUse warnings instead
- Heavy computation: Keep PreToolUse light to avoid latency
- Redundant injection: Track injected files to avoid context bloat
- Direct state mutation: Use
output.output +=instead of replacing