ai-project-manage-cli 8.1.11 → 8.1.13

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.
Files changed (2) hide show
  1. package/dist/worker-script.js +247 -85
  2. package/package.json +1 -1
@@ -1996,6 +1996,14 @@ var MinioClient = class {
1996
1996
  async removeObject(bucket, objectKey) {
1997
1997
  await this.inner.removeObject(bucket, objectKey);
1998
1998
  }
1999
+ async getObjectBuffer(bucket, objectKey) {
2000
+ const stream = await this.inner.getObject(bucket, objectKey);
2001
+ const chunks = [];
2002
+ for await (const chunk of stream) {
2003
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
2004
+ }
2005
+ return Buffer.concat(chunks);
2006
+ }
1999
2007
  };
2000
2008
 
2001
2009
  // src/commands/connect/apm-log-minio.ts
@@ -2460,6 +2468,76 @@ function createPtySessionMcpServers(cfg2) {
2460
2468
  }
2461
2469
 
2462
2470
  // 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
+ }
2463
2541
  function asCheckpointRef(value) {
2464
2542
  if (value === void 0) return void 0;
2465
2543
  if (value === null) return null;
@@ -2534,6 +2612,25 @@ function base64ToBytes(dataBase64) {
2534
2612
  }
2535
2613
  function createRemoteLocalAgentStore(cfg2) {
2536
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);
2629
+ }
2630
+ function forgetCheckpoint(agentId, blobId) {
2631
+ memoryCheckpointCache.delete(checkpointCacheKey(agentId, blobId));
2632
+ deleteLocalCheckpoint(agentId, blobId);
2633
+ }
2537
2634
  async function upsertAgent(agent) {
2538
2635
  const row = await api.cli.cursorStoreUpsertAgent({
2539
2636
  agentId: agent.agentId,
@@ -2570,13 +2667,58 @@ function createRemoteLocalAgentStore(cfg2) {
2570
2667
  return fromApiRun(row);
2571
2668
  }
2572
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
+ }
2573
2687
  await api.cli.cursorStorePutCheckpoint({
2574
2688
  agentId: input.agentId,
2575
2689
  blobId: input.blobId,
2576
2690
  dataBase64: bytesToBase64(input.data),
2577
2691
  byteSize: input.data.byteLength,
2578
- createdAt: Date.now()
2692
+ createdAt
2579
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;
2580
2722
  }
2581
2723
  return {
2582
2724
  agents: {
@@ -2732,12 +2874,7 @@ function createRemoteLocalAgentStore(cfg2) {
2732
2874
  },
2733
2875
  checkpoints: {
2734
2876
  async get(input) {
2735
- const row = await api.cli.cursorStoreGetCheckpoint({
2736
- agentId: input.agentId,
2737
- blobId: input.blobId
2738
- });
2739
- if (!row?.dataBase64) return null;
2740
- return base64ToBytes(row.dataBase64);
2877
+ return readCheckpointBytes(input);
2741
2878
  },
2742
2879
  async create(input) {
2743
2880
  await putCheckpoint(input);
@@ -2750,6 +2887,23 @@ function createRemoteLocalAgentStore(cfg2) {
2750
2887
  const blobIds = input.filter.blobIds?.map((id) => id.trim()).filter(Boolean);
2751
2888
  if (agentIds && agentIds.length > 0 || blobIds && blobIds.length > 0) {
2752
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
+ }
2753
2907
  return;
2754
2908
  }
2755
2909
  let cursor;
@@ -2766,6 +2920,8 @@ function createRemoteLocalAgentStore(cfg2) {
2766
2920
  if (!page.nextCursor) break;
2767
2921
  cursor = page.nextCursor;
2768
2922
  }
2923
+ clearLocalCheckpointCache();
2924
+ memoryCheckpointCache.clear();
2769
2925
  },
2770
2926
  async list(input) {
2771
2927
  const page = await api.cli.cursorStoreListCheckpoints({
@@ -3180,14 +3336,14 @@ function createThrottledWebIdeMessageLogSync(cfg2, ctx, onError, options) {
3180
3336
 
3181
3337
  // src/commands/sync-webide-agent.ts
3182
3338
  import {
3183
- existsSync as existsSync5,
3184
- mkdirSync as mkdirSync4,
3339
+ existsSync as existsSync6,
3340
+ mkdirSync as mkdirSync5,
3185
3341
  readdirSync as readdirSync3,
3186
- readFileSync as readFileSync4,
3187
- unlinkSync,
3188
- writeFileSync as writeFileSync3
3342
+ readFileSync as readFileSync5,
3343
+ unlinkSync as unlinkSync2,
3344
+ writeFileSync as writeFileSync4
3189
3345
  } from "fs";
3190
- import { join as join4 } from "path";
3346
+ import { join as join5 } from "path";
3191
3347
  var REVISION_FILE = ".webide-agent.json";
3192
3348
  var RULE_KEY = /^[a-z0-9_]+$/;
3193
3349
  function withTrailingNewline(text) {
@@ -3195,10 +3351,10 @@ function withTrailingNewline(text) {
3195
3351
  `;
3196
3352
  }
3197
3353
  function readRevision(apmDir) {
3198
- const path3 = toFsPath(join4(apmDir, REVISION_FILE));
3199
- if (!existsSync5(path3)) return null;
3354
+ const path3 = toFsPath(join5(apmDir, REVISION_FILE));
3355
+ if (!existsSync6(path3)) return null;
3200
3356
  try {
3201
- const parsed = JSON.parse(readFileSync4(path3, "utf8"));
3357
+ const parsed = JSON.parse(readFileSync5(path3, "utf8"));
3202
3358
  if (parsed?.version === 1 && parsed.revision?.trim()) {
3203
3359
  return parsed.revision.trim();
3204
3360
  }
@@ -3208,8 +3364,8 @@ function readRevision(apmDir) {
3208
3364
  return null;
3209
3365
  }
3210
3366
  function writeRevision(apmDir, revision) {
3211
- writeFileSync3(
3212
- toFsPath(join4(apmDir, REVISION_FILE)),
3367
+ writeFileSync4(
3368
+ toFsPath(join5(apmDir, REVISION_FILE)),
3213
3369
  `${JSON.stringify({ version: 1, revision }, null, 2)}
3214
3370
  `,
3215
3371
  "utf8"
@@ -3223,14 +3379,14 @@ async function syncWebIdeAgentFiles(workdir, cfg2) {
3223
3379
  throw new Error("[apm] \u5E73\u53F0\u672A\u8FD4\u56DE WebIDE \u89C4\u5219\u7248\u672C");
3224
3380
  }
3225
3381
  const apmDir = workspaceApmDir(workdir);
3226
- mkdirSync4(toFsPath(apmDir), { recursive: true });
3382
+ mkdirSync5(toFsPath(apmDir), { recursive: true });
3227
3383
  if (readRevision(apmDir) === revision) {
3228
3384
  return { revision, wrote: false, ruleCount: bundle.rules?.length ?? 0 };
3229
3385
  }
3230
- const rulesDir = join4(apmDir, "rules");
3231
- mkdirSync4(toFsPath(rulesDir), { recursive: true });
3232
- writeFileSync3(
3233
- toFsPath(join4(apmDir, "AGENTS.md")),
3386
+ const rulesDir = join5(apmDir, "rules");
3387
+ mkdirSync5(toFsPath(rulesDir), { recursive: true });
3388
+ writeFileSync4(
3389
+ toFsPath(join5(apmDir, "AGENTS.md")),
3234
3390
  withTrailingNewline(bundle.guide ?? ""),
3235
3391
  "utf8"
3236
3392
  );
@@ -3241,8 +3397,8 @@ async function syncWebIdeAgentFiles(workdir, cfg2) {
3241
3397
  throw new Error(`[apm] \u975E\u6CD5\u89C4\u5219\u540D: ${key || "(\u7A7A)"}`);
3242
3398
  }
3243
3399
  keep.add(`${key}.md`);
3244
- writeFileSync3(
3245
- toFsPath(join4(rulesDir, `${key}.md`)),
3400
+ writeFileSync4(
3401
+ toFsPath(join5(rulesDir, `${key}.md`)),
3246
3402
  withTrailingNewline(rule.body ?? ""),
3247
3403
  "utf8"
3248
3404
  );
@@ -3250,7 +3406,7 @@ async function syncWebIdeAgentFiles(workdir, cfg2) {
3250
3406
  for (const name of readdirSync3(toFsPath(rulesDir))) {
3251
3407
  if (!name.endsWith(".md")) continue;
3252
3408
  if (keep.has(name)) continue;
3253
- unlinkSync(toFsPath(join4(rulesDir, name)));
3409
+ unlinkSync2(toFsPath(join5(rulesDir, name)));
3254
3410
  }
3255
3411
  writeRevision(apmDir, revision);
3256
3412
  return {
@@ -3275,14 +3431,14 @@ async function ensureWorkspaceInitialized(workdir) {
3275
3431
 
3276
3432
  // src/utils/project-documents.ts
3277
3433
  import {
3278
- existsSync as existsSync6,
3434
+ existsSync as existsSync7,
3279
3435
  readdirSync as readdirSync4,
3280
- readFileSync as readFileSync5,
3281
- rmSync,
3282
- writeFileSync as writeFileSync4
3436
+ readFileSync as readFileSync6,
3437
+ rmSync as rmSync2,
3438
+ writeFileSync as writeFileSync5
3283
3439
  } from "fs";
3284
- import { createHash as createHash2 } from "crypto";
3285
- import { dirname as dirname2, join as join5, relative as relative4, sep } from "path";
3440
+ import { createHash as createHash3 } from "crypto";
3441
+ import { dirname as dirname3, join as join6, relative as relative4, sep } from "path";
3286
3442
  var MANIFEST_FILE = "manifest.json";
3287
3443
  function normalizeProjectIdForPath(projectId) {
3288
3444
  const id = projectId.trim();
@@ -3296,11 +3452,11 @@ function normalizeProjectIdForPath(projectId) {
3296
3452
  }
3297
3453
  function projectDocumentsDir(apmRoot, projectId) {
3298
3454
  const id = normalizeProjectIdForPath(projectId);
3299
- return join5(apmRoot ?? workspaceApmDir(), "project", id);
3455
+ return join6(apmRoot ?? workspaceApmDir(), "project", id);
3300
3456
  }
3301
3457
  function projectDocumentLocalPath(apmRoot, projectId, documentPath) {
3302
3458
  const normalized = normalizeLocalDocumentPath(documentPath);
3303
- return join5(
3459
+ return join6(
3304
3460
  projectDocumentsDir(apmRoot, projectId),
3305
3461
  ...normalized.split("/")
3306
3462
  );
@@ -3317,19 +3473,19 @@ function normalizeLocalDocumentPath(path3) {
3317
3473
  return segments.join("/");
3318
3474
  }
3319
3475
  function hashLocalFileContent(content) {
3320
- return createHash2("sha256").update(content, "utf8").digest("hex");
3476
+ return createHash3("sha256").update(content, "utf8").digest("hex");
3321
3477
  }
3322
3478
  function readLocalManifest(apmRoot, projectId) {
3323
- const manifestPath2 = join5(
3479
+ const manifestPath2 = join6(
3324
3480
  projectDocumentsDir(apmRoot, projectId),
3325
3481
  MANIFEST_FILE
3326
3482
  );
3327
- if (!existsSync6(manifestPath2)) {
3483
+ if (!existsSync7(manifestPath2)) {
3328
3484
  return null;
3329
3485
  }
3330
3486
  try {
3331
3487
  return JSON.parse(
3332
- readFileSync5(manifestPath2, "utf8")
3488
+ readFileSync6(manifestPath2, "utf8")
3333
3489
  );
3334
3490
  } catch {
3335
3491
  return null;
@@ -3337,13 +3493,13 @@ function readLocalManifest(apmRoot, projectId) {
3337
3493
  }
3338
3494
  function listLocalDocumentPaths(apmRoot, projectId) {
3339
3495
  const root = projectDocumentsDir(apmRoot, projectId);
3340
- if (!existsSync6(root)) {
3496
+ if (!existsSync7(root)) {
3341
3497
  return [];
3342
3498
  }
3343
3499
  const paths = [];
3344
3500
  const walk = (dir) => {
3345
3501
  for (const entry of readdirSync4(dir, { withFileTypes: true })) {
3346
- const abs = join5(dir, entry.name);
3502
+ const abs = join6(dir, entry.name);
3347
3503
  if (entry.isDirectory()) {
3348
3504
  walk(abs);
3349
3505
  continue;
@@ -3462,8 +3618,8 @@ ${diagnostic ?? ""}`);
3462
3618
  const absPath = toFsPath(
3463
3619
  projectDocumentLocalPath(targetApmDir, projectId, doc.path)
3464
3620
  );
3465
- await ensureDirExists(dirname2(absPath));
3466
- writeFileSync4(absPath, doc.content, "utf8");
3621
+ await ensureDirExists(dirname3(absPath));
3622
+ writeFileSync5(absPath, doc.content, "utf8");
3467
3623
  downloaded += 1;
3468
3624
  }
3469
3625
  }
@@ -3472,13 +3628,13 @@ ${diagnostic ?? ""}`);
3472
3628
  const absPath = toFsPath(
3473
3629
  projectDocumentLocalPath(targetApmDir, projectId, path3)
3474
3630
  );
3475
- if (existsSync6(absPath)) {
3476
- rmSync(absPath, { force: true });
3631
+ if (existsSync7(absPath)) {
3632
+ rmSync2(absPath, { force: true });
3477
3633
  deleted += 1;
3478
3634
  }
3479
3635
  }
3480
- writeFileSync4(
3481
- toFsPath(join5(docsDir, MANIFEST_FILE)),
3636
+ writeFileSync5(
3637
+ toFsPath(join6(docsDir, MANIFEST_FILE)),
3482
3638
  `${JSON.stringify(remoteManifest, null, 2)}
3483
3639
  `,
3484
3640
  "utf8"
@@ -3521,7 +3677,7 @@ async function syncProjectDocumentsPush(cfg2, workdirPath, apmRoot, options) {
3521
3677
  const absPath = toFsPath(
3522
3678
  projectDocumentLocalPath(targetApmDir, projectId, path3)
3523
3679
  );
3524
- const content = readFileSync5(absPath, "utf8");
3680
+ const content = readFileSync6(absPath, "utf8");
3525
3681
  const contentHash = hashLocalFileContent(content);
3526
3682
  if (remoteHashByPath.get(path3) === contentHash) {
3527
3683
  continue;
@@ -4006,18 +4162,18 @@ async function handleStartProject(cfg2, msg2, signal) {
4006
4162
  }
4007
4163
 
4008
4164
  // src/commands/connect/webide-agent-registry.ts
4009
- import { existsSync as existsSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "node:fs";
4010
- import { dirname as dirname3, resolve as resolve6 } from "node:path";
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";
4011
4167
  function registryPath(workdir, taskId, fileName = "cursor-agent.json") {
4012
4168
  return resolve6(workdir, ".apm", "webide", taskId, fileName);
4013
4169
  }
4014
4170
  var DESIGN_AGENT_FILE = "design-agent.json";
4015
4171
  function readRegistry(path3) {
4016
- if (!existsSync7(path3)) {
4172
+ if (!existsSync8(path3)) {
4017
4173
  return {};
4018
4174
  }
4019
4175
  try {
4020
- const parsed = JSON.parse(readFileSync6(path3, "utf8"));
4176
+ const parsed = JSON.parse(readFileSync7(path3, "utf8"));
4021
4177
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
4022
4178
  const raw = parsed;
4023
4179
  const state = {};
@@ -4046,8 +4202,8 @@ function readRegistry(path3) {
4046
4202
  return {};
4047
4203
  }
4048
4204
  function writeRegistry(path3, registry) {
4049
- mkdirSync5(dirname3(path3), { recursive: true });
4050
- writeFileSync5(path3, `${JSON.stringify(registry, null, 2)}
4205
+ mkdirSync6(dirname4(path3), { recursive: true });
4206
+ writeFileSync6(path3, `${JSON.stringify(registry, null, 2)}
4051
4207
  `, "utf8");
4052
4208
  }
4053
4209
  function syncWebIdeTaskState(workdir, taskId, patch) {
@@ -4088,7 +4244,7 @@ function saveWebIdeAgentId(workdir, taskId, agentId) {
4088
4244
  }
4089
4245
  function clearWebIdeAgentId(workdir, taskId) {
4090
4246
  const path3 = registryPath(workdir, taskId);
4091
- if (!existsSync7(path3)) return;
4247
+ if (!existsSync8(path3)) return;
4092
4248
  syncWebIdeTaskState(workdir, taskId, { agentId: "" });
4093
4249
  }
4094
4250
  function loadWebIdeDesignAgentId(workdir, taskId) {
@@ -4108,7 +4264,7 @@ function saveWebIdeDesignAgentId(workdir, taskId, agentId) {
4108
4264
  }
4109
4265
  function clearWebIdeDesignAgentId(workdir, taskId) {
4110
4266
  const path3 = registryPath(workdir, taskId, DESIGN_AGENT_FILE);
4111
- if (!existsSync7(path3)) return;
4267
+ if (!existsSync8(path3)) return;
4112
4268
  const current = readRegistry(path3);
4113
4269
  const next = { ...current };
4114
4270
  delete next.agentId;
@@ -4120,7 +4276,7 @@ function clearWebIdeDesignAgentId(workdir, taskId) {
4120
4276
  }
4121
4277
 
4122
4278
  // src/commands/clean-webide-cache.ts
4123
- import { existsSync as existsSync8, rmSync as rmSync2 } from "node:fs";
4279
+ import { existsSync as existsSync9, rmSync as rmSync3 } from "node:fs";
4124
4280
  import { resolve as resolve7 } from "node:path";
4125
4281
  async function purgeCursorAgentStoreForAgent(cfg2, agentId) {
4126
4282
  const trimmedAgentId = agentId.trim();
@@ -4147,6 +4303,7 @@ async function purgeCursorAgentStoreForAgent(cfg2, agentId) {
4147
4303
  await store.runs.delete({ filter: { agentIds: [trimmedAgentId] } });
4148
4304
  await store.checkpoints.delete({ filter: { agentIds: [trimmedAgentId] } });
4149
4305
  await store.agents.delete({ filter: { agentIds: [trimmedAgentId] } });
4306
+ clearLocalCheckpointCache(trimmedAgentId);
4150
4307
  return true;
4151
4308
  }
4152
4309
  async function cleanWebIdeWorkspaceCache(taskId, workdir, cfg2) {
@@ -4176,8 +4333,8 @@ async function cleanWebIdeWorkspaceCache(taskId, workdir, cfg2) {
4176
4333
  );
4177
4334
  }
4178
4335
  const dir = resolve7(trimmedWorkdir, ".apm", "webide", trimmedTaskId);
4179
- if (existsSync8(dir)) {
4180
- rmSync2(dir, { recursive: true, force: true });
4336
+ if (existsSync9(dir)) {
4337
+ rmSync3(dir, { recursive: true, force: true });
4181
4338
  console.log(`[apm] \u5DF2\u6E05\u7406 WebIDE \u7F13\u5B58 ${dir}`);
4182
4339
  } else {
4183
4340
  console.log(`[apm] WebIDE \u7F13\u5B58\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7 ${dir}`);
@@ -4498,8 +4655,8 @@ async function ensureWebIdePullRequests(cfg2, taskId, workdir) {
4498
4655
  }
4499
4656
 
4500
4657
  // src/commands/sync-webide-attachments.ts
4501
- import { existsSync as existsSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
4502
- import { join as join6 } from "path";
4658
+ import { existsSync as existsSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "fs";
4659
+ import { join as join7 } from "path";
4503
4660
  var MANIFEST_FILE2 = ".sync-manifest.json";
4504
4661
  async function downloadAttachment(cfg2, attachmentId) {
4505
4662
  const base = cfg2.baseUrl.trim().replace(/\/+$/, "");
@@ -4515,13 +4672,13 @@ async function downloadAttachment(cfg2, attachmentId) {
4515
4672
  return Buffer.from(await res.arrayBuffer());
4516
4673
  }
4517
4674
  function loadManifest(dir) {
4518
- const path3 = join6(dir, MANIFEST_FILE2);
4519
- if (!existsSync9(path3)) {
4675
+ const path3 = join7(dir, MANIFEST_FILE2);
4676
+ if (!existsSync10(path3)) {
4520
4677
  return { version: 1, attachments: {} };
4521
4678
  }
4522
4679
  try {
4523
4680
  const parsed = JSON.parse(
4524
- readFileSync7(path3, "utf8")
4681
+ readFileSync8(path3, "utf8")
4525
4682
  );
4526
4683
  if (parsed?.version === 1 && parsed.attachments && typeof parsed.attachments === "object") {
4527
4684
  return parsed;
@@ -4531,15 +4688,15 @@ function loadManifest(dir) {
4531
4688
  return { version: 1, attachments: {} };
4532
4689
  }
4533
4690
  function saveManifest(dir, manifest) {
4534
- writeFileSync6(
4535
- join6(dir, MANIFEST_FILE2),
4691
+ writeFileSync7(
4692
+ join7(dir, MANIFEST_FILE2),
4536
4693
  `${JSON.stringify(manifest, null, 2)}
4537
4694
  `,
4538
4695
  "utf8"
4539
4696
  );
4540
4697
  }
4541
4698
  function isAttachmentUpToDate(entry, item, dest) {
4542
- if (!entry || !existsSync9(dest)) return false;
4699
+ if (!entry || !existsSync10(dest)) return false;
4543
4700
  if (entry.name !== item.name) return false;
4544
4701
  const createdAt = item.createdAt ?? "";
4545
4702
  return entry.createdAt === createdAt;
@@ -4554,7 +4711,7 @@ async function syncAttachmentsToDirectory(cfg2, attachments, dir, logLabel) {
4554
4711
  const nextManifest = { version: 1, attachments: {} };
4555
4712
  const names = [];
4556
4713
  for (const item of attachments) {
4557
- const dest = join6(dir, item.name);
4714
+ const dest = join7(dir, item.name);
4558
4715
  const entry = manifest.attachments[item.id];
4559
4716
  const createdAt = item.createdAt ?? "";
4560
4717
  names.push(item.name);
@@ -4564,7 +4721,7 @@ async function syncAttachmentsToDirectory(cfg2, attachments, dir, logLabel) {
4564
4721
  continue;
4565
4722
  }
4566
4723
  const buffer = await downloadAttachment(cfg2, item.id);
4567
- writeFileSync6(dest, buffer);
4724
+ writeFileSync7(dest, buffer);
4568
4725
  nextManifest.attachments[item.id] = {
4569
4726
  name: item.name,
4570
4727
  createdAt
@@ -4585,9 +4742,9 @@ async function syncWebIdeAttachments(cfg2, taskId, workdir, attachments) {
4585
4742
  }
4586
4743
 
4587
4744
  // src/commands/sync-webide-design.ts
4588
- import { createHash as createHash3 } from "crypto";
4589
- import { existsSync as existsSync10, readdirSync as readdirSync5, readFileSync as readFileSync8, statSync as statSync5, writeFileSync as writeFileSync7 } from "fs";
4590
- import { join as join7 } from "path";
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";
4591
4748
 
4592
4749
  // src/opc-shared-types.ts
4593
4750
  function webIdeDesignObjectKey(taskId, fileName) {
@@ -4605,15 +4762,15 @@ function webIdeDesignArtifactContentType(name) {
4605
4762
  // src/commands/sync-webide-design.ts
4606
4763
  var MANIFEST_FILE3 = ".sync-manifest.json";
4607
4764
  function hashBuffer(buf) {
4608
- return createHash3("sha256").update(buf).digest("hex");
4765
+ return createHash4("sha256").update(buf).digest("hex");
4609
4766
  }
4610
4767
  function loadManifest2(dir) {
4611
- const path3 = join7(dir, MANIFEST_FILE3);
4612
- if (!existsSync10(path3)) {
4768
+ const path3 = join8(dir, MANIFEST_FILE3);
4769
+ if (!existsSync11(path3)) {
4613
4770
  return { version: 1, files: {} };
4614
4771
  }
4615
4772
  try {
4616
- const parsed = JSON.parse(readFileSync8(path3, "utf8"));
4773
+ const parsed = JSON.parse(readFileSync9(path3, "utf8"));
4617
4774
  if (parsed?.version === 1 && parsed.files && typeof parsed.files === "object") {
4618
4775
  return parsed;
4619
4776
  }
@@ -4622,8 +4779,8 @@ function loadManifest2(dir) {
4622
4779
  return { version: 1, files: {} };
4623
4780
  }
4624
4781
  function saveManifest2(dir, manifest) {
4625
- writeFileSync7(
4626
- join7(dir, MANIFEST_FILE3),
4782
+ writeFileSync8(
4783
+ join8(dir, MANIFEST_FILE3),
4627
4784
  `${JSON.stringify(manifest, null, 2)}
4628
4785
  `,
4629
4786
  "utf8"
@@ -4651,13 +4808,13 @@ async function syncWebIdeDesign(cfg2, taskId, workdir, artifacts) {
4651
4808
  for (const art of artifacts) {
4652
4809
  const name = art.name?.trim();
4653
4810
  if (!name || !isWebIdeDesignArtifactName(name)) continue;
4654
- const localPath = join7(dir, name);
4811
+ const localPath = join8(dir, name);
4655
4812
  const entry = manifest.files[name];
4656
- if (entry?.contentHash === art.contentHash && existsSync10(localPath)) {
4813
+ if (entry?.contentHash === art.contentHash && existsSync11(localPath)) {
4657
4814
  continue;
4658
4815
  }
4659
4816
  const buf = await downloadDesignFile(cfg2, taskId, name);
4660
- writeFileSync7(localPath, buf);
4817
+ writeFileSync8(localPath, buf);
4661
4818
  manifest.files[name] = { contentHash: hashBuffer(buf) };
4662
4819
  synced.push(name);
4663
4820
  }
@@ -4666,13 +4823,13 @@ async function syncWebIdeDesign(cfg2, taskId, workdir, artifacts) {
4666
4823
  }
4667
4824
  function listLocalDesignArtifactFiles(taskId, workdir) {
4668
4825
  const dir = webideDesignDir(taskId, workdir);
4669
- if (!existsSync10(dir)) return [];
4826
+ if (!existsSync11(dir)) return [];
4670
4827
  const out = [];
4671
4828
  for (const name of readdirSync5(dir)) {
4672
4829
  if (!isWebIdeDesignArtifactName(name)) continue;
4673
- const absPath = join7(dir, name);
4830
+ const absPath = join8(dir, name);
4674
4831
  if (!statSync5(absPath).isFile()) continue;
4675
- const buf = readFileSync8(absPath);
4832
+ const buf = readFileSync9(absPath);
4676
4833
  if (buf.length === 0) continue;
4677
4834
  out.push({ name, absPath, contentHash: hashBuffer(buf) });
4678
4835
  }
@@ -5103,6 +5260,11 @@ async function handleWebIdeInboundMessage(cfg2, msg2, signal) {
5103
5260
  const savedAgentId = startLocalServices || useNewAgent ? void 0 : designAction ? loadWebIdeDesignAgentId(workdir, taskId) : loadWebIdeAgentId(workdir, taskId);
5104
5261
  const promptPayload = toolNames.includes("MysqlExecute") ? parseWebIdePromptPayload(msg2.content) : null;
5105
5262
  const sqlExecutionId = toolNames.includes("MysqlExecute") && typeof promptPayload?.executionId === "string" ? promptPayload.executionId.trim() : void 0;
5263
+ if (toolNames.includes("MysqlExecute") && !sqlExecutionId) {
5264
+ console.warn(
5265
+ "[apm] \u5DE5\u5177\u540D\u5355\u542B MysqlExecute\uFF0C\u4F46 prompt \u672B\u5C3E\u6CA1\u6709 executionId\uFF0C\u672C\u8F6E\u4E0D\u4F1A\u6302\u8F7D\u8BE5\u5DE5\u5177"
5266
+ );
5267
+ }
5106
5268
  const persistAgentId = (agentId) => {
5107
5269
  if (startLocalServices) return;
5108
5270
  if (designAction) {
@@ -5212,7 +5374,7 @@ ${assumptionAnswersText}` : msg2.content,
5212
5374
  detail,
5213
5375
  tokenUsage
5214
5376
  );
5215
- if (sqlExecutionId) {
5377
+ if (sqlExecutionId && msg2.action !== "request-bugfix") {
5216
5378
  try {
5217
5379
  await api.cli.webideFinalizeSqlExecution({
5218
5380
  executionId: sqlExecutionId,
@@ -5237,7 +5399,7 @@ ${assumptionAnswersText}` : msg2.content,
5237
5399
  "\u5DF2\u53D6\u6D88",
5238
5400
  tokenUsage
5239
5401
  );
5240
- if (sqlExecutionId) {
5402
+ if (sqlExecutionId && msg2.action !== "request-bugfix") {
5241
5403
  try {
5242
5404
  await api.cli.webideFinalizeSqlExecution({
5243
5405
  executionId: sqlExecutionId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-project-manage-cli",
3
- "version": "8.1.11",
3
+ "version": "8.1.13",
4
4
  "description": "命令行工具:后续用于调用平台后端 API 完成运维与自动化操作",
5
5
  "type": "module",
6
6
  "private": false,