@deepseek-ai/dsh-hook-protocol 0.0.1-rc.1 → 0.0.1-rc.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +2 -2
- package/README.md +6 -6
- package/README.zh.md +8 -8
- package/lib/index.js +4 -4
- package/lib/invariant.js +1 -1
- package/lib/types/runner.d.ts +4 -4
- package/lib/types/types.d.ts +4 -4
- package/package.json +9 -9
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/hooks/hook-protocol/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: cebf93a04caef67a82549663018c10aac4cd535d
|
|
6
|
+
README.zh.md: ecdad2396d7f185f02404d55fc3edb86635ab1f5
|
package/README.md
CHANGED
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
English | [中文](README.zh.md)
|
|
4
4
|
|
|
5
|
-
The **shared core** of the Claude Code / Codex hook wire protocol. NOT a cordis plugin — it registers nothing and injects nothing. It is a **library** of dialect-neutral primitives the two bridge plugins (`@deepseek-ai/dsh-hooks-claude`, `@deepseek-ai/dsh-hooks-codex`) import so neither re-implements the identical halves of the protocol.
|
|
5
|
+
The **shared core** of the Claude Code / Codex hook wire protocol. NOT a cordis plugin — it registers nothing and injects nothing. It is a **library** of dialect-neutral primitives the two bridge plugins (`@deepseek-ai/dsh-hooks-claude-code`, `@deepseek-ai/dsh-hooks-codex`) import so neither re-implements the identical halves of the protocol.
|
|
6
6
|
|
|
7
7
|
Codex deliberately reimplements a *subset* of the Claude Code hook protocol — the same `hooks.json` matcher-group shape, the same exit-code/stdout output contract, the same command-hook execution model. The genuinely-shared parts live here; each bridge owns only what differs.
|
|
8
8
|
|
|
9
9
|
## What's shared (here) vs. per-dialect (the bridges)
|
|
10
10
|
|
|
11
|
-
| Concern | Here (`dsh-hook-protocol`) | The bridge (`dsh-hooks-claude` / `-codex`) |
|
|
11
|
+
| Concern | Here (`dsh-hook-protocol`) | The bridge (`dsh-hooks-claude-code` / `-codex`) |
|
|
12
12
|
|---|---|---|
|
|
13
13
|
| Matcher validation + test | `matcherDiagnostic(pattern, mode)` for parse-time diagnostics; `matchesMatcher(pattern, query, mode)` for contained runtime matching | picks its `mode` (`claude` = literal-or-regex, `codex` = always regex) and rejects a config group carrying a diagnostic |
|
|
14
|
-
| Run a hook | `runHook(bash, hook, opts, now)` — stdin payload + env via `ctx.
|
|
14
|
+
| Run a hook | `runHook(bash, hook, opts, now)` — stdin payload + env via `ctx.shell`, decode | builds the per-event stdin **payload** + the dialect's **env** |
|
|
15
15
|
| Decode output | `parseHookOutput(exit, stdout, stderr)` → neutral `HookOutput` | maps the neutral `HookOutput` onto an extension-point-specific typed Decision |
|
|
16
16
|
| Merge N hooks | `mergeHookOutputs(outputs)` → most-restrictive `MergedHookOutcome` | — |
|
|
17
17
|
| Durable record | `appendHookInvoked` / `appendHookResult` (`hook/*` session events; the result's `decision`/`stderrSummary` derive from the `HookOutput` here) | calls them around each invocation |
|
|
@@ -20,20 +20,20 @@ Codex deliberately reimplements a *subset* of the Claude Code hook protocol —
|
|
|
20
20
|
## Primitives
|
|
21
21
|
|
|
22
22
|
- **`matcherDiagnostic(matcher, mode)` / `matchesMatcher(matcher, query, mode)`** — match-all on absent/`''`/`'*'`; `claude` mode treats a pure `[A-Za-z0-9_|]+` pattern as a literal (pipe = exact-match alternation) and anything else as a regex; `codex` mode is always an unanchored regex. Bridge parsers discard matcher fields for events without matcher subjects, then use `matcherDiagnostic` to reject an invalid consumed regex with a stable diagnostic before registering any hooks. The runtime predicate still contains an invalid pattern as a non-match, so a direct library caller cannot throw into the agent loop.
|
|
23
|
-
- **`runHook(bash, hook, options, now)`** — require and forward the caller-owned `options.signal`, serialize `options.payload` to the hook's stdin (with a trailing newline iff `options.trailingNewline`), merge `options.env` after the executor's credential scrub (the `dsh-
|
|
23
|
+
- **`runHook(bash, hook, options, now)`** — require and forward the caller-owned `options.signal`, serialize `options.payload` to the hook's stdin (with a trailing newline iff `options.trailingNewline`), merge `options.env` after the executor's credential scrub (the `dsh-shell` trusted-plugin API), honor the hook's `timeoutSec` (else `options.defaultTimeoutMs` — the bridge owns the default, its config defaulting to the lib's `DEFAULT_HOOK_TIMEOUT_MS` 10-minute reference), and decode the result (threading `options.expectedEventName` to the codec). Cancellation therefore reaches the executor's process-group kill and join boundary. Never throws: an executor rejection (infra fault) becomes a `HookOutput` with `exitCode: undefined` (a non-blocking error). `now` is injected for testable durations.
|
|
24
24
|
- **`parseHookOutput(exitCode, stdout, stderr, expectedEventName?)`** decodes exit status and structured stdout. Exit 2 blocks with stderr; other failures are non-blocking. A matching hook-specific permission decision overrides the legacy top-level decision; mismatched or missing event discriminators suppress only event-specific fields. Top-level fields remain event-agnostic, and successful non-JSON output is left to the bridge.
|
|
25
25
|
- **`mergeHookOutputs(outputs)`** — fold the results of every hook that matched one point: permission precedence **deny > ask > allow**, halt sticky on the first `continue:false`, block reasons joined with `\n\n`, `additionalContext`/`systemMessages` accumulated in order.
|
|
26
26
|
- **`createDetachedRuns()`** — quiescence tracking for the emit-shaped points, which run detached (no extension point awaits them). The bridge tracks each run chain — the hook run PLUS its continuation — and registers `drain()` as its effect disposer: drain fires the tracker's abort `signal` (so a still-running hook process is killed via `runHook`, not awaited out to its timeout), then resolves once every tracked chain has settled. `fiber.dispose()` resolving therefore means no detached hook work is left to fire into a disposed context ([defensive patterns](../../../docs/defensive-patterns.md): dispose must reach quiescence).
|
|
27
27
|
|
|
28
28
|
## `hook/*` session events
|
|
29
29
|
|
|
30
|
-
Declaration-merged into `SessionEventMap` (log-only, like `
|
|
30
|
+
Declaration-merged into `SessionEventMap` (log-only, like `compaction/*` — NOT a `SurfaceEventType`, no `surfaceOp`): `hook/invoked` (a hook command ran) and `hook/result` (its outcome, paired by `handlerId`, with `appendHookResult` owning the decision rule). Payloads and per-event JSDoc are in the generated [persistence log event catalog](../../../docs/persistence-catalog.md); `stderrSummary` is truncated to the record's `stderrSummaryMaxChars` (the bridge's config, reference default `DEFAULT_STDERR_SUMMARY_MAX_CHARS` = 500; omitted when empty).
|
|
31
31
|
|
|
32
32
|
Hook invocation/result records must sit inside an open turn. `UserPromptSubmit`, `PreToolUse`, `PostToolUse`, and `Stop` satisfy that owner-defined relation by construction. `SessionStart` runs before turn 1 and gets no `hook/*` record; its allowed context remains pending in the inbox until a waking delivery opens a turn — see the hooks Agent Note.
|
|
33
33
|
|
|
34
34
|
## Model Experience
|
|
35
35
|
|
|
36
|
-
Indirectly, through `dsh-hooks-claude` and `dsh-hooks-codex`, which can turn parsed hook output into prompt context, blocked outcomes, or continuation feedback.
|
|
36
|
+
Indirectly, through `dsh-hooks-claude-code` and `dsh-hooks-codex`, which can turn parsed hook output into prompt context, blocked outcomes, or continuation feedback.
|
|
37
37
|
|
|
38
38
|
#### KV Cache effect
|
|
39
39
|
|
package/README.zh.md
CHANGED
|
@@ -2,38 +2,38 @@
|
|
|
2
2
|
|
|
3
3
|
[English](README.md) | 中文
|
|
4
4
|
|
|
5
|
-
Claude Code/Codex hook 协议格式(wire format)的**共享核心**。它不是 Cordis 插件:不注册也不注入任何内容。它是一个**库**,提供两个桥接插件(`@deepseek-ai/dsh-hooks-claude`、`@deepseek-ai/dsh-hooks-codex`)导入的方言无关原语,使两者都无需重复实现协议中相同的部分。
|
|
5
|
+
Claude Code/Codex hook 协议格式(wire format)的**共享核心**。它不是 Cordis 插件:不注册也不注入任何内容。它是一个**库**,提供两个桥接插件(`@deepseek-ai/dsh-hooks-claude-code`、`@deepseek-ai/dsh-hooks-codex`)导入的方言无关原语,使两者都无需重复实现协议中相同的部分。
|
|
6
6
|
|
|
7
7
|
Codex 有意重新实现了 Claude Code hook 协议的一个*子集*,包括相同的 `hooks.json` matcher group 结构、相同的退出码/stdout 输出约定以及相同的 command hook 执行模式。真正共享的部分位于此处;每个桥接只负责不同的部分。
|
|
8
8
|
|
|
9
9
|
## 共享内容(此处)与各方言内容(桥接)
|
|
10
10
|
|
|
11
|
-
| 关注点 | 此处(`dsh-hook-protocol`) | 桥接(`dsh-hooks-claude` / `-codex`) |
|
|
11
|
+
| 关注点 | 此处(`dsh-hook-protocol`) | 桥接(`dsh-hooks-claude-code` / `-codex`) |
|
|
12
12
|
|---|---|---|
|
|
13
|
-
| Matcher
|
|
14
|
-
| 运行 hook | `runHook(bash, hook, opts, now)`:通过 `ctx.
|
|
13
|
+
| Matcher 校验与匹配判断 | `matcherDiagnostic(pattern, mode)` 用于解析时诊断;`matchesMatcher(pattern, query, mode)` 用于隔离的运行时匹配 | 选择自身的 `mode`(`claude` = 字面量或正则,`codex` = 始终使用正则),并拒绝带有诊断的配置组 |
|
|
14
|
+
| 运行 hook | `runHook(bash, hook, opts, now)`:通过 `ctx.shell` 提供 stdin payload + env,再解码 | 构造每个事件的 stdin **payload** + 该方言的 **env** |
|
|
15
15
|
| 解码输出 | `parseHookOutput(exit, stdout, stderr)` → 中性 `HookOutput` | 将中性 `HookOutput` 映射到扩展点特定的类型化 Decision |
|
|
16
16
|
| 合并 N 个 hook | `mergeHookOutputs(outputs)` → 最严格的 `MergedHookOutcome` | (无) |
|
|
17
17
|
| 持久记录 | `appendHookInvoked` / `appendHookResult`(`hook/*` 会话事件;结果的 `decision`/`stderrSummary` 从此处的 `HookOutput` 派生) | 在每次调用前后调用它们 |
|
|
18
|
-
|
|
|
18
|
+
| 脱离运行的完全停稳 | `createDetachedRuns()`:跟踪触发后不等待的运行链;`drain()` 先 abort,再等待它们 | 将 `signal` 传给每个脱离的 `runHook`,并将 `drain` 注册为 effect disposer |
|
|
19
19
|
|
|
20
20
|
## 原语
|
|
21
21
|
|
|
22
22
|
- **`matcherDiagnostic(matcher, mode)` / `matchesMatcher(matcher, query, mode)`**:缺失、`''` 或 `'*'` 时匹配全部;`claude` mode 将纯 `[A-Za-z0-9_|]+` pattern 视为字面量(管道符 = 精确匹配交替),其他 pattern 视为正则;`codex` mode 始终使用未锚定正则。桥接解析器会丢弃没有 matcher 匹配对象的事件所带的 matcher 字段,再用 `matcherDiagnostic` 拒绝事件实际使用的无效正则,并在注册任何钩子之前给出稳定诊断。运行时谓词仍会将无效 pattern 隔离为不匹配,因此直接调用本库不会向 agent loop(智能体循环)抛异常。
|
|
23
|
-
- **`runHook(bash, hook, options, now)`**:要求并转发调用方拥有的 `options.signal`,将 `options.payload` 序列化到 hook stdin(当且仅当 `options.trailingNewline` 时添加尾随换行符),在执行器凭证清理后合并 `options.env`(`dsh-
|
|
23
|
+
- **`runHook(bash, hook, options, now)`**:要求并转发调用方拥有的 `options.signal`,将 `options.payload` 序列化到 hook stdin(当且仅当 `options.trailingNewline` 时添加尾随换行符),在执行器凭证清理后合并 `options.env`(`dsh-shell` 受信任插件接口),遵循 hook 的 `timeoutSec`(否则使用 `options.defaultTimeoutMs`;默认值属于桥接,其配置默认为 lib 的 `DEFAULT_HOOK_TIMEOUT_MS` 10 分钟参考值),再解码结果(将 `options.expectedEventName` 传递给 codec)。因此取消会到达执行器的进程组终止与 join 边界。它绝不抛出异常:执行器拒绝(基础设施故障)会变为 `HookOutput`,其 `exitCode: undefined`(非阻塞错误)。`now` 会被注入,以便测试持续时间。
|
|
24
24
|
- **`parseHookOutput(exitCode, stdout, stderr, expectedEventName?)`** 解码退出状态与结构化 stdout。退出码为 2 时,会以 stderr 内容阻止执行;其他失败不阻塞。匹配的 hook 特定权限决策会覆盖遗留顶层决策;事件判别字段不匹配或缺失只会抑制事件特定字段。顶层字段仍与事件无关,成功但非 JSON 的输出会留给桥接处理。
|
|
25
25
|
- **`mergeHookOutputs(outputs)`**:折叠在一个点上匹配的每个 hook 结果:权限优先级为 **deny > ask > allow**,从首个 `continue:false` 起,halt 状态保持不变,阻塞原因用 `\n\n` 连接,`additionalContext`/`systemMessages` 按顺序累积。
|
|
26
26
|
- **`createDetachedRuns()`**:跟踪以 emit 形式脱离运行的点是否完全停稳(没有扩展点等待它们)。桥接会跟踪每条运行链,包括 hook 运行及其 continuation,并将 `drain()` 注册为 effect disposer。drain 会触发 tracker 的 abort `signal`(因此仍在运行的 hook 进程会通过 `runHook` 终止,而不是等待到超时),随后在所有已跟踪链结算后 resolve。因此 `fiber.dispose()` resolve 时,不会遗留任何可能作用于已 dispose(资源释放)的上下文的脱离 hook 工作(见 [防御模式](../../../docs/defensive-patterns.md):dispose 必须达到完全停稳)。
|
|
27
27
|
|
|
28
28
|
## `hook/*` 会话事件
|
|
29
29
|
|
|
30
|
-
通过 declaration merging 合并到 `SessionEventMap`(仅日志,与 `
|
|
30
|
+
通过 declaration merging 合并到 `SessionEventMap`(仅日志,与 `compaction/*` 相同;不是 `SurfaceEventType`,没有 `surfaceOp`):`hook/invoked`(hook 命令已运行)与 `hook/result`(其结果,按 `handlerId` 配对,决策规则由 `appendHookResult` 负责)。Payload 与每事件 JSDoc 位于生成的 [持久化日志事件目录](../../../docs/persistence-catalog.md);`stderrSummary` 会截断到记录的 `stderrSummaryMaxChars`(桥接配置,参考默认值 `DEFAULT_STDERR_SUMMARY_MAX_CHARS` = 500;为空时省略)。
|
|
31
31
|
|
|
32
32
|
Hook 调用/结果记录必须位于一个尚未结束的轮次内。`UserPromptSubmit`、`PreToolUse`、`PostToolUse` 与 `Stop` 按构造满足这条由所有者定义的关系。`SessionStart` 在轮次 1 之前运行,因此没有 `hook/*` 记录;其获准的上下文会在 inbox 中保持待处理,直到唤醒交付打开一个轮次,详见 hooks Agent Note。
|
|
33
33
|
|
|
34
34
|
## 模型体验
|
|
35
35
|
|
|
36
|
-
通过 `dsh-hooks-claude` 与 `dsh-hooks-codex` 间接影响;它们可以将解析后 hook 输出转为提示词上下文、已阻塞结果或 continuation 反馈。
|
|
36
|
+
通过 `dsh-hooks-claude-code` 与 `dsh-hooks-codex` 间接影响;它们可以将解析后 hook 输出转为提示词上下文、已阻塞结果或 continuation 反馈。
|
|
37
37
|
|
|
38
38
|
#### KV Cache 影响
|
|
39
39
|
|
package/lib/index.js
CHANGED
|
@@ -30,7 +30,7 @@ function compileRegex(pattern) {
|
|
|
30
30
|
function matcherDiagnostic(matcher, mode) {
|
|
31
31
|
if (isMatchAll(matcher)) return void 0;
|
|
32
32
|
const pattern = matcher;
|
|
33
|
-
if (mode === "claude" && CLAUDE_LITERAL.test(pattern)) return void 0;
|
|
33
|
+
if (mode === "claude-code" && CLAUDE_LITERAL.test(pattern)) return void 0;
|
|
34
34
|
return compileRegex(pattern) === void 0 ? `invalid ${mode} regex matcher ${JSON.stringify(pattern)}` : void 0;
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
@@ -47,7 +47,7 @@ function matcherDiagnostic(matcher, mode) {
|
|
|
47
47
|
function matchesMatcher(matcher, query, mode) {
|
|
48
48
|
if (isMatchAll(matcher)) return true;
|
|
49
49
|
const pattern = matcher;
|
|
50
|
-
if (mode === "claude" && CLAUDE_LITERAL.test(pattern)) return pattern.split("|").includes(query);
|
|
50
|
+
if (mode === "claude-code" && CLAUDE_LITERAL.test(pattern)) return pattern.split("|").includes(query);
|
|
51
51
|
return compileRegex(pattern)?.test(query) ?? false;
|
|
52
52
|
}
|
|
53
53
|
//#endregion
|
|
@@ -159,7 +159,7 @@ function applyStructured(output, parsed, expectedEventName) {
|
|
|
159
159
|
//#endregion
|
|
160
160
|
//#region lib/types/runner.js
|
|
161
161
|
/**
|
|
162
|
-
* Execute command hooks through `ctx.
|
|
162
|
+
* Execute command hooks through `ctx.shell`, using its credential scrub,
|
|
163
163
|
* process-group cancellation, and timeout machinery. The bridge supplies the
|
|
164
164
|
* trusted stdin payload and dialect environment, then this module decodes the
|
|
165
165
|
* captured outcome.
|
|
@@ -170,7 +170,7 @@ function applyStructured(output, parsed, expectedEventName) {
|
|
|
170
170
|
* Claude Code and Codex apply to a hook whose config sets no `timeout`. It
|
|
171
171
|
* lives here, once, as the protocol's default; the bridges' `defaultTimeoutMs`
|
|
172
172
|
* config defaults to it, and a per-hook {@link CommandHook.timeoutSec} is the
|
|
173
|
-
* override
|
|
173
|
+
* override API.
|
|
174
174
|
*/
|
|
175
175
|
const DEFAULT_HOOK_TIMEOUT_MS = 6e5;
|
|
176
176
|
/**
|
package/lib/invariant.js
CHANGED
|
@@ -17,7 +17,7 @@ function validateHookEvent(trace, event, fail) {
|
|
|
17
17
|
if (event.type === "hook/invoked") {
|
|
18
18
|
if (event.data.point.length === 0 || event.data.handlerId.length === 0) fail("hook/invoked point and handlerId must be non-empty");
|
|
19
19
|
const dialect = event.data.dialect;
|
|
20
|
-
if (dialect !== "claude" && dialect !== "codex") fail(`hook/invoked carries unknown dialect ${JSON.stringify(dialect)}`);
|
|
20
|
+
if (dialect !== "claude-code" && dialect !== "codex") fail(`hook/invoked carries unknown dialect ${JSON.stringify(dialect)}`);
|
|
21
21
|
return {
|
|
22
22
|
key: hookKey(event.data),
|
|
23
23
|
delta: 1
|
package/lib/types/runner.d.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Execute command hooks through `ctx.
|
|
2
|
+
* Execute command hooks through `ctx.shell`, using its credential scrub,
|
|
3
3
|
* process-group cancellation, and timeout machinery. The bridge supplies the
|
|
4
4
|
* trusted stdin payload and dialect environment, then this module decodes the
|
|
5
5
|
* captured outcome.
|
|
6
6
|
* @module @deepseek-ai/dsh-hook-protocol/runner
|
|
7
7
|
*/
|
|
8
|
-
import type {
|
|
8
|
+
import type { ShellExecutor } from '@deepseek-ai/dsh-shell';
|
|
9
9
|
import type { CommandHook, HookOutput } from './types.ts';
|
|
10
10
|
/**
|
|
11
11
|
* The reference default per-hook timeout, in ms (10 minutes) — the value both
|
|
12
12
|
* Claude Code and Codex apply to a hook whose config sets no `timeout`. It
|
|
13
13
|
* lives here, once, as the protocol's default; the bridges' `defaultTimeoutMs`
|
|
14
14
|
* config defaults to it, and a per-hook {@link CommandHook.timeoutSec} is the
|
|
15
|
-
* override
|
|
15
|
+
* override API.
|
|
16
16
|
*/
|
|
17
17
|
export declare const DEFAULT_HOOK_TIMEOUT_MS = 600000;
|
|
18
18
|
/** Everything a single hook invocation needs beyond its command line. */
|
|
@@ -58,5 +58,5 @@ export interface RunHookResult {
|
|
|
58
58
|
* @param now - millisecond clock used for the reported duration.
|
|
59
59
|
* @returns the decoded output plus the run's wall-clock duration.
|
|
60
60
|
*/
|
|
61
|
-
export declare function runHook(bash:
|
|
61
|
+
export declare function runHook(bash: ShellExecutor, hook: CommandHook, options: RunHookOptions, now: () => number): Promise<RunHookResult>;
|
|
62
62
|
//# sourceMappingURL=runner.d.ts.map
|
package/lib/types/types.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ declare module '@deepseek-ai/dsh-session/types' {
|
|
|
8
8
|
interface SessionEventMap {
|
|
9
9
|
/**
|
|
10
10
|
* A hook command was invoked at a hook point — a log-only record (like
|
|
11
|
-
* `
|
|
11
|
+
* `compaction/*`; NOT a {@link SurfaceEventType}, carries no `surfaceOp`).
|
|
12
12
|
* `dialect` is the bridge that ran it (`claude`/`codex`), `point`
|
|
13
13
|
* the hook point (`PreToolUse`, `Stop`, …), `matcher` the matcher-group
|
|
14
14
|
* pattern that selected it (absent for match-all), `handlerId` a stable id
|
|
@@ -39,11 +39,11 @@ declare module '@deepseek-ai/dsh-session/types' {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
42
|
-
* The bridge that ran a hook — the CC bridge stamps `'claude'`, the Codex
|
|
42
|
+
* The bridge that ran a hook — the CC bridge stamps `'claude-code'`, the Codex
|
|
43
43
|
* bridge `'codex'`. A native plugin at the interception points is not a bridge
|
|
44
44
|
* and writes no `hook/*` invocation/result records (see the interception extension-points Agent Note).
|
|
45
45
|
*/
|
|
46
|
-
export type HookDialect = 'claude' | 'codex';
|
|
46
|
+
export type HookDialect = 'claude-code' | 'codex';
|
|
47
47
|
/**
|
|
48
48
|
* One configured command hook (the `{ type: 'command', command, timeout? }`
|
|
49
49
|
* shape shared by both dialects). Non-command hook types (CC's `prompt`/`agent`/
|
|
@@ -71,7 +71,7 @@ export interface MatcherGroup {
|
|
|
71
71
|
* {@link regex} otherwise; Codex is always {@link regex}. The bridge picks the
|
|
72
72
|
* mode for its dialect.
|
|
73
73
|
*/
|
|
74
|
-
export type MatcherMode = 'claude' | 'codex';
|
|
74
|
+
export type MatcherMode = 'claude-code' | 'codex';
|
|
75
75
|
/**
|
|
76
76
|
* The dialect-neutral OUTCOME a hook produced, parsed from its exit code +
|
|
77
77
|
* stdout JSON + stderr by {@link parseHookOutput}. A bridge maps this onto a
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-hook-protocol",
|
|
3
3
|
"description": "Shared Claude Code / Codex hook wire protocol: matcher engine, stdin/exit-code/stdout codec, multi-hook merge, and hook/* session events",
|
|
4
|
-
"version": "0.0.1-rc.
|
|
4
|
+
"version": "0.0.1-rc.5",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "restricted"
|
|
7
7
|
},
|
|
@@ -32,15 +32,15 @@
|
|
|
32
32
|
],
|
|
33
33
|
"license": "BSD-3-Clause",
|
|
34
34
|
"peerDependencies": {
|
|
35
|
-
"@deepseek-ai/dsh-
|
|
36
|
-
"@deepseek-ai/dsh-
|
|
37
|
-
"@deepseek-ai/dsh-session": "^0.0.1-rc.
|
|
38
|
-
"@deepseek-ai/cordis": "^4.0.1-rc.
|
|
35
|
+
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.5",
|
|
36
|
+
"@deepseek-ai/dsh-shell": "^0.0.1-rc.5",
|
|
37
|
+
"@deepseek-ai/dsh-session": "^0.0.1-rc.5",
|
|
38
|
+
"@deepseek-ai/cordis": "^4.0.1-rc.4"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@deepseek-ai/dsh-
|
|
42
|
-
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.
|
|
43
|
-
"@deepseek-ai/dsh-session": "^0.0.1-rc.
|
|
44
|
-
"@deepseek-ai/cordis": "^4.0.1-rc.
|
|
41
|
+
"@deepseek-ai/dsh-shell": "^0.0.1-rc.5",
|
|
42
|
+
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.5",
|
|
43
|
+
"@deepseek-ai/dsh-session": "^0.0.1-rc.5",
|
|
44
|
+
"@deepseek-ai/cordis": "^4.0.1-rc.4"
|
|
45
45
|
}
|
|
46
46
|
}
|