ai-project-manage-cli 8.1.13 → 8.1.15

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"
@@ -274,22 +279,6 @@ var requestConfig = {
274
279
  cursorStoreDeleteRunEvents: defineEndpoint({
275
280
  method: "POST",
276
281
  path: "/cli/cursor-store/run-events/delete"
277
- }),
278
- cursorStorePutCheckpoint: defineEndpoint({
279
- method: "PUT",
280
- path: "/cli/cursor-store/checkpoints"
281
- }),
282
- cursorStoreGetCheckpoint: defineEndpoint({
283
- method: "GET",
284
- path: "/cli/cursor-store/checkpoints/get"
285
- }),
286
- cursorStoreListCheckpoints: defineEndpoint({
287
- method: "POST",
288
- path: "/cli/cursor-store/checkpoints/list"
289
- }),
290
- cursorStoreDeleteCheckpoints: defineEndpoint({
291
- method: "POST",
292
- path: "/cli/cursor-store/checkpoints/delete"
293
282
  })
294
283
  }
295
284
  };
@@ -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"
@@ -185,22 +190,6 @@ var requestConfig = {
185
190
  cursorStoreDeleteRunEvents: defineEndpoint({
186
191
  method: "POST",
187
192
  path: "/cli/cursor-store/run-events/delete"
188
- }),
189
- cursorStorePutCheckpoint: defineEndpoint({
190
- method: "PUT",
191
- path: "/cli/cursor-store/checkpoints"
192
- }),
193
- cursorStoreGetCheckpoint: defineEndpoint({
194
- method: "GET",
195
- path: "/cli/cursor-store/checkpoints/get"
196
- }),
197
- cursorStoreListCheckpoints: defineEndpoint({
198
- method: "POST",
199
- path: "/cli/cursor-store/checkpoints/list"
200
- }),
201
- cursorStoreDeleteCheckpoints: defineEndpoint({
202
- method: "POST",
203
- path: "/cli/cursor-store/checkpoints/delete"
204
193
  })
205
194
  }
206
195
  };
@@ -2467,77 +2456,11 @@ function createPtySessionMcpServers(cfg2) {
2467
2456
  };
2468
2457
  }
2469
2458
 
2459
+ // src/commands/connect/local-sqlite-agent-store.ts
2460
+ import { composeLocalAgentStore } from "@cursor/sdk";
2461
+ import { SqliteLocalAgentStore } from "@cursor/sdk/sqlite";
2462
+
2470
2463
  // src/commands/connect/remote-local-agent-store.ts
2471
- import { createHash as createHash2 } from "node:crypto";
2472
- import {
2473
- existsSync as existsSync5,
2474
- mkdirSync as mkdirSync4,
2475
- readFileSync as readFileSync4,
2476
- rmSync,
2477
- unlinkSync,
2478
- writeFileSync as writeFileSync3
2479
- } from "node:fs";
2480
- import { dirname as dirname2, join as join4 } from "node:path";
2481
- var INLINE_CHECKPOINT_MAX_BYTES = 256 * 1024;
2482
- var CHECKPOINT_CACHE_DIR = join4(APM_CONFIG_DIR, "cursor-checkpoint-cache");
2483
- function checkpointObjectKey(agentId, blobId) {
2484
- return `cursor-agents/${agentId}/checkpoints/${blobId}`;
2485
- }
2486
- function safeBlobFileName(blobId) {
2487
- if (/^[a-zA-Z0-9._-]+$/.test(blobId)) return blobId;
2488
- return createHash2("sha256").update(blobId).digest("hex");
2489
- }
2490
- function checkpointCachePath(agentId, blobId) {
2491
- return join4(CHECKPOINT_CACHE_DIR, agentId, safeBlobFileName(blobId));
2492
- }
2493
- function checkpointCacheKey(agentId, blobId) {
2494
- return `${agentId}\0${blobId}`;
2495
- }
2496
- function readLocalCheckpoint(agentId, blobId) {
2497
- try {
2498
- const path3 = checkpointCachePath(agentId, blobId);
2499
- if (!existsSync5(path3)) return null;
2500
- return new Uint8Array(readFileSync4(path3));
2501
- } catch {
2502
- return null;
2503
- }
2504
- }
2505
- function writeLocalCheckpoint(agentId, blobId, data) {
2506
- try {
2507
- const path3 = checkpointCachePath(agentId, blobId);
2508
- mkdirSync4(dirname2(path3), { recursive: true });
2509
- writeFileSync3(path3, Buffer.from(data));
2510
- } catch (err) {
2511
- console.warn(
2512
- `[apm] checkpoint \u672C\u5730\u7F13\u5B58\u5199\u5165\u5931\u8D25 agentId=${agentId} blobId=${blobId}:`,
2513
- err instanceof Error ? err.message : err
2514
- );
2515
- }
2516
- }
2517
- function deleteLocalCheckpoint(agentId, blobId) {
2518
- try {
2519
- const path3 = checkpointCachePath(agentId, blobId);
2520
- if (existsSync5(path3)) unlinkSync(path3);
2521
- } catch {
2522
- }
2523
- }
2524
- function clearLocalCheckpointCache(agentId) {
2525
- try {
2526
- if (agentId?.trim()) {
2527
- const dir = join4(CHECKPOINT_CACHE_DIR, agentId.trim());
2528
- if (existsSync5(dir)) rmSync(dir, { recursive: true, force: true });
2529
- return;
2530
- }
2531
- if (existsSync5(CHECKPOINT_CACHE_DIR)) {
2532
- rmSync(CHECKPOINT_CACHE_DIR, { recursive: true, force: true });
2533
- }
2534
- } catch (err) {
2535
- console.warn(
2536
- `[apm] \u6E05\u7406 checkpoint \u672C\u5730\u7F13\u5B58\u5931\u8D25:`,
2537
- err instanceof Error ? err.message : err
2538
- );
2539
- }
2540
- }
2541
2464
  function asCheckpointRef(value) {
2542
2465
  if (value === void 0) return void 0;
2543
2466
  if (value === null) return null;
@@ -2592,45 +2515,32 @@ function fromApiRun(row) {
2592
2515
  latestCheckpointRef: asCheckpointRef(row.latestCheckpointRef) ?? null
2593
2516
  };
2594
2517
  }
