@skillfm/local 2.0.4 → 2.0.6
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/dist/agent-hints.d.ts.map +1 -1
- package/dist/agent-hints.js +29 -14
- package/dist/agent-hints.js.map +1 -1
- package/dist/doctor.d.ts +26 -0
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +184 -0
- package/dist/doctor.js.map +1 -1
- package/dist/guard/bin.js +0 -0
- package/dist/guard/cli.d.ts.map +1 -1
- package/dist/guard/cli.js +26 -0
- package/dist/guard/cli.js.map +1 -1
- package/dist/harness/kernels/deny-pipeline.d.ts +21 -0
- package/dist/harness/kernels/deny-pipeline.d.ts.map +1 -0
- package/dist/harness/kernels/deny-pipeline.js +225 -0
- package/dist/harness/kernels/deny-pipeline.js.map +1 -0
- package/dist/harness/kernels/hook-file.d.ts +16 -0
- package/dist/harness/kernels/hook-file.d.ts.map +1 -0
- package/dist/harness/kernels/hook-file.js +229 -0
- package/dist/harness/kernels/hook-file.js.map +1 -0
- package/dist/harness/kernels/json-merge.d.ts +45 -0
- package/dist/harness/kernels/json-merge.d.ts.map +1 -0
- package/dist/harness/kernels/json-merge.js +123 -0
- package/dist/harness/kernels/json-merge.js.map +1 -0
- package/dist/harness/kernels/mcp-only.d.ts +23 -0
- package/dist/harness/kernels/mcp-only.d.ts.map +1 -0
- package/dist/harness/kernels/mcp-only.js +215 -0
- package/dist/harness/kernels/mcp-only.js.map +1 -0
- package/dist/harness/kernels/protocol-reject.d.ts +18 -0
- package/dist/harness/kernels/protocol-reject.d.ts.map +1 -0
- package/dist/harness/kernels/protocol-reject.js +117 -0
- package/dist/harness/kernels/protocol-reject.js.map +1 -0
- package/dist/harness/kernels/registry.d.ts +56 -0
- package/dist/harness/kernels/registry.d.ts.map +1 -0
- package/dist/harness/kernels/registry.js +139 -0
- package/dist/harness/kernels/registry.js.map +1 -0
- package/dist/harness/kernels/types.d.ts +86 -0
- package/dist/harness/kernels/types.d.ts.map +1 -0
- package/dist/harness/kernels/types.js +21 -0
- package/dist/harness/kernels/types.js.map +1 -0
- package/dist/index.js +467 -19
- package/dist/index.js.map +1 -1
- package/dist/mcp-output/builder.d.ts +24 -0
- package/dist/mcp-output/builder.d.ts.map +1 -0
- package/dist/mcp-output/builder.js +99 -0
- package/dist/mcp-output/builder.js.map +1 -0
- package/dist/mcp-output/deny-review.d.ts +64 -0
- package/dist/mcp-output/deny-review.d.ts.map +1 -0
- package/dist/mcp-output/deny-review.js +212 -0
- package/dist/mcp-output/deny-review.js.map +1 -0
- package/dist/mcp-output/types.d.ts +64 -0
- package/dist/mcp-output/types.d.ts.map +1 -0
- package/dist/mcp-output/types.js +21 -0
- package/dist/mcp-output/types.js.map +1 -0
- package/dist/skill-md/template.d.ts +30 -0
- package/dist/skill-md/template.d.ts.map +1 -0
- package/dist/skill-md/template.js +194 -0
- package/dist/skill-md/template.js.map +1 -0
- package/dist/skill-md/writer.d.ts +30 -0
- package/dist/skill-md/writer.d.ts.map +1 -0
- package/dist/skill-md/writer.js +129 -0
- package/dist/skill-md/writer.js.map +1 -0
- package/package.json +3 -2
- package/dist/lang.d.ts +0 -21
- package/dist/lang.d.ts.map +0 -1
- package/dist/lang.js +0 -62
- package/dist/lang.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deny-review.js","sourceRoot":"","sources":["../../src/mcp-output/deny-review.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BSO M9.5 — MCP Protocol-Reject 输出层类型
|
|
3
|
+
*
|
|
4
|
+
* Refs:
|
|
5
|
+
* - docs/prd/PRD-BSO-M9-HARNESS-HOOKS.md §3.3
|
|
6
|
+
* - docs/research/EMERGING-AGENT-PRODUCTS-2026-04-19.md §3
|
|
7
|
+
* - MCP spec 2025-11-25
|
|
8
|
+
* · tools/call response with isError
|
|
9
|
+
* · elicitation/create
|
|
10
|
+
* · URLElicitationRequiredError (-32042)
|
|
11
|
+
*/
|
|
12
|
+
export declare const MCP_OUTPUT_VERSION = "v2";
|
|
13
|
+
export declare const MCP_OUTPUT_FEATURES: readonly ["isError", "elicitation", "url-elicitation-required-error"];
|
|
14
|
+
export type McpOutputFeature = (typeof MCP_OUTPUT_FEATURES)[number];
|
|
15
|
+
export interface RejectInput {
|
|
16
|
+
/** 任务 id(生命周期内唯一,用于 elicitation 配对) */
|
|
17
|
+
task_id: string;
|
|
18
|
+
/** 触发的 9 红线 ID(S1-S9) */
|
|
19
|
+
redline?: string;
|
|
20
|
+
/** 风险等级 */
|
|
21
|
+
tier?: 'A' | 'B' | 'C';
|
|
22
|
+
/** 失败原因(中文,给用户看) */
|
|
23
|
+
reason: string;
|
|
24
|
+
/** 操作建议(中文,给用户看) */
|
|
25
|
+
hint?: string;
|
|
26
|
+
/** 触发的 tool 名 */
|
|
27
|
+
tool?: string;
|
|
28
|
+
/** sidecar 自身 base URL(构造 /deny-review/:task_id 用) */
|
|
29
|
+
sidecarBaseUrl: string;
|
|
30
|
+
/** request id (jsonrpc) — 镜像回 MCP error response */
|
|
31
|
+
requestId?: string | number | null;
|
|
32
|
+
}
|
|
33
|
+
export interface McpRejectEnvelope {
|
|
34
|
+
/** RFC 8259: 协议层错误(机制 A)*/
|
|
35
|
+
error?: {
|
|
36
|
+
jsonrpc: '2.0';
|
|
37
|
+
id: string | number | null;
|
|
38
|
+
error: {
|
|
39
|
+
code: -32042;
|
|
40
|
+
message: string;
|
|
41
|
+
data: {
|
|
42
|
+
elicitations: Array<{
|
|
43
|
+
mode: 'url';
|
|
44
|
+
elicitationId: string;
|
|
45
|
+
url: string;
|
|
46
|
+
message: string;
|
|
47
|
+
}>;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
/** result + isError(机制 B,最广兼容)*/
|
|
52
|
+
result: {
|
|
53
|
+
jsonrpc: '2.0';
|
|
54
|
+
id: string | number | null;
|
|
55
|
+
result: {
|
|
56
|
+
content: Array<{
|
|
57
|
+
type: 'text';
|
|
58
|
+
text: string;
|
|
59
|
+
}>;
|
|
60
|
+
isError: true;
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/mcp-output/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC,eAAO,MAAM,mBAAmB,uEAItB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAMpE,MAAM,WAAW,WAAW;IAC1B,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,yBAAyB;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW;IACX,IAAI,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IACvB,oBAAoB;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iBAAiB;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,cAAc,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CACpC;AAMD,MAAM,WAAW,iBAAiB;IAChC,2BAA2B;IAC3B,KAAK,CAAC,EAAE;QACN,OAAO,EAAE,KAAK,CAAC;QACf,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;QAC3B,KAAK,EAAE;YACL,IAAI,EAAE,CAAC,KAAK,CAAC;YACb,OAAO,EAAE,MAAM,CAAC;YAChB,IAAI,EAAE;gBACJ,YAAY,EAAE,KAAK,CAAC;oBAClB,IAAI,EAAE,KAAK,CAAC;oBACZ,aAAa,EAAE,MAAM,CAAC;oBACtB,GAAG,EAAE,MAAM,CAAC;oBACZ,OAAO,EAAE,MAAM,CAAC;iBACjB,CAAC,CAAC;aACJ,CAAC;SACH,CAAC;KACH,CAAC;IACF,iCAAiC;IACjC,MAAM,EAAE;QACN,OAAO,EAAE,KAAK,CAAC;QACf,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;QAC3B,MAAM,EAAE;YACN,OAAO,EAAE,KAAK,CAAC;gBAAE,IAAI,EAAE,MAAM,CAAC;gBAAC,IAAI,EAAE,MAAM,CAAA;aAAE,CAAC,CAAC;YAC/C,OAAO,EAAE,IAAI,CAAC;SACf,CAAC;KACH,CAAC;CACH"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BSO M9.5 — MCP Protocol-Reject 输出层类型
|
|
3
|
+
*
|
|
4
|
+
* Refs:
|
|
5
|
+
* - docs/prd/PRD-BSO-M9-HARNESS-HOOKS.md §3.3
|
|
6
|
+
* - docs/research/EMERGING-AGENT-PRODUCTS-2026-04-19.md §3
|
|
7
|
+
* - MCP spec 2025-11-25
|
|
8
|
+
* · tools/call response with isError
|
|
9
|
+
* · elicitation/create
|
|
10
|
+
* · URLElicitationRequiredError (-32042)
|
|
11
|
+
*/
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// 输出层版本(doctor probe 用)
|
|
14
|
+
// ============================================================================
|
|
15
|
+
export const MCP_OUTPUT_VERSION = 'v2';
|
|
16
|
+
export const MCP_OUTPUT_FEATURES = [
|
|
17
|
+
'isError',
|
|
18
|
+
'elicitation',
|
|
19
|
+
'url-elicitation-required-error',
|
|
20
|
+
];
|
|
21
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/mcp-output/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,+EAA+E;AAC/E,wBAAwB;AACxB,+EAA+E;AAE/E,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEvC,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,SAAS;IACT,aAAa;IACb,gCAAgC;CACxB,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BSO M9 v0.3 — Layer 1: SKILL.md 模板(兼容 Anthropic Skills 格式)
|
|
3
|
+
*
|
|
4
|
+
* Refs:
|
|
5
|
+
* - docs/prd/PRD-BSO-M9-HARNESS-HOOKS.md §3.2
|
|
6
|
+
* - 主公决策 Q2=B': Layer 1 文件格式 100% 对齐 Anthropic Skills 标准;
|
|
7
|
+
* Layer 2/3 拦截协议保持 SkillFM 差异化。
|
|
8
|
+
*
|
|
9
|
+
* 文件格式:YAML frontmatter + Markdown body
|
|
10
|
+
* frontmatter 字段(Anthropic Skills 标准):
|
|
11
|
+
* - name: 唯一 slug
|
|
12
|
+
* - description: 何时触发本 skill 的描述(写给 LLM 看)
|
|
13
|
+
* - license: 默认 Apache-2.0
|
|
14
|
+
* - allowed-tools: skill 调用的 tool 白名单
|
|
15
|
+
* - metadata: 自定义字段(嵌套,不污染顶层)
|
|
16
|
+
*
|
|
17
|
+
* 写入位置(由 writer.ts 决定):
|
|
18
|
+
* - 项目级:./SKILL.md
|
|
19
|
+
* - Anthropic Claude Code 用户级(可选):~/.claude/skills/skillfm-bso/SKILL.md
|
|
20
|
+
*/
|
|
21
|
+
export type SkillLang = 'zh' | 'en' | 'auto';
|
|
22
|
+
export declare const SKILL_MD_BEGIN = "<!-- SKILLFM-SKILL-BEGIN: do not edit, managed by @skillfm/local -->";
|
|
23
|
+
export declare const SKILL_MD_END = "<!-- SKILLFM-SKILL-END -->";
|
|
24
|
+
export interface BuildSkillMdOptions {
|
|
25
|
+
lang?: SkillLang;
|
|
26
|
+
/** 是否包含 SKILLFM-BEGIN/END 边界(写到现有文件时建议 true)*/
|
|
27
|
+
withBoundaryMarkers?: boolean;
|
|
28
|
+
}
|
|
29
|
+
export declare function buildSkillMd(opts?: BuildSkillMdOptions): string;
|
|
30
|
+
//# sourceMappingURL=template.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/skill-md/template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AA+CH,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;AAwI7C,eAAO,MAAM,cAAc,yEAAyE,CAAC;AACrG,eAAO,MAAM,YAAY,+BAA+B,CAAC;AAMzD,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,+CAA+C;IAC/C,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,wBAAgB,YAAY,CAAC,IAAI,GAAE,mBAAwB,GAAG,MAAM,CASnE"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BSO M9 v0.3 — Layer 1: SKILL.md 模板(兼容 Anthropic Skills 格式)
|
|
3
|
+
*
|
|
4
|
+
* Refs:
|
|
5
|
+
* - docs/prd/PRD-BSO-M9-HARNESS-HOOKS.md §3.2
|
|
6
|
+
* - 主公决策 Q2=B': Layer 1 文件格式 100% 对齐 Anthropic Skills 标准;
|
|
7
|
+
* Layer 2/3 拦截协议保持 SkillFM 差异化。
|
|
8
|
+
*
|
|
9
|
+
* 文件格式:YAML frontmatter + Markdown body
|
|
10
|
+
* frontmatter 字段(Anthropic Skills 标准):
|
|
11
|
+
* - name: 唯一 slug
|
|
12
|
+
* - description: 何时触发本 skill 的描述(写给 LLM 看)
|
|
13
|
+
* - license: 默认 Apache-2.0
|
|
14
|
+
* - allowed-tools: skill 调用的 tool 白名单
|
|
15
|
+
* - metadata: 自定义字段(嵌套,不污染顶层)
|
|
16
|
+
*
|
|
17
|
+
* 写入位置(由 writer.ts 决定):
|
|
18
|
+
* - 项目级:./SKILL.md
|
|
19
|
+
* - Anthropic Claude Code 用户级(可选):~/.claude/skills/skillfm-bso/SKILL.md
|
|
20
|
+
*/
|
|
21
|
+
import { readFileSync } from 'node:fs';
|
|
22
|
+
import { join } from 'node:path';
|
|
23
|
+
import { fileURLToPath } from 'node:url';
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// 元信息(运行时读包 version,避免硬编码漂移)
|
|
26
|
+
// ============================================================================
|
|
27
|
+
function loadPackageVersion() {
|
|
28
|
+
const here = __dirnameSafe();
|
|
29
|
+
// 候选路径(覆盖 dist/skill-md/, src/skill-md/, 以及 npm install 安装路径)
|
|
30
|
+
const candidates = [
|
|
31
|
+
join(here, '..', '..', 'package.json'), // dist/skill-md/template.js → ../../package.json
|
|
32
|
+
join(here, '..', 'package.json'),
|
|
33
|
+
join(here, '..', '..', '..', 'package.json'),
|
|
34
|
+
];
|
|
35
|
+
for (const p of candidates) {
|
|
36
|
+
try {
|
|
37
|
+
const raw = readFileSync(p, 'utf-8');
|
|
38
|
+
const pkg = JSON.parse(raw);
|
|
39
|
+
if (pkg?.name === '@skillfm/local' && typeof pkg.version === 'string') {
|
|
40
|
+
return pkg.version;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// continue
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return 'unknown';
|
|
48
|
+
}
|
|
49
|
+
function __dirnameSafe() {
|
|
50
|
+
try {
|
|
51
|
+
if (typeof import.meta !== 'undefined' && import.meta.url) {
|
|
52
|
+
return fileURLToPath(new URL('.', import.meta.url));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// fall through
|
|
57
|
+
}
|
|
58
|
+
return process.cwd();
|
|
59
|
+
}
|
|
60
|
+
const DEFAULT_FRONTMATTER = () => ({
|
|
61
|
+
name: 'skillfm-bso-priming',
|
|
62
|
+
description: 'SkillFM BSO 协议 priming — 触发条件:当前 workspace 装了 @skillfm/local 且任务涉及破坏性操作(写文件 / 改代码 / 跑命令 / 调外部 API / 涉及支付)时自动加载',
|
|
63
|
+
license: 'Apache-2.0',
|
|
64
|
+
'allowed-tools': [
|
|
65
|
+
'mcp__skillfm__brain_run',
|
|
66
|
+
'mcp__skillfm__list_skills',
|
|
67
|
+
'mcp__skillfm__my_status',
|
|
68
|
+
'mcp__skillfm__guard_status',
|
|
69
|
+
],
|
|
70
|
+
metadata: {
|
|
71
|
+
skillfm_version: loadPackageVersion(),
|
|
72
|
+
bso_version: 'v1.1',
|
|
73
|
+
layer: 1,
|
|
74
|
+
homepage: 'https://skillfm.ai',
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
function renderFrontmatterYaml(fm) {
|
|
78
|
+
// 手写极简 YAML(避免引入 yaml 依赖;@skillfm/local zero-dep 原则)
|
|
79
|
+
const lines = [
|
|
80
|
+
'---',
|
|
81
|
+
`name: ${fm.name}`,
|
|
82
|
+
`description: ${quoteIfNeeded(fm.description)}`,
|
|
83
|
+
`license: ${fm.license}`,
|
|
84
|
+
'allowed-tools:',
|
|
85
|
+
...fm['allowed-tools'].map((t) => ` - ${t}`),
|
|
86
|
+
'metadata:',
|
|
87
|
+
` skillfm_version: "${fm.metadata.skillfm_version}"`,
|
|
88
|
+
` bso_version: "${fm.metadata.bso_version}"`,
|
|
89
|
+
` layer: ${fm.metadata.layer}`,
|
|
90
|
+
` homepage: ${fm.metadata.homepage}`,
|
|
91
|
+
'---',
|
|
92
|
+
];
|
|
93
|
+
return lines.join('\n');
|
|
94
|
+
}
|
|
95
|
+
function quoteIfNeeded(s) {
|
|
96
|
+
// 含特殊字符(含 ":"、换行、单/双引号、#)→ 加双引号 + escape
|
|
97
|
+
if (/[:"\n#]/.test(s) || /^[ \t]/.test(s)) {
|
|
98
|
+
return `"${s.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
|
|
99
|
+
}
|
|
100
|
+
return s;
|
|
101
|
+
}
|
|
102
|
+
// ============================================================================
|
|
103
|
+
// body 模板(zh / en)
|
|
104
|
+
// ============================================================================
|
|
105
|
+
const BODY_ZH = `# SkillFM BSO 协议 priming
|
|
106
|
+
|
|
107
|
+
## 你必须知道
|
|
108
|
+
|
|
109
|
+
本 workspace 启用了 SkillFM BSO(Behavioral Soul Override)协议。
|
|
110
|
+
任何破坏性操作(写文件 / 改代码 / 跑命令 / 调外部 API / 涉及支付)开始前,
|
|
111
|
+
必须先调用 \`mcp__skillfm__brain_run\`,拿到 ScriptCard 后按 \`must_do\` 顺序执行。
|
|
112
|
+
|
|
113
|
+
未先 call brain_run 直接执行破坏性操作 → harness 层 hook 会 \`exit 2\` 阻断;
|
|
114
|
+
若 hook 失效 → MCP 协议层会以 \`URLElicitationRequiredError\` 要求用户在
|
|
115
|
+
SkillFM 控制台审阅;若两者都被绕过 → sidecar 9 红线在协议契约层兜底拒绝。
|
|
116
|
+
|
|
117
|
+
## 三层防御一览(仅供你理解,不必复述)
|
|
118
|
+
|
|
119
|
+
- L1 你的 priming(本文件) · 跟随率 70-95%
|
|
120
|
+
- L2 sidecar 协议 + MCP reject · 协议级强制
|
|
121
|
+
- L3 brain 仲裁 + harness hook · 机械级强制
|
|
122
|
+
|
|
123
|
+
## 何时该 call brain_run
|
|
124
|
+
|
|
125
|
+
- 涉及业务流程编排(多步骤 + 风险评级)
|
|
126
|
+
- 用户首次发出某类请求(无历史 ScriptCard 缓存)
|
|
127
|
+
- 检测到 \`mode=strict\` / Tier ≥ B 的任务
|
|
128
|
+
- 用户要赚钱 / 出交付物 / 走对外发布场景
|
|
129
|
+
|
|
130
|
+
## 边界
|
|
131
|
+
|
|
132
|
+
- 不要编造价格、收入、市场数据 — 引用 pipeline 返回的数字
|
|
133
|
+
- 用户要交付物且你能帮忙 → 走 \`brain_run\`,不要凭记忆手搓
|
|
134
|
+
- 移除:\`skillfm uninstall\` 或直接删本块(含 \`<!-- SKILLFM-BEGIN -->\` 边界)
|
|
135
|
+
`;
|
|
136
|
+
const BODY_EN = `# SkillFM BSO Protocol priming
|
|
137
|
+
|
|
138
|
+
## You must know
|
|
139
|
+
|
|
140
|
+
This workspace has the SkillFM BSO (Behavioral Soul Override) protocol enabled.
|
|
141
|
+
Before ANY destructive operation (file write / code edit / shell command /
|
|
142
|
+
external API call / payment), you MUST first call \`mcp__skillfm__brain_run\`
|
|
143
|
+
and follow the returned ScriptCard's \`must_do\` order.
|
|
144
|
+
|
|
145
|
+
Skipping brain_run and going straight to destructive ops → the harness-layer
|
|
146
|
+
hook will \`exit 2\` to block you; if the hook is disabled → the MCP protocol
|
|
147
|
+
layer will return \`URLElicitationRequiredError\` forcing the user to review in
|
|
148
|
+
SkillFM console; if both are bypassed → the sidecar 9 redlines reject at the
|
|
149
|
+
contract layer.
|
|
150
|
+
|
|
151
|
+
## Three-layer defense (for your understanding; do not narrate)
|
|
152
|
+
|
|
153
|
+
- L1 your priming (this file) · 70-95% follow rate
|
|
154
|
+
- L2 sidecar + MCP reject · protocol-level enforcement
|
|
155
|
+
- L3 brain arbitration + harness hook · mechanical enforcement
|
|
156
|
+
|
|
157
|
+
## When to call brain_run
|
|
158
|
+
|
|
159
|
+
- Multi-step business orchestration with risk tiers
|
|
160
|
+
- First time the user makes this kind of request (no prior ScriptCard cache)
|
|
161
|
+
- Detected \`mode=strict\` or Tier ≥ B tasks
|
|
162
|
+
- User wants to earn money / produce deliverables / publish externally
|
|
163
|
+
|
|
164
|
+
## Boundary
|
|
165
|
+
|
|
166
|
+
- Never fabricate pricing / earnings / market data — quote pipeline output
|
|
167
|
+
- If the user wants a deliverable you could help with → route through \`brain_run\`
|
|
168
|
+
- To remove: \`skillfm uninstall\` or delete this block (incl. SKILLFM-BEGIN markers)
|
|
169
|
+
`;
|
|
170
|
+
// ============================================================================
|
|
171
|
+
// 边界标记(与 priming.ts 一致,复用 uninstall 命令)
|
|
172
|
+
// ============================================================================
|
|
173
|
+
export const SKILL_MD_BEGIN = '<!-- SKILLFM-SKILL-BEGIN: do not edit, managed by @skillfm/local -->';
|
|
174
|
+
export const SKILL_MD_END = '<!-- SKILLFM-SKILL-END -->';
|
|
175
|
+
export function buildSkillMd(opts = {}) {
|
|
176
|
+
const lang = resolveLang(opts.lang);
|
|
177
|
+
const fm = renderFrontmatterYaml(DEFAULT_FRONTMATTER());
|
|
178
|
+
const body = lang === 'zh' ? BODY_ZH : BODY_EN;
|
|
179
|
+
const content = `${fm}\n\n${body}`;
|
|
180
|
+
if (opts.withBoundaryMarkers) {
|
|
181
|
+
return `${SKILL_MD_BEGIN}\n${content}${SKILL_MD_END}\n`;
|
|
182
|
+
}
|
|
183
|
+
return content;
|
|
184
|
+
}
|
|
185
|
+
function resolveLang(lang) {
|
|
186
|
+
if (lang === 'zh')
|
|
187
|
+
return 'zh';
|
|
188
|
+
if (lang === 'en')
|
|
189
|
+
return 'en';
|
|
190
|
+
// auto
|
|
191
|
+
const lc = (process.env.LANG || process.env.LC_ALL || process.env.LC_MESSAGES || '').toLowerCase();
|
|
192
|
+
return lc.includes('zh') ? 'zh' : 'en';
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/skill-md/template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,+EAA+E;AAC/E,6BAA6B;AAC7B,+EAA+E;AAE/E,SAAS,kBAAkB;IACzB,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAC7B,8DAA8D;IAC9D,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,iDAAiD;QACzF,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC;QAChC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC;KAC7C,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACrC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC5B,IAAI,GAAG,EAAE,IAAI,KAAK,gBAAgB,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;gBACtE,OAAO,GAAG,CAAC,OAAO,CAAC;YACrB,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,WAAW;QACb,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,aAAa;IACpB,IAAI,CAAC;QACH,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YAC1D,OAAO,aAAa,CAAC,IAAI,GAAG,CAAC,GAAG,EAAG,MAAM,CAAC,IAAwB,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,eAAe;IACjB,CAAC;IACD,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC;AACvB,CAAC;AAqBD,MAAM,mBAAmB,GAAG,GAAqB,EAAE,CAAC,CAAC;IACnD,IAAI,EAAE,qBAAqB;IAC3B,WAAW,EACT,gHAAgH;IAClH,OAAO,EAAE,YAAY;IACrB,eAAe,EAAE;QACf,yBAAyB;QACzB,2BAA2B;QAC3B,yBAAyB;QACzB,4BAA4B;KAC7B;IACD,QAAQ,EAAE;QACR,eAAe,EAAE,kBAAkB,EAAE;QACrC,WAAW,EAAE,MAAM;QACnB,KAAK,EAAE,CAAC;QACR,QAAQ,EAAE,oBAAoB;KAC/B;CACF,CAAC,CAAC;AAEH,SAAS,qBAAqB,CAAC,EAAoB;IACjD,qDAAqD;IACrD,MAAM,KAAK,GAAa;QACtB,KAAK;QACL,SAAS,EAAE,CAAC,IAAI,EAAE;QAClB,gBAAgB,aAAa,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE;QAC/C,YAAY,EAAE,CAAC,OAAO,EAAE;QACxB,gBAAgB;QAChB,GAAG,EAAE,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,WAAW;QACX,uBAAuB,EAAE,CAAC,QAAQ,CAAC,eAAe,GAAG;QACrD,mBAAmB,EAAE,CAAC,QAAQ,CAAC,WAAW,GAAG;QAC7C,YAAY,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE;QAC/B,eAAe,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE;QACrC,KAAK;KACN,CAAC;IACF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,aAAa,CAAC,CAAS;IAC9B,yCAAyC;IACzC,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC;IAC9D,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,+EAA+E;AAC/E,mBAAmB;AACnB,+EAA+E;AAE/E,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8Bf,CAAC;AAEF,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCf,CAAC;AAEF,+EAA+E;AAC/E,wCAAwC;AACxC,+EAA+E;AAE/E,MAAM,CAAC,MAAM,cAAc,GAAG,sEAAsE,CAAC;AACrG,MAAM,CAAC,MAAM,YAAY,GAAG,4BAA4B,CAAC;AAYzD,MAAM,UAAU,YAAY,CAAC,OAA4B,EAAE;IACzD,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,EAAE,GAAG,qBAAqB,CAAC,mBAAmB,EAAE,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IAC/C,MAAM,OAAO,GAAG,GAAG,EAAE,OAAO,IAAI,EAAE,CAAC;IACnC,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC7B,OAAO,GAAG,cAAc,KAAK,OAAO,GAAG,YAAY,IAAI,CAAC;IAC1D,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,WAAW,CAAC,IAA2B;IAC9C,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC/B,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC/B,OAAO;IACP,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IACnG,OAAO,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BSO M9 v0.3 — Layer 1: SKILL.md 写入器
|
|
3
|
+
*
|
|
4
|
+
* Refs:
|
|
5
|
+
* - docs/prd/PRD-BSO-M9-HARNESS-HOOKS.md §3.2.2
|
|
6
|
+
*
|
|
7
|
+
* 写入策略:
|
|
8
|
+
* - 项目级 ./SKILL.md:必写(所有 host 都拿到 priming)
|
|
9
|
+
* - Anthropic Claude Code 用户级 ~/.claude/skills/skillfm-bso/SKILL.md:可选
|
|
10
|
+
* (由 init flag --copy-to-user 触发,本里程碑只提供 hint)
|
|
11
|
+
*
|
|
12
|
+
* 已存在 ./SKILL.md:
|
|
13
|
+
* - 内含 SKILLFM-SKILL-BEGIN/END → upgrade-safe replace
|
|
14
|
+
* - 不含我们的标记 → backup 后 append(不覆盖用户已有 skill)
|
|
15
|
+
*/
|
|
16
|
+
import { type SkillLang } from './template.js';
|
|
17
|
+
export interface SkillMdWriteResult {
|
|
18
|
+
path: string;
|
|
19
|
+
action: 'created' | 'appended' | 'replaced' | 'already-present';
|
|
20
|
+
bytesWritten: number;
|
|
21
|
+
backupPath?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface WriteSkillMdOptions {
|
|
24
|
+
cwd: string;
|
|
25
|
+
lang?: SkillLang;
|
|
26
|
+
}
|
|
27
|
+
export declare function writeProjectSkillMd(opts: WriteSkillMdOptions): SkillMdWriteResult;
|
|
28
|
+
export declare function userScopeSkillMdPath(): string;
|
|
29
|
+
export declare function writeUserScopeSkillMd(lang?: SkillLang): SkillMdWriteResult;
|
|
30
|
+
//# sourceMappingURL=writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/skill-md/writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAWH,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,eAAe,CAAC;AAMvB,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,iBAAiB,CAAC;IAChE,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAMD,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,mBAAmB,GAAG,kBAAkB,CAqEjF;AAMD,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED,wBAAgB,qBAAqB,CAAC,IAAI,CAAC,EAAE,SAAS,GAAG,kBAAkB,CAqC1E"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BSO M9 v0.3 — Layer 1: SKILL.md 写入器
|
|
3
|
+
*
|
|
4
|
+
* Refs:
|
|
5
|
+
* - docs/prd/PRD-BSO-M9-HARNESS-HOOKS.md §3.2.2
|
|
6
|
+
*
|
|
7
|
+
* 写入策略:
|
|
8
|
+
* - 项目级 ./SKILL.md:必写(所有 host 都拿到 priming)
|
|
9
|
+
* - Anthropic Claude Code 用户级 ~/.claude/skills/skillfm-bso/SKILL.md:可选
|
|
10
|
+
* (由 init flag --copy-to-user 触发,本里程碑只提供 hint)
|
|
11
|
+
*
|
|
12
|
+
* 已存在 ./SKILL.md:
|
|
13
|
+
* - 内含 SKILLFM-SKILL-BEGIN/END → upgrade-safe replace
|
|
14
|
+
* - 不含我们的标记 → backup 后 append(不覆盖用户已有 skill)
|
|
15
|
+
*/
|
|
16
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, } from 'node:fs';
|
|
17
|
+
import { dirname, join } from 'node:path';
|
|
18
|
+
import { homedir } from 'node:os';
|
|
19
|
+
import { backupFileBeforeWrite } from '../soul-security.js';
|
|
20
|
+
import { buildSkillMd, SKILL_MD_BEGIN, SKILL_MD_END, } from './template.js';
|
|
21
|
+
export function writeProjectSkillMd(opts) {
|
|
22
|
+
const filePath = join(opts.cwd, 'SKILL.md');
|
|
23
|
+
const existed = existsSync(filePath);
|
|
24
|
+
const original = existed ? readFileSync(filePath, 'utf-8') : '';
|
|
25
|
+
const wrapped = buildSkillMd({ lang: opts.lang, withBoundaryMarkers: true });
|
|
26
|
+
// upgrade-safe 检查
|
|
27
|
+
const hasOurBlock = original.includes(SKILL_MD_BEGIN);
|
|
28
|
+
if (hasOurBlock && original.includes(wrapped.trimEnd())) {
|
|
29
|
+
return {
|
|
30
|
+
path: filePath,
|
|
31
|
+
action: 'already-present',
|
|
32
|
+
bytesWritten: 0,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
// 文件不存在 → 直接写(无边界,因为整文件就是我们的)
|
|
36
|
+
if (!existed) {
|
|
37
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
38
|
+
const standalone = buildSkillMd({ lang: opts.lang, withBoundaryMarkers: false });
|
|
39
|
+
writeFileSync(filePath, standalone, { encoding: 'utf-8', mode: 0o644 });
|
|
40
|
+
return {
|
|
41
|
+
path: filePath,
|
|
42
|
+
action: 'created',
|
|
43
|
+
bytesWritten: Buffer.byteLength(standalone, 'utf-8'),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
// backup
|
|
47
|
+
let backupPath;
|
|
48
|
+
try {
|
|
49
|
+
const r = backupFileBeforeWrite(filePath, original);
|
|
50
|
+
backupPath = r.backup_path;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// not critical
|
|
54
|
+
}
|
|
55
|
+
let next;
|
|
56
|
+
let action;
|
|
57
|
+
if (hasOurBlock) {
|
|
58
|
+
// replace 旧 block
|
|
59
|
+
const startIdx = original.indexOf(SKILL_MD_BEGIN);
|
|
60
|
+
const endIdx = original.indexOf(SKILL_MD_END);
|
|
61
|
+
if (startIdx === -1 || endIdx === -1 || endIdx < startIdx) {
|
|
62
|
+
// 标记残缺 — 保守 append
|
|
63
|
+
next = `${original}${original.endsWith('\n') ? '' : '\n'}\n${wrapped}`;
|
|
64
|
+
action = 'appended';
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
const before = original.slice(0, startIdx).replace(/\n+$/, '\n');
|
|
68
|
+
const after = original.slice(endIdx + SKILL_MD_END.length).replace(/^\n+/, '');
|
|
69
|
+
next = `${before}\n${wrapped}${after}`.replace(/\n{3,}/g, '\n\n');
|
|
70
|
+
action = 'replaced';
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
// 用户已有 SKILL.md(自定义 skill)→ append 我们的 block 在尾部
|
|
75
|
+
next = `${original}${original.endsWith('\n') ? '' : '\n'}\n${wrapped}`;
|
|
76
|
+
action = 'appended';
|
|
77
|
+
}
|
|
78
|
+
writeFileSync(filePath, next, { encoding: 'utf-8', mode: 0o644 });
|
|
79
|
+
return {
|
|
80
|
+
path: filePath,
|
|
81
|
+
action,
|
|
82
|
+
bytesWritten: Buffer.byteLength(next, 'utf-8'),
|
|
83
|
+
backupPath,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
// ============================================================================
|
|
87
|
+
// 用户级 hint(不实际写,只返回路径让 init 决定是否问用户)
|
|
88
|
+
// ============================================================================
|
|
89
|
+
export function userScopeSkillMdPath() {
|
|
90
|
+
return join(homedir(), '.claude', 'skills', 'skillfm-bso', 'SKILL.md');
|
|
91
|
+
}
|
|
92
|
+
export function writeUserScopeSkillMd(lang) {
|
|
93
|
+
const filePath = userScopeSkillMdPath();
|
|
94
|
+
const standalone = buildSkillMd({ lang, withBoundaryMarkers: false });
|
|
95
|
+
const existed = existsSync(filePath);
|
|
96
|
+
if (existed) {
|
|
97
|
+
const original = readFileSync(filePath, 'utf-8');
|
|
98
|
+
if (original.trim() === standalone.trim()) {
|
|
99
|
+
return {
|
|
100
|
+
path: filePath,
|
|
101
|
+
action: 'already-present',
|
|
102
|
+
bytesWritten: 0,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
let backupPath;
|
|
106
|
+
try {
|
|
107
|
+
const r = backupFileBeforeWrite(filePath, original);
|
|
108
|
+
backupPath = r.backup_path;
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// ignore
|
|
112
|
+
}
|
|
113
|
+
writeFileSync(filePath, standalone, { encoding: 'utf-8', mode: 0o644 });
|
|
114
|
+
return {
|
|
115
|
+
path: filePath,
|
|
116
|
+
action: 'replaced',
|
|
117
|
+
bytesWritten: Buffer.byteLength(standalone, 'utf-8'),
|
|
118
|
+
backupPath,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
122
|
+
writeFileSync(filePath, standalone, { encoding: 'utf-8', mode: 0o644 });
|
|
123
|
+
return {
|
|
124
|
+
path: filePath,
|
|
125
|
+
action: 'created',
|
|
126
|
+
bytesWritten: Buffer.byteLength(standalone, 'utf-8'),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer.js","sourceRoot":"","sources":["../../src/skill-md/writer.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skillfm/local",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.6",
|
|
4
4
|
"description": "SkillFM local sidecar — a tiny localhost HTTP proxy that lets any AI agent activate and run SkillFM skills in the current conversation without restarting its MCP runtime. Writes ~/.skillfm/local.json for service discovery.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
"dev": "tsx src/index.ts",
|
|
28
28
|
"typecheck": "tsc --noEmit",
|
|
29
29
|
"start": "node dist/index.js start",
|
|
30
|
-
"test": "tsx --test src/harness/detector.test.ts src/harness/priming.test.ts src/harness/writers.test.ts src/guard/state.test.ts src/soul.test.ts",
|
|
30
|
+
"test": "tsx --test src/harness/detector.test.ts src/harness/priming.test.ts src/harness/writers.test.ts src/guard/state.test.ts src/soul.test.ts src/harness/kernels/registry.test.ts src/mcp-output/builder.test.ts src/mcp-output/deny-review.test.ts src/mcp-output/integration.test.ts src/skill-md/template.test.ts src/skill-md/writer.test.ts",
|
|
31
|
+
"test:acceptance": "npm run build && bash scripts/acceptance-matrix.sh",
|
|
31
32
|
"postpublish": "curl -sS -m 10 -X PUT 'https://registry.npmmirror.com/-/package/@skillfm/local/syncs?sync_upstream=true' > /dev/null && echo '✓ npmmirror sync triggered' || echo '⚠ npmmirror sync failed (非阻塞,可手动触发)'"
|
|
32
33
|
},
|
|
33
34
|
"dependencies": {},
|
package/dist/lang.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 用户语言检测 — sidecar 在输出 hint_for_agent 前决定语言
|
|
3
|
-
*
|
|
4
|
-
* 目标: agent 读到 sidecar 返回的指令时, 按用户本机环境的语言回应.
|
|
5
|
-
* 当前仅识别 zh / en 两档, 后续可扩展 ja / ko / es 等.
|
|
6
|
-
*
|
|
7
|
-
* 检测顺序 (首个命中即返回):
|
|
8
|
-
* 1. 环境变量 SKILLFM_LANG=zh|en — 用户/企业显式覆盖
|
|
9
|
-
* 2. env.LANGUAGE — Linux/ glibc 优先 (逗号分隔, 取第一个)
|
|
10
|
-
* 3. env.LC_ALL / LC_MESSAGES / LANG — POSIX locale
|
|
11
|
-
* 4. Intl.DateTimeFormat().resolvedOptions().locale — macOS/Windows 可靠回落
|
|
12
|
-
* 5. 默认 'en'
|
|
13
|
-
*
|
|
14
|
-
* 任何字符串若开头(或整串 lowercase)含 "zh" → 返回 'zh'; 否则 'en'.
|
|
15
|
-
*/
|
|
16
|
-
export type Lang = 'zh' | 'en';
|
|
17
|
-
/**
|
|
18
|
-
* 检测当前用户语言. 纯函数, 给 env 和 intlLocale 方便测试.
|
|
19
|
-
*/
|
|
20
|
-
export declare function detectLang(env?: NodeJS.ProcessEnv, intlLocale?: () => string): Lang;
|
|
21
|
-
//# sourceMappingURL=lang.d.ts.map
|
package/dist/lang.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lang.d.ts","sourceRoot":"","sources":["../src/lang.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,MAAM,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAS/B;;GAEG;AACH,wBAAgB,UAAU,CACxB,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,UAAU,GAAE,MAAM,MAMjB,GACA,IAAI,CA2BN"}
|
package/dist/lang.js
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 用户语言检测 — sidecar 在输出 hint_for_agent 前决定语言
|
|
3
|
-
*
|
|
4
|
-
* 目标: agent 读到 sidecar 返回的指令时, 按用户本机环境的语言回应.
|
|
5
|
-
* 当前仅识别 zh / en 两档, 后续可扩展 ja / ko / es 等.
|
|
6
|
-
*
|
|
7
|
-
* 检测顺序 (首个命中即返回):
|
|
8
|
-
* 1. 环境变量 SKILLFM_LANG=zh|en — 用户/企业显式覆盖
|
|
9
|
-
* 2. env.LANGUAGE — Linux/ glibc 优先 (逗号分隔, 取第一个)
|
|
10
|
-
* 3. env.LC_ALL / LC_MESSAGES / LANG — POSIX locale
|
|
11
|
-
* 4. Intl.DateTimeFormat().resolvedOptions().locale — macOS/Windows 可靠回落
|
|
12
|
-
* 5. 默认 'en'
|
|
13
|
-
*
|
|
14
|
-
* 任何字符串若开头(或整串 lowercase)含 "zh" → 返回 'zh'; 否则 'en'.
|
|
15
|
-
*/
|
|
16
|
-
const ZH_PATTERN = /(^|[_-])zh([_-]|$)|^zh/;
|
|
17
|
-
function matchZh(raw) {
|
|
18
|
-
if (!raw)
|
|
19
|
-
return false;
|
|
20
|
-
return ZH_PATTERN.test(raw.toLowerCase());
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* 检测当前用户语言. 纯函数, 给 env 和 intlLocale 方便测试.
|
|
24
|
-
*/
|
|
25
|
-
export function detectLang(env = process.env, intlLocale = () => {
|
|
26
|
-
try {
|
|
27
|
-
return Intl.DateTimeFormat().resolvedOptions().locale;
|
|
28
|
-
}
|
|
29
|
-
catch {
|
|
30
|
-
return '';
|
|
31
|
-
}
|
|
32
|
-
}) {
|
|
33
|
-
// 1. 显式覆盖
|
|
34
|
-
const explicit = (env.SKILLFM_LANG || '').trim().toLowerCase();
|
|
35
|
-
if (explicit === 'zh' || explicit === 'en')
|
|
36
|
-
return explicit;
|
|
37
|
-
if (explicit && matchZh(explicit))
|
|
38
|
-
return 'zh';
|
|
39
|
-
// 2. LANGUAGE (glibc list, first wins)
|
|
40
|
-
const languageFirst = (env.LANGUAGE || '').split(':')[0];
|
|
41
|
-
if (languageFirst) {
|
|
42
|
-
if (matchZh(languageFirst))
|
|
43
|
-
return 'zh';
|
|
44
|
-
// 非 zh 的显式值不要立刻返回 en, 让后面 locale 有机会补判
|
|
45
|
-
}
|
|
46
|
-
// 3. POSIX locale 链
|
|
47
|
-
const posix = env.LC_ALL || env.LC_MESSAGES || env.LANG || '';
|
|
48
|
-
if (posix && matchZh(posix))
|
|
49
|
-
return 'zh';
|
|
50
|
-
// 4. Intl (macOS / Windows 兜底)
|
|
51
|
-
try {
|
|
52
|
-
const intl = intlLocale();
|
|
53
|
-
if (matchZh(intl))
|
|
54
|
-
return 'zh';
|
|
55
|
-
}
|
|
56
|
-
catch {
|
|
57
|
-
/* ignore */
|
|
58
|
-
}
|
|
59
|
-
// 5. 默认英文
|
|
60
|
-
return 'en';
|
|
61
|
-
}
|
|
62
|
-
//# sourceMappingURL=lang.js.map
|
package/dist/lang.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lang.js","sourceRoot":"","sources":["../src/lang.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,MAAM,UAAU,GAAG,wBAAwB,CAAC;AAE5C,SAAS,OAAO,CAAC,GAA8B;IAC7C,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC;IACvB,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CACxB,MAAyB,OAAO,CAAC,GAAG,EACpC,aAA2B,GAAG,EAAE;IAC9B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC,eAAe,EAAE,CAAC,MAAM,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;IAED,UAAU;IACV,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC/D,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,QAAgB,CAAC;IACpE,IAAI,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAE/C,uCAAuC;IACvC,MAAM,aAAa,GAAG,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,IAAI,aAAa,EAAE,CAAC;QAClB,IAAI,OAAO,CAAC,aAAa,CAAC;YAAE,OAAO,IAAI,CAAC;QACxC,uCAAuC;IACzC,CAAC;IAED,oBAAoB;IACpB,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;IAC9D,IAAI,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEzC,+BAA+B;IAC/B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;QAC1B,IAAI,OAAO,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,YAAY;IACd,CAAC;IAED,UAAU;IACV,OAAO,IAAI,CAAC;AACd,CAAC"}
|