@sema-agent/settings-schema 1.2.0 → 1.3.0

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/CHANGELOG.md CHANGED
@@ -6,6 +6,93 @@
6
6
  > `@sema-agent/registry-core`(更早还曾是 `@sema-ai/registry-core`)。本档 `0.19.0` 以下各节里的
7
7
  > 包名是**历史记录**,如实保留不追改。
8
8
 
9
+ ## 1.3.0 — hooks 域加员 `DirectoryAdded`(CC 2.1.219 新事件;`HooksConfig` 拒键病形修复)
10
+
11
+ **`HOOK_EVENTS` 30 → 31:`POST_198_HOOK_EVENTS` **尾插** `DirectoryAdded`(1.2.0 三员声明序逐字节不动;重排 = BREAKING,
12
+ 免裁)。additive:既有 30 员的 matcher 字段 / owner / 输入形 / `hookSpecificOutput` 臂一字不动(FROZEN 1.2.0 全表字面量夹具钉,
13
+ `test/hooks-directory-added-1.3.0.test.ts`,字面量独立誊自 bfbd140、非从现表派生——1.1.0/1.2.0 safety-merge-spec 夹具同律)。
14
+ 版号 minor = 加词(1.2.0 口径)。**
15
+
16
+ ### 病形(修前)
17
+
18
+ `HooksConfig = z.record(HookEventName, …)` 键集**闭合**(设计如此:wire 上抓 typo)——用户 settings 里 `hooks.DirectoryAdded`
19
+ (壳自 CC 2.1.219 起真会点亮的事件)在 1.2.0 下**整条** hooks 配置被拒(zod `Invalid enum value` at key);同时 `HookInput`
20
+ union 无该臂、`HookEventName` 不收该词。壳认得、schema 不收——与 cli `hooksSchema218.test.ts` 建门帖所述「壳自己认得的
21
+ 输入形,壳自己的注册面不收」同形。
22
+
23
+ ### CC 真形(亲读镜像坐标,非按名推断)
24
+
25
+ 来源 = cli 树 `node_modules/@sema-agent/agent-types`(`@anthropic-ai/claude-agent-sdk@0.3.220` `sdk.d.ts` 的镜像,CC 2.1.220,
26
+ 与 0.3.219 逐字节同):
27
+
28
+ - `hooks.d.ts:582-586` `DirectoryAddedHookInput = BaseHookInput & { hook_event_name:'DirectoryAdded'; directory:string;
29
+ source:'slash_command'|'register_repo_root' }`,`@since CC 2.1.219`(:574-575:目录经 `/add-dir` 或 repo-root 注册加入会话
30
+ 工作集;cli `hooksConfigManager.ts:283-287` 文案:`directory` 为绝对路径)。
31
+ - `hooks.d.ts:638` / `runtime.d.ts:111`:CC 序位于 `FileChanged` 与 `MessageDisplay` 之间;本包**尾插**——声明序非规范,
32
+ 枚举当集合用(与 `MinTrust` 1.2.0 同律);夹具钉「1.2.0 三十员 = `HOOK_EVENTS` 逐字节前缀」。
33
+ - `hooks.d.ts:14-17`:上游**无** `hookSpecificOutput` 臂——本版不加臂,测试钉「缺席」(非遗漏)。
34
+ - **matcher 语义**:cli `src/utils/hooks.ts:1706-1760` `getMatchingHooks` 开关**无** `DirectoryAdded` 臂 → 落 `default` →
35
+ `matchQuery` 空 → 所有 matcher 组皆触发;`hooksConfigManager.ts` 该员亦无 `matcherMetadata` ⇒
36
+ `HOOK_EVENT_MATCHER_FIELD.DirectoryAdded = null`(与 CwdChanged / MessageDisplay 同族;entry 上写 `matcher` 仍是合法配置,
37
+ 只是不被查阅)。
38
+ - **owner = `shell`**(工作集在壳;`ENGINE_OWNED_HOOK_EVENTS` 9 员不动,`HOOK_EVENT_OWNER` 为派生表、自动含新员)。
39
+
40
+ ### API 形(全文)
41
+
42
+ ```ts
43
+ export const POST_198_HOOK_EVENTS = ["CwdChanged", "FileChanged", "MessageDisplay", "DirectoryAdded"] as const; // 尾插
44
+ export const DIRECTORY_ADDED_SOURCES = ["slash_command", "register_repo_root"] as const;
45
+ export const DirectoryAddedHookInput = BaseHookInput.extend({
46
+ hook_event_name: z.literal("DirectoryAdded"),
47
+ directory: z.string(),
48
+ source: z.enum(DIRECTORY_ADDED_SOURCES),
49
+ });
50
+ export type DirectoryAddedHookInput = z.infer<typeof DirectoryAddedHookInput>;
51
+ // HookInput union + 1 臂(尾);HOOK_EVENT_MATCHER_FIELD + 1 行(null);HookSpecificOutput 不动;HooksSlotSemantics 不动(非逐员表)
52
+ ```
53
+
54
+ ### 消费方可见(与 1.2.0 同一课:「表不动」≠「消费方零感知」)
55
+
56
+ - **cli**(`package.json` 范围 `^1.2.0`,但 `package-lock.json:1261-1264` **钉 1.2.0**——`npm ci` 不会静默提到 1.3.0;
57
+ 只有 `npm update` / 无锁重解析才命中):**运行时零影响**——cli `src/` 非测试文件对本包只 import `isAtLeast`
58
+ (`src/sema/settings/resolver.ts:28`),hook 符号零运行时消费(亲 grep)。提货影响全在常驻门
59
+ `src/types/hooksSchema218.test.ts`(以本包 `HOOK_EVENTS` 为 canonical 钉三面集合等式):亲读该门代码推断(**未实测**,
60
+ 不动 cli 树)提货 1.3.0 后 **五条**红——**H2**(T1 缺 `DirectoryAdded`)/ **H6**(计数 30≠31)/ **H7**(字面量
61
+ `CANON.length === 30` 与差集 `=== 3`)/ **H8**(按 CANON 31 键铺满喂 initialize,`DirectoryAdded` 对 T1 的 partialRecord
62
+ 是未知键 ⇒ 拒)/ **H10a**(`OLD_27 = CANON − 3` 亦含新员 ⇒ 同因拒);修法 = 该门自注「三面同动」:`coreSchemas.HOOK_EVENTS`
63
+ 加员 + `HookInputSchema` 加臂 + H7 字面量改 31 / 4。其 :177-178 把「`DirectoryAdded` 该不该进 settings 域」记为候裁,
64
+ 本版加员即回应该候裁项(cli 提货时表态);`coreTypes.HOOK_EVENTS`(31 员)与本版集合恰好相等。发布帖须 @cli 点名
65
+ (能力显式表态制)。
66
+ - 持 `Record<HookEventName, …>` 字面量 / 对 `HookEventName` 穷举 `switch` 的消费方:升级即**编译错**(响亮,正是要的)。
67
+ - 用 `HookEventName` / `HookInput` / `HooksConfig` 校验**外部**值的 1.2.0 消费方:收不下 `DirectoryAdded`(名词拒、整条
68
+ config 拒)——这正是本版修的病形;夹具钉住 1.2.0 行为供对照(frozen `z.record(z.enum(HOOK_EVENTS_1_2_0), …)` 拒、1.3.0 收)。
69
+ - **server**(`package.json:58` **精确钉** `"1.2.0"`,无 caret——永不自动提货):亲读 `src/hooks/hook-runner.ts`——
70
+ `parseHooksConfig` 走 `HooksConfig.safeParse`(:200),`createTaskHooks` 按 `HOOK_EVENT_OWNER` 分流(:1179/:1185);提货后
71
+ wire 上 `settings.hooks.DirectoryAdded` 不再被拒,落 shell-owned 分支 = `debug("hook_events_shell_owned")` 记账不点亮不告警
72
+ (:1185-1188)——「配置合法但 owner 是壳」本就是既定语义(非本版新义)。server 无 `Record<HookEventName,…>` 穷举表、
73
+ 无 30 计数钉(亲 grep src + test),提货零编译红零测试红(推断自 grep,提货批自证)。
74
+
75
+ ### 门
76
+
77
+ - **红先**:修前 solo 跑 `test/hooks.test.ts` + `test/hooks-directory-added-1.3.0.test.ts` = **11 红**(新文件 8:集合/
78
+ `HooksConfig` 收键/`HookInput` 判别/导出符号/owner/matcher/前缀冻结/1.2.0 对照;`hooks.test.ts` 计数钉 3)+ `tsc --noEmit`
79
+ **10 错**(全在测试文件——`Record<HookEventName,…>` 无该键、union 收窄为 `never`);修后 34/34 绿、tsc 0 错。
80
+ - **变异刀 4/4 红**(每刀后源文件复原逐字节一致):K1 `POST_198_HOOK_EVENTS` 去员 → vitest 8 红 + tsc 5 错(矩阵多余键 =
81
+ 编译红,穷举表如约响);K2 输入字段 `directory`→`dir` → 判别钉 2 红 + tsc 1 错;K3 matcher `null`→`"directory"` → 1 红;
82
+ K4 重排到 CC 序(DirectoryAdded 前置 MessageDisplay)→ 前缀冻结钉 2 红。
83
+ - **全门**:`npm run build` exit 0;`npm test` 40 文件 / 631 用例全过;`tsc --noEmit` exit 0;dist 亲验(`node -e` 加载
84
+ `dist/index.js`):`HOOK_EVENTS.length===31`、末员 `DirectoryAdded`、owner `shell`、matcher `null`、`HooksConfig` 收
85
+ `{DirectoryAdded:[…]}`;`dist/hooks.d.ts` 含 `DIRECTORY_ADDED_SOURCES` / `DirectoryAddedHookInput`(值+类型)。
86
+ - README 无 hooks 员数句(模块清单未列 hooks 域),无需同步。
87
+ - **codex 对抗复审 R1**(`adversarial-review`,工作树 diff):verdict needs-attention,**1 条 [high]** =「minor 发版必破
88
+ cli 消费方(`^1.2.0` 自动命中,契约门红),建议先落 cli 再发或改用 `^1.2.0` 选不中的版号」。处置:**不是代码缺陷,是发版
89
+ 协同事实**(且是从本段 CHANGELOG 自述推出的)——实证如上:cli 锁文件钉 1.2.0、cli 运行时零 hook 消费、server 精确钉;
90
+ 「破」的实体 = cli 常驻门(该门建门即自注「三面同动」),提货批修门是 cli 侧既定动作;发布走能力显式表态制 @cli。
91
+ 「改版号避开 `^1.2.0`」= 升 major,与 1.2.0 段 codex R2 严格 semver 异议同类,当时记为**候裁项**——本版沿用 minor 口径,
92
+ 异议原样留档供裁。另:codex 沙箱内 `npm run typecheck && npm test` exit 1——**同命令标准环境复跑 exit 0**(typecheck 0
93
+ 错 + 40 文件 631 用例),归因 codex `--sandbox read-only` 下 vitest 写 `node_modules/.vite/vitest` 缓存失败(目录亲验存在;
94
+ 归因为假设,复跑绿为实测)。
95
+
9
96
  ## 1.2.0 — `MinTrust` 排序原语 + `task` 员([5796] 序题 → [5805] schema 认领 / [5807] cli 表态三点)
