ai-project-manage-cli 8.0.17 → 8.0.18
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/index.js +8 -0
- package/dist/webide-message-worker.js +277 -45
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -142,6 +142,14 @@ var init_request_config = __esm({
|
|
|
142
142
|
method: "GET",
|
|
143
143
|
path: "/cli/webide/attachments"
|
|
144
144
|
}),
|
|
145
|
+
webideListDesignArtifacts: defineEndpoint({
|
|
146
|
+
method: "GET",
|
|
147
|
+
path: "/cli/webide/design-artifacts"
|
|
148
|
+
}),
|
|
149
|
+
webideRegisterDesignArtifacts: defineEndpoint({
|
|
150
|
+
method: "PUT",
|
|
151
|
+
path: "/cli/webide/design-artifacts"
|
|
152
|
+
}),
|
|
145
153
|
webideRecommendPlan: defineEndpoint({
|
|
146
154
|
method: "PUT",
|
|
147
155
|
path: "/cli/webide/plan-recommendation"
|
|
@@ -46,6 +46,14 @@ var requestConfig = {
|
|
|
46
46
|
method: "GET",
|
|
47
47
|
path: "/cli/webide/attachments"
|
|
48
48
|
}),
|
|
49
|
+
webideListDesignArtifacts: defineEndpoint({
|
|
50
|
+
method: "GET",
|
|
51
|
+
path: "/cli/webide/design-artifacts"
|
|
52
|
+
}),
|
|
53
|
+
webideRegisterDesignArtifacts: defineEndpoint({
|
|
54
|
+
method: "PUT",
|
|
55
|
+
path: "/cli/webide/design-artifacts"
|
|
56
|
+
}),
|
|
49
57
|
webideRecommendPlan: defineEndpoint({
|
|
50
58
|
method: "PUT",
|
|
51
59
|
path: "/cli/webide/plan-recommendation"
|
|
@@ -263,12 +271,16 @@ function isWorkspaceApmInitialized(workdir) {
|
|
|
263
271
|
}
|
|
264
272
|
var WEBIDE_SUBDIR = "webide";
|
|
265
273
|
var WEBIDE_ATTACHMENTS_SUBDIR = "attachments";
|
|
274
|
+
var WEBIDE_DESIGN_SUBDIR = "design";
|
|
266
275
|
function webideTaskDir(taskId, workdir) {
|
|
267
276
|
return join2(workdir, ".apm", WEBIDE_SUBDIR, taskId);
|
|
268
277
|
}
|
|
269
278
|
function webideAttachmentsDir(taskId, workdir) {
|
|
270
279
|
return join2(webideTaskDir(taskId, workdir), WEBIDE_ATTACHMENTS_SUBDIR);
|
|
271
280
|
}
|
|
281
|
+
function webideDesignDir(taskId, workdir) {
|
|
282
|
+
return join2(webideTaskDir(taskId, workdir), WEBIDE_DESIGN_SUBDIR);
|
|
283
|
+
}
|
|
272
284
|
async function ensureLoggedConfig() {
|
|
273
285
|
const cfg = await ensureApmConfig();
|
|
274
286
|
if (!resolveApiKey(cfg)) {
|
|
@@ -2563,9 +2575,10 @@ async function runCursorAgent(cfg, ctx, options) {
|
|
|
2563
2575
|
// src/commands/connect/webide-agent-registry.ts
|
|
2564
2576
|
import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
2565
2577
|
import { dirname as dirname3, resolve as resolve6 } from "node:path";
|
|
2566
|
-
function registryPath(workdir, taskId) {
|
|
2567
|
-
return resolve6(workdir, ".apm", "webide", taskId,
|
|
2578
|
+
function registryPath(workdir, taskId, fileName = "cursor-agent.json") {
|
|
2579
|
+
return resolve6(workdir, ".apm", "webide", taskId, fileName);
|
|
2568
2580
|
}
|
|
2581
|
+
var DESIGN_AGENT_FILE = "design-agent.json";
|
|
2569
2582
|
function readRegistry(path3) {
|
|
2570
2583
|
if (!existsSync5(path3)) {
|
|
2571
2584
|
return {};
|
|
@@ -2645,6 +2658,33 @@ function clearWebIdeAgentId(workdir, taskId) {
|
|
|
2645
2658
|
if (!existsSync5(path3)) return;
|
|
2646
2659
|
syncWebIdeTaskState(workdir, taskId, { agentId: "" });
|
|
2647
2660
|
}
|
|
2661
|
+
function loadWebIdeDesignAgentId(workdir, taskId) {
|
|
2662
|
+
return readRegistry(registryPath(workdir, taskId, DESIGN_AGENT_FILE)).agentId;
|
|
2663
|
+
}
|
|
2664
|
+
function saveWebIdeDesignAgentId(workdir, taskId, agentId) {
|
|
2665
|
+
const trimmedTaskId = taskId.trim();
|
|
2666
|
+
if (!trimmedTaskId) return;
|
|
2667
|
+
const path3 = registryPath(workdir, trimmedTaskId, DESIGN_AGENT_FILE);
|
|
2668
|
+
const current = readRegistry(path3);
|
|
2669
|
+
writeRegistry(path3, {
|
|
2670
|
+
...current,
|
|
2671
|
+
taskId: trimmedTaskId,
|
|
2672
|
+
agentId: agentId.trim() || void 0,
|
|
2673
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2674
|
+
});
|
|
2675
|
+
}
|
|
2676
|
+
function clearWebIdeDesignAgentId(workdir, taskId) {
|
|
2677
|
+
const path3 = registryPath(workdir, taskId, DESIGN_AGENT_FILE);
|
|
2678
|
+
if (!existsSync5(path3)) return;
|
|
2679
|
+
const current = readRegistry(path3);
|
|
2680
|
+
const next = { ...current };
|
|
2681
|
+
delete next.agentId;
|
|
2682
|
+
writeRegistry(path3, {
|
|
2683
|
+
...next,
|
|
2684
|
+
taskId: taskId.trim(),
|
|
2685
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2686
|
+
});
|
|
2687
|
+
}
|
|
2648
2688
|
|
|
2649
2689
|
// src/commands/clean-webide-cache.ts
|
|
2650
2690
|
import { existsSync as existsSync6, rmSync } from "node:fs";
|
|
@@ -3314,17 +3354,149 @@ async function syncWebIdeAttachments(cfg, taskId, workdir, attachments) {
|
|
|
3314
3354
|
);
|
|
3315
3355
|
}
|
|
3316
3356
|
|
|
3357
|
+
// src/commands/sync-webide-design.ts
|
|
3358
|
+
import { createHash as createHash2 } from "crypto";
|
|
3359
|
+
import { existsSync as existsSync8, readdirSync as readdirSync3, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "fs";
|
|
3360
|
+
import { join as join6 } from "path";
|
|
3361
|
+
var MANIFEST_FILE2 = ".sync-manifest.json";
|
|
3362
|
+
function hashBuffer(buf) {
|
|
3363
|
+
return createHash2("sha256").update(buf).digest("hex");
|
|
3364
|
+
}
|
|
3365
|
+
function loadManifest2(dir) {
|
|
3366
|
+
const path3 = join6(dir, MANIFEST_FILE2);
|
|
3367
|
+
if (!existsSync8(path3)) {
|
|
3368
|
+
return { version: 1, files: {} };
|
|
3369
|
+
}
|
|
3370
|
+
try {
|
|
3371
|
+
const parsed = JSON.parse(readFileSync7(path3, "utf8"));
|
|
3372
|
+
if (parsed?.version === 1 && parsed.files && typeof parsed.files === "object") {
|
|
3373
|
+
return parsed;
|
|
3374
|
+
}
|
|
3375
|
+
} catch {
|
|
3376
|
+
}
|
|
3377
|
+
return { version: 1, files: {} };
|
|
3378
|
+
}
|
|
3379
|
+
function saveManifest2(dir, manifest) {
|
|
3380
|
+
writeFileSync5(
|
|
3381
|
+
join6(dir, MANIFEST_FILE2),
|
|
3382
|
+
`${JSON.stringify(manifest, null, 2)}
|
|
3383
|
+
`,
|
|
3384
|
+
"utf8"
|
|
3385
|
+
);
|
|
3386
|
+
}
|
|
3387
|
+
async function downloadDesignFile(cfg, taskId, name) {
|
|
3388
|
+
const base = cfg.baseUrl.trim().replace(/\/+$/, "");
|
|
3389
|
+
const apiKey = resolveApiKey(cfg);
|
|
3390
|
+
const params = new URLSearchParams({ taskId, name });
|
|
3391
|
+
if (apiKey) params.set("apiKey", apiKey);
|
|
3392
|
+
const url = `${base}/api/v1/cli/webide/design-artifacts/file?${params}`;
|
|
3393
|
+
const res = await fetch(url);
|
|
3394
|
+
if (!res.ok) {
|
|
3395
|
+
throw new Error(
|
|
3396
|
+
`[apm] \u4E0B\u8F7D\u8BBE\u8BA1\u6587\u4EF6\u5931\u8D25 (${res.status}): taskId=${taskId} name=${name}`
|
|
3397
|
+
);
|
|
3398
|
+
}
|
|
3399
|
+
return Buffer.from(await res.arrayBuffer());
|
|
3400
|
+
}
|
|
3401
|
+
async function syncWebIdeDesign(cfg, taskId, workdir, artifacts) {
|
|
3402
|
+
const dir = webideDesignDir(taskId, workdir);
|
|
3403
|
+
await ensureDirExists(dir);
|
|
3404
|
+
const manifest = loadManifest2(dir);
|
|
3405
|
+
const synced = [];
|
|
3406
|
+
for (const art of artifacts) {
|
|
3407
|
+
const name = art.name?.trim();
|
|
3408
|
+
if (!name || !name.toLowerCase().endsWith(".html")) continue;
|
|
3409
|
+
const localPath = join6(dir, name);
|
|
3410
|
+
const entry = manifest.files[name];
|
|
3411
|
+
if (entry?.contentHash === art.contentHash && existsSync8(localPath)) {
|
|
3412
|
+
continue;
|
|
3413
|
+
}
|
|
3414
|
+
const buf = await downloadDesignFile(cfg, taskId, name);
|
|
3415
|
+
writeFileSync5(localPath, buf);
|
|
3416
|
+
manifest.files[name] = { contentHash: hashBuffer(buf) };
|
|
3417
|
+
synced.push(name);
|
|
3418
|
+
}
|
|
3419
|
+
saveManifest2(dir, manifest);
|
|
3420
|
+
return synced;
|
|
3421
|
+
}
|
|
3422
|
+
function listLocalDesignHtmlFiles(taskId, workdir) {
|
|
3423
|
+
const dir = webideDesignDir(taskId, workdir);
|
|
3424
|
+
if (!existsSync8(dir)) return [];
|
|
3425
|
+
const out = [];
|
|
3426
|
+
for (const name of readdirSync3(dir)) {
|
|
3427
|
+
if (!name.toLowerCase().endsWith(".html")) continue;
|
|
3428
|
+
const absPath = join6(dir, name);
|
|
3429
|
+
const buf = readFileSync7(absPath);
|
|
3430
|
+
if (buf.length === 0) continue;
|
|
3431
|
+
out.push({ name, absPath, contentHash: hashBuffer(buf) });
|
|
3432
|
+
}
|
|
3433
|
+
return out;
|
|
3434
|
+
}
|
|
3435
|
+
|
|
3436
|
+
// src/opc-shared-types.ts
|
|
3437
|
+
function webIdeDesignObjectKey(taskId, fileName) {
|
|
3438
|
+
const safe = fileName.replace(/[/\\:*?"<>|]/g, "_").trim() || "index.html";
|
|
3439
|
+
return `tasks/${taskId.trim()}/design/${safe}`;
|
|
3440
|
+
}
|
|
3441
|
+
|
|
3442
|
+
// src/commands/connect/upload-webide-design.ts
|
|
3443
|
+
async function uploadWebIdeDesignArtifacts(cfg, taskId, workdir) {
|
|
3444
|
+
const locals = listLocalDesignHtmlFiles(taskId, workdir);
|
|
3445
|
+
if (locals.length === 0) {
|
|
3446
|
+
throw new Error(
|
|
3447
|
+
`\u8BBE\u8BA1\u76EE\u5F55\u65E0 HTML \u4EA7\u7269\uFF1A.apm/webide/${taskId}/design/\uFF08\u8BF7\u5199\u5165\u81F3\u5C11\u4E00\u4EFD .html\uFF09`
|
|
3448
|
+
);
|
|
3449
|
+
}
|
|
3450
|
+
const api = createApmApiClient(cfg);
|
|
3451
|
+
const remote = await api.cli.webideListDesignArtifacts({ taskId }) ?? [];
|
|
3452
|
+
const remoteByName = new Map(
|
|
3453
|
+
remote.map((r) => [r.name, r])
|
|
3454
|
+
);
|
|
3455
|
+
const { client, bucket } = await createApmLogMinioClient(cfg);
|
|
3456
|
+
await client.ensureBucket(bucket);
|
|
3457
|
+
let uploaded = 0;
|
|
3458
|
+
let skipped = 0;
|
|
3459
|
+
const artifacts = [];
|
|
3460
|
+
for (const file of locals) {
|
|
3461
|
+
const objectKey = webIdeDesignObjectKey(taskId, file.name);
|
|
3462
|
+
const prev = remoteByName.get(file.name);
|
|
3463
|
+
if (prev?.contentHash === file.contentHash) {
|
|
3464
|
+
skipped += 1;
|
|
3465
|
+
artifacts.push({
|
|
3466
|
+
name: file.name,
|
|
3467
|
+
objectKey: prev.objectKey || objectKey,
|
|
3468
|
+
contentHash: file.contentHash
|
|
3469
|
+
});
|
|
3470
|
+
continue;
|
|
3471
|
+
}
|
|
3472
|
+
await client.fPutObject(bucket, objectKey, file.absPath, {
|
|
3473
|
+
"Content-Type": "text/html; charset=utf-8"
|
|
3474
|
+
});
|
|
3475
|
+
uploaded += 1;
|
|
3476
|
+
artifacts.push({
|
|
3477
|
+
name: file.name,
|
|
3478
|
+
objectKey,
|
|
3479
|
+
contentHash: file.contentHash
|
|
3480
|
+
});
|
|
3481
|
+
}
|
|
3482
|
+
await api.cli.webideRegisterDesignArtifacts({
|
|
3483
|
+
taskId,
|
|
3484
|
+
artifacts
|
|
3485
|
+
});
|
|
3486
|
+
return { uploaded, skipped, artifacts };
|
|
3487
|
+
}
|
|
3488
|
+
|
|
3317
3489
|
// src/utils/project-documents.ts
|
|
3318
3490
|
import {
|
|
3319
|
-
existsSync as
|
|
3320
|
-
readdirSync as
|
|
3321
|
-
readFileSync as
|
|
3491
|
+
existsSync as existsSync9,
|
|
3492
|
+
readdirSync as readdirSync4,
|
|
3493
|
+
readFileSync as readFileSync8,
|
|
3322
3494
|
rmSync as rmSync2,
|
|
3323
|
-
writeFileSync as
|
|
3495
|
+
writeFileSync as writeFileSync6
|
|
3324
3496
|
} from "fs";
|
|
3325
|
-
import { createHash as
|
|
3326
|
-
import { dirname as dirname5, join as
|
|
3327
|
-
var
|
|
3497
|
+
import { createHash as createHash3 } from "crypto";
|
|
3498
|
+
import { dirname as dirname5, join as join7, relative as relative4, sep } from "path";
|
|
3499
|
+
var MANIFEST_FILE3 = "manifest.json";
|
|
3328
3500
|
function normalizeProjectIdForPath(projectId) {
|
|
3329
3501
|
const id = projectId.trim();
|
|
3330
3502
|
if (!id) {
|
|
@@ -3337,11 +3509,11 @@ function normalizeProjectIdForPath(projectId) {
|
|
|
3337
3509
|
}
|
|
3338
3510
|
function projectDocumentsDir(apmRoot, projectId) {
|
|
3339
3511
|
const id = normalizeProjectIdForPath(projectId);
|
|
3340
|
-
return
|
|
3512
|
+
return join7(apmRoot ?? workspaceApmDir(), "project", id);
|
|
3341
3513
|
}
|
|
3342
3514
|
function projectDocumentLocalPath(apmRoot, projectId, documentPath) {
|
|
3343
3515
|
const normalized = normalizeLocalDocumentPath(documentPath);
|
|
3344
|
-
return
|
|
3516
|
+
return join7(
|
|
3345
3517
|
projectDocumentsDir(apmRoot, projectId),
|
|
3346
3518
|
...normalized.split("/")
|
|
3347
3519
|
);
|
|
@@ -3358,19 +3530,19 @@ function normalizeLocalDocumentPath(path3) {
|
|
|
3358
3530
|
return segments.join("/");
|
|
3359
3531
|
}
|
|
3360
3532
|
function hashLocalFileContent(content) {
|
|
3361
|
-
return
|
|
3533
|
+
return createHash3("sha256").update(content, "utf8").digest("hex");
|
|
3362
3534
|
}
|
|
3363
3535
|
function readLocalManifest(apmRoot, projectId) {
|
|
3364
|
-
const manifestPath3 =
|
|
3536
|
+
const manifestPath3 = join7(
|
|
3365
3537
|
projectDocumentsDir(apmRoot, projectId),
|
|
3366
|
-
|
|
3538
|
+
MANIFEST_FILE3
|
|
3367
3539
|
);
|
|
3368
|
-
if (!
|
|
3540
|
+
if (!existsSync9(manifestPath3)) {
|
|
3369
3541
|
return null;
|
|
3370
3542
|
}
|
|
3371
3543
|
try {
|
|
3372
3544
|
return JSON.parse(
|
|
3373
|
-
|
|
3545
|
+
readFileSync8(manifestPath3, "utf8")
|
|
3374
3546
|
);
|
|
3375
3547
|
} catch {
|
|
3376
3548
|
return null;
|
|
@@ -3378,18 +3550,18 @@ function readLocalManifest(apmRoot, projectId) {
|
|
|
3378
3550
|
}
|
|
3379
3551
|
function listLocalDocumentPaths(apmRoot, projectId) {
|
|
3380
3552
|
const root = projectDocumentsDir(apmRoot, projectId);
|
|
3381
|
-
if (!
|
|
3553
|
+
if (!existsSync9(root)) {
|
|
3382
3554
|
return [];
|
|
3383
3555
|
}
|
|
3384
3556
|
const paths = [];
|
|
3385
3557
|
const walk = (dir) => {
|
|
3386
|
-
for (const entry of
|
|
3387
|
-
const abs =
|
|
3558
|
+
for (const entry of readdirSync4(dir, { withFileTypes: true })) {
|
|
3559
|
+
const abs = join7(dir, entry.name);
|
|
3388
3560
|
if (entry.isDirectory()) {
|
|
3389
3561
|
walk(abs);
|
|
3390
3562
|
continue;
|
|
3391
3563
|
}
|
|
3392
|
-
if (entry.isFile() && entry.name ===
|
|
3564
|
+
if (entry.isFile() && entry.name === MANIFEST_FILE3) {
|
|
3393
3565
|
continue;
|
|
3394
3566
|
}
|
|
3395
3567
|
const rel = relative4(root, abs).split(sep).join("/");
|
|
@@ -3504,7 +3676,7 @@ ${diagnostic ?? ""}`);
|
|
|
3504
3676
|
projectDocumentLocalPath(targetApmDir, projectId, doc.path)
|
|
3505
3677
|
);
|
|
3506
3678
|
await ensureDirExists(dirname5(absPath));
|
|
3507
|
-
|
|
3679
|
+
writeFileSync6(absPath, doc.content, "utf8");
|
|
3508
3680
|
downloaded += 1;
|
|
3509
3681
|
}
|
|
3510
3682
|
}
|
|
@@ -3513,13 +3685,13 @@ ${diagnostic ?? ""}`);
|
|
|
3513
3685
|
const absPath = toFsPath(
|
|
3514
3686
|
projectDocumentLocalPath(targetApmDir, projectId, path3)
|
|
3515
3687
|
);
|
|
3516
|
-
if (
|
|
3688
|
+
if (existsSync9(absPath)) {
|
|
3517
3689
|
rmSync2(absPath, { force: true });
|
|
3518
3690
|
deleted += 1;
|
|
3519
3691
|
}
|
|
3520
3692
|
}
|
|
3521
|
-
|
|
3522
|
-
toFsPath(
|
|
3693
|
+
writeFileSync6(
|
|
3694
|
+
toFsPath(join7(docsDir, MANIFEST_FILE3)),
|
|
3523
3695
|
`${JSON.stringify(remoteManifest, null, 2)}
|
|
3524
3696
|
`,
|
|
3525
3697
|
"utf8"
|
|
@@ -3562,7 +3734,7 @@ async function syncProjectDocumentsPush(cfg, workdirPath, apmRoot, options) {
|
|
|
3562
3734
|
const absPath = toFsPath(
|
|
3563
3735
|
projectDocumentLocalPath(targetApmDir, projectId, path3)
|
|
3564
3736
|
);
|
|
3565
|
-
const content =
|
|
3737
|
+
const content = readFileSync8(absPath, "utf8");
|
|
3566
3738
|
const contentHash = hashLocalFileContent(content);
|
|
3567
3739
|
if (remoteHashByPath.get(path3) === contentHash) {
|
|
3568
3740
|
continue;
|
|
@@ -3583,20 +3755,20 @@ async function syncProjectDocumentsPush(cfg, workdirPath, apmRoot, options) {
|
|
|
3583
3755
|
}
|
|
3584
3756
|
|
|
3585
3757
|
// src/commands/connect/cli-version-sync.ts
|
|
3586
|
-
import { existsSync as
|
|
3587
|
-
import { join as
|
|
3758
|
+
import { existsSync as existsSync10, readFileSync as readFileSync9, writeFileSync as writeFileSync7 } from "fs";
|
|
3759
|
+
import { join as join8 } from "path";
|
|
3588
3760
|
var CLI_VERSION_FILE = ".cli-version.json";
|
|
3589
3761
|
function manifestPath2(apmDir) {
|
|
3590
|
-
return
|
|
3762
|
+
return join8(apmDir, CLI_VERSION_FILE);
|
|
3591
3763
|
}
|
|
3592
|
-
function
|
|
3764
|
+
function loadManifest3(apmDir) {
|
|
3593
3765
|
const path3 = toFsPath(manifestPath2(apmDir));
|
|
3594
|
-
if (!
|
|
3766
|
+
if (!existsSync10(path3)) {
|
|
3595
3767
|
return null;
|
|
3596
3768
|
}
|
|
3597
3769
|
try {
|
|
3598
3770
|
const parsed = JSON.parse(
|
|
3599
|
-
|
|
3771
|
+
readFileSync9(path3, "utf8")
|
|
3600
3772
|
);
|
|
3601
3773
|
if (parsed?.version === 1 && typeof parsed.cliVersion === "string" && parsed.cliVersion.trim()) {
|
|
3602
3774
|
return parsed;
|
|
@@ -3605,9 +3777,9 @@ function loadManifest2(apmDir) {
|
|
|
3605
3777
|
}
|
|
3606
3778
|
return null;
|
|
3607
3779
|
}
|
|
3608
|
-
function
|
|
3780
|
+
function saveManifest3(apmDir, cliVersion) {
|
|
3609
3781
|
const manifest = { version: 1, cliVersion };
|
|
3610
|
-
|
|
3782
|
+
writeFileSync7(
|
|
3611
3783
|
toFsPath(manifestPath2(apmDir)),
|
|
3612
3784
|
`${JSON.stringify(manifest, null, 2)}
|
|
3613
3785
|
`,
|
|
@@ -3620,7 +3792,7 @@ function shouldSyncSkillsForCliVersion(workdir, currentVersion) {
|
|
|
3620
3792
|
if (cached === currentVersion) {
|
|
3621
3793
|
return false;
|
|
3622
3794
|
}
|
|
3623
|
-
const stored =
|
|
3795
|
+
const stored = loadManifest3(workspaceApmDir(workdir));
|
|
3624
3796
|
if (stored?.cliVersion === currentVersion) {
|
|
3625
3797
|
syncedInSession.set(workdir, currentVersion);
|
|
3626
3798
|
return false;
|
|
@@ -3628,7 +3800,7 @@ function shouldSyncSkillsForCliVersion(workdir, currentVersion) {
|
|
|
3628
3800
|
return true;
|
|
3629
3801
|
}
|
|
3630
3802
|
function markSkillsSyncedForCliVersion(workdir, cliVersion) {
|
|
3631
|
-
|
|
3803
|
+
saveManifest3(workspaceApmDir(workdir), cliVersion);
|
|
3632
3804
|
syncedInSession.set(workdir, cliVersion);
|
|
3633
3805
|
}
|
|
3634
3806
|
|
|
@@ -3665,6 +3837,9 @@ function shouldCommitAfterWebIdeMessage(action) {
|
|
|
3665
3837
|
function isStartLocalServicesAction(action) {
|
|
3666
3838
|
return action === "enter-manual-test" || action === "skip-test";
|
|
3667
3839
|
}
|
|
3840
|
+
function isDesignAction(action) {
|
|
3841
|
+
return action === "start-design" || action === "revise-design";
|
|
3842
|
+
}
|
|
3668
3843
|
function isExecuteSqlAction(action) {
|
|
3669
3844
|
return action === "execute-sql";
|
|
3670
3845
|
}
|
|
@@ -3870,6 +4045,28 @@ async function handleWebIdeInboundMessage(cfg, msg, signal) {
|
|
|
3870
4045
|
},
|
|
3871
4046
|
(names) => names.length > 0 ? `\u5DF2\u540C\u6B65 ${names.length} \u4E2A\u9644\u4EF6` : "\u65E0\u9644\u4EF6\u6216\u540C\u6B65\u8DF3\u8FC7"
|
|
3872
4047
|
);
|
|
4048
|
+
await runPrepStep(
|
|
4049
|
+
"\u540C\u6B65\u8BBE\u8BA1\u4EA7\u7269",
|
|
4050
|
+
async () => {
|
|
4051
|
+
try {
|
|
4052
|
+
const artifacts = await api.cli.webideListDesignArtifacts({ taskId });
|
|
4053
|
+
const names = await syncWebIdeDesign(
|
|
4054
|
+
cfg,
|
|
4055
|
+
taskId,
|
|
4056
|
+
workdir,
|
|
4057
|
+
artifacts ?? []
|
|
4058
|
+
);
|
|
4059
|
+
return names;
|
|
4060
|
+
} catch (err) {
|
|
4061
|
+
console.warn(
|
|
4062
|
+
"[apm] WebIDE \u8BBE\u8BA1\u4EA7\u7269\u540C\u6B65\u5931\u8D25:",
|
|
4063
|
+
err instanceof Error ? err.message : err
|
|
4064
|
+
);
|
|
4065
|
+
return [];
|
|
4066
|
+
}
|
|
4067
|
+
},
|
|
4068
|
+
(names) => names.length > 0 ? `\u5DF2\u540C\u6B65 ${names.length} \u4E2A\u8BBE\u8BA1\u6587\u4EF6` : "\u65E0\u8BBE\u8BA1\u6587\u4EF6\u6216\u540C\u6B65\u8DF3\u8FC7"
|
|
4069
|
+
);
|
|
3873
4070
|
eventSession.addCliStep(
|
|
3874
4071
|
"\u542F\u52A8 Cursor Agent",
|
|
3875
4072
|
"\u51C6\u5907 resume/create\u2026",
|
|
@@ -3877,10 +4074,19 @@ async function handleWebIdeInboundMessage(cfg, msg, signal) {
|
|
|
3877
4074
|
);
|
|
3878
4075
|
await syncPrepLog();
|
|
3879
4076
|
const startLocalServices = isStartLocalServicesAction(msg.action);
|
|
4077
|
+
const designAction = isDesignAction(msg.action);
|
|
3880
4078
|
const executeSql = isExecuteSqlAction(msg.action);
|
|
3881
|
-
const savedAgentId = startLocalServices ? void 0 : loadWebIdeAgentId(workdir, taskId);
|
|
4079
|
+
const savedAgentId = startLocalServices ? void 0 : designAction ? loadWebIdeDesignAgentId(workdir, taskId) : loadWebIdeAgentId(workdir, taskId);
|
|
3882
4080
|
const promptPayload = executeSql ? parseWebIdePromptPayload(msg.content) : null;
|
|
3883
4081
|
const sqlExecutionId = executeSql && typeof promptPayload?.executionId === "string" ? promptPayload.executionId.trim() : void 0;
|
|
4082
|
+
const persistAgentId = (agentId) => {
|
|
4083
|
+
if (startLocalServices) return;
|
|
4084
|
+
if (designAction) {
|
|
4085
|
+
saveWebIdeDesignAgentId(workdir, taskId, agentId);
|
|
4086
|
+
} else {
|
|
4087
|
+
saveWebIdeAgentId(workdir, taskId, agentId);
|
|
4088
|
+
}
|
|
4089
|
+
};
|
|
3884
4090
|
const outcome = await runCursorAgent(
|
|
3885
4091
|
cfg,
|
|
3886
4092
|
{
|
|
@@ -3903,17 +4109,21 @@ async function handleWebIdeInboundMessage(cfg, msg, signal) {
|
|
|
3903
4109
|
signal
|
|
3904
4110
|
}),
|
|
3905
4111
|
enableAskQuestion: !startLocalServices && !executeSql,
|
|
3906
|
-
enableWebIdePlanTools: !startLocalServices && !executeSql,
|
|
4112
|
+
enableWebIdePlanTools: !startLocalServices && !executeSql && !designAction,
|
|
3907
4113
|
enablePtySessionMcp: startLocalServices,
|
|
3908
4114
|
enableMysqlTools: executeSql,
|
|
3909
4115
|
sqlExecutionId,
|
|
3910
4116
|
enableSandbox: false,
|
|
3911
|
-
onInvalidatePersistedAgentId: startLocalServices ? void 0 : () =>
|
|
4117
|
+
onInvalidatePersistedAgentId: startLocalServices ? void 0 : () => {
|
|
4118
|
+
if (designAction) {
|
|
4119
|
+
clearWebIdeDesignAgentId(workdir, taskId);
|
|
4120
|
+
} else {
|
|
4121
|
+
clearWebIdeAgentId(workdir, taskId);
|
|
4122
|
+
}
|
|
4123
|
+
},
|
|
3912
4124
|
taskId,
|
|
3913
4125
|
createRemoteLogSync: (agentId) => {
|
|
3914
|
-
|
|
3915
|
-
saveWebIdeAgentId(workdir, taskId, agentId);
|
|
3916
|
-
}
|
|
4126
|
+
persistAgentId(agentId);
|
|
3917
4127
|
logSyncRef.current = createThrottledWebIdeMessageLogSync(
|
|
3918
4128
|
cfg,
|
|
3919
4129
|
{ taskId, messageId, agentId },
|
|
@@ -3927,9 +4137,7 @@ async function handleWebIdeInboundMessage(cfg, msg, signal) {
|
|
|
3927
4137
|
return logSyncRef.current;
|
|
3928
4138
|
},
|
|
3929
4139
|
onRunStarted: async ({ agentId, runId }) => {
|
|
3930
|
-
|
|
3931
|
-
saveWebIdeAgentId(workdir, taskId, agentId);
|
|
3932
|
-
}
|
|
4140
|
+
persistAgentId(agentId);
|
|
3933
4141
|
eventSession.addCliStep(
|
|
3934
4142
|
"\u542F\u52A8 Cursor Agent",
|
|
3935
4143
|
`agentId=${agentId} runId=${runId}`,
|
|
@@ -3942,7 +4150,7 @@ async function handleWebIdeInboundMessage(cfg, msg, signal) {
|
|
|
3942
4150
|
}
|
|
3943
4151
|
);
|
|
3944
4152
|
if (!startLocalServices) {
|
|
3945
|
-
|
|
4153
|
+
persistAgentId(outcome.agentId);
|
|
3946
4154
|
}
|
|
3947
4155
|
const tokenUsage = outcome.usage != null ? {
|
|
3948
4156
|
modelId: outcome.modelId ?? (msg.model?.trim() || void 0),
|
|
@@ -4028,6 +4236,30 @@ async function handleWebIdeInboundMessage(cfg, msg, signal) {
|
|
|
4028
4236
|
);
|
|
4029
4237
|
}
|
|
4030
4238
|
}
|
|
4239
|
+
if (isDesignAction(msg.action)) {
|
|
4240
|
+
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
4241
|
+
try {
|
|
4242
|
+
const uploaded = await uploadWebIdeDesignArtifacts(
|
|
4243
|
+
cfg,
|
|
4244
|
+
taskId,
|
|
4245
|
+
workdir
|
|
4246
|
+
);
|
|
4247
|
+
console.log(
|
|
4248
|
+
`[apm] webide \u8BBE\u8BA1\u4EA7\u7269\u4E0A\u4F20 action=${msg.action} uploaded=${uploaded.uploaded} skipped=${uploaded.skipped} files=${uploaded.artifacts.map((a) => a.name).join(",")}`
|
|
4249
|
+
);
|
|
4250
|
+
} catch (err) {
|
|
4251
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
4252
|
+
await logSyncRef.current?.markRun(
|
|
4253
|
+
outcome.runId,
|
|
4254
|
+
"error",
|
|
4255
|
+
detail,
|
|
4256
|
+
tokenUsage
|
|
4257
|
+
);
|
|
4258
|
+
await setError(cfg, messageId, detail);
|
|
4259
|
+
syncLocalTaskStatus(workdir, taskId, msg, "FAILED");
|
|
4260
|
+
return;
|
|
4261
|
+
}
|
|
4262
|
+
}
|
|
4031
4263
|
if (shouldCommitAfterWebIdeMessage(msg.action)) {
|
|
4032
4264
|
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
4033
4265
|
const committed = await commitWorkspaceReposIfDirty(
|