@shgroup/opencode-serenity-plugin 0.2.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.
Files changed (151) hide show
  1. package/README.md +199 -0
  2. package/bin/opencode-serenity-plugin.js +316 -0
  3. package/dist/activation.d.ts +40 -0
  4. package/dist/activation.d.ts.map +1 -0
  5. package/dist/activation.js +133 -0
  6. package/dist/activation.js.map +1 -0
  7. package/dist/bash-override.d.ts +10 -0
  8. package/dist/bash-override.d.ts.map +1 -0
  9. package/dist/bash-override.js +24 -0
  10. package/dist/bash-override.js.map +1 -0
  11. package/dist/bash-toggle.d.ts +17 -0
  12. package/dist/bash-toggle.d.ts.map +1 -0
  13. package/dist/bash-toggle.js +42 -0
  14. package/dist/bash-toggle.js.map +1 -0
  15. package/dist/config-schema.d.ts +300 -0
  16. package/dist/config-schema.d.ts.map +1 -0
  17. package/dist/config-schema.js +185 -0
  18. package/dist/config-schema.js.map +1 -0
  19. package/dist/errors.d.ts +90 -0
  20. package/dist/errors.d.ts.map +1 -0
  21. package/dist/errors.js +151 -0
  22. package/dist/errors.js.map +1 -0
  23. package/dist/fs/file-system-tool.d.ts +25 -0
  24. package/dist/fs/file-system-tool.d.ts.map +1 -0
  25. package/dist/fs/file-system-tool.js +318 -0
  26. package/dist/fs/file-system-tool.js.map +1 -0
  27. package/dist/fs/resolve-path.d.ts +53 -0
  28. package/dist/fs/resolve-path.d.ts.map +1 -0
  29. package/dist/fs/resolve-path.js +100 -0
  30. package/dist/fs/resolve-path.js.map +1 -0
  31. package/dist/hooks/compacting.d.ts +23 -0
  32. package/dist/hooks/compacting.d.ts.map +1 -0
  33. package/dist/hooks/compacting.js +90 -0
  34. package/dist/hooks/compacting.js.map +1 -0
  35. package/dist/hooks/permission-auto-reply.d.ts +91 -0
  36. package/dist/hooks/permission-auto-reply.d.ts.map +1 -0
  37. package/dist/hooks/permission-auto-reply.js +158 -0
  38. package/dist/hooks/permission-auto-reply.js.map +1 -0
  39. package/dist/hooks/permission-guards.d.ts +41 -0
  40. package/dist/hooks/permission-guards.d.ts.map +1 -0
  41. package/dist/hooks/permission-guards.js +153 -0
  42. package/dist/hooks/permission-guards.js.map +1 -0
  43. package/dist/hooks/shell-env.d.ts +20 -0
  44. package/dist/hooks/shell-env.d.ts.map +1 -0
  45. package/dist/hooks/shell-env.js +38 -0
  46. package/dist/hooks/shell-env.js.map +1 -0
  47. package/dist/hooks/util.d.ts +81 -0
  48. package/dist/hooks/util.d.ts.map +1 -0
  49. package/dist/hooks/util.js +172 -0
  50. package/dist/hooks/util.js.map +1 -0
  51. package/dist/index.d.ts +26 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +63 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/init/init-wizard.d.ts +39 -0
  56. package/dist/init/init-wizard.d.ts.map +1 -0
  57. package/dist/init/init-wizard.js +297 -0
  58. package/dist/init/init-wizard.js.map +1 -0
  59. package/dist/install.d.ts +117 -0
  60. package/dist/install.d.ts.map +1 -0
  61. package/dist/install.js +255 -0
  62. package/dist/install.js.map +1 -0
  63. package/dist/msm-schema.d.ts +76 -0
  64. package/dist/msm-schema.d.ts.map +1 -0
  65. package/dist/msm-schema.js +207 -0
  66. package/dist/msm-schema.js.map +1 -0
  67. package/dist/msm.d.ts +25 -0
  68. package/dist/msm.d.ts.map +1 -0
  69. package/dist/msm.js +317 -0
  70. package/dist/msm.js.map +1 -0
  71. package/dist/session/lib.d.ts +33 -0
  72. package/dist/session/lib.d.ts.map +1 -0
  73. package/dist/session/lib.js +475 -0
  74. package/dist/session/lib.js.map +1 -0
  75. package/dist/session/session-tool.d.ts +17 -0
  76. package/dist/session/session-tool.d.ts.map +1 -0
  77. package/dist/session/session-tool.js +109 -0
  78. package/dist/session/session-tool.js.map +1 -0
  79. package/dist/skills/install-skill.d.ts +36 -0
  80. package/dist/skills/install-skill.d.ts.map +1 -0
  81. package/dist/skills/install-skill.js +91 -0
  82. package/dist/skills/install-skill.js.map +1 -0
  83. package/dist/skills/template-loader.d.ts +79 -0
  84. package/dist/skills/template-loader.d.ts.map +1 -0
  85. package/dist/skills/template-loader.js +170 -0
  86. package/dist/skills/template-loader.js.map +1 -0
  87. package/dist/state.d.ts +35 -0
  88. package/dist/state.d.ts.map +1 -0
  89. package/dist/state.js +62 -0
  90. package/dist/state.js.map +1 -0
  91. package/dist/tui.d.ts +61 -0
  92. package/dist/tui.d.ts.map +1 -0
  93. package/dist/tui.js +279 -0
  94. package/dist/tui.js.map +1 -0
  95. package/dist/types/index.d.ts +30 -0
  96. package/dist/types/index.d.ts.map +1 -0
  97. package/dist/types/index.js +17 -0
  98. package/dist/types/index.js.map +1 -0
  99. package/dist/util/config-patch.d.ts +58 -0
  100. package/dist/util/config-patch.d.ts.map +1 -0
  101. package/dist/util/config-patch.js +117 -0
  102. package/dist/util/config-patch.js.map +1 -0
  103. package/dist/util/git.d.ts +29 -0
  104. package/dist/util/git.d.ts.map +1 -0
  105. package/dist/util/git.js +74 -0
  106. package/dist/util/git.js.map +1 -0
  107. package/dist/util/init-check.d.ts +22 -0
  108. package/dist/util/init-check.d.ts.map +1 -0
  109. package/dist/util/init-check.js +76 -0
  110. package/dist/util/init-check.js.map +1 -0
  111. package/dist/util/init.d.ts +54 -0
  112. package/dist/util/init.d.ts.map +1 -0
  113. package/dist/util/init.js +87 -0
  114. package/dist/util/init.js.map +1 -0
  115. package/dist/util/log.d.ts +25 -0
  116. package/dist/util/log.d.ts.map +1 -0
  117. package/dist/util/log.js +28 -0
  118. package/dist/util/log.js.map +1 -0
  119. package/dist/util/msm-call.d.ts +48 -0
  120. package/dist/util/msm-call.d.ts.map +1 -0
  121. package/dist/util/msm-call.js +86 -0
  122. package/dist/util/msm-call.js.map +1 -0
  123. package/dist/util/msm-exec-runtime.d.ts +123 -0
  124. package/dist/util/msm-exec-runtime.d.ts.map +1 -0
  125. package/dist/util/msm-exec-runtime.js +532 -0
  126. package/dist/util/msm-exec-runtime.js.map +1 -0
  127. package/dist/util/path.d.ts +10 -0
  128. package/dist/util/path.d.ts.map +1 -0
  129. package/dist/util/path.js +21 -0
  130. package/dist/util/path.js.map +1 -0
  131. package/dist/util/ready-state.d.ts +43 -0
  132. package/dist/util/ready-state.d.ts.map +1 -0
  133. package/dist/util/ready-state.js +104 -0
  134. package/dist/util/ready-state.js.map +1 -0
  135. package/dist/util/serenity-file.d.ts +30 -0
  136. package/dist/util/serenity-file.d.ts.map +1 -0
  137. package/dist/util/serenity-file.js +69 -0
  138. package/dist/util/serenity-file.js.map +1 -0
  139. package/dist/util/tui-install.d.ts +61 -0
  140. package/dist/util/tui-install.d.ts.map +1 -0
  141. package/dist/util/tui-install.js +94 -0
  142. package/dist/util/tui-install.js.map +1 -0
  143. package/docs/architecture-v0.md +294 -0
  144. package/docs/contract-v0.md +417 -0
  145. package/docs/plugin-self-contained-msm-v1.md +182 -0
  146. package/docs/refactor-direction-v1.11.md +78 -0
  147. package/docs/requirements-v0-scope.md +104 -0
  148. package/docs/requirements-v0-summary.md +108 -0
  149. package/docs/rr7-init-design.md +304 -0
  150. package/docs/v0.1-candidates.md +132 -0
  151. package/package.json +54 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activation.js","sourceRoot":"","sources":["../src/activation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 同名 bash tool — RR3 核心实现
