II.
Page reference
Reading · 6 minpage: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.
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