@skillfm/local 2.0.0 → 2.0.3

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 (55) hide show
  1. package/dist/agent-hints.d.ts +25 -0
  2. package/dist/agent-hints.d.ts.map +1 -0
  3. package/dist/agent-hints.js +87 -0
  4. package/dist/agent-hints.js.map +1 -0
  5. package/dist/doctor.d.ts +30 -0
  6. package/dist/doctor.d.ts.map +1 -0
  7. package/dist/doctor.js +272 -0
  8. package/dist/doctor.js.map +1 -0
  9. package/dist/guard/bin.d.ts +11 -0
  10. package/dist/guard/bin.d.ts.map +1 -0
  11. package/dist/guard/bin.js +16 -0
  12. package/dist/guard/bin.js.map +1 -0
  13. package/dist/guard/cli.d.ts +23 -0
  14. package/dist/guard/cli.d.ts.map +1 -0
  15. package/dist/guard/cli.js +249 -0
  16. package/dist/guard/cli.js.map +1 -0
  17. package/dist/guard/sidecar-client.d.ts +46 -0
  18. package/dist/guard/sidecar-client.d.ts.map +1 -0
  19. package/dist/guard/sidecar-client.js +92 -0
  20. package/dist/guard/sidecar-client.js.map +1 -0
  21. package/dist/guard/state.d.ts +80 -0
  22. package/dist/guard/state.d.ts.map +1 -0
  23. package/dist/guard/state.js +119 -0
  24. package/dist/guard/state.js.map +1 -0
  25. package/dist/harness/detector.d.ts +47 -0
  26. package/dist/harness/detector.d.ts.map +1 -0
  27. package/dist/harness/detector.js +177 -0
  28. package/dist/harness/detector.js.map +1 -0
  29. package/dist/harness/priming.d.ts +42 -0
  30. package/dist/harness/priming.d.ts.map +1 -0
  31. package/dist/harness/priming.js +89 -0
  32. package/dist/harness/priming.js.map +1 -0
  33. package/dist/harness/templates.d.ts +108 -0
  34. package/dist/harness/templates.d.ts.map +1 -0
  35. package/dist/harness/templates.js +171 -0
  36. package/dist/harness/templates.js.map +1 -0
  37. package/dist/harness/writers.d.ts +82 -0
  38. package/dist/harness/writers.d.ts.map +1 -0
  39. package/dist/harness/writers.js +266 -0
  40. package/dist/harness/writers.js.map +1 -0
  41. package/dist/index.js +562 -4
  42. package/dist/index.js.map +1 -1
  43. package/dist/lang.d.ts +21 -0
  44. package/dist/lang.d.ts.map +1 -0
  45. package/dist/lang.js +62 -0
  46. package/dist/lang.js.map +1 -0
  47. package/dist/soul-security.d.ts +76 -0
  48. package/dist/soul-security.d.ts.map +1 -0
  49. package/dist/soul-security.js +197 -0
  50. package/dist/soul-security.js.map +1 -0
  51. package/dist/soul.d.ts +135 -0
  52. package/dist/soul.d.ts.map +1 -0
  53. package/dist/soul.js +439 -0
  54. package/dist/soul.js.map +1 -0
  55. package/package.json +7 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/harness/templates.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * BSO M9-2 — 配置写入器(idempotent + backup)