2595
- function fromApiEvent(row) {
2596
- return {
2597
- runId: row.runId,
2598
- seq: row.seq,
2599
- offset: row.offset,
2600
- eventType: row.eventType,
2601
- payload: row.payload,
2602
- payloadRef: row.payloadRef,
2603
- idempotencyKey: row.idempotencyKey,
2604
- createdAt: row.createdAt
2605
- };
2606
- }
2607
- function bytesToBase64(data) {
2608
- return Buffer.from(data).toString("base64");
2609
- }
2610
- function base64ToBytes(dataBase64) {
2611
- return new Uint8Array(Buffer.from(dataBase64, "base64"));
2612
- }
2613
- function createRemoteLocalAgentStore(cfg2) {
2614
- const api = createApmApiClient(cfg2);
2615
- let minioCache = null;
2616
- const memoryCheckpointCache = /* @__PURE__ */ new Map();
2617
- function getMinio() {
2618
- if (!minioCache) {
2619
- minioCache = createApmLogMinioClient(cfg2).then(({ client, bucket }) => ({
2620
- client,
2621
- bucket
2622
- }));
2623
- }
2624
- return minioCache;
2625
- }
2626
- function rememberCheckpoint(agentId, blobId, data) {
2627
- memoryCheckpointCache.set(checkpointCacheKey(agentId, blobId), data);
2628
- writeLocalCheckpoint(agentId, blobId, data);
2518
+ var unsupportedCheckpoints = {
2519
+ async get() {
2520
+ return null;
2521
+ },
2522
+ async create() {
2523
+ },
2524
+ async update() {
2525
+ },
2526
+ async delete() {
2527
+ },
2528
+ async list() {
2529
+ return { items: [] };
2629
2530
  }
2630
- function forgetCheckpoint(agentId, blobId) {
2631
- memoryCheckpointCache.delete(checkpointCacheKey(agentId, blobId));
2632
- deleteLocalCheckpoint(agentId, blobId);
2531
+ };
2532
+ var unsupportedRunEvents = {
2533
+ async append() {
2534
+ throw new Error("runEvents \u4EC5\u5B58\u672C\u673A SQLite");
2535
+ },
2536
+ async list() {
2537
+ return { items: [] };
2538
+ },
2539
+ async delete() {
2633
2540
  }
2541
+ };
2542
+ function createRemoteLocalAgentStore(cfg2) {
2543
+ const api = createApmApiClient(cfg2);
2634
2544
  async function upsertAgent(agent) {
2635
2545
  const row = await api.cli.cursorStoreUpsertAgent({
2636
2546
  agentId: agent.agentId,
@@ -2666,60 +2576,6 @@ function createRemoteLocalAgentStore(cfg2) {
2666
2576
  });
2667
2577
  return fromApiRun(row);
2668
2578
  }
2669
- async function putCheckpoint(input) {
2670
- const createdAt = Date.now();
2671
- if (input.data.byteLength > INLINE_CHECKPOINT_MAX_BYTES) {
2672
- const { client, bucket } = await getMinio();
2673
- const objectKey = checkpointObjectKey(input.agentId, input.blobId);
2674
- await client.putObject(bucket, objectKey, Buffer.from(input.data), {
2675
- "Content-Type": "application/octet-stream"
2676
- });
2677
- await api.cli.cursorStorePutCheckpoint({
2678
- agentId: input.agentId,
2679
- blobId: input.blobId,
2680
- objectKey,
2681
- byteSize: input.data.byteLength,
2682
- createdAt
2683
- });
2684
- rememberCheckpoint(input.agentId, input.blobId, input.data);
2685
- return;
2686
- }
2687
- await api.cli.cursorStorePutCheckpoint({
2688
- agentId: input.agentId,
2689
- blobId: input.blobId,
2690
- dataBase64: bytesToBase64(input.data),
2691
- byteSize: input.data.byteLength,
2692
- createdAt
2693
- });
2694
- rememberCheckpoint(input.agentId, input.blobId, input.data);
2695
- }
2696
- async function readCheckpointBytes(input) {
2697
- const memKey = checkpointCacheKey(input.agentId, input.blobId);
2698
- const cached = memoryCheckpointCache.get(memKey);
2699
- if (cached) return cached;
2700
- const local = readLocalCheckpoint(input.agentId, input.blobId);
2701
- if (local) {
2702
- memoryCheckpointCache.set(memKey, local);
2703
- return local;
2704
- }
2705
- const row = await api.cli.cursorStoreGetCheckpoint({
2706
- agentId: input.agentId,
2707
- blobId: input.blobId
2708
- });
2709
- if (!row) return null;
2710
- let bytes = null;
2711
- if (row.dataBase64) {
2712
- bytes = base64ToBytes(row.dataBase64);
2713
- } else {
2714
- const objectKey = row.objectKey?.trim();
2715
- if (!objectKey) return null;
2716
- const { client, bucket } = await getMinio();
2717
- const buf = await client.getObjectBuffer(bucket, objectKey);
2718
- bytes = new Uint8Array(buf);
2719
- }
2720
- rememberCheckpoint(input.agentId, input.blobId, bytes);
2721
- return bytes;
2722
- }
2723
2579
  return {
2724
2580
  agents: {
2725
2581
  async get(input) {
@@ -2774,10 +2630,11 @@ function createRemoteLocalAgentStore(cfg2) {
2774
2630
  },
2775
2631
  runs: {
2776
2632
  async get(input) {
2777
- const row = await api.cli.cursorStoreGetRun({
2778
- agentId: input.agentId,
2779
- runId: input.runId
2633
+ const page = await api.cli.cursorStoreListRuns({
2634
+ runIds: [input.runId],
2635
+ limit: 1
2780
2636
  });
2637
+ const row = page.items[0];
2781
2638
  return row ? fromApiRun(row) : null;
2782
2639
  },
2783
2640
  async create(input) {
@@ -2821,124 +2678,54 @@ function createRemoteLocalAgentStore(cfg2) {
2821
2678
  return result;
2822
2679
  }
2823
2680
  },
2824
- runEvents: {
2825
- async append(input) {
2826
- const { items } = await api.cli.cursorStoreAppendRunEvents({
2827
- events: [
2828
- {
2829
- runId: input.runId,
2830
- eventType: input.eventType,
2831
- payload: input.payload,
2832
- payloadRef: input.payloadRef ?? null,
2833
- idempotencyKey: input.idempotencyKey ?? null
2834
- }
2835
- ]
2836
- });
2837
- const row = items[0];
2838
- if (!row) {
2839
- throw new Error("cursor-store append run event \u672A\u8FD4\u56DE\u7ED3\u679C");
2840
- }
2841
- return fromApiEvent(row);
2842
- },
2843
- async list(input) {
2844
- const page = await api.cli.cursorStoreListRunEvents({
2845
- runId: input.runId,
2846
- afterOffset: input.afterOffset ?? null,
2847
- limit: input.limit
2848
- });
2849
- return {
2850
- items: page.items.map(fromApiEvent),
2851
- ...page.nextOffset ? { nextOffset: page.nextOffset } : {}
2852
- };
2853
- },
2854
- async delete(input) {
2855
- const runIds = input.filter.runIds?.map((id) => id.trim()).filter(Boolean);
2856
- if (runIds && runIds.length > 0) {
2857
- await api.cli.cursorStoreDeleteRunEvents({ runIds });
2858
- return;
2859
- }
2860
- let cursor;
2861
- for (; ; ) {
2862
- const page = await api.cli.cursorStoreListRuns({
2863
- cursor,
2864
- limit: 200
2865
- });
2866
- if (page.items.length === 0) break;
2867
- await api.cli.cursorStoreDeleteRunEvents({
2868
- runIds: page.items.map((item) => item.runId)
2869
- });
2870
- if (!page.nextCursor) break;
2871
- cursor = page.nextCursor;
2872
- }
2873
- }
2874
- },
2875
- checkpoints: {
2876
- async get(input) {
2877
- return readCheckpointBytes(input);
2878
- },
2879
- async create(input) {
2880
- await putCheckpoint(input);
2881
- },
2882
- async update(input) {
2883
- await putCheckpoint(input);
2884
- },
2885
- async delete(input) {
2886
- const agentIds = input.filter.agentIds?.map((id) => id.trim()).filter(Boolean);
2887
- const blobIds = input.filter.blobIds?.map((id) => id.trim()).filter(Boolean);
2888
- if (agentIds && agentIds.length > 0 || blobIds && blobIds.length > 0) {
2889
- await api.cli.cursorStoreDeleteCheckpoints({ agentIds, blobIds });
2890
- if (agentIds && agentIds.length > 0 && !blobIds?.length) {
2891
- for (const id of agentIds) clearLocalCheckpointCache(id);
2892
- } else if (agentIds && blobIds) {
2893
- for (const id of agentIds) {
2894
- for (const blobId of blobIds) forgetCheckpoint(id, blobId);
2895
- }
2896
- } else if (blobIds) {
2897
- for (const blobId of blobIds) {
2898
- for (const key of memoryCheckpointCache.keys()) {
2899
- const sep2 = key.indexOf("\0");
2900
- if (sep2 < 0) continue;
2901
- if (key.slice(sep2 + 1) === blobId) {
2902
- forgetCheckpoint(key.slice(0, sep2), blobId);
2903
- }
2904
- }
2905
- }
2906
- }
2907
- return;
2908
- }
2909
- let cursor;
2910
- for (; ; ) {
2911
- const page = await api.cli.cursorStoreListCheckpoints({
2912
- cursor,
2913
- limit: 200
2914
- });
2915
- if (page.items.length === 0) break;
2916
- await api.cli.cursorStoreDeleteCheckpoints({
2917
- agentIds: [...new Set(page.items.map((item) => item.agentId))],
2918
- blobIds: page.items.map((item) => item.blobId)
2919
- });
2920
- if (!page.nextCursor) break;
2921
- cursor = page.nextCursor;
2922
- }
2923
- clearLocalCheckpointCache();
2924
- memoryCheckpointCache.clear();
2925
- },
2926
- async list(input) {
2927
- const page = await api.cli.cursorStoreListCheckpoints({
2928
- agentIds: input?.filter?.agentIds ? [...input.filter.agentIds] : void 0,
2929
- blobIds: input?.filter?.blobIds ? [...input.filter.blobIds] : void 0,
2930
- cursor: input?.filter?.cursor,
2931
- limit: input?.filter?.limit
2932
- });
2933
- return {
2934
- items: page.items.map((item) => item.blobId),
2935
- ...page.nextCursor ? { nextCursor: page.nextCursor } : {}
2936
- };
2937
- }
2938
- }
2681
+ checkpoints: unsupportedCheckpoints,
2682
+ runEvents: unsupportedRunEvents
2939
2683
  };
2940
2684
  }
2941
2685
 
2686
+ // src/commands/connect/local-sqlite-agent-store.ts
2687
+ var sqliteByKey = /* @__PURE__ */ new Map();
2688
+ async function openSqliteLocalAgentStore(workspaceRef) {
2689
+ const cwd = workspaceRef.trim();
2690
+ if (!cwd) throw new Error("openSqliteLocalAgentStore: workspaceRef \u4E0D\u80FD\u4E3A\u7A7A");
2691
+ const existing = sqliteByKey.get(cwd);
2692
+ if (existing) return existing;
2693
+ const pending2 = SqliteLocalAgentStore.open({ workspaceRef: cwd }).then(
2694
+ (store) => {
2695
+ console.log(
2696
+ `[apm] Cursor store sqlite ready cwd=${cwd} stateRoot=${store.stateRoot}`
2697
+ );
2698
+ return store;
2699
+ }
2700
+ );
2701
+ sqliteByKey.set(cwd, pending2);
2702
+ return pending2;
2703
+ }
2704
+ async function createApmCursorAgentStore(cfg2, workspaceRef) {
2705
+ const cwd = workspaceRef.trim();
2706
+ const [sqlite, remote] = await Promise.all([
2707
+ openSqliteLocalAgentStore(cwd),
2708
+ Promise.resolve(createRemoteLocalAgentStore(cfg2))
2709
+ ]);
2710
+ return composeLocalAgentStore({
2711
+ agents: remote.agents,
2712
+ runs: remote.runs,
2713
+ checkpoints: sqlite.checkpoints,
2714
+ runEvents: sqlite.runEvents
2715
+ });
2716
+ }
2717
+ async function purgeLocalSqliteAgentData(input) {
2718
+ const agentId = input.agentId.trim();
2719
+ const workspaceRef = input.workspaceRef.trim();
2720
+ if (!agentId || !workspaceRef) return;
2721
+ const sqlite = await openSqliteLocalAgentStore(workspaceRef);
2722
+ const runIds = [...input.runIds ?? []];
2723
+ if (runIds.length > 0) {
2724
+ await sqlite.runEvents.delete({ filter: { runIds } });
2725
+ }
2726
+ await sqlite.checkpoints.delete({ filter: { agentIds: [agentId] } });
2727
+ }
2728
+
2942
2729
  // src/commands/connect/core/worker/run-steer.ts
2943
2730
  var impl = null;
2944
2731
  var pending = null;
@@ -2984,7 +2771,7 @@ function formatCursorRunFailure(runId, options) {
2984
2771
  return `Cursor run \u5931\u8D25: ${runId} \u2014 ${details.join("\uFF1B")}`;
2985
2772
  }
2986
2773
  async function obtainAgent(ctx) {
2987
- const store = createRemoteLocalAgentStore(ctx.cfg);
2774
+ const store = await createApmCursorAgentStore(ctx.cfg, ctx.cwd);
2988
2775
  const agentOptions = {
2989
2776
  apiKey: ctx.apiKey,
2990
2777
  model: { id: ctx.model || "default" },
@@ -3336,14 +3123,14 @@ function createThrottledWebIdeMessageLogSync(cfg2, ctx, onError, options) {
3336
3123
 
3337
3124
  // src/commands/sync-webide-agent.ts
3338
3125
  import {
3339
- existsSync as existsSync6,
3340
- mkdirSync as mkdirSync5,
3126
+ existsSync as existsSync5,
3127
+ mkdirSync as mkdirSync4,
3341
3128
  readdirSync as readdirSync3,
3342
- readFileSync as readFileSync5,
3343
- unlinkSync as unlinkSync2,
3344
- writeFileSync as writeFileSync4
3129
+ readFileSync as readFileSync4,
3130
+ unlinkSync,
3131
+ writeFileSync as writeFileSync3
3345
3132
  } from "fs";
3346
- import { join as join5 } from "path";
3133
+ import { join as join4 } from "path";
3347
3134
  var REVISION_FILE = ".webide-agent.json";
3348
3135
  var RULE_KEY = /^[a-z0-9_]+$/;
3349
3136
  function withTrailingNewline(text) {
@@ -3351,10 +3138,10 @@ function withTrailingNewline(text) {
3351
3138
  `;
3352
3139
  }
3353
3140
  function readRevision(apmDir) {
3354
- const path3 = toFsPath(join5(apmDir, REVISION_FILE));
3355
- if (!existsSync6(path3)) return null;
3141
+ const path3 = toFsPath(join4(apmDir, REVISION_FILE));
3142
+ if (!existsSync5(path3)) return null;
3356
3143
  try {
3357
- const parsed = JSON.parse(readFileSync5(path3, "utf8"));
3144
+ const parsed = JSON.parse(readFileSync4(path3, "utf8"));
3358
3145
  if (parsed?.version === 1 && parsed.revision?.trim()) {
3359
3146
  return parsed.revision.trim();
3360
3147
  }
@@ -3364,8 +3151,8 @@ function readRevision(apmDir) {
3364
3151
  return null;
3365
3152
  }
3366
3153
  function writeRevision(apmDir, revision) {
3367
- writeFileSync4(
3368
- toFsPath(join5(apmDir, REVISION_FILE)),
3154
+ writeFileSync3(
3155
+ toFsPath(join4(apmDir, REVISION_FILE)),
3369
3156
  `${JSON.stringify({ version: 1, revision }, null, 2)}
3370
3157
  `,
3371
3158
  "utf8"
@@ -3379,14 +3166,14 @@ async function syncWebIdeAgentFiles(workdir, cfg2) {
3379
3166
  throw new Error("[apm] \u5E73\u53F0\u672A\u8FD4\u56DE WebIDE \u89C4\u5219\u7248\u672C");
3380
3167
  }
3381
3168
  const apmDir = workspaceApmDir(workdir);
3382
- mkdirSync5(toFsPath(apmDir), { recursive: true });
3169
+ mkdirSync4(toFsPath(apmDir), { recursive: true });
3383
3170
  if (readRevision(apmDir) === revision) {
3384
3171
  return { revision, wrote: false, ruleCount: bundle.rules?.length ?? 0 };
3385
3172
  }
3386
- const rulesDir = join5(apmDir, "rules");
3387
- mkdirSync5(toFsPath(rulesDir), { recursive: true });
3388
- writeFileSync4(
3389
- toFsPath(join5(apmDir, "AGENTS.md")),
3173
+ const rulesDir = join4(apmDir, "rules");
3174
+ mkdirSync4(toFsPath(rulesDir), { recursive: true });
3175
+ writeFileSync3(
3176
+ toFsPath(join4(apmDir, "AGENTS.md")),
3390
3177
  withTrailingNewline(bundle.guide ?? ""),
3391
3178
  "utf8"
3392
3179
  );
@@ -3397,8 +3184,8 @@ async function syncWebIdeAgentFiles(workdir, cfg2) {
3397
3184
  throw new Error(`[apm] \u975E\u6CD5\u89C4\u5219\u540D: ${key || "(\u7A7A)"}`);
3398
3185
  }
3399
3186
  keep.add(`${key}.md`);
3400
- writeFileSync4(
3401
- toFsPath(join5(rulesDir, `${key}.md`)),
3187
+ writeFileSync3(
3188
+ toFsPath(join4(rulesDir, `${key}.md`)),
3402
3189
  withTrailingNewline(rule.body ?? ""),
3403
3190
  "utf8"
3404
3191
  );
@@ -3406,7 +3193,7 @@ async function syncWebIdeAgentFiles(workdir, cfg2) {
3406
3193
  for (const name of readdirSync3(toFsPath(rulesDir))) {
3407
3194
  if (!name.endsWith(".md")) continue;
3408
3195
  if (keep.has(name)) continue;
3409
- unlinkSync2(toFsPath(join5(rulesDir, name)));
3196
+ unlinkSync(toFsPath(join4(rulesDir, name)));
3410
3197
  }
3411
3198
  writeRevision(apmDir, revision);
3412
3199
  return {
@@ -3431,14 +3218,14 @@ async function ensureWorkspaceInitialized(workdir) {
3431
3218
 
3432
3219
  // src/utils/project-documents.ts
3433
3220
  import {
3434
- existsSync as existsSync7,
3221
+ existsSync as existsSync6,
3435
3222
  readdirSync as readdirSync4,
3436
- readFileSync as readFileSync6,
3437
- rmSync as rmSync2,
3438
- writeFileSync as writeFileSync5
3223
+ readFileSync as readFileSync5,
3224
+ rmSync,
3225
+ writeFileSync as writeFileSync4
3439
3226
  } from "fs";
3440
- import { createHash as createHash3 } from "crypto";
3441
- import { dirname as dirname3, join as join6, relative as relative4, sep } from "path";
3227
+ import { createHash as createHash2 } from "crypto";
3228
+ import { dirname as dirname2, join as join5, relative as relative4, sep } from "path";
3442
3229
  var MANIFEST_FILE = "manifest.json";
3443
3230
  function normalizeProjectIdForPath(projectId) {
3444
3231
  const id = projectId.trim();
@@ -3452,11 +3239,11 @@ function normalizeProjectIdForPath(projectId) {
3452
3239
  }
3453
3240
  function projectDocumentsDir(apmRoot, projectId) {
3454
3241
  const id = normalizeProjectIdForPath(projectId);
3455
- return join6(apmRoot ?? workspaceApmDir(), "project", id);
3242
+ return join5(apmRoot ?? workspaceApmDir(), "project", id);
3456
3243
  }
3457
3244
  function projectDocumentLocalPath(apmRoot, projectId, documentPath) {
3458
3245
  const normalized = normalizeLocalDocumentPath(documentPath);
3459
- return join6(
3246
+ return join5(
3460
3247
  projectDocumentsDir(apmRoot, projectId),
3461
3248
  ...normalized.split("/")
3462
3249
  );
@@ -3473,19 +3260,19 @@ function normalizeLocalDocumentPath(path3) {
3473
3260
  return segments.join("/");
3474
3261
  }
3475
3262
  function hashLocalFileContent(content) {
3476
- return createHash3("sha256").update(content, "utf8").digest("hex");
3263
+ return createHash2("sha256").update(content, "utf8").digest("hex");
3477
3264
  }
3478
3265
  function readLocalManifest(apmRoot, projectId) {
3479
- const manifestPath2 = join6(
3266
+ const manifestPath2 = join5(
3480
3267
  projectDocumentsDir(apmRoot, projectId),
3481
3268
  MANIFEST_FILE
3482
3269
  );
3483
- if (!existsSync7(manifestPath2)) {
3270
+ if (!existsSync6(manifestPath2)) {
3484
3271
  return null;
3485
3272
  }
3486
3273
  try {
3487
3274
  return JSON.parse(
3488
- readFileSync6(manifestPath2, "utf8")
3275
+ readFileSync5(manifestPath2, "utf8")
3489
3276
  );
3490
3277
  } catch {
3491
3278
  return null;
@@ -3493,13 +3280,13 @@ function readLocalManifest(apmRoot, projectId) {
3493
3280
  }
3494
3281
  function listLocalDocumentPaths(apmRoot, projectId) {
3495
3282
  const root = projectDocumentsDir(apmRoot, projectId);
3496
- if (!existsSync7(root)) {
3283
+ if (!existsSync6(root)) {
3497
3284
  return [];
3498
3285
  }
3499
3286
  const paths = [];
3500
3287
  const walk = (dir) => {
3501
3288
  for (const entry of readdirSync4(dir, { withFileTypes: true })) {
3502
- const abs = join6(dir, entry.name);
3289
+ const abs = join5(dir, entry.name);
3503
3290
  if (entry.isDirectory()) {
3504
3291
  walk(abs);
3505
3292
  continue;
@@ -3618,8 +3405,8 @@ ${diagnostic ?? ""}`);
3618
3405
  const absPath = toFsPath(
3619
3406
  projectDocumentLocalPath(targetApmDir, projectId, doc.path)
3620
3407
  );
3621
- await ensureDirExists(dirname3(absPath));
3622
- writeFileSync5(absPath, doc.content, "utf8");
3408
+ await ensureDirExists(dirname2(absPath));
3409
+ writeFileSync4(absPath, doc.content, "utf8");
3623
3410
  downloaded += 1;
3624
3411
  }
3625
3412
  }
@@ -3628,13 +3415,13 @@ ${diagnostic ?? ""}`);
3628
3415
  const absPath = toFsPath(
3629
3416
  projectDocumentLocalPath(targetApmDir, projectId, path3)
3630
3417
  );
3631
- if (existsSync7(absPath)) {
3632
- rmSync2(absPath, { force: true });
3418
+ if (existsSync6(absPath)) {
3419
+ rmSync(absPath, { force: true });
3633
3420
  deleted += 1;
3634
3421
  }
3635
3422
  }
3636
- writeFileSync5(
3637
- toFsPath(join6(docsDir, MANIFEST_FILE)),
3423
+ writeFileSync4(
3424
+ toFsPath(join5(docsDir, MANIFEST_FILE)),
3638
3425
  `${JSON.stringify(remoteManifest, null, 2)}
3639
3426
  `,
3640
3427
  "utf8"
@@ -3677,7 +3464,7 @@ async function syncProjectDocumentsPush(cfg2, workdirPath, apmRoot, options) {
3677
3464
  const absPath = toFsPath(
3678
3465
  projectDocumentLocalPath(targetApmDir, projectId, path3)
3679
3466
  );
3680
- const content = readFileSync6(absPath, "utf8");
3467
+ const content = readFileSync5(absPath, "utf8");
3681
3468
  const contentHash = hashLocalFileContent(content);
3682
3469
  if (remoteHashByPath.get(path3) === contentHash) {
3683
3470
  continue;
@@ -4162,18 +3949,18 @@ async function handleStartProject(cfg2, msg2, signal) {
4162
3949
  }
4163
3950
 
4164
3951
  // src/commands/connect/webide-agent-registry.ts
4165
- import { existsSync as existsSync8, mkdirSync as mkdirSync6, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "node:fs";
4166
- import { dirname as dirname4, resolve as resolve6 } from "node:path";
3952
+ import { existsSync as existsSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "node:fs";
3953
+ import { dirname as dirname3, resolve as resolve6 } from "node:path";
4167
3954
  function registryPath(workdir, taskId, fileName = "cursor-agent.json") {
4168
3955
  return resolve6(workdir, ".apm", "webide", taskId, fileName);
4169
3956
  }
4170
3957
  var DESIGN_AGENT_FILE = "design-agent.json";
4171
3958
  function readRegistry(path3) {
4172
- if (!existsSync8(path3)) {
3959
+ if (!existsSync7(path3)) {
4173
3960
  return {};
4174
3961
  }
4175
3962
  try {
4176
- const parsed = JSON.parse(readFileSync7(path3, "utf8"));
3963
+ const parsed = JSON.parse(readFileSync6(path3, "utf8"));
4177
3964
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
4178
3965
  const raw = parsed;
4179
3966
  const state = {};
@@ -4202,8 +3989,8 @@ function readRegistry(path3) {
4202
3989
  return {};
4203
3990
  }
4204
3991
  function writeRegistry(path3, registry) {
4205
- mkdirSync6(dirname4(path3), { recursive: true });
4206
- writeFileSync6(path3, `${JSON.stringify(registry, null, 2)}
3992
+ mkdirSync5(dirname3(path3), { recursive: true });
3993
+ writeFileSync5(path3, `${JSON.stringify(registry, null, 2)}
4207
3994
  `, "utf8");
4208
3995
  }
4209
3996
  function syncWebIdeTaskState(workdir, taskId, patch) {
@@ -4244,7 +4031,7 @@ function saveWebIdeAgentId(workdir, taskId, agentId) {
4244
4031
  }
4245
4032
  function clearWebIdeAgentId(workdir, taskId) {
4246
4033
  const path3 = registryPath(workdir, taskId);
4247
- if (!existsSync8(path3)) return;
4034
+ if (!existsSync7(path3)) return;
4248
4035
  syncWebIdeTaskState(workdir, taskId, { agentId: "" });
4249
4036
  }
4250
4037
  function loadWebIdeDesignAgentId(workdir, taskId) {
@@ -4264,7 +4051,7 @@ function saveWebIdeDesignAgentId(workdir, taskId, agentId) {
4264
4051
  }
4265
4052
  function clearWebIdeDesignAgentId(workdir, taskId) {
4266
4053
  const path3 = registryPath(workdir, taskId, DESIGN_AGENT_FILE);
4267
- if (!existsSync8(path3)) return;
4054
+ if (!existsSync7(path3)) return;
4268
4055
  const current = readRegistry(path3);
4269
4056
  const next = { ...current };
4270
4057
  delete next.agentId;
@@ -4276,9 +4063,9 @@ function clearWebIdeDesignAgentId(workdir, taskId) {
4276
4063
  }
4277
4064
 
4278
4065
  // src/commands/clean-webide-cache.ts
4279
- import { existsSync as existsSync9, rmSync as rmSync3 } from "node:fs";
4066
+ import { existsSync as existsSync8, rmSync as rmSync2 } from "node:fs";
4280
4067
  import { resolve as resolve7 } from "node:path";
4281
- async function purgeCursorAgentStoreForAgent(cfg2, agentId) {
4068
+ async function purgeCursorAgentStoreForAgent(cfg2, agentId, workspaceRef) {
4282
4069
  const trimmedAgentId = agentId.trim();
4283
4070
  if (!trimmedAgentId) return false;
4284
4071
  const store = createRemoteLocalAgentStore(cfg2);
@@ -4297,13 +4084,16 @@ async function purgeCursorAgentStoreForAgent(cfg2, agentId) {
4297
4084
  }
4298
4085
  cursor = page.nextCursor;
4299
4086
  } while (cursor);
4300
- if (runIds.length > 0) {
4301
- await store.runEvents.delete({ filter: { runIds } });
4302
- }
4303
4087
  await store.runs.delete({ filter: { agentIds: [trimmedAgentId] } });
4304
- await store.checkpoints.delete({ filter: { agentIds: [trimmedAgentId] } });
4305
4088
  await store.agents.delete({ filter: { agentIds: [trimmedAgentId] } });
4306
- clearLocalCheckpointCache(trimmedAgentId);
4089
+ const workdir = workspaceRef?.trim();
4090
+ if (workdir) {
4091
+ await purgeLocalSqliteAgentData({
4092
+ workspaceRef: workdir,
4093
+ agentId: trimmedAgentId,
4094
+ runIds
4095
+ });
4096
+ }
4307
4097
  return true;
4308
4098
  }
4309
4099
  async function cleanWebIdeWorkspaceCache(taskId, workdir, cfg2) {
@@ -4315,7 +4105,11 @@ async function cleanWebIdeWorkspaceCache(taskId, workdir, cfg2) {
4315
4105
  const agentId = loadWebIdeAgentId(trimmedWorkdir, trimmedTaskId);
4316
4106
  if (agentId) {
4317
4107
  try {
4318
- const purged = await purgeCursorAgentStoreForAgent(cfg2, agentId);
4108
+ const purged = await purgeCursorAgentStoreForAgent(
4109
+ cfg2,
4110
+ agentId,
4111
+ trimmedWorkdir
4112
+ );
4319
4113
  if (purged) {
4320
4114
  console.log(
4321
4115
  `[apm] \u5DF2\u6E05\u7406 Cursor agent store agentId=${agentId} taskId=${trimmedTaskId}`
@@ -4333,8 +4127,8 @@ async function cleanWebIdeWorkspaceCache(taskId, workdir, cfg2) {
4333
4127
  );
4334
4128
  }
4335
4129
  const dir = resolve7(trimmedWorkdir, ".apm", "webide", trimmedTaskId);
4336
- if (existsSync9(dir)) {
4337
- rmSync3(dir, { recursive: true, force: true });
4130
+ if (existsSync8(dir)) {
4131
+ rmSync2(dir, { recursive: true, force: true });
4338
4132
  console.log(`[apm] \u5DF2\u6E05\u7406 WebIDE \u7F13\u5B58 ${dir}`);
4339
4133
  } else {
4340
4134
  console.log(`[apm] WebIDE \u7F13\u5B58\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7 ${dir}`);
@@ -4655,8 +4449,8 @@ async function ensureWebIdePullRequests(cfg2, taskId, workdir) {
4655
4449
  }
4656
4450
 
4657
4451
  // src/commands/sync-webide-attachments.ts
4658
- import { existsSync as existsSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "fs";
4659
- import { join as join7 } from "path";
4452
+ import { existsSync as existsSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
4453
+ import { join as join6 } from "path";
4660
4454
  var MANIFEST_FILE2 = ".sync-manifest.json";
4661
4455
  async function downloadAttachment(cfg2, attachmentId) {
4662
4456
  const base = cfg2.baseUrl.trim().replace(/\/+$/, "");
@@ -4672,13 +4466,13 @@ async function downloadAttachment(cfg2, attachmentId) {
4672
4466
  return Buffer.from(await res.arrayBuffer());
4673
4467
  }
4674
4468
  function loadManifest(dir) {
4675
- const path3 = join7(dir, MANIFEST_FILE2);
4676
- if (!existsSync10(path3)) {
4469
+ const path3 = join6(dir, MANIFEST_FILE2);
4470
+ if (!existsSync9(path3)) {
4677
4471
  return { version: 1, attachments: {} };
4678
4472
  }
4679
4473
  try {
4680
4474
  const parsed = JSON.parse(
4681
- readFileSync8(path3, "utf8")
4475
+ readFileSync7(path3, "utf8")
4682
4476
  );
4683
4477
  if (parsed?.version === 1 && parsed.attachments && typeof parsed.attachments === "object") {
4684
4478
  return parsed;
@@ -4688,15 +4482,15 @@ function loadManifest(dir) {
4688
4482
  return { version: 1, attachments: {} };
4689
4483
  }
4690
4484
  function saveManifest(dir, manifest) {
4691
- writeFileSync7(
4692
- join7(dir, MANIFEST_FILE2),
4485
+ writeFileSync6(
4486
+ join6(dir, MANIFEST_FILE2),
4693
4487
  `${JSON.stringify(manifest, null, 2)}
4694
4488
  `,
4695
4489
  "utf8"
4696
4490
  );
4697
4491
  }
4698
4492
  function isAttachmentUpToDate(entry, item, dest) {
4699
- if (!entry || !existsSync10(dest)) return false;
4493
+ if (!entry || !existsSync9(dest)) return false;
4700
4494
  if (entry.name !== item.name) return false;
4701
4495
  const createdAt = item.createdAt ?? "";
4702
4496
  return entry.createdAt === createdAt;
@@ -4711,7 +4505,7 @@ async function syncAttachmentsToDirectory(cfg2, attachments, dir, logLabel) {
4711
4505
  const nextManifest = { version: 1, attachments: {} };
4712
4506
  const names = [];
4713
4507
  for (const item of attachments) {
4714
- const dest = join7(dir, item.name);
4508
+ const dest = join6(dir, item.name);
4715
4509
  const entry = manifest.attachments[item.id];
4716
4510
  const createdAt = item.createdAt ?? "";
4717
4511
  names.push(item.name);
@@ -4721,7 +4515,7 @@ async function syncAttachmentsToDirectory(cfg2, attachments, dir, logLabel) {
4721
4515
  continue;
4722
4516
  }
4723
4517
  const buffer = await downloadAttachment(cfg2, item.id);
4724
- writeFileSync7(dest, buffer);
4518
+ writeFileSync6(dest, buffer);
4725
4519
  nextManifest.attachments[item.id] = {
4726
4520
  name: item.name,
4727
4521
  createdAt
@@ -4742,9 +4536,9 @@ async function syncWebIdeAttachments(cfg2, taskId, workdir, attachments) {
4742
4536
  }
4743
4537
 
4744
4538
  // src/commands/sync-webide-design.ts
4745
- import { createHash as createHash4 } from "crypto";
4746
- import { existsSync as existsSync11, readdirSync as readdirSync5, readFileSync as readFileSync9, statSync as statSync5, writeFileSync as writeFileSync8 } from "fs";
4747
- import { join as join8 } from "path";
4539
+ import { createHash as createHash3 } from "crypto";
4540
+ import { existsSync as existsSync10, readdirSync as readdirSync5, readFileSync as readFileSync8, statSync as statSync5, writeFileSync as writeFileSync7 } from "fs";
4541
+ import { join as join7 } from "path";
4748
4542
 
4749
4543
  // src/opc-shared-types.ts
4750
4544
  function webIdeDesignObjectKey(taskId, fileName) {
@@ -4762,15 +4556,15 @@ function webIdeDesignArtifactContentType(name) {
4762
4556
  // src/commands/sync-webide-design.ts
4763
4557
  var MANIFEST_FILE3 = ".sync-manifest.json";
4764
4558
  function hashBuffer(buf) {
4765
- return createHash4("sha256").update(buf).digest("hex");
4559
+ return createHash3("sha256").update(buf).digest("hex");
4766
4560
  }
4767
4561
  function loadManifest2(dir) {
4768
- const path3 = join8(dir, MANIFEST_FILE3);
4769
- if (!existsSync11(path3)) {
4562
+ const path3 = join7(dir, MANIFEST_FILE3);
4563
+ if (!existsSync10(path3)) {
4770
4564
  return { version: 1, files: {} };
4771
4565
  }
4772
4566
  try {
4773
- const parsed = JSON.parse(readFileSync9(path3, "utf8"));
4567
+ const parsed = JSON.parse(readFileSync8(path3, "utf8"));
4774
4568
  if (parsed?.version === 1 && parsed.files && typeof parsed.files === "object") {
4775
4569
  return parsed;
4776
4570
  }
@@ -4779,8 +4573,8 @@ function loadManifest2(dir) {
4779
4573
  return { version: 1, files: {} };
4780
4574
  }
4781
4575
  function saveManifest2(dir, manifest) {
4782
- writeFileSync8(
4783
- join8(dir, MANIFEST_FILE3),
4576
+ writeFileSync7(
4577
+ join7(dir, MANIFEST_FILE3),
4784
4578
  `${JSON.stringify(manifest, null, 2)}
4785
4579
  `,
4786
4580
  "utf8"
@@ -4808,13 +4602,13 @@ async function syncWebIdeDesign(cfg2, taskId, workdir, artifacts) {
4808
4602
  for (const art of artifacts) {
4809
4603
  const name = art.name?.trim();
4810
4604
  if (!name || !isWebIdeDesignArtifactName(name)) continue;
4811
- const localPath = join8(dir, name);
4605
+ const localPath = join7(dir, name);
4812
4606
  const entry = manifest.files[name];
4813
- if (entry?.contentHash === art.contentHash && existsSync11(localPath)) {
4607
+ if (entry?.contentHash === art.contentHash && existsSync10(localPath)) {
4814
4608
  continue;
4815
4609
  }
4816
4610
  const buf = await downloadDesignFile(cfg2, taskId, name);
4817
- writeFileSync8(localPath, buf);
4611
+ writeFileSync7(localPath, buf);
4818
4612
  manifest.files[name] = { contentHash: hashBuffer(buf) };
4819
4613
  synced.push(name);
4820
4614
  }
@@ -4823,13 +4617,13 @@ async function syncWebIdeDesign(cfg2, taskId, workdir, artifacts) {
4823
4617
  }
4824
4618
  function listLocalDesignArtifactFiles(taskId, workdir) {
4825
4619
  const dir = webideDesignDir(taskId, workdir);
4826
- if (!existsSync11(dir)) return [];
4620
+ if (!existsSync10(dir)) return [];
4827
4621
  const out = [];
4828
4622
  for (const name of readdirSync5(dir)) {
4829
4623
  if (!isWebIdeDesignArtifactName(name)) continue;
4830
- const absPath = join8(dir, name);
4624
+ const absPath = join7(dir, name);
4831
4625
  if (!statSync5(absPath).isFile()) continue;
4832
- const buf = readFileSync9(absPath);
4626
+ const buf = readFileSync8(absPath);
4833
4627
  if (buf.length === 0) continue;
4834
4628
  out.push({ name, absPath, contentHash: hashBuffer(buf) });
4835
4629
  }
@@ -4934,26 +4728,36 @@ function completeActionForInbound(action) {
4934
4728
  switch (action) {
4935
4729
  case "request-assessment":
4936
4730
  case "confirm-assumptions":
4731
+ case "start-assessment":
4732
+ case "continue-assessment":
4937
4733
  return "complete-assessment";
4938
4734
  case "request-design":
4939
4735
  case "request-revise-design":
4736
+ case "start-design":
4940
4737
  return "complete-design";
4941
4738
  case "request-write-plan":
4942
4739
  case "request-revise-plan":
4740
+ case "start-write-plan":
4943
4741
  return "complete-write-plan";
4944
4742
  case "request-develop":
4945
4743
  case "skip-plan":
4744
+ case "start-develop":
4946
4745
  return "complete-develop";
4947
4746
  case "request-start-project":
4747
+ case "start-project":
4948
4748
  return "complete-project";
4949
4749
  case "request-execute-sql":
4750
+ case "start-execute-sql":
4950
4751
  return "complete-execute-sql";
4951
4752
  case "request-bugfix":
4753
+ case "start-bugfix":
4952
4754
  return "complete-bugfix";
4953
4755
  case "request-organize-code":
4954
4756
  case "request-patch":
4757
+ case "start-organize-code":
4955
4758
  return "complete-organize-code";
4956
4759
  case "request-accept":
4760
+ case "start-accept":
4957
4761
  return "complete-accept";
4958
4762
  default:
4959
4763
  return null;
@@ -4964,6 +4768,13 @@ async function webIdeRunAction(cfg2, taskId, action, params) {
4964
4768
  await api.cli.webideRunAction({ taskId, action, params });
4965
4769
  console.log(`[apm] webide runAction ok action=${action} taskId=${taskId}`);
4966
4770
  }
4771
+ async function webIdeAttachContinueRun(cfg2, taskId, runId) {
4772
+ const api = createApmApiClient(cfg2);
4773
+ await api.cli.webideAttachContinueRun({ taskId, runId });
4774
+ console.log(
4775
+ `[apm] webide attachContinueRun ok runId=${runId} taskId=${taskId}`
4776
+ );
4777
+ }
4967
4778
  async function webIdeSyncTransitionPrepEvents(cfg2, taskId, startAction, prepEvents) {
4968
4779
  try {
4969
4780
  const api = createApmApiClient(cfg2);
@@ -5036,8 +4847,11 @@ async function handleWebIdeInboundMessage(cfg2, msg2, signal) {
5036
4847
  const messageId = msg2.messageId;
5037
4848
  const taskId = msg2.taskId;
5038
4849
  const branchCacheKey = taskId;
4850
+ const continuePayload = msg2.action === "continue" ? parseWebIdePromptPayload(msg2.content) : null;
4851
+ const previousAction = typeof continuePayload?.previousAction === "string" ? continuePayload.previousAction.trim() : "";
4852
+ const effectiveAction = msg2.action === "continue" && previousAction ? previousAction : msg2.action;
5039
4853
  console.log(
5040
- `[apm] webide-message action=${msg2.action} taskId=${taskId} messageId=${messageId}`
4854
+ `[apm] webide-message action=${msg2.action}${previousAction ? ` previousAction=${previousAction}` : ""} taskId=${taskId} messageId=${messageId}`
5041
4855
  );
5042
4856
  await updateStatus2(cfg2, messageId, "TYPING");
5043
4857
  syncLocalTaskStatus(workdir, taskId, msg2, "TYPING");
@@ -5140,7 +4954,7 @@ async function handleWebIdeInboundMessage(cfg2, msg2, signal) {
5140
4954
  eventSession.addCliStep("\u51C6\u5907\u7279\u6027\u5206\u652F", "\u5DF2\u7F13\u5B58\uFF0C\u8DF3\u8FC7", "skip");
5141
4955
  await syncPrepLog();
5142
4956
  }
5143
- if (shouldEnsureWebIdePullRequests(msg2.action)) {
4957
+ if (shouldEnsureWebIdePullRequests(effectiveAction)) {
5144
4958
  if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
5145
4959
  await runPrepStep(
5146
4960
  "\u9A8C\u6536\u524D\u63A8\u9001",
@@ -5246,8 +5060,8 @@ async function handleWebIdeInboundMessage(cfg2, msg2, signal) {
5246
5060
  "running"
5247
5061
  );
5248
5062
  await syncPrepLog();
5249
- const startLocalServices = isStartLocalServicesAction(msg2.action);
5250
- const designAction = isDesignAction(msg2.action);
5063
+ const startLocalServices = isStartLocalServicesAction(effectiveAction);
5064
+ const designAction = isDesignAction(effectiveAction);
5251
5065
  const useNewAgent = msg2.useNewAgent === true;
5252
5066
  const toolNames = Array.isArray(msg2.tools) ? msg2.tools.map((t) => String(t).trim()).filter(Boolean) : [];
5253
5067
  if (useNewAgent && !startLocalServices) {
@@ -5258,7 +5072,7 @@ async function handleWebIdeInboundMessage(cfg2, msg2, signal) {
5258
5072
  }
5259
5073
  }
5260
5074
  const savedAgentId = startLocalServices || useNewAgent ? void 0 : designAction ? loadWebIdeDesignAgentId(workdir, taskId) : loadWebIdeAgentId(workdir, taskId);
5261
- const promptPayload = toolNames.includes("MysqlExecute") ? parseWebIdePromptPayload(msg2.content) : null;
5075
+ const promptPayload = toolNames.includes("MysqlExecute") ? continuePayload ?? parseWebIdePromptPayload(msg2.content) : null;
5262
5076
  const sqlExecutionId = toolNames.includes("MysqlExecute") && typeof promptPayload?.executionId === "string" ? promptPayload.executionId.trim() : void 0;
5263
5077
  if (toolNames.includes("MysqlExecute") && !sqlExecutionId) {
5264
5078
  console.warn(
@@ -5348,6 +5162,15 @@ ${assumptionAnswersText}` : msg2.content,
5348
5162
  eventSession.getCliSteps()
5349
5163
  );
5350
5164
  await webIdeRunAction(cfg2, taskId, startAction, { runId });
5165
+ } else if (msg2.action === "continue") {
5166
+ try {
5167
+ await webIdeAttachContinueRun(cfg2, taskId, runId);
5168
+ } catch (err) {
5169
+ console.warn(
5170
+ "[apm] attach continue run failed:",
5171
+ err instanceof Error ? err.message : err
5172
+ );
5173
+ }
5351
5174
  }
5352
5175
  }
5353
5176
  }
@@ -5374,7 +5197,7 @@ ${assumptionAnswersText}` : msg2.content,
5374
5197
  detail,
5375
5198
  tokenUsage
5376
5199
  );
5377
- if (sqlExecutionId && msg2.action !== "request-bugfix") {
5200
+ if (sqlExecutionId && effectiveAction !== "request-bugfix") {
5378
5201
  try {
5379
5202
  await api.cli.webideFinalizeSqlExecution({
5380
5203
  executionId: sqlExecutionId,
@@ -5399,7 +5222,7 @@ ${assumptionAnswersText}` : msg2.content,
5399
5222
  "\u5DF2\u53D6\u6D88",
5400
5223
  tokenUsage
5401
5224
  );
5402
- if (sqlExecutionId && msg2.action !== "request-bugfix") {
5225
+ if (sqlExecutionId && effectiveAction !== "request-bugfix") {
5403
5226
  try {
5404
5227
  await api.cli.webideFinalizeSqlExecution({
5405
5228
  executionId: sqlExecutionId,
@@ -5426,7 +5249,7 @@ ${assumptionAnswersText}` : msg2.content,
5426
5249
  id: messageId,
5427
5250
  content: fallback
5428
5251
  });
5429
- if ((msg2.action === "write-plan" || msg2.action === "revise-plan") && outcome.createPlan && outcome.createPlan.trim()) {
5252
+ if ((effectiveAction === "write-plan" || effectiveAction === "revise-plan" || effectiveAction === "request-write-plan" || effectiveAction === "request-revise-plan" || effectiveAction === "start-write-plan") && outcome.createPlan && outcome.createPlan.trim()) {
5430
5253
  try {
5431
5254
  await api.cli.webideUpsertPlan({
5432
5255
  taskId,
@@ -5434,12 +5257,12 @@ ${assumptionAnswersText}` : msg2.content,
5434
5257
  });
5435
5258
  } catch (err) {
5436
5259
  console.warn(
5437
- `[apm] ${msg2.action} \u8865\u5199\u8BA1\u5212\u5931\u8D25:`,
5260
+ `[apm] ${effectiveAction} \u8865\u5199\u8BA1\u5212\u5931\u8D25:`,
5438
5261
  err instanceof Error ? err.message : err
5439
5262
  );
5440
5263
  }
5441
5264
  }
5442
- if (isDesignAction(msg2.action)) {
5265
+ if (isDesignAction(effectiveAction)) {
5443
5266
  if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
5444
5267
  try {
5445
5268
  const uploaded = await uploadWebIdeDesignArtifacts(
@@ -5448,7 +5271,7 @@ ${assumptionAnswersText}` : msg2.content,
5448
5271
  workdir
5449
5272
  );
5450
5273
  console.log(
5451
- `[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(",")}`
5274
+ `[apm] webide \u8BBE\u8BA1\u4EA7\u7269\u4E0A\u4F20 action=${effectiveAction} uploaded=${uploaded.uploaded} skipped=${uploaded.skipped} files=${uploaded.artifacts.map((a) => a.name).join(",")}`
5452
5275
  );
5453
5276
  } catch (err) {
5454
5277
  const detail = err instanceof Error ? err.message : String(err);
@@ -5463,27 +5286,27 @@ ${assumptionAnswersText}` : msg2.content,
5463
5286
  return;
5464
5287
  }
5465
5288
  }
5466
- if (shouldCommitAfterWebIdeMessage(msg2.action)) {
5289
+ if (shouldCommitAfterWebIdeMessage(effectiveAction)) {
5467
5290
  if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
5468
5291
  const committed = await commitWorkspaceReposIfDirty(
5469
5292
  workdir,
5470
- `chore(webide): sync after ${msg2.action} (${taskId})`
5293
+ `chore(webide): sync after ${effectiveAction} (${taskId})`
5471
5294
  );
5472
5295
  console.log(
5473
- `[apm] webide \u515C\u5E95 commit action=${msg2.action} repos=${committed}`
5296
+ `[apm] webide \u515C\u5E95 commit action=${effectiveAction} repos=${committed}`
5474
5297
  );
5475
5298
  if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
5476
5299
  const pushed = await pushWorkspaceRepos(workdir);
5477
5300
  console.log(
5478
- `[apm] webide \u81EA\u52A8 push action=${msg2.action} repos=${pushed}`
5301
+ `[apm] webide \u81EA\u52A8 push action=${effectiveAction} repos=${pushed}`
5479
5302
  );
5480
5303
  }
5481
- if (shouldEnsureWebIdePullRequestsAfterAgent(msg2.action)) {
5304
+ if (shouldEnsureWebIdePullRequestsAfterAgent(effectiveAction)) {
5482
5305
  if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
5483
- if (!shouldCommitAfterWebIdeMessage(msg2.action)) {
5306
+ if (!shouldCommitAfterWebIdeMessage(effectiveAction)) {
5484
5307
  const pushed = await pushWorkspaceRepos(workdir);
5485
5308
  console.log(
5486
- `[apm] webide create-pr \u524D push action=${msg2.action} repos=${pushed}`
5309
+ `[apm] webide create-pr \u524D push action=${effectiveAction} repos=${pushed}`
5487
5310
  );
5488
5311
  }
5489
5312
  const prResult = await ensureWebIdePullRequests(cfg2, taskId, workdir);
@@ -5537,20 +5360,20 @@ ${assumptionAnswersText}` : msg2.content,
5537
5360
  null,
5538
5361
  tokenUsage
5539
5362
  );
5540
- const completeAction = completeActionForInbound(msg2.action);
5363
+ const completeAction = completeActionForInbound(effectiveAction);
5541
5364
  if (completeAction && !pausedForAssumptions) {
5542
5365
  await webIdeRunAction(cfg2, taskId, completeAction);
5543
5366
  } else if (pausedForAssumptions) {
5544
5367
  console.log(
5545
- `[apm] \u672C\u8F6E\u505C\u5728\u5F85\u786E\u8BA4\u5047\u8BBE\uFF0C\u8DF3\u8FC7 complete action=${msg2.action} taskId=${taskId}`
5368
+ `[apm] \u672C\u8F6E\u505C\u5728\u5F85\u786E\u8BA4\u5047\u8BBE\uFF0C\u8DF3\u8FC7 complete action=${effectiveAction} taskId=${taskId}`
5546
5369
  );
5547
5370
  }
5548
5371
  await updateStatus2(cfg2, messageId, "SUCCESS");
5549
5372
  syncLocalTaskStatus(workdir, taskId, msg2, "SUCCESS");
5550
5373
  console.log(
5551
- `[apm] webide-message \u5B8C\u6210 action=${msg2.action} messageId=${messageId} agentId=${outcome.agentId}`
5374
+ `[apm] webide-message \u5B8C\u6210 action=${msg2.action}${previousAction ? ` previousAction=${previousAction}` : ""} messageId=${messageId} agentId=${outcome.agentId}`
5552
5375
  );
5553
- if (msg2.action === "request-accept") {
5376
+ if (effectiveAction === "request-accept" || effectiveAction === "start-accept") {
5554
5377
  try {
5555
5378
  await cleanWebIdeWorkspaceCache(taskId, workdir, cfg2);
5556
5379
  } catch (err) {
@@ -5577,7 +5400,7 @@ ${assumptionAnswersText}` : msg2.content,
5577
5400
  statusErr instanceof Error ? statusErr.message : statusErr
5578
5401
  );
5579
5402
  }
5580
- const completeAction = completeActionForInbound(msg2.action);
5403
+ const completeAction = completeActionForInbound(effectiveAction);
5581
5404
  if (completeAction === "complete-assessment" && !pausedForAssumptions) {
5582
5405
  try {
5583
5406
  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.13",
3
+ "version": "8.1.15",
4
4
  "description": "命令行工具:后续用于调用平台后端 API 完成运维与自动化操作",
5
5
  "type": "module",
6
6
  "private": false,