@skillfm/local 2.7.5 → 2.7.7
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 +47 -0
- package/dist/agent-forcing/forcing-rules.d.ts.map +1 -0
- package/dist/agent-forcing/forcing-rules.js +206 -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 +387 -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-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 +15 -4
- 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/package.json +1 -1
|
@@ -0,0 +1,387 @@
|
|
|
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 { SKILLFM_MARKER_START, SKILLFM_MARKER_END } from './types.js';
|
|
8
|
+
import { renderForcingGuide, injectOrReplaceBlock, removeBlock, hasMarkerBlock, renderSoulIdentityBlock, renderToolsGuideBlock, } from './forcing-rules.js';
|
|
9
|
+
const BACKUP_BASE = path.join(homedir(), '.skillfm', 'agent-forcing-backup');
|
|
10
|
+
async function backupFile(filePath) {
|
|
11
|
+
const ts = new Date().toISOString().replace(/[:.]/g, '-');
|
|
12
|
+
const dir = path.join(BACKUP_BASE, ts);
|
|
13
|
+
await fs.promises.mkdir(dir, { recursive: true, mode: 0o700 });
|
|
14
|
+
const name = path.basename(filePath);
|
|
15
|
+
const backupPath = path.join(dir, name);
|
|
16
|
+
await fs.promises.copyFile(filePath, backupPath);
|
|
17
|
+
return backupPath;
|
|
18
|
+
}
|
|
19
|
+
// ── OpenClaw ────────────────────────────────────────────────────────
|
|
20
|
+
// 真路径分层 (Eric "design 不够好" 后调研发现 OpenClaw 真层级):
|
|
21
|
+
// - SOUL.md: identity 层 (model 当自我, 训练数据 identity 模式最熟) → 注 identity assimilation
|
|
22
|
+
// - TOOLS.md: OpenClaw 专为 MCP tool 配置 → 注 tool guide (5 tool 触发 + 用法 + example)
|
|
23
|
+
// - AGENTS.md: 跨 agent instructions → 保留 long guide (detail reference)
|
|
24
|
+
// - IDENTITY/HEARTBEAT/MEMORY: 次要 → 注 short rule 重复保险
|
|
25
|
+
//
|
|
26
|
+
// 关键改动 (vs 旧版 5 文件 short PREPEND): SOUL/TOOLS 是真 identity/tool 主战场,
|
|
27
|
+
// 不是 instructions. 这才是 OpenClaw 设计真意图 (https://docs.openclaw.ai/concepts/system-prompt).
|
|
28
|
+
const OPENCLAW_SOUL_FILE = 'SOUL.md'; // identity 层 — 真核武器
|
|
29
|
+
const OPENCLAW_TOOLS_FILE = 'TOOLS.md'; // tool 专用层
|
|
30
|
+
const OPENCLAW_AGENTS_FILE = 'AGENTS.md'; // instructions 层 (long guide)
|
|
31
|
+
const OPENCLAW_FORCED_SHORT_FILES = ['IDENTITY.md', 'HEARTBEAT.md', 'MEMORY.md']; // 次要保险
|
|
32
|
+
export async function detectOpenClaw() {
|
|
33
|
+
const workspaceDir = path.join(homedir(), '.openclaw', 'workspace');
|
|
34
|
+
const detected = fs.existsSync(workspaceDir);
|
|
35
|
+
const soulPath = path.join(workspaceDir, OPENCLAW_SOUL_FILE);
|
|
36
|
+
let already = false;
|
|
37
|
+
if (detected && fs.existsSync(soulPath)) {
|
|
38
|
+
try {
|
|
39
|
+
const c = await fs.promises.readFile(soulPath, 'utf-8');
|
|
40
|
+
already = hasMarkerBlock(c);
|
|
41
|
+
}
|
|
42
|
+
catch { }
|
|
43
|
+
}
|
|
44
|
+
return { harness: 'openclaw', detected, inject_path: detected ? soulPath : undefined, already_injected: already };
|
|
45
|
+
}
|
|
46
|
+
export async function injectOpenClaw(opts = {}) {
|
|
47
|
+
const det = await detectOpenClaw();
|
|
48
|
+
if (!det.detected) {
|
|
49
|
+
return { harness: 'openclaw', applied: false, error: 'OpenClaw workspace not found (~/.openclaw/workspace)' };
|
|
50
|
+
}
|
|
51
|
+
const workspaceDir = path.join(homedir(), '.openclaw', 'workspace');
|
|
52
|
+
// 清理旧版独立文件 (deprecated, OpenClaw 不读)
|
|
53
|
+
const oldStandalonePath = path.join(workspaceDir, 'SKILLFM-AGENT-GUIDE.md');
|
|
54
|
+
if (fs.existsSync(oldStandalonePath)) {
|
|
55
|
+
await fs.promises.unlink(oldStandalonePath).catch(() => { });
|
|
56
|
+
}
|
|
57
|
+
let totalBytes = 0;
|
|
58
|
+
const injectedFiles = [];
|
|
59
|
+
let mainBackupPath;
|
|
60
|
+
// 1️⃣ SOUL.md — identity assimilation (真核武器)
|
|
61
|
+
await injectOpenClawFile({
|
|
62
|
+
workspaceDir,
|
|
63
|
+
filename: OPENCLAW_SOUL_FILE,
|
|
64
|
+
block: renderSoulIdentityBlock(opts),
|
|
65
|
+
onResult: (bytes, backup) => {
|
|
66
|
+
totalBytes += bytes;
|
|
67
|
+
injectedFiles.push(path.join(workspaceDir, OPENCLAW_SOUL_FILE));
|
|
68
|
+
if (backup)
|
|
69
|
+
mainBackupPath = backup;
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
// 2️⃣ TOOLS.md — MCP tool 详细说明 (OpenClaw 专为 tool 设计)
|
|
73
|
+
await injectOpenClawFile({
|
|
74
|
+
workspaceDir,
|
|
75
|
+
filename: OPENCLAW_TOOLS_FILE,
|
|
76
|
+
block: renderToolsGuideBlock(opts),
|
|
77
|
+
onResult: (bytes) => {
|
|
78
|
+
totalBytes += bytes;
|
|
79
|
+
injectedFiles.push(path.join(workspaceDir, OPENCLAW_TOOLS_FILE));
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
// 3️⃣ AGENTS.md — long forcing guide (detail reference)
|
|
83
|
+
await injectOpenClawFile({
|
|
84
|
+
workspaceDir,
|
|
85
|
+
filename: OPENCLAW_AGENTS_FILE,
|
|
86
|
+
block: renderForcingGuide(opts),
|
|
87
|
+
onResult: (bytes) => {
|
|
88
|
+
totalBytes += bytes;
|
|
89
|
+
injectedFiles.push(path.join(workspaceDir, OPENCLAW_AGENTS_FILE));
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
// 4️⃣ IDENTITY/HEARTBEAT/MEMORY — short rule (重复保险, model 看到 6 处)
|
|
93
|
+
for (const filename of OPENCLAW_FORCED_SHORT_FILES) {
|
|
94
|
+
const filePath = path.join(workspaceDir, filename);
|
|
95
|
+
let existing = '';
|
|
96
|
+
if (fs.existsSync(filePath)) {
|
|
97
|
+
existing = await fs.promises.readFile(filePath, 'utf-8');
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
existing = `# ${filename.replace('.md', '')}\n\n`;
|
|
101
|
+
}
|
|
102
|
+
// 用 short rule (不是 SOUL/TOOLS 的 full guide)
|
|
103
|
+
const newContent = injectOrReplaceBlock(existing, opts, 'short');
|
|
104
|
+
await fs.promises.writeFile(filePath, newContent, 'utf-8');
|
|
105
|
+
totalBytes += Buffer.byteLength(newContent, 'utf-8') - Buffer.byteLength(existing, 'utf-8');
|
|
106
|
+
injectedFiles.push(filePath);
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
harness: 'openclaw',
|
|
110
|
+
applied: true,
|
|
111
|
+
inject_path: injectedFiles.join(', '),
|
|
112
|
+
backup_path: mainBackupPath,
|
|
113
|
+
revert_command: 'npx -y -p @skillfm/local skillfm-local forcing uninstall',
|
|
114
|
+
bytes_injected: totalBytes,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* 单文件注入 helper (用于 SOUL/TOOLS/AGENTS 不同 block 内容).
|
|
119
|
+
* block 是已 render 好的字符串, 直接 PREPEND/replace 进文件.
|
|
120
|
+
*/
|
|
121
|
+
async function injectOpenClawFile(opts) {
|
|
122
|
+
const filePath = path.join(opts.workspaceDir, opts.filename);
|
|
123
|
+
let existing = '';
|
|
124
|
+
let backup;
|
|
125
|
+
if (fs.existsSync(filePath)) {
|
|
126
|
+
backup = await backupFile(filePath);
|
|
127
|
+
existing = await fs.promises.readFile(filePath, 'utf-8');
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
existing = `# ${opts.filename.replace('.md', '')}\n\n`;
|
|
131
|
+
}
|
|
132
|
+
// PREPEND or replace existing block
|
|
133
|
+
const startIdx = existing.indexOf(SKILLFM_MARKER_START);
|
|
134
|
+
const endIdx = existing.indexOf(SKILLFM_MARKER_END);
|
|
135
|
+
let newContent;
|
|
136
|
+
if (startIdx >= 0 && endIdx > startIdx) {
|
|
137
|
+
newContent = existing.slice(0, startIdx).trimEnd() + '\n\n' + opts.block + '\n' + existing.slice(endIdx + SKILLFM_MARKER_END.length).trimStart();
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
const trimmed = existing.trimStart();
|
|
141
|
+
const firstNewline = trimmed.indexOf('\n');
|
|
142
|
+
if (firstNewline > 0 && trimmed.startsWith('#')) {
|
|
143
|
+
newContent = trimmed.slice(0, firstNewline + 1) + '\n' + opts.block + '\n\n' + trimmed.slice(firstNewline + 1);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
newContent = opts.block + '\n\n' + existing.trimStart();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
await fs.promises.writeFile(filePath, newContent, 'utf-8');
|
|
150
|
+
opts.onResult(Buffer.byteLength(newContent, 'utf-8') - Buffer.byteLength(existing, 'utf-8'), backup);
|
|
151
|
+
}
|
|
152
|
+
// ── Claude Code ─────────────────────────────────────────────────────
|
|
153
|
+
// 路径: ~/.claude/CLAUDE.md (user-level memory, Claude Code 必读)
|
|
154
|
+
// 注入: marker block append/replace 进现有 CLAUDE.md
|
|
155
|
+
export async function detectClaudeCode() {
|
|
156
|
+
const claudeDir = path.join(homedir(), '.claude');
|
|
157
|
+
const injectPath = path.join(claudeDir, 'CLAUDE.md');
|
|
158
|
+
const detected = fs.existsSync(claudeDir);
|
|
159
|
+
let already = false;
|
|
160
|
+
if (detected && fs.existsSync(injectPath)) {
|
|
161
|
+
try {
|
|
162
|
+
const c = await fs.promises.readFile(injectPath, 'utf-8');
|
|
163
|
+
already = hasMarkerBlock(c);
|
|
164
|
+
}
|
|
165
|
+
catch { }
|
|
166
|
+
}
|
|
167
|
+
return { harness: 'claude-code', detected, inject_path: detected ? injectPath : undefined, already_injected: already };
|
|
168
|
+
}
|
|
169
|
+
export async function injectClaudeCode(opts = {}) {
|
|
170
|
+
const det = await detectClaudeCode();
|
|
171
|
+
if (!det.detected) {
|
|
172
|
+
return { harness: 'claude-code', applied: false, error: 'Claude Code not detected (~/.claude not found)' };
|
|
173
|
+
}
|
|
174
|
+
const filePath = det.inject_path;
|
|
175
|
+
let existingContent = '';
|
|
176
|
+
let backup_path;
|
|
177
|
+
if (fs.existsSync(filePath)) {
|
|
178
|
+
backup_path = await backupFile(filePath);
|
|
179
|
+
existingContent = await fs.promises.readFile(filePath, 'utf-8');
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
existingContent = '# Claude Code Memory\n\n';
|
|
183
|
+
}
|
|
184
|
+
const newContent = injectOrReplaceBlock(existingContent, opts);
|
|
185
|
+
await fs.promises.writeFile(filePath, newContent, 'utf-8');
|
|
186
|
+
return {
|
|
187
|
+
harness: 'claude-code',
|
|
188
|
+
applied: true,
|
|
189
|
+
inject_path: filePath,
|
|
190
|
+
backup_path,
|
|
191
|
+
revert_command: backup_path ? `cp "${backup_path}" "${filePath}"` : `rm "${filePath}"`,
|
|
192
|
+
bytes_injected: Buffer.byteLength(newContent, 'utf-8') - Buffer.byteLength(existingContent, 'utf-8'),
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
// ── Cursor ──────────────────────────────────────────────────────────
|
|
196
|
+
// 路径: 当前 cwd 的 .cursor/rules/skillfm.md (project-level)
|
|
197
|
+
// Cursor 自动注入 .cursor/rules/*.md 到 agent system prompt
|
|
198
|
+
export async function detectCursor() {
|
|
199
|
+
// Mac: ~/Library/Application Support/Cursor/ — 检测 Cursor 装了
|
|
200
|
+
const cursorAppDir = path.join(homedir(), 'Library', 'Application Support', 'Cursor');
|
|
201
|
+
const detected = fs.existsSync(cursorAppDir);
|
|
202
|
+
// 注入路径: 用户当前 cwd 下 .cursor/rules/skillfm.md
|
|
203
|
+
// 但 sidecar cmdStart 时 cwd 可能不是 user's project — 这里只能 surface 提示
|
|
204
|
+
const cwdRules = path.join(process.cwd(), '.cursor', 'rules');
|
|
205
|
+
const injectPath = path.join(cwdRules, 'skillfm.md');
|
|
206
|
+
let already = false;
|
|
207
|
+
if (detected && fs.existsSync(injectPath)) {
|
|
208
|
+
try {
|
|
209
|
+
const c = await fs.promises.readFile(injectPath, 'utf-8');
|
|
210
|
+
already = hasMarkerBlock(c);
|
|
211
|
+
}
|
|
212
|
+
catch { }
|
|
213
|
+
}
|
|
214
|
+
return { harness: 'cursor', detected, inject_path: detected ? injectPath : undefined, already_injected: already };
|
|
215
|
+
}
|
|
216
|
+
export async function injectCursor(opts = {}) {
|
|
217
|
+
const det = await detectCursor();
|
|
218
|
+
if (!det.detected) {
|
|
219
|
+
return { harness: 'cursor', applied: false, error: 'Cursor not detected' };
|
|
220
|
+
}
|
|
221
|
+
const filePath = det.inject_path;
|
|
222
|
+
const dir = path.dirname(filePath);
|
|
223
|
+
if (!fs.existsSync(dir)) {
|
|
224
|
+
await fs.promises.mkdir(dir, { recursive: true });
|
|
225
|
+
}
|
|
226
|
+
let backup_path;
|
|
227
|
+
if (fs.existsSync(filePath)) {
|
|
228
|
+
backup_path = await backupFile(filePath);
|
|
229
|
+
}
|
|
230
|
+
const content = renderForcingGuide(opts);
|
|
231
|
+
await fs.promises.writeFile(filePath, content, 'utf-8');
|
|
232
|
+
return {
|
|
233
|
+
harness: 'cursor',
|
|
234
|
+
applied: true,
|
|
235
|
+
inject_path: filePath,
|
|
236
|
+
backup_path,
|
|
237
|
+
revert_command: backup_path ? `cp "${backup_path}" "${filePath}"` : `rm "${filePath}"`,
|
|
238
|
+
bytes_injected: Buffer.byteLength(content, 'utf-8'),
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
// ── Codex ──────────────────────────────────────────────────────────
|
|
242
|
+
// 路径: ~/.codex/AGENTS.md (marker block)
|
|
243
|
+
export async function detectCodex() {
|
|
244
|
+
const codexDir = path.join(homedir(), '.codex');
|
|
245
|
+
const injectPath = path.join(codexDir, 'AGENTS.md');
|
|
246
|
+
const detected = fs.existsSync(codexDir);
|
|
247
|
+
let already = false;
|
|
248
|
+
if (detected && fs.existsSync(injectPath)) {
|
|
249
|
+
try {
|
|
250
|
+
const c = await fs.promises.readFile(injectPath, 'utf-8');
|
|
251
|
+
already = hasMarkerBlock(c);
|
|
252
|
+
}
|
|
253
|
+
catch { }
|
|
254
|
+
}
|
|
255
|
+
return { harness: 'codex', detected, inject_path: detected ? injectPath : undefined, already_injected: already };
|
|
256
|
+
}
|
|
257
|
+
export async function injectCodex(opts = {}) {
|
|
258
|
+
const det = await detectCodex();
|
|
259
|
+
if (!det.detected) {
|
|
260
|
+
return { harness: 'codex', applied: false, error: 'Codex not detected (~/.codex not found)' };
|
|
261
|
+
}
|
|
262
|
+
const filePath = det.inject_path;
|
|
263
|
+
let existing = '';
|
|
264
|
+
let backup_path;
|
|
265
|
+
if (fs.existsSync(filePath)) {
|
|
266
|
+
backup_path = await backupFile(filePath);
|
|
267
|
+
existing = await fs.promises.readFile(filePath, 'utf-8');
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
existing = '# Codex AGENTS.md\n\n';
|
|
271
|
+
}
|
|
272
|
+
const newContent = injectOrReplaceBlock(existing, opts);
|
|
273
|
+
await fs.promises.writeFile(filePath, newContent, 'utf-8');
|
|
274
|
+
return {
|
|
275
|
+
harness: 'codex',
|
|
276
|
+
applied: true,
|
|
277
|
+
inject_path: filePath,
|
|
278
|
+
backup_path,
|
|
279
|
+
revert_command: backup_path ? `cp "${backup_path}" "${filePath}"` : `rm "${filePath}"`,
|
|
280
|
+
bytes_injected: Buffer.byteLength(newContent, 'utf-8') - Buffer.byteLength(existing, 'utf-8'),
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
// ── Continue (config.json systemMessage) — MVP 暂用 stub, 后续真做 ──
|
|
284
|
+
export async function detectContinue() {
|
|
285
|
+
const cfgPath = path.join(homedir(), '.continue', 'config.json');
|
|
286
|
+
return { harness: 'continue', detected: fs.existsSync(cfgPath), inject_path: cfgPath, already_injected: false };
|
|
287
|
+
}
|
|
288
|
+
// ── Detect 全部 ──
|
|
289
|
+
export async function detectAllHarnesses() {
|
|
290
|
+
return Promise.all([
|
|
291
|
+
detectOpenClaw(),
|
|
292
|
+
detectClaudeCode(),
|
|
293
|
+
detectCursor(),
|
|
294
|
+
detectCodex(),
|
|
295
|
+
detectContinue(),
|
|
296
|
+
]);
|
|
297
|
+
}
|
|
298
|
+
// ── Inject 全部检测到的 ──
|
|
299
|
+
export async function injectAllDetected(opts = {}) {
|
|
300
|
+
const detections = await detectAllHarnesses();
|
|
301
|
+
const results = [];
|
|
302
|
+
for (const d of detections) {
|
|
303
|
+
if (!d.detected)
|
|
304
|
+
continue;
|
|
305
|
+
if (d.harness === 'openclaw')
|
|
306
|
+
results.push(await injectOpenClaw(opts));
|
|
307
|
+
else if (d.harness === 'claude-code')
|
|
308
|
+
results.push(await injectClaudeCode(opts));
|
|
309
|
+
else if (d.harness === 'cursor')
|
|
310
|
+
results.push(await injectCursor(opts));
|
|
311
|
+
else if (d.harness === 'codex')
|
|
312
|
+
results.push(await injectCodex(opts));
|
|
313
|
+
// continue MVP skip
|
|
314
|
+
}
|
|
315
|
+
return results;
|
|
316
|
+
}
|
|
317
|
+
// ── Uninstall: 移除所有注入 ──
|
|
318
|
+
export async function removeAllInjections() {
|
|
319
|
+
const detections = await detectAllHarnesses();
|
|
320
|
+
const results = [];
|
|
321
|
+
for (const d of detections) {
|
|
322
|
+
if (d.harness === 'openclaw') {
|
|
323
|
+
// OpenClaw: 6 文件全清 marker block (跟 inject 对称)
|
|
324
|
+
const workspaceDir = path.join(homedir(), '.openclaw', 'workspace');
|
|
325
|
+
const allOpenClawFiles = [
|
|
326
|
+
OPENCLAW_SOUL_FILE, OPENCLAW_TOOLS_FILE, OPENCLAW_AGENTS_FILE,
|
|
327
|
+
...OPENCLAW_FORCED_SHORT_FILES,
|
|
328
|
+
];
|
|
329
|
+
let totalRemoved = 0;
|
|
330
|
+
const cleanedFiles = [];
|
|
331
|
+
for (const filename of allOpenClawFiles) {
|
|
332
|
+
const filePath = path.join(workspaceDir, filename);
|
|
333
|
+
if (!fs.existsSync(filePath))
|
|
334
|
+
continue;
|
|
335
|
+
try {
|
|
336
|
+
const content = await fs.promises.readFile(filePath, 'utf-8');
|
|
337
|
+
if (!hasMarkerBlock(content))
|
|
338
|
+
continue;
|
|
339
|
+
const cleaned = removeBlock(content);
|
|
340
|
+
await fs.promises.writeFile(filePath, cleaned, 'utf-8');
|
|
341
|
+
totalRemoved += Buffer.byteLength(content, 'utf-8') - Buffer.byteLength(cleaned, 'utf-8');
|
|
342
|
+
cleanedFiles.push(filename);
|
|
343
|
+
}
|
|
344
|
+
catch {
|
|
345
|
+
// skip
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
if (cleanedFiles.length > 0) {
|
|
349
|
+
results.push({
|
|
350
|
+
harness: 'openclaw',
|
|
351
|
+
applied: true,
|
|
352
|
+
inject_path: cleanedFiles.join(', '),
|
|
353
|
+
bytes_injected: -totalRemoved,
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
358
|
+
// 其他 harness: 单文件
|
|
359
|
+
if (!d.inject_path)
|
|
360
|
+
continue;
|
|
361
|
+
if (!fs.existsSync(d.inject_path))
|
|
362
|
+
continue;
|
|
363
|
+
try {
|
|
364
|
+
const content = await fs.promises.readFile(d.inject_path, 'utf-8');
|
|
365
|
+
if (!hasMarkerBlock(content))
|
|
366
|
+
continue;
|
|
367
|
+
const cleaned = removeBlock(content);
|
|
368
|
+
if (d.harness === 'cursor') {
|
|
369
|
+
await fs.promises.unlink(d.inject_path);
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
await fs.promises.writeFile(d.inject_path, cleaned, 'utf-8');
|
|
373
|
+
}
|
|
374
|
+
results.push({
|
|
375
|
+
harness: d.harness,
|
|
376
|
+
applied: true,
|
|
377
|
+
inject_path: d.inject_path,
|
|
378
|
+
bytes_injected: -(Buffer.byteLength(content, 'utf-8') - Buffer.byteLength(cleaned, 'utf-8')),
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
catch (e) {
|
|
382
|
+
results.push({ harness: d.harness, applied: false, error: e.message });
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
return results;
|
|
386
|
+
}
|
|
387
|
+
//# 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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkup-cli.d.ts","sourceRoot":"","sources":["../src/checkup-cli.ts"],"names":[],"mappings":"AAsBA,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CA+BhD"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// sdk/skillfm-local/src/checkup-cli.ts
|
|
2
|
+
//
|
|
3
|
+
// CLI fallback (V1.4): npx @skillfm/local checkup
|
|
4
|
+
// 用户终端直接看主入口 UX, 完全 bypass agent.
|
|
5
|
+
//
|
|
6
|
+
// 真用法:
|
|
7
|
+
// npx -y @skillfm/local@latest checkup # today
|
|
8
|
+
// npx -y @skillfm/local@latest checkup --week # 本周
|
|
9
|
+
// npx -y @skillfm/local@latest checkup --json # raw JSON
|
|
10
|
+
//
|
|
11
|
+
// 这是解决 agent 弱问题的 0 摩擦兜底 — 即使 agent 抽风, 用户能直接看.
|
|
12
|
+
import { startUsageLocal } from './usage-local/index.js';
|
|
13
|
+
import { ReconciliationEngine } from './reconciliation/index.js';
|
|
14
|
+
import { AnthropicConnector, OpenAIConnector, DeepSeekConnector, KimiConnector, QwenConnector, DoubaoConnector, } from './connectors/index.js';
|
|
15
|
+
import { Vault } from './vault/index.js';
|
|
16
|
+
import { runCheckup, renderMainEntry } from './checkup/index.js';
|
|
17
|
+
export async function cmdCheckup() {
|
|
18
|
+
const args = process.argv.slice(3);
|
|
19
|
+
const jsonMode = args.includes('--json');
|
|
20
|
+
// 启动 L0 watcher (warm scan), 等真聚合数据
|
|
21
|
+
const usage = await startUsageLocal({ verbose: false });
|
|
22
|
+
const vault = new Vault();
|
|
23
|
+
const connectors = {
|
|
24
|
+
anthropic: new AnthropicConnector(),
|
|
25
|
+
openai: new OpenAIConnector(),
|
|
26
|
+
deepseek: new DeepSeekConnector(),
|
|
27
|
+
kimi: new KimiConnector(),
|
|
28
|
+
qwen: new QwenConnector(),
|
|
29
|
+
doubao: new DoubaoConnector(),
|
|
30
|
+
};
|
|
31
|
+
const recEngine = new ReconciliationEngine({ vault, connectors, store: usage.store });
|
|
32
|
+
const report = await runCheckup({
|
|
33
|
+
store: usage.store,
|
|
34
|
+
reconciliationEngine: recEngine,
|
|
35
|
+
is_pro: false, // CLI 模式 default Free; 后续可加 --pro flag
|
|
36
|
+
});
|
|
37
|
+
if (jsonMode) {
|
|
38
|
+
console.log(JSON.stringify(report, null, 2));
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
console.log(renderMainEntry(report));
|
|
42
|
+
}
|
|
43
|
+
usage.stop();
|
|
44
|
+
process.exit(0);
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=checkup-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkup-cli.js","sourceRoot":"","sources":["../src/checkup-cli.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,EAAE;AACF,kDAAkD;AAClD,kCAAkC;AAClC,EAAE;AACF,OAAO;AACP,2DAA2D;AAC3D,wDAAwD;AACxD,8DAA8D;AAC9D,EAAE;AACF,gDAAgD;AAEhD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EACL,kBAAkB,EAAE,eAAe,EAAE,iBAAiB,EACtD,aAAa,EAAE,aAAa,EAAE,eAAe,GAC9C,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAEjE,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEzC,oCAAoC;IACpC,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;IAC1B,MAAM,UAAU,GAA8B;QAC5C,SAAS,EAAE,IAAI,kBAAkB,EAAE;QACnC,MAAM,EAAE,IAAI,eAAe,EAAE;QAC7B,QAAQ,EAAE,IAAI,iBAAiB,EAAE;QACjC,IAAI,EAAE,IAAI,aAAa,EAAE;QACzB,IAAI,EAAE,IAAI,aAAa,EAAE;QACzB,MAAM,EAAE,IAAI,eAAe,EAAE;KAC9B,CAAC;IACF,MAAM,SAAS,GAAG,IAAI,oBAAoB,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;IAEtF,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC;QAC9B,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,oBAAoB,EAAE,SAAS;QAC/B,MAAM,EAAE,KAAK,EAAE,uCAAuC;KACvD,CAAC,CAAC;IAEH,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,IAAI,EAAE,CAAC;IACb,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forcing-cli.d.ts","sourceRoot":"","sources":["../src/forcing-cli.ts"],"names":[],"mappings":"AAeA,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAsChD"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// sdk/skillfm-local/src/forcing-cli.ts
|
|
2
|
+
//
|
|
3
|
+
// CLI: npx @skillfm/local forcing <subcommand>
|
|
4
|
+
// detect — 仅检测各 harness, 不真改
|
|
5
|
+
// inject — 真注入 SKILLFM-AGENT-GUIDE block 到检测到的 harness
|
|
6
|
+
// uninstall — 移除已注入的 block
|
|
7
|
+
//
|
|
8
|
+
// 这是用户手动控制 agent forcing 的 CLI fallback (sidecar 启动时也会自动跑 inject).
|
|
9
|
+
import { detectAllHarnesses, injectAllDetected, removeAllInjections, } from './agent-forcing/index.js';
|
|
10
|
+
export async function cmdForcing() {
|
|
11
|
+
const sub = process.argv[3] ?? 'detect';
|
|
12
|
+
if (sub === 'detect') {
|
|
13
|
+
const detections = await detectAllHarnesses();
|
|
14
|
+
console.log('🤖 SkillFM Agent Forcing — Detection');
|
|
15
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
16
|
+
for (const d of detections) {
|
|
17
|
+
const status = !d.detected ? '❌ 未装'
|
|
18
|
+
: d.already_injected ? '✅ 已注入'
|
|
19
|
+
: '⚠️ 未注入';
|
|
20
|
+
console.log(` ${d.harness}: ${status}${d.inject_path ? ` (${d.inject_path})` : ''}`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
else if (sub === 'inject') {
|
|
24
|
+
const results = await injectAllDetected({});
|
|
25
|
+
console.log('🤖 SkillFM Agent Forcing — Inject');
|
|
26
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
27
|
+
for (const r of results) {
|
|
28
|
+
if (r.applied) {
|
|
29
|
+
console.log(` ✅ ${r.harness}: 注入 ${r.bytes_injected} 字节 → ${r.inject_path}`);
|
|
30
|
+
if (r.revert_command)
|
|
31
|
+
console.log(` 回滚: ${r.revert_command}`);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
console.log(` ⚠️ ${r.harness}: ${r.error ?? 'skip'}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else if (sub === 'uninstall') {
|
|
39
|
+
const results = await removeAllInjections();
|
|
40
|
+
console.log('🗑 SkillFM Agent Forcing — Uninstall');
|
|
41
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
42
|
+
for (const r of results) {
|
|
43
|
+
console.log(r.applied ? ` ✅ ${r.harness}: 移除完成` : ` ⚠️ ${r.harness}: ${r.error ?? 'no block'}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
console.error(`Unknown forcing subcommand: ${sub}`);
|
|
48
|
+
console.error('Usage: skillfm-local forcing <detect|inject|uninstall>');
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
process.exit(0);
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=forcing-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forcing-cli.js","sourceRoot":"","sources":["../src/forcing-cli.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,EAAE;AACF,+CAA+C;AAC/C,qCAAqC;AACrC,+DAA+D;AAC/D,gCAAgC;AAChC,EAAE;AACF,mEAAmE;AAEnE,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAElC,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC;IAExC,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;QACrB,MAAM,UAAU,GAAG,MAAM,kBAAkB,EAAE,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;QACxC,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM;gBACjC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,OAAO;oBAC9B,CAAC,CAAC,QAAQ,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,KAAK,MAAM,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;SAAM,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,EAAE,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;QACxC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;gBACd,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,QAAQ,CAAC,CAAC,cAAc,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;gBAC9E,IAAI,CAAC,CAAC,cAAc;oBAAE,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC;YACpE,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,KAAK,IAAI,MAAM,EAAE,CAAC,CAAC;YACzD,CAAC;QACH,CAAC;IACH,CAAC;SAAM,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,MAAM,mBAAmB,EAAE,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;QACxC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,KAAK,IAAI,UAAU,EAAE,CAAC,CAAC;QACpG,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,+BAA+B,GAAG,EAAE,CAAC,CAAC;QACpD,OAAO,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;QACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1371,6 +1371,33 @@ async function cmdStart() {
|
|
|
1371
1371
|
}));
|
|
1372
1372
|
});
|
|
1373
1373
|
}
|
|
1374
|
+
// V1.4 — Agent Forcing auto-inject (Eric 反馈: install 时就该写 forcing block)
|
|
1375
|
+
// 解决 agent (尤其 MiniMax 类弱 instruction following) 不调 SkillFM MCP tool 的核心问题
|
|
1376
|
+
// 检测各 harness workspace files + 写 SKILLFM-AGENT-GUIDE marker block
|
|
1377
|
+
// 已注入的会 detect + skip / 升级时 replace block
|
|
1378
|
+
// fire-and-forget; 失败不阻塞 sidecar
|
|
1379
|
+
void (async () => {
|
|
1380
|
+
try {
|
|
1381
|
+
const { injectAllDetected } = await import('./agent-forcing/index.js');
|
|
1382
|
+
const results = await injectAllDetected({
|
|
1383
|
+
sidecar_url: url,
|
|
1384
|
+
version: PKG_VERSION,
|
|
1385
|
+
});
|
|
1386
|
+
const applied = results.filter((r) => r.applied);
|
|
1387
|
+
if (applied.length > 0) {
|
|
1388
|
+
console.error(JSON.stringify({
|
|
1389
|
+
ok: true,
|
|
1390
|
+
agent_forcing_injected: applied.map((r) => ({ harness: r.harness, path: r.inject_path })),
|
|
1391
|
+
}));
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
catch (err) {
|
|
1395
|
+
console.error(JSON.stringify({
|
|
1396
|
+
ok: false,
|
|
1397
|
+
agent_forcing_failed: err.message,
|
|
1398
|
+
}));
|
|
1399
|
+
}
|
|
1400
|
+
})();
|
|
1374
1401
|
const shutdown = () => {
|
|
1375
1402
|
deleteLocalSettings();
|
|
1376
1403
|
server.close(() => process.exit(0));
|
|
@@ -1516,6 +1543,20 @@ const main = async () => {
|
|
|
1516
1543
|
await startServer();
|
|
1517
1544
|
break;
|
|
1518
1545
|
}
|
|
1546
|
+
case 'checkup': {
|
|
1547
|
+
// V1.4 — CLI fallback (bypass agent). 用户终端直接看主入口 UX.
|
|
1548
|
+
// 即使 agent 抽风不调 MCP, 用户也能 npx skillfm-local checkup 看真数据.
|
|
1549
|
+
const { cmdCheckup } = await import('./checkup-cli.js');
|
|
1550
|
+
await cmdCheckup();
|
|
1551
|
+
break;
|
|
1552
|
+
}
|
|
1553
|
+
case 'forcing': {
|
|
1554
|
+
// V1.4 — Agent forcing 一键配 (CLI fallback)
|
|
1555
|
+
// 用户可手动 `npx skillfm-local forcing inject` / `forcing detect` / `forcing uninstall`
|
|
1556
|
+
const { cmdForcing } = await import('./forcing-cli.js');
|
|
1557
|
+
await cmdForcing();
|
|
1558
|
+
break;
|
|
1559
|
+
}
|
|
1519
1560
|
case 'skill': {
|
|
1520
1561
|
// Alias for run-skill, kept for the npx subcommand router
|
|
1521
1562
|
// (`npx -y @skillfm/local skill <slug>`).
|