10
97
 
11
98
  **新导出 `trustRank(layer)` / `isAtLeast(layer, minTrust)`——规范信任阶梯的**单源**(v2-design §1:29 逐字);
package/dist/hooks.d.ts CHANGED
@@ -2,10 +2,10 @@
2
2
  * `hooks` — the CC-parity hooks contract (incl. stop attribution).
3
3
  *
4
4
  * ONE definition of the FULL hook-event set — 27 CC 2.1.198 events (REF: the `jP` array in
5
- * claude-cli-2.1.198.pretty.js) + 3 post-198 events the shell already ships (CwdChanged / FileChanged /
6
- * MessageDisplay). Per the product ruling: the CONTRACT is the full set from day one; the engine
7
- * hook-runner (service) and the shell light events up in PHASES — adding an event later is pure
8
- * implementation, never a schema change.
5
+ * claude-cli-2.1.198.pretty.js) + 4 post-198 events the shell already ships (CwdChanged / FileChanged /
6
+ * MessageDisplay, and DirectoryAdded from CC 2.1.219). Per the product ruling: the CONTRACT is the full set
7
+ * from day one; the engine hook-runner (service) and the shell light events up in PHASES — adding an event
8
+ * later is pure implementation, never a schema change.
9
9
  *
10
10
  * CONSUMERS
