docs/agent-stack/hooks/missing-capabilities
Missing Hook Capabilities — Agent Stack Gaps reference
Beyond the 13 missing events, the agent stack lacks several hook capabilities that Claude Code supports.
Continue reading
Nearby pages in the same section.
Missing Hook Capabilities — Agent Stack Gaps
Beyond the 13 missing events, the agent stack lacks several hook capabilities that Claude Code supports.
1. Handler Types (core support implemented; platform executors pending)
Claude Code supports 5 hook handler types. hooks-adapter core now models and dispatches all 5 handler types. command remains the legacy default when type is omitted.
| Handler Type | Claude Code | Agent Stack | Gap |
|---|---|---|---|
command | ✅ Shell subprocess | ✅ hooks-adapter runner.ts | — |
http | ✅ POST to webhook URL | ✅ hooks-adapter core | Platform policy may still restrict private URLs; local/private endpoints require explicit opt-in |
mcp_tool | ✅ Call MCP server tool | Partial | hooks-adapter has the typed handler and injectable executor seam; live tools-adapter/MCP registry wiring remains tied to #576 |
prompt | ✅ LLM evaluates prompt | Partial | hooks-adapter has the typed handler and bounded executor seam; host model invocation must be supplied by agent-platform/adapters |
agent | ✅ Spawn subagent to evaluate | Partial | hooks-adapter has the typed handler and bounded executor seam; host agent spawning must be supplied by agent-platform/adapters |
Implemented
**hooks-adapter/core:**
src/normalizer/runner.ts— Dispatches by handler type and preserves command fail-open/fail-closed semanticssrc/types/plan.ts—HandlerRefis a backward-compatible typed union; omittedtypebehaves ascommandsrc/handlers/http.ts— HTTP POST handler with allowed-env header interpolation, URL validation, timeout, and JSON result parsingsrc/handlers/mcp-tool.ts— MCP tool handler through an injected executor seamsrc/handlers/prompt.ts— Prompt handler through an injected, timeout/depth-bounded executor seamsrc/handlers/agent.ts— Agent handler through an injected, timeout/depth/max-turn bounded executor seam
Remaining integration work
**agent-platform:**
src/harness/adapters/adapterBridge.tsalready forwards opaque hook config to adapters. Livemcp_tool,prompt, andagentexecution still needs platform wiring that supplies hooks-adapter executor seams from the unified tool registry/model/agent invocation surfaces.
2. Decision Types (3 missing)
| Decision | Claude Code | Agent Stack | Gap |
|---|---|---|---|
allow | ✅ PreToolUse | ✅ hooks-adapter | — |
deny | ✅ PreToolUse | ✅ hooks-adapter | — |
ask | ✅ PreToolUse | ✅ hooks-adapter | — |
defer | ✅ Let normal flow decide | ✅ hooks-adapter | First-class decision; renders as normal flow where native adapters have no explicit field |
block | ✅ Block action with reason | ✅ hooks-adapter + agent-platform bridge | Precedence and audit bridge implemented; Claude PreToolUse renders as deny |
retry | ✅ PermissionDenied recovery | Partial | First-class decision with bounded/audited agent-platform metadata; native Claude retry rendering is deferred until a stable event contract exists |
Changes needed
**hooks-adapter/core:**
src/types/result.ts—defer,block,retryare in the decision unionsrc/merge-engine/merge.tsandsrc/sdk-interface/parser.ts— Handle precedence and validation for the decision types
**hooks-adapter/adapter-claude:**
src/renderer.ts— Rendersblockas PreToolUsedeny;deferand unsupportedretryomit native decisions explicitly
**agent-platform:**
src/harness/internal/createRun/orchestration/effects.ts— Handles hook decision metadata for block/retry/session abortsrc/governance/— Existing permission events audit hook block/retry bridge decisions
3. Matcher Patterns (regex, negation, OR missing)
| Capability | Claude Code | Agent Stack | Gap |
|---|---|---|---|
| Exact match | ✅ "Bash" | ✅ dot-path equality | — |
| Pipe-separated OR | ✅ `"Edit\ | Write"` | ❌ AND-only |
| Regex patterns | ✅ "mcp__.*" | ❌ exact only | Need regex support |
| Negation | ✅ (via regex ^(?!rm)) | ❌ | Need negation operator |
if conditional | ✅ "Bash(rm *)" permission syntax | ❌ | Need if field parsing |
Changes needed
**hooks-adapter/core:**
src/normalizer/plan-resolver.ts— ExtendevaluateWhen()with regex, OR, negationsrc/types/plan.ts— Addiffield to HookPlanEntry
4. Async Execution (fully missing)
| Capability | Claude Code | Agent Stack | Gap |
|---|---|---|---|
async: true | ✅ Background, non-blocking | ❌ | Need async handler spawn |
asyncRewake: true | ✅ Background + rewake on exit 2 | ❌ | Need rewake mechanism |
once: true | ✅ Run only once per session | ❌ | Need per-session dedup |
Changes needed
**hooks-adapter/core:**
src/normalizer/runner.ts— Add async spawn mode (don't await)src/normalizer/runner.ts— Add rewake: monitor exit code, inject stderr as system reminder- New:
src/state/hook-execution-tracker.ts— Trackonceper session
**agent-platform:**
- Background hook results need to feed back into orchestration context
5. Environment Variables (2 missing)
| Variable | Claude Code | Agent Stack | Gap |
|---|---|---|---|
CLAUDE_PROJECT_DIR | ✅ | ❌ | Map to AGENT_WORKSPACE_ROOT or add |
CLAUDE_ENV_FILE | ✅ Persist env vars | ❌ | Need env file mechanism |
CLAUDE_PLUGIN_ROOT | ✅ | ✅ via PI_PLUGIN_ROOT | Naming mismatch |
CLAUDE_PLUGIN_DATA | ✅ | ❌ | Need plugin data dir |
CLAUDE_EFFORT | ✅ | ❌ | Need effort level propagation |
CLAUDE_CODE_REMOTE | ✅ | ❌ | Need remote detection |
Changes needed
**hooks-adapter/core:**
src/propagation/materialize.ts— Add missing env vars to injection- New: env file mechanism for SessionStart/Setup/CwdChanged/FileChanged hooks
**agent-platform:**
- Propagate
CLAUDE_EFFORTfrom session options
6. Hook Output Processing (partial)
| Capability | Claude Code | Agent Stack | Gap |
|---|---|---|---|
continue: false | ✅ Stop entire session | Partial | Core merge and Claude Stop rendering exist; agent-platform hook metadata bridge treats it as an abort signal |
stopReason | ✅ Message on stop | ✅ hooks-adapter + Claude renderer | Core merge and Claude Stop reason rendering exist |
suppressOutput | ✅ Hide hook output | ✅ hooks-adapter + Claude renderer | MessageDisplay can render empty display content |
systemMessage | ✅ Warning to user | Partial | Exists but not all events |
terminalSequence | ✅ Terminal escape codes | ❌ | Need terminal sequence injection |
additionalContext | ✅ Context for Claude | Partial | Some events only |
updatedInput | ✅ Modify tool input | ✅ hooks-adapter + Claude PreToolUse | Adapter/parser alias over canonical toolMutation; platform mutation only applies where a live tool invocation can be proven |
sessionTitle | ✅ Set session name | ✅ Claude SessionStart renderer | Existing hook-specific output propagates sessionTitle |
watchPaths | ✅ Add file watchers | Deferred | Current daemon watchers have static trigger config and expose no safe dynamic registration API |
Changes needed
**hooks-adapter/core:**
src/types/result.ts— Continue to keep supported output fields as typed top-level fieldssrc/sdk-interface/parser.tsandsrc/merge-engine/merge.ts— NormalizeupdatedInputto canonicaltoolMutation
**agent-platform:**
src/harness/internal/createRun/orchestration/— Handles hook metadatacontinueSession:falseas session abortsrc/session/— No new API required for current ClaudesessionTitle; it is emitted through SessionStart hook-specific outputsrc/harness/—updatedInputremains canonicalized totoolMutation; live tool input mutation requires a provable pending tool invocation boundary
**agent-runtime:**
src/daemon/— Dynamic file watcher registration forwatchPathsremains deferred until watcher handles support safe runtime registration
7. Hook Configuration (partial)
| Capability | Claude Code | Agent Stack | Gap |
|---|---|---|---|
disableAllHooks | ✅ Global kill switch | ❌ | Need in hooks-adapter config |
statusMessage | ✅ Custom spinner text | ❌ | Need in hook UI |
timeout per hook | ✅ Configurable | ❌ | Need per-hook timeout in runner |
shell selection | ✅ bash/powershell | ❌ | Need in hook command config |
| Header env interpolation | ✅ $VAR in headers | ❌ | Need for HTTP handler |
allowedEnvVars | ✅ Restrict env leaks | ❌ | Need for HTTP handler |
Changes needed
**hooks-adapter/core:**
src/config.ts— AdddisableAllHookssupportsrc/normalizer/runner.ts— Per-hook timeout, shell selection- New HTTP handler: header interpolation with allowedEnvVars