mn-ws 0.1.0 → 0.2.1

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 (178) hide show
  1. package/assets/groups.json +10 -0
  2. package/assets/mn-ws/SKILL.md +55 -0
  3. package/assets/mn-ws/hooks.json +14 -0
  4. package/assets/mn-ws/install/inject-root.mjs +26 -0
  5. package/bin/ws.mjs +13 -0
  6. package/dist/core/auth.d.ts +194 -0
  7. package/dist/core/auth.d.ts.map +1 -0
  8. package/dist/core/auth.js +331 -0
  9. package/dist/core/auth.js.map +1 -0
  10. package/dist/core/brand.d.ts +11 -0
  11. package/dist/core/brand.d.ts.map +1 -0
  12. package/dist/core/brand.js +7 -0
  13. package/dist/core/brand.js.map +1 -0
  14. package/dist/core/bridge.d.ts +106 -0
  15. package/dist/core/bridge.d.ts.map +1 -0
  16. package/dist/core/bridge.js +308 -0
  17. package/dist/core/bridge.js.map +1 -0
  18. package/dist/core/config.d.ts +174 -0
  19. package/dist/core/config.d.ts.map +1 -0
  20. package/dist/core/config.js +417 -0
  21. package/dist/core/config.js.map +1 -0
  22. package/dist/core/controller.d.ts +64 -0
  23. package/dist/core/controller.d.ts.map +1 -0
  24. package/dist/core/controller.js +100 -0
  25. package/dist/core/controller.js.map +1 -0
  26. package/dist/core/errors/index.d.ts +30 -0
  27. package/dist/core/errors/index.d.ts.map +1 -0
  28. package/dist/core/errors/index.js +88 -0
  29. package/dist/core/errors/index.js.map +1 -0
  30. package/dist/core/open.d.ts +3 -0
  31. package/dist/core/open.d.ts.map +1 -0
  32. package/dist/core/open.js +27 -0
  33. package/dist/core/open.js.map +1 -0
  34. package/dist/core/paths.d.ts +15 -0
  35. package/dist/core/paths.d.ts.map +1 -0
  36. package/dist/core/paths.js +50 -0
  37. package/dist/core/paths.js.map +1 -0
  38. package/dist/core/serve-port.d.ts +73 -0
  39. package/dist/core/serve-port.d.ts.map +1 -0
  40. package/dist/core/serve-port.js +134 -0
  41. package/dist/core/serve-port.js.map +1 -0
  42. package/dist/core/session.d.ts +78 -0
  43. package/dist/core/session.d.ts.map +1 -0
  44. package/dist/core/session.js +124 -0
  45. package/dist/core/session.js.map +1 -0
  46. package/dist/core/skills/bus.d.ts +29 -0
  47. package/dist/core/skills/bus.d.ts.map +1 -0
  48. package/dist/core/skills/bus.js +114 -0
  49. package/dist/core/skills/bus.js.map +1 -0
  50. package/dist/core/skills/get.d.ts +17 -0
  51. package/dist/core/skills/get.d.ts.map +1 -0
  52. package/dist/core/skills/get.js +87 -0
  53. package/dist/core/skills/get.js.map +1 -0
  54. package/dist/core/skills/handlers.d.ts +22 -0
  55. package/dist/core/skills/handlers.d.ts.map +1 -0
  56. package/dist/core/skills/handlers.js +86 -0
  57. package/dist/core/skills/handlers.js.map +1 -0
  58. package/dist/core/skills/index.d.ts +47 -0
  59. package/dist/core/skills/index.d.ts.map +1 -0
  60. package/dist/core/skills/index.js +268 -0
  61. package/dist/core/skills/index.js.map +1 -0
  62. package/dist/core/skills/install.d.ts +18 -0
  63. package/dist/core/skills/install.d.ts.map +1 -0
  64. package/dist/core/skills/install.js +123 -0
  65. package/dist/core/skills/install.js.map +1 -0
  66. package/dist/core/skills/text-util.d.ts +2 -0
  67. package/dist/core/skills/text-util.d.ts.map +1 -0
  68. package/dist/core/skills/text-util.js +14 -0
  69. package/dist/core/skills/text-util.js.map +1 -0
  70. package/dist/core/store.d.ts +29 -0
  71. package/dist/core/store.d.ts.map +1 -0
  72. package/dist/core/store.js +100 -0
  73. package/dist/core/store.js.map +1 -0
  74. package/dist/core/views.d.ts +11 -0
  75. package/dist/core/views.d.ts.map +1 -0
  76. package/dist/core/views.js +20 -0
  77. package/dist/core/views.js.map +1 -0
  78. package/dist/index.d.ts +6 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +8 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/modules/auth/index.d.ts +73 -0
  83. package/dist/modules/auth/index.d.ts.map +1 -0
  84. package/dist/modules/auth/index.js +64 -0
  85. package/dist/modules/auth/index.js.map +1 -0
  86. package/dist/modules/auth/service.d.ts +98 -0
  87. package/dist/modules/auth/service.d.ts.map +1 -0
  88. package/dist/modules/auth/service.js +200 -0
  89. package/dist/modules/auth/service.js.map +1 -0
  90. package/dist/modules/bridge/index.d.ts +73 -0
  91. package/dist/modules/bridge/index.d.ts.map +1 -0
  92. package/dist/modules/bridge/index.js +89 -0
  93. package/dist/modules/bridge/index.js.map +1 -0
  94. package/dist/modules/bridge/service.d.ts +75 -0
  95. package/dist/modules/bridge/service.d.ts.map +1 -0
  96. package/dist/modules/bridge/service.js +134 -0
  97. package/dist/modules/bridge/service.js.map +1 -0
  98. package/dist/modules/home/index.d.ts +95 -0
  99. package/dist/modules/home/index.d.ts.map +1 -0
  100. package/dist/modules/home/index.js +123 -0
  101. package/dist/modules/home/index.js.map +1 -0
  102. package/dist/modules/home/service.d.ts +48 -0
  103. package/dist/modules/home/service.d.ts.map +1 -0
  104. package/dist/modules/home/service.js +195 -0
  105. package/dist/modules/home/service.js.map +1 -0
  106. package/dist/modules/skill/index.d.ts +78 -0
  107. package/dist/modules/skill/index.d.ts.map +1 -0
  108. package/dist/modules/skill/index.js +132 -0
  109. package/dist/modules/skill/index.js.map +1 -0
  110. package/dist/runtime/api.d.ts +24 -0
  111. package/dist/runtime/api.d.ts.map +1 -0
  112. package/dist/runtime/api.js +140 -0
  113. package/dist/runtime/api.js.map +1 -0
  114. package/dist/runtime/cli.d.ts +23 -0
  115. package/dist/runtime/cli.d.ts.map +1 -0
  116. package/dist/runtime/cli.js +410 -0
  117. package/dist/runtime/cli.js.map +1 -0
  118. package/dist/runtime/help.d.ts +29 -0
  119. package/dist/runtime/help.d.ts.map +1 -0
  120. package/dist/runtime/help.js +89 -0
  121. package/dist/runtime/help.js.map +1 -0
  122. package/dist/runtime/registry.d.ts +318 -0
  123. package/dist/runtime/registry.d.ts.map +1 -0
  124. package/dist/runtime/registry.js +75 -0
  125. package/dist/runtime/registry.js.map +1 -0
  126. package/dist/runtime/server.d.ts +10 -0
  127. package/dist/runtime/server.d.ts.map +1 -0
  128. package/dist/runtime/server.js +127 -0
  129. package/dist/runtime/server.js.map +1 -0
  130. package/dist/runtime/spec.d.ts +32 -0
  131. package/dist/runtime/spec.d.ts.map +1 -0
  132. package/dist/runtime/spec.js +180 -0
  133. package/dist/runtime/spec.js.map +1 -0
  134. package/dist/runtime/types/action.d.ts +101 -0
  135. package/dist/runtime/types/action.d.ts.map +1 -0
  136. package/dist/runtime/types/action.js +19 -0
  137. package/dist/runtime/types/action.js.map +1 -0
  138. package/dist/runtime/types/client.d.ts +39 -0
  139. package/dist/runtime/types/client.d.ts.map +1 -0
  140. package/dist/runtime/types/client.js +2 -0
  141. package/dist/runtime/types/client.js.map +1 -0
  142. package/dist/runtime/types/http.d.ts +22 -0
  143. package/dist/runtime/types/http.d.ts.map +1 -0
  144. package/dist/runtime/types/http.js +6 -0
  145. package/dist/runtime/types/http.js.map +1 -0
  146. package/dist/runtime/types/module.d.ts +72 -0
  147. package/dist/runtime/types/module.d.ts.map +1 -0
  148. package/dist/runtime/types/module.js +15 -0
  149. package/dist/runtime/types/module.js.map +1 -0
  150. package/dist/web/public/assets/CliHints-BOxU-Duc.js +1 -0
  151. package/dist/web/public/assets/index-BTRKdMIW.js +50 -0
  152. package/dist/web/public/assets/index-BjGe8ggI.css +1 -0
  153. package/dist/web/public/assets/view-CE4tnCuy.js +1 -0
  154. package/dist/web/public/assets/view-CEQ2uPxE.js +1 -0
  155. package/dist/web/public/favicon-16.png +0 -0
  156. package/dist/web/public/favicon-32.png +0 -0
  157. package/dist/web/public/favicon-48.png +0 -0
  158. package/dist/web/public/favicon.ico +0 -0
  159. package/dist/web/public/index.html +19 -0
  160. package/dist/web/public/logo-rounded.png +0 -0
  161. package/dist/web/public/logo-rounded.svg +6 -0
  162. package/dist/web/public/logo.png +0 -0
  163. package/dist/web/public/logo.svg +6 -0
  164. package/package.json +56 -35
  165. package/README.md +0 -251
  166. package/bin/index.js +0 -714
  167. package/client/bridge-client.js +0 -160
  168. package/client/web.js +0 -234
  169. package/client/ws-client.js +0 -191
  170. package/lib/apps.js +0 -237
  171. package/lib/auth.js +0 -319
  172. package/lib/config.js +0 -534
  173. package/lib/index.js +0 -15
  174. package/lib/logger.js +0 -63
  175. package/lib/protocol.js +0 -208
  176. package/lib/store.js +0 -66
  177. package/server/auth.js +0 -274
  178. package/server/server.js +0 -752
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { type HookHandlerSpec } from './handlers.js';
2
+ export declare const HOOK_CONFIG_FILE = "hooks.json";
3
+ export interface HookRule {
4
+ match: string;
5
+ hooks: HookHandlerSpec[];
6
+ }
7
+ export interface HookConfig {
8
+ dir: string;
9
+ hooks: Record<string, HookRule[]>;
10
+ }
11
+ export declare function loadHookConfig(dir: string): Promise<HookConfig | null>;
12
+ export interface HookOutcome {
13
+ ran: number;
14
+ blocked: boolean;
15
+ reason?: string;
16
+ by: string;
17
+ vars: Record<string, string>;
18
+ data: unknown[];
19
+ }
20
+ interface RunEventInput {
21
+ event: string;
22
+ target: string;
23
+ configs: Array<HookConfig | null>;
24
+ fields?: Record<string, unknown>;
25
+ }
26
+ export declare function runHookEvent(input: RunEventInput): Promise<HookOutcome>;
27
+ export declare function emit(event: string, target: string, config: HookConfig | null, fields?: Record<string, unknown>): Promise<HookOutcome>;
28
+ export {};
29
+ //# sourceMappingURL=bus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bus.d.ts","sourceRoot":"","sources":["../../../src/core/skills/bus.ts"],"names":[],"mappings":"AAyBA,OAAO,EAGL,KAAK,eAAe,EAErB,MAAM,eAAe,CAAC;AAEvB,eAAO,MAAM,gBAAgB,eAAe,CAAC;AAE7C,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,eAAe,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;CACnC;AAGD,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CA4C5E;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,IAAI,EAAE,OAAO,EAAE,CAAC;CACjB;AAED,UAAU,aAAa;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAElC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAID,wBAAsB,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CAiC7E;AAGD,wBAAsB,IAAI,CACxB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,UAAU,GAAG,IAAI,EACzB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,WAAW,CAAC,CAEtB"}
@@ -0,0 +1,114 @@
1
+ // 通用 hook 总线:配置文件桥接、match 过滤、无限事件平面。
2
+ //
3
+ // 模型参考 Claude Code hooks(settings.json → hooks → 事件组 → matcher → handlers),
4
+ // 在 nx-nx 内落地为每个 skill / 项目可自带的 hooks.json:
5
+ //
6
+ // {
7
+ // "version": 1,
8
+ // "hooks": {
9
+ // "<任意事件名>": [
10
+ // { "match": "<正则,匹配 target>",
11
+ // "hooks": [ { "type": "module", "use": "./x.mjs" },
12
+ // { "type": "command", "command": "node y.mjs" } ] }
13
+ // ]
14
+ // }
15
+ // }
16
+ //
17
+ // 关键性质:
18
+ // 1. 事件平面开放——核心不枚举事件,任意字符串都能注册与触发(无限平面扩展)
19
+ // 2. match = 正则白名单,只在 target 命中时执行该规则
20
+ // 3. handler 顺序执行;decision.vars 聚合、decision.block 立即阻断
21
+ // 4. 配置 schema / 坏 JSON / 坏正则一律显眼报错(作者资产,不静默)
22
+ import fsp from 'node:fs/promises';
23
+ import { existsSync } from 'node:fs';
24
+ import { join } from 'node:path';
25
+ import { specError } from '../errors/index.js';
26
+ import { runHandler, } from './handlers.js';
27
+ export const HOOK_CONFIG_FILE = 'hooks.json';
28
+ // 加载目录下的 hooks.json;不存在 → null(无钩子);坏 JSON / schema 错 → 抛错。
29
+ export async function loadHookConfig(dir) {
30
+ const file = join(dir, HOOK_CONFIG_FILE);
31
+ if (!existsSync(file))
32
+ return null;
33
+ let raw;
34
+ try {
35
+ raw = await fsp.readFile(file, 'utf8');
36
+ }
37
+ catch (e) {
38
+ throw specError(`无法读取 ${HOOK_CONFIG_FILE}: ${String(e.message || e)}`);
39
+ }
40
+ let parsed;
41
+ try {
42
+ parsed = JSON.parse(raw);
43
+ }
44
+ catch {
45
+ throw specError(`${HOOK_CONFIG_FILE} 不是合法 JSON(目录: ${dir})`);
46
+ }
47
+ const groups = parsed.hooks;
48
+ if (!groups || typeof groups !== 'object') {
49
+ throw specError(`${HOOK_CONFIG_FILE} schema 错误:缺少 hooks 对象(目录: ${dir})`);
50
+ }
51
+ for (const [event, rules] of Object.entries(groups)) {
52
+ if (!Array.isArray(rules) || !rules.length) {
53
+ throw specError(`${HOOK_CONFIG_FILE} 事件 "${event}" 必须是非空规则数组`);
54
+ }
55
+ for (const rule of rules) {
56
+ if (typeof rule.match !== 'string' || !rule.match) {
57
+ throw specError(`${HOOK_CONFIG_FILE} 事件 "${event}" 的规则缺少非空 match`);
58
+ }
59
+ try {
60
+ new RegExp(rule.match);
61
+ }
62
+ catch (e) {
63
+ throw specError(`${HOOK_CONFIG_FILE} 事件 "${event}" 的 match 不是合法正则: ${rule.match}(${String(e.message)})`);
64
+ }
65
+ if (!Array.isArray(rule.hooks) || !rule.hooks.length) {
66
+ throw specError(`${HOOK_CONFIG_FILE} 事件 "${event}" 的规则缺少非空 hooks 数组`);
67
+ }
68
+ }
69
+ }
70
+ return { dir, hooks: groups };
71
+ }
72
+ // 触发一个事件:汇总各配置中该事件的规则,match 命中则顺序执行 handlers。
73
+ // 事件名任意——总线不认识固定平面,新事件无需改核心。
74
+ export async function runHookEvent(input) {
75
+ const outcome = { ran: 0, blocked: false, vars: {}, data: [], by: '' };
76
+ for (const config of input.configs) {
77
+ if (!config)
78
+ continue;
79
+ const rules = config.hooks[input.event];
80
+ if (!rules)
81
+ continue;
82
+ for (const rule of rules) {
83
+ if (!new RegExp(rule.match).test(input.target))
84
+ continue;
85
+ const payload = {
86
+ ...input.fields,
87
+ event: input.event,
88
+ target: input.target,
89
+ match: rule.match,
90
+ cwd: input.fields?.cwd || process.cwd(),
91
+ };
92
+ for (const handler of rule.hooks) {
93
+ const decision = await runHandler(handler, config.dir, payload);
94
+ outcome.ran++;
95
+ if (decision?.vars)
96
+ Object.assign(outcome.vars, decision.vars);
97
+ if (decision?.data !== undefined)
98
+ outcome.data.push(decision.data);
99
+ if (decision?.block) {
100
+ outcome.blocked = true;
101
+ outcome.reason = decision.block;
102
+ outcome.by = handler.use || handler.command || 'handler';
103
+ return outcome;
104
+ }
105
+ }
106
+ }
107
+ }
108
+ return outcome;
109
+ }
110
+ // 便捷封装:单配置来源。
111
+ export async function emit(event, target, config, fields) {
112
+ return runHookEvent({ event, target, configs: [config], fields });
113
+ }
114
+ //# sourceMappingURL=bus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bus.js","sourceRoot":"","sources":["../../../src/core/skills/bus.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { installOne } from './index.js';
2
+ export interface SkillGetResult {
3
+ skillName: string;
4
+ ref: string;
5
+ content: string;
6
+ contentBytes: number;
7
+ install: Awaited<ReturnType<typeof installOne>>;
8
+ }
9
+ export declare function listRefs(name: unknown): Promise<string[]>;
10
+ export declare function getSkill(name: unknown, opts?: {
11
+ ref?: string;
12
+ to?: string;
13
+ force?: boolean;
14
+ }): Promise<SkillGetResult>;
15
+ export declare function skillGetPrefix(name: string, ref: string): string;
16
+ export declare function installStatusLine(r: Awaited<ReturnType<typeof installOne>>): string;
17
+ //# sourceMappingURL=get.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../src/core/skills/get.ts"],"names":[],"mappings":"AAOA,OAAO,EAA+B,UAAU,EAAE,MAAM,YAAY,CAAC;AAIrE,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC;CACjD;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAS/D;AA+BD,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,OAAO,EACb,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GACxD,OAAO,CAAC,cAAc,CAAC,CAiBzB;AAGD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAQhE;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,GAAG,MAAM,CAOnF"}
@@ -0,0 +1,87 @@
1
+ // skill get:把指定 skill 的文档导出给外部 agent,并顺手幂等安装。
2
+ // 与 skills.ts 分开:一个管安装/分组,一个管文档读取,各自不超限。
3
+ import fsp from 'node:fs/promises';
4
+ import { existsSync } from 'node:fs';
5
+ import { join } from 'node:path';
6
+ import { badInput, notFound } from '../errors/index.js';
7
+ import { assertSafeName } from '../paths.js';
8
+ import { assetsDir, defaultSkillsDir, installOne } from './index.js';
9
+ const SENTINEL = '# --- begin skill content (do not modify this line) ---';
10
+ export async function listRefs(name) {
11
+ const safe = assertSafeName(name, 'skill 名');
12
+ const dir = join(assetsDir(), safe, 'references');
13
+ try {
14
+ const entries = await fsp.readdir(dir);
15
+ return entries.filter((f) => f.endsWith('.md')).map((f) => f.replace(/\.md$/, '')).sort();
16
+ }
17
+ catch {
18
+ return [];
19
+ }
20
+ }
21
+ // 解析 ref 到 skill 内的相对路径:
22
+ // 空 / SKILL.md → SKILL.md;裸名 → references/<裸名>.md(再退到 <裸名>.md);
23
+ // 含 / 的显式路径去掉 ./ 前缀。任何 '..' 或越界一律拒绝。
24
+ async function resolveRefPath(name, ref) {
25
+ let rel;
26
+ if (!ref || ref === 'SKILL.md') {
27
+ rel = 'SKILL.md';
28
+ }
29
+ else if (ref.includes('/')) {
30
+ rel = ref.replace(/^\.\//, '');
31
+ }
32
+ else {
33
+ const a = join(assetsDir(), name, 'references', `${ref}.md`);
34
+ const b = join(assetsDir(), name, `${ref}.md`);
35
+ rel = existsSync(a) ? join('references', `${ref}.md`) : existsSync(b) ? `${ref}.md` : null;
36
+ if (!rel) {
37
+ const refs = await listRefs(name);
38
+ throw badInput(`未知 ref: ${ref}(可用: SKILL.md, ${refs.join(', ')})`);
39
+ }
40
+ }
41
+ if (rel.split(/[\\/]/).includes('..')) {
42
+ throw badInput(`ref 路径不允许包含 '..': ${ref}`);
43
+ }
44
+ const base = join(assetsDir(), name);
45
+ const resolved = join(base, rel);
46
+ if (!resolved.startsWith(base))
47
+ throw badInput(`ref 越界: ${ref}`);
48
+ // 文档路径随包跨平台分发,统一用正斜杠
49
+ return rel.replace(/\\/g, '/');
50
+ }
51
+ export async function getSkill(name, opts = {}) {
52
+ const safe = assertSafeName(name, 'skill 名');
53
+ if (!existsSync(join(assetsDir(), safe, 'SKILL.md'))) {
54
+ throw notFound(`未找到内置 skill: ${safe}`);
55
+ }
56
+ const rel = await resolveRefPath(safe, opts.ref || '');
57
+ const file = join(assetsDir(), safe, rel);
58
+ let content;
59
+ try {
60
+ content = await fsp.readFile(file, 'utf8');
61
+ }
62
+ catch {
63
+ throw notFound(`未找到 skill 文档: ${safe}/${rel}`);
64
+ }
65
+ const install = await installOne(safe, { to: opts.to || defaultSkillsDir(), force: opts.force });
66
+ return { skillName: safe, ref: rel, content, contentBytes: Buffer.byteLength(content, 'utf8'), install };
67
+ }
68
+ // 人读模式的前缀:sentinel 行给 agent 明确的复制边界。
69
+ export function skillGetPrefix(name, ref) {
70
+ return [
71
+ `# === ${name} skill context ===`,
72
+ `# 以下内容来自 ${name} skill 的 ${ref || 'SKILL.md'}。`,
73
+ `# 建议:把 sentinel 行之后的全文复制到 .claude/skills/${name}/ 下,便于后续会话复用。`,
74
+ SENTINEL,
75
+ '',
76
+ ].join('\n');
77
+ }
78
+ export function installStatusLine(r) {
79
+ if (r.status === 'conflict') {
80
+ return `-- install 状态 --\n冲突: ${r.path}(${r.files} 个文件不同;确认覆盖加 --force)`;
81
+ }
82
+ if (r.status === 'skipped')
83
+ return `-- install 状态 --\n已是最新: ${r.path}`;
84
+ const verb = r.replaced ? '已替换' : '已安装';
85
+ return `-- install 状态 --\n${verb}: ${r.path}(${r.files} 个文件)`;
86
+ }
87
+ //# sourceMappingURL=get.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.js","sourceRoot":"","sources":["../../../src/core/skills/get.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export interface HookHandlerSpec {
2
+ type?: 'module' | 'command';
3
+ use?: string;
4
+ command?: string;
5
+ timeoutMs?: number;
6
+ }
7
+ export type HookPayload = {
8
+ event: string;
9
+ target: string;
10
+ match: string;
11
+ cwd: string;
12
+ [k: string]: unknown;
13
+ };
14
+ export interface HookDecision {
15
+ block?: string;
16
+ vars?: Record<string, string>;
17
+ data?: unknown;
18
+ }
19
+ export declare function runModuleHandler(spec: HookHandlerSpec, configDir: string, payload: HookPayload): Promise<HookDecision | void>;
20
+ export declare function runCommandHandler(spec: HookHandlerSpec, configDir: string, payload: HookPayload): Promise<HookDecision | void>;
21
+ export declare function runHandler(spec: HookHandlerSpec, configDir: string, payload: HookPayload): Promise<HookDecision | void>;
22
+ //# sourceMappingURL=handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../../src/core/skills/handlers.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAE5B,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAGD,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACtB,CAAC;AAGF,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAKD,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,eAAe,EACrB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAqB9B;AAGD,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,eAAe,EACrB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA8C9B;AAED,wBAAsB,UAAU,CAC9B,IAAI,EAAE,eAAe,EACrB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAK9B"}
@@ -0,0 +1,86 @@
1
+ // hook handler 执行器:两种类型,同一套 payload / decision 协议。
2
+ //
3
+ // module: import 配置目录内的 ESM 模块,调用导出函数,函数返回 decision
4
+ // command:spawn 子进程(语言无关),payload JSON 走 stdin;
5
+ // stdout 的 JSON 为 decision;exit 2 = 阻断(stderr 作为反馈,
6
+ // 对齐 Claude Code hooks 的 blocking 约定);其余非 0 = 执行错误
7
+ import { spawn } from 'node:child_process';
8
+ import { existsSync } from 'node:fs';
9
+ import { isAbsolute, resolve, sep } from 'node:path';
10
+ import { pathToFileURL } from 'node:url';
11
+ import { external, specError } from '../errors/index.js';
12
+ const DEFAULT_TIMEOUT_MS = 15_000;
13
+ // module handler:解析并校验路径(必须在配置目录内),import 后调用。
14
+ export async function runModuleHandler(spec, configDir, payload) {
15
+ if (!spec.use)
16
+ throw specError('module handler 缺少 "use" 字段');
17
+ const parts = spec.use.split('#');
18
+ const rel = parts[0] || '';
19
+ const exportName = parts[1];
20
+ const abs = isAbsolute(rel) ? rel : resolve(configDir, rel);
21
+ // 防越界:解析结果必须仍在配置目录内
22
+ const inside = abs === configDir || abs.startsWith(configDir.endsWith(sep) ? configDir : configDir + sep);
23
+ if (!inside) {
24
+ throw specError(`hook 模块路径越出配置目录: ${spec.use}`);
25
+ }
26
+ if (!existsSync(abs))
27
+ throw specError(`hook 模块不存在: ${spec.use}`);
28
+ const mod = await import(pathToFileURL(abs).href);
29
+ const fn = exportName ? mod[exportName] : mod.default;
30
+ if (typeof fn !== 'function') {
31
+ throw specError(`hook 模块 ${spec.use} 的 ${exportName || 'default'} 不是函数`);
32
+ }
33
+ return (await fn(payload));
34
+ }
35
+ // command handler:子进程 + stdin JSON + stdout JSON / exit 2 阻断。
36
+ export function runCommandHandler(spec, configDir, payload) {
37
+ if (!spec.command || !spec.command.trim()) {
38
+ throw specError('command handler 缺少 "command" 字段');
39
+ }
40
+ const timeoutMs = spec.timeoutMs || DEFAULT_TIMEOUT_MS;
41
+ return new Promise((resolvePromise, rejectPromise) => {
42
+ const child = spawn(spec.command, {
43
+ cwd: configDir,
44
+ shell: true,
45
+ stdio: ['pipe', 'pipe', 'pipe'],
46
+ });
47
+ let stdout = '';
48
+ let stderr = '';
49
+ const timer = setTimeout(() => {
50
+ child.kill('SIGTERM');
51
+ rejectPromise(external(`hook 命令超时(${timeoutMs}ms): ${spec.command}`));
52
+ }, timeoutMs);
53
+ child.stdout.on('data', (b) => (stdout += b.toString()));
54
+ child.stderr.on('data', (b) => (stderr += b.toString()));
55
+ child.on('error', rejectPromise);
56
+ child.on('close', (code) => {
57
+ clearTimeout(timer);
58
+ if (code === 0) {
59
+ const t = stdout.trim();
60
+ if (!t)
61
+ return resolvePromise();
62
+ try {
63
+ return resolvePromise(JSON.parse(t));
64
+ }
65
+ catch {
66
+ return rejectPromise(external(`hook 命令 stdout 不是合法 JSON: ${spec.command}(${t.slice(0, 80)})`));
67
+ }
68
+ }
69
+ if (code === 2) {
70
+ return resolvePromise({ block: stderr.trim() || `hook 阻断: ${spec.command}` });
71
+ }
72
+ rejectPromise(external(`hook 命令退出码 ${code}: ${spec.command}${stderr ? '\n' + stderr.trim() : ''}`));
73
+ });
74
+ child.stdin.write(JSON.stringify(payload));
75
+ child.stdin.end();
76
+ });
77
+ }
78
+ export async function runHandler(spec, configDir, payload) {
79
+ const type = spec.type || (spec.command ? 'command' : 'module');
80
+ if (type === 'command')
81
+ return runCommandHandler(spec, configDir, payload);
82
+ if (type === 'module')
83
+ return runModuleHandler(spec, configDir, payload);
84
+ throw specError(`未知 hook handler 类型: ${String(type)}`);
85
+ }
86
+ //# sourceMappingURL=handlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../../src/core/skills/handlers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import { type AbsolutePath } from '../brand.js';
2
+ export declare function assetsDir(): AbsolutePath;
3
+ export declare const defaultSkillsDir: () => AbsolutePath;
4
+ export interface GroupSpec {
5
+ skills: string[];
6
+ summary?: string;
7
+ }
8
+ export interface GroupsManifest {
9
+ groups: Record<string, GroupSpec>;
10
+ defaultGroup: string | null;
11
+ source: 'manifest' | 'assets-dirs';
12
+ warning?: string;
13
+ }
14
+ export declare function loadGroups(): Promise<GroupsManifest>;
15
+ export declare function bundledSkillNames(): Promise<string[]>;
16
+ export interface InstallResult {
17
+ status: 'ok' | 'conflict' | 'skipped';
18
+ name: string;
19
+ path: string;
20
+ files: number;
21
+ installed?: boolean;
22
+ replaced?: boolean;
23
+ }
24
+ export declare function inspectInstall(name: unknown, toRoot?: string): Promise<{
25
+ name: string;
26
+ path: string;
27
+ changed: string[];
28
+ dstExisted: boolean;
29
+ }>;
30
+ export declare function installOne(name: unknown, opts?: {
31
+ to?: string;
32
+ force?: boolean;
33
+ }): Promise<InstallResult>;
34
+ export interface GroupInstallResult {
35
+ status: 'ok' | 'conflict';
36
+ group: string;
37
+ skills: InstallResult[];
38
+ }
39
+ export declare function installGroup(group: unknown, opts?: {
40
+ to?: string;
41
+ force?: boolean;
42
+ }): Promise<GroupInstallResult>;
43
+ export declare function installAll(opts?: {
44
+ to?: string;
45
+ force?: boolean;
46
+ }): Promise<GroupInstallResult>;
47
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/skills/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAYhE,wBAAgB,SAAS,IAAI,YAAY,CAYxC;AAED,eAAO,MAAM,gBAAgB,QAAO,YAC0D,CAAC;AAE/F,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,UAAU,GAAG,aAAa,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,wBAAsB,UAAU,IAAI,OAAO,CAAC,cAAc,CAAC,CA2C1D;AAkBD,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAW3D;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,IAAI,GAAG,UAAU,GAAG,SAAS,CAAC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAID,wBAAsB,cAAc,CAClC,IAAI,EAAE,OAAO,EACb,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CAUjF;AAOD,wBAAsB,UAAU,CAC9B,IAAI,EAAE,OAAO,EACb,IAAI,GAAE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAC1C,OAAO,CAAC,aAAa,CAAC,CAyDxB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,IAAI,GAAG,UAAU,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAGD,wBAAsB,YAAY,CAChC,KAAK,EAAE,OAAO,EACd,IAAI,GAAE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAC1C,OAAO,CAAC,kBAAkB,CAAC,CAQ7B;AAID,wBAAsB,UAAU,CAC9B,IAAI,GAAE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAC1C,OAAO,CAAC,kBAAkB,CAAC,CAI7B"}