2.13.0-beta.20). Features may change before the next stable release.Switch to stable →Hooks and runtime
Engineer Hooks and runtime support
Understand the Engineer Hook event graph, visible outcomes, and runtime-specific support boundaries.
Engineer Hooks add workflow automation around tool use, prompts, session boundaries, and handoffs. They can return guidance, request approval, stop an unsafe or overly broad operation, or update bounded workflow state. You do not invoke them as Skills or commands; the selected runtime calls the supported handlers when their events occur.
The resolved Engineer package contains 44 Hook package entries. That number is an artifact inventory, not 44 independent behaviors. It includes the Hook manifest, event handlers, shared support libraries, and Engineer-specific state and statusline helpers. One handler can participate in several events, while a support file may never run on its own.
Hooks supplement existing safeguards
Hook checks and reminders can reduce mistakes, but they do not replace runtime permissions, repository controls, secret management, code review, or your own approval. Review every requested action and the resulting changes.
Active event graph
The active graph is organized around outcomes rather than package file count:
| Event | What you can observe |
|---|---|
PreToolUse | Provides naming guidance for new files, checks sensitive-file access, and stops overly broad or ignored-path scouting when the request falls outside the supported boundary. A check may allow the request, return guidance, or ask for approval. |
PostToolUse | Keeps plan formatting coherent after edits and writes, refreshes task/session state after supported task operations, and updates usage state after tool activity. |
PreCompact | Captures enough workflow orientation to continue after context compaction. |
SessionStart | Initializes project and session context for the new session. |
SubagentStart | Initializes subagent state and supplies the relevant team context. |
Stop | Refreshes session and usage state. When an active plan is bound, the plan reminder can return valid nonblocking JSON with continue and systemMessage; otherwise it exits silently. |
SubagentStop | Refreshes shared session state at the subagent boundary. |
UserPromptSubmit | Supplies project-development guidance, checks for secret-like output risk, applies the simplify-before-shipping gate when relevant, and refreshes usage state. |
These outcomes support the Engineer workflow; they do not approve a plan, commit, merge, deploy, or release work for you.
Configured paths at session start
The SessionStart handler resolves project path preferences before exporting
the environment used by Engineer workflows. A relative paths.docs or
paths.plans value resolves under the session's project base. An absolute value
is exported verbatim as CK_DOCS_PATH or CK_PLANS_PATH, rather than being
joined to the project path. This export makes the configured locations
available to Skills; Go-native plan, journal, and dashboard surfaces separately
require a project-relative paths.plans and fall back to plans/ for an
absolute value.
Runtime projection
The labels below describe what becomes active:
- Emitted means AgentKit writes an active native artifact.
- Translated means AgentKit maps a supported behavior to the runtime's native event model.
- Dropped means the runtime cannot represent the behavior, so it is not active.
- Narrowed means the handlers remain active only for the representable subset of the original matcher.
- Sidecar-preserved means package material remains available for support or provenance but is not an active runtime feature by itself.
| Surface | Claude Code | Codex | Cursor |
|---|---|---|---|
| Hook event graph | Emitted: the declared graph uses Claude Code's native or plugin Hook surface. | Translated: representable events and matchers become Codex Hook registrations. Dropped: unsupported groups are omitted. Narrowed: supported matcher atoms stay active. Both outcomes are disclosed; installation can still succeed. | Translated: supported groups become Cursor Hook registrations. Source support does not prove identical behavior across every provider setup. |
| Handler dependencies | Dependencies required by active handlers are emitted; remaining support material is sidecar-preserved. | Dependencies required by translated handlers are emitted; remaining support material is sidecar-preserved. | Dependencies required by translated handlers are emitted; remaining support material is sidecar-preserved. |
| Engineer statusline | Emitted: active when AgentKit can install it without replacing a foreign statusline. | Dropped: unsupported. | Dropped: unsupported. |
The Engineer statusline is Claude Code only. Codex and Cursor do not gain a statusline merely because the package contains statusline support files.
Codex partial support
Codex has a smaller event and matcher model than Claude Code. Engineer projects one fully dropped group and two narrowed matchers:
PostToolUsematcherAgent|Task|TodoWrite|TodoRead, handlersession-state.cjs, is fully dropped. SeparateStopandSubagentStopregistrations remain.Read|Write|Edit|BashbecomesWrite|Edit|Bash, droppingReadwhile keepingprivacy-block.cjsactive for the supported atoms.Bash|ReadbecomesBash, droppingReadwhile keepingscout-block.cjsactive for Bash.
A drop or narrow does not make installation fail. Human output lists them under
Hooks dropped (unsupported on this target) and Hook matchers narrowed
(some tool matches unsupported on this target). JSON uses the optional
hooksDropped, droppedHookSummaries, hookMatchersNarrowed, and
narrowedHookSummaries fields. Treat them as capability disclosure, not as
evidence that all Engineer automation is missing.
The plan reminder is exported only on wildcard Stop, not SubagentStop. With
no active plan it exits 0 with empty stdout. When relevant it emits JSON with
only allowed success fields, shaped as
{"continue":true,"systemMessage":"..."}, and remains fail-open.
Windows Hook launch support
On Windows, an eligible .cjs Hook inside the resolved Codex home can run from
an ordinary path containing spaces. AgentKit emits a managed sibling .cmd
shim and references that shim from the translated Hook configuration. The shim
is an AgentKit-owned output and participates in normal refresh and uninstall
handling.
This support is deliberately bounded. A spaced path outside the Codex home, a
path with cmd.exe metacharacters, a non-ASCII shim name, or unsafe/non-ASCII
baked arguments remains unsupported and produces a warning. Empty arguments get
a distinct warning; identical same-path shims deduplicate, while conflicting
content keeps the first shim and warns. Paths that do not need a shim continue
to use the direct command. Do not hand-edit generated shims or Hook configuration.
Diagnose the active Claude Code surfaces
ak doctor --adapter claude-code --json discovers enabled Claude Code Hook
surfaces by scope and delivery mode instead of treating package files as proof
that a Hook is active. For native project and user installs, the
hook_registration check compares the installed expectations with the active
settings.json registrations and verifies referenced entrypoints. For plugin
installs, it checks the active Hook manifest and its entrypoints. Hooks disabled
through AgentKit are excluded from the native expectations.
The hook_log check reads the log associated with each discovered native or
plugin surface. A new active surface with no log yet remains healthy; missing
registrations, manifests, or entrypoints are reported with their scope and
delivery mode. Use these results to identify the affected surface before
refreshing or reinstalling a Kit.
Ownership and lifecycle
Project and user-scope Hook registrations can coexist. For shared global Codex configuration, AgentKit merges registrations it owns while preserving user Hooks, foreign fields, and registrations owned by another Kit. A modified or conflicting entry is preserved or reported rather than silently overwritten.
Owned Hook metadata participates in rollback, and last-owner cleanup removes empty structures created by AgentKit without removing pre-existing or foreign structure. This is lifecycle hardening, not a security guarantee and not permission to delete arbitrary content from the shared Hooks configuration.
Refresh and uninstall operate on recorded AgentKit-owned material, not every Hook in the runtime. Review the operation preview and recovery snapshot before applying a lifecycle change. Do not delete a runtime home or the complete shared Hooks configuration as a repair step.
Troubleshoot safely
- Read the installation disclosure. Check both the dropped and narrowed headings or their JSON fields before assuming the whole Hook graph failed.
- Confirm the target and scope. Project and user installs are separate, and the runtime can load a different copy than the one you expected.
- Run the target health check. Use
ak doctor --adapter claude-code --jsonfor Claude Code orak doctor --adapter codex --jsonfor Codex, and inspect the reported checks instead of assuming file presence means a Hook is active. - Check the Windows path classification. An eligible in-home
.cjspath can use a managed shim; unsupported external or unsafe path forms warn. - Use the matching lifecycle route. Preview refresh or uninstall, preserve user-modified content, and inspect any recovery snapshot before applying a change.
For exact install flags, see Installing kits
and the ak kit init reference. For
adapter-wide capability differences, see Runtime
adapters. If installation or discovery is
still unclear, continue with Kit installation
problems and Runtime cannot find a
Skill or Agent.