@skillfm/local 2.7.4 → 2.7.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-forcing/forcing-rules.d.ts +27 -0
- package/dist/agent-forcing/forcing-rules.d.ts.map +1 -0
- package/dist/agent-forcing/forcing-rules.js +98 -0
- package/dist/agent-forcing/forcing-rules.js.map +1 -0
- package/dist/agent-forcing/index.d.ts +5 -0
- package/dist/agent-forcing/index.d.ts.map +1 -0
- package/dist/agent-forcing/index.js +6 -0
- package/dist/agent-forcing/index.js.map +1 -0
- package/dist/agent-forcing/injectors.d.ts +29 -0
- package/dist/agent-forcing/injectors.d.ts.map +1 -0
- package/dist/agent-forcing/injectors.js +255 -0
- package/dist/agent-forcing/injectors.js.map +1 -0
- package/dist/agent-forcing/types.d.ts +26 -0
- package/dist/agent-forcing/types.d.ts.map +1 -0
- package/dist/agent-forcing/types.js +21 -0
- package/dist/agent-forcing/types.js.map +1 -0
- package/dist/checkup/dimension-3-files.d.ts +15 -2
- package/dist/checkup/dimension-3-files.d.ts.map +1 -1
- package/dist/checkup/dimension-3-files.js +134 -23
- package/dist/checkup/dimension-3-files.js.map +1 -1
- package/dist/checkup/report.d.ts +7 -2
- package/dist/checkup/report.d.ts.map +1 -1
- package/dist/checkup/report.js +69 -29
- package/dist/checkup/report.js.map +1 -1
- package/dist/checkup-cli.d.ts +2 -0
- package/dist/checkup-cli.d.ts.map +1 -0
- package/dist/checkup-cli.js +46 -0
- package/dist/checkup-cli.js.map +1 -0
- package/dist/forcing-cli.d.ts +2 -0
- package/dist/forcing-cli.d.ts.map +1 -0
- package/dist/forcing-cli.js +53 -0
- package/dist/forcing-cli.js.map +1 -0
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/tools/index.d.ts.map +1 -1
- package/dist/mcp/tools/index.js +24 -3
- package/dist/mcp/tools/index.js.map +1 -1
- package/dist/mcp/tools/setup-agent-forcing.d.ts +19 -0
- package/dist/mcp/tools/setup-agent-forcing.d.ts.map +1 -0
- package/dist/mcp/tools/setup-agent-forcing.js +86 -0
- package/dist/mcp/tools/setup-agent-forcing.js.map +1 -0
- package/dist/usage-local/index.d.ts +3 -1
- package/dist/usage-local/index.d.ts.map +1 -1
- package/dist/usage-local/index.js +1 -0
- package/dist/usage-local/index.js.map +1 -1
- package/dist/usage-local/model-pricing.d.ts +11 -7
- package/dist/usage-local/model-pricing.d.ts.map +1 -1
- package/dist/usage-local/model-pricing.js +109 -86
- package/dist/usage-local/model-pricing.js.map +1 -1
- package/dist/usage-local/plan.d.ts +58 -0
- package/dist/usage-local/plan.d.ts.map +1 -0
- package/dist/usage-local/plan.js +84 -0
- package/dist/usage-local/plan.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface ForcingGuideOptions {
|
|
2
|
+
/** Sidecar URL (e.g. http://127.0.0.1:19821) */
|
|
3
|
+
sidecar_url?: string;
|
|
4
|
+
/** 包版本 (写入 guide 让用户知道哪个版本注入的) */
|
|
5
|
+
version?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* 主 forcing guide markdown — 用于 OpenClaw / Claude Code / Cursor / Codex 注入.
|
|
9
|
+
* 双语 (中英) — 跟用户语言无关都覆盖.
|
|
10
|
+
*/
|
|
11
|
+
export declare function renderForcingGuide(opts?: ForcingGuideOptions): string;
|
|
12
|
+
/**
|
|
13
|
+
* 给已存在 markdown 文件 (如 Claude CLAUDE.md) 用的 — 自动 detect 并替换/append marker block.
|
|
14
|
+
*
|
|
15
|
+
* 输入: 现有 markdown 文件内容
|
|
16
|
+
* 输出: 含 SkillFM marker block 的新内容 (替换旧块 / 或 append 新块)
|
|
17
|
+
*/
|
|
18
|
+
export declare function injectOrReplaceBlock(existingContent: string, opts?: ForcingGuideOptions): string;
|
|
19
|
+
/**
|
|
20
|
+
* 移除已注入的 SkillFM block (uninstall 用)
|
|
21
|
+
*/
|
|
22
|
+
export declare function removeBlock(existingContent: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* 检测一个文件是否已含 SkillFM block
|
|
25
|
+
*/
|
|
26
|
+
export declare function hasMarkerBlock(content: string): boolean;
|
|
27
|
+
//# sourceMappingURL=forcing-rules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forcing-rules.d.ts","sourceRoot":"","sources":["../../src/agent-forcing/forcing-rules.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,mBAAmB;IAClC,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,mBAAwB,GAAG,MAAM,CAiDzE;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,eAAe,EAAE,MAAM,EAAE,IAAI,GAAE,mBAAwB,GAAG,MAAM,CAkBpG;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAQ3D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEvD"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// sdk/skillfm-local/src/agent-forcing/forcing-rules.ts
|
|
2
|
+
//
|
|
3
|
+
// SkillFM Agent Forcing Guide — 真注入 system prompt 的强 forcing rule.
|
|
4
|
+
// 文案直接 inject 进 workspace files (如 OpenClaw AGENTS.md / Claude CLAUDE.md).
|
|
5
|
+
import { SKILLFM_MARKER_START, SKILLFM_MARKER_END } from './types.js';
|
|
6
|
+
const PACKAGE_VERSION = '__INJECT_VERSION__'; // 由 build 时 / runtime 替换
|
|
7
|
+
/**
|
|
8
|
+
* 主 forcing guide markdown — 用于 OpenClaw / Claude Code / Cursor / Codex 注入.
|
|
9
|
+
* 双语 (中英) — 跟用户语言无关都覆盖.
|
|
10
|
+
*/
|
|
11
|
+
export function renderForcingGuide(opts = {}) {
|
|
12
|
+
const sidecar = opts.sidecar_url ?? 'http://127.0.0.1:19821';
|
|
13
|
+
const ver = opts.version ?? PACKAGE_VERSION;
|
|
14
|
+
return `${SKILLFM_MARKER_START}
|
|
15
|
+
|
|
16
|
+
# SkillFM — Agent Forcing Rules (auto-injected by skillfm-local v${ver})
|
|
17
|
+
|
|
18
|
+
> 这是 SkillFM 写入的 agent 行为强约束. 当前 sidecar: ${sidecar}
|
|
19
|
+
> 不要手动删 — 卸载 SkillFM 时跑 \`npx @skillfm/local uninstall\` 自动清.
|
|
20
|
+
|
|
21
|
+
## 中文规则 — 强制必读
|
|
22
|
+
|
|
23
|
+
当用户提到以下任何关键词,**必须先调对应的 SkillFM MCP tool**,**禁止用 exec/curl/bash 命令绕过**:
|
|
24
|
+
|
|
25
|
+
| 用户说什么 | 必调 MCP tool | 禁忌行为 |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| SkillFM / 体检 / 我家 AI 状态 / 健康度 | \`skillfm_checkup\` | ❌ 不要 \`curl /status\` 自己拼; ❌ 不要凭空说"健康度 67" |
|
|
28
|
+
| 我用了多少 token / 花了多少钱 / 哪能省 | \`skillfm_show_my_usage({window: 'today'\\|'week'\\|'month'})\` | ❌ 不要凭空算用量 |
|
|
29
|
+
| 给 OpenAI / Anthropic / DeepSeek API key | \`skillfm_explain_provider_key({provider})\` 然后 \`skillfm_save_credential\` | ❌ 不要直接问用户要 key 不解释; ❌ 不要凭空说"你需要 billing-only key" |
|
|
30
|
+
| 装 / 接入 / 配置 SkillFM | \`skillfm_setup_gateway({dry_run: true})\` 先看检测; 用户 OK 后 \`{dry_run: false}\` | ❌ 不要直接改用户 IDE config 不问; ❌ 不要凭空写"激活码 XXXXXXXX" |
|
|
31
|
+
| 看完整体检 / 5 维度详情 | \`skillfm_checkup({full: true})\` | 同上 |
|
|
32
|
+
|
|
33
|
+
**Tool 输出处理规则**:
|
|
34
|
+
- 所有 SkillFM MCP tool 返回的 \`rendered\` 字段是**预渲染好的用户面 UX**,**直接显示给用户**, 不要修改 / 概括 / 加自己的话.
|
|
35
|
+
- 如果 tool 返 \`{ok:false, error}\`, 把 \`error.message\` 真显示给用户, 不要装作成功.
|
|
36
|
+
|
|
37
|
+
**激活流程禁忌**:
|
|
38
|
+
- 用户说"接入 SkillFM" → 真执行 \`POST ${sidecar}/activate/start\` 拿真 device code, **绝不凭空写 placeholder URL** 如 \`code=XXXXXXXX\`.
|
|
39
|
+
- 真 URL 包含 device code 由 sidecar 返, 不是你猜的.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## English Rules — Mandatory
|
|
44
|
+
|
|
45
|
+
When user mentions any of these keywords, **MUST call the corresponding SkillFM MCP tool**, **NEVER bypass with exec/curl/bash**:
|
|
46
|
+
|
|
47
|
+
| User says | Call this MCP tool | Forbidden |
|
|
48
|
+
|---|---|---|
|
|
49
|
+
| SkillFM / checkup / my AI status / health score | \`skillfm_checkup\` | ❌ Don't curl /status; ❌ Don't fabricate score |
|
|
50
|
+
| how much token / cost / where to save | \`skillfm_show_my_usage({window})\` | ❌ Don't fabricate usage |
|
|
51
|
+
| give OpenAI / Anthropic key | \`skillfm_explain_provider_key({provider})\` then \`skillfm_save_credential\` | ❌ Don't ask for "billing-only key" without explaining via tool |
|
|
52
|
+
| install / setup SkillFM | \`skillfm_setup_gateway({dry_run: true})\` first, then \`{dry_run: false}\` | ❌ Don't modify IDE config without asking |
|
|
53
|
+
|
|
54
|
+
**Tool output handling**: SkillFM MCP tools return a pre-rendered \`rendered\` field — show it directly to user, don't paraphrase.
|
|
55
|
+
|
|
56
|
+
**Activation flow**: User says "install SkillFM" → call sidecar \`POST ${sidecar}/activate/start\` to get real device code. **NEVER fabricate placeholder URLs like \`code=XXXXXXXX\`.**
|
|
57
|
+
|
|
58
|
+
${SKILLFM_MARKER_END}`;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* 给已存在 markdown 文件 (如 Claude CLAUDE.md) 用的 — 自动 detect 并替换/append marker block.
|
|
62
|
+
*
|
|
63
|
+
* 输入: 现有 markdown 文件内容
|
|
64
|
+
* 输出: 含 SkillFM marker block 的新内容 (替换旧块 / 或 append 新块)
|
|
65
|
+
*/
|
|
66
|
+
export function injectOrReplaceBlock(existingContent, opts = {}) {
|
|
67
|
+
const newBlock = renderForcingGuide(opts);
|
|
68
|
+
const startIdx = existingContent.indexOf(SKILLFM_MARKER_START);
|
|
69
|
+
const endIdx = existingContent.indexOf(SKILLFM_MARKER_END);
|
|
70
|
+
if (startIdx >= 0 && endIdx > startIdx) {
|
|
71
|
+
// 替换已有 block (升级版本 / 文案 update)
|
|
72
|
+
return (existingContent.slice(0, startIdx).trimEnd() +
|
|
73
|
+
'\n\n' +
|
|
74
|
+
newBlock +
|
|
75
|
+
'\n' +
|
|
76
|
+
existingContent.slice(endIdx + SKILLFM_MARKER_END.length).trimStart());
|
|
77
|
+
}
|
|
78
|
+
// Append (没 block, 加在末尾)
|
|
79
|
+
return existingContent.trimEnd() + '\n\n' + newBlock + '\n';
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* 移除已注入的 SkillFM block (uninstall 用)
|
|
83
|
+
*/
|
|
84
|
+
export function removeBlock(existingContent) {
|
|
85
|
+
const startIdx = existingContent.indexOf(SKILLFM_MARKER_START);
|
|
86
|
+
const endIdx = existingContent.indexOf(SKILLFM_MARKER_END);
|
|
87
|
+
if (startIdx < 0 || endIdx <= startIdx)
|
|
88
|
+
return existingContent;
|
|
89
|
+
return (existingContent.slice(0, startIdx).trimEnd() +
|
|
90
|
+
existingContent.slice(endIdx + SKILLFM_MARKER_END.length).trimStart());
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* 检测一个文件是否已含 SkillFM block
|
|
94
|
+
*/
|
|
95
|
+
export function hasMarkerBlock(content) {
|
|
96
|
+
return content.includes(SKILLFM_MARKER_START) && content.includes(SKILLFM_MARKER_END);
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=forcing-rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forcing-rules.js","sourceRoot":"","sources":["../../src/agent-forcing/forcing-rules.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,EAAE;AACF,mEAAmE;AACnE,2EAA2E;AAE3E,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEtE,MAAM,eAAe,GAAG,oBAAoB,CAAC,CAAC,yBAAyB;AASvE;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAA4B,EAAE;IAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,IAAI,wBAAwB,CAAC;IAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,IAAI,eAAe,CAAC;IAE5C,OAAO,GAAG,oBAAoB;;mEAEmC,GAAG;;4CAE1B,OAAO;;;;;;;;;;;;;;;;;;;;iCAoBlB,OAAO;;;;;;;;;;;;;;;;;;yEAkBiC,OAAO;;EAE9E,kBAAkB,EAAE,CAAC;AACvB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,eAAuB,EAAE,OAA4B,EAAE;IAC1F,MAAM,QAAQ,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAE3D,IAAI,QAAQ,IAAI,CAAC,IAAI,MAAM,GAAG,QAAQ,EAAE,CAAC;QACvC,gCAAgC;QAChC,OAAO,CACL,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,OAAO,EAAE;YAC5C,MAAM;YACN,QAAQ;YACR,IAAI;YACJ,eAAe,CAAC,KAAK,CAAC,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,CACtE,CAAC;IACJ,CAAC;IAED,yBAAyB;IACzB,OAAO,eAAe,CAAC,OAAO,EAAE,GAAG,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC;AAC9D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,eAAuB;IACjD,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC3D,IAAI,QAAQ,GAAG,CAAC,IAAI,MAAM,IAAI,QAAQ;QAAE,OAAO,eAAe,CAAC;IAC/D,OAAO,CACL,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,OAAO,EAAE;QAC5C,eAAe,CAAC,KAAK,CAAC,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,CACtE,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,OAAO,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;AACxF,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { HarnessId, HarnessDetection, ForcingInjectResult, } from './types.js';
|
|
2
|
+
export { SKILLFM_MARKER_START, SKILLFM_MARKER_END } from './types.js';
|
|
3
|
+
export { renderForcingGuide, injectOrReplaceBlock, removeBlock, hasMarkerBlock, } from './forcing-rules.js';
|
|
4
|
+
export { detectOpenClaw, injectOpenClaw, detectClaudeCode, injectClaudeCode, detectCursor, injectCursor, detectCodex, injectCodex, detectContinue, detectAllHarnesses, injectAllDetected, removeAllInjections, } from './injectors.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agent-forcing/index.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,SAAS,EACT,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,WAAW,EACX,cAAc,GACf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// sdk/skillfm-local/src/agent-forcing/index.ts
|
|
2
|
+
// Agent Forcing Adapter — public API.
|
|
3
|
+
export { SKILLFM_MARKER_START, SKILLFM_MARKER_END } from './types.js';
|
|
4
|
+
export { renderForcingGuide, injectOrReplaceBlock, removeBlock, hasMarkerBlock, } from './forcing-rules.js';
|
|
5
|
+
export { detectOpenClaw, injectOpenClaw, detectClaudeCode, injectClaudeCode, detectCursor, injectCursor, detectCodex, injectCodex, detectContinue, detectAllHarnesses, injectAllDetected, removeAllInjections, } from './injectors.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/agent-forcing/index.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,sCAAsC;AAOtC,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,WAAW,EACX,cAAc,GACf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { HarnessDetection, ForcingInjectResult } from './types.js';
|
|
2
|
+
export declare function detectOpenClaw(): Promise<HarnessDetection>;
|
|
3
|
+
export declare function injectOpenClaw(opts?: {
|
|
4
|
+
sidecar_url?: string;
|
|
5
|
+
version?: string;
|
|
6
|
+
}): Promise<ForcingInjectResult>;
|
|
7
|
+
export declare function detectClaudeCode(): Promise<HarnessDetection>;
|
|
8
|
+
export declare function injectClaudeCode(opts?: {
|
|
9
|
+
sidecar_url?: string;
|
|
10
|
+
version?: string;
|
|
11
|
+
}): Promise<ForcingInjectResult>;
|
|
12
|
+
export declare function detectCursor(): Promise<HarnessDetection>;
|
|
13
|
+
export declare function injectCursor(opts?: {
|
|
14
|
+
sidecar_url?: string;
|
|
15
|
+
version?: string;
|
|
16
|
+
}): Promise<ForcingInjectResult>;
|
|
17
|
+
export declare function detectCodex(): Promise<HarnessDetection>;
|
|
18
|
+
export declare function injectCodex(opts?: {
|
|
19
|
+
sidecar_url?: string;
|
|
20
|
+
version?: string;
|
|
21
|
+
}): Promise<ForcingInjectResult>;
|
|
22
|
+
export declare function detectContinue(): Promise<HarnessDetection>;
|
|
23
|
+
export declare function detectAllHarnesses(): Promise<HarnessDetection[]>;
|
|
24
|
+
export declare function injectAllDetected(opts?: {
|
|
25
|
+
sidecar_url?: string;
|
|
26
|
+
version?: string;
|
|
27
|
+
}): Promise<ForcingInjectResult[]>;
|
|
28
|
+
export declare function removeAllInjections(): Promise<ForcingInjectResult[]>;
|
|
29
|
+
//# sourceMappingURL=injectors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"injectors.d.ts","sourceRoot":"","sources":["../../src/agent-forcing/injectors.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAa,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAwBnF,wBAAsB,cAAc,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAYhE;AAED,wBAAsB,cAAc,CAAC,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAoBxH;AAMD,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAYlE;AAED,wBAAsB,gBAAgB,CAAC,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAwB1H;AAMD,wBAAsB,YAAY,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAgB9D;AAED,wBAAsB,YAAY,CAAC,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAwBtH;AAKD,wBAAsB,WAAW,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAY7D;AAED,wBAAsB,WAAW,CAAC,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAwBrH;AAGD,wBAAsB,cAAc,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAGhE;AAGD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAQtE;AAGD,wBAAsB,iBAAiB,CAAC,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAY7H;AAGD,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC,CA2B1E"}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
// sdk/skillfm-local/src/agent-forcing/injectors.ts
|
|
2
|
+
//
|
|
3
|
+
// Per-harness 注入实现 — detect + inject + revert.
|
|
4
|
+
import * as fs from 'node:fs';
|
|
5
|
+
import * as path from 'node:path';
|
|
6
|
+
import { homedir } from 'node:os';
|
|
7
|
+
import { renderForcingGuide, injectOrReplaceBlock, removeBlock, hasMarkerBlock, } from './forcing-rules.js';
|
|
8
|
+
const BACKUP_BASE = path.join(homedir(), '.skillfm', 'agent-forcing-backup');
|
|
9
|
+
async function backupFile(filePath) {
|
|
10
|
+
const ts = new Date().toISOString().replace(/[:.]/g, '-');
|
|
11
|
+
const dir = path.join(BACKUP_BASE, ts);
|
|
12
|
+
await fs.promises.mkdir(dir, { recursive: true, mode: 0o700 });
|
|
13
|
+
const name = path.basename(filePath);
|
|
14
|
+
const backupPath = path.join(dir, name);
|
|
15
|
+
await fs.promises.copyFile(filePath, backupPath);
|
|
16
|
+
return backupPath;
|
|
17
|
+
}
|
|
18
|
+
// ── OpenClaw ────────────────────────────────────────────────────────
|
|
19
|
+
// 路径: ~/.openclaw/workspace/SKILLFM-AGENT-GUIDE.md (新建独立文件)
|
|
20
|
+
// OpenClaw 自动 inject workspace 所有 .md 到 system_prompt (我们 trace 验过 48KB)
|
|
21
|
+
export async function detectOpenClaw() {
|
|
22
|
+
const workspaceDir = path.join(homedir(), '.openclaw', 'workspace');
|
|
23
|
+
const injectPath = path.join(workspaceDir, 'SKILLFM-AGENT-GUIDE.md');
|
|
24
|
+
const detected = fs.existsSync(workspaceDir);
|
|
25
|
+
let already = false;
|
|
26
|
+
if (detected && fs.existsSync(injectPath)) {
|
|
27
|
+
try {
|
|
28
|
+
const c = await fs.promises.readFile(injectPath, 'utf-8');
|
|
29
|
+
already = hasMarkerBlock(c);
|
|
30
|
+
}
|
|
31
|
+
catch { }
|
|
32
|
+
}
|
|
33
|
+
return { harness: 'openclaw', detected, inject_path: detected ? injectPath : undefined, already_injected: already };
|
|
34
|
+
}
|
|
35
|
+
export async function injectOpenClaw(opts = {}) {
|
|
36
|
+
const det = await detectOpenClaw();
|
|
37
|
+
if (!det.detected) {
|
|
38
|
+
return { harness: 'openclaw', applied: false, error: 'OpenClaw workspace not found (~/.openclaw/workspace)' };
|
|
39
|
+
}
|
|
40
|
+
const filePath = det.inject_path;
|
|
41
|
+
let backup_path;
|
|
42
|
+
if (fs.existsSync(filePath)) {
|
|
43
|
+
backup_path = await backupFile(filePath);
|
|
44
|
+
}
|
|
45
|
+
const content = renderForcingGuide(opts);
|
|
46
|
+
await fs.promises.writeFile(filePath, content, 'utf-8');
|
|
47
|
+
return {
|
|
48
|
+
harness: 'openclaw',
|
|
49
|
+
applied: true,
|
|
50
|
+
inject_path: filePath,
|
|
51
|
+
backup_path,
|
|
52
|
+
revert_command: backup_path ? `cp "${backup_path}" "${filePath}"` : `rm "${filePath}"`,
|
|
53
|
+
bytes_injected: Buffer.byteLength(content, 'utf-8'),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
// ── Claude Code ─────────────────────────────────────────────────────
|
|
57
|
+
// 路径: ~/.claude/CLAUDE.md (user-level memory, Claude Code 必读)
|
|
58
|
+
// 注入: marker block append/replace 进现有 CLAUDE.md
|
|
59
|
+
export async function detectClaudeCode() {
|
|
60
|
+
const claudeDir = path.join(homedir(), '.claude');
|
|
61
|
+
const injectPath = path.join(claudeDir, 'CLAUDE.md');
|
|
62
|
+
const detected = fs.existsSync(claudeDir);
|
|
63
|
+
let already = false;
|
|
64
|
+
if (detected && fs.existsSync(injectPath)) {
|
|
65
|
+
try {
|
|
66
|
+
const c = await fs.promises.readFile(injectPath, 'utf-8');
|
|
67
|
+
already = hasMarkerBlock(c);
|
|
68
|
+
}
|
|
69
|
+
catch { }
|
|
70
|
+
}
|
|
71
|
+
return { harness: 'claude-code', detected, inject_path: detected ? injectPath : undefined, already_injected: already };
|
|
72
|
+
}
|
|
73
|
+
export async function injectClaudeCode(opts = {}) {
|
|
74
|
+
const det = await detectClaudeCode();
|
|
75
|
+
if (!det.detected) {
|
|
76
|
+
return { harness: 'claude-code', applied: false, error: 'Claude Code not detected (~/.claude not found)' };
|
|
77
|
+
}
|
|
78
|
+
const filePath = det.inject_path;
|
|
79
|
+
let existingContent = '';
|
|
80
|
+
let backup_path;
|
|
81
|
+
if (fs.existsSync(filePath)) {
|
|
82
|
+
backup_path = await backupFile(filePath);
|
|
83
|
+
existingContent = await fs.promises.readFile(filePath, 'utf-8');
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
existingContent = '# Claude Code Memory\n\n';
|
|
87
|
+
}
|
|
88
|
+
const newContent = injectOrReplaceBlock(existingContent, opts);
|
|
89
|
+
await fs.promises.writeFile(filePath, newContent, 'utf-8');
|
|
90
|
+
return {
|
|
91
|
+
harness: 'claude-code',
|
|
92
|
+
applied: true,
|
|
93
|
+
inject_path: filePath,
|
|
94
|
+
backup_path,
|
|
95
|
+
revert_command: backup_path ? `cp "${backup_path}" "${filePath}"` : `rm "${filePath}"`,
|
|
96
|
+
bytes_injected: Buffer.byteLength(newContent, 'utf-8') - Buffer.byteLength(existingContent, 'utf-8'),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
// ── Cursor ──────────────────────────────────────────────────────────
|
|
100
|
+
// 路径: 当前 cwd 的 .cursor/rules/skillfm.md (project-level)
|
|
101
|
+
// Cursor 自动注入 .cursor/rules/*.md 到 agent system prompt
|
|
102
|
+
export async function detectCursor() {
|
|
103
|
+
// Mac: ~/Library/Application Support/Cursor/ — 检测 Cursor 装了
|
|
104
|
+
const cursorAppDir = path.join(homedir(), 'Library', 'Application Support', 'Cursor');
|
|
105
|
+
const detected = fs.existsSync(cursorAppDir);
|
|
106
|
+
// 注入路径: 用户当前 cwd 下 .cursor/rules/skillfm.md
|
|
107
|
+
// 但 sidecar cmdStart 时 cwd 可能不是 user's project — 这里只能 surface 提示
|
|
108
|
+
const cwdRules = path.join(process.cwd(), '.cursor', 'rules');
|
|
109
|
+
const injectPath = path.join(cwdRules, 'skillfm.md');
|
|
110
|
+
let already = false;
|
|
111
|
+
if (detected && fs.existsSync(injectPath)) {
|
|
112
|
+
try {
|
|
113
|
+
const c = await fs.promises.readFile(injectPath, 'utf-8');
|
|
114
|
+
already = hasMarkerBlock(c);
|
|
115
|
+
}
|
|
116
|
+
catch { }
|
|
117
|
+
}
|
|
118
|
+
return { harness: 'cursor', detected, inject_path: detected ? injectPath : undefined, already_injected: already };
|
|
119
|
+
}
|
|
120
|
+
export async function injectCursor(opts = {}) {
|
|
121
|
+
const det = await detectCursor();
|
|
122
|
+
if (!det.detected) {
|
|
123
|
+
return { harness: 'cursor', applied: false, error: 'Cursor not detected' };
|
|
124
|
+
}
|
|
125
|
+
const filePath = det.inject_path;
|
|
126
|
+
const dir = path.dirname(filePath);
|
|
127
|
+
if (!fs.existsSync(dir)) {
|
|
128
|
+
await fs.promises.mkdir(dir, { recursive: true });
|
|
129
|
+
}
|
|
130
|
+
let backup_path;
|
|
131
|
+
if (fs.existsSync(filePath)) {
|
|
132
|
+
backup_path = await backupFile(filePath);
|
|
133
|
+
}
|
|
134
|
+
const content = renderForcingGuide(opts);
|
|
135
|
+
await fs.promises.writeFile(filePath, content, 'utf-8');
|
|
136
|
+
return {
|
|
137
|
+
harness: 'cursor',
|
|
138
|
+
applied: true,
|
|
139
|
+
inject_path: filePath,
|
|
140
|
+
backup_path,
|
|
141
|
+
revert_command: backup_path ? `cp "${backup_path}" "${filePath}"` : `rm "${filePath}"`,
|
|
142
|
+
bytes_injected: Buffer.byteLength(content, 'utf-8'),
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
// ── Codex ──────────────────────────────────────────────────────────
|
|
146
|
+
// 路径: ~/.codex/AGENTS.md (marker block)
|
|
147
|
+
export async function detectCodex() {
|
|
148
|
+
const codexDir = path.join(homedir(), '.codex');
|
|
149
|
+
const injectPath = path.join(codexDir, 'AGENTS.md');
|
|
150
|
+
const detected = fs.existsSync(codexDir);
|
|
151
|
+
let already = false;
|
|
152
|
+
if (detected && fs.existsSync(injectPath)) {
|
|
153
|
+
try {
|
|
154
|
+
const c = await fs.promises.readFile(injectPath, 'utf-8');
|
|
155
|
+
already = hasMarkerBlock(c);
|
|
156
|
+
}
|
|
157
|
+
catch { }
|
|
158
|
+
}
|
|
159
|
+
return { harness: 'codex', detected, inject_path: detected ? injectPath : undefined, already_injected: already };
|
|
160
|
+
}
|
|
161
|
+
export async function injectCodex(opts = {}) {
|
|
162
|
+
const det = await detectCodex();
|
|
163
|
+
if (!det.detected) {
|
|
164
|
+
return { harness: 'codex', applied: false, error: 'Codex not detected (~/.codex not found)' };
|
|
165
|
+
}
|
|
166
|
+
const filePath = det.inject_path;
|
|
167
|
+
let existing = '';
|
|
168
|
+
let backup_path;
|
|
169
|
+
if (fs.existsSync(filePath)) {
|
|
170
|
+
backup_path = await backupFile(filePath);
|
|
171
|
+
existing = await fs.promises.readFile(filePath, 'utf-8');
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
existing = '# Codex AGENTS.md\n\n';
|
|
175
|
+
}
|
|
176
|
+
const newContent = injectOrReplaceBlock(existing, opts);
|
|
177
|
+
await fs.promises.writeFile(filePath, newContent, 'utf-8');
|
|
178
|
+
return {
|
|
179
|
+
harness: 'codex',
|
|
180
|
+
applied: true,
|
|
181
|
+
inject_path: filePath,
|
|
182
|
+
backup_path,
|
|
183
|
+
revert_command: backup_path ? `cp "${backup_path}" "${filePath}"` : `rm "${filePath}"`,
|
|
184
|
+
bytes_injected: Buffer.byteLength(newContent, 'utf-8') - Buffer.byteLength(existing, 'utf-8'),
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
// ── Continue (config.json systemMessage) — MVP 暂用 stub, 后续真做 ──
|
|
188
|
+
export async function detectContinue() {
|
|
189
|
+
const cfgPath = path.join(homedir(), '.continue', 'config.json');
|
|
190
|
+
return { harness: 'continue', detected: fs.existsSync(cfgPath), inject_path: cfgPath, already_injected: false };
|
|
191
|
+
}
|
|
192
|
+
// ── Detect 全部 ──
|
|
193
|
+
export async function detectAllHarnesses() {
|
|
194
|
+
return Promise.all([
|
|
195
|
+
detectOpenClaw(),
|
|
196
|
+
detectClaudeCode(),
|
|
197
|
+
detectCursor(),
|
|
198
|
+
detectCodex(),
|
|
199
|
+
detectContinue(),
|
|
200
|
+
]);
|
|
201
|
+
}
|
|
202
|
+
// ── Inject 全部检测到的 ──
|
|
203
|
+
export async function injectAllDetected(opts = {}) {
|
|
204
|
+
const detections = await detectAllHarnesses();
|
|
205
|
+
const results = [];
|
|
206
|
+
for (const d of detections) {
|
|
207
|
+
if (!d.detected)
|
|
208
|
+
continue;
|
|
209
|
+
if (d.harness === 'openclaw')
|
|
210
|
+
results.push(await injectOpenClaw(opts));
|
|
211
|
+
else if (d.harness === 'claude-code')
|
|
212
|
+
results.push(await injectClaudeCode(opts));
|
|
213
|
+
else if (d.harness === 'cursor')
|
|
214
|
+
results.push(await injectCursor(opts));
|
|
215
|
+
else if (d.harness === 'codex')
|
|
216
|
+
results.push(await injectCodex(opts));
|
|
217
|
+
// continue MVP skip
|
|
218
|
+
}
|
|
219
|
+
return results;
|
|
220
|
+
}
|
|
221
|
+
// ── Uninstall: 移除所有注入 ──
|
|
222
|
+
export async function removeAllInjections() {
|
|
223
|
+
const detections = await detectAllHarnesses();
|
|
224
|
+
const results = [];
|
|
225
|
+
for (const d of detections) {
|
|
226
|
+
if (!d.inject_path)
|
|
227
|
+
continue;
|
|
228
|
+
if (!fs.existsSync(d.inject_path))
|
|
229
|
+
continue;
|
|
230
|
+
try {
|
|
231
|
+
const content = await fs.promises.readFile(d.inject_path, 'utf-8');
|
|
232
|
+
if (!hasMarkerBlock(content))
|
|
233
|
+
continue;
|
|
234
|
+
const cleaned = removeBlock(content);
|
|
235
|
+
// 如果 cleaned 是空 / 只剩默认 header → 删文件 (适用 OpenClaw / Cursor 独立文件)
|
|
236
|
+
if (d.harness === 'openclaw' || d.harness === 'cursor') {
|
|
237
|
+
await fs.promises.unlink(d.inject_path);
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
await fs.promises.writeFile(d.inject_path, cleaned, 'utf-8');
|
|
241
|
+
}
|
|
242
|
+
results.push({
|
|
243
|
+
harness: d.harness,
|
|
244
|
+
applied: true,
|
|
245
|
+
inject_path: d.inject_path,
|
|
246
|
+
bytes_injected: -(Buffer.byteLength(content, 'utf-8') - Buffer.byteLength(cleaned, 'utf-8')),
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
catch (e) {
|
|
250
|
+
results.push({ harness: d.harness, applied: false, error: e.message });
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return results;
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=injectors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"injectors.js","sourceRoot":"","sources":["../../src/agent-forcing/injectors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type HarnessId = 'openclaw' | 'claude-code' | 'cursor' | 'codex' | 'continue';
|
|
2
|
+
export interface HarnessDetection {
|
|
3
|
+
harness: HarnessId;
|
|
4
|
+
/** 是否检测到这个 harness 已装 */
|
|
5
|
+
detected: boolean;
|
|
6
|
+
/** 注入文件真路径 (e.g. ~/.openclaw/workspace/SKILLFM-AGENT-GUIDE.md) */
|
|
7
|
+
inject_path?: string;
|
|
8
|
+
/** SkillFM 块当前是否已注入 (检查 marker) */
|
|
9
|
+
already_injected: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface ForcingInjectResult {
|
|
12
|
+
harness: HarnessId;
|
|
13
|
+
applied: boolean;
|
|
14
|
+
inject_path?: string;
|
|
15
|
+
/** Backup 路径 (如果改了已存在文件) */
|
|
16
|
+
backup_path?: string;
|
|
17
|
+
/** Revert 命令 1 行 */
|
|
18
|
+
revert_command?: string;
|
|
19
|
+
error?: string;
|
|
20
|
+
/** 注入的字符数 */
|
|
21
|
+
bytes_injected?: number;
|
|
22
|
+
}
|
|
23
|
+
/** SkillFM marker 块标记 — 用来识别已注入 + revert 时定位 */
|
|
24
|
+
export declare const SKILLFM_MARKER_START = "<!-- SKILLFM-AGENT-GUIDE BEGIN (auto-injected, do not delete) -->";
|
|
25
|
+
export declare const SKILLFM_MARKER_END = "<!-- SKILLFM-AGENT-GUIDE END -->";
|
|
26
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agent-forcing/types.ts"],"names":[],"mappings":"AAkBA,MAAM,MAAM,SAAS,GACjB,UAAU,GACV,aAAa,GACb,QAAQ,GACR,OAAO,GACP,UAAU,CAAC;AAEf,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,SAAS,CAAC;IACnB,yBAAyB;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,SAAS,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4BAA4B;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa;IACb,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,gDAAgD;AAChD,eAAO,MAAM,oBAAoB,sEAAsE,CAAC;AACxG,eAAO,MAAM,kBAAkB,qCAAqC,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// sdk/skillfm-local/src/agent-forcing/types.ts
|
|
2
|
+
//
|
|
3
|
+
// Agent Forcing Adapter — install 时主动检测各 harness workspace files +
|
|
4
|
+
// 注入 SKILLFM-AGENT-GUIDE 强 forcing rule 进 system prompt.
|
|
5
|
+
//
|
|
6
|
+
// 真问题 (Eric 反馈, turn 4 真测):
|
|
7
|
+
// - MiniMax-M2.7 instruction following 弱, 倾向 generic exec, 不调 SkillFM MCP tool
|
|
8
|
+
// - MCP tool description 写多强都输 system prompt 注入 (训练数据 bias)
|
|
9
|
+
// - 真解 = 各 harness workspace files 加 SkillFM forcing rule, agent 必看
|
|
10
|
+
//
|
|
11
|
+
// 各 harness 真注入路径 (调研验证):
|
|
12
|
+
// OpenClaw: ~/.openclaw/workspace/SKILLFM-AGENT-GUIDE.md
|
|
13
|
+
// Claude Code: ~/.claude/CLAUDE.md (user-level, marker block)
|
|
14
|
+
// Cursor: .cursor/rules/skillfm.md (project-level)
|
|
15
|
+
// Codex: ~/.codex/AGENTS.md (marker block)
|
|
16
|
+
// Continue: continue.config.json systemMessage (后续)
|
|
17
|
+
// Aider: ❌ 没 system prompt 注入机制 (用 CLI fallback)
|
|
18
|
+
/** SkillFM marker 块标记 — 用来识别已注入 + revert 时定位 */
|
|
19
|
+
export const SKILLFM_MARKER_START = '<!-- SKILLFM-AGENT-GUIDE BEGIN (auto-injected, do not delete) -->';
|
|
20
|
+
export const SKILLFM_MARKER_END = '<!-- SKILLFM-AGENT-GUIDE END -->';
|
|
21
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/agent-forcing/types.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,EAAE;AACF,mEAAmE;AACnE,yDAAyD;AACzD,EAAE;AACF,4BAA4B;AAC5B,iFAAiF;AACjF,8DAA8D;AAC9D,sEAAsE;AACtE,EAAE;AACF,0BAA0B;AAC1B,2DAA2D;AAC3D,gEAAgE;AAChE,qDAAqD;AACrD,6CAA6C;AAC7C,sDAAsD;AACtD,mDAAmD;AAgCnD,gDAAgD;AAChD,MAAM,CAAC,MAAM,oBAAoB,GAAG,mEAAmE,CAAC;AACxG,MAAM,CAAC,MAAM,kBAAkB,GAAG,kCAAkC,CAAC"}
|
|
@@ -5,12 +5,26 @@ interface FileGroup {
|
|
|
5
5
|
total_bytes: number;
|
|
6
6
|
age_days_min: number;
|
|
7
7
|
}
|
|
8
|
+
interface CleanupHistoryEntry {
|
|
9
|
+
timestamp: string;
|
|
10
|
+
bytes_freed: number;
|
|
11
|
+
files_moved: number;
|
|
12
|
+
}
|
|
13
|
+
declare function appendCleanupHistory(entry: CleanupHistoryEntry): Promise<void>;
|
|
8
14
|
/**
|
|
9
|
-
* 跑一次 file 体检 — 返 DimensionStatus + 各 group 详情
|
|
15
|
+
* 跑一次 file 体检 — 返 DimensionStatus + 各 group 详情 + 累计 history
|
|
10
16
|
*/
|
|
11
17
|
export declare function checkDimensionFiles(): Promise<DimensionStatus & {
|
|
12
18
|
groups: FileGroup[];
|
|
19
|
+
cumulative_this_month: {
|
|
20
|
+
bytes: number;
|
|
21
|
+
files: number;
|
|
22
|
+
};
|
|
13
23
|
}>;
|
|
24
|
+
/**
|
|
25
|
+
* Export for cleanup execution to record history
|
|
26
|
+
*/
|
|
27
|
+
export { appendCleanupHistory };
|
|
14
28
|
/**
|
|
15
29
|
* 一键清 — 删 group 列出的文件 (移到 ~/.skillfm/cleanup-archive/<timestamp>/ 不真删, 7 天后真清)
|
|
16
30
|
* 返 删了多少 bytes + 多少 file
|
|
@@ -19,5 +33,4 @@ export declare function executeFileCleanup(groups: FileGroup[]): Promise<{
|
|
|
19
33
|
bytes_freed: number;
|
|
20
34
|
files_moved: number;
|
|
21
35
|
}>;
|
|
22
|
-
export {};
|
|
23
36
|
//# sourceMappingURL=dimension-3-files.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dimension-3-files.d.ts","sourceRoot":"","sources":["../../src/checkup/dimension-3-files.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,YAAY,CAAC;AAErE,UAAU,SAAS;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;
|
|
1
|
+
{"version":3,"file":"dimension-3-files.d.ts","sourceRoot":"","sources":["../../src/checkup/dimension-3-files.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,YAAY,CAAC;AAErE,UAAU,SAAS;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AA4HD,UAAU,mBAAmB;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AA0BD,iBAAe,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAM7E;AASD;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,eAAe,GAAG;IAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAAC,qBAAqB,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC,CAoEvJ;AAED;;GAEG;AACH,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAEhC;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAgCnH"}
|