ai-project-manage-cli 8.1.12 → 8.1.14

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 CHANGED
@@ -133,6 +133,11 @@ var requestConfig = {
133
133
  method: "PUT",
134
134
  path: "/cli/webide/transition-prep-events"
135
135
  }),
136
+ /** 「继续」开跑后挂新 runId */
137
+ webideAttachContinueRun: defineEndpoint({
138
+ method: "PUT",
139
+ path: "/cli/webide/continue-run"
140
+ }),
136
141
  webideUpsertMessageLog: defineEndpoint({
137
142
  method: "PUT",
138
143
  path: "/cli/webide/message-logs"
@@ -44,6 +44,11 @@ var requestConfig = {
44
44
  method: "PUT",
45
45
  path: "/cli/webide/transition-prep-events"
46
46
  }),
47
+ /** 「继续」开跑后挂新 runId */
48
+ webideAttachContinueRun: defineEndpoint({
49
+ method: "PUT",
50
+ path: "/cli/webide/continue-run"
51
+ }),
47
52
  webideUpsertMessageLog: defineEndpoint({
48
53
  method: "PUT",
49
54
  path: "/cli/webide/message-logs"
@@ -2468,10 +2473,76 @@ function createPtySessionMcpServers(cfg2) {
2468
2473
  }
2469
2474
 
2470
2475
  // src/commands/connect/remote-local-agent-store.ts
2476
+ import { createHash as createHash2 } from "node:crypto";
2477
+ import {
2478
+ existsSync as existsSync5,
2479
+ mkdirSync as mkdirSync4,
2480
+ readFileSync as readFileSync4,
2481
+ rmSync,
2482
+ unlinkSync,
2483
+ writeFileSync as writeFileSync3
2484
+ } from "node:fs";
2485
+ import { dirname as dirname2, join as join4 } from "node:path";
2471
2486
  var INLINE_CHECKPOINT_MAX_BYTES = 256 * 1024;
2487
+ var CHECKPOINT_CACHE_DIR = join4(APM_CONFIG_DIR, "cursor-checkpoint-cache");
2472
2488
  function checkpointObjectKey(agentId, blobId) {
2473
2489
  return `cursor-agents/${agentId}/checkpoints/${blobId}`;
2474
2490
  }
2491
+ function safeBlobFileName(blobId) {
2492
+ if (/^[a-zA-Z0-9._-]+$/.test(blobId)) return blobId;
2493
+ return createHash2("sha256").update(blobId).digest("hex");
2494
+ }
2495
+ function checkpointCachePath(agentId, blobId) {
2496
+ return join4(CHECKPOINT_CACHE_DIR, agentId, safeBlobFileName(blobId));
2497
+ }
2498
+ function checkpointCacheKey(agentId, blobId) {
2499
+ return `${agentId}\0${blobId}`;
2500
+ }
2501
+ function readLocalCheckpoint(agentId, blobId) {
2502
+ try {
2503
+ const path3 = checkpointCachePath(agentId, blobId);
2504
+ if (!existsSync5(path3)) return null;
2505
+ return new Uint8Array(readFileSync4(path3));
2506
+ } catch {
2507
+ return null;
2508
+ }
2509
+ }
2510
+ function writeLocalCheckpoint(agentId, blobId, data) {
2511
+ try {
2512
+ const path3 = checkpointCachePath(agentId, blobId);
2513
+ mkdirSync4(dirname2(path3), { recursive: true });
2514
+ writeFileSync3(path3, Buffer.from(data));
2515
+ } catch (err) {
2516
+ console.warn(
2517
+ `[apm] checkpoint \u672C\u5730\u7F13\u5B58\u5199\u5165\u5931\u8D25 agentId=${agentId} blobId=${blobId}:`,
2518
+ err instanceof Error ? err.message : err
2519
+ );
2520
+ }
2521
+ }
2522
+ function deleteLocalCheckpoint(agentId, blobId) {
2523
+ try {
2524
+ const path3 = checkpointCachePath(agentId, blobId);
2525
+ if (existsSync5(path3)) unlinkSync(path3);
2526
+ } catch {
2527
+ }
2528
+ }
2529
+ function clearLocalCheckpointCache(agentId) {
2530
+ try {
2531
+ if (agentId?.trim()) {
2532
+ const dir = join4(CHECKPOINT_CACHE_DIR, agentId.trim());
2533
+ if (existsSync5(dir)) rmSync(dir, { recursive: true, force: true });
2534
+ return;
2535
+ }
2536
+ if (existsSync5(CHECKPOINT_CACHE_DIR)) {
2537
+ rmSync(CHECKPOINT_CACHE_DIR, { recursive: true, force: true });
2538
+ }
2539
+ } catch (err) {
2540
+ console.warn(
2541
+ `[apm] \u6E05\u7406 checkpoint \u672C\u5730\u7F13\u5B58\u5931\u8D25:`,
2542
+ err instanceof Error ? err.message : err
2543
+ );
2544
+ }
2545
+ }
2475
2546
  function asCheckpointRef(value) {
2476
2547
  if (value === void 0) return void 0;
2477
2548
  if (value === null) return null;
@@ -2544,9 +2615,16 @@ function bytesToBase64(data) {
2544
2615
  function base64ToBytes(dataBase64) {
2545
2616
  return new Uint8Array(Buffer.from(dataBase64, "base64"));
2546
2617
  }
2618
+ var pendingCheckpointUploads = /* @__PURE__ */ new Map();
2619
+ async function flushPendingCheckpointUploads() {
2620
+ const pending2 = [...pendingCheckpointUploads.values()];
2621
+ if (pending2.length === 0) return;
2622
+ await Promise.allSettled(pending2);
2623
+ }
2547
2624
  function createRemoteLocalAgentStore(cfg2) {
2548
2625
  const api = createApmApiClient(cfg2);
2549
2626
  let minioCache = null;
2627
+ const memoryCheckpointCache = /* @__PURE__ */ new Map();
2550
2628
  function getMinio() {
2551
2629
  if (!minioCache) {
2552
2630
  minioCache = createApmLogMinioClient(cfg2).then(({ client, bucket }) => ({
@@ -2556,6 +2634,14 @@ function createRemoteLocalAgentStore(cfg2) {
2556
2634
  }
2557
2635
  return minioCache;
2558
2636
  }
2637
+ function rememberCheckpoint(agentId, blobId, data) {
2638
+ memoryCheckpointCache.set(checkpointCacheKey(agentId, blobId), data);
2639
+ writeLocalCheckpoint(agentId, blobId, data);
2640
+ }
2641
+ function forgetCheckpoint(agentId, blobId) {
2642
+ memoryCheckpointCache.delete(checkpointCacheKey(agentId, blobId));
2643
+ deleteLocalCheckpoint(agentId, blobId);
2644
+ }
2559
2645
  async function upsertAgent(agent) {
2560
2646
  const row = await api.cli.cursorStoreUpsertAgent({
2561
2647
  agentId: agent.agentId,
@@ -2591,7 +2677,7 @@ function createRemoteLocalAgentStore(cfg2) {
2591
2677
  });
2592
2678
  return fromApiRun(row);
2593
2679
  }
2594
- async function putCheckpoint(input) {
2680
+ async function uploadCheckpointRemote(input) {
2595
2681
  const createdAt = Date.now();
2596
2682
  if (input.data.byteLength > INLINE_CHECKPOINT_MAX_BYTES) {
2597
2683
  const { client, bucket } = await getMinio();
@@ -2616,20 +2702,56 @@ function createRemoteLocalAgentStore(cfg2) {
2616
2702
  createdAt
2617
2703
  });
2618
2704
  }
2705
+ async function putCheckpoint(input) {
2706
+ const data = new Uint8Array(input.data);
2707
+ rememberCheckpoint(input.agentId, input.blobId, data);
2708
+ const key = checkpointCacheKey(input.agentId, input.blobId);
2709
+ if (pendingCheckpointUploads.has(key)) return;
2710
+ const startedAt = Date.now();
2711
+ const uploadPromise = uploadCheckpointRemote({
2712
+ agentId: input.agentId,
2713
+ blobId: input.blobId,
2714
+ data
2715
+ }).then(() => {
2716
+ console.log(
2717
+ `[apm] checkpoint \u8FDC\u7A0B\u4E0A\u4F20\u5B8C\u6210 agentId=${input.agentId} blobId=${input.blobId} bytes=${data.byteLength} ms=${Date.now() - startedAt}`
2718
+ );
2719
+ }).catch((err) => {
2720
+ console.warn(
2721
+ `[apm] checkpoint \u8FDC\u7A0B\u4E0A\u4F20\u5931\u8D25\uFF08\u672C\u5730\u5DF2\u7F13\u5B58\uFF09 agentId=${input.agentId} blobId=${input.blobId}:`,
2722
+ err instanceof Error ? err.message : err
2723
+ );
2724
+ }).finally(() => {
2725
+ pendingCheckpointUploads.delete(key);
2726
+ });
2727
+ pendingCheckpointUploads.set(key, uploadPromise);
2728
+ }
2619
2729
  async function readCheckpointBytes(input) {
2730
+ const memKey = checkpointCacheKey(input.agentId, input.blobId);
2731
+ const cached = memoryCheckpointCache.get(memKey);
2732
+ if (cached) return cached;
2733
+ const local = readLocalCheckpoint(input.agentId, input.blobId);
2734
+ if (local) {
2735
+ memoryCheckpointCache.set(memKey, local);
2736
+ return local;
2737
+ }
2620
2738
  const row = await api.cli.cursorStoreGetCheckpoint({
2621
2739
  agentId: input.agentId,
2622
2740
  blobId: input.blobId
2623
2741
  });
2624
2742
  if (!row) return null;
2743
+ let bytes = null;
2625
2744
  if (row.dataBase64) {
2626
- return base64ToBytes(row.dataBase64);
2745
+ bytes = base64ToBytes(row.dataBase64);
2746
+ } else {
2747
+ const objectKey = row.objectKey?.trim();
2748
+ if (!objectKey) return null;
2749
+ const { client, bucket } = await getMinio();
2750
+ const buf = await client.getObjectBuffer(bucket, objectKey);
2751
+ bytes = new Uint8Array(buf);
2627
2752
  }
2628
- const objectKey = row.objectKey?.trim();
2629
- if (!objectKey) return null;
2630
- const { client, bucket } = await getMinio();
2631
- const buf = await client.getObjectBuffer(bucket, objectKey);
2632
- return new Uint8Array(buf);
2753
+ rememberCheckpoint(input.agentId, input.blobId, bytes);
2754
+ return bytes;
2633
2755
  }
2634
2756
  return {
2635
2757
  agents: {
@@ -2798,6 +2920,23 @@ function createRemoteLocalAgentStore(cfg2) {
2798
2920
  const blobIds = input.filter.blobIds?.map((id) => id.trim()).filter(Boolean);
2799
2921
  if (agentIds && agentIds.length > 0 || blobIds && blobIds.length > 0) {
2800
2922
  await api.cli.cursorStoreDeleteCheckpoints({ agentIds, blobIds });
2923
+ if (agentIds && agentIds.length > 0 && !blobIds?.length) {
2924
+ for (const id of agentIds) clearLocalCheckpointCache(id);
2925
+ } else if (agentIds && blobIds) {
2926
+ for (const id of agentIds) {
2927
+ for (const blobId of blobIds) forgetCheckpoint(id, blobId);
2928
+ }
2929
+ } else if (blobIds) {
2930
+ for (const blobId of blobIds) {
2931
+ for (const key of memoryCheckpointCache.keys()) {
2932
+ const sep2 = key.indexOf("\0");
2933
+ if (sep2 < 0) continue;
2934
+ if (key.slice(sep2 + 1) === blobId) {
2935
+ forgetCheckpoint(key.slice(0, sep2), blobId);
2936
+ }
2937
+ }
2938
+ }
2939
+ }
2801
2940
  return;
2802
2941
  }
2803
2942
  let cursor;
@@ -2814,6 +2953,8 @@ function createRemoteLocalAgentStore(cfg2) {
2814
2953
  if (!page.nextCursor) break;
2815
2954
  cursor = page.nextCursor;
2816
2955
  }
2956
+ clearLocalCheckpointCache();
2957
+ memoryCheckpointCache.clear();
2817
2958
  },
2818
2959
  async list(input) {
2819
2960
  const page = await api.cli.cursorStoreListCheckpoints({
@@ -3228,14 +3369,14 @@ function createThrottledWebIdeMessageLogSync(cfg2, ctx, onError, options) {
3228
3369
 
3229
3370
  // src/commands/sync-webide-agent.ts
3230
3371
  import {
3231
- existsSync as existsSync5,
3232
- mkdirSync as mkdirSync4,
3372
+ existsSync as existsSync6,
3373
+ mkdirSync as mkdirSync5,
3233
3374
  readdirSync as readdirSync3,
3234
- readFileSync as readFileSync4,
3235
- unlinkSync,
3236
- writeFileSync as writeFileSync3
3375
+ readFileSync as readFileSync5,
3376
+ unlinkSync as unlinkSync2,
3377
+ writeFileSync as writeFileSync4
3237
3378
  } from "fs";
3238
- import { join as join4 } from "path";
3379
+ import { join as join5 } from "path";
3239
3380
  var REVISION_FILE = ".webide-agent.json";
3240
3381
  var RULE_KEY = /^[a-z0-9_]+$/;
3241
3382
  function withTrailingNewline(text) {
@@ -3243,10 +3384,10 @@ function withTrailingNewline(text) {
3243
3384
  `;
3244
3385
  }
3245
3386
  function readRevision(apmDir) {
3246
- const path3 = toFsPath(join4(apmDir, REVISION_FILE));
3247
- if (!existsSync5(path3)) return null;
3387
+ const path3 = toFsPath(join5(apmDir, REVISION_FILE));
3388
+ if (!existsSync6(path3)) return null;
3248
3389
  try {
3249
- const parsed = JSON.parse(readFileSync4(path3, "utf8"));
3390
+ const parsed = JSON.parse(readFileSync5(path3, "utf8"));
3250
3391
  if (parsed?.version === 1 && parsed.revision?.trim()) {
3251
3392
  return parsed.revision.trim();
3252
3393
  }
@@ -3256,8 +3397,8 @@ function readRevision(apmDir) {
3256
3397
  return null;
3257
3398
  }
3258
3399
  function writeRevision(apmDir, revision) {
3259
- writeFileSync3(
3260
- toFsPath(join4(apmDir, REVISION_FILE)),
3400
+ writeFileSync4(
3401
+ toFsPath(join5(apmDir, REVISION_FILE)),
3261
3402
  `${JSON.stringify({ version: 1, revision }, null, 2)}
3262
3403
  `,
3263
3404
  "utf8"
@@ -3271,14 +3412,14 @@ async function syncWebIdeAgentFiles(workdir, cfg2) {
3271
3412
  throw new Error("[apm] \u5E73\u53F0\u672A\u8FD4\u56DE WebIDE \u89C4\u5219\u7248\u672C");
3272
3413
  }
3273
3414
  const apmDir = workspaceApmDir(workdir);
3274
- mkdirSync4(toFsPath(apmDir), { recursive: true });
3415
+ mkdirSync5(toFsPath(apmDir), { recursive: true });
3275
3416
  if (readRevision(apmDir) === revision) {
3276
3417
  return { revision, wrote: false, ruleCount: bundle.rules?.length ?? 0 };
3277
3418
  }
3278
- const rulesDir = join4(apmDir, "rules");
3279
- mkdirSync4(toFsPath(rulesDir), { recursive: true });
3280
- writeFileSync3(
3281
- toFsPath(join4(apmDir, "AGENTS.md")),
3419
+ const rulesDir = join5(apmDir, "rules");
3420
+ mkdirSync5(toFsPath(rulesDir), { recursive: true });
3421
+ writeFileSync4(
3422
+ toFsPath(join5(apmDir, "AGENTS.md")),
3282
3423
  withTrailingNewline(bundle.guide ?? ""),
3283
3424
  "utf8"
3284
3425
  );
@@ -3289,8 +3430,8 @@ async function syncWebIdeAgentFiles(workdir, cfg2) {
3289
3430
  throw new Error(`[apm] \u975E\u6CD5\u89C4\u5219\u540D: ${key || "(\u7A7A)"}`);
3290
3431
  }
3291
3432
  keep.add(`${key}.md`);
3292
- writeFileSync3(
3293
- toFsPath(join4(rulesDir, `${key}.md`)),
3433
+ writeFileSync4(
3434
+ toFsPath(join5(rulesDir, `${key}.md`)),
3294
3435
  withTrailingNewline(rule.body ?? ""),
3295
3436
  "utf8"
3296
3437
  );
@@ -3298,7 +3439,7 @@ async function syncWebIdeAgentFiles(workdir, cfg2) {
3298
3439
  for (const name of readdirSync3(toFsPath(rulesDir))) {
3299
3440
  if (!name.endsWith(".md")) continue;
3300
3441
  if (keep.has(name)) continue;
3301
- unlinkSync(toFsPath(join4(rulesDir, name)));
3442
+ unlinkSync2(toFsPath(join5(rulesDir, name)));
3302
3443
  }
3303
3444
  writeRevision(apmDir, revision);
3304
3445
  return {
@@ -3323,14 +3464,14 @@ async function ensureWorkspaceInitialized(workdir) {
3323
3464
 
3324
3465
  // src/utils/project-documents.ts
3325
3466
  import {
3326
- existsSync as existsSync6,
3467
+ existsSync as existsSync7,
3327
3468
  readdirSync as readdirSync4,
3328
- readFileSync as readFileSync5,
3329
- rmSync,
3330
- writeFileSync as writeFileSync4
3469
+ readFileSync as readFileSync6,
3470
+ rmSync as rmSync2,
3471
+ writeFileSync as writeFileSync5
3331
3472
  } from "fs";
3332
- import { createHash as createHash2 } from "crypto";
3333
- import { dirname as dirname2, join as join5, relative as relative4, sep } from "path";
3473
+ import { createHash as createHash3 } from "crypto";
3474
+ import { dirname as dirname3, join as join6, relative as relative4, sep } from "path";
3334
3475
  var MANIFEST_FILE = "manifest.json";
3335
3476
  function normalizeProjectIdForPath(projectId) {
3336
3477
  const id = projectId.trim();
@@ -3344,11 +3485,11 @@ function normalizeProjectIdForPath(projectId) {
3344
3485
  }
3345
3486
  function projectDocumentsDir(apmRoot, projectId) {
3346
3487
  const id = normalizeProjectIdForPath(projectId);
3347
- return join5(apmRoot ?? workspaceApmDir(), "project", id);
3488
+ return join6(apmRoot ?? workspaceApmDir(), "project", id);
3348
3489
  }
3349
3490
  function projectDocumentLocalPath(apmRoot, projectId, documentPath) {
3350
3491
  const normalized = normalizeLocalDocumentPath(documentPath);
3351
- return join5(
3492
+ return join6(
3352
3493
  projectDocumentsDir(apmRoot, projectId),
3353
3494
  ...normalized.split("/")
3354
3495
  );
@@ -3365,19 +3506,19 @@ function normalizeLocalDocumentPath(path3) {
3365
3506
  return segments.join("/");
3366
3507
  }
3367
3508
  function hashLocalFileContent(content) {
3368
- return createHash2("sha256").update(content, "utf8").digest("hex");
3509
+ return createHash3("sha256").update(content, "utf8").digest("hex");
3369
3510
  }
3370
3511
  function readLocalManifest(apmRoot, projectId) {
3371
- const manifestPath2 = join5(
3512
+ const manifestPath2 = join6(
3372
3513
  projectDocumentsDir(apmRoot, projectId),
3373
3514
  MANIFEST_FILE
3374
3515
  );
3375
- if (!existsSync6(manifestPath2)) {
3516
+ if (!existsSync7(manifestPath2)) {
3376
3517
  return null;
3377
3518
  }
3378
3519
  try {
3379
3520
  return JSON.parse(
3380
- readFileSync5(manifestPath2, "utf8")
3521
+ readFileSync6(manifestPath2, "utf8")
3381
3522
  );
3382
3523
  } catch {
3383
3524
  return null;
@@ -3385,13 +3526,13 @@ function readLocalManifest(apmRoot, projectId) {
3385
3526
  }
3386
3527
  function listLocalDocumentPaths(apmRoot, projectId) {
3387
3528
  const root = projectDocumentsDir(apmRoot, projectId);
3388
- if (!existsSync6(root)) {
3529
+ if (!existsSync7(root)) {
3389
3530
  return [];
3390
3531
  }
3391
3532
  const paths = [];
3392
3533
  const walk = (dir) => {
3393
3534
  for (const entry of readdirSync4(dir, { withFileTypes: true })) {
3394
- const abs = join5(dir, entry.name);
3535
+ const abs = join6(dir, entry.name);
3395
3536
  if (entry.isDirectory()) {
3396
3537
  walk(abs);
3397
3538
  continue;
@@ -3510,8 +3651,8 @@ ${diagnostic ?? ""}`);
3510
3651
  const absPath = toFsPath(
3511
3652
  projectDocumentLocalPath(targetApmDir, projectId, doc.path)
3512
3653
  );
3513
- await ensureDirExists(dirname2(absPath));
3514
- writeFileSync4(absPath, doc.content, "utf8");
3654
+ await ensureDirExists(dirname3(absPath));
3655
+ writeFileSync5(absPath, doc.content, "utf8");
3515
3656
  downloaded += 1;
3516
3657
  }
3517
3658
  }
@@ -3520,13 +3661,13 @@ ${diagnostic ?? ""}`);
3520
3661
  const absPath = toFsPath(
3521
3662
  projectDocumentLocalPath(targetApmDir, projectId, path3)
3522
3663
  );
3523
- if (existsSync6(absPath)) {
3524
- rmSync(absPath, { force: true });
3664
+ if (existsSync7(absPath)) {
3665
+ rmSync2(absPath, { force: true });
3525
3666
  deleted += 1;
3526
3667
  }
3527
3668
  }
3528
- writeFileSync4(
3529
- toFsPath(join5(docsDir, MANIFEST_FILE)),
3669
+ writeFileSync5(
3670
+ toFsPath(join6(docsDir, MANIFEST_FILE)),
3530
3671
  `${JSON.stringify(remoteManifest, null, 2)}
3531
3672
  `,
3532
3673
  "utf8"
@@ -3569,7 +3710,7 @@ async function syncProjectDocumentsPush(cfg2, workdirPath, apmRoot, options) {
3569
3710
  const absPath = toFsPath(
3570
3711
  projectDocumentLocalPath(targetApmDir, projectId, path3)
3571
3712
  );
3572
- const content = readFileSync5(absPath, "utf8");
3713
+ const content = readFileSync6(absPath, "utf8");
3573
3714
  const contentHash = hashLocalFileContent(content);
3574
3715
  if (remoteHashByPath.get(path3) === contentHash) {
3575
3716
  continue;
@@ -4054,18 +4195,18 @@ async function handleStartProject(cfg2, msg2, signal) {
4054
4195
  }
4055
4196
 
4056
4197
  // src/commands/connect/webide-agent-registry.ts
4057
- import { existsSync as existsSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "node:fs";
4058
- import { dirname as dirname3, resolve as resolve6 } from "node:path";
4198
+ import { existsSync as existsSync8, mkdirSync as mkdirSync6, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "node:fs";
4199
+ import { dirname as dirname4, resolve as resolve6 } from "node:path";
4059
4200
  function registryPath(workdir, taskId, fileName = "cursor-agent.json") {
4060
4201
  return resolve6(workdir, ".apm", "webide", taskId, fileName);
4061
4202
  }
4062
4203
  var DESIGN_AGENT_FILE = "design-agent.json";
4063
4204
  function readRegistry(path3) {
4064
- if (!existsSync7(path3)) {
4205
+ if (!existsSync8(path3)) {
4065
4206
  return {};
4066
4207
  }
4067
4208
  try {
4068
- const parsed = JSON.parse(readFileSync6(path3, "utf8"));
4209
+ const parsed = JSON.parse(readFileSync7(path3, "utf8"));
4069
4210
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
4070
4211
  const raw = parsed;
4071
4212
  const state = {};
@@ -4094,8 +4235,8 @@ function readRegistry(path3) {
4094
4235
  return {};
4095
4236
  }
4096
4237
  function writeRegistry(path3, registry) {
4097
- mkdirSync5(dirname3(path3), { recursive: true });
4098
- writeFileSync5(path3, `${JSON.stringify(registry, null, 2)}
4238
+ mkdirSync6(dirname4(path3), { recursive: true });
4239
+ writeFileSync6(path3, `${JSON.stringify(registry, null, 2)}
4099
4240
  `, "utf8");
4100
4241
  }
4101
4242
  function syncWebIdeTaskState(workdir, taskId, patch) {
@@ -4136,7 +4277,7 @@ function saveWebIdeAgentId(workdir, taskId, agentId) {
4136
4277
  }
4137
4278
  function clearWebIdeAgentId(workdir, taskId) {
4138
4279
  const path3 = registryPath(workdir, taskId);
4139
- if (!existsSync7(path3)) return;
4280
+ if (!existsSync8(path3)) return;
4140
4281
  syncWebIdeTaskState(workdir, taskId, { agentId: "" });
4141
4282
  }
4142
4283
  function loadWebIdeDesignAgentId(workdir, taskId) {
@@ -4156,7 +4297,7 @@ function saveWebIdeDesignAgentId(workdir, taskId, agentId) {
4156
4297
  }
4157
4298
  function clearWebIdeDesignAgentId(workdir, taskId) {
4158
4299
  const path3 = registryPath(workdir, taskId, DESIGN_AGENT_FILE);
4159
- if (!existsSync7(path3)) return;
4300
+ if (!existsSync8(path3)) return;
4160
4301
  const current = readRegistry(path3);
4161
4302
  const next = { ...current };
4162
4303
  delete next.agentId;
@@ -4168,11 +4309,12 @@ function clearWebIdeDesignAgentId(workdir, taskId) {
4168
4309
  }
4169
4310
 
4170
4311
  // src/commands/clean-webide-cache.ts
4171
- import { existsSync as existsSync8, rmSync as rmSync2 } from "node:fs";
4312
+ import { existsSync as existsSync9, rmSync as rmSync3 } from "node:fs";
4172
4313
  import { resolve as resolve7 } from "node:path";
4173
4314
  async function purgeCursorAgentStoreForAgent(cfg2, agentId) {
4174
4315
  const trimmedAgentId = agentId.trim();
4175
4316
  if (!trimmedAgentId) return false;
4317
+ await flushPendingCheckpointUploads();
4176
4318
  const store = createRemoteLocalAgentStore(cfg2);
4177
4319
  const runIds = [];
4178
4320
  let cursor;
@@ -4195,6 +4337,7 @@ async function purgeCursorAgentStoreForAgent(cfg2, agentId) {
4195
4337
  await store.runs.delete({ filter: { agentIds: [trimmedAgentId] } });
4196
4338
  await store.checkpoints.delete({ filter: { agentIds: [trimmedAgentId] } });
4197
4339
  await store.agents.delete({ filter: { agentIds: [trimmedAgentId] } });
4340
+ clearLocalCheckpointCache(trimmedAgentId);
4198
4341
  return true;
4199
4342
  }
4200
4343
  async function cleanWebIdeWorkspaceCache(taskId, workdir, cfg2) {
@@ -4224,8 +4367,8 @@ async function cleanWebIdeWorkspaceCache(taskId, workdir, cfg2) {
4224
4367
  );
4225
4368
  }
4226
4369
  const dir = resolve7(trimmedWorkdir, ".apm", "webide", trimmedTaskId);
4227
- if (existsSync8(dir)) {
4228
- rmSync2(dir, { recursive: true, force: true });
4370
+ if (existsSync9(dir)) {
4371
+ rmSync3(dir, { recursive: true, force: true });
4229
4372
  console.log(`[apm] \u5DF2\u6E05\u7406 WebIDE \u7F13\u5B58 ${dir}`);
4230
4373
  } else {
4231
4374
  console.log(`[apm] WebIDE \u7F13\u5B58\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7 ${dir}`);
@@ -4546,8 +4689,8 @@ async function ensureWebIdePullRequests(cfg2, taskId, workdir) {
4546
4689
  }
4547
4690
 
4548
4691
  // src/commands/sync-webide-attachments.ts
4549
- import { existsSync as existsSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
4550
- import { join as join6 } from "path";
4692
+ import { existsSync as existsSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "fs";
4693
+ import { join as join7 } from "path";
4551
4694
  var MANIFEST_FILE2 = ".sync-manifest.json";
4552
4695
  async function downloadAttachment(cfg2, attachmentId) {
4553
4696
  const base = cfg2.baseUrl.trim().replace(/\/+$/, "");
@@ -4563,13 +4706,13 @@ async function downloadAttachment(cfg2, attachmentId) {
4563
4706
  return Buffer.from(await res.arrayBuffer());
4564
4707
  }
4565
4708
  function loadManifest(dir) {
4566
- const path3 = join6(dir, MANIFEST_FILE2);
4567
- if (!existsSync9(path3)) {
4709
+ const path3 = join7(dir, MANIFEST_FILE2);
4710
+ if (!existsSync10(path3)) {
4568
4711
  return { version: 1, attachments: {} };
4569
4712
  }
4570
4713
  try {
4571
4714
  const parsed = JSON.parse(
4572
- readFileSync7(path3, "utf8")
4715
+ readFileSync8(path3, "utf8")
4573
4716
  );
4574
4717
  if (parsed?.version === 1 && parsed.attachments && typeof parsed.attachments === "object") {
4575
4718
  return parsed;
@@ -4579,15 +4722,15 @@ function loadManifest(dir) {
4579
4722
  return { version: 1, attachments: {} };
4580
4723
  }
4581
4724
  function saveManifest(dir, manifest) {
4582
- writeFileSync6(
4583
- join6(dir, MANIFEST_FILE2),
4725
+ writeFileSync7(
4726
+ join7(dir, MANIFEST_FILE2),
4584
4727
  `${JSON.stringify(manifest, null, 2)}
4585
4728
  `,
4586
4729
  "utf8"
4587
4730
  );
4588
4731
  }
4589
4732
  function isAttachmentUpToDate(entry, item, dest) {
4590
- if (!entry || !existsSync9(dest)) return false;
4733
+ if (!entry || !existsSync10(dest)) return false;
4591
4734
  if (entry.name !== item.name) return false;
4592
4735
  const createdAt = item.createdAt ?? "";
4593
4736
  return entry.createdAt === createdAt;
@@ -4602,7 +4745,7 @@ async function syncAttachmentsToDirectory(cfg2, attachments, dir, logLabel) {
4602
4745
  const nextManifest = { version: 1, attachments: {} };
4603
4746
  const names = [];
4604
4747
  for (const item of attachments) {
4605
- const dest = join6(dir, item.name);
4748
+ const dest = join7(dir, item.name);
4606
4749
  const entry = manifest.attachments[item.id];
4607
4750
  const createdAt = item.createdAt ?? "";
4608
4751
  names.push(item.name);
@@ -4612,7 +4755,7 @@ async function syncAttachmentsToDirectory(cfg2, attachments, dir, logLabel) {
4612
4755
  continue;
4613
4756
  }
4614
4757
  const buffer = await downloadAttachment(cfg2, item.id);
4615
- writeFileSync6(dest, buffer);
4758
+ writeFileSync7(dest, buffer);
4616
4759
  nextManifest.attachments[item.id] = {
4617
4760
  name: item.name,
4618
4761
  createdAt
@@ -4633,9 +4776,9 @@ async function syncWebIdeAttachments(cfg2, taskId, workdir, attachments) {
4633
4776
  }
4634
4777
 
4635
4778
  // src/commands/sync-webide-design.ts
4636
- import { createHash as createHash3 } from "crypto";
4637
- import { existsSync as existsSync10, readdirSync as readdirSync5, readFileSync as readFileSync8, statSync as statSync5, writeFileSync as writeFileSync7 } from "fs";
4638
- import { join as join7 } from "path";
4779
+ import { createHash as createHash4 } from "crypto";
4780
+ import { existsSync as existsSync11, readdirSync as readdirSync5, readFileSync as readFileSync9, statSync as statSync5, writeFileSync as writeFileSync8 } from "fs";
4781
+ import { join as join8 } from "path";
4639
4782
 
4640
4783
  // src/opc-shared-types.ts
4641
4784
  function webIdeDesignObjectKey(taskId, fileName) {
@@ -4653,15 +4796,15 @@ function webIdeDesignArtifactContentType(name) {
4653
4796
  // src/commands/sync-webide-design.ts
4654
4797
  var MANIFEST_FILE3 = ".sync-manifest.json";
4655
4798
  function hashBuffer(buf) {
4656
- return createHash3("sha256").update(buf).digest("hex");
4799
+ return createHash4("sha256").update(buf).digest("hex");
4657
4800
  }
4658
4801
  function loadManifest2(dir) {
4659
- const path3 = join7(dir, MANIFEST_FILE3);
4660
- if (!existsSync10(path3)) {
4802
+ const path3 = join8(dir, MANIFEST_FILE3);
4803
+ if (!existsSync11(path3)) {
4661
4804
  return { version: 1, files: {} };
4662
4805
  }
4663
4806
  try {
4664
- const parsed = JSON.parse(readFileSync8(path3, "utf8"));
4807
+ const parsed = JSON.parse(readFileSync9(path3, "utf8"));
4665
4808
  if (parsed?.version === 1 && parsed.files && typeof parsed.files === "object") {
4666
4809
  return parsed;
4667
4810
  }
@@ -4670,8 +4813,8 @@ function loadManifest2(dir) {
4670
4813
  return { version: 1, files: {} };
4671
4814
  }
4672
4815
  function saveManifest2(dir, manifest) {
4673
- writeFileSync7(
4674
- join7(dir, MANIFEST_FILE3),
4816
+ writeFileSync8(
4817
+ join8(dir, MANIFEST_FILE3),
4675
4818
  `${JSON.stringify(manifest, null, 2)}
4676
4819
  `,
4677
4820
  "utf8"
@@ -4699,13 +4842,13 @@ async function syncWebIdeDesign(cfg2, taskId, workdir, artifacts) {
4699
4842
  for (const art of artifacts) {
4700
4843
  const name = art.name?.trim();
4701
4844
  if (!name || !isWebIdeDesignArtifactName(name)) continue;
4702
- const localPath = join7(dir, name);
4845
+ const localPath = join8(dir, name);
4703
4846
  const entry = manifest.files[name];
4704
- if (entry?.contentHash === art.contentHash && existsSync10(localPath)) {
4847
+ if (entry?.contentHash === art.contentHash && existsSync11(localPath)) {
4705
4848
  continue;
4706
4849
  }
4707
4850
  const buf = await downloadDesignFile(cfg2, taskId, name);
4708
- writeFileSync7(localPath, buf);
4851
+ writeFileSync8(localPath, buf);
4709
4852
  manifest.files[name] = { contentHash: hashBuffer(buf) };
4710
4853
  synced.push(name);
4711
4854
  }
@@ -4714,13 +4857,13 @@ async function syncWebIdeDesign(cfg2, taskId, workdir, artifacts) {
4714
4857
  }
4715
4858
  function listLocalDesignArtifactFiles(taskId, workdir) {
4716
4859
  const dir = webideDesignDir(taskId, workdir);
4717
- if (!existsSync10(dir)) return [];
4860
+ if (!existsSync11(dir)) return [];
4718
4861
  const out = [];
4719
4862
  for (const name of readdirSync5(dir)) {
4720
4863
  if (!isWebIdeDesignArtifactName(name)) continue;
4721
- const absPath = join7(dir, name);
4864
+ const absPath = join8(dir, name);
4722
4865
  if (!statSync5(absPath).isFile()) continue;
4723
- const buf = readFileSync8(absPath);
4866
+ const buf = readFileSync9(absPath);
4724
4867
  if (buf.length === 0) continue;
4725
4868
  out.push({ name, absPath, contentHash: hashBuffer(buf) });
4726
4869
  }
@@ -4825,26 +4968,36 @@ function completeActionForInbound(action) {
4825
4968
  switch (action) {
4826
4969
  case "request-assessment":
4827
4970
  case "confirm-assumptions":
4971
+ case "start-assessment":
4972
+ case "continue-assessment":
4828
4973
  return "complete-assessment";
4829
4974
  case "request-design":
4830
4975
  case "request-revise-design":
4976
+ case "start-design":
4831
4977
  return "complete-design";
4832
4978
  case "request-write-plan":
4833
4979
  case "request-revise-plan":
4980
+ case "start-write-plan":
4834
4981
  return "complete-write-plan";
4835
4982
  case "request-develop":
4836
4983
  case "skip-plan":
4984
+ case "start-develop":
4837
4985
  return "complete-develop";
4838
4986
  case "request-start-project":
4987
+ case "start-project":
4839
4988
  return "complete-project";
4840
4989
  case "request-execute-sql":
4990
+ case "start-execute-sql":
4841
4991
  return "complete-execute-sql";
4842
4992
  case "request-bugfix":
4993
+ case "start-bugfix":
4843
4994
  return "complete-bugfix";
4844
4995
  case "request-organize-code":
4845
4996
  case "request-patch":
4997
+ case "start-organize-code":
4846
4998
  return "complete-organize-code";
4847
4999
  case "request-accept":
5000
+ case "start-accept":
4848
5001
  return "complete-accept";
4849
5002
  default:
4850
5003
  return null;
@@ -4855,6 +5008,13 @@ async function webIdeRunAction(cfg2, taskId, action, params) {
4855
5008
  await api.cli.webideRunAction({ taskId, action, params });
4856
5009
  console.log(`[apm] webide runAction ok action=${action} taskId=${taskId}`);
4857
5010
  }
5011
+ async function webIdeAttachContinueRun(cfg2, taskId, runId) {
5012
+ const api = createApmApiClient(cfg2);
5013
+ await api.cli.webideAttachContinueRun({ taskId, runId });
5014
+ console.log(
5015
+ `[apm] webide attachContinueRun ok runId=${runId} taskId=${taskId}`
5016
+ );
5017
+ }
4858
5018
  async function webIdeSyncTransitionPrepEvents(cfg2, taskId, startAction, prepEvents) {
4859
5019
  try {
4860
5020
  const api = createApmApiClient(cfg2);
@@ -4927,8 +5087,11 @@ async function handleWebIdeInboundMessage(cfg2, msg2, signal) {
4927
5087
  const messageId = msg2.messageId;
4928
5088
  const taskId = msg2.taskId;
4929
5089
  const branchCacheKey = taskId;
5090
+ const continuePayload = msg2.action === "continue" ? parseWebIdePromptPayload(msg2.content) : null;
5091
+ const previousAction = typeof continuePayload?.previousAction === "string" ? continuePayload.previousAction.trim() : "";
5092
+ const effectiveAction = msg2.action === "continue" && previousAction ? previousAction : msg2.action;
4930
5093
  console.log(
4931
- `[apm] webide-message action=${msg2.action} taskId=${taskId} messageId=${messageId}`
5094
+ `[apm] webide-message action=${msg2.action}${previousAction ? ` previousAction=${previousAction}` : ""} taskId=${taskId} messageId=${messageId}`
4932
5095
  );
4933
5096
  await updateStatus2(cfg2, messageId, "TYPING");
4934
5097
  syncLocalTaskStatus(workdir, taskId, msg2, "TYPING");
@@ -5031,7 +5194,7 @@ async function handleWebIdeInboundMessage(cfg2, msg2, signal) {
5031
5194
  eventSession.addCliStep("\u51C6\u5907\u7279\u6027\u5206\u652F", "\u5DF2\u7F13\u5B58\uFF0C\u8DF3\u8FC7", "skip");
5032
5195
  await syncPrepLog();
5033
5196
  }
5034
- if (shouldEnsureWebIdePullRequests(msg2.action)) {
5197
+ if (shouldEnsureWebIdePullRequests(effectiveAction)) {
5035
5198
  if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
5036
5199
  await runPrepStep(
5037
5200
  "\u9A8C\u6536\u524D\u63A8\u9001",
@@ -5137,8 +5300,8 @@ async function handleWebIdeInboundMessage(cfg2, msg2, signal) {
5137
5300
  "running"
5138
5301
  );
5139
5302
  await syncPrepLog();
5140
- const startLocalServices = isStartLocalServicesAction(msg2.action);
5141
- const designAction = isDesignAction(msg2.action);
5303
+ const startLocalServices = isStartLocalServicesAction(effectiveAction);
5304
+ const designAction = isDesignAction(effectiveAction);
5142
5305
  const useNewAgent = msg2.useNewAgent === true;
5143
5306
  const toolNames = Array.isArray(msg2.tools) ? msg2.tools.map((t) => String(t).trim()).filter(Boolean) : [];
5144
5307
  if (useNewAgent && !startLocalServices) {
@@ -5149,7 +5312,7 @@ async function handleWebIdeInboundMessage(cfg2, msg2, signal) {
5149
5312
  }
5150
5313
  }
5151
5314
  const savedAgentId = startLocalServices || useNewAgent ? void 0 : designAction ? loadWebIdeDesignAgentId(workdir, taskId) : loadWebIdeAgentId(workdir, taskId);
5152
- const promptPayload = toolNames.includes("MysqlExecute") ? parseWebIdePromptPayload(msg2.content) : null;
5315
+ const promptPayload = toolNames.includes("MysqlExecute") ? continuePayload ?? parseWebIdePromptPayload(msg2.content) : null;
5153
5316
  const sqlExecutionId = toolNames.includes("MysqlExecute") && typeof promptPayload?.executionId === "string" ? promptPayload.executionId.trim() : void 0;
5154
5317
  if (toolNames.includes("MysqlExecute") && !sqlExecutionId) {
5155
5318
  console.warn(
@@ -5239,6 +5402,15 @@ ${assumptionAnswersText}` : msg2.content,
5239
5402
  eventSession.getCliSteps()
5240
5403
  );
5241
5404
  await webIdeRunAction(cfg2, taskId, startAction, { runId });
5405
+ } else if (msg2.action === "continue") {
5406
+ try {
5407
+ await webIdeAttachContinueRun(cfg2, taskId, runId);
5408
+ } catch (err) {
5409
+ console.warn(
5410
+ "[apm] attach continue run failed:",
5411
+ err instanceof Error ? err.message : err
5412
+ );
5413
+ }
5242
5414
  }
5243
5415
  }
5244
5416
  }
@@ -5265,7 +5437,7 @@ ${assumptionAnswersText}` : msg2.content,
5265
5437
  detail,
5266
5438
  tokenUsage
5267
5439
  );
5268
- if (sqlExecutionId && msg2.action !== "request-bugfix") {
5440
+ if (sqlExecutionId && effectiveAction !== "request-bugfix") {
5269
5441
  try {
5270
5442
  await api.cli.webideFinalizeSqlExecution({
5271
5443
  executionId: sqlExecutionId,
@@ -5290,7 +5462,7 @@ ${assumptionAnswersText}` : msg2.content,
5290
5462
  "\u5DF2\u53D6\u6D88",
5291
5463
  tokenUsage
5292
5464
  );
5293
- if (sqlExecutionId && msg2.action !== "request-bugfix") {
5465
+ if (sqlExecutionId && effectiveAction !== "request-bugfix") {
5294
5466
  try {
5295
5467
  await api.cli.webideFinalizeSqlExecution({
5296
5468
  executionId: sqlExecutionId,
@@ -5317,7 +5489,7 @@ ${assumptionAnswersText}` : msg2.content,
5317
5489
  id: messageId,
5318
5490
  content: fallback
5319
5491
  });
5320
- if ((msg2.action === "write-plan" || msg2.action === "revise-plan") && outcome.createPlan && outcome.createPlan.trim()) {
5492
+ if ((effectiveAction === "write-plan" || effectiveAction === "revise-plan" || effectiveAction === "request-write-plan" || effectiveAction === "request-revise-plan" || effectiveAction === "start-write-plan") && outcome.createPlan && outcome.createPlan.trim()) {
5321
5493
  try {
5322
5494
  await api.cli.webideUpsertPlan({
5323
5495
  taskId,
@@ -5325,12 +5497,12 @@ ${assumptionAnswersText}` : msg2.content,
5325
5497
  });
5326
5498
  } catch (err) {
5327
5499
  console.warn(
5328
- `[apm] ${msg2.action} \u8865\u5199\u8BA1\u5212\u5931\u8D25:`,
5500
+ `[apm] ${effectiveAction} \u8865\u5199\u8BA1\u5212\u5931\u8D25:`,
5329
5501
  err instanceof Error ? err.message : err
5330
5502
  );
5331
5503
  }
5332
5504
  }
5333
- if (isDesignAction(msg2.action)) {
5505
+ if (isDesignAction(effectiveAction)) {
5334
5506
  if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
5335
5507
  try {
5336
5508
  const uploaded = await uploadWebIdeDesignArtifacts(
@@ -5339,7 +5511,7 @@ ${assumptionAnswersText}` : msg2.content,
5339
5511
  workdir
5340
5512
  );
5341
5513
  console.log(
5342
- `[apm] webide \u8BBE\u8BA1\u4EA7\u7269\u4E0A\u4F20 action=${msg2.action} uploaded=${uploaded.uploaded} skipped=${uploaded.skipped} files=${uploaded.artifacts.map((a) => a.name).join(",")}`
5514
+ `[apm] webide \u8BBE\u8BA1\u4EA7\u7269\u4E0A\u4F20 action=${effectiveAction} uploaded=${uploaded.uploaded} skipped=${uploaded.skipped} files=${uploaded.artifacts.map((a) => a.name).join(",")}`
5343
5515
  );
5344
5516
  } catch (err) {
5345
5517
  const detail = err instanceof Error ? err.message : String(err);
@@ -5354,27 +5526,27 @@ ${assumptionAnswersText}` : msg2.content,
5354
5526
  return;
5355
5527
  }
5356
5528
  }
5357
- if (shouldCommitAfterWebIdeMessage(msg2.action)) {
5529
+ if (shouldCommitAfterWebIdeMessage(effectiveAction)) {
5358
5530
  if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
5359
5531
  const committed = await commitWorkspaceReposIfDirty(
5360
5532
  workdir,
5361
- `chore(webide): sync after ${msg2.action} (${taskId})`
5533
+ `chore(webide): sync after ${effectiveAction} (${taskId})`
5362
5534
  );
5363
5535
  console.log(
5364
- `[apm] webide \u515C\u5E95 commit action=${msg2.action} repos=${committed}`
5536
+ `[apm] webide \u515C\u5E95 commit action=${effectiveAction} repos=${committed}`
5365
5537
  );
5366
5538
  if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
5367
5539
  const pushed = await pushWorkspaceRepos(workdir);
5368
5540
  console.log(
5369
- `[apm] webide \u81EA\u52A8 push action=${msg2.action} repos=${pushed}`
5541
+ `[apm] webide \u81EA\u52A8 push action=${effectiveAction} repos=${pushed}`
5370
5542
  );
5371
5543
  }
5372
- if (shouldEnsureWebIdePullRequestsAfterAgent(msg2.action)) {
5544
+ if (shouldEnsureWebIdePullRequestsAfterAgent(effectiveAction)) {
5373
5545
  if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
5374
- if (!shouldCommitAfterWebIdeMessage(msg2.action)) {
5546
+ if (!shouldCommitAfterWebIdeMessage(effectiveAction)) {
5375
5547
  const pushed = await pushWorkspaceRepos(workdir);
5376
5548
  console.log(
5377
- `[apm] webide create-pr \u524D push action=${msg2.action} repos=${pushed}`
5549
+ `[apm] webide create-pr \u524D push action=${effectiveAction} repos=${pushed}`
5378
5550
  );
5379
5551
  }
5380
5552
  const prResult = await ensureWebIdePullRequests(cfg2, taskId, workdir);
@@ -5428,20 +5600,20 @@ ${assumptionAnswersText}` : msg2.content,
5428
5600
  null,
5429
5601
  tokenUsage
5430
5602
  );
5431
- const completeAction = completeActionForInbound(msg2.action);
5603
+ const completeAction = completeActionForInbound(effectiveAction);
5432
5604
  if (completeAction && !pausedForAssumptions) {
5433
5605
  await webIdeRunAction(cfg2, taskId, completeAction);
5434
5606
  } else if (pausedForAssumptions) {
5435
5607
  console.log(
5436
- `[apm] \u672C\u8F6E\u505C\u5728\u5F85\u786E\u8BA4\u5047\u8BBE\uFF0C\u8DF3\u8FC7 complete action=${msg2.action} taskId=${taskId}`
5608
+ `[apm] \u672C\u8F6E\u505C\u5728\u5F85\u786E\u8BA4\u5047\u8BBE\uFF0C\u8DF3\u8FC7 complete action=${effectiveAction} taskId=${taskId}`
5437
5609
  );
5438
5610
  }
5439
5611
  await updateStatus2(cfg2, messageId, "SUCCESS");
5440
5612
  syncLocalTaskStatus(workdir, taskId, msg2, "SUCCESS");
5441
5613
  console.log(
5442
- `[apm] webide-message \u5B8C\u6210 action=${msg2.action} messageId=${messageId} agentId=${outcome.agentId}`
5614
+ `[apm] webide-message \u5B8C\u6210 action=${msg2.action}${previousAction ? ` previousAction=${previousAction}` : ""} messageId=${messageId} agentId=${outcome.agentId}`
5443
5615
  );
5444
- if (msg2.action === "request-accept") {
5616
+ if (effectiveAction === "request-accept" || effectiveAction === "start-accept") {
5445
5617
  try {
5446
5618
  await cleanWebIdeWorkspaceCache(taskId, workdir, cfg2);
5447
5619
  } catch (err) {
@@ -5468,7 +5640,7 @@ ${assumptionAnswersText}` : msg2.content,
5468
5640
  statusErr instanceof Error ? statusErr.message : statusErr
5469
5641
  );
5470
5642
  }
5471
- const completeAction = completeActionForInbound(msg2.action);
5643
+ const completeAction = completeActionForInbound(effectiveAction);
5472
5644
  if (completeAction === "complete-assessment" && !pausedForAssumptions) {
5473
5645
  try {
5474
5646
  await webIdeRunAction(cfg2, taskId, completeAction, { force: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-project-manage-cli",
3
- "version": "8.1.12",
3
+ "version": "8.1.14",
4
4
  "description": "命令行工具:后续用于调用平台后端 API 完成运维与自动化操作",
5
5
  "type": "module",
6
6
  "private": false,