ai-project-manage-cli 8.1.4 → 8.1.6

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
@@ -287,6 +287,11 @@ var requestConfig = {
287
287
  method: "POST",
288
288
  path: "/cli/webide/actions"
289
289
  }),
290
+ /** CLI 准备步骤实时回写到「待→进行中」转移线 */
291
+ webideUpdateTransitionPrepEvents: defineEndpoint({
292
+ method: "PUT",
293
+ path: "/cli/webide/transition-prep-events"
294
+ }),
290
295
  webideUpsertMessageLog: defineEndpoint({
291
296
  method: "PUT",
292
297
  path: "/cli/webide/message-logs"
@@ -376,6 +381,66 @@ var requestConfig = {
376
381
  projectPackageEnsureContent: defineEndpoint({
377
382
  method: "PUT",
378
383
  path: "/cli/project-packages/ensure-content"
384
+ }),
385
+ cursorStoreUpsertAgent: defineEndpoint({
386
+ method: "PUT",
387
+ path: "/cli/cursor-store/agents"
388
+ }),
389
+ cursorStoreGetAgent: defineEndpoint({
390
+ method: "GET",
391
+ path: "/cli/cursor-store/agents/get"
392
+ }),
393
+ cursorStoreListAgents: defineEndpoint({
394
+ method: "POST",
395
+ path: "/cli/cursor-store/agents/list"
396
+ }),
397
+ cursorStoreDeleteAgents: defineEndpoint({
398
+ method: "POST",
399
+ path: "/cli/cursor-store/agents/delete"
400
+ }),
401
+ cursorStoreUpsertRun: defineEndpoint({
402
+ method: "PUT",
403
+ path: "/cli/cursor-store/runs"
404
+ }),
405
+ cursorStoreGetRun: defineEndpoint({
406
+ method: "GET",
407
+ path: "/cli/cursor-store/runs/get"
408
+ }),
409
+ cursorStoreListRuns: defineEndpoint({
410
+ method: "POST",
411
+ path: "/cli/cursor-store/runs/list"
412
+ }),
413
+ cursorStoreDeleteRuns: defineEndpoint({
414
+ method: "POST",
415
+ path: "/cli/cursor-store/runs/delete"
416
+ }),
417
+ cursorStoreAppendRunEvents: defineEndpoint({
418
+ method: "POST",
419
+ path: "/cli/cursor-store/run-events/append"
420
+ }),
421
+ cursorStoreListRunEvents: defineEndpoint({
422
+ method: "POST",
423
+ path: "/cli/cursor-store/run-events/list"
424
+ }),
425
+ cursorStoreDeleteRunEvents: defineEndpoint({
426
+ method: "POST",
427
+ path: "/cli/cursor-store/run-events/delete"
428
+ }),
429
+ cursorStorePutCheckpoint: defineEndpoint({
430
+ method: "PUT",
431
+ path: "/cli/cursor-store/checkpoints"
432
+ }),
433
+ cursorStoreGetCheckpoint: defineEndpoint({
434
+ method: "GET",
435
+ path: "/cli/cursor-store/checkpoints/get"
436
+ }),
437
+ cursorStoreListCheckpoints: defineEndpoint({
438
+ method: "POST",
439
+ path: "/cli/cursor-store/checkpoints/list"
440
+ }),
441
+ cursorStoreDeleteCheckpoints: defineEndpoint({
442
+ method: "POST",
443
+ path: "/cli/cursor-store/checkpoints/delete"
379
444
  })
380
445
  }
381
446
  };
@@ -35,6 +35,11 @@ var requestConfig = {
35
35
  method: "POST",
36
36
  path: "/cli/webide/actions"
37
37
  }),
