@@ -179,6 +179,48 @@ the same backend and keeps `/hooks_external` and `/hooks-external` as aliases
179179for the unified ` /hooks ` management view. ` reset ` is available only as explicit
180180recovery for a corrupt OpenBitFun-managed index and never changes source files.
181181
182+ ## Hooks declared by skills
183+
184+ Invoking a Claude-format skill through ` Skill ` registers its validated synchronous
185+ ` type: "command" ` handlers in the existing Hook engine for that session. Discovery,
186+ listing, and importing do not register or execute them. Imported Claude skills
187+ retain their source dialect. The external Hook catalog remains read-only.
188+
189+ Skill hooks use the supported lifecycle events listed above, regular-expression
190+ matchers, stdin JSON, exit-code blocking, and ` updatedInput ` . They run after the
191+ configured command layers. Registration is idempotent; invoking a changed hook
192+ declaration in the same session returns an error instead of replacing active rules.
193+ ` once: true ` is consumed after exit code 0, atomically across concurrent dispatches;
194+ exit 2, other failures, and timeouts leave it eligible. A skill loaded mid-batch is
195+ a preflight barrier: later calls see its hooks even within the same model response.
196+
197+ The Claude adapter maps ` Bash ` to ` ExecCommand ` and ` command ` to ` cmd ` . For ` Write ` ,
198+ it translates the path-first ` payload ` into ` file_path ` /` content ` and converts
199+ ` updatedInput ` back before normal input validation. An ambiguous Write destination
200+ is blocked while a matching skill hook is active. ` Edit ` keeps its existing fields.
201+ The command receives ` CLAUDE_SKILL_DIR ` , ` CLAUDE_SESSION_ID ` , and
202+ ` CLAUDE_PROJECT_DIR ` ; this does not expand variables in the skill's prose.
203+
204+ Skill ` PreToolUse ` hooks also support Claude's ` permissionDecision: "ask" ` through
205+ the existing session permission mailbox. An ask requires a fresh reply even in
206+ bypass mode; a policy deny still wins. The hook reason is included in the approval
207+ metadata. Native ` hooks.json ` keeps its Codex decision contract.
208+
209+ The master ` app.hooks.enabled ` gate applies. Project skills additionally require
210+ ` app.hooks.project_hooks_enabled ` , including on subsequent dispatch. Activation
211+ without a session/local workspace, or in an SSH/remote workspace, returns an
212+ explicit error; no controller-local fallback executes. Remote control, Peer Device,
213+ and Detached Dispatch reuse their target runtime's session and permission owners;
214+ this change does not introduce a separate client-side hook runner.
215+
216+ Registrations survive ordinary turns and idle in-process session unloading. Session
217+ end/delete/discard removes them and cancels running handlers; cancelled SessionEnd
218+ dispatch also clears them. They are process-local and are not restored after a
219+ runtime restart: invoke the skill again. Unknown events, asynchronous handlers,
220+ ` prompt ` /` agent ` handlers, and unknown execution fields reject the entire skill
221+ rather than silently dropping constraints. Script files remain live dependencies,
222+ as for native command hooks; the declaration fingerprint does not snapshot scripts.
223+
182224## Quick start
183225
184226Create ` <user config dir>/config/hooks.json ` :
0 commit comments