ai-project-manage-cli 8.1.14 → 8.1.16

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
@@ -279,22 +279,6 @@ var requestConfig = {
279
279
  cursorStoreDeleteRunEvents: defineEndpoint({
280
280
  method: "POST",
281
281
  path: "/cli/cursor-store/run-events/delete"
282
- }),
283
- cursorStorePutCheckpoint: defineEndpoint({
284
- method: "PUT",
285
- path: "/cli/cursor-store/checkpoints"
286
- }),
287
- cursorStoreGetCheckpoint: defineEndpoint({
288
- method: "GET",
289
- path: "/cli/cursor-store/checkpoints/get"
290
- }),
291
- cursorStoreListCheckpoints: defineEndpoint({
292
- method: "POST",
293
- path: "/cli/cursor-store/checkpoints/list"
294
- }),
295
- cursorStoreDeleteCheckpoints: defineEndpoint({
296
- method: "POST",
297
- path: "/cli/cursor-store/checkpoints/delete"
298
282
  })
299
283
  }
300
284
  };
@@ -190,22 +190,6 @@ var requestConfig = {
190
190
  cursorStoreDeleteRunEvents: defineEndpoint({
191
191
  method: "POST",
192
192
  path: "/cli/cursor-store/run-events/delete"
193
- }),
194
- cursorStorePutCheckpoint: defineEndpoint({
195
- method: "PUT",
196
- path: "/cli/cursor-store/checkpoints"
197
- }),
198
- cursorStoreGetCheckpoint: defineEndpoint({
199
- method: "GET",
200
- path: "/cli/cursor-store/checkpoints/get"
201
- }),
202
- cursorStoreListCheckpoints: defineEndpoint({
203
- method: "POST",
204
- path: "/cli/cursor-store/checkpoints/list"
205
- }),
206
- cursorStoreDeleteCheckpoints: defineEndpoint({
207
- method: "POST",
208
- path: "/cli/cursor-store/checkpoints/delete"
209
193
  })
210
194
  }
211
195
  };
@@ -2472,77 +2456,11 @@ function createPtySessionMcpServers(cfg2) {
2472
2456
  };
2473
2457
  }
2474
2458
 
2459
+ // src/commands/connect/local-sqlite-agent-store.ts
2460
+ import { composeLocalAgentStore } from "@cursor/sdk";
2461
+ import { SqliteLocalAgentStore } from "@cursor/sdk/sqlite";
2462
+
2475
2463
  // 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";
2486
- var INLINE_CHECKPOINT_MAX_BYTES = 256 * 1024;
2487
- var CHECKPOINT_CACHE_DIR = join4(APM_CONFIG_DIR, "cursor-checkpoint-cache");
2488
- function checkpointObjectKey(agentId, blobId) {
2489
- return `cursor-agents/${agentId}/checkpoints/${blobId}`;
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
- }
2546
2464
  function asCheckpointRef(value) {
2547
2465
  if (value === void 0) return void 0;
2548
2466
  if (value === null) return null;
@@ -2597,51 +2515,32 @@ function fromApiRun(row) {
2597
2515
  latestCheckpointRef: asCheckpointRef(row.latestCheckpointRef) ?? null
2598
2516
  };
2599
2517
  }
2600
- function fromApiEvent(row) {
2601
- return {
2602
- runId: row.runId,
2603
- seq: row.seq,
2604
- offset: row.offset,
2605
- eventType: row.eventType,
2606
- payload: row.payload,
2607
- payloadRef: row.payloadRef,
2608
- idempotencyKey: row.idempotencyKey,
2609
- createdAt: row.createdAt
2610
- };
2611
- }
2612
- function bytesToBase64(data) {
2613
- return Buffer.from(data).toString("base64");
2614
- }
2615
- function base64ToBytes(dataBase64) {
2616
- return new Uint8Array(Buffer.from(dataBase64, "base64"));
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
- }
2624
- function createRemoteLocalAgentStore(cfg2) {
2625
- const api = createApmApiClient(cfg2);
2626
- let minioCache = null;
2627
- const memoryCheckpointCache = /* @__PURE__ */ new Map();
2628
- function getMinio() {
2629
- if (!minioCache) {
2630
- minioCache = createApmLogMinioClient(cfg2).then(({ client, bucket }) => ({
2631
- client,
2632
- bucket
2633
- }));
2634
- }
2635
- return minioCache;
2636
- }
2637
- function rememberCheckpoint(agentId, blobId, data) {
2638
- memoryCheckpointCache.set(checkpointCacheKey(agentId, blobId), data);
2639
- 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: [] };
2640
2530
  }