38
+ /** CLI 准备步骤实时回写到「待→进行中」转移线 */
39
+ webideUpdateTransitionPrepEvents: defineEndpoint({
40
+ method: "PUT",
41
+ path: "/cli/webide/transition-prep-events"
42
+ }),
38
43
  webideUpsertMessageLog: defineEndpoint({
39
44
  method: "PUT",
40
45
  path: "/cli/webide/message-logs"
@@ -124,6 +129,66 @@ var requestConfig = {
124
129
  projectPackageEnsureContent: defineEndpoint({
125
130
  method: "PUT",
126
131
  path: "/cli/project-packages/ensure-content"
132
+ }),
133
+ cursorStoreUpsertAgent: defineEndpoint({
134
+ method: "PUT",
135
+ path: "/cli/cursor-store/agents"
136
+ }),
137
+ cursorStoreGetAgent: defineEndpoint({
138
+ method: "GET",
139
+ path: "/cli/cursor-store/agents/get"
140
+ }),
141
+ cursorStoreListAgents: defineEndpoint({
142
+ method: "POST",
143
+ path: "/cli/cursor-store/agents/list"
144
+ }),
145
+ cursorStoreDeleteAgents: defineEndpoint({
146
+ method: "POST",
147
+ path: "/cli/cursor-store/agents/delete"
148
+ }),
149
+ cursorStoreUpsertRun: defineEndpoint({
150
+ method: "PUT",
151
+ path: "/cli/cursor-store/runs"
152
+ }),
153
+ cursorStoreGetRun: defineEndpoint({
154
+ method: "GET",
155
+ path: "/cli/cursor-store/runs/get"
156
+ }),
157
+ cursorStoreListRuns: defineEndpoint({
158
+ method: "POST",
159
+ path: "/cli/cursor-store/runs/list"
160
+ }),
161
+ cursorStoreDeleteRuns: defineEndpoint({
162
+ method: "POST",
163
+ path: "/cli/cursor-store/runs/delete"
164
+ }),
165
+ cursorStoreAppendRunEvents: defineEndpoint({
166
+ method: "POST",
167
+ path: "/cli/cursor-store/run-events/append"
168
+ }),
169
+ cursorStoreListRunEvents: defineEndpoint({
170
+ method: "POST",
171
+ path: "/cli/cursor-store/run-events/list"
172
+ }),
173
+ cursorStoreDeleteRunEvents: defineEndpoint({
174
+ method: "POST",
175
+ path: "/cli/cursor-store/run-events/delete"
176
+ }),
177
+ cursorStorePutCheckpoint: defineEndpoint({
178
+ method: "PUT",
179
+ path: "/cli/cursor-store/checkpoints"
180
+ }),
181
+ cursorStoreGetCheckpoint: defineEndpoint({
182
+ method: "GET",
183
+ path: "/cli/cursor-store/checkpoints/get"
184
+ }),
185
+ cursorStoreListCheckpoints: defineEndpoint({
186
+ method: "POST",
187
+ path: "/cli/cursor-store/checkpoints/list"
188
+ }),
189
+ cursorStoreDeleteCheckpoints: defineEndpoint({
190
+ method: "POST",
191
+ path: "/cli/cursor-store/checkpoints/delete"
127
192
  })
128
193
  }
129
194
  };
@@ -1156,6 +1221,16 @@ var EventSession = class {
1156
1221
  });
1157
1222
  this.markDirty(this.events.length - 1);
1158
1223
  }
