The two hook bridges (dsh-hooks-claude, dsh-hooks-codex) would otherwise duplicate
the bulk of the protocol — Codex deliberately reimplements a SUBSET of the Claude
Code protocol (same hooks.json shape, exit-code/stdout contract, command-hook
model). This library holds the genuinely-identical primitives; each bridge owns
only what differs (per-event stdin payload, env/substitution, decision mapping).
New packages/hooks/ group; hook-protocol is a LIBRARY (no plugin, registers/injects
nothing):
- matcher: matchesMatcher(pattern, query, mode) — the one dialect axis collapsed to
a mode param (claude = literal-or-regex with pipe alternation; codex = always
unanchored regex). Match-all on absent/''/'*'; invalid regex matches nothing.
- codec: parseHookOutput(exit, stdout, stderr) → dialect-neutral HookOutput. Exit 0
→ lenient JSON; exit 2 → blocking error (stderr = reason, surfaced as
decision:'block'); other → non-blocking. Parses the CC superset
(continue/stopReason/decision/hookSpecificOutput.{permissionDecision,
additionalContext,updatedInput}/systemMessage); permissionDecision overrides the
legacy top-level decision.
- runner: runHook(bash, hook, opts, now) — runs a command hook via ctx.bash (stdin
payload + trusted-plugin env), honors timeoutSec, never throws (executor reject →
non-blocking-error HookOutput). Injected clock for testable durations.
- merge: mergeHookOutputs — most-restrictive fold (deny>ask>allow, sticky stop,
block reasons joined, context/system-messages accumulated).
- hook/* session events (declaration-merged into SessionEventMap, log-only like
compact/*) + appendHookInvoked/appendHookResult helpers.
updatedInput is parsed but NOT honored (deferred pre-tool-input-rewrite RFC); a
bridge logs+warns. 47 unit tests at per-file 100% (matcher per-mode, codec per
exit-code/field, runner plumbing w/ stub executor, merge precedence, hook/*
helpers). RFC: implemented/feature/2026-06-30-hook-protocol-lib.md.
58 lines
2.2 KiB
JSON
58 lines
2.2 KiB
JSON
{
|
|
"extends": "./tsconfig.base.json",
|
|
"compilerOptions": {
|
|
"noEmit": true,
|
|
"rewriteRelativeImportExtensions": false
|
|
},
|
|
"include": [
|
|
"examples/*/src/**/*.ts",
|
|
"examples/*/start.ts",
|
|
"examples/*/tests/**/*.ts",
|
|
"packages/*/*/tests/**/*.ts",
|
|
"scripts/**/*.ts"
|
|
],
|
|
"references": [
|
|
{ "path": "./vendor/cosmokit" },
|
|
{ "path": "./vendor/schemastery" },
|
|
{ "path": "./vendor/cordis" },
|
|
{ "path": "./vendor/loader" },
|
|
{ "path": "./vendor/include" },
|
|
{ "path": "./vendor/group" },
|
|
{ "path": "./vendor/timer" },
|
|
{ "path": "./vendor/hmr" },
|
|
{ "path": "./vendor/logger-console" },
|
|
{ "path": "./packages/util/brand" },
|
|
{ "path": "./packages/llm/llm" },
|
|
{ "path": "./packages/core/session" },
|
|
{ "path": "./packages/session-persistence/session-persistence" },
|
|
{ "path": "./packages/session-persistence/session-persistence-jsonl" },
|
|
{ "path": "./packages/session-persistence/session-persistence-sqlite" },
|
|
{ "path": "./packages/core/system-prompt" },
|
|
{ "path": "./packages/core/agent" },
|
|
{ "path": "./packages/core/tools" },
|
|
{ "path": "./packages/core/agent-loop" },
|
|
{ "path": "./packages/core/agent-core" },
|
|
{ "path": "./packages/bash/bash" },
|
|
{ "path": "./packages/llm/llm-deepseek" },
|
|
{ "path": "./packages/llm/llm-pi-ai" },
|
|
{ "path": "./packages/bash/bash-local" },
|
|
{ "path": "./packages/bash/tool-bash" },
|
|
{ "path": "./packages/compact/compact" },
|
|
{ "path": "./packages/support/invariants" },
|
|
{ "path": "./packages/ui/acp" },
|
|
{ "path": "./packages/ui/acp-agent" },
|
|
{ "path": "./packages/ui/stdio-agent" },
|
|
{ "path": "./packages/support/ui-stdio" },
|
|
{ "path": "./packages/support/llm-replay" },
|
|
{ "path": "./packages/subagent/subagent" },
|
|
{ "path": "./packages/support/subagent-mock" },
|
|
{ "path": "./packages/subagent/tool-subagent" },
|
|
{ "path": "./packages/subagent/subagent-inprocess" },
|
|
{ "path": "./packages/subagent/subagent-spawn" },
|
|
{ "path": "./packages/subagent/subagent-fork" },
|
|
{ "path": "./packages/subagent/subagent-acp" },
|
|
{ "path": "./packages/todo/tool-todo" },
|
|
{ "path": "./packages/hooks/hook-protocol" }
|
|
]
|
|
}
|