ai-project-manage-cli 8.1.6 → 8.1.8
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/README.md +3 -1
- package/dist/index.js +274 -220
- package/dist/worker-script.js +315 -344
- package/package.json +1 -1
- package/template/AGENTS.webide.md +0 -28
- package/template/rules/webide_git_commit.md +0 -16
- package/template/rules/webide_merge.md +0 -16
- package/template/rules/webide_package.md +0 -70
- package/template/rules/webide_reply.md +0 -18
- package/template/rules/webide_sql_change.md +0 -28
- package/template/rules/webide_sql_execute.md +0 -29
- package/template/rules/webide_terminal.md +0 -45
- package/template/rules/webide_testcase.md +0 -47
package/dist/worker-script.js
CHANGED
|
@@ -14,6 +14,10 @@ var requestConfig = {
|
|
|
14
14
|
path: "/cli/me"
|
|
15
15
|
}
|
|
16
16
|
),
|
|
17
|
+
webideAgentConfig: defineEndpoint({
|
|
18
|
+
method: "GET",
|
|
19
|
+
path: "/cli/webide/agent-config"
|
|
20
|
+
}),
|
|
17
21
|
webideAppendMessageContent: defineEndpoint({
|
|
18
22
|
method: "PUT",
|
|
19
23
|
path: "/cli/webide/messages/content"
|
|
@@ -72,6 +76,14 @@ var requestConfig = {
|
|
|
72
76
|
method: "PUT",
|
|
73
77
|
path: "/cli/webide/plan"
|
|
74
78
|
}),
|
|
79
|
+
webideUpsertChecklist: defineEndpoint({
|
|
80
|
+
method: "PUT",
|
|
81
|
+
path: "/cli/webide/checklist"
|
|
82
|
+
}),
|
|
83
|
+
webideGetChecklist: defineEndpoint({
|
|
84
|
+
method: "GET",
|
|
85
|
+
path: "/cli/webide/checklist"
|
|
86
|
+
}),
|
|
75
87
|
webideReplaceTestCases: defineEndpoint({
|
|
76
88
|
method: "PUT",
|
|
77
89
|
path: "/cli/webide/test-cases"
|
|
@@ -317,11 +329,8 @@ function requireRemoteWorkdir(workdir) {
|
|
|
317
329
|
}
|
|
318
330
|
|
|
319
331
|
// src/utils/workspace.ts
|
|
320
|
-
import {
|
|
321
|
-
import {
|
|
322
|
-
import { fileURLToPath } from "url";
|
|
323
|
-
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
324
|
-
var CLI_TEMPLATE_DIR = resolve2(__dirname, "../template");
|
|
332
|
+
import { existsSync, mkdirSync as mkdirSync2, readdirSync, statSync } from "fs";
|
|
333
|
+
import { join as join2, resolve as resolve2 } from "path";
|
|
325
334
|
function workspaceApmDir(cwd = resolveWorkdirPath()) {
|
|
326
335
|
return resolve2(resolve2(cwd), ".apm");
|
|
327
336
|
}
|
|
@@ -372,90 +381,6 @@ async function ensureWorkspaceApmDirForInit(cwd = resolveWorkdirPath()) {
|
|
|
372
381
|
}
|
|
373
382
|
mkdirSync2(fsDir, { recursive: true });
|
|
374
383
|
}
|
|
375
|
-
var WEBIDE_AGENTS_TEMPLATE_NAME = "AGENTS.webide.md";
|
|
376
|
-
function shouldSkipTemplateEntry(name) {
|
|
377
|
-
return name === ".DS_Store" || name === "Thumbs.db";
|
|
378
|
-
}
|
|
379
|
-
function isWebIdeRuleFileName(name) {
|
|
380
|
-
return name.startsWith("webide");
|
|
381
|
-
}
|
|
382
|
-
function copyTemplateEntry(src, dest) {
|
|
383
|
-
const fsSrc = toFsPath(src);
|
|
384
|
-
const fsDest = toFsPath(dest);
|
|
385
|
-
const st = statSync(fsSrc);
|
|
386
|
-
if (st.isDirectory()) {
|
|
387
|
-
mkdirSync2(fsDest, { recursive: true });
|
|
388
|
-
for (const name of readdirSync(fsSrc)) {
|
|
389
|
-
if (shouldSkipTemplateEntry(name)) continue;
|
|
390
|
-
copyTemplateEntry(join2(src, name), join2(dest, name));
|
|
391
|
-
}
|
|
392
|
-
return;
|
|
393
|
-
}
|
|
394
|
-
if (!st.isFile()) return;
|
|
395
|
-
mkdirSync2(toFsPath(dirname(dest)), { recursive: true });
|
|
396
|
-
copyFileSync(fsSrc, fsDest);
|
|
397
|
-
}
|
|
398
|
-
function listWebIdeRuleFileNames(rulesDir) {
|
|
399
|
-
const fsRulesDir = toFsPath(rulesDir);
|
|
400
|
-
if (!existsSync(fsRulesDir) || !statSync(fsRulesDir).isDirectory()) {
|
|
401
|
-
return [];
|
|
402
|
-
}
|
|
403
|
-
return readdirSync(fsRulesDir).filter((name) => {
|
|
404
|
-
if (shouldSkipTemplateEntry(name) || !isWebIdeRuleFileName(name)) {
|
|
405
|
-
return false;
|
|
406
|
-
}
|
|
407
|
-
return statSync(toFsPath(join2(rulesDir, name))).isFile();
|
|
408
|
-
});
|
|
409
|
-
}
|
|
410
|
-
function assertWebIdeTemplateCopiedToApm(apmDir, workdir) {
|
|
411
|
-
const required = ["AGENTS.md", "rules"];
|
|
412
|
-
for (const item of required) {
|
|
413
|
-
const path3 = join2(apmDir, item);
|
|
414
|
-
if (!existsSync(toFsPath(path3))) {
|
|
415
|
-
throw new Error(`[apm] WebIDE \u521D\u59CB\u5316\u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5C11: ${path3}`);
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
const rulesDir = join2(apmDir, "rules");
|
|
419
|
-
const ruleNames = listWebIdeRuleFileNames(rulesDir);
|
|
420
|
-
if (ruleNames.length === 0) {
|
|
421
|
-
throw new Error(`[apm] WebIDE \u521D\u59CB\u5316\u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5C11 webide \u89C4\u5219: ${rulesDir}`);
|
|
422
|
-
}
|
|
423
|
-
const leakedRules = join2(workdir, "rules");
|
|
424
|
-
const apmRules = join2(apmDir, "rules");
|
|
425
|
-
if (existsSync(toFsPath(leakedRules)) && !existsSync(toFsPath(join2(apmRules, "webide_reply.md")))) {
|
|
426
|
-
throw new Error(
|
|
427
|
-
`[apm] \u6A21\u677F\u88AB\u590D\u5236\u5230\u9519\u8BEF\u4F4D\u7F6E: ${leakedRules}\uFF08\u5E94\u5728 ${apmRules}\uFF09`
|
|
428
|
-
);
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
async function copyWebIdeTemplateFiles(targetDir, workdir = resolveWorkdirPath()) {
|
|
432
|
-
const resolvedTarget = resolve2(targetDir);
|
|
433
|
-
const templateDir = resolve2(CLI_TEMPLATE_DIR);
|
|
434
|
-
const fsTemplateDir = toFsPath(templateDir);
|
|
435
|
-
if (!existsSync(fsTemplateDir) || !statSync(fsTemplateDir).isDirectory()) {
|
|
436
|
-
throw new Error(`[apm] \u672A\u627E\u5230 CLI \u6A21\u677F\u76EE\u5F55: ${templateDir}`);
|
|
437
|
-
}
|
|
438
|
-
const agentsSrc = join2(templateDir, WEBIDE_AGENTS_TEMPLATE_NAME);
|
|
439
|
-
if (!existsSync(toFsPath(agentsSrc))) {
|
|
440
|
-
throw new Error(`[apm] \u672A\u627E\u5230 WebIDE \u6307\u5357: ${agentsSrc}`);
|
|
441
|
-
}
|
|
442
|
-
const rulesSrc = join2(templateDir, "rules");
|
|
443
|
-
const ruleNames = listWebIdeRuleFileNames(rulesSrc);
|
|
444
|
-
if (ruleNames.length === 0) {
|
|
445
|
-
throw new Error(`[apm] CLI \u6A21\u677F\u4E2D\u6CA1\u6709 webide \u89C4\u5219: ${rulesSrc}`);
|
|
446
|
-
}
|
|
447
|
-
mkdirSync2(toFsPath(resolvedTarget), { recursive: true });
|
|
448
|
-
copyFileSync(
|
|
449
|
-
toFsPath(agentsSrc),
|
|
450
|
-
toFsPath(join2(resolvedTarget, "AGENTS.md"))
|
|
451
|
-
);
|
|
452
|
-
const rulesDest = join2(resolvedTarget, "rules");
|
|
453
|
-
mkdirSync2(toFsPath(rulesDest), { recursive: true });
|
|
454
|
-
for (const name of ruleNames) {
|
|
455
|
-
copyTemplateEntry(join2(rulesSrc, name), join2(rulesDest, name));
|
|
456
|
-
}
|
|
457
|
-
assertWebIdeTemplateCopiedToApm(resolvedTarget, resolve2(workdir));
|
|
458
|
-
}
|
|
459
384
|
|
|
460
385
|
// src/utils/git.ts
|
|
461
386
|
import { execFile as execFile2 } from "child_process";
|
|
@@ -656,7 +581,7 @@ import {
|
|
|
656
581
|
statSync as statSync2,
|
|
657
582
|
writeFileSync as writeFileSync2
|
|
658
583
|
} from "fs";
|
|
659
|
-
import { basename, dirname
|
|
584
|
+
import { basename, dirname, join as join3, relative, resolve as resolve3 } from "path";
|
|
660
585
|
var WORKSPACE_REPOS_MANIFEST = "workspace-repos.json";
|
|
661
586
|
var WORKSPACE_REPOS_VERSION = 1;
|
|
662
587
|
var SKIP_DIR_NAMES = /* @__PURE__ */ new Set([".apm", "node_modules"]);
|
|
@@ -1499,7 +1424,7 @@ function createMergeWebIdePullRequestsTool(options) {
|
|
|
1499
1424
|
const { webideMergePullRequests } = options;
|
|
1500
1425
|
return {
|
|
1501
1426
|
MergeWebIdePullRequests: {
|
|
1502
|
-
description: "Merge all open pull requests for this WebIDE task.
|
|
1427
|
+
description: "Merge all open pull requests for this WebIDE task. During accept, call UpsertWebIdeChecklist first with the full acceptance checklist, then call this once with confirmedConflictFree=true. No baseline sync is required before merging.",
|
|
1503
1428
|
inputSchema: {
|
|
1504
1429
|
type: "object",
|
|
1505
1430
|
properties: {
|
|
@@ -1586,6 +1511,63 @@ function createUpsertWebIdePlanTool(options) {
|
|
|
1586
1511
|
}
|
|
1587
1512
|
};
|
|
1588
1513
|
}
|
|
1514
|
+
function createUpsertWebIdeChecklistTool(options) {
|
|
1515
|
+
const { webideUpsertChecklist } = options;
|
|
1516
|
+
return {
|
|
1517
|
+
UpsertWebIdeChecklist: {
|
|
1518
|
+
description: "Persist or replace the acceptance checklist markdown for this WebIDE task. Call with the full checklist (what changed, which repos/files, how to verify) before merging PRs. Use during accept so humans can review later.",
|
|
1519
|
+
inputSchema: {
|
|
1520
|
+
type: "object",
|
|
1521
|
+
properties: {
|
|
1522
|
+
content: {
|
|
1523
|
+
type: "string",
|
|
1524
|
+
description: "Full acceptance checklist in Markdown (Chinese): summary of code changes, scope by repo, key files, verification notes"
|
|
1525
|
+
}
|
|
1526
|
+
},
|
|
1527
|
+
required: ["content"]
|
|
1528
|
+
},
|
|
1529
|
+
execute: async (args) => {
|
|
1530
|
+
const content = asString(args.content);
|
|
1531
|
+
if (!content) {
|
|
1532
|
+
throw new Error("UpsertWebIdeChecklist \u7F3A\u5C11 content");
|
|
1533
|
+
}
|
|
1534
|
+
await webideUpsertChecklist({ content });
|
|
1535
|
+
return JSON.stringify({ ok: true, chars: content.length }, null, 2);
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1538
|
+
};
|
|
1539
|
+
}
|
|
1540
|
+
function createGetWebIdeChecklistTool(options) {
|
|
1541
|
+
const { boundTaskId, webideGetChecklist } = options;
|
|
1542
|
+
return {
|
|
1543
|
+
GetWebIdeChecklist: {
|
|
1544
|
+
description: "Fetch the acceptance checklist markdown for a WebIDE task by taskId. Returns content=null if none has been written yet. Use when you need to read or revise an existing checklist.",
|
|
1545
|
+
inputSchema: {
|
|
1546
|
+
type: "object",
|
|
1547
|
+
properties: {
|
|
1548
|
+
taskId: {
|
|
1549
|
+
type: "string",
|
|
1550
|
+
description: "WebIDE task id whose checklist to load"
|
|
1551
|
+
}
|
|
1552
|
+
},
|
|
1553
|
+
required: ["taskId"]
|
|
1554
|
+
},
|
|
1555
|
+
execute: async (args) => {
|
|
1556
|
+
const taskId = asString(args.taskId);
|
|
1557
|
+
if (!taskId) {
|
|
1558
|
+
throw new Error("GetWebIdeChecklist \u7F3A\u5C11 taskId");
|
|
1559
|
+
}
|
|
1560
|
+
if (taskId !== boundTaskId) {
|
|
1561
|
+
throw new Error(
|
|
1562
|
+
`GetWebIdeChecklist \u7684 taskId \u987B\u4E3A\u5F53\u524D\u4EFB\u52A1 ${boundTaskId}`
|
|
1563
|
+
);
|
|
1564
|
+
}
|
|
1565
|
+
const result = await webideGetChecklist({ taskId });
|
|
1566
|
+
return JSON.stringify(result, null, 2);
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
};
|
|
1570
|
+
}
|
|
1589
1571
|
|
|
1590
1572
|
// src/commands/connect/tools/webide-test-case-tools.ts
|
|
1591
1573
|
function asString2(value) {
|
|
@@ -1618,7 +1600,7 @@ function createUpsertWebIdeTestCasesTool(options) {
|
|
|
1618
1600
|
const { webideReplaceTestCases } = options;
|
|
1619
1601
|
return {
|
|
1620
1602
|
UpsertWebIdeTestCases: {
|
|
1621
|
-
description: "Persist generated automated test cases for this WebIDE task (full replace)
|
|
1603
|
+
description: "Persist generated automated test cases for this WebIDE task (full replace). Call once with the complete case list after reviewing the task and code changes. Does not change workflow phase.",
|
|
1622
1604
|
inputSchema: {
|
|
1623
1605
|
type: "object",
|
|
1624
1606
|
properties: {
|
|
@@ -2364,6 +2346,23 @@ function createCursorCustomTools(cfg2, options) {
|
|
|
2364
2346
|
})
|
|
2365
2347
|
);
|
|
2366
2348
|
}
|
|
2349
|
+
if (wantsTool("UpsertWebIdeChecklist", options, enablePlan)) {
|
|
2350
|
+
Object.assign(
|
|
2351
|
+
tools,
|
|
2352
|
+
createUpsertWebIdeChecklistTool({
|
|
2353
|
+
webideUpsertChecklist: (args) => cli.webideUpsertChecklist({ taskId, ...args })
|
|
2354
|
+
})
|
|
2355
|
+
);
|
|
2356
|
+
}
|
|
2357
|
+
if (wantsTool("GetWebIdeChecklist", options, enablePlan)) {
|
|
2358
|
+
Object.assign(
|
|
2359
|
+
tools,
|
|
2360
|
+
createGetWebIdeChecklistTool({
|
|
2361
|
+
boundTaskId: taskId,
|
|
2362
|
+
webideGetChecklist: (args) => cli.webideGetChecklist(args)
|
|
2363
|
+
})
|
|
2364
|
+
);
|
|
2365
|
+
}
|
|
2367
2366
|
if (wantsTool("UpsertWebIdeTestCases", options, enablePlan)) {
|
|
2368
2367
|
Object.assign(
|
|
2369
2368
|
tools,
|
|
@@ -3138,14 +3137,75 @@ function createThrottledWebIdeMessageLogSync(cfg2, ctx, onError, options) {
|
|
|
3138
3137
|
};
|
|
3139
3138
|
}
|
|
3140
3139
|
|
|
3141
|
-
// src/commands/
|
|
3142
|
-
|
|
3143
|
-
|
|
3140
|
+
// src/commands/sync-webide-agent.ts
|
|
3141
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
3142
|
+
import { join as join4 } from "path";
|
|
3143
|
+
var REVISION_FILE = ".webide-agent.json";
|
|
3144
|
+
var RULE_KEY = /^webide_[a-z0-9_]+$/;
|
|
3145
|
+
function withTrailingNewline(text) {
|
|
3146
|
+
return text.endsWith("\n") ? text : `${text}
|
|
3147
|
+
`;
|
|
3148
|
+
}
|
|
3149
|
+
function readRevision(apmDir) {
|
|
3150
|
+
const path3 = toFsPath(join4(apmDir, REVISION_FILE));
|
|
3151
|
+
if (!existsSync5(path3)) return null;
|
|
3152
|
+
try {
|
|
3153
|
+
const parsed = JSON.parse(readFileSync4(path3, "utf8"));
|
|
3154
|
+
if (parsed?.version === 1 && parsed.revision?.trim()) {
|
|
3155
|
+
return parsed.revision.trim();
|
|
3156
|
+
}
|
|
3157
|
+
} catch {
|
|
3158
|
+
return null;
|
|
3159
|
+
}
|
|
3160
|
+
return null;
|
|
3161
|
+
}
|
|
3162
|
+
function writeRevision(apmDir, revision) {
|
|
3163
|
+
writeFileSync3(
|
|
3164
|
+
toFsPath(join4(apmDir, REVISION_FILE)),
|
|
3165
|
+
`${JSON.stringify({ version: 1, revision }, null, 2)}
|
|
3166
|
+
`,
|
|
3167
|
+
"utf8"
|
|
3168
|
+
);
|
|
3169
|
+
}
|
|
3170
|
+
async function syncWebIdeAgentFiles(workdir, cfg2) {
|
|
3171
|
+
const api = createApmApiClient(cfg2);
|
|
3172
|
+
const bundle = await api.cli.webideAgentConfig();
|
|
3173
|
+
const revision = bundle.revision?.trim();
|
|
3174
|
+
if (!revision) {
|
|
3175
|
+
throw new Error("[apm] \u5E73\u53F0\u672A\u8FD4\u56DE WebIDE \u89C4\u5219\u7248\u672C");
|
|
3176
|
+
}
|
|
3144
3177
|
const apmDir = workspaceApmDir(workdir);
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3178
|
+
mkdirSync4(toFsPath(apmDir), { recursive: true });
|
|
3179
|
+
if (readRevision(apmDir) === revision) {
|
|
3180
|
+
return { revision, wrote: false, ruleCount: bundle.rules?.length ?? 0 };
|
|
3181
|
+
}
|
|
3182
|
+
const rulesDir = join4(apmDir, "rules");
|
|
3183
|
+
mkdirSync4(toFsPath(rulesDir), { recursive: true });
|
|
3184
|
+
writeFileSync3(
|
|
3185
|
+
toFsPath(join4(apmDir, "AGENTS.md")),
|
|
3186
|
+
withTrailingNewline(bundle.guide ?? ""),
|
|
3187
|
+
"utf8"
|
|
3188
|
+
);
|
|
3189
|
+
for (const rule of bundle.rules ?? []) {
|
|
3190
|
+
const key = rule.key?.trim() ?? "";
|
|
3191
|
+
if (!RULE_KEY.test(key)) {
|
|
3192
|
+
throw new Error(`[apm] \u975E\u6CD5\u89C4\u5219\u540D: ${key || "(\u7A7A)"}`);
|
|
3193
|
+
}
|
|
3194
|
+
writeFileSync3(
|
|
3195
|
+
toFsPath(join4(rulesDir, `${key}.md`)),
|
|
3196
|
+
withTrailingNewline(rule.body ?? ""),
|
|
3197
|
+
"utf8"
|
|
3198
|
+
);
|
|
3199
|
+
}
|
|
3200
|
+
writeRevision(apmDir, revision);
|
|
3201
|
+
return {
|
|
3202
|
+
revision,
|
|
3203
|
+
wrote: true,
|
|
3204
|
+
ruleCount: bundle.rules?.length ?? 0
|
|
3205
|
+
};
|
|
3148
3206
|
}
|
|
3207
|
+
|
|
3208
|
+
// src/commands/init.ts
|
|
3149
3209
|
async function ensureWorkspaceInitialized(workdir) {
|
|
3150
3210
|
if (isWorkspaceApmInitialized(workdir)) {
|
|
3151
3211
|
return { didInit: false };
|
|
@@ -3153,19 +3213,21 @@ async function ensureWorkspaceInitialized(workdir) {
|
|
|
3153
3213
|
console.log(
|
|
3154
3214
|
`[apm] \u5DE5\u4F5C\u76EE\u5F55 ${workdir} \u672A\u68C0\u6D4B\u5230\u5DF2\u521D\u59CB\u5316\u7684 .apm\uFF0C\u6B63\u5728\u6309 WebIDE \u81EA\u52A8\u521D\u59CB\u5316\u2026`
|
|
3155
3215
|
);
|
|
3156
|
-
|
|
3216
|
+
await ensureWorkspaceApmDirForInit(workdir);
|
|
3217
|
+
console.log(`[apm] \u5DF2\u521B\u5EFA\u5DE5\u4F5C\u533A\u76EE\u5F55\uFF1A${workspaceApmDir(workdir)}`);
|
|
3218
|
+
return { didInit: true };
|
|
3157
3219
|
}
|
|
3158
3220
|
|
|
3159
3221
|
// src/utils/project-documents.ts
|
|
3160
3222
|
import {
|
|
3161
|
-
existsSync as
|
|
3223
|
+
existsSync as existsSync6,
|
|
3162
3224
|
readdirSync as readdirSync3,
|
|
3163
|
-
readFileSync as
|
|
3225
|
+
readFileSync as readFileSync5,
|
|
3164
3226
|
rmSync,
|
|
3165
|
-
writeFileSync as
|
|
3227
|
+
writeFileSync as writeFileSync4
|
|
3166
3228
|
} from "fs";
|
|
3167
3229
|
import { createHash as createHash2 } from "crypto";
|
|
3168
|
-
import { dirname as
|
|
3230
|
+
import { dirname as dirname2, join as join5, relative as relative4, sep } from "path";
|
|
3169
3231
|
var MANIFEST_FILE = "manifest.json";
|
|
3170
3232
|
function normalizeProjectIdForPath(projectId) {
|
|
3171
3233
|
const id = projectId.trim();
|
|
@@ -3179,11 +3241,11 @@ function normalizeProjectIdForPath(projectId) {
|
|
|
3179
3241
|
}
|
|
3180
3242
|
function projectDocumentsDir(apmRoot, projectId) {
|
|
3181
3243
|
const id = normalizeProjectIdForPath(projectId);
|
|
3182
|
-
return
|
|
3244
|
+
return join5(apmRoot ?? workspaceApmDir(), "project", id);
|
|
3183
3245
|
}
|
|
3184
3246
|
function projectDocumentLocalPath(apmRoot, projectId, documentPath) {
|
|
3185
3247
|
const normalized = normalizeLocalDocumentPath(documentPath);
|
|
3186
|
-
return
|
|
3248
|
+
return join5(
|
|
3187
3249
|
projectDocumentsDir(apmRoot, projectId),
|
|
3188
3250
|
...normalized.split("/")
|
|
3189
3251
|
);
|
|
@@ -3203,16 +3265,16 @@ function hashLocalFileContent(content) {
|
|
|
3203
3265
|
return createHash2("sha256").update(content, "utf8").digest("hex");
|
|
3204
3266
|
}
|
|
3205
3267
|
function readLocalManifest(apmRoot, projectId) {
|
|
3206
|
-
const
|
|
3268
|
+
const manifestPath2 = join5(
|
|
3207
3269
|
projectDocumentsDir(apmRoot, projectId),
|
|
3208
3270
|
MANIFEST_FILE
|
|
3209
3271
|
);
|
|
3210
|
-
if (!
|
|
3272
|
+
if (!existsSync6(manifestPath2)) {
|
|
3211
3273
|
return null;
|
|
3212
3274
|
}
|
|
3213
3275
|
try {
|
|
3214
3276
|
return JSON.parse(
|
|
3215
|
-
|
|
3277
|
+
readFileSync5(manifestPath2, "utf8")
|
|
3216
3278
|
);
|
|
3217
3279
|
} catch {
|
|
3218
3280
|
return null;
|
|
@@ -3220,13 +3282,13 @@ function readLocalManifest(apmRoot, projectId) {
|
|
|
3220
3282
|
}
|
|
3221
3283
|
function listLocalDocumentPaths(apmRoot, projectId) {
|
|
3222
3284
|
const root = projectDocumentsDir(apmRoot, projectId);
|
|
3223
|
-
if (!
|
|
3285
|
+
if (!existsSync6(root)) {
|
|
3224
3286
|
return [];
|
|
3225
3287
|
}
|
|
3226
3288
|
const paths = [];
|
|
3227
3289
|
const walk = (dir) => {
|
|
3228
3290
|
for (const entry of readdirSync3(dir, { withFileTypes: true })) {
|
|
3229
|
-
const abs =
|
|
3291
|
+
const abs = join5(dir, entry.name);
|
|
3230
3292
|
if (entry.isDirectory()) {
|
|
3231
3293
|
walk(abs);
|
|
3232
3294
|
continue;
|
|
@@ -3345,8 +3407,8 @@ ${diagnostic ?? ""}`);
|
|
|
3345
3407
|
const absPath = toFsPath(
|
|
3346
3408
|
projectDocumentLocalPath(targetApmDir, projectId, doc.path)
|
|
3347
3409
|
);
|
|
3348
|
-
await ensureDirExists(
|
|
3349
|
-
|
|
3410
|
+
await ensureDirExists(dirname2(absPath));
|
|
3411
|
+
writeFileSync4(absPath, doc.content, "utf8");
|
|
3350
3412
|
downloaded += 1;
|
|
3351
3413
|
}
|
|
3352
3414
|
}
|
|
@@ -3355,13 +3417,13 @@ ${diagnostic ?? ""}`);
|
|
|
3355
3417
|
const absPath = toFsPath(
|
|
3356
3418
|
projectDocumentLocalPath(targetApmDir, projectId, path3)
|
|
3357
3419
|
);
|
|
3358
|
-
if (
|
|
3420
|
+
if (existsSync6(absPath)) {
|
|
3359
3421
|
rmSync(absPath, { force: true });
|
|
3360
3422
|
deleted += 1;
|
|
3361
3423
|
}
|
|
3362
3424
|
}
|
|
3363
|
-
|
|
3364
|
-
toFsPath(
|
|
3425
|
+
writeFileSync4(
|
|
3426
|
+
toFsPath(join5(docsDir, MANIFEST_FILE)),
|
|
3365
3427
|
`${JSON.stringify(remoteManifest, null, 2)}
|
|
3366
3428
|
`,
|
|
3367
3429
|
"utf8"
|
|
@@ -3404,7 +3466,7 @@ async function syncProjectDocumentsPush(cfg2, workdirPath, apmRoot, options) {
|
|
|
3404
3466
|
const absPath = toFsPath(
|
|
3405
3467
|
projectDocumentLocalPath(targetApmDir, projectId, path3)
|
|
3406
3468
|
);
|
|
3407
|
-
const content =
|
|
3469
|
+
const content = readFileSync5(absPath, "utf8");
|
|
3408
3470
|
const contentHash = hashLocalFileContent(content);
|
|
3409
3471
|
if (remoteHashByPath.get(path3) === contentHash) {
|
|
3410
3472
|
continue;
|
|
@@ -3424,71 +3486,6 @@ async function syncProjectDocumentsPush(cfg2, workdirPath, apmRoot, options) {
|
|
|
3424
3486
|
return synced;
|
|
3425
3487
|
}
|
|
3426
3488
|
|
|
3427
|
-
// src/version.ts
|
|
3428
|
-
import { readFileSync as readFileSync5 } from "fs";
|
|
3429
|
-
import { dirname as dirname4, join as join5 } from "path";
|
|
3430
|
-
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
3431
|
-
function readCliVersion() {
|
|
3432
|
-
try {
|
|
3433
|
-
const dir = dirname4(fileURLToPath2(import.meta.url));
|
|
3434
|
-
const pkgPath = join5(dir, "..", "package.json");
|
|
3435
|
-
const pkg = JSON.parse(readFileSync5(pkgPath, "utf8"));
|
|
3436
|
-
return pkg.version ?? "0.0.0";
|
|
3437
|
-
} catch {
|
|
3438
|
-
return "0.0.0";
|
|
3439
|
-
}
|
|
3440
|
-
}
|
|
3441
|
-
|
|
3442
|
-
// src/commands/connect/cli-version-sync.ts
|
|
3443
|
-
import { existsSync as existsSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
|
|
3444
|
-
import { join as join6 } from "path";
|
|
3445
|
-
var CLI_VERSION_FILE = ".cli-version.json";
|
|
3446
|
-
function manifestPath2(apmDir) {
|
|
3447
|
-
return join6(apmDir, CLI_VERSION_FILE);
|
|
3448
|
-
}
|
|
3449
|
-
function loadManifest(apmDir) {
|
|
3450
|
-
const path3 = toFsPath(manifestPath2(apmDir));
|
|
3451
|
-
if (!existsSync6(path3)) {
|
|
3452
|
-
return null;
|
|
3453
|
-
}
|
|
3454
|
-
try {
|
|
3455
|
-
const parsed = JSON.parse(
|
|
3456
|
-
readFileSync6(path3, "utf8")
|
|
3457
|
-
);
|
|
3458
|
-
if (parsed?.version === 1 && typeof parsed.cliVersion === "string" && parsed.cliVersion.trim()) {
|
|
3459
|
-
return parsed;
|
|
3460
|
-
}
|
|
3461
|
-
} catch {
|
|
3462
|
-
}
|
|
3463
|
-
return null;
|
|
3464
|
-
}
|
|
3465
|
-
function saveManifest(apmDir, cliVersion) {
|
|
3466
|
-
const manifest = { version: 1, cliVersion };
|
|
3467
|
-
writeFileSync4(
|
|
3468
|
-
toFsPath(manifestPath2(apmDir)),
|
|
3469
|
-
`${JSON.stringify(manifest, null, 2)}
|
|
3470
|
-
`,
|
|
3471
|
-
"utf8"
|
|
3472
|
-
);
|
|
3473
|
-
}
|
|
3474
|
-
var syncedInSession = /* @__PURE__ */ new Map();
|
|
3475
|
-
function shouldSyncSkillsForCliVersion(workdir, currentVersion) {
|
|
3476
|
-
const cached = syncedInSession.get(workdir);
|
|
3477
|
-
if (cached === currentVersion) {
|
|
3478
|
-
return false;
|
|
3479
|
-
}
|
|
3480
|
-
const stored = loadManifest(workspaceApmDir(workdir));
|
|
3481
|
-
if (stored?.cliVersion === currentVersion) {
|
|
3482
|
-
syncedInSession.set(workdir, currentVersion);
|
|
3483
|
-
return false;
|
|
3484
|
-
}
|
|
3485
|
-
return true;
|
|
3486
|
-
}
|
|
3487
|
-
function markSkillsSyncedForCliVersion(workdir, cliVersion) {
|
|
3488
|
-
saveManifest(workspaceApmDir(workdir), cliVersion);
|
|
3489
|
-
syncedInSession.set(workdir, cliVersion);
|
|
3490
|
-
}
|
|
3491
|
-
|
|
3492
3489
|
// src/commands/connect/upload-package-artifact.ts
|
|
3493
3490
|
import fs2 from "node:fs";
|
|
3494
3491
|
import path2 from "node:path";
|
|
@@ -3608,26 +3605,12 @@ async function handleWebIdePackage(cfg2, msg2, signal) {
|
|
|
3608
3605
|
},
|
|
3609
3606
|
(didInit) => didInit ? "\u5DF2\u521D\u59CB\u5316\u5DE5\u4F5C\u533A" : "\u5DE5\u4F5C\u533A\u5DF2\u5C31\u7EEA"
|
|
3610
3607
|
);
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
await copyWebIdeTemplateFiles(workspaceApmDir(workdir), workdir);
|
|
3618
|
-
markSkillsSyncedForCliVersion(workdir, cliVersion);
|
|
3619
|
-
return cliVersion;
|
|
3620
|
-
},
|
|
3621
|
-
(version) => `\u5DF2\u540C\u6B65\u81F3 CLI ${version}`
|
|
3622
|
-
);
|
|
3623
|
-
} else {
|
|
3624
|
-
eventSession.addCliStep(
|
|
3625
|
-
"\u540C\u6B65 WebIDE \u89C4\u5219",
|
|
3626
|
-
`\u7248\u672C\u4E00\u81F4\uFF08${cliVersion}\uFF09\uFF0C\u8DF3\u8FC7`,
|
|
3627
|
-
"skip"
|
|
3628
|
-
);
|
|
3629
|
-
await syncPrepLog();
|
|
3630
|
-
}
|
|
3608
|
+
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
3609
|
+
await runPrepStep(
|
|
3610
|
+
"\u540C\u6B65 WebIDE \u89C4\u5219",
|
|
3611
|
+
async () => syncWebIdeAgentFiles(workdir, cfg2),
|
|
3612
|
+
(result) => result.wrote ? `\u5DF2\u5199\u5165 ${result.ruleCount} \u6761\u89C4\u5219` : "\u89C4\u5219\u672A\u53D8\u5316\uFF0C\u8DF3\u8FC7"
|
|
3613
|
+
);
|
|
3631
3614
|
await runPrepStep(
|
|
3632
3615
|
"\u5DE5\u4F5C\u533A\u4ED3\u5E93\u6E05\u5355",
|
|
3633
3616
|
async () => {
|
|
@@ -3856,6 +3839,7 @@ async function handleStartProject(cfg2, msg2, signal) {
|
|
|
3856
3839
|
try {
|
|
3857
3840
|
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
3858
3841
|
await ensureWorkspaceInitialized(workdir);
|
|
3842
|
+
await syncWebIdeAgentFiles(workdir, cfg2);
|
|
3859
3843
|
const api = createApmApiClient(cfg2);
|
|
3860
3844
|
const outcome = await runCursorAgent(
|
|
3861
3845
|
cfg2,
|
|
@@ -3967,8 +3951,8 @@ async function handleStartProject(cfg2, msg2, signal) {
|
|
|
3967
3951
|
}
|
|
3968
3952
|
|
|
3969
3953
|
// src/commands/connect/webide-agent-registry.ts
|
|
3970
|
-
import { existsSync as existsSync7, mkdirSync as
|
|
3971
|
-
import { dirname as
|
|
3954
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "node:fs";
|
|
3955
|
+
import { dirname as dirname3, resolve as resolve6 } from "node:path";
|
|
3972
3956
|
function registryPath(workdir, taskId, fileName = "cursor-agent.json") {
|
|
3973
3957
|
return resolve6(workdir, ".apm", "webide", taskId, fileName);
|
|
3974
3958
|
}
|
|
@@ -3978,7 +3962,7 @@ function readRegistry(path3) {
|
|
|
3978
3962
|
return {};
|
|
3979
3963
|
}
|
|
3980
3964
|
try {
|
|
3981
|
-
const parsed = JSON.parse(
|
|
3965
|
+
const parsed = JSON.parse(readFileSync6(path3, "utf8"));
|
|
3982
3966
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
3983
3967
|
const raw = parsed;
|
|
3984
3968
|
const state = {};
|
|
@@ -4007,7 +3991,7 @@ function readRegistry(path3) {
|
|
|
4007
3991
|
return {};
|
|
4008
3992
|
}
|
|
4009
3993
|
function writeRegistry(path3, registry) {
|
|
4010
|
-
|
|
3994
|
+
mkdirSync5(dirname3(path3), { recursive: true });
|
|
4011
3995
|
writeFileSync5(path3, `${JSON.stringify(registry, null, 2)}
|
|
4012
3996
|
`, "utf8");
|
|
4013
3997
|
}
|
|
@@ -4145,100 +4129,6 @@ async function cleanWebIdeWorkspaceCache(taskId, workdir, cfg2) {
|
|
|
4145
4129
|
}
|
|
4146
4130
|
}
|
|
4147
4131
|
|
|
4148
|
-
// src/commands/connect/webide-run-action.ts
|
|
4149
|
-
function startActionForInbound(action) {
|
|
4150
|
-
switch (action) {
|
|
4151
|
-
case "request-assessment":
|
|
4152
|
-
return "start-assessment";
|
|
4153
|
-
case "request-design":
|
|
4154
|
-
case "request-revise-design":
|
|
4155
|
-
return "start-design";
|
|
4156
|
-
case "request-write-plan":
|
|
4157
|
-
case "request-revise-plan":
|
|
4158
|
-
return "start-write-plan";
|
|
4159
|
-
case "request-develop":
|
|
4160
|
-
case "skip-plan":
|
|
4161
|
-
return "start-develop";
|
|
4162
|
-
case "request-start-project":
|
|
4163
|
-
return "start-project";
|
|
4164
|
-
case "request-execute-sql":
|
|
4165
|
-
return "start-execute-sql";
|
|
4166
|
-
case "request-bugfix":
|
|
4167
|
-
return "start-bugfix";
|
|
4168
|
-
case "request-organize-code":
|
|
4169
|
-
case "request-patch":
|
|
4170
|
-
return "start-organize-code";
|
|
4171
|
-
case "request-accept":
|
|
4172
|
-
return "start-accept";
|
|
4173
|
-
default:
|
|
4174
|
-
return null;
|
|
4175
|
-
}
|
|
4176
|
-
}
|
|
4177
|
-
function completeActionForInbound(action) {
|
|
4178
|
-
switch (action) {
|
|
4179
|
-
case "request-assessment":
|
|
4180
|
-
case "confirm-assumptions":
|
|
4181
|
-
return "complete-assessment";
|
|
4182
|
-
case "request-design":
|
|
4183
|
-
case "request-revise-design":
|
|
4184
|
-
return "complete-design";
|
|
4185
|
-
case "request-write-plan":
|
|
4186
|
-
case "request-revise-plan":
|
|
4187
|
-
return "complete-write-plan";
|
|
4188
|
-
case "request-develop":
|
|
4189
|
-
case "skip-plan":
|
|
4190
|
-
return "complete-develop";
|
|
4191
|
-
case "request-start-project":
|
|
4192
|
-
return "complete-project";
|
|
4193
|
-
case "request-execute-sql":
|
|
4194
|
-
return "complete-execute-sql";
|
|
4195
|
-
case "request-bugfix":
|
|
4196
|
-
return "complete-bugfix";
|
|
4197
|
-
case "request-organize-code":
|
|
4198
|
-
case "request-patch":
|
|
4199
|
-
return "complete-organize-code";
|
|
4200
|
-
case "request-accept":
|
|
4201
|
-
return "complete-accept";
|
|
4202
|
-
default:
|
|
4203
|
-
return null;
|
|
4204
|
-
}
|
|
4205
|
-
}
|
|
4206
|
-
async function webIdeRunAction(cfg2, taskId, action, params) {
|
|
4207
|
-
const api = createApmApiClient(cfg2);
|
|
4208
|
-
await api.cli.webideRunAction({ taskId, action, params });
|
|
4209
|
-
console.log(`[apm] webide runAction ok action=${action} taskId=${taskId}`);
|
|
4210
|
-
}
|
|
4211
|
-
async function webIdeSyncTransitionPrepEvents(cfg2, taskId, startAction, prepEvents) {
|
|
4212
|
-
try {
|
|
4213
|
-
const api = createApmApiClient(cfg2);
|
|
4214
|
-
await api.cli.webideUpdateTransitionPrepEvents({
|
|
4215
|
-
taskId,
|
|
4216
|
-
startAction,
|
|
4217
|
-
prepEvents
|
|
4218
|
-
});
|
|
4219
|
-
} catch (err) {
|
|
4220
|
-
console.warn(
|
|
4221
|
-
`[apm] sync transition prepEvents failed taskId=${taskId}:`,
|
|
4222
|
-
err instanceof Error ? err.message : err
|
|
4223
|
-
);
|
|
4224
|
-
}
|
|
4225
|
-
}
|
|
4226
|
-
async function webIdeDiscardTransitionPrepDraft(cfg2, taskId, startAction) {
|
|
4227
|
-
try {
|
|
4228
|
-
const api = createApmApiClient(cfg2);
|
|
4229
|
-
await api.cli.webideUpdateTransitionPrepEvents({
|
|
4230
|
-
taskId,
|
|
4231
|
-
startAction,
|
|
4232
|
-
discardDraft: true
|
|
4233
|
-
});
|
|
4234
|
-
} catch (err) {
|
|
4235
|
-
console.warn(
|
|
4236
|
-
`[apm] discard transition prep draft failed taskId=${taskId}:`,
|
|
4237
|
-
err instanceof Error ? err.message : err
|
|
4238
|
-
);
|
|
4239
|
-
}
|
|
4240
|
-
}
|
|
4241
|
-
|
|
4242
4132
|
// src/commands/connect/webide-ask-question.ts
|
|
4243
4133
|
function asString5(value) {
|
|
4244
4134
|
return typeof value === "string" ? value.trim() : "";
|
|
@@ -4298,9 +4188,8 @@ async function fetchAssumptionAnswersAndContinueAssessment(options) {
|
|
|
4298
4188
|
resolution: row.resolution
|
|
4299
4189
|
});
|
|
4300
4190
|
}
|
|
4301
|
-
await webIdeRunAction(cfg2, taskId, "continue-assessment");
|
|
4302
4191
|
console.log(
|
|
4303
|
-
`[apm] \u5047\u8BBE\u7ED3\u679C\u5DF2\u62C9\u53D6
|
|
4192
|
+
`[apm] \u5047\u8BBE\u7ED3\u679C\u5DF2\u62C9\u53D6 taskId=${taskId} count=${answers.length}`
|
|
4304
4193
|
);
|
|
4305
4194
|
return JSON.stringify({ title, answers }, null, 2);
|
|
4306
4195
|
}
|
|
@@ -4554,8 +4443,8 @@ async function ensureWebIdePullRequests(cfg2, taskId, workdir) {
|
|
|
4554
4443
|
}
|
|
4555
4444
|
|
|
4556
4445
|
// src/commands/sync-webide-attachments.ts
|
|
4557
|
-
import { existsSync as existsSync9, readFileSync as
|
|
4558
|
-
import { join as
|
|
4446
|
+
import { existsSync as existsSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
|
|
4447
|
+
import { join as join6 } from "path";
|
|
4559
4448
|
var MANIFEST_FILE2 = ".sync-manifest.json";
|
|
4560
4449
|
async function downloadAttachment(cfg2, attachmentId) {
|
|
4561
4450
|
const base = cfg2.baseUrl.trim().replace(/\/+$/, "");
|
|
@@ -4570,14 +4459,14 @@ async function downloadAttachment(cfg2, attachmentId) {
|
|
|
4570
4459
|
}
|
|
4571
4460
|
return Buffer.from(await res.arrayBuffer());
|
|
4572
4461
|
}
|
|
4573
|
-
function
|
|
4574
|
-
const path3 =
|
|
4462
|
+
function loadManifest(dir) {
|
|
4463
|
+
const path3 = join6(dir, MANIFEST_FILE2);
|
|
4575
4464
|
if (!existsSync9(path3)) {
|
|
4576
4465
|
return { version: 1, attachments: {} };
|
|
4577
4466
|
}
|
|
4578
4467
|
try {
|
|
4579
4468
|
const parsed = JSON.parse(
|
|
4580
|
-
|
|
4469
|
+
readFileSync7(path3, "utf8")
|
|
4581
4470
|
);
|
|
4582
4471
|
if (parsed?.version === 1 && parsed.attachments && typeof parsed.attachments === "object") {
|
|
4583
4472
|
return parsed;
|
|
@@ -4586,9 +4475,9 @@ function loadManifest2(dir) {
|
|
|
4586
4475
|
}
|
|
4587
4476
|
return { version: 1, attachments: {} };
|
|
4588
4477
|
}
|
|
4589
|
-
function
|
|
4478
|
+
function saveManifest(dir, manifest) {
|
|
4590
4479
|
writeFileSync6(
|
|
4591
|
-
|
|
4480
|
+
join6(dir, MANIFEST_FILE2),
|
|
4592
4481
|
`${JSON.stringify(manifest, null, 2)}
|
|
4593
4482
|
`,
|
|
4594
4483
|
"utf8"
|
|
@@ -4603,14 +4492,14 @@ function isAttachmentUpToDate(entry, item, dest) {
|
|
|
4603
4492
|
async function syncAttachmentsToDirectory(cfg2, attachments, dir, logLabel) {
|
|
4604
4493
|
await ensureDirExists(dir);
|
|
4605
4494
|
if (attachments.length === 0) {
|
|
4606
|
-
|
|
4495
|
+
saveManifest(dir, { version: 1, attachments: {} });
|
|
4607
4496
|
return [];
|
|
4608
4497
|
}
|
|
4609
|
-
const manifest =
|
|
4498
|
+
const manifest = loadManifest(dir);
|
|
4610
4499
|
const nextManifest = { version: 1, attachments: {} };
|
|
4611
4500
|
const names = [];
|
|
4612
4501
|
for (const item of attachments) {
|
|
4613
|
-
const dest =
|
|
4502
|
+
const dest = join6(dir, item.name);
|
|
4614
4503
|
const entry = manifest.attachments[item.id];
|
|
4615
4504
|
const createdAt = item.createdAt ?? "";
|
|
4616
4505
|
names.push(item.name);
|
|
@@ -4627,7 +4516,7 @@ async function syncAttachmentsToDirectory(cfg2, attachments, dir, logLabel) {
|
|
|
4627
4516
|
};
|
|
4628
4517
|
console.log(`[apm] \u5DF2\u4E0B\u8F7D\u9644\u4EF6: ${logLabel}/${item.name}`);
|
|
4629
4518
|
}
|
|
4630
|
-
|
|
4519
|
+
saveManifest(dir, nextManifest);
|
|
4631
4520
|
return names;
|
|
4632
4521
|
}
|
|
4633
4522
|
async function syncWebIdeAttachments(cfg2, taskId, workdir, attachments) {
|
|
@@ -4642,19 +4531,19 @@ async function syncWebIdeAttachments(cfg2, taskId, workdir, attachments) {
|
|
|
4642
4531
|
|
|
4643
4532
|
// src/commands/sync-webide-design.ts
|
|
4644
4533
|
import { createHash as createHash3 } from "crypto";
|
|
4645
|
-
import { existsSync as existsSync10, readdirSync as readdirSync4, readFileSync as
|
|
4646
|
-
import { join as
|
|
4534
|
+
import { existsSync as existsSync10, readdirSync as readdirSync4, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "fs";
|
|
4535
|
+
import { join as join7 } from "path";
|
|
4647
4536
|
var MANIFEST_FILE3 = ".sync-manifest.json";
|
|
4648
4537
|
function hashBuffer(buf) {
|
|
4649
4538
|
return createHash3("sha256").update(buf).digest("hex");
|
|
4650
4539
|
}
|
|
4651
|
-
function
|
|
4652
|
-
const path3 =
|
|
4540
|
+
function loadManifest2(dir) {
|
|
4541
|
+
const path3 = join7(dir, MANIFEST_FILE3);
|
|
4653
4542
|
if (!existsSync10(path3)) {
|
|
4654
4543
|
return { version: 1, files: {} };
|
|
4655
4544
|
}
|
|
4656
4545
|
try {
|
|
4657
|
-
const parsed = JSON.parse(
|
|
4546
|
+
const parsed = JSON.parse(readFileSync8(path3, "utf8"));
|
|
4658
4547
|
if (parsed?.version === 1 && parsed.files && typeof parsed.files === "object") {
|
|
4659
4548
|
return parsed;
|
|
4660
4549
|
}
|
|
@@ -4662,9 +4551,9 @@ function loadManifest3(dir) {
|
|
|
4662
4551
|
}
|
|
4663
4552
|
return { version: 1, files: {} };
|
|
4664
4553
|
}
|
|
4665
|
-
function
|
|
4554
|
+
function saveManifest2(dir, manifest) {
|
|
4666
4555
|
writeFileSync7(
|
|
4667
|
-
|
|
4556
|
+
join7(dir, MANIFEST_FILE3),
|
|
4668
4557
|
`${JSON.stringify(manifest, null, 2)}
|
|
4669
4558
|
`,
|
|
4670
4559
|
"utf8"
|
|
@@ -4687,12 +4576,12 @@ async function downloadDesignFile(cfg2, taskId, name) {
|
|
|
4687
4576
|
async function syncWebIdeDesign(cfg2, taskId, workdir, artifacts) {
|
|
4688
4577
|
const dir = webideDesignDir(taskId, workdir);
|
|
4689
4578
|
await ensureDirExists(dir);
|
|
4690
|
-
const manifest =
|
|
4579
|
+
const manifest = loadManifest2(dir);
|
|
4691
4580
|
const synced = [];
|
|
4692
4581
|
for (const art of artifacts) {
|
|
4693
4582
|
const name = art.name?.trim();
|
|
4694
4583
|
if (!name || !name.toLowerCase().endsWith(".html")) continue;
|
|
4695
|
-
const localPath =
|
|
4584
|
+
const localPath = join7(dir, name);
|
|
4696
4585
|
const entry = manifest.files[name];
|
|
4697
4586
|
if (entry?.contentHash === art.contentHash && existsSync10(localPath)) {
|
|
4698
4587
|
continue;
|
|
@@ -4702,7 +4591,7 @@ async function syncWebIdeDesign(cfg2, taskId, workdir, artifacts) {
|
|
|
4702
4591
|
manifest.files[name] = { contentHash: hashBuffer(buf) };
|
|
4703
4592
|
synced.push(name);
|
|
4704
4593
|
}
|
|
4705
|
-
|
|
4594
|
+
saveManifest2(dir, manifest);
|
|
4706
4595
|
return synced;
|
|
4707
4596
|
}
|
|
4708
4597
|
function listLocalDesignHtmlFiles(taskId, workdir) {
|
|
@@ -4711,8 +4600,8 @@ function listLocalDesignHtmlFiles(taskId, workdir) {
|
|
|
4711
4600
|
const out = [];
|
|
4712
4601
|
for (const name of readdirSync4(dir)) {
|
|
4713
4602
|
if (!name.toLowerCase().endsWith(".html")) continue;
|
|
4714
|
-
const absPath =
|
|
4715
|
-
const buf =
|
|
4603
|
+
const absPath = join7(dir, name);
|
|
4604
|
+
const buf = readFileSync8(absPath);
|
|
4716
4605
|
if (buf.length === 0) continue;
|
|
4717
4606
|
out.push({ name, absPath, contentHash: hashBuffer(buf) });
|
|
4718
4607
|
}
|
|
@@ -4790,6 +4679,102 @@ function parseWebIdePromptPayload(content) {
|
|
|
4790
4679
|
return null;
|
|
4791
4680
|
}
|
|
4792
4681
|
|
|
4682
|
+
// src/commands/connect/webide-run-action.ts
|
|
4683
|
+
function startActionForInbound(action) {
|
|
4684
|
+
switch (action) {
|
|
4685
|
+
case "request-assessment":
|
|
4686
|
+
return "start-assessment";
|
|
4687
|
+
case "request-design":
|
|
4688
|
+
case "request-revise-design":
|
|
4689
|
+
return "start-design";
|
|
4690
|
+
case "request-write-plan":
|
|
4691
|
+
case "request-revise-plan":
|
|
4692
|
+
return "start-write-plan";
|
|
4693
|
+
case "request-develop":
|
|
4694
|
+
case "skip-plan":
|
|
4695
|
+
return "start-develop";
|
|
4696
|
+
case "request-start-project":
|
|
4697
|
+
return "start-project";
|
|
4698
|
+
case "request-execute-sql":
|
|
4699
|
+
return "start-execute-sql";
|
|
4700
|
+
case "request-bugfix":
|
|
4701
|
+
return "start-bugfix";
|
|
4702
|
+
case "request-organize-code":
|
|
4703
|
+
case "request-patch":
|
|
4704
|
+
return "start-organize-code";
|
|
4705
|
+
case "request-accept":
|
|
4706
|
+
return "start-accept";
|
|
4707
|
+
case "confirm-assumptions":
|
|
4708
|
+
return "continue-assessment";
|
|
4709
|
+
default:
|
|
4710
|
+
return null;
|
|
4711
|
+
}
|
|
4712
|
+
}
|
|
4713
|
+
function completeActionForInbound(action) {
|
|
4714
|
+
switch (action) {
|
|
4715
|
+
case "request-assessment":
|
|
4716
|
+
case "confirm-assumptions":
|
|
4717
|
+
return "complete-assessment";
|
|
4718
|
+
case "request-design":
|
|
4719
|
+
case "request-revise-design":
|
|
4720
|
+
return "complete-design";
|
|
4721
|
+
case "request-write-plan":
|
|
4722
|
+
case "request-revise-plan":
|
|
4723
|
+
return "complete-write-plan";
|
|
4724
|
+
case "request-develop":
|
|
4725
|
+
case "skip-plan":
|
|
4726
|
+
return "complete-develop";
|
|
4727
|
+
case "request-start-project":
|
|
4728
|
+
return "complete-project";
|
|
4729
|
+
case "request-execute-sql":
|
|
4730
|
+
return "complete-execute-sql";
|
|
4731
|
+
case "request-bugfix":
|
|
4732
|
+
return "complete-bugfix";
|
|
4733
|
+
case "request-organize-code":
|
|
4734
|
+
case "request-patch":
|
|
4735
|
+
return "complete-organize-code";
|
|
4736
|
+
case "request-accept":
|
|
4737
|
+
return "complete-accept";
|
|
4738
|
+
default:
|
|
4739
|
+
return null;
|
|
4740
|
+
}
|
|
4741
|
+
}
|
|
4742
|
+
async function webIdeRunAction(cfg2, taskId, action, params) {
|
|
4743
|
+
const api = createApmApiClient(cfg2);
|
|
4744
|
+
await api.cli.webideRunAction({ taskId, action, params });
|
|
4745
|
+
console.log(`[apm] webide runAction ok action=${action} taskId=${taskId}`);
|
|
4746
|
+
}
|
|
4747
|
+
async function webIdeSyncTransitionPrepEvents(cfg2, taskId, startAction, prepEvents) {
|
|
4748
|
+
try {
|
|
4749
|
+
const api = createApmApiClient(cfg2);
|
|
4750
|
+
await api.cli.webideUpdateTransitionPrepEvents({
|
|
4751
|
+
taskId,
|
|
4752
|
+
startAction,
|
|
4753
|
+
prepEvents
|
|
4754
|
+
});
|
|
4755
|
+
} catch (err) {
|
|
4756
|
+
console.warn(
|
|
4757
|
+
`[apm] sync transition prepEvents failed taskId=${taskId}:`,
|
|
4758
|
+
err instanceof Error ? err.message : err
|
|
4759
|
+
);
|
|
4760
|
+
}
|
|
4761
|
+
}
|
|
4762
|
+
async function webIdeDiscardTransitionPrepDraft(cfg2, taskId, startAction) {
|
|
4763
|
+
try {
|
|
4764
|
+
const api = createApmApiClient(cfg2);
|
|
4765
|
+
await api.cli.webideUpdateTransitionPrepEvents({
|
|
4766
|
+
taskId,
|
|
4767
|
+
startAction,
|
|
4768
|
+
discardDraft: true
|
|
4769
|
+
});
|
|
4770
|
+
} catch (err) {
|
|
4771
|
+
console.warn(
|
|
4772
|
+
`[apm] discard transition prep draft failed taskId=${taskId}:`,
|
|
4773
|
+
err instanceof Error ? err.message : err
|
|
4774
|
+
);
|
|
4775
|
+
}
|
|
4776
|
+
}
|
|
4777
|
+
|
|
4793
4778
|
// src/commands/connect/core/worker/handlers/webide-message.ts
|
|
4794
4779
|
var WEBIDE_CODE_CHANGE_ACTIONS = /* @__PURE__ */ new Set([
|
|
4795
4780
|
"skip-plan",
|
|
@@ -4899,26 +4884,12 @@ async function handleWebIdeInboundMessage(cfg2, msg2, signal) {
|
|
|
4899
4884
|
},
|
|
4900
4885
|
(didInit) => didInit ? "\u5DF2\u521D\u59CB\u5316\u5DE5\u4F5C\u533A" : "\u5DE5\u4F5C\u533A\u5DF2\u5C31\u7EEA"
|
|
4901
4886
|
);
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
4908
|
-
await copyWebIdeTemplateFiles(workspaceApmDir(workdir), workdir);
|
|
4909
|
-
markSkillsSyncedForCliVersion(workdir, cliVersion);
|
|
4910
|
-
return cliVersion;
|
|
4911
|
-
},
|
|
4912
|
-
(version) => `\u5DF2\u540C\u6B65\u81F3 CLI ${version}`
|
|
4913
|
-
);
|
|
4914
|
-
} else {
|
|
4915
|
-
eventSession.addCliStep(
|
|
4916
|
-
"\u540C\u6B65 WebIDE \u89C4\u5219",
|
|
4917
|
-
`\u7248\u672C\u4E00\u81F4\uFF08${cliVersion}\uFF09\uFF0C\u8DF3\u8FC7`,
|
|
4918
|
-
"skip"
|
|
4919
|
-
);
|
|
4920
|
-
await syncPrepLog();
|
|
4921
|
-
}
|
|
4887
|
+
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
4888
|
+
await runPrepStep(
|
|
4889
|
+
"\u540C\u6B65 WebIDE \u89C4\u5219",
|
|
4890
|
+
async () => syncWebIdeAgentFiles(workdir, cfg2),
|
|
4891
|
+
(result) => result.wrote ? `\u5DF2\u5199\u5165 ${result.ruleCount} \u6761\u89C4\u5219` : "\u89C4\u5219\u672A\u53D8\u5316\uFF0C\u8DF3\u8FC7"
|
|
4892
|
+
);
|
|
4922
4893
|
await runPrepStep(
|
|
4923
4894
|
"\u5DE5\u4F5C\u533A\u4ED3\u5E93\u6E05\u5355",
|
|
4924
4895
|
async () => {
|