1224
+ /** 导出当前 CLI 准备步骤快照(供 start-* 写入转移日志) */
1225
+ getCliSteps() {
1226
+ return this.events.filter((e) => e.type === "cli_step" && typeof e.step === "string").map((e) => ({
1227
+ step: String(e.step),
1228
+ status: typeof e.status === "string" ? e.status : "ok",
1229
+ text: typeof e.text === "string" ? e.text : "",
1230
+ ...typeof e.at === "string" ? { at: e.at } : {},
1231
+ ...typeof e.durationMs === "number" && Number.isFinite(e.durationMs) ? { durationMs: e.durationMs } : {}
1232
+ }));
1233
+ }
1159
1234
  formatEvent(event) {
1160
1235
  switch (event.type) {
1161
1236
  case "assistant": {
@@ -2385,6 +2460,330 @@ function createPtySessionMcpServers(cfg2) {
2385
2460
  };
2386
2461
  }
2387
2462
 
2463
+ // src/commands/connect/remote-local-agent-store.ts
2464
+ function asCheckpointRef(value) {
2465
+ if (value === void 0) return void 0;
2466
+ if (value === null) return null;
2467
+ if (!value || typeof value !== "object") return null;
2468
+ const row = value;
2469
+ if (typeof row.rootBlobId !== "string" || !row.rootBlobId.trim()) {
2470
+ return null;
2471
+ }
2472
+ return {
2473
+ schemaVersion: 1,
2474
+ rootBlobId: row.rootBlobId
2475
+ };
2476
+ }
2477
+ function toApiCheckpointRef(ref) {
2478
+ if (ref === void 0) return void 0;
2479
+ if (ref === null) return null;
2480
+ return {
2481
+ schemaVersion: ref.schemaVersion,
2482
+ rootBlobId: ref.rootBlobId
2483
+ };
2484
+ }
2485
+ function fromApiAgent(row) {
2486
+ return {
2487
+ agentId: row.agentId,
2488
+ cwd: row.cwd,
2489
+ status: row.status,
2490
+ activeRunId: row.activeRunId,
2491
+ name: row.name,
2492
+ createdAt: row.createdAt,
2493
+ updatedAt: row.updatedAt,
2494
+ latestCheckpoint: asCheckpointRef(row.latestCheckpoint) ?? null,
2495
+ sdkMetadata: row.sdkMetadata ?? void 0
2496
+ };
2497
+ }
2498
+ function fromApiRun(row) {
2499
+ return {
2500
+ runId: row.runId,
2501
+ requestId: row.requestId,
2502
+ agentId: row.agentId,
2503
+ turnNumber: row.turnNumber,
2504
+ status: row.status,
2505
+ model: row.model ?? null,
2506
+ result: row.result,
2507
+ error: row.error,
2508
+ usageRef: row.usageRef,
2509
+ usage: row.usage ?? null,
2510
+ createdAt: row.createdAt,
2511
+ updatedAt: row.updatedAt,
2512
+ startedAt: row.startedAt,
2513
+ endedAt: row.endedAt,
2514
+ startCheckpointRef: asCheckpointRef(row.startCheckpointRef) ?? null,
2515
+ latestCheckpointRef: asCheckpointRef(row.latestCheckpointRef) ?? null
2516
+ };
2517
+ }
2518
+ function fromApiEvent(row) {
2519
+ return {
2520
+ runId: row.runId,
2521
+ seq: row.seq,
2522
+ offset: row.offset,
2523
+ eventType: row.eventType,
2524
+ payload: row.payload,
2525
+ payloadRef: row.payloadRef,
2526
+ idempotencyKey: row.idempotencyKey,
2527
+ createdAt: row.createdAt
2528
+ };
2529
+ }
2530
+ function bytesToBase64(data) {
2531
+ return Buffer.from(data).toString("base64");
2532
+ }
2533
+ function base64ToBytes(dataBase64) {
2534
+ return new Uint8Array(Buffer.from(dataBase64, "base64"));
2535
+ }
2536
+ function createRemoteLocalAgentStore(cfg2) {
2537
+ const api = createApmApiClient(cfg2);
2538
+ async function upsertAgent(agent) {
2539
+ const row = await api.cli.cursorStoreUpsertAgent({
2540
+ agentId: agent.agentId,
2541
+ cwd: agent.cwd,
2542
+ status: agent.status,
2543
+ activeRunId: agent.activeRunId ?? null,
2544
+ name: agent.name ?? null,
2545
+ latestCheckpoint: toApiCheckpointRef(agent.latestCheckpoint) ?? null,
2546
+ sdkMetadata: agent.sdkMetadata ?? null,
2547
+ createdAt: agent.createdAt,
2548
+ updatedAt: agent.updatedAt
2549
+ });
2550
+ return fromApiAgent(row);
2551
+ }
2552
+ async function upsertRun(run) {
2553
+ const row = await api.cli.cursorStoreUpsertRun({
2554
+ runId: run.runId,
2555
+ agentId: run.agentId,
2556
+ requestId: run.requestId ?? null,
2557
+ turnNumber: run.turnNumber,
2558
+ status: run.status,
2559
+ model: run.model ?? null,
2560
+ result: run.result ?? null,
2561
+ error: run.error ?? null,
2562
+ usageRef: run.usageRef ?? null,
2563
+ usage: run.usage ?? null,
2564
+ startCheckpointRef: toApiCheckpointRef(run.startCheckpointRef) ?? null,
2565
+ latestCheckpointRef: toApiCheckpointRef(run.latestCheckpointRef) ?? null,
2566
+ createdAt: run.createdAt,
2567
+ updatedAt: run.updatedAt,
2568
+ startedAt: run.startedAt ?? null,
2569
+ endedAt: run.endedAt ?? null
2570
+ });
2571
+ return fromApiRun(row);
2572
+ }
2573
+ async function putCheckpoint(input) {
2574
+ await api.cli.cursorStorePutCheckpoint({
2575
+ agentId: input.agentId,
2576
+ blobId: input.blobId,
2577
+ dataBase64: bytesToBase64(input.data),
2578
+ byteSize: input.data.byteLength,
2579
+ createdAt: Date.now()
2580
+ });
2581
+ }
2582
+ return {
2583
+ agents: {
2584
+ async get(input) {
2585
+ const row = await api.cli.cursorStoreGetAgent({
2586
+ agentId: input.agentId
2587
+ });
2588
+ return row ? fromApiAgent(row) : null;
2589
+ },
2590
+ async create(input) {
2591
+ return upsertAgent(input.agent);
2592
+ },
2593
+ async update(input) {
2594
+ return upsertAgent(input.agent);
2595
+ },
2596
+ async delete(input) {
2597
+ const agentIds = input.filter.agentIds?.map((id) => id.trim()).filter(Boolean);
2598
+ const cwd = input.filter.cwd?.trim();
2599
+ if (agentIds && agentIds.length > 0) {
2600
+ await api.cli.cursorStoreDeleteAgents({ agentIds, cwd });
2601
+ return;
2602
+ }
2603
+ if (cwd) {
2604
+ await api.cli.cursorStoreDeleteAgents({ cwd });
2605
+ return;
2606
+ }
2607
+ let cursor;
2608
+ for (; ; ) {
2609
+ const page = await api.cli.cursorStoreListAgents({
2610
+ cursor,
2611
+ limit: 200
2612
+ });
2613
+ if (page.items.length === 0) break;
2614
+ await api.cli.cursorStoreDeleteAgents({
2615
+ agentIds: page.items.map((item) => item.agentId)
2616
+ });
2617
+ if (!page.nextCursor) break;
2618
+ cursor = page.nextCursor;
2619
+ }
2620
+ },
2621
+ async list(input) {
2622
+ const page = await api.cli.cursorStoreListAgents({
2623
+ cursor: input?.filter?.cursor,
2624
+ limit: input?.filter?.limit,
2625
+ cwd: input?.filter?.cwd
2626
+ });
2627
+ const result = {
2628
+ items: page.items.map(fromApiAgent),
2629
+ ...page.nextCursor ? { nextCursor: page.nextCursor } : {}
2630
+ };
2631
+ return result;
2632
+ }
2633
+ },
2634
+ runs: {
2635
+ async get(input) {
2636
+ const row = await api.cli.cursorStoreGetRun({
2637
+ agentId: input.agentId,
2638
+ runId: input.runId
2639
+ });
2640
+ return row ? fromApiRun(row) : null;
2641
+ },
2642
+ async create(input) {
2643
+ return upsertRun(input.run);
2644
+ },
2645
+ async update(input) {
2646
+ return upsertRun(input.run);
2647
+ },
2648
+ async delete(input) {
2649
+ const agentIds = input.filter.agentIds?.map((id) => id.trim()).filter(Boolean);
2650
+ const runIds = input.filter.runIds?.map((id) => id.trim()).filter(Boolean);
2651
+ if (agentIds && agentIds.length > 0 || runIds && runIds.length > 0) {
2652
+ await api.cli.cursorStoreDeleteRuns({ agentIds, runIds });
2653
+ return;
2654
+ }
2655
+ let cursor;
2656
+ for (; ; ) {
2657
+ const page = await api.cli.cursorStoreListRuns({
2658
+ cursor,
2659
+ limit: 200
2660
+ });
2661
+ if (page.items.length === 0) break;
2662
+ await api.cli.cursorStoreDeleteRuns({
2663
+ runIds: page.items.map((item) => item.runId)
2664
+ });
2665
+ if (!page.nextCursor) break;
2666
+ cursor = page.nextCursor;
2667
+ }
2668
+ },
2669
+ async list(input) {
2670
+ const page = await api.cli.cursorStoreListRuns({
2671
+ agentIds: input?.filter?.agentIds ? [...input.filter.agentIds] : void 0,
2672
+ runIds: input?.filter?.runIds ? [...input.filter.runIds] : void 0,
2673
+ cursor: input?.filter?.cursor,
2674
+ limit: input?.filter?.limit
2675
+ });
2676
+ const result = {
2677
+ items: page.items.map(fromApiRun),
2678
+ ...page.nextCursor ? { nextCursor: page.nextCursor } : {}
2679
+ };
2680
+ return result;
2681
+ }
2682
+ },
2683
+ runEvents: {
2684
+ async append(input) {
2685
+ const { items } = await api.cli.cursorStoreAppendRunEvents({
2686
+ events: [
2687
+ {
2688
+ runId: input.runId,
2689
+ eventType: input.eventType,
2690
+ payload: input.payload,
2691
+ payloadRef: input.payloadRef ?? null,
2692
+ idempotencyKey: input.idempotencyKey ?? null
2693
+ }
2694
+ ]
2695
+ });
2696
+ const row = items[0];
2697
+ if (!row) {
2698
+ throw new Error("cursor-store append run event \u672A\u8FD4\u56DE\u7ED3\u679C");
2699
+ }
2700
+ return fromApiEvent(row);
2701
+ },
2702
+ async list(input) {
2703
+ const page = await api.cli.cursorStoreListRunEvents({
2704
+ runId: input.runId,
2705
+ afterOffset: input.afterOffset ?? null,
2706
+ limit: input.limit
2707
+ });
2708
+ return {
2709
+ items: page.items.map(fromApiEvent),
2710
+ ...page.nextOffset ? { nextOffset: page.nextOffset } : {}
2711
+ };
2712
+ },
2713
+ async delete(input) {
2714
+ const runIds = input.filter.runIds?.map((id) => id.trim()).filter(Boolean);
2715
+ if (runIds && runIds.length > 0) {
2716
+ await api.cli.cursorStoreDeleteRunEvents({ runIds });
2717
+ return;
2718
+ }
2719
+ let cursor;
2720
+ for (; ; ) {
2721
+ const page = await api.cli.cursorStoreListRuns({
2722
+ cursor,
2723
+ limit: 200
2724
+ });
2725
+ if (page.items.length === 0) break;
2726
+ await api.cli.cursorStoreDeleteRunEvents({
2727
+ runIds: page.items.map((item) => item.runId)
2728
+ });
2729
+ if (!page.nextCursor) break;
2730
+ cursor = page.nextCursor;
2731
+ }
2732
+ }
2733
+ },
2734
+ checkpoints: {
2735
+ async get(input) {
2736
+ const row = await api.cli.cursorStoreGetCheckpoint({
2737
+ agentId: input.agentId,
2738
+ blobId: input.blobId
2739
+ });
2740
+ if (!row?.dataBase64) return null;
2741
+ return base64ToBytes(row.dataBase64);
2742
+ },
2743
+ async create(input) {
2744
+ await putCheckpoint(input);
2745
+ },
2746
+ async update(input) {
2747
+ await putCheckpoint(input);
2748
+ },
2749
+ async delete(input) {
2750
+ const agentIds = input.filter.agentIds?.map((id) => id.trim()).filter(Boolean);
2751
+ const blobIds = input.filter.blobIds?.map((id) => id.trim()).filter(Boolean);
2752
+ if (agentIds && agentIds.length > 0 || blobIds && blobIds.length > 0) {
2753
+ await api.cli.cursorStoreDeleteCheckpoints({ agentIds, blobIds });
2754
+ return;
2755
+ }
2756
+ let cursor;
2757
+ for (; ; ) {
2758
+ const page = await api.cli.cursorStoreListCheckpoints({
2759
+ cursor,
2760
+ limit: 200
2761
+ });
2762
+ if (page.items.length === 0) break;
2763
+ await api.cli.cursorStoreDeleteCheckpoints({
2764
+ agentIds: [...new Set(page.items.map((item) => item.agentId))],
2765
+ blobIds: page.items.map((item) => item.blobId)
2766
+ });
2767
+ if (!page.nextCursor) break;
2768
+ cursor = page.nextCursor;
2769
+ }
2770
+ },
2771
+ async list(input) {
2772
+ const page = await api.cli.cursorStoreListCheckpoints({
2773
+ agentIds: input?.filter?.agentIds ? [...input.filter.agentIds] : void 0,
2774
+ blobIds: input?.filter?.blobIds ? [...input.filter.blobIds] : void 0,
2775
+ cursor: input?.filter?.cursor,
2776
+ limit: input?.filter?.limit
2777
+ });
2778
+ return {
2779
+ items: page.items.map((item) => item.blobId),
2780
+ ...page.nextCursor ? { nextCursor: page.nextCursor } : {}
2781
+ };
2782
+ }
2783
+ }
2784
+ };
2785
+ }
2786
+
2388
2787
  // src/commands/connect/cursor-agent.ts
2389
2788
  var noopRemoteLogSync = {
2390
2789
  schedule(_session) {
@@ -2406,11 +2805,13 @@ function formatCursorRunFailure(runId, options) {
2406
2805
  return `Cursor run \u5931\u8D25: ${runId} \u2014 ${details.join("\uFF1B")}`;
2407
2806
  }
2408
2807
  async function obtainAgent(ctx) {
2808
+ const store = createRemoteLocalAgentStore(ctx.cfg);
2409
2809
  const agentOptions = {
2410
2810
  apiKey: ctx.apiKey,
2411
2811
  model: { id: ctx.model || "default" },
2412
2812
  local: {
2413
2813
  cwd: ctx.cwd,
2814
+ store,
2414
2815
  ...ctx.customTools ? { customTools: ctx.customTools } : {},
2415
2816
  ...ctx.enableSandbox ? {
2416
2817
  sandboxOptions: { enabled: true },
@@ -2481,6 +2882,7 @@ async function runCursorAgent(cfg2, ctx, options) {
2481
2882
  `[apm] Cursor Agent \u5F00\u59CB messageId=${ctx.messageId} cwd=${workdir} sandbox=${enableSandbox}`
2482
2883
  );
2483
2884
  const { agent, resumed } = await obtainAgent({
2885
+ cfg: cfg2,
2484
2886
  apiKey,
2485
2887
  model: ctx.model,
2486
2888
  cwd: workdir,
@@ -3681,48 +4083,34 @@ function clearWebIdeDesignAgentId(workdir, taskId) {
3681
4083
  // src/commands/clean-webide-cache.ts
3682
4084
  import { existsSync as existsSync8, rmSync as rmSync2 } from "node:fs";
3683
4085
  import { resolve as resolve7 } from "node:path";
3684
- import { getDefaultSdkStateRoot } from "@cursor/sdk";
3685
- async function purgeCursorAgentStoreForAgent(workdir, agentId) {
4086
+ async function purgeCursorAgentStoreForAgent(cfg2, agentId) {
3686
4087
  const trimmedAgentId = agentId.trim();
3687
- const trimmedWorkdir = workdir.trim();
3688
- if (!trimmedAgentId || !trimmedWorkdir) return false;
3689
- const stateRoot = getDefaultSdkStateRoot(trimmedWorkdir);
3690
- if (!existsSync8(stateRoot)) return false;
3691
- const { SqliteLocalAgentStore } = await import(
3692
- /* @vite-ignore */
3693
- "@cursor/sdk/sqlite"
3694
- );
3695
- const store = await SqliteLocalAgentStore.open({
3696
- workspaceRef: trimmedWorkdir
3697
- });
3698
- try {
3699
- const runIds = [];
3700
- let cursor;
3701
- do {
3702
- const page = await store.runs.list({
3703
- filter: {
3704
- agentIds: [trimmedAgentId],
3705
- ...cursor ? { cursor } : {},
3706
- limit: 200
3707
- }
3708
- });
3709
- for (const run of page.items) {
3710
- runIds.push(run.runId);
4088
+ if (!trimmedAgentId) return false;
4089
+ const store = createRemoteLocalAgentStore(cfg2);
4090
+ const runIds = [];
4091
+ let cursor;
4092
+ do {
4093
+ const page = await store.runs.list({
4094
+ filter: {
4095
+ agentIds: [trimmedAgentId],
4096
+ ...cursor ? { cursor } : {},
4097
+ limit: 200
3711
4098
  }
3712
- cursor = page.nextCursor;
3713
- } while (cursor);
3714
- if (runIds.length > 0) {
3715
- await store.runEvents.delete({ filter: { runIds } });
3716
- }
3717
- await store.runs.delete({ filter: { agentIds: [trimmedAgentId] } });
3718
- await store.checkpoints.delete({ filter: { agentIds: [trimmedAgentId] } });
3719
- await store.agents.delete({ filter: { agentIds: [trimmedAgentId] } });
3720
- } finally {
3721
- await store.dispose();
3722
- }
4099
+ });
4100
+ for (const run of page.items) {
4101
+ runIds.push(run.runId);
4102
+ }
4103
+ cursor = page.nextCursor;
4104
+ } while (cursor);
4105
+ if (runIds.length > 0) {
4106
+ await store.runEvents.delete({ filter: { runIds } });
4107
+ }
4108
+ await store.runs.delete({ filter: { agentIds: [trimmedAgentId] } });
4109
+ await store.checkpoints.delete({ filter: { agentIds: [trimmedAgentId] } });
4110
+ await store.agents.delete({ filter: { agentIds: [trimmedAgentId] } });
3723
4111
  return true;
3724
4112
  }
3725
- async function cleanWebIdeWorkspaceCache(taskId, workdir) {
4113
+ async function cleanWebIdeWorkspaceCache(taskId, workdir, cfg2) {
3726
4114
  const trimmedTaskId = taskId.trim();
3727
4115
  const trimmedWorkdir = workdir.trim();
3728
4116
  if (!trimmedTaskId || !trimmedWorkdir) {
@@ -3731,10 +4119,7 @@ async function cleanWebIdeWorkspaceCache(taskId, workdir) {
3731
4119
  const agentId = loadWebIdeAgentId(trimmedWorkdir, trimmedTaskId);
3732
4120
  if (agentId) {
3733
4121
  try {
3734
- const purged = await purgeCursorAgentStoreForAgent(
3735
- trimmedWorkdir,
3736
- agentId
3737
- );
4122
+ const purged = await purgeCursorAgentStoreForAgent(cfg2, agentId);
3738
4123
  if (purged) {
3739
4124
  console.log(
3740
4125
  `[apm] \u5DF2\u6E05\u7406 Cursor agent store agentId=${agentId} taskId=${trimmedTaskId}`
@@ -3823,6 +4208,36 @@ async function webIdeRunAction(cfg2, taskId, action, params) {
3823
4208
  await api.cli.webideRunAction({ taskId, action, params });
3824
4209
  console.log(`[apm] webide runAction ok action=${action} taskId=${taskId}`);
3825
4210
  }
4211
+ async function webIdeSyncTransitionPrepEvents(cfg2, taskId, startAction, prepEvents) {
4212
+ try {
4213
+ const api = createApmApiClient(cfg2);
4214
+ await api.cli.webideUpdateTransitionPrepEvents({
4215
+ taskId,
4216
+ startAction,
4217
+ prepEvents
4218
+ });
4219
+ } catch (err) {
4220
+ console.warn(
4221
+ `[apm] sync transition prepEvents failed taskId=${taskId}:`,
4222
+ err instanceof Error ? err.message : err
4223
+ );
4224
+ }
4225
+ }
4226
+ async function webIdeDiscardTransitionPrepDraft(cfg2, taskId, startAction) {
4227
+ try {
4228
+ const api = createApmApiClient(cfg2);
4229
+ await api.cli.webideUpdateTransitionPrepEvents({
4230
+ taskId,
4231
+ startAction,
4232
+ discardDraft: true
4233
+ });
4234
+ } catch (err) {
4235
+ console.warn(
4236
+ `[apm] discard transition prep draft failed taskId=${taskId}:`,
4237
+ err instanceof Error ? err.message : err
4238
+ );
4239
+ }
4240
+ }
3826
4241
 
3827
4242
  // src/commands/connect/webide-ask-question.ts
3828
4243
  function asString5(value) {
@@ -4435,11 +4850,22 @@ async function handleWebIdeInboundMessage(cfg2, msg2, signal) {
4435
4850
  }
4436
4851
  )
4437
4852
  };
4853
+ let pausedForAssumptions = false;
4854
+ let startAction = null;
4438
4855
  const syncPrepLog = async () => {
4439
4856
  const sync = logSyncRef.current;
4440
- if (!sync) return;
4441
- sync.schedule(eventSession);
4442
- await sync.flush(eventSession);
4857
+ if (sync) {
4858
+ sync.schedule(eventSession);
4859
+ await sync.flush(eventSession);
4860
+ }
4861
+ if (startAction) {
4862
+ await webIdeSyncTransitionPrepEvents(
4863
+ cfg2,
4864
+ taskId,
4865
+ startAction,
4866
+ eventSession.getCliSteps()
4867
+ );
4868
+ }
4443
4869
  };
4444
4870
  const runPrepStep = async (step, work, formatOk) => {
4445
4871
  eventSession.addCliStep(step, "\u8FDB\u884C\u4E2D\u2026", "running");
@@ -4456,12 +4882,8 @@ async function handleWebIdeInboundMessage(cfg2, msg2, signal) {
4456
4882
  throw err;
4457
4883
  }
4458
4884
  };
4459
- let pausedForAssumptions = false;
4460
4885
  try {
4461
- const startAction = startActionForInbound(msg2.action);
4462
- if (startAction) {
4463
- await webIdeRunAction(cfg2, taskId, startAction);
4464
- }
4886
+ startAction = startActionForInbound(msg2.action);
4465
4887
  if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
4466
4888
  let assumptionAnswersText;
4467
4889
  if (msg2.action === "confirm-assumptions") {
@@ -4722,6 +5144,15 @@ ${assumptionAnswersText}` : msg2.content,
4722
5144
  logSyncRef.current?.schedule(eventSession);
4723
5145
  await logSyncRef.current?.markRun(runId, "running");
4724
5146
  await logSyncRef.current?.flush(eventSession);
5147
+ if (startAction) {
5148
+ await webIdeSyncTransitionPrepEvents(
5149
+ cfg2,
5150
+ taskId,
5151
+ startAction,
5152
+ eventSession.getCliSteps()
5153
+ );
5154
+ await webIdeRunAction(cfg2, taskId, startAction, { runId });
5155
+ }
4725
5156
  }
4726
5157
  }
4727
5158
  );
@@ -4925,7 +5356,7 @@ ${assumptionAnswersText}` : msg2.content,
4925
5356
  );
4926
5357
  if (msg2.action === "request-accept") {
4927
5358
  try {
4928
- await cleanWebIdeWorkspaceCache(taskId, workdir);
5359
+ await cleanWebIdeWorkspaceCache(taskId, workdir, cfg2);
4929
5360
  } catch (err) {
4930
5361
  console.warn(
4931
5362
  "[apm] \u5408\u5E76 PR \u540E\u6E05\u7406 WebIDE agent \u7F13\u5B58\u5931\u8D25:",
@@ -4936,6 +5367,9 @@ ${assumptionAnswersText}` : msg2.content,
4936
5367
  } catch (err) {
4937
5368
  const detail = err instanceof Error ? err.message : String(err);
4938
5369
  console.error(`[apm] webide-message \u5931\u8D25: ${detail}`);
5370
+ if (startAction) {
5371
+ await webIdeDiscardTransitionPrepDraft(cfg2, taskId, startAction);
5372
+ }
4939
5373
  if (detail.includes("\u590D\u7528 Agent") || detail.includes("resume")) {
4940
5374
  clearWebIdeAgentId(workdir, taskId);
4941
5375
  }
@@ -4948,14 +5382,9 @@ ${assumptionAnswersText}` : msg2.content,
4948
5382
  );
4949
5383
  }
4950
5384
  const completeAction = completeActionForInbound(msg2.action);
4951
- if (completeAction && !pausedForAssumptions) {
5385
+ if (completeAction === "complete-assessment" && !pausedForAssumptions) {
4952
5386
  try {
4953
- await webIdeRunAction(
4954
- cfg2,
4955
- taskId,
4956
- completeAction,
4957
- completeAction === "complete-assessment" ? { force: true } : void 0
4958
- );
5387
+ await webIdeRunAction(cfg2, taskId, completeAction, { force: true });
4959
5388
  } catch (completeErr) {
4960
5389
  console.warn(
4961
5390
  `[apm] \u5931\u8D25\u540E\u56DE\u5199 complete \u8DF3\u8FC7 action=${completeAction}:`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-project-manage-cli",
3
- "version": "8.1.4",
3
+ "version": "8.1.6",
4
4
  "description": "命令行工具:后续用于调用平台后端 API 完成运维与自动化操作",
5
5
  "type": "module",
6
6
  "private": false,