3
+ *
4
+ * Refs: docs/prd/PRD-BSO-M9-HARNESS-HOOKS.md §3.3 + §7.3 回滚
5
+ *
6
+ * 职责:
7
+ * - 写 LLM priming block 到 CLAUDE.md / AGENTS.md(追加在尾部,用 SKILLFM-BEGIN/END 边界,
8
+ * 复用 soul.ts 的 block 机制,已存在则先撤再写 → 唯一)
9
+ * - 合并(不覆盖)Claude Code settings.json 的 hooks
10
+ * - 合并 Aider .aider.conf.yml 的 commands_pre/post
11
+ * - 所有写入前都 backup 原文件到 ~/.skillfm/backups/<ts>/
12
+ * - 所有操作 idempotent — 已注册则 skip
13
+ *
14
+ * 不实现:
15
+ * - PR #7 已落的 soul 文件写入(writeSkillfmBlock 在 soul.ts)— priming 和 soul block
16
+ * 是同一个 BEGIN/END 边界块,共用一套基础设施
17
+ * - MCP stdio bridge(需要另做,M9 范围外)
18
+ */
19
+ import { type AiderConfigPatch, type ClaudeSettingsPatch, type HarnessPaths } from './templates.js';
20
+ import type { Harness } from './detector.js';
21
+ import { type PrimingLang } from './priming.js';
22
+ export type HarnessWriterErrorCode = 'SKILLFM.HARNESS.UNSUPPORTED' | 'SKILLFM.HARNESS.WRITE_FAILED' | 'SKILLFM.HARNESS.PARSE_FAILED';
23
+ export declare class HarnessWriterError extends Error {
24
+ code: HarnessWriterErrorCode;
25
+ constructor(code: HarnessWriterErrorCode, message: string);
26
+ }
27
+ export interface InitReport {
28
+ harness: Harness;
29
+ paths: HarnessPaths;
30
+ llm_priming: {
31
+ file: string;
32
+ action: 'created' | 'appended' | 'replaced' | 'already-present';
33
+ };
34
+ harness_config: {
35
+ file: string | null;
36
+ action: 'created' | 'merged' | 'already-registered' | 'skipped-no-hook-support' | 'skipped-no-config-file';
37
+ details?: string;
38
+ };
39
+ warnings: string[];
40
+ }
41
+ /**
42
+ * 把 priming block 写入目标文件。BEGIN/END 边界。
43
+ * 已存在 → 先移除旧的再追加新的(upgrade-safe)。
44
+ */
45
+ export declare function writePrimingBlock(filePath: string, lang?: PrimingLang): {
46
+ action: InitReport['llm_priming']['action'];
47
+ bytesWritten: number;
48
+ };
49
+ /**
50
+ * additive merge:
51
+ * - 已有 hooks.SessionStart / PreToolUse / PostToolUse 保留
52
+ * - 我们的 hooks(identified by command startsWith(SKILLFM_GUARD_COMMAND))已在则 skip
53
+ * - 否则 append
54
+ */
55
+ export declare function mergeClaudeSettings(filePath: string, patch: ClaudeSettingsPatch): {
56
+ action: InitReport['harness_config']['action'];
57
+ details?: string;
58
+ };
59
+ /**
60
+ * Aider 配置用 YAML,但我们只需要设置 `commands_pre` / `commands_post` 两个 list。
61
+ * 避免引入 `js-yaml` 依赖(@skillfm/local 坚持 zero-dep)— 手写 minimal YAML writer。
62
+ *
63
+ * 策略:
64
+ * - 文件不存在 → 创建只含我们的两个 key
65
+ * - 文件存在 → 读为字符串,grep `commands_pre:` / `commands_post:` 是否已含我们的命令;
66
+ * 已含则 skip,否则追加
67
+ *
68
+ * 不尝试全解析 YAML(复杂度高、易出错),只做 append-safe 操作。
69
+ */
70
+ export declare function mergeAiderConfig(filePath: string, patch: AiderConfigPatch): {
71
+ action: InitReport['harness_config']['action'];
72
+ details?: string;
73
+ };
74
+ export interface InitHarnessOptions {
75
+ harness: Harness;
76
+ cwd: string;
77
+ lang?: PrimingLang;
78
+ /** 若为 true,跳过 harness 层写入(只写 LLM 层 priming)*/
79
+ llmOnly?: boolean;
80
+ }
81
+ export declare function initHarness(opts: InitHarnessOptions): InitReport;
82
+ //# sourceMappingURL=writers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writers.d.ts","sourceRoot":"","sources":["../../src/harness/writers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AASH,OAAO,EAML,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,YAAY,EAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAgD,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAO9F,MAAM,MAAM,sBAAsB,GAC9B,6BAA6B,GAC7B,8BAA8B,GAC9B,8BAA8B,CAAC;AAEnC,qBAAa,kBAAmB,SAAQ,KAAK;IACxB,IAAI,EAAE,sBAAsB;gBAA5B,IAAI,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM;CAIjE;AAMD,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,YAAY,CAAC;IACpB,WAAW,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,iBAAiB,CAAC;KACjE,CAAC;IACF,cAAc,EAAE;QACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QACpB,MAAM,EACF,SAAS,GACT,QAAQ,GACR,oBAAoB,GACpB,yBAAyB,GACzB,wBAAwB,CAAC;QAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,WAAoB,GACzB;IAAE,MAAM,EAAE,UAAU,CAAC,aAAa,CAAC,CAAC,QAAQ,CAAC,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAgDvE;AAMD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,mBAAmB,GACzB;IAAE,MAAM,EAAE,UAAU,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAsEtE;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,gBAAgB,GACtB;IAAE,MAAM,EAAE,UAAU,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CA2CtE;AAMD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,UAAU,CA2DhE"}
@@ -0,0 +1,266 @@
1
+ /**
2
+ * BSO M9-2 — 配置写入器(idempotent + backup)
3
+ *
4
+ * Refs: docs/prd/PRD-BSO-M9-HARNESS-HOOKS.md §3.3 + §7.3 回滚
5
+ *
6
+ * 职责:
7
+ * - 写 LLM priming block 到 CLAUDE.md / AGENTS.md(追加在尾部,用 SKILLFM-BEGIN/END 边界,
8
+ * 复用 soul.ts 的 block 机制,已存在则先撤再写 → 唯一)
9
+ * - 合并(不覆盖)Claude Code settings.json 的 hooks
10
+ * - 合并 Aider .aider.conf.yml 的 commands_pre/post
11
+ * - 所有写入前都 backup 原文件到 ~/.skillfm/backups/<ts>/
12
+ * - 所有操作 idempotent — 已注册则 skip
13
+ *
14
+ * 不实现:
15
+ * - PR #7 已落的 soul 文件写入(writeSkillfmBlock 在 soul.ts)— priming 和 soul block
16
+ * 是同一个 BEGIN/END 边界块,共用一套基础设施
17
+ * - MCP stdio bridge(需要另做,M9 范围外)
18
+ */
19
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, } from 'node:fs';
20
+ import { dirname } from 'node:path';
21
+ import { aiderConfigPatch, capabilitiesFor, claudeSettingsPatch, pathsFor, SKILLFM_GUARD_COMMAND, } from './templates.js';
22
+ import { wrapPrimingBlock, PRIMING_BEGIN, PRIMING_END } from './priming.js';
23
+ import { backupFileBeforeWrite } from '../soul-security.js';
24
+ export class HarnessWriterError extends Error {
25
+ code;
26
+ constructor(code, message) {
27
+ super(message);
28
+ this.code = code;
29
+ this.name = 'HarnessWriterError';
30
+ }
31
+ }
32
+ // ============================================================================
33
+ // LLM 层写入:priming block
34
+ // ============================================================================
35
+ /**
36
+ * 把 priming block 写入目标文件。BEGIN/END 边界。
37
+ * 已存在 → 先移除旧的再追加新的(upgrade-safe)。
38
+ */
39
+ export function writePrimingBlock(filePath, lang = 'auto') {
40
+ const block = wrapPrimingBlock(lang);
41
+ const existed = existsSync(filePath);
42
+ const original = existed ? readFileSync(filePath, 'utf-8') : '';
43
+ const alreadyHas = original.includes(PRIMING_BEGIN);
44
+ // upgrade-safe:如果已经有 block 且完全一致 → no-op
45
+ if (alreadyHas && original.includes(block.trimEnd())) {
46
+ return { action: 'already-present', bytesWritten: 0 };
47
+ }
48
+ // backup 原文件(若存在)
49
+ if (existed) {
50
+ try {
51
+ backupFileBeforeWrite(filePath, original);
52
+ }
53
+ catch {
54
+ // backup 失败不致命(priming 不同于 soul 写入,非安全关键)
55
+ }
56
+ }
57
+ let next;
58
+ let action;
59
+ if (alreadyHas) {
60
+ // 移除旧 block 再追加新
61
+ const startIdx = original.indexOf(PRIMING_BEGIN);
62
+ const endIdx = original.indexOf(PRIMING_END);
63
+ if (startIdx === -1 || endIdx === -1 || endIdx < startIdx) {
64
+ throw new HarnessWriterError('SKILLFM.HARNESS.PARSE_FAILED', `${filePath} 含 SKILLFM-BEGIN 但 END 缺失/顺序反转,拒绝自动修复,请手动检查`);
65
+ }
66
+ const before = original.slice(0, startIdx).replace(/\n+$/, '\n');
67
+ const after = original.slice(endIdx + PRIMING_END.length).replace(/^\n+/, '');
68
+ next = `${before}\n${block}${after}`.replace(/\n{3,}/g, '\n\n');
69
+ action = 'replaced';
70
+ }
71
+ else if (existed) {
72
+ next = `${original}${original.endsWith('\n') ? '' : '\n'}\n${block}`;
73
+ action = 'appended';
74
+ }
75
+ else {
76
+ mkdirSync(dirname(filePath), { recursive: true });
77
+ next = block;
78
+ action = 'created';
79
+ }
80
+ writeFileSync(filePath, next, { encoding: 'utf-8', mode: 0o644 });
81
+ return { action, bytesWritten: Buffer.byteLength(next, 'utf-8') };
82
+ }
83
+ // ============================================================================
84
+ // Claude Code settings.json 合并
85
+ // ============================================================================
86
+ /**
87
+ * additive merge:
88
+ * - 已有 hooks.SessionStart / PreToolUse / PostToolUse 保留
89
+ * - 我们的 hooks(identified by command startsWith(SKILLFM_GUARD_COMMAND))已在则 skip
90
+ * - 否则 append
91
+ */
92
+ export function mergeClaudeSettings(filePath, patch) {
93
+ const existed = existsSync(filePath);
94
+ const original = existed ? readFileSync(filePath, 'utf-8') : '{}';
95
+ let data;
96
+ try {
97
+ data = JSON.parse(original);
98
+ }
99
+ catch (err) {
100
+ throw new HarnessWriterError('SKILLFM.HARNESS.PARSE_FAILED', `${filePath} 不是合法 JSON: ${err.message}`);
101
+ }
102
+ if (!data || typeof data !== 'object')
103
+ data = {};
104
+ if (!data.hooks || typeof data.hooks !== 'object')
105
+ data.hooks = {};
106
+ let addedCount = 0;
107
+ let skippedCount = 0;
108
+ const mergeSection = (section) => {
109
+ const ours = patch.hooks[section];
110
+ if (!ours)
111
+ return;
112
+ if (!Array.isArray(data.hooks[section]))
113
+ data.hooks[section] = [];
114
+ for (const entry of ours) {
115
+ const alreadyHas = data.hooks[section].some((h) => (h.hooks || []).some((x) => typeof x.command === 'string' && x.command.startsWith(SKILLFM_GUARD_COMMAND)));
116
+ if (alreadyHas) {
117
+ skippedCount += 1;
118
+ }
119
+ else {
120
+ data.hooks[section].push(entry);
121
+ addedCount += 1;
122
+ }
123
+ }
124
+ };
125
+ mergeSection('SessionStart');
126
+ mergeSection('PreToolUse');
127
+ mergeSection('PostToolUse');
128
+ if (existed) {
129
+ try {
130
+ backupFileBeforeWrite(filePath, original);
131
+ }
132
+ catch {
133
+ // backup 失败不致命
134
+ }
135
+ }
136
+ else {
137
+ mkdirSync(dirname(filePath), { recursive: true });
138
+ }
139
+ const out = JSON.stringify(data, null, 2) + '\n';
140
+ writeFileSync(filePath, out, { encoding: 'utf-8', mode: 0o644 });
141
+ if (addedCount === 0 && skippedCount > 0) {
142
+ return { action: 'already-registered', details: `all ${skippedCount} hooks already present` };
143
+ }
144
+ if (!existed) {
145
+ return { action: 'created', details: `added ${addedCount} hook(s)` };
146
+ }
147
+ return {
148
+ action: 'merged',
149
+ details: `added ${addedCount} / skipped ${skippedCount} existing hook(s)`,
150
+ };
151
+ }
152
+ // ============================================================================
153
+ // Aider .aider.conf.yml 合并(极简 YAML 操作,不引入 yaml 依赖)
154
+ // ============================================================================
155
+ /**
156
+ * Aider 配置用 YAML,但我们只需要设置 `commands_pre` / `commands_post` 两个 list。
157
+ * 避免引入 `js-yaml` 依赖(@skillfm/local 坚持 zero-dep)— 手写 minimal YAML writer。
158
+ *
159
+ * 策略:
160
+ * - 文件不存在 → 创建只含我们的两个 key
161
+ * - 文件存在 → 读为字符串,grep `commands_pre:` / `commands_post:` 是否已含我们的命令;
162
+ * 已含则 skip,否则追加
163
+ *
164
+ * 不尝试全解析 YAML(复杂度高、易出错),只做 append-safe 操作。
165
+ */
166
+ export function mergeAiderConfig(filePath, patch) {
167
+ const existed = existsSync(filePath);
168
+ const original = existed ? readFileSync(filePath, 'utf-8') : '';
169
+ const guardMarker = SKILLFM_GUARD_COMMAND;
170
+ const alreadyHasPre = original.includes('commands_pre') && original.includes(guardMarker);
171
+ const alreadyHasPost = original.includes('commands_post') && original.includes(guardMarker);
172
+ if (alreadyHasPre && alreadyHasPost) {
173
+ return { action: 'already-registered' };
174
+ }
175
+ const header = existed && !original.endsWith('\n') ? `${original}\n` : original;
176
+ const appendedBlock = [
177
+ '',
178
+ '# SkillFM M9 harness hooks (managed by @skillfm/local; edit via `skillfm init`)',
179
+ `commands_pre:`,
180
+ ...patch.commands_pre.map((c) => ` - "${c}"`),
181
+ `commands_post:`,
182
+ ...patch.commands_post.map((c) => ` - "${c}"`),
183
+ '',
184
+ ].join('\n');
185
+ if (existed) {
186
+ try {
187
+ backupFileBeforeWrite(filePath, original);
188
+ }
189
+ catch {
190
+ /* not critical */
191
+ }
192
+ }
193
+ else {
194
+ mkdirSync(dirname(filePath), { recursive: true });
195
+ }
196
+ const next = `${header}${appendedBlock}`;
197
+ writeFileSync(filePath, next, { encoding: 'utf-8', mode: 0o644 });
198
+ return {
199
+ action: existed ? 'merged' : 'created',
200
+ details: `appended commands_pre/post (${patch.commands_pre.length}/${patch.commands_post.length})`,
201
+ };
202
+ }
203
+ export function initHarness(opts) {
204
+ const paths = pathsFor(opts.harness, opts.cwd);
205
+ const caps = capabilitiesFor(opts.harness);
206
+ const warnings = [];
207
+ // 1. LLM priming
208
+ const llm = writePrimingBlock(paths.primingFile, opts.lang ?? 'auto');
209
+ // 2. harness 层
210
+ let harnessConfig;
211
+ if (opts.llmOnly || !paths.harnessConfigFile || !caps.preToolUseHook) {
212
+ harnessConfig = {
213
+ file: paths.harnessConfigFile,
214
+ action: !paths.harnessConfigFile
215
+ ? 'skipped-no-config-file'
216
+ : 'skipped-no-hook-support',
217
+ details: caps.fallback,
218
+ };
219
+ if (caps.fallback)
220
+ warnings.push(caps.fallback);
221
+ }
222
+ else {
223
+ try {
224
+ if (opts.harness === 'claude-code') {
225
+ const r = mergeClaudeSettings(paths.harnessConfigFile, claudeSettingsPatch());
226
+ harnessConfig = { file: paths.harnessConfigFile, action: r.action, details: r.details };
227
+ }
228
+ else if (opts.harness === 'aider') {
229
+ const r = mergeAiderConfig(paths.harnessConfigFile, aiderConfigPatch());
230
+ harnessConfig = { file: paths.harnessConfigFile, action: r.action, details: r.details };
231
+ }
232
+ else {
233
+ harnessConfig = {
234
+ file: paths.harnessConfigFile,
235
+ action: 'skipped-no-hook-support',
236
+ details: `${opts.harness} PreToolUse hook not yet implemented`,
237
+ };
238
+ warnings.push(harnessConfig.details);
239
+ }
240
+ }
241
+ catch (err) {
242
+ if (err instanceof HarnessWriterError) {
243
+ harnessConfig = {
244
+ file: paths.harnessConfigFile,
245
+ action: 'skipped-no-hook-support',
246
+ details: `${err.code}: ${err.message}`,
247
+ };
248
+ warnings.push(err.message);
249
+ }
250
+ else {
251
+ throw err;
252
+ }
253
+ }
254
+ }
255
+ return {
256
+ harness: opts.harness,
257
+ paths,
258
+ llm_priming: {
259
+ file: paths.primingFile,
260
+ action: llm.action,
261
+ },
262
+ harness_config: harnessConfig,
263
+ warnings,
264
+ };
265
+ }
266
+ //# sourceMappingURL=writers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writers.js","sourceRoot":"","sources":["../../src/harness/writers.ts"],"names":[],"mappings":"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"}