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.
- package/dist/worker-script.js +247 -85
- package/package.json +1 -1
package/dist/worker-script.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
|
3184
|
-
mkdirSync as
|
|
3339
|
+
existsSync as existsSync6,
|
|
3340
|
+
mkdirSync as mkdirSync5,
|
|
3185
3341
|
readdirSync as readdirSync3,
|
|
3186
|
-
readFileSync as
|
|
3187
|
-
unlinkSync,
|
|
3188
|
-
writeFileSync as
|
|
3342
|
+
readFileSync as readFileSync5,
|
|
3343
|
+
unlinkSync as unlinkSync2,
|
|
3344
|
+
writeFileSync as writeFileSync4
|
|
3189
3345
|
} from "fs";
|
|
3190
|
-
import { join as
|
|
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(
|
|
3199
|
-
if (!
|
|
3354
|
+
const path3 = toFsPath(join5(apmDir, REVISION_FILE));
|
|
3355
|
+
if (!existsSync6(path3)) return null;
|
|
3200
3356
|
try {
|
|
3201
|
-
const parsed = JSON.parse(
|
|
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
|
-
|
|
3212
|
-
toFsPath(
|
|
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
|
-
|
|
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 =
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
toFsPath(
|
|
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
|
-
|
|
3245
|
-
toFsPath(
|
|
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
|
-
|
|
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
|
|
3434
|
+
existsSync as existsSync7,
|
|
3279
3435
|
readdirSync as readdirSync4,
|
|
3280
|
-
readFileSync as
|
|
3281
|
-
rmSync,
|
|
3282
|
-
writeFileSync as
|
|
3436
|
+
readFileSync as readFileSync6,
|
|
3437
|
+
rmSync as rmSync2,
|
|
3438
|
+
writeFileSync as writeFileSync5
|
|
3283
3439
|
} from "fs";
|
|
3284
|
-
import { createHash as
|
|
3285
|
-
import { dirname as
|
|
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
|
|
3455
|
+
return join6(apmRoot ?? workspaceApmDir(), "project", id);
|
|
3300
3456
|
}
|
|
3301
3457
|
function projectDocumentLocalPath(apmRoot, projectId, documentPath) {
|
|
3302
3458
|
const normalized = normalizeLocalDocumentPath(documentPath);
|
|
3303
|
-
return
|
|
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
|
|
3476
|
+
return createHash3("sha256").update(content, "utf8").digest("hex");
|
|
3321
3477
|
}
|
|
3322
3478
|
function readLocalManifest(apmRoot, projectId) {
|
|
3323
|
-
const manifestPath2 =
|
|
3479
|
+
const manifestPath2 = join6(
|
|
3324
3480
|
projectDocumentsDir(apmRoot, projectId),
|
|
3325
3481
|
MANIFEST_FILE
|
|
3326
3482
|
);
|
|
3327
|
-
if (!
|
|
3483
|
+
if (!existsSync7(manifestPath2)) {
|
|
3328
3484
|
return null;
|
|
3329
3485
|
}
|
|
3330
3486
|
try {
|
|
3331
3487
|
return JSON.parse(
|
|
3332
|
-
|
|
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 (!
|
|
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 =
|
|
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(
|
|
3466
|
-
|
|
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 (
|
|
3476
|
-
|
|
3631
|
+
if (existsSync7(absPath)) {
|
|
3632
|
+
rmSync2(absPath, { force: true });
|
|
3477
3633
|
deleted += 1;
|
|
3478
3634
|
}
|
|
3479
3635
|
}
|
|
3480
|
-
|
|
3481
|
-
toFsPath(
|
|
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 =
|
|
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
|
|
4010
|
-
import { dirname as
|
|
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 (!
|
|
4172
|
+
if (!existsSync8(path3)) {
|
|
4017
4173
|
return {};
|
|
4018
4174
|
}
|
|
4019
4175
|
try {
|
|
4020
|
-
const parsed = JSON.parse(
|
|
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
|
-
|
|
4050
|
-
|
|
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 (!
|
|
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 (!
|
|
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
|
|
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 (
|
|
4180
|
-
|
|
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
|
|
4502
|
-
import { join as
|
|
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 =
|
|
4519
|
-
if (!
|
|
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
|
-
|
|
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
|
-
|
|
4535
|
-
|
|
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 || !
|
|
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 =
|
|
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
|
-
|
|
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
|
|
4589
|
-
import { existsSync as
|
|
4590
|
-
import { join as
|
|
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
|
|
4765
|
+
return createHash4("sha256").update(buf).digest("hex");
|
|
4609
4766
|
}
|
|
4610
4767
|
function loadManifest2(dir) {
|
|
4611
|
-
const path3 =
|
|
4612
|
-
if (!
|
|
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(
|
|
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
|
-
|
|
4626
|
-
|
|
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 =
|
|
4811
|
+
const localPath = join8(dir, name);
|
|
4655
4812
|
const entry = manifest.files[name];
|
|
4656
|
-
if (entry?.contentHash === art.contentHash &&
|
|
4813
|
+
if (entry?.contentHash === art.contentHash && existsSync11(localPath)) {
|
|
4657
4814
|
continue;
|
|
4658
4815
|
}
|
|
4659
4816
|
const buf = await downloadDesignFile(cfg2, taskId, name);
|
|
4660
|
-
|
|
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 (!
|
|
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 =
|
|
4830
|
+
const absPath = join8(dir, name);
|
|
4674
4831
|
if (!statSync5(absPath).isFile()) continue;
|
|
4675
|
-
const buf =
|
|
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,
|