11
11
  * - service (sema-server): `TaskRequest.settings.hooks` wire face = `HooksConfig` below; the worker-side
@@ -26,11 +26,15 @@
26
26
  import { z } from "zod";
27
27
  /** CC 2.1.198 full hook-event set (jP array) — 27 events. Order matches the shell's HOOK_EVENTS. */
28
28
  export declare const CC_198_HOOK_EVENTS: readonly ["PreToolUse", "PostToolUse", "PostToolUseFailure", "PostToolBatch", "Notification", "UserPromptSubmit", "UserPromptExpansion", "SessionStart", "SessionEnd", "Stop", "StopFailure", "SubagentStart", "SubagentStop", "PreCompact", "PostCompact", "PermissionRequest", "PermissionDenied", "Setup", "TeammateIdle", "TaskCreated", "TaskCompleted", "Elicitation", "ElicitationResult", "ConfigChange", "WorktreeCreate", "WorktreeRemove", "InstructionsLoaded"];
29
- /** Post-CC-2.1.198 additions the shell already ships (sema superset; CC added them after 198). */
30
- export declare const POST_198_HOOK_EVENTS: readonly ["CwdChanged", "FileChanged", "MessageDisplay"];
31
- /** The full 30-event contract set = CC 198's 27 + the 3 post-198 shell events. */
32
- export declare const HOOK_EVENTS: readonly ["PreToolUse", "PostToolUse", "PostToolUseFailure", "PostToolBatch", "Notification", "UserPromptSubmit", "UserPromptExpansion", "SessionStart", "SessionEnd", "Stop", "StopFailure", "SubagentStart", "SubagentStop", "PreCompact", "PostCompact", "PermissionRequest", "PermissionDenied", "Setup", "TeammateIdle", "TaskCreated", "TaskCompleted", "Elicitation", "ElicitationResult", "ConfigChange", "WorktreeCreate", "WorktreeRemove", "InstructionsLoaded", "CwdChanged", "FileChanged", "MessageDisplay"];
33
- export declare const HookEventName: z.ZodEnum<["PreToolUse", "PostToolUse", "PostToolUseFailure", "PostToolBatch", "Notification", "UserPromptSubmit", "UserPromptExpansion", "SessionStart", "SessionEnd", "Stop", "StopFailure", "SubagentStart", "SubagentStop", "PreCompact", "PostCompact", "PermissionRequest", "PermissionDenied", "Setup", "TeammateIdle", "TaskCreated", "TaskCompleted", "Elicitation", "ElicitationResult", "ConfigChange", "WorktreeCreate", "WorktreeRemove", "InstructionsLoaded", "CwdChanged", "FileChanged", "MessageDisplay"]>;
29
+ /**
30
+ * Post-CC-2.1.198 additions the shell already ships (sema superset; CC added them after 198).
31
+ * APPEND-ONLY: new members go at the tail (1.3.0 `DirectoryAdded`, CC 2.1.219 — CC's own tuple places it
32
+ * between FileChanged and MessageDisplay; the declaration order here is not normative, the enum is a set).
33
+ */
34
+ export declare const POST_198_HOOK_EVENTS: readonly ["CwdChanged", "FileChanged", "MessageDisplay", "DirectoryAdded"];
35
+ /** The full 31-event contract set = CC 198's 27 + the 4 post-198 shell events. */
36
+ export declare const HOOK_EVENTS: readonly ["PreToolUse", "PostToolUse", "PostToolUseFailure", "PostToolBatch", "Notification", "UserPromptSubmit", "UserPromptExpansion", "SessionStart", "SessionEnd", "Stop", "StopFailure", "SubagentStart", "SubagentStop", "PreCompact", "PostCompact", "PermissionRequest", "PermissionDenied", "Setup", "TeammateIdle", "TaskCreated", "TaskCompleted", "Elicitation", "ElicitationResult", "ConfigChange", "WorktreeCreate", "WorktreeRemove", "InstructionsLoaded", "CwdChanged", "FileChanged", "MessageDisplay", "DirectoryAdded"];
37
+ export declare const HookEventName: z.ZodEnum<["PreToolUse", "PostToolUse", "PostToolUseFailure", "PostToolBatch", "Notification", "UserPromptSubmit", "UserPromptExpansion", "SessionStart", "SessionEnd", "Stop", "StopFailure", "SubagentStart", "SubagentStop", "PreCompact", "PostCompact", "PermissionRequest", "PermissionDenied", "Setup", "TeammateIdle", "TaskCreated", "TaskCompleted", "Elicitation", "ElicitationResult", "ConfigChange", "WorktreeCreate", "WorktreeRemove", "InstructionsLoaded", "CwdChanged", "FileChanged", "MessageDisplay", "DirectoryAdded"]>;
34
38
  export type HookEventName = z.infer<typeof HookEventName>;