3
+ *
4
+ * 通过注册同名 `bash` tool 覆盖 opencode 内置 bash
5
+ * execute 内部抛 BashDisabledError
6
+ * L3 验证:同名 tool 后注册覆盖前注册(registry.ts:271 + tools.ts:83)
7
+ */
8
+ import { type ToolDefinition } from '@opencode-ai/plugin';
9
+ export declare const bashOverrideTool: ToolDefinition;
10
+ //# sourceMappingURL=bash-override.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash-override.d.ts","sourceRoot":"","sources":["../src/bash-override.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAQ,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAIhE,eAAO,MAAM,gBAAgB,EAAE,cAa7B,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * 同名 bash tool — RR3 核心实现
3
+ *
4
+ * 通过注册同名 `bash` tool 覆盖 opencode 内置 bash
5
+ * execute 内部抛 BashDisabledError
6
+ * L3 验证:同名 tool 后注册覆盖前注册(registry.ts:271 + tools.ts:83)
7
+ */
8
+ import { tool } from '@opencode-ai/plugin';
9
+ import { z } from 'zod';
10
+ import { BashDisabledError } from './errors.js';
11
+ export const bashOverrideTool = tool({
12
+ description: '[SERENITY OVERRIDE] The native `bash` tool is **disabled by serenity policy (RR3)**. ' +
13
+ 'Use `msm_list` to discover available MSMs, then `msm_exec` to invoke one. ' +
14
+ 'If you need a new shell operation, ask the user to register a new MSM in mech-registry.json first.',
15
+ args: {
16
+ command: z.string().describe('(disabled)'),
17
+ description: z.string().optional().describe('(disabled)'),
18
+ },
19
+ execute: async () => {
20
+ // 抛错:opencode 把错误返回给 LLM,让 LLM 看到为什么不能调 bash
21
+ throw new BashDisabledError();
22
+ },
23
+ });
24
+ //# sourceMappingURL=bash-override.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash-override.js","sourceRoot":"","sources":["../src/bash-override.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,IAAI,EAAuB,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,CAAC,MAAM,gBAAgB,GAAmB,IAAI,CAAC;IACnD,WAAW,EACT,uFAAuF;QACvF,4EAA4E;QAC5E,oGAAoG;IACtG,IAAI,EAAE;QACJ,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC;QAC1C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC;KAC1D;IACD,OAAO,EAAE,KAAK,IAAI,EAAE;QAClB,6CAA6C;QAC7C,MAAM,IAAI,iBAAiB,EAAE,CAAC;IAChC,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * bash-toggle.ts — Bash 开关状态管理(文件 IPC)
3
+ *
4
+ * 架构:
5
+ * TUI entry(slash command) ──写入──→ /tmp/serenity-bash-state
6
+ * Server entry(hook) ──读取──→ /tmp/serenity-bash-state
7
+ *
8
+ * 因为 TUI 和 Server 是两个独立的 Node.js 进程,模块级变量不共享。
9
+ * 用 /tmp 文件作为 IPC 通道。/tmp 重启即清,符合"不保留"要求。
10
+ *
11
+ * 默认值:bash 启用(bashDisabled = false)。文件不存在时视为启用。
12
+ */
13
+ /** bash 是否被禁用(默认 false = 启用) */
14
+ export declare function isBashDisabled(): boolean;
15
+ /** 设置 bash 禁用状态 */
16
+ export declare function setBashDisabled(v: boolean): void;
17
+ //# sourceMappingURL=bash-toggle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash-toggle.d.ts","sourceRoot":"","sources":["../src/bash-toggle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AASH,gCAAgC;AAChC,wBAAgB,cAAc,IAAI,OAAO,CAQxC;AAED,mBAAmB;AACnB,wBAAgB,eAAe,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAShD"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * bash-toggle.ts — Bash 开关状态管理(文件 IPC)
3
+ *
4
+ * 架构:
5
+ * TUI entry(slash command) ──写入──→ /tmp/serenity-bash-state
6
+ * Server entry(hook) ──读取──→ /tmp/serenity-bash-state
7
+ *
8
+ * 因为 TUI 和 Server 是两个独立的 Node.js 进程,模块级变量不共享。
9
+ * 用 /tmp 文件作为 IPC 通道。/tmp 重启即清,符合"不保留"要求。
10
+ *
11
+ * 默认值:bash 启用(bashDisabled = false)。文件不存在时视为启用。
12
+ */
13
+ import { readFileSync, writeFileSync, existsSync } from 'node:fs';
14
+ import { tmpdir } from 'node:os';
15
+ import { join } from 'node:path';
16
+ import { log } from './util/log.js';
17
+ const STATE_FILE = join(tmpdir(), 'serenity-bash-state');
18
+ /** bash 是否被禁用(默认 false = 启用) */
19
+ export function isBashDisabled() {
20
+ try {
21
+ if (!existsSync(STATE_FILE))
22
+ return false;
23
+ const content = readFileSync(STATE_FILE, 'utf8').trim();
24
+ return content === 'true';
25
+ }
26
+ catch {
27
+ return false;
28
+ }
29
+ }
30
+ /** 设置 bash 禁用状态 */
31
+ export function setBashDisabled(v) {
32
+ try {
33
+ writeFileSync(STATE_FILE, v ? 'true' : 'false', 'utf8');
34
+ log.info('bash-toggle', `bash ${v ? 'disabled' : 'enabled'}`);
35
+ }
36
+ catch (err) {
37
+ log.warn('bash-toggle', 'failed to write state file', {
38
+ error: err instanceof Error ? err.message : String(err),
39
+ });
40
+ }
41
+ }
42
+ //# sourceMappingURL=bash-toggle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash-toggle.js","sourceRoot":"","sources":["../src/bash-toggle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAEpC,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,qBAAqB,CAAC,CAAC;AAEzD,gCAAgC;AAChC,MAAM,UAAU,cAAc;IAC5B,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;YAAE,OAAO,KAAK,CAAC;QAC1C,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QACxD,OAAO,OAAO,KAAK,MAAM,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,mBAAmB;AACnB,MAAM,UAAU,eAAe,CAAC,CAAU;IACxC,IAAI,CAAC;QACH,aAAa,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACxD,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;IAChE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,4BAA4B,EAAE;YACpD,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
@@ -0,0 +1,300 @@
1
+ /**
2
+ * config-schema.ts — v1.13 zod-first plugin config
3
+ *
4
+ * 设计目标 (D26 决策 — 仿 omo OhMyOpenCodeConfig 模式):
5
+ * - zod schema 作为单一真相源(single source of truth)
6
+ * - TS 类型由 z.infer 派生(避免手写 interface 与 schema 重复)
7
+ * - 公开 parseConfig / safeParseConfig 给配置加载/校验场景
8
+ * - 保留 v1.11 之前的所有 type export (向后兼容, 公共 API 不变)
9
+ *
10
+ * 迁移范围 (v1.13):
11
+ * - MechEntry (msm.ts 内) — zod schema 化
12
+ * - HookConfig (hooks/util.ts 内) — zod schema 化 (轻量, catchall boolean)
13
+ * - 新增 PluginConfig — 用户面向配置 (omo 风格, 启用/禁用 hooks/tools/mcps + 协议层选项)
14
+ *
15
+ * 不在 v1.13 范围 (D26 §3 锁定):
16
+ * - PluginConfig 的实际消费 (parseConfig 在 plugin 入口接线) — 留 v1.15
17
+ * - 把 PluginConfig 写入 opencode.json — 留 v1.15
18
+ * - PluginConfig 与 msm-exec 协议 flag 联动 (msm_exec_format / msm_exec_log) — 留 v1.15
19
+ *
20
+ * 与 v0.2 msm-writing-standards §5 兼容:
21
+ * - 错误处理走 zod.ZodError (6 字段 schema 友好)
22
+ * - safeParseConfig 返回 { success, data, error } 模式(不抛错给调用方)
23
+ */
24
+ import { z, type ZodError } from 'zod';
25
+ /**
26
+ * Plugin 当前注入到 opencode 的 hook 名清单 (v1.18 单一真相源)
27
+ *
28
+ * 与 Hooks (来自 @opencode-ai/plugin) 的子集保持一致 — `satisfies` 保证
29
+ * 此处列出的每一项都是 opencode 真实存在的 hook。
30
+ *
31
+ * 维护规则:新增 hook 时先在此处加常量,再在 createXxxHooks 工厂里用。
32
+ */
33
+ export declare const HOOK_NAMES: readonly ["shell.env", "tool.execute.before", "tool.definition", "experimental.chat.system.transform", "experimental.session.compacting"];
34
+ /** hook 名类型(HOOK_NAMES 元素的 union) */
35
+ export type HookName = (typeof HOOK_NAMES)[number];
36
+ /**
37
+ * flag schema: 兼容 v0 schema (name/type) 和 v1 schema (flag/description)
38
+ * 见 msm-schema.ts 的 normalizeFlag 逻辑
39
+ */
40
+ export declare const mechFlagSchema: z.ZodUnion<readonly [z.ZodObject<{
41
+ name: z.ZodString;
42
+ type: z.ZodDefault<z.ZodString>;
43
+ description: z.ZodOptional<z.ZodString>;
44
+ required: z.ZodOptional<z.ZodBoolean>;
45
+ default: z.ZodOptional<z.ZodUnknown>;
46
+ }, z.core.$strip>, z.ZodObject<{
47
+ flag: z.ZodString;
48
+ description: z.ZodOptional<z.ZodString>;
49
+ }, z.core.$strip>]>;
50
+ /** mech-registry.json 单条 entry schema (v1 包装格式) */
51
+ export declare const mechEntrySchema: z.ZodObject<{
52
+ name: z.ZodString;
53
+ path: z.ZodString;
54
+ skill: z.ZodString;
55
+ category: z.ZodEnum<{
56
+ mech: "mech";
57
+ "semi-mech": "semi-mech";
58
+ }>;
59
+ description: z.ZodString;
60
+ usage: z.ZodString;
61
+ subcommands: z.ZodOptional<z.ZodArray<z.ZodObject<{
62
+ name: z.ZodString;
63
+ description: z.ZodString;
64
+ args: z.ZodOptional<z.ZodArray<z.ZodObject<{
65
+ name: z.ZodString;
66
+ type: z.ZodString;
67
+ required: z.ZodOptional<z.ZodBoolean>;
68
+ description: z.ZodOptional<z.ZodString>;
69
+ }, z.core.$strip>>>;
70
+ flags: z.ZodOptional<z.ZodArray<z.ZodObject<{
71
+ name: z.ZodString;
72
+ type: z.ZodString;
73
+ default: z.ZodOptional<z.ZodUnknown>;
74
+ description: z.ZodOptional<z.ZodString>;
75
+ }, z.core.$strip>>>;
76
+ }, z.core.$strip>>>;
77
+ flags: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
78
+ name: z.ZodString;
79
+ type: z.ZodDefault<z.ZodString>;
80
+ description: z.ZodOptional<z.ZodString>;
81
+ required: z.ZodOptional<z.ZodBoolean>;
82
+ default: z.ZodOptional<z.ZodUnknown>;
83
+ }, z.core.$strip>, z.ZodObject<{
84
+ flag: z.ZodString;
85
+ description: z.ZodOptional<z.ZodString>;
86
+ }, z.core.$strip>]>>>;
87
+ exit_codes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
88
+ error_codes: z.ZodOptional<z.ZodArray<z.ZodString>>;
89
+ }, z.core.$strip>;
90
+ /** 派生 TS 类型 (替代原 msm.ts 内手写 type MechEntry) */
91
+ export type MechEntry = z.infer<typeof mechEntrySchema>;
92
+ /** 注册表顶层 schema */
93
+ export declare const mechRegistryFileSchema: z.ZodUnion<readonly [z.ZodArray<z.ZodObject<{
94
+ name: z.ZodString;
95
+ path: z.ZodString;
96
+ skill: z.ZodString;
97
+ category: z.ZodEnum<{
98
+ mech: "mech";
99
+ "semi-mech": "semi-mech";
100
+ }>;
101
+ description: z.ZodString;
102
+ usage: z.ZodString;
103
+ subcommands: z.ZodOptional<z.ZodArray<z.ZodObject<{
104
+ name: z.ZodString;
105
+ description: z.ZodString;
106
+ args: z.ZodOptional<z.ZodArray<z.ZodObject<{
107
+ name: z.ZodString;
108
+ type: z.ZodString;
109
+ required: z.ZodOptional<z.ZodBoolean>;
110
+ description: z.ZodOptional<z.ZodString>;
111
+ }, z.core.$strip>>>;
112
+ flags: z.ZodOptional<z.ZodArray<z.ZodObject<{
113
+ name: z.ZodString;
114
+ type: z.ZodString;
115
+ default: z.ZodOptional<z.ZodUnknown>;
116
+ description: z.ZodOptional<z.ZodString>;
117
+ }, z.core.$strip>>>;
118
+ }, z.core.$strip>>>;
119
+ flags: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
120
+ name: z.ZodString;
121
+ type: z.ZodDefault<z.ZodString>;
122
+ description: z.ZodOptional<z.ZodString>;
123
+ required: z.ZodOptional<z.ZodBoolean>;
124
+ default: z.ZodOptional<z.ZodUnknown>;
125
+ }, z.core.$strip>, z.ZodObject<{
126
+ flag: z.ZodString;
127
+ description: z.ZodOptional<z.ZodString>;
128
+ }, z.core.$strip>]>>>;
129
+ exit_codes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
130
+ error_codes: z.ZodOptional<z.ZodArray<z.ZodString>>;
131
+ }, z.core.$strip>>, z.ZodObject<{
132
+ version: z.ZodOptional<z.ZodNumber>;
133
+ description: z.ZodOptional<z.ZodString>;
134
+ entries: z.ZodArray<z.ZodObject<{
135
+ name: z.ZodString;
136
+ path: z.ZodString;
137
+ skill: z.ZodString;
138
+ category: z.ZodEnum<{
139
+ mech: "mech";
140
+ "semi-mech": "semi-mech";
141
+ }>;
142
+ description: z.ZodString;
143
+ usage: z.ZodString;
144
+ subcommands: z.ZodOptional<z.ZodArray<z.ZodObject<{
145
+ name: z.ZodString;
146
+ description: z.ZodString;
147
+ args: z.ZodOptional<z.ZodArray<z.ZodObject<{
148
+ name: z.ZodString;
149
+ type: z.ZodString;
150
+ required: z.ZodOptional<z.ZodBoolean>;
151
+ description: z.ZodOptional<z.ZodString>;
152
+ }, z.core.$strip>>>;
153
+ flags: z.ZodOptional<z.ZodArray<z.ZodObject<{
154
+ name: z.ZodString;
155
+ type: z.ZodString;
156
+ default: z.ZodOptional<z.ZodUnknown>;
157
+ description: z.ZodOptional<z.ZodString>;
158
+ }, z.core.$strip>>>;
159
+ }, z.core.$strip>>>;
160
+ flags: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
161
+ name: z.ZodString;
162
+ type: z.ZodDefault<z.ZodString>;
163
+ description: z.ZodOptional<z.ZodString>;
164
+ required: z.ZodOptional<z.ZodBoolean>;
165
+ default: z.ZodOptional<z.ZodUnknown>;
166
+ }, z.core.$strip>, z.ZodObject<{
167
+ flag: z.ZodString;
168
+ description: z.ZodOptional<z.ZodString>;
169
+ }, z.core.$strip>]>>>;
170
+ exit_codes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
171
+ error_codes: z.ZodOptional<z.ZodArray<z.ZodString>>;
172
+ }, z.core.$strip>>;
173
+ }, z.core.$strip>]>;
174
+ export type MechRegistryFile = z.infer<typeof mechRegistryFileSchema>;
175
+ /** RegistryFile 包装 (msm.ts 内迁移, v1 包装/数组双格式) */
176
+ export declare const registryFileSchema: z.ZodObject<{
177
+ entries: z.ZodArray<z.ZodObject<{
178
+ name: z.ZodString;
179
+ path: z.ZodString;
180
+ skill: z.ZodString;
181
+ category: z.ZodEnum<{
182
+ mech: "mech";
183
+ "semi-mech": "semi-mech";
184
+ }>;
185
+ description: z.ZodString;
186
+ usage: z.ZodString;
187
+ subcommands: z.ZodOptional<z.ZodArray<z.ZodObject<{
188
+ name: z.ZodString;
189
+ description: z.ZodString;
190
+ args: z.ZodOptional<z.ZodArray<z.ZodObject<{
191
+ name: z.ZodString;
192
+ type: z.ZodString;
193
+ required: z.ZodOptional<z.ZodBoolean>;
194
+ description: z.ZodOptional<z.ZodString>;
195
+ }, z.core.$strip>>>;
196
+ flags: z.ZodOptional<z.ZodArray<z.ZodObject<{
197
+ name: z.ZodString;
198
+ type: z.ZodString;
199
+ default: z.ZodOptional<z.ZodUnknown>;
200
+ description: z.ZodOptional<z.ZodString>;
201
+ }, z.core.$strip>>>;
202
+ }, z.core.$strip>>>;
203
+ flags: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
204
+ name: z.ZodString;
205
+ type: z.ZodDefault<z.ZodString>;
206
+ description: z.ZodOptional<z.ZodString>;
207
+ required: z.ZodOptional<z.ZodBoolean>;
208
+ default: z.ZodOptional<z.ZodUnknown>;
209
+ }, z.core.$strip>, z.ZodObject<{
210
+ flag: z.ZodString;
211
+ description: z.ZodOptional<z.ZodString>;
212
+ }, z.core.$strip>]>>>;
213
+ exit_codes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
214
+ error_codes: z.ZodOptional<z.ZodArray<z.ZodString>>;
215
+ }, z.core.$strip>>;
216
+ isV1Wrapped: z.ZodBoolean;
217
+ version: z.ZodOptional<z.ZodNumber>;
218
+ description: z.ZodOptional<z.ZodString>;
219
+ }, z.core.$strip>;
220
+ export type RegistryFile = z.infer<typeof registryFileSchema>;
221
+ /**
222
+ * HookConfig = 部分 hook 启用/禁用 map
223
+ *
224
+ * 关键:key 必须是 HOOK_NAMES 之一 (单一真相源, v1.18 统一)
225
+ * value 是 boolean (false = 禁用, 缺省/true = 启用)
226
+ *
227
+ * 实现:z.object 显式列出每个 HOOK_NAME 为 optional boolean。
228
+ * - 严格 key 校验(zod 4 的 z.record(K, V) 行为不稳定, 此方案最稳)
229
+ * - 旧用法(如 `{'shell.env': false}`)仍兼容
230
+ * - 严格模式会拒绝拼错 hook 名
231
+ */
232
+ export declare const hookConfigSchema: z.ZodObject<{
233
+ "tool.execute.before"?: z.ZodOptional<z.ZodBoolean> | undefined;
234
+ "shell.env"?: z.ZodOptional<z.ZodBoolean> | undefined;
235
+ "experimental.chat.system.transform"?: z.ZodOptional<z.ZodBoolean> | undefined;
236
+ "experimental.session.compacting"?: z.ZodOptional<z.ZodBoolean> | undefined;
237
+ "tool.definition"?: z.ZodOptional<z.ZodBoolean> | undefined;
238
+ }, z.core.$strip>;
239
+ /** 派生 TS 类型 */
240
+ export type HookConfig = z.infer<typeof hookConfigSchema>;
241
+ /**
242
+ * PluginConfig = 插件全局配置
243
+ *
244
+ * v1.13 引入 schema, 实际消费接线留 v1.15
245
+ * 设计参考 omo 的 OhMyOpenCodeConfig:
246
+ * - disabled_hooks/tools/mcps 数组
247
+ * - msm_exec 协议层默认选项
248
+ * - 其他可扩展字段
249
+ */
250
+ export declare const pluginConfigSchema: z.ZodObject<{
251
+ $schema: z.ZodOptional<z.ZodString>;
252
+ disabled_hooks: z.ZodOptional<z.ZodArray<z.ZodString>>;
253
+ disabled_tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
254
+ disabled_msms: z.ZodOptional<z.ZodArray<z.ZodString>>;
255
+ msm_exec_format: z.ZodOptional<z.ZodEnum<{
256
+ text: "text";
257
+ json: "json";
258
+ }>>;
259
+ msm_exec_log: z.ZodOptional<z.ZodString>;
260
+ msm_exec_timeout_ms: z.ZodOptional<z.ZodNumber>;
261
+ blocked_msm_paths: z.ZodOptional<z.ZodArray<z.ZodString>>;
262
+ }, z.core.$strip>;
263
+ /** 派生 TS 类型 */
264
+ export type PluginConfig = z.infer<typeof pluginConfigSchema>;
265
+ /**
266
+ * 校验并返回 PluginConfig (parse 失败时抛 zod.ZodError)
267
+ *
268
+ * 用法:
269
+ * ```ts
270
+ * try {
271
+ * const config = parseConfig(input);
272
+ * // config 是已验证的 PluginConfig
273
+ * } catch (err) {
274
+ * if (err instanceof ZodError) { ... }
275
+ * }
276
+ * ```
277
+ */
278
+ export declare function parseConfig(input: unknown): PluginConfig;
279
+ /**
280
+ * 不抛错版本 — Result 风格
281
+ *
282
+ * 返回:
283
+ * - { success: true, data: PluginConfig }
284
+ * - { success: false, error: ZodError }
285
+ */
286
+ export type SafeParseResult<T> = {
287
+ success: true;
288
+ data: T;
289
+ } | {
290
+ success: false;
291
+ error: ZodError;
292
+ };
293
+ export declare function safeParseConfig(input: unknown): SafeParseResult<PluginConfig>;
294
+ /** 解析 mech-registry.json 顶层 (双 schema 兼容) */
295
+ export declare function parseMechRegistryFile(input: unknown): SafeParseResult<MechRegistryFile>;
296
+ /** 解析单条 MechEntry */
297
+ export declare function parseMechEntry(input: unknown): SafeParseResult<MechEntry>;
298
+ /** 解析 HookConfig (per-hook enable/disable map) */
299
+ export declare function parseHookConfig(input: unknown): SafeParseResult<HookConfig>;
300
+ //# sourceMappingURL=config-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-schema.d.ts","sourceRoot":"","sources":["../src/config-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,CAAC,EAAE,KAAK,QAAQ,EAAE,MAAM,KAAK,CAAC;AAGvC;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,2IAMsB,CAAC;AAE9C,qCAAqC;AACrC,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAInD;;;GAGG;AACH,eAAO,MAAM,cAAc;;;;;;;;;mBAYzB,CAAC;AAEH,mDAAmD;AACnD,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsC1B,CAAC;AAEH,+CAA+C;AAC/C,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,mBAAmB;AACnB,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAOjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,gDAAgD;AAChD,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAK7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB;;;;;;iBAMuD,CAAC;AAErF,eAAe;AACf,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAI1D;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;iBAwB7B,CAAC;AAEH,eAAe;AACf,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAI9D;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAExD;AAED;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,IACzB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,GAC1B;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,CAAC;AAExC,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAAC,YAAY,CAAC,CAE7E;AAID,6CAA6C;AAC7C,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAAC,gBAAgB,CAAC,CAEvF;AAED,qBAAqB;AACrB,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAAC,SAAS,CAAC,CAEzE;AAID,kDAAkD;AAClD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAAC,UAAU,CAAC,CAE3E"}
@@ -0,0 +1,185 @@
1
+ /**
2
+ * config-schema.ts — v1.13 zod-first plugin config
3
+ *
4
+ * 设计目标 (D26 决策 — 仿 omo OhMyOpenCodeConfig 模式):
5
+ * - zod schema 作为单一真相源(single source of truth)
6
+ * - TS 类型由 z.infer 派生(避免手写 interface 与 schema 重复)
7
+ * - 公开 parseConfig / safeParseConfig 给配置加载/校验场景
8
+ * - 保留 v1.11 之前的所有 type export (向后兼容, 公共 API 不变)
9
+ *
10
+ * 迁移范围 (v1.13):
11
+ * - MechEntry (msm.ts 内) — zod schema 化
12
+ * - HookConfig (hooks/util.ts 内) — zod schema 化 (轻量, catchall boolean)
13
+ * - 新增 PluginConfig — 用户面向配置 (omo 风格, 启用/禁用 hooks/tools/mcps + 协议层选项)
14
+ *
15
+ * 不在 v1.13 范围 (D26 §3 锁定):
16
+ * - PluginConfig 的实际消费 (parseConfig 在 plugin 入口接线) — 留 v1.15
17
+ * - 把 PluginConfig 写入 opencode.json — 留 v1.15
18
+ * - PluginConfig 与 msm-exec 协议 flag 联动 (msm_exec_format / msm_exec_log) — 留 v1.15
19
+ *
20
+ * 与 v0.2 msm-writing-standards §5 兼容:
21
+ * - 错误处理走 zod.ZodError (6 字段 schema 友好)
22
+ * - safeParseConfig 返回 { success, data, error } 模式(不抛错给调用方)
23
+ */
24
+ import { z } from 'zod';
25
+ /**
26
+ * Plugin 当前注入到 opencode 的 hook 名清单 (v1.18 单一真相源)
27
+ *
28
+ * 与 Hooks (来自 @opencode-ai/plugin) 的子集保持一致 — `satisfies` 保证
29
+ * 此处列出的每一项都是 opencode 真实存在的 hook。
30
+ *
31
+ * 维护规则:新增 hook 时先在此处加常量,再在 createXxxHooks 工厂里用。
32
+ */
33
+ export const HOOK_NAMES = [
34
+ 'shell.env',
35
+ 'tool.execute.before',
36
+ 'tool.definition',
37
+ 'experimental.chat.system.transform',
38
+ 'experimental.session.compacting',
39
+ ];
40
+ // ── MechEntry (msm.ts 内迁移) ──
41
+ /**
42
+ * flag schema: 兼容 v0 schema (name/type) 和 v1 schema (flag/description)
43
+ * 见 msm-schema.ts 的 normalizeFlag 逻辑
44
+ */
45
+ export const mechFlagSchema = z.union([
46
+ z.object({
47
+ name: z.string(),
48
+ type: z.string().default('string'),
49
+ description: z.string().optional(),
50
+ required: z.boolean().optional(),
51
+ default: z.unknown().optional(),
52
+ }),
53
+ z.object({
54
+ flag: z.string(),
55
+ description: z.string().optional(),
56
+ }),
57
+ ]);
58
+ /** mech-registry.json 单条 entry schema (v1 包装格式) */
59
+ export const mechEntrySchema = z.object({
60
+ name: z.string().min(1),
61
+ path: z.string().min(1),
62
+ skill: z.string().min(1),
63
+ category: z.enum(['mech', 'semi-mech']),
64
+ description: z.string().min(1),
65
+ usage: z.string(),
66
+ subcommands: z
67
+ .array(z.object({
68
+ name: z.string(),
69
+ description: z.string(),
70
+ args: z
71
+ .array(z.object({
72
+ name: z.string(),
73
+ type: z.string(),
74
+ required: z.boolean().optional(),
75
+ description: z.string().optional(),
76
+ }))
77
+ .optional(),
78
+ flags: z
79
+ .array(z.object({
80
+ name: z.string(),
81
+ type: z.string(),
82
+ default: z.unknown().optional(),
83
+ description: z.string().optional(),
84
+ }))
85
+ .optional(),
86
+ }))
87
+ .optional(),
88
+ flags: z.array(mechFlagSchema).default([]),
89
+ exit_codes: z.record(z.string(), z.string()).optional(),
90
+ error_codes: z.array(z.string()).optional(),
91
+ });
92
+ /** 注册表顶层 schema */
93
+ export const mechRegistryFileSchema = z.union([
94
+ z.array(mechEntrySchema),
95
+ z.object({
96
+ version: z.number().optional(),
97
+ description: z.string().optional(),
98
+ entries: z.array(mechEntrySchema),
99
+ }),
100
+ ]);
101
+ /** RegistryFile 包装 (msm.ts 内迁移, v1 包装/数组双格式) */
102
+ export const registryFileSchema = z.object({
103
+ entries: z.array(mechEntrySchema),
104
+ isV1Wrapped: z.boolean(),
105
+ version: z.number().optional(),
106
+ description: z.string().optional(),
107
+ });
108
+ // ── HookConfig (hooks/util.ts 内迁移) ──
109
+ /**
110
+ * HookConfig = 部分 hook 启用/禁用 map
111
+ *
112
+ * 关键:key 必须是 HOOK_NAMES 之一 (单一真相源, v1.18 统一)
113
+ * value 是 boolean (false = 禁用, 缺省/true = 启用)
114
+ *
115
+ * 实现:z.object 显式列出每个 HOOK_NAME 为 optional boolean。
116
+ * - 严格 key 校验(zod 4 的 z.record(K, V) 行为不稳定, 此方案最稳)
117
+ * - 旧用法(如 `{'shell.env': false}`)仍兼容
118
+ * - 严格模式会拒绝拼错 hook 名
119
+ */
120
+ export const hookConfigSchema = z
121
+ .object(Object.fromEntries(HOOK_NAMES.map((name) => [name, z.boolean().optional()])))
122
+ .describe('per-hook enable/disable map; key = HookName, value = false = disabled');
123
+ // ── PluginConfig (新增 — 用户面向配置, omo 风格) ──
124
+ /**
125
+ * PluginConfig = 插件全局配置
126
+ *
127
+ * v1.13 引入 schema, 实际消费接线留 v1.15
128
+ * 设计参考 omo 的 OhMyOpenCodeConfig:
129
+ * - disabled_hooks/tools/mcps 数组
130
+ * - msm_exec 协议层默认选项
131
+ * - 其他可扩展字段
132
+ */
133
+ export const pluginConfigSchema = z.object({
134
+ /** 配置 schema 版本 (v1.13 = 1) */
135
+ $schema: z.string().optional(),
136
+ /** 禁用的 hook 列表 (按 hook 名) */
137
+ disabled_hooks: z.array(z.string()).optional(),
138
+ /** 禁用的 tool 列表 (按 tool 名) */
139
+ disabled_tools: z.array(z.string()).optional(),
140
+ /** 禁用的 msm 列表 (按 msm 名) */
141
+ disabled_msms: z.array(z.string()).optional(),
142
+ /** msm_exec 协议层默认 format (v1.14) */
143
+ msm_exec_format: z.enum(['text', 'json']).optional(),
144
+ /** msm_exec 协议层默认 log 路径 (v1.14) */
145
+ msm_exec_log: z.string().optional(),
146
+ /** msm_exec 协议层默认超时 (ms, 默认 30000) */
147
+ msm_exec_timeout_ms: z.number().int().positive().optional(),
148
+ /** 业务 msm 路径黑名单 (安全增强) */
149
+ blocked_msm_paths: z.array(z.string()).optional(),
150
+ });
151
+ // ── parseConfig / safeParseConfig ──
152
+ /**
153
+ * 校验并返回 PluginConfig (parse 失败时抛 zod.ZodError)
154
+ *
155
+ * 用法:
156
+ * ```ts
157
+ * try {
158
+ * const config = parseConfig(input);
159
+ * // config 是已验证的 PluginConfig
160
+ * } catch (err) {
161
+ * if (err instanceof ZodError) { ... }
162
+ * }
163
+ * ```
164
+ */
165
+ export function parseConfig(input) {
166
+ return pluginConfigSchema.parse(input);
167
+ }
168
+ export function safeParseConfig(input) {
169
+ return pluginConfigSchema.safeParse(input);
170
+ }
171
+ // ── MechEntry parse 工具 ──
172
+ /** 解析 mech-registry.json 顶层 (双 schema 兼容) */
173
+ export function parseMechRegistryFile(input) {
174
+ return mechRegistryFileSchema.safeParse(input);
175
+ }
176
+ /** 解析单条 MechEntry */
177
+ export function parseMechEntry(input) {
178
+ return mechEntrySchema.safeParse(input);
179
+ }
180
+ // ── HookConfig parse 工具 ──
181
+ /** 解析 HookConfig (per-hook enable/disable map) */
182
+ export function parseHookConfig(input) {
183
+ return hookConfigSchema.safeParse(input);
184
+ }
185
+ //# sourceMappingURL=config-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-schema.js","sourceRoot":"","sources":["../src/config-schema.ts"],"names":[],"mappings":"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"}