2641
- function forgetCheckpoint(agentId, blobId) {
2642
- memoryCheckpointCache.delete(checkpointCacheKey(agentId, blobId));
2643
- 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() {
2644
2540
  }
2541
+ };
2542
+ function createRemoteLocalAgentStore(cfg2) {
2543
+ const api = createApmApiClient(cfg2);
2645
2544
  async function upsertAgent(agent) {
2646
2545
  const row = await api.cli.cursorStoreUpsertAgent({
2647
2546
  agentId: agent.agentId,
@@ -2677,82 +2576,6 @@ function createRemoteLocalAgentStore(cfg2) {
2677
2576
  });
2678
2577
  return fromApiRun(row);
2679
2578
  }
2680
- async function uploadCheckpointRemote(input) {
2681
- const createdAt = Date.now();
2682
- if (input.data.byteLength > INLINE_CHECKPOINT_MAX_BYTES) {
2683
- const { client, bucket } = await getMinio();
2684
- const objectKey = checkpointObjectKey(input.agentId, input.blobId);
2685
- await client.putObject(bucket, objectKey, Buffer.from(input.data), {
2686
- "Content-Type": "application/octet-stream"
2687
- });
2688
- await api.cli.cursorStorePutCheckpoint({
2689
- agentId: input.agentId,
2690
- blobId: input.blobId,
2691
- objectKey,
2692
- byteSize: input.data.byteLength,
2693
- createdAt
2694
- });
2695
- return;
2696
- }
2697
- await api.cli.cursorStorePutCheckpoint({
2698
- agentId: input.agentId,
2699
- blobId: input.blobId,
2700
- dataBase64: bytesToBase64(input.data),
2701
- byteSize: input.data.byteLength,
2702
- createdAt
2703
- });
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
- }
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
- }
2738
- const row = await api.cli.cursorStoreGetCheckpoint({
2739
- agentId: input.agentId,
2740
- blobId: input.blobId
2741
- });
2742
- if (!row) return null;
2743
- let bytes = null;
2744
- if (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);
2752
- }
2753
- rememberCheckpoint(input.agentId, input.blobId, bytes);
2754
- return bytes;
2755
- }
2756
2579
  return {
2757
2580
  agents: {
2758
2581
  async get(input) {
@@ -2807,10 +2630,11 @@ function createRemoteLocalAgentStore(cfg2) {
2807
2630
  },
2808
2631
  runs: {
2809
2632
  async get(input) {
2810
- const row = await api.cli.cursorStoreGetRun({
2811
- agentId: input.agentId,
2812
- runId: input.runId
2633
+ const page = await api.cli.cursorStoreListRuns({
2634
+ runIds: [input.runId],
2635
+ limit: 1
2813
2636
  });
2637
+ const row = page.items[0];
2814
2638
  return row ? fromApiRun(row) : null;
2815
2639
  },
2816
2640
  async create(input) {
@@ -2854,124 +2678,54 @@ function createRemoteLocalAgentStore(cfg2) {
2854
2678
  return result;
2855
2679
  }
2856
2680
  },
2857
- runEvents: {
2858
- async append(input) {
2859
- const { items } = await api.cli.cursorStoreAppendRunEvents({
2860
- events: [
2861
- {
2862
- runId: input.runId,
2863
- eventType: input.eventType,
2864
- payload: input.payload,
2865
- payloadRef: input.payloadRef ?? null,
2866
- idempotencyKey: input.idempotencyKey ?? null
2867
- }
2868
- ]
2869
- });
2870
- const row = items[0];
2871
- if (!row) {
2872
- throw new Error("cursor-store append run event \u672A\u8FD4\u56DE\u7ED3\u679C");
2873
- }
2874
- return fromApiEvent(row);
2875
- },
2876
- async list(input) {
2877
- const page = await api.cli.cursorStoreListRunEvents({
2878
- runId: input.runId,
2879
- afterOffset: input.afterOffset ?? null,
2880
- limit: input.limit
2881
- });
2882
- return {
2883
- items: page.items.map(fromApiEvent),
2884
- ...page.nextOffset ? { nextOffset: page.nextOffset } : {}
2885
- };
2886
- },
2887
- async delete(input) {
2888
- const runIds = input.filter.runIds?.map((id) => id.trim()).filter(Boolean);
2889
- if (runIds && runIds.length > 0) {
2890
- await api.cli.cursorStoreDeleteRunEvents({ runIds });
2891
- return;
2892
- }
2893
- let cursor;
2894
- for (; ; ) {
2895
- const page = await api.cli.cursorStoreListRuns({
2896
- cursor,
2897
- limit: 200
2898
- });
2899
- if (page.items.length === 0) break;
2900
- await api.cli.cursorStoreDeleteRunEvents({
2901
- runIds: page.items.map((item) => item.runId)
2902
- });
2903
- if (!page.nextCursor) break;
2904
- cursor = page.nextCursor;
2905
- }
2906
- }
2907
- },
2908
- checkpoints: {
2909
- async get(input) {
2910
- return readCheckpointBytes(input);
2911
- },
2912
- async create(input) {
2913
- await putCheckpoint(input);
2914
- },
2915
- async update(input) {
2916
- await putCheckpoint(input);
2917
- },
2918
- async delete(input) {
2919
- const agentIds = input.filter.agentIds?.map((id) => id.trim()).filter(Boolean);
2920
- const blobIds = input.filter.blobIds?.map((id) => id.trim()).filter(Boolean);
2921
- if (agentIds && agentIds.length > 0 || blobIds && blobIds.length > 0) {
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
- }
2940
- return;
2941
- }
2942
- let cursor;
2943
- for (; ; ) {
2944
- const page = await api.cli.cursorStoreListCheckpoints({
2945
- cursor,
2946
- limit: 200
2947
- });
2948
- if (page.items.length === 0) break;
2949
- await api.cli.cursorStoreDeleteCheckpoints({
2950
- agentIds: [...new Set(page.items.map((item) => item.agentId))],
2951
- blobIds: page.items.map((item) => item.blobId)
2952
- });
2953
- if (!page.nextCursor) break;
2954
- cursor = page.nextCursor;
2955
- }
2956
- clearLocalCheckpointCache();
2957
- memoryCheckpointCache.clear();
2958
- },
2959
- async list(input) {
2960
- const page = await api.cli.cursorStoreListCheckpoints({
2961
- agentIds: input?.filter?.agentIds ? [...input.filter.agentIds] : void 0,
2962
- blobIds: input?.filter?.blobIds ? [...input.filter.blobIds] : void 0,
2963
- cursor: input?.filter?.cursor,
2964
- limit: input?.filter?.limit
2965
- });
2966
- return {
2967
- items: page.items.map((item) => item.blobId),
2968
- ...page.nextCursor ? { nextCursor: page.nextCursor } : {}
2969
- };
2970
- }
2971
- }
2681
+ checkpoints: unsupportedCheckpoints,
2682
+ runEvents: unsupportedRunEvents
2972
2683
  };
2973
2684
  }
2974
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
+
2975
2729
  // src/commands/connect/core/worker/run-steer.ts
2976
2730
  var impl = null;
2977
2731
  var pending = null;
@@ -3017,7 +2771,7 @@ function formatCursorRunFailure(runId, options) {
3017
2771
  return `Cursor run \u5931\u8D25: ${runId} \u2014 ${details.join("\uFF1B")}`;
3018
2772
  }
3019
2773
  async function obtainAgent(ctx) {
3020
- const store = createRemoteLocalAgentStore(ctx.cfg);
2774
+ const store = await createApmCursorAgentStore(ctx.cfg, ctx.cwd);
3021
2775
  const agentOptions = {
3022
2776
  apiKey: ctx.apiKey,
3023
2777
  model: { id: ctx.model || "default" },
@@ -3369,14 +3123,14 @@ function createThrottledWebIdeMessageLogSync(cfg2, ctx, onError, options) {
3369
3123
 
3370
3124
  // src/commands/sync-webide-agent.ts
3371
3125
  import {
3372
- existsSync as existsSync6,
3373
- mkdirSync as mkdirSync5,
3126
+ existsSync as existsSync5,
3127
+ mkdirSync as mkdirSync4,
3374
3128
  readdirSync as readdirSync3,
3375
- readFileSync as readFileSync5,
3376
- unlinkSync as unlinkSync2,
3377
- writeFileSync as writeFileSync4
3129
+ readFileSync as readFileSync4,
3130
+ unlinkSync,
3131
+ writeFileSync as writeFileSync3
3378
3132
  } from "fs";
3379
- import { join as join5 } from "path";
3133
+ import { join as join4 } from "path";
3380
3134
  var REVISION_FILE = ".webide-agent.json";
3381
3135
  var RULE_KEY = /^[a-z0-9_]+$/;
3382
3136
  function withTrailingNewline(text) {
@@ -3384,10 +3138,10 @@ function withTrailingNewline(text) {
3384
3138
  `;
3385
3139
  }
3386
3140
  function readRevision(apmDir) {
3387
- const path3 = toFsPath(join5(apmDir, REVISION_FILE));
3388
- if (!existsSync6(path3)) return null;
3141
+ const path3 = toFsPath(join4(apmDir, REVISION_FILE));
3142
+ if (!existsSync5(path3)) return null;
3389
3143
  try {
3390
- const parsed = JSON.parse(readFileSync5(path3, "utf8"));
3144
+ const parsed = JSON.parse(readFileSync4(path3, "utf8"));
3391
3145
  if (parsed?.version === 1 && parsed.revision?.trim()) {
3392
3146
  return parsed.revision.trim();
3393
3147
  }
@@ -3397,8 +3151,8 @@ function readRevision(apmDir) {
3397
3151
  return null;
3398
3152
  }
3399
3153
  function writeRevision(apmDir, revision) {
3400
- writeFileSync4(
3401
- toFsPath(join5(apmDir, REVISION_FILE)),
3154
+ writeFileSync3(
3155
+ toFsPath(join4(apmDir, REVISION_FILE)),
3402
3156
  `${JSON.stringify({ version: 1, revision }, null, 2)}
3403
3157
  `,
3404
3158
  "utf8"
@@ -3412,14 +3166,14 @@ async function syncWebIdeAgentFiles(workdir, cfg2) {
3412
3166
  throw new Error("[apm] \u5E73\u53F0\u672A\u8FD4\u56DE WebIDE \u89C4\u5219\u7248\u672C");
3413
3167
  }
3414
3168
  const apmDir = workspaceApmDir(workdir);
3415
- mkdirSync5(toFsPath(apmDir), { recursive: true });
3169
+ mkdirSync4(toFsPath(apmDir), { recursive: true });
3416
3170
  if (readRevision(apmDir) === revision) {
3417
3171
  return { revision, wrote: false, ruleCount: bundle.rules?.length ?? 0 };
3418
3172
  }
3419
- const rulesDir = join5(apmDir, "rules");
3420
- mkdirSync5(toFsPath(rulesDir), { recursive: true });
3421
- writeFileSync4(
3422
- 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")),
3423
3177
  withTrailingNewline(bundle.guide ?? ""),
3424
3178
  "utf8"
3425
3179
  );
@@ -3430,8 +3184,8 @@ async function syncWebIdeAgentFiles(workdir, cfg2) {
3430
3184
  throw new Error(`[apm] \u975E\u6CD5\u89C4\u5219\u540D: ${key || "(\u7A7A)"}`);
3431
3185
  }
3432
3186
  keep.add(`${key}.md`);
3433
- writeFileSync4(
3434
- toFsPath(join5(rulesDir, `${key}.md`)),
3187
+ writeFileSync3(
3188
+ toFsPath(join4(rulesDir, `${key}.md`)),
3435
3189
  withTrailingNewline(rule.body ?? ""),
3436
3190
  "utf8"
3437
3191
  );
@@ -3439,7 +3193,7 @@ async function syncWebIdeAgentFiles(workdir, cfg2) {
3439
3193
  for (const name of readdirSync3(toFsPath(rulesDir))) {
3440
3194
  if (!name.endsWith(".md")) continue;
3441
3195
  if (keep.has(name)) continue;
3442
- unlinkSync2(toFsPath(join5(rulesDir, name)));
3196
+ unlinkSync(toFsPath(join4(rulesDir, name)));
3443
3197
  }
3444
3198
  writeRevision(apmDir, revision);
3445
3199
  return {
@@ -3464,14 +3218,14 @@ async function ensureWorkspaceInitialized(workdir) {
3464
3218
 
3465
3219
  // src/utils/project-documents.ts
3466
3220
  import {
3467
- existsSync as existsSync7,
3221
+ existsSync as existsSync6,
3468
3222
  readdirSync as readdirSync4,
3469
- readFileSync as readFileSync6,
3470
- rmSync as rmSync2,
3471
- writeFileSync as writeFileSync5
3223
+ readFileSync as readFileSync5,
3224
+ rmSync,
3225
+ writeFileSync as writeFileSync4
3472
3226
  } from "fs";
3473
- import { createHash as createHash3 } from "crypto";
3474
- 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";
3475
3229
  var MANIFEST_FILE = "manifest.json";
3476
3230
  function normalizeProjectIdForPath(projectId) {
3477
3231
  const id = projectId.trim();
@@ -3485,11 +3239,11 @@ function normalizeProjectIdForPath(projectId) {
3485
3239
  }
3486
3240
  function projectDocumentsDir(apmRoot, projectId) {
3487
3241
  const id = normalizeProjectIdForPath(projectId);
3488
- return join6(apmRoot ?? workspaceApmDir(), "project", id);
3242
+ return join5(apmRoot ?? workspaceApmDir(), "project", id);
3489
3243
  }
3490
3244
  function projectDocumentLocalPath(apmRoot, projectId, documentPath) {
3491
3245
  const normalized = normalizeLocalDocumentPath(documentPath);
3492
- return join6(
3246
+ return join5(
3493
3247
  projectDocumentsDir(apmRoot, projectId),
3494
3248
  ...normalized.split("/")
3495
3249
  );
@@ -3506,19 +3260,19 @@ function normalizeLocalDocumentPath(path3) {
3506
3260
  return segments.join("/");
3507
3261
  }
3508
3262
  function hashLocalFileContent(content) {
3509
- return createHash3("sha256").update(content, "utf8").digest("hex");
3263
+ return createHash2("sha256").update(content, "utf8").digest("hex");
3510
3264
  }
3511
3265
  function readLocalManifest(apmRoot, projectId) {
3512
- const manifestPath2 = join6(
3266
+ const manifestPath2 = join5(
3513
3267
  projectDocumentsDir(apmRoot, projectId),
3514
3268
  MANIFEST_FILE
3515
3269
  );
3516
- if (!existsSync7(manifestPath2)) {
3270
+ if (!existsSync6(manifestPath2)) {
3517
3271
  return null;
3518
3272
  }
3519
3273
  try {
3520
3274
  return JSON.parse(
3521
- readFileSync6(manifestPath2, "utf8")
3275
+ readFileSync5(manifestPath2, "utf8")
3522
3276
  );
3523
3277
  } catch {
3524
3278
  return null;
@@ -3526,13 +3280,13 @@ function readLocalManifest(apmRoot, projectId) {
3526
3280
  }
3527
3281
  function listLocalDocumentPaths(apmRoot, projectId) {
3528
3282
  const root = projectDocumentsDir(apmRoot, projectId);
3529
- if (!existsSync7(root)) {
3283
+ if (!existsSync6(root)) {
3530
3284
  return [];
3531
3285
  }
3532
3286
  const paths = [];
3533
3287
  const walk = (dir) => {
3534
3288
  for (const entry of readdirSync4(dir, { withFileTypes: true })) {
3535
- const abs = join6(dir, entry.name);
3289
+ const abs = join5(dir, entry.name);
3536
3290
  if (entry.isDirectory()) {
3537
3291
  walk(abs);
3538
3292
  continue;
@@ -3651,8 +3405,8 @@ ${diagnostic ?? ""}`);
3651
3405
  const absPath = toFsPath(
3652
3406
  projectDocumentLocalPath(targetApmDir, projectId, doc.path)
3653
3407
  );
3654
- await ensureDirExists(dirname3(absPath));
3655
- writeFileSync5(absPath, doc.content, "utf8");
3408
+ await ensureDirExists(dirname2(absPath));
3409
+ writeFileSync4(absPath, doc.content, "utf8");
3656
3410
  downloaded += 1;
3657
3411
  }
3658
3412
  }
@@ -3661,13 +3415,13 @@ ${diagnostic ?? ""}`);
3661
3415
  const absPath = toFsPath(
3662
3416
  projectDocumentLocalPath(targetApmDir, projectId, path3)
3663
3417
  );
3664
- if (existsSync7(absPath)) {
3665
- rmSync2(absPath, { force: true });
3418
+ if (existsSync6(absPath)) {
3419
+ rmSync(absPath, { force: true });
3666
3420
  deleted += 1;
3667
3421
  }
3668
3422
  }
3669
- writeFileSync5(
3670
- toFsPath(join6(docsDir, MANIFEST_FILE)),
3423
+ writeFileSync4(
3424
+ toFsPath(join5(docsDir, MANIFEST_FILE)),
3671
3425
  `${JSON.stringify(remoteManifest, null, 2)}
3672
3426
  `,
3673
3427
  "utf8"
@@ -3710,7 +3464,7 @@ async function syncProjectDocumentsPush(cfg2, workdirPath, apmRoot, options) {
3710
3464
  const absPath = toFsPath(
3711
3465
  projectDocumentLocalPath(targetApmDir, projectId, path3)
3712
3466
  );
3713
- const content = readFileSync6(absPath, "utf8");
3467
+ const content = readFileSync5(absPath, "utf8");
3714
3468
  const contentHash = hashLocalFileContent(content);
3715
3469
  if (remoteHashByPath.get(path3) === contentHash) {
3716
3470
  continue;
@@ -4195,18 +3949,18 @@ async function handleStartProject(cfg2, msg2, signal) {
4195
3949
  }
4196
3950
 
4197
3951
  // src/commands/connect/webide-agent-registry.ts
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";
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";
4200
3954
  function registryPath(workdir, taskId, fileName = "cursor-agent.json") {
4201
3955
  return resolve6(workdir, ".apm", "webide", taskId, fileName);
4202
3956
  }
4203
3957
  var DESIGN_AGENT_FILE = "design-agent.json";
4204
3958
  function readRegistry(path3) {
4205
- if (!existsSync8(path3)) {
3959
+ if (!existsSync7(path3)) {
4206
3960
  return {};
4207
3961
  }
4208
3962
  try {
4209
- const parsed = JSON.parse(readFileSync7(path3, "utf8"));
3963
+ const parsed = JSON.parse(readFileSync6(path3, "utf8"));
4210
3964
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
4211
3965
  const raw = parsed;
4212
3966
  const state = {};
@@ -4235,8 +3989,8 @@ function readRegistry(path3) {
4235
3989
  return {};
4236
3990
  }
4237
3991
  function writeRegistry(path3, registry) {
4238
- mkdirSync6(dirname4(path3), { recursive: true });
4239
- writeFileSync6(path3, `${JSON.stringify(registry, null, 2)}
3992
+ mkdirSync5(dirname3(path3), { recursive: true });
3993
+ writeFileSync5(path3, `${JSON.stringify(registry, null, 2)}
4240
3994
  `, "utf8");
4241
3995
  }
4242
3996
  function syncWebIdeTaskState(workdir, taskId, patch) {
@@ -4277,7 +4031,7 @@ function saveWebIdeAgentId(workdir, taskId, agentId) {
4277
4031
  }
4278
4032
  function clearWebIdeAgentId(workdir, taskId) {
4279
4033
  const path3 = registryPath(workdir, taskId);
4280
- if (!existsSync8(path3)) return;
4034
+ if (!existsSync7(path3)) return;
4281
4035
  syncWebIdeTaskState(workdir, taskId, { agentId: "" });
4282
4036
  }
4283
4037
  function loadWebIdeDesignAgentId(workdir, taskId) {
@@ -4297,7 +4051,7 @@ function saveWebIdeDesignAgentId(workdir, taskId, agentId) {
4297
4051
  }
4298
4052
  function clearWebIdeDesignAgentId(workdir, taskId) {
4299
4053
  const path3 = registryPath(workdir, taskId, DESIGN_AGENT_FILE);
4300
- if (!existsSync8(path3)) return;
4054
+ if (!existsSync7(path3)) return;
4301
4055
  const current = readRegistry(path3);
4302
4056
  const next = { ...current };
4303
4057
  delete next.agentId;
@@ -4309,12 +4063,11 @@ function clearWebIdeDesignAgentId(workdir, taskId) {
4309
4063
  }
4310
4064
 
4311
4065
  // src/commands/clean-webide-cache.ts
4312
- import { existsSync as existsSync9, rmSync as rmSync3 } from "node:fs";
4066
+ import { existsSync as existsSync8, rmSync as rmSync2 } from "node:fs";
4313
4067
  import { resolve as resolve7 } from "node:path";
4314
- async function purgeCursorAgentStoreForAgent(cfg2, agentId) {
4068
+ async function purgeCursorAgentStoreForAgent(cfg2, agentId, workspaceRef) {
4315
4069
  const trimmedAgentId = agentId.trim();
4316
4070
  if (!trimmedAgentId) return false;
4317
- await flushPendingCheckpointUploads();
4318
4071
  const store = createRemoteLocalAgentStore(cfg2);
4319
4072
  const runIds = [];
4320
4073
  let cursor;
@@ -4331,13 +4084,16 @@ async function purgeCursorAgentStoreForAgent(cfg2, agentId) {
4331
4084
  }
4332
4085
  cursor = page.nextCursor;
4333
4086
  } while (cursor);
4334
- if (runIds.length > 0) {
4335
- await store.runEvents.delete({ filter: { runIds } });
4336
- }
4337
4087
  await store.runs.delete({ filter: { agentIds: [trimmedAgentId] } });
4338
- await store.checkpoints.delete({ filter: { agentIds: [trimmedAgentId] } });
4339
4088
  await store.agents.delete({ filter: { agentIds: [trimmedAgentId] } });
4340
- clearLocalCheckpointCache(trimmedAgentId);
4089
+ const workdir = workspaceRef?.trim();
4090
+ if (workdir) {
4091
+ await purgeLocalSqliteAgentData({
4092
+ workspaceRef: workdir,
4093
+ agentId: trimmedAgentId,
4094
+ runIds
4095
+ });
4096
+ }
4341
4097
  return true;
4342
4098
  }
4343
4099
  async function cleanWebIdeWorkspaceCache(taskId, workdir, cfg2) {
@@ -4349,7 +4105,11 @@ async function cleanWebIdeWorkspaceCache(taskId, workdir, cfg2) {
4349
4105
  const agentId = loadWebIdeAgentId(trimmedWorkdir, trimmedTaskId);
4350
4106
  if (agentId) {
4351
4107
  try {
4352
- const purged = await purgeCursorAgentStoreForAgent(cfg2, agentId);
4108
+ const purged = await purgeCursorAgentStoreForAgent(
4109
+ cfg2,
4110
+ agentId,
4111
+ trimmedWorkdir
4112
+ );
4353
4113
  if (purged) {
4354
4114
  console.log(
4355
4115
  `[apm] \u5DF2\u6E05\u7406 Cursor agent store agentId=${agentId} taskId=${trimmedTaskId}`
@@ -4367,8 +4127,8 @@ async function cleanWebIdeWorkspaceCache(taskId, workdir, cfg2) {
4367
4127
  );
4368
4128
  }
4369
4129
  const dir = resolve7(trimmedWorkdir, ".apm", "webide", trimmedTaskId);
4370
- if (existsSync9(dir)) {
4371
- rmSync3(dir, { recursive: true, force: true });
4130
+ if (existsSync8(dir)) {
4131
+ rmSync2(dir, { recursive: true, force: true });
4372
4132
  console.log(`[apm] \u5DF2\u6E05\u7406 WebIDE \u7F13\u5B58 ${dir}`);
4373
4133
  } else {
4374
4134
  console.log(`[apm] WebIDE \u7F13\u5B58\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7 ${dir}`);
@@ -4689,8 +4449,8 @@ async function ensureWebIdePullRequests(cfg2, taskId, workdir) {
4689
4449
  }
4690
4450
 
4691
4451
  // src/commands/sync-webide-attachments.ts
4692
- import { existsSync as existsSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "fs";
4693
- 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";
4694
4454
  var MANIFEST_FILE2 = ".sync-manifest.json";
4695
4455
  async function downloadAttachment(cfg2, attachmentId) {
4696
4456
  const base = cfg2.baseUrl.trim().replace(/\/+$/, "");
@@ -4706,13 +4466,13 @@ async function downloadAttachment(cfg2, attachmentId) {
4706
4466
  return Buffer.from(await res.arrayBuffer());
4707
4467
  }
4708
4468
  function loadManifest(dir) {
4709
- const path3 = join7(dir, MANIFEST_FILE2);
4710
- if (!existsSync10(path3)) {
4469
+ const path3 = join6(dir, MANIFEST_FILE2);
4470
+ if (!existsSync9(path3)) {
4711
4471
  return { version: 1, attachments: {} };
4712
4472
  }
4713
4473
  try {
4714
4474
  const parsed = JSON.parse(
4715
- readFileSync8(path3, "utf8")
4475
+ readFileSync7(path3, "utf8")
4716
4476
  );
4717
4477
  if (parsed?.version === 1 && parsed.attachments && typeof parsed.attachments === "object") {
4718
4478
  return parsed;
@@ -4722,15 +4482,15 @@ function loadManifest(dir) {
4722
4482
  return { version: 1, attachments: {} };
4723
4483
  }
4724
4484
  function saveManifest(dir, manifest) {
4725
- writeFileSync7(
4726
- join7(dir, MANIFEST_FILE2),
4485
+ writeFileSync6(
4486
+ join6(dir, MANIFEST_FILE2),
4727
4487
  `${JSON.stringify(manifest, null, 2)}
4728
4488
  `,
4729
4489
  "utf8"
4730
4490
  );
4731
4491
  }
4732
4492
  function isAttachmentUpToDate(entry, item, dest) {
4733
- if (!entry || !existsSync10(dest)) return false;
4493
+ if (!entry || !existsSync9(dest)) return false;
4734
4494
  if (entry.name !== item.name) return false;
4735
4495
  const createdAt = item.createdAt ?? "";
4736
4496
  return entry.createdAt === createdAt;
@@ -4745,7 +4505,7 @@ async function syncAttachmentsToDirectory(cfg2, attachments, dir, logLabel) {
4745
4505
  const nextManifest = { version: 1, attachments: {} };
4746
4506
  const names = [];
4747
4507
  for (const item of attachments) {
4748
- const dest = join7(dir, item.name);
4508
+ const dest = join6(dir, item.name);
4749
4509
  const entry = manifest.attachments[item.id];
4750
4510
  const createdAt = item.createdAt ?? "";
4751
4511
  names.push(item.name);
@@ -4755,7 +4515,7 @@ async function syncAttachmentsToDirectory(cfg2, attachments, dir, logLabel) {
4755
4515
  continue;
4756
4516
  }
4757
4517
  const buffer = await downloadAttachment(cfg2, item.id);
4758
- writeFileSync7(dest, buffer);
4518
+ writeFileSync6(dest, buffer);
4759
4519
  nextManifest.attachments[item.id] = {
4760
4520
  name: item.name,
4761
4521
  createdAt
@@ -4776,9 +4536,9 @@ async function syncWebIdeAttachments(cfg2, taskId, workdir, attachments) {
4776
4536
  }
4777
4537
 
4778
4538
  // src/commands/sync-webide-design.ts
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";
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";
4782
4542
 
4783
4543
  // src/opc-shared-types.ts
4784
4544
  function webIdeDesignObjectKey(taskId, fileName) {
@@ -4796,15 +4556,15 @@ function webIdeDesignArtifactContentType(name) {
4796
4556
  // src/commands/sync-webide-design.ts
4797
4557
  var MANIFEST_FILE3 = ".sync-manifest.json";
4798
4558
  function hashBuffer(buf) {
4799
- return createHash4("sha256").update(buf).digest("hex");
4559
+ return createHash3("sha256").update(buf).digest("hex");
4800
4560
  }
4801
4561
  function loadManifest2(dir) {
4802
- const path3 = join8(dir, MANIFEST_FILE3);
4803
- if (!existsSync11(path3)) {
4562
+ const path3 = join7(dir, MANIFEST_FILE3);
4563
+ if (!existsSync10(path3)) {
4804
4564
  return { version: 1, files: {} };
4805
4565
  }
4806
4566
  try {
4807
- const parsed = JSON.parse(readFileSync9(path3, "utf8"));
4567
+ const parsed = JSON.parse(readFileSync8(path3, "utf8"));
4808
4568
  if (parsed?.version === 1 && parsed.files && typeof parsed.files === "object") {
4809
4569
  return parsed;
4810
4570
  }
@@ -4813,8 +4573,8 @@ function loadManifest2(dir) {
4813
4573
  return { version: 1, files: {} };
4814
4574
  }
4815
4575
  function saveManifest2(dir, manifest) {
4816
- writeFileSync8(
4817
- join8(dir, MANIFEST_FILE3),
4576
+ writeFileSync7(
4577
+ join7(dir, MANIFEST_FILE3),
4818
4578
  `${JSON.stringify(manifest, null, 2)}
4819
4579
  `,
4820
4580
  "utf8"
@@ -4842,13 +4602,13 @@ async function syncWebIdeDesign(cfg2, taskId, workdir, artifacts) {
4842
4602
  for (const art of artifacts) {
4843
4603
  const name = art.name?.trim();
4844
4604
  if (!name || !isWebIdeDesignArtifactName(name)) continue;
4845
- const localPath = join8(dir, name);
4605
+ const localPath = join7(dir, name);
4846
4606
  const entry = manifest.files[name];
4847
- if (entry?.contentHash === art.contentHash && existsSync11(localPath)) {
4607
+ if (entry?.contentHash === art.contentHash && existsSync10(localPath)) {
4848
4608
  continue;
4849
4609
  }
4850
4610
  const buf = await downloadDesignFile(cfg2, taskId, name);
4851
- writeFileSync8(localPath, buf);
4611
+ writeFileSync7(localPath, buf);
4852
4612
  manifest.files[name] = { contentHash: hashBuffer(buf) };
4853
4613
  synced.push(name);
4854
4614
  }
@@ -4857,13 +4617,13 @@ async function syncWebIdeDesign(cfg2, taskId, workdir, artifacts) {
4857
4617
  }
4858
4618
  function listLocalDesignArtifactFiles(taskId, workdir) {
4859
4619
  const dir = webideDesignDir(taskId, workdir);
4860
- if (!existsSync11(dir)) return [];
4620
+ if (!existsSync10(dir)) return [];
4861
4621
  const out = [];
4862
4622
  for (const name of readdirSync5(dir)) {
4863
4623
  if (!isWebIdeDesignArtifactName(name)) continue;
4864
- const absPath = join8(dir, name);
4624
+ const absPath = join7(dir, name);
4865
4625
  if (!statSync5(absPath).isFile()) continue;
4866
- const buf = readFileSync9(absPath);
4626
+ const buf = readFileSync8(absPath);
4867
4627
  if (buf.length === 0) continue;
4868
4628
  out.push({ name, absPath, contentHash: hashBuffer(buf) });
4869
4629
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-project-manage-cli",
3
- "version": "8.1.14",
3
+ "version": "8.1.16",
4
4
  "description": "命令行工具:后续用于调用平台后端 API 完成运维与自动化操作",
5
5
  "type": "module",
6
6
  "private": false,