35
39
  export declare const HookOwner: z.ZodEnum<["engine", "shell"]>;
36
40
  export type HookOwner = z.infer<typeof HookOwner>;
@@ -1586,7 +1590,48 @@ export declare const MessageDisplayHookInput: z.ZodObject<{
1586
1590
  permission_mode?: string | undefined;
1587
1591
  agent_id?: string | undefined;
1588
1592
  }>;
1589
- /** Any hook input discriminated on `hook_event_name` (all 30 events). */
1593
+ /** How a directory joined the session working set: the `/add-dir` slash command or repo-root registration. */
1594
+ export declare const DIRECTORY_ADDED_SOURCES: readonly ["slash_command", "register_repo_root"];
1595
+ /**
1596
+ * Fired after a directory joins the session's working set (CC 2.1.219; agent-types hooks.d.ts:582-586 —
1597
+ * `directory` is the absolute path). Shell-owned; matcher ignored; no hookSpecificOutput arm upstream.
1598
+ */
1599
+ export declare const DirectoryAddedHookInput: z.ZodObject<{
1600
+ session_id: z.ZodString;
1601
+ transcript_path: z.ZodString;
1602
+ cwd: z.ZodString;
1603
+ permission_mode: z.ZodOptional<z.ZodString>;
1604
+ /** Subagent id — present only when the hook fires from within a subagent. */
1605
+ agent_id: z.ZodOptional<z.ZodString>;
1606
+ /** Agent type name (e.g. "general-purpose") — present alongside agent_id, or on --agent main threads. */
1607
+ agent_type: z.ZodOptional<z.ZodString>;
1608
+ } & {
1609
+ hook_event_name: z.ZodLiteral<"DirectoryAdded">;
1610
+ directory: z.ZodString;
1611
+ source: z.ZodEnum<["slash_command", "register_repo_root"]>;
1612
+ }, "strip", z.ZodTypeAny, {
1613
+ source: "slash_command" | "register_repo_root";
1614
+ session_id: string;
1615
+ transcript_path: string;
1616
+ cwd: string;
1617
+ hook_event_name: "DirectoryAdded";
1618
+ directory: string;
1619
+ agent_type?: string | undefined;
1620
+ permission_mode?: string | undefined;
1621
+ agent_id?: string | undefined;
1622
+ }, {
1623
+ source: "slash_command" | "register_repo_root";
1624
+ session_id: string;
1625
+ transcript_path: string;
1626
+ cwd: string;
1627
+ hook_event_name: "DirectoryAdded";
1628
+ directory: string;
1629
+ agent_type?: string | undefined;
1630
+ permission_mode?: string | undefined;
1631
+ agent_id?: string | undefined;
1632
+ }>;
1633
+ export type DirectoryAddedHookInput = z.infer<typeof DirectoryAddedHookInput>;
1634
+ /** Any hook input — discriminated on `hook_event_name` (all 31 events). */
1590
1635
  export declare const HookInput: z.ZodDiscriminatedUnion<"hook_event_name", [z.ZodObject<{
1591
1636
  session_id: z.ZodString;
1592
1637
  transcript_path: z.ZodString;
@@ -2884,6 +2929,39 @@ export declare const HookInput: z.ZodDiscriminatedUnion<"hook_event_name", [z.Zo
2884
2929
  agent_type?: string | undefined;
2885
2930
  permission_mode?: string | undefined;
2886
2931
  agent_id?: string | undefined;
2932
+ }>, z.ZodObject<{
2933
+ session_id: z.ZodString;
2934
+ transcript_path: z.ZodString;
2935
+ cwd: z.ZodString;
2936
+ permission_mode: z.ZodOptional<z.ZodString>;
2937
+ /** Subagent id — present only when the hook fires from within a subagent. */
2938
+ agent_id: z.ZodOptional<z.ZodString>;
2939
+ /** Agent type name (e.g. "general-purpose") — present alongside agent_id, or on --agent main threads. */
2940
+ agent_type: z.ZodOptional<z.ZodString>;
2941
+ } & {
2942
+ hook_event_name: z.ZodLiteral<"DirectoryAdded">;
2943
+ directory: z.ZodString;
2944
+ source: z.ZodEnum<["slash_command", "register_repo_root"]>;
2945
+ }, "strip", z.ZodTypeAny, {
2946
+ source: "slash_command" | "register_repo_root";
2947
+ session_id: string;
2948
+ transcript_path: string;
2949
+ cwd: string;
2950
+ hook_event_name: "DirectoryAdded";
2951
+ directory: string;
2952
+ agent_type?: string | undefined;
2953
+ permission_mode?: string | undefined;
2954
+ agent_id?: string | undefined;
2955
+ }, {
2956
+ source: "slash_command" | "register_repo_root";
2957
+ session_id: string;
2958
+ transcript_path: string;
2959
+ cwd: string;
2960
+ hook_event_name: "DirectoryAdded";
2961
+ directory: string;
2962
+ agent_type?: string | undefined;
2963
+ permission_mode?: string | undefined;
2964
+ agent_id?: string | undefined;
2887
2965
  }>]>;
2888
2966
  export type HookInput = z.infer<typeof HookInput>;
2889
2967
  /** Legacy top-level decision (CC): "approve" ≈ allow, "block" feeds `reason` back to the model. */
@@ -5442,7 +5520,7 @@ export declare const HookMatcherEntry: z.ZodObject<{
5442
5520
  export type HookMatcherEntry = z.infer<typeof HookMatcherEntry>;
5443
5521
  /**
5444
5522
  * The hooks config record — the shape `TaskRequest.settings.hooks` carries on the wire and the shell
5445
- * reads from settings JSON: `{ [eventName]: [{ matcher?, hooks: [...] }] }`. Keys limited to the 30
5523
+ * reads from settings JSON: `{ [eventName]: [{ matcher?, hooks: [...] }] }`. Keys limited to the 31
5446
5524
  * contract events (an unknown event name fails parse — catch typos at the wire); all keys optional.
5447
5525
  */
5448
5526
  export type HooksConfig = Partial<Record<HookEventName, HookMatcherEntry[]>>;
package/dist/hooks.js CHANGED
@@ -2,10 +2,10 @@
2
2
  * `hooks` — the CC-parity hooks contract (incl. stop attribution).
3
3
  *
4
4
  * ONE definition of the FULL hook-event set — 27 CC 2.1.198 events (REF: the `jP` array in
5
- * claude-cli-2.1.198.pretty.js) + 3 post-198 events the shell already ships (CwdChanged / FileChanged /
6
- * MessageDisplay). Per the product ruling: the CONTRACT is the full set from day one; the engine
7
- * hook-runner (service) and the shell light events up in PHASES — adding an event later is pure
8
- * implementation, never a schema change.
5
+ * claude-cli-2.1.198.pretty.js) + 4 post-198 events the shell already ships (CwdChanged / FileChanged /
6
+ * MessageDisplay, and DirectoryAdded from CC 2.1.219). Per the product ruling: the CONTRACT is the full set
7
+ * from day one; the engine hook-runner (service) and the shell light events up in PHASES — adding an event
8
+ * later is pure implementation, never a schema change.
9
9
  *
10
10
  * CONSUMERS
11
11
  * - service (sema-server): `TaskRequest.settings.hooks` wire face = `HooksConfig` below; the worker-side
@@ -55,9 +55,13 @@ export const CC_198_HOOK_EVENTS = [
55
55
  "WorktreeRemove",
56
56
  "InstructionsLoaded",
57
57
  ];
58
- /** Post-CC-2.1.198 additions the shell already ships (sema superset; CC added them after 198). */
59
- export const POST_198_HOOK_EVENTS = ["CwdChanged", "FileChanged", "MessageDisplay"];
60
- /** The full 30-event contract set = CC 198's 27 + the 3 post-198 shell events. */
58
+ /**
59
+ * Post-CC-2.1.198 additions the shell already ships (sema superset; CC added them after 198).
60
+ * APPEND-ONLY: new members go at the tail (1.3.0 `DirectoryAdded`, CC 2.1.219 — CC's own tuple places it
61
+ * between FileChanged and MessageDisplay; the declaration order here is not normative, the enum is a set).
62
+ */
63
+ export const POST_198_HOOK_EVENTS = ["CwdChanged", "FileChanged", "MessageDisplay", "DirectoryAdded"];
64
+ /** The full 31-event contract set = CC 198's 27 + the 4 post-198 shell events. */
61
65
  export const HOOK_EVENTS = [...CC_198_HOOK_EVENTS, ...POST_198_HOOK_EVENTS];
62
66
  export const HookEventName = z.enum(HOOK_EVENTS);
63
67
  // ── ownership (owner-single) ─────────────────────────────────────────────────────────────────────
@@ -119,6 +123,7 @@ export const HOOK_EVENT_MATCHER_FIELD = {
119
123
  CwdChanged: null,
120
124
  FileChanged: "file_path", // matched against basename(file_path)
121
125
  MessageDisplay: null,
126
+ DirectoryAdded: null, // the shell's getMatchingHooks switch has no arm for it → every entry matches (CwdChanged family)
122
127
  };
123
128
  // ── shared enums (CC-verbatim) ─────────────────────────────────────────────────────────────────────────
124
129
  export const PermissionBehavior = z.enum(["allow", "deny", "ask"]);
@@ -382,7 +387,18 @@ export const MessageDisplayHookInput = BaseHookInput.extend({
382
387
  /** Newly completed lines since the prior flush (final flush may end mid-line / be empty). */
383
388
  delta: z.string(),
384
389
  });
385
- /** Any hook input discriminated on `hook_event_name` (all 30 events). */
390
+ /** How a directory joined the session working set: the `/add-dir` slash command or repo-root registration. */
391
+ export const DIRECTORY_ADDED_SOURCES = ["slash_command", "register_repo_root"];
392
+ /**
393
+ * Fired after a directory joins the session's working set (CC 2.1.219; agent-types hooks.d.ts:582-586 —
394
+ * `directory` is the absolute path). Shell-owned; matcher ignored; no hookSpecificOutput arm upstream.
395
+ */
396
+ export const DirectoryAddedHookInput = BaseHookInput.extend({
397
+ hook_event_name: z.literal("DirectoryAdded"),
398
+ directory: z.string(),
399
+ source: z.enum(DIRECTORY_ADDED_SOURCES),
400
+ });
401
+ /** Any hook input — discriminated on `hook_event_name` (all 31 events). */
386
402
  export const HookInput = z.discriminatedUnion("hook_event_name", [
387
403
  PreToolUseHookInput,
388
404
  PostToolUseHookInput,
@@ -414,6 +430,7 @@ export const HookInput = z.discriminatedUnion("hook_event_name", [
414
430
  CwdChangedHookInput,
415
431
  FileChangedHookInput,
416
432
  MessageDisplayHookInput,
433
+ DirectoryAddedHookInput,
417
434
  ]);
418
435
  // ── hook output / decision semantics (CC-verbatim, with the service-receipt design points pinned) ────────
419
436
  //
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ export * from "./cross-domain.js"; // pure half only (no fleet placement)
14
14
  export * from "./remote-exec.js";
15
15
  export * from "./safety-merge-spec.js"; // #14 per-category safety merge-spec (settings resolver authority)
16
16
  export * from "./scheduler-store.js"; // R7 self-wake scheduler store CONTRACT (pure: type + parse/serialize + SchedulerStore interface; fs binding in ./node)
17
- export * from "./hooks.js"; // CC-parity hooks contract (30-event set + owner map + per-event input/output shapes + HooksConfig) & stop attribution (stoppedBy) — pure/browser-safe
17
+ export * from "./hooks.js"; // CC-parity hooks contract (31-event set + owner map + per-event input/output shapes + HooksConfig) & stop attribution (stoppedBy) — pure/browser-safe
18
18
  export * from "./fleet.js"; // scheduling/fleet contract (drain protocol · instance discovery · dispatch policy · quota lease · usage report · quota reset event) — CONTROL-PLANE-SCHEDULING-DESIGN, pure/browser-safe
19
19
  export * from "./migrate.js"; // 0.5→0.6 migration tools (hosts grandfathering + worker.model→catalog migration PLAN — report/draft only, E1; EXPERT-REDESIGN §2-2/§3), pure/browser-safe
20
20
  export * from "./api/auth.js"; // /api/v1/auth/* wire contract (RFC 8628 device flow + rotating refresh + logout + approve) — REGISTRY-REBUILD-DESIGN §2, M1 shipped shapes frozen, pure/browser-safe
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/settings-schema",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Sema settings schema — pure config contract (zod domains + effective-config + roster resolution + ref-integrity + remoteExec) shared by sema-registry, sema-server, and the TOC desktop/CLI. One source of truth. (Renamed at 1.0.0 from @sema-agent/registry-core — name and docs only, no behavior change; note the range moves 0.19.0 -> 1.0.0, so a dependency must become ^1.0.0. The old names @sema-agent/registry-core <=0.19.0 and @sema-ai/registry-core remain published, frozen, for migration.)",
5
5
  "type": "module",
6
6
  "license": "BUSL-1.1",