ai-project-manage-cli 8.1.12 → 8.1.14
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 +5 -0
- package/dist/worker-script.js +278 -106
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -133,6 +133,11 @@ var requestConfig = {
|
|
|
133
133
|
method: "PUT",
|
|
134
134
|
path: "/cli/webide/transition-prep-events"
|
|
135
135
|
}),
|
|
136
|
+
/** 「继续」开跑后挂新 runId */
|
|
137
|
+
webideAttachContinueRun: defineEndpoint({
|
|
138
|
+
method: "PUT",
|
|
139
|
+
path: "/cli/webide/continue-run"
|
|
140
|
+
}),
|
|
136
141
|
webideUpsertMessageLog: defineEndpoint({
|
|
137
142
|
method: "PUT",
|
|
138
143
|
path: "/cli/webide/message-logs"
|
package/dist/worker-script.js
CHANGED
|
@@ -44,6 +44,11 @@ var requestConfig = {
|
|
|
44
44
|
method: "PUT",
|
|
45
45
|
path: "/cli/webide/transition-prep-events"
|
|
46
46
|
}),
|
|
47
|
+
/** 「继续」开跑后挂新 runId */
|
|
48
|
+
webideAttachContinueRun: defineEndpoint({
|
|
49
|
+
method: "PUT",
|
|
50
|
+
path: "/cli/webide/continue-run"
|
|
51
|
+
}),
|
|
47
52
|
webideUpsertMessageLog: defineEndpoint({
|
|
48
53
|
method: "PUT",
|
|
49
54
|
path: "/cli/webide/message-logs"
|
|
@@ -2468,10 +2473,76 @@ function createPtySessionMcpServers(cfg2) {
|
|
|
2468
2473
|
}
|
|
2469
2474
|
|
|
2470
2475
|
// 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";
|
|
2471
2486
|
var INLINE_CHECKPOINT_MAX_BYTES = 256 * 1024;
|
|
2487
|
+
var CHECKPOINT_CACHE_DIR = join4(APM_CONFIG_DIR, "cursor-checkpoint-cache");
|
|
2472
2488
|
function checkpointObjectKey(agentId, blobId) {
|
|
2473
2489
|
return `cursor-agents/${agentId}/checkpoints/${blobId}`;
|
|
2474
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
|
+
}
|
|
2475
2546
|
function asCheckpointRef(value) {
|
|
2476
2547
|
if (value === void 0) return void 0;
|
|
2477
2548
|
if (value === null) return null;
|
|
@@ -2544,9 +2615,16 @@ function bytesToBase64(data) {
|
|
|
2544
2615
|
function base64ToBytes(dataBase64) {
|
|
2545
2616
|
return new Uint8Array(Buffer.from(dataBase64, "base64"));
|
|
2546
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
|
+
}
|
|
2547
2624
|
function createRemoteLocalAgentStore(cfg2) {
|
|
2548
2625
|
const api = createApmApiClient(cfg2);
|
|
2549
2626
|
let minioCache = null;
|
|
2627
|
+
const memoryCheckpointCache = /* @__PURE__ */ new Map();
|
|
2550
2628
|
function getMinio() {
|
|
2551
2629
|
if (!minioCache) {
|
|
2552
2630
|
minioCache = createApmLogMinioClient(cfg2).then(({ client, bucket }) => ({
|
|
@@ -2556,6 +2634,14 @@ function createRemoteLocalAgentStore(cfg2) {
|
|
|
2556
2634
|
}
|
|
2557
2635
|
return minioCache;
|
|
2558
2636
|
}
|
|
2637
|
+
function rememberCheckpoint(agentId, blobId, data) {
|
|
2638
|
+
memoryCheckpointCache.set(checkpointCacheKey(agentId, blobId), data);
|
|
2639
|
+
writeLocalCheckpoint(agentId, blobId, data);
|
|
2640
|
+
}
|
|
2641
|
+
function forgetCheckpoint(agentId, blobId) {
|
|
2642
|
+
memoryCheckpointCache.delete(checkpointCacheKey(agentId, blobId));
|
|
2643
|
+
deleteLocalCheckpoint(agentId, blobId);
|
|
2644
|
+
}
|
|
2559
2645
|
async function upsertAgent(agent) {
|
|
2560
2646
|
const row = await api.cli.cursorStoreUpsertAgent({
|
|
2561
2647
|
agentId: agent.agentId,
|
|
@@ -2591,7 +2677,7 @@ function createRemoteLocalAgentStore(cfg2) {
|
|
|
2591
2677
|
});
|
|
2592
2678
|
return fromApiRun(row);
|
|
2593
2679
|
}
|
|
2594
|
-
async function
|
|
2680
|
+
async function uploadCheckpointRemote(input) {
|
|
2595
2681
|
const createdAt = Date.now();
|
|
2596
2682
|
if (input.data.byteLength > INLINE_CHECKPOINT_MAX_BYTES) {
|
|
2597
2683
|
const { client, bucket } = await getMinio();
|
|
@@ -2616,20 +2702,56 @@ function createRemoteLocalAgentStore(cfg2) {
|
|
|
2616
2702
|
createdAt
|
|
2617
2703
|
});
|
|
2618
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
|
+
}
|
|
2619
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
|
+
}
|
|
2620
2738
|
const row = await api.cli.cursorStoreGetCheckpoint({
|
|
2621
2739
|
agentId: input.agentId,
|
|
2622
2740
|
blobId: input.blobId
|
|
2623
2741
|
});
|
|
2624
2742
|
if (!row) return null;
|
|
2743
|
+
let bytes = null;
|
|
2625
2744
|
if (row.dataBase64) {
|
|
2626
|
-
|
|
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);
|
|
2627
2752
|
}
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
const { client, bucket } = await getMinio();
|
|
2631
|
-
const buf = await client.getObjectBuffer(bucket, objectKey);
|
|
2632
|
-
return new Uint8Array(buf);
|
|
2753
|
+
rememberCheckpoint(input.agentId, input.blobId, bytes);
|
|
2754
|
+
return bytes;
|
|
2633
2755
|
}
|
|
2634
2756
|
return {
|
|
2635
2757
|
agents: {
|
|
@@ -2798,6 +2920,23 @@ function createRemoteLocalAgentStore(cfg2) {
|
|
|
2798
2920
|
const blobIds = input.filter.blobIds?.map((id) => id.trim()).filter(Boolean);
|
|
2799
2921
|
if (agentIds && agentIds.length > 0 || blobIds && blobIds.length > 0) {
|
|
2800
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
|
+
}
|
|
2801
2940
|
return;
|
|
2802
2941
|
}
|
|
2803
2942
|
let cursor;
|
|
@@ -2814,6 +2953,8 @@ function createRemoteLocalAgentStore(cfg2) {
|
|
|
2814
2953
|
if (!page.nextCursor) break;
|
|
2815
2954
|
cursor = page.nextCursor;
|
|
2816
2955
|
}
|
|
2956
|
+
clearLocalCheckpointCache();
|
|
2957
|
+
memoryCheckpointCache.clear();
|
|
2817
2958
|
},
|
|
2818
2959
|
async list(input) {
|
|
2819
2960
|
const page = await api.cli.cursorStoreListCheckpoints({
|
|
@@ -3228,14 +3369,14 @@ function createThrottledWebIdeMessageLogSync(cfg2, ctx, onError, options) {
|
|
|
3228
3369
|
|
|
3229
3370
|
// src/commands/sync-webide-agent.ts
|
|
3230
3371
|
import {
|
|
3231
|
-
existsSync as
|
|
3232
|
-
mkdirSync as
|
|
3372
|
+
existsSync as existsSync6,
|
|
3373
|
+
mkdirSync as mkdirSync5,
|
|
3233
3374
|
readdirSync as readdirSync3,
|
|
3234
|
-
readFileSync as
|
|
3235
|
-
unlinkSync,
|
|
3236
|
-
writeFileSync as
|
|
3375
|
+
readFileSync as readFileSync5,
|
|
3376
|
+
unlinkSync as unlinkSync2,
|
|
3377
|
+
writeFileSync as writeFileSync4
|
|
3237
3378
|
} from "fs";
|
|
3238
|
-
import { join as
|
|
3379
|
+
import { join as join5 } from "path";
|
|
3239
3380
|
var REVISION_FILE = ".webide-agent.json";
|
|
3240
3381
|
var RULE_KEY = /^[a-z0-9_]+$/;
|
|
3241
3382
|
function withTrailingNewline(text) {
|
|
@@ -3243,10 +3384,10 @@ function withTrailingNewline(text) {
|
|
|
3243
3384
|
`;
|
|
3244
3385
|
}
|
|
3245
3386
|
function readRevision(apmDir) {
|
|
3246
|
-
const path3 = toFsPath(
|
|
3247
|
-
if (!
|
|
3387
|
+
const path3 = toFsPath(join5(apmDir, REVISION_FILE));
|
|
3388
|
+
if (!existsSync6(path3)) return null;
|
|
3248
3389
|
try {
|
|
3249
|
-
const parsed = JSON.parse(
|
|
3390
|
+
const parsed = JSON.parse(readFileSync5(path3, "utf8"));
|
|
3250
3391
|
if (parsed?.version === 1 && parsed.revision?.trim()) {
|
|
3251
3392
|
return parsed.revision.trim();
|
|
3252
3393
|
}
|
|
@@ -3256,8 +3397,8 @@ function readRevision(apmDir) {
|
|
|
3256
3397
|
return null;
|
|
3257
3398
|
}
|
|
3258
3399
|
function writeRevision(apmDir, revision) {
|
|
3259
|
-
|
|
3260
|
-
toFsPath(
|
|
3400
|
+
writeFileSync4(
|
|
3401
|
+
toFsPath(join5(apmDir, REVISION_FILE)),
|
|
3261
3402
|
`${JSON.stringify({ version: 1, revision }, null, 2)}
|
|
3262
3403
|
`,
|
|
3263
3404
|
"utf8"
|
|
@@ -3271,14 +3412,14 @@ async function syncWebIdeAgentFiles(workdir, cfg2) {
|
|
|
3271
3412
|
throw new Error("[apm] \u5E73\u53F0\u672A\u8FD4\u56DE WebIDE \u89C4\u5219\u7248\u672C");
|
|
3272
3413
|
}
|
|
3273
3414
|
const apmDir = workspaceApmDir(workdir);
|
|
3274
|
-
|
|
3415
|
+
mkdirSync5(toFsPath(apmDir), { recursive: true });
|
|
3275
3416
|
if (readRevision(apmDir) === revision) {
|
|
3276
3417
|
return { revision, wrote: false, ruleCount: bundle.rules?.length ?? 0 };
|
|
3277
3418
|
}
|
|
3278
|
-
const rulesDir =
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
toFsPath(
|
|
3419
|
+
const rulesDir = join5(apmDir, "rules");
|
|
3420
|
+
mkdirSync5(toFsPath(rulesDir), { recursive: true });
|
|
3421
|
+
writeFileSync4(
|
|
3422
|
+
toFsPath(join5(apmDir, "AGENTS.md")),
|
|
3282
3423
|
withTrailingNewline(bundle.guide ?? ""),
|
|
3283
3424
|
"utf8"
|
|
3284
3425
|
);
|
|
@@ -3289,8 +3430,8 @@ async function syncWebIdeAgentFiles(workdir, cfg2) {
|
|
|
3289
3430
|
throw new Error(`[apm] \u975E\u6CD5\u89C4\u5219\u540D: ${key || "(\u7A7A)"}`);
|
|
3290
3431
|
}
|
|
3291
3432
|
keep.add(`${key}.md`);
|
|
3292
|
-
|
|
3293
|
-
toFsPath(
|
|
3433
|
+
writeFileSync4(
|
|
3434
|
+
toFsPath(join5(rulesDir, `${key}.md`)),
|
|
3294
3435
|
withTrailingNewline(rule.body ?? ""),
|
|
3295
3436
|
"utf8"
|
|
3296
3437
|
);
|
|
@@ -3298,7 +3439,7 @@ async function syncWebIdeAgentFiles(workdir, cfg2) {
|
|
|
3298
3439
|
for (const name of readdirSync3(toFsPath(rulesDir))) {
|
|
3299
3440
|
if (!name.endsWith(".md")) continue;
|
|
3300
3441
|
if (keep.has(name)) continue;
|
|
3301
|
-
|
|
3442
|
+
unlinkSync2(toFsPath(join5(rulesDir, name)));
|
|
3302
3443
|
}
|
|
3303
3444
|
writeRevision(apmDir, revision);
|
|
3304
3445
|
return {
|
|
@@ -3323,14 +3464,14 @@ async function ensureWorkspaceInitialized(workdir) {
|
|
|
3323
3464
|
|
|
3324
3465
|
// src/utils/project-documents.ts
|
|
3325
3466
|
import {
|
|
3326
|
-
existsSync as
|
|
3467
|
+
existsSync as existsSync7,
|
|
3327
3468
|
readdirSync as readdirSync4,
|
|
3328
|
-
readFileSync as
|
|
3329
|
-
rmSync,
|
|
3330
|
-
writeFileSync as
|
|
3469
|
+
readFileSync as readFileSync6,
|
|
3470
|
+
rmSync as rmSync2,
|
|
3471
|
+
writeFileSync as writeFileSync5
|
|
3331
3472
|
} from "fs";
|
|
3332
|
-
import { createHash as
|
|
3333
|
-
import { dirname as
|
|
3473
|
+
import { createHash as createHash3 } from "crypto";
|
|
3474
|
+
import { dirname as dirname3, join as join6, relative as relative4, sep } from "path";
|
|
3334
3475
|
var MANIFEST_FILE = "manifest.json";
|
|
3335
3476
|
function normalizeProjectIdForPath(projectId) {
|
|
3336
3477
|
const id = projectId.trim();
|
|
@@ -3344,11 +3485,11 @@ function normalizeProjectIdForPath(projectId) {
|
|
|
3344
3485
|
}
|
|
3345
3486
|
function projectDocumentsDir(apmRoot, projectId) {
|
|
3346
3487
|
const id = normalizeProjectIdForPath(projectId);
|
|
3347
|
-
return
|
|
3488
|
+
return join6(apmRoot ?? workspaceApmDir(), "project", id);
|
|
3348
3489
|
}
|
|
3349
3490
|
function projectDocumentLocalPath(apmRoot, projectId, documentPath) {
|
|
3350
3491
|
const normalized = normalizeLocalDocumentPath(documentPath);
|
|
3351
|
-
return
|
|
3492
|
+
return join6(
|
|
3352
3493
|
projectDocumentsDir(apmRoot, projectId),
|
|
3353
3494
|
...normalized.split("/")
|
|
3354
3495
|
);
|
|
@@ -3365,19 +3506,19 @@ function normalizeLocalDocumentPath(path3) {
|
|
|
3365
3506
|
return segments.join("/");
|
|
3366
3507
|
}
|
|
3367
3508
|
function hashLocalFileContent(content) {
|
|
3368
|
-
return
|
|
3509
|
+
return createHash3("sha256").update(content, "utf8").digest("hex");
|
|
3369
3510
|
}
|
|
3370
3511
|
function readLocalManifest(apmRoot, projectId) {
|
|
3371
|
-
const manifestPath2 =
|
|
3512
|
+
const manifestPath2 = join6(
|
|
3372
3513
|
projectDocumentsDir(apmRoot, projectId),
|
|
3373
3514
|
MANIFEST_FILE
|
|
3374
3515
|
);
|
|
3375
|
-
if (!
|
|
3516
|
+
if (!existsSync7(manifestPath2)) {
|
|
3376
3517
|
return null;
|
|
3377
3518
|
}
|
|
3378
3519
|
try {
|
|
3379
3520
|
return JSON.parse(
|
|
3380
|
-
|
|
3521
|
+
readFileSync6(manifestPath2, "utf8")
|
|
3381
3522
|
);
|
|
3382
3523
|
} catch {
|
|
3383
3524
|
return null;
|
|
@@ -3385,13 +3526,13 @@ function readLocalManifest(apmRoot, projectId) {
|
|
|
3385
3526
|
}
|
|
3386
3527
|
function listLocalDocumentPaths(apmRoot, projectId) {
|
|
3387
3528
|
const root = projectDocumentsDir(apmRoot, projectId);
|
|
3388
|
-
if (!
|
|
3529
|
+
if (!existsSync7(root)) {
|
|
3389
3530
|
return [];
|
|
3390
3531
|
}
|
|
3391
3532
|
const paths = [];
|
|
3392
3533
|
const walk = (dir) => {
|
|
3393
3534
|
for (const entry of readdirSync4(dir, { withFileTypes: true })) {
|
|
3394
|
-
const abs =
|
|
3535
|
+
const abs = join6(dir, entry.name);
|
|
3395
3536
|
if (entry.isDirectory()) {
|
|
3396
3537
|
walk(abs);
|
|
3397
3538
|
continue;
|
|
@@ -3510,8 +3651,8 @@ ${diagnostic ?? ""}`);
|
|
|
3510
3651
|
const absPath = toFsPath(
|
|
3511
3652
|
projectDocumentLocalPath(targetApmDir, projectId, doc.path)
|
|
3512
3653
|
);
|
|
3513
|
-
await ensureDirExists(
|
|
3514
|
-
|
|
3654
|
+
await ensureDirExists(dirname3(absPath));
|
|
3655
|
+
writeFileSync5(absPath, doc.content, "utf8");
|
|
3515
3656
|
downloaded += 1;
|
|
3516
3657
|
}
|
|
3517
3658
|
}
|
|
@@ -3520,13 +3661,13 @@ ${diagnostic ?? ""}`);
|
|
|
3520
3661
|
const absPath = toFsPath(
|
|
3521
3662
|
projectDocumentLocalPath(targetApmDir, projectId, path3)
|
|
3522
3663
|
);
|
|
3523
|
-
if (
|
|
3524
|
-
|
|
3664
|
+
if (existsSync7(absPath)) {
|
|
3665
|
+
rmSync2(absPath, { force: true });
|
|
3525
3666
|
deleted += 1;
|
|
3526
3667
|
}
|
|
3527
3668
|
}
|
|
3528
|
-
|
|
3529
|
-
toFsPath(
|
|
3669
|
+
writeFileSync5(
|
|
3670
|
+
toFsPath(join6(docsDir, MANIFEST_FILE)),
|
|
3530
3671
|
`${JSON.stringify(remoteManifest, null, 2)}
|
|
3531
3672
|
`,
|
|
3532
3673
|
"utf8"
|
|
@@ -3569,7 +3710,7 @@ async function syncProjectDocumentsPush(cfg2, workdirPath, apmRoot, options) {
|
|
|
3569
3710
|
const absPath = toFsPath(
|
|
3570
3711
|
projectDocumentLocalPath(targetApmDir, projectId, path3)
|
|
3571
3712
|
);
|
|
3572
|
-
const content =
|
|
3713
|
+
const content = readFileSync6(absPath, "utf8");
|
|
3573
3714
|
const contentHash = hashLocalFileContent(content);
|
|
3574
3715
|
if (remoteHashByPath.get(path3) === contentHash) {
|
|
3575
3716
|
continue;
|
|
@@ -4054,18 +4195,18 @@ async function handleStartProject(cfg2, msg2, signal) {
|
|
|
4054
4195
|
}
|
|
4055
4196
|
|
|
4056
4197
|
// src/commands/connect/webide-agent-registry.ts
|
|
4057
|
-
import { existsSync as
|
|
4058
|
-
import { dirname as
|
|
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";
|
|
4059
4200
|
function registryPath(workdir, taskId, fileName = "cursor-agent.json") {
|
|
4060
4201
|
return resolve6(workdir, ".apm", "webide", taskId, fileName);
|
|
4061
4202
|
}
|
|
4062
4203
|
var DESIGN_AGENT_FILE = "design-agent.json";
|
|
4063
4204
|
function readRegistry(path3) {
|
|
4064
|
-
if (!
|
|
4205
|
+
if (!existsSync8(path3)) {
|
|
4065
4206
|
return {};
|
|
4066
4207
|
}
|
|
4067
4208
|
try {
|
|
4068
|
-
const parsed = JSON.parse(
|
|
4209
|
+
const parsed = JSON.parse(readFileSync7(path3, "utf8"));
|
|
4069
4210
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
4070
4211
|
const raw = parsed;
|
|
4071
4212
|
const state = {};
|
|
@@ -4094,8 +4235,8 @@ function readRegistry(path3) {
|
|
|
4094
4235
|
return {};
|
|
4095
4236
|
}
|
|
4096
4237
|
function writeRegistry(path3, registry) {
|
|
4097
|
-
|
|
4098
|
-
|
|
4238
|
+
mkdirSync6(dirname4(path3), { recursive: true });
|
|
4239
|
+
writeFileSync6(path3, `${JSON.stringify(registry, null, 2)}
|
|
4099
4240
|
`, "utf8");
|
|
4100
4241
|
}
|
|
4101
4242
|
function syncWebIdeTaskState(workdir, taskId, patch) {
|
|
@@ -4136,7 +4277,7 @@ function saveWebIdeAgentId(workdir, taskId, agentId) {
|
|
|
4136
4277
|
}
|
|
4137
4278
|
function clearWebIdeAgentId(workdir, taskId) {
|
|
4138
4279
|
const path3 = registryPath(workdir, taskId);
|
|
4139
|
-
if (!
|
|
4280
|
+
if (!existsSync8(path3)) return;
|
|
4140
4281
|
syncWebIdeTaskState(workdir, taskId, { agentId: "" });
|
|
4141
4282
|
}
|
|
4142
4283
|
function loadWebIdeDesignAgentId(workdir, taskId) {
|
|
@@ -4156,7 +4297,7 @@ function saveWebIdeDesignAgentId(workdir, taskId, agentId) {
|
|
|
4156
4297
|
}
|
|
4157
4298
|
function clearWebIdeDesignAgentId(workdir, taskId) {
|
|
4158
4299
|
const path3 = registryPath(workdir, taskId, DESIGN_AGENT_FILE);
|
|
4159
|
-
if (!
|
|
4300
|
+
if (!existsSync8(path3)) return;
|
|
4160
4301
|
const current = readRegistry(path3);
|
|
4161
4302
|
const next = { ...current };
|
|
4162
4303
|
delete next.agentId;
|
|
@@ -4168,11 +4309,12 @@ function clearWebIdeDesignAgentId(workdir, taskId) {
|
|
|
4168
4309
|
}
|
|
4169
4310
|
|
|
4170
4311
|
// src/commands/clean-webide-cache.ts
|
|
4171
|
-
import { existsSync as
|
|
4312
|
+
import { existsSync as existsSync9, rmSync as rmSync3 } from "node:fs";
|
|
4172
4313
|
import { resolve as resolve7 } from "node:path";
|
|
4173
4314
|
async function purgeCursorAgentStoreForAgent(cfg2, agentId) {
|
|
4174
4315
|
const trimmedAgentId = agentId.trim();
|
|
4175
4316
|
if (!trimmedAgentId) return false;
|
|
4317
|
+
await flushPendingCheckpointUploads();
|
|
4176
4318
|
const store = createRemoteLocalAgentStore(cfg2);
|
|
4177
4319
|
const runIds = [];
|
|
4178
4320
|
let cursor;
|
|
@@ -4195,6 +4337,7 @@ async function purgeCursorAgentStoreForAgent(cfg2, agentId) {
|
|
|
4195
4337
|
await store.runs.delete({ filter: { agentIds: [trimmedAgentId] } });
|
|
4196
4338
|
await store.checkpoints.delete({ filter: { agentIds: [trimmedAgentId] } });
|
|
4197
4339
|
await store.agents.delete({ filter: { agentIds: [trimmedAgentId] } });
|
|
4340
|
+
clearLocalCheckpointCache(trimmedAgentId);
|
|
4198
4341
|
return true;
|
|
4199
4342
|
}
|
|
4200
4343
|
async function cleanWebIdeWorkspaceCache(taskId, workdir, cfg2) {
|
|
@@ -4224,8 +4367,8 @@ async function cleanWebIdeWorkspaceCache(taskId, workdir, cfg2) {
|
|
|
4224
4367
|
);
|
|
4225
4368
|
}
|
|
4226
4369
|
const dir = resolve7(trimmedWorkdir, ".apm", "webide", trimmedTaskId);
|
|
4227
|
-
if (
|
|
4228
|
-
|
|
4370
|
+
if (existsSync9(dir)) {
|
|
4371
|
+
rmSync3(dir, { recursive: true, force: true });
|
|
4229
4372
|
console.log(`[apm] \u5DF2\u6E05\u7406 WebIDE \u7F13\u5B58 ${dir}`);
|
|
4230
4373
|
} else {
|
|
4231
4374
|
console.log(`[apm] WebIDE \u7F13\u5B58\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7 ${dir}`);
|
|
@@ -4546,8 +4689,8 @@ async function ensureWebIdePullRequests(cfg2, taskId, workdir) {
|
|
|
4546
4689
|
}
|
|
4547
4690
|
|
|
4548
4691
|
// src/commands/sync-webide-attachments.ts
|
|
4549
|
-
import { existsSync as
|
|
4550
|
-
import { join as
|
|
4692
|
+
import { existsSync as existsSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "fs";
|
|
4693
|
+
import { join as join7 } from "path";
|
|
4551
4694
|
var MANIFEST_FILE2 = ".sync-manifest.json";
|
|
4552
4695
|
async function downloadAttachment(cfg2, attachmentId) {
|
|
4553
4696
|
const base = cfg2.baseUrl.trim().replace(/\/+$/, "");
|
|
@@ -4563,13 +4706,13 @@ async function downloadAttachment(cfg2, attachmentId) {
|
|
|
4563
4706
|
return Buffer.from(await res.arrayBuffer());
|
|
4564
4707
|
}
|
|
4565
4708
|
function loadManifest(dir) {
|
|
4566
|
-
const path3 =
|
|
4567
|
-
if (!
|
|
4709
|
+
const path3 = join7(dir, MANIFEST_FILE2);
|
|
4710
|
+
if (!existsSync10(path3)) {
|
|
4568
4711
|
return { version: 1, attachments: {} };
|
|
4569
4712
|
}
|
|
4570
4713
|
try {
|
|
4571
4714
|
const parsed = JSON.parse(
|
|
4572
|
-
|
|
4715
|
+
readFileSync8(path3, "utf8")
|
|
4573
4716
|
);
|
|
4574
4717
|
if (parsed?.version === 1 && parsed.attachments && typeof parsed.attachments === "object") {
|
|
4575
4718
|
return parsed;
|
|
@@ -4579,15 +4722,15 @@ function loadManifest(dir) {
|
|
|
4579
4722
|
return { version: 1, attachments: {} };
|
|
4580
4723
|
}
|
|
4581
4724
|
function saveManifest(dir, manifest) {
|
|
4582
|
-
|
|
4583
|
-
|
|
4725
|
+
writeFileSync7(
|
|
4726
|
+
join7(dir, MANIFEST_FILE2),
|
|
4584
4727
|
`${JSON.stringify(manifest, null, 2)}
|
|
4585
4728
|
`,
|
|
4586
4729
|
"utf8"
|
|
4587
4730
|
);
|
|
4588
4731
|
}
|
|
4589
4732
|
function isAttachmentUpToDate(entry, item, dest) {
|
|
4590
|
-
if (!entry || !
|
|
4733
|
+
if (!entry || !existsSync10(dest)) return false;
|
|
4591
4734
|
if (entry.name !== item.name) return false;
|
|
4592
4735
|
const createdAt = item.createdAt ?? "";
|
|
4593
4736
|
return entry.createdAt === createdAt;
|
|
@@ -4602,7 +4745,7 @@ async function syncAttachmentsToDirectory(cfg2, attachments, dir, logLabel) {
|
|
|
4602
4745
|
const nextManifest = { version: 1, attachments: {} };
|
|
4603
4746
|
const names = [];
|
|
4604
4747
|
for (const item of attachments) {
|
|
4605
|
-
const dest =
|
|
4748
|
+
const dest = join7(dir, item.name);
|
|
4606
4749
|
const entry = manifest.attachments[item.id];
|
|
4607
4750
|
const createdAt = item.createdAt ?? "";
|
|
4608
4751
|
names.push(item.name);
|
|
@@ -4612,7 +4755,7 @@ async function syncAttachmentsToDirectory(cfg2, attachments, dir, logLabel) {
|
|
|
4612
4755
|
continue;
|
|
4613
4756
|
}
|
|
4614
4757
|
const buffer = await downloadAttachment(cfg2, item.id);
|
|
4615
|
-
|
|
4758
|
+
writeFileSync7(dest, buffer);
|
|
4616
4759
|
nextManifest.attachments[item.id] = {
|
|
4617
4760
|
name: item.name,
|
|
4618
4761
|
createdAt
|
|
@@ -4633,9 +4776,9 @@ async function syncWebIdeAttachments(cfg2, taskId, workdir, attachments) {
|
|
|
4633
4776
|
}
|
|
4634
4777
|
|
|
4635
4778
|
// src/commands/sync-webide-design.ts
|
|
4636
|
-
import { createHash as
|
|
4637
|
-
import { existsSync as
|
|
4638
|
-
import { join as
|
|
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";
|
|
4639
4782
|
|
|
4640
4783
|
// src/opc-shared-types.ts
|
|
4641
4784
|
function webIdeDesignObjectKey(taskId, fileName) {
|
|
@@ -4653,15 +4796,15 @@ function webIdeDesignArtifactContentType(name) {
|
|
|
4653
4796
|
// src/commands/sync-webide-design.ts
|
|
4654
4797
|
var MANIFEST_FILE3 = ".sync-manifest.json";
|
|
4655
4798
|
function hashBuffer(buf) {
|
|
4656
|
-
return
|
|
4799
|
+
return createHash4("sha256").update(buf).digest("hex");
|
|
4657
4800
|
}
|
|
4658
4801
|
function loadManifest2(dir) {
|
|
4659
|
-
const path3 =
|
|
4660
|
-
if (!
|
|
4802
|
+
const path3 = join8(dir, MANIFEST_FILE3);
|
|
4803
|
+
if (!existsSync11(path3)) {
|
|
4661
4804
|
return { version: 1, files: {} };
|
|
4662
4805
|
}
|
|
4663
4806
|
try {
|
|
4664
|
-
const parsed = JSON.parse(
|
|
4807
|
+
const parsed = JSON.parse(readFileSync9(path3, "utf8"));
|
|
4665
4808
|
if (parsed?.version === 1 && parsed.files && typeof parsed.files === "object") {
|
|
4666
4809
|
return parsed;
|
|
4667
4810
|
}
|
|
@@ -4670,8 +4813,8 @@ function loadManifest2(dir) {
|
|
|
4670
4813
|
return { version: 1, files: {} };
|
|
4671
4814
|
}
|
|
4672
4815
|
function saveManifest2(dir, manifest) {
|
|
4673
|
-
|
|
4674
|
-
|
|
4816
|
+
writeFileSync8(
|
|
4817
|
+
join8(dir, MANIFEST_FILE3),
|
|
4675
4818
|
`${JSON.stringify(manifest, null, 2)}
|
|
4676
4819
|
`,
|
|
4677
4820
|
"utf8"
|
|
@@ -4699,13 +4842,13 @@ async function syncWebIdeDesign(cfg2, taskId, workdir, artifacts) {
|
|
|
4699
4842
|
for (const art of artifacts) {
|
|
4700
4843
|
const name = art.name?.trim();
|
|
4701
4844
|
if (!name || !isWebIdeDesignArtifactName(name)) continue;
|
|
4702
|
-
const localPath =
|
|
4845
|
+
const localPath = join8(dir, name);
|
|
4703
4846
|
const entry = manifest.files[name];
|
|
4704
|
-
if (entry?.contentHash === art.contentHash &&
|
|
4847
|
+
if (entry?.contentHash === art.contentHash && existsSync11(localPath)) {
|
|
4705
4848
|
continue;
|
|
4706
4849
|
}
|
|
4707
4850
|
const buf = await downloadDesignFile(cfg2, taskId, name);
|
|
4708
|
-
|
|
4851
|
+
writeFileSync8(localPath, buf);
|
|
4709
4852
|
manifest.files[name] = { contentHash: hashBuffer(buf) };
|
|
4710
4853
|
synced.push(name);
|
|
4711
4854
|
}
|
|
@@ -4714,13 +4857,13 @@ async function syncWebIdeDesign(cfg2, taskId, workdir, artifacts) {
|
|
|
4714
4857
|
}
|
|
4715
4858
|
function listLocalDesignArtifactFiles(taskId, workdir) {
|
|
4716
4859
|
const dir = webideDesignDir(taskId, workdir);
|
|
4717
|
-
if (!
|
|
4860
|
+
if (!existsSync11(dir)) return [];
|
|
4718
4861
|
const out = [];
|
|
4719
4862
|
for (const name of readdirSync5(dir)) {
|
|
4720
4863
|
if (!isWebIdeDesignArtifactName(name)) continue;
|
|
4721
|
-
const absPath =
|
|
4864
|
+
const absPath = join8(dir, name);
|
|
4722
4865
|
if (!statSync5(absPath).isFile()) continue;
|
|
4723
|
-
const buf =
|
|
4866
|
+
const buf = readFileSync9(absPath);
|
|
4724
4867
|
if (buf.length === 0) continue;
|
|
4725
4868
|
out.push({ name, absPath, contentHash: hashBuffer(buf) });
|
|
4726
4869
|
}
|
|
@@ -4825,26 +4968,36 @@ function completeActionForInbound(action) {
|
|
|
4825
4968
|
switch (action) {
|
|
4826
4969
|
case "request-assessment":
|
|
4827
4970
|
case "confirm-assumptions":
|
|
4971
|
+
case "start-assessment":
|
|
4972
|
+
case "continue-assessment":
|
|
4828
4973
|
return "complete-assessment";
|
|
4829
4974
|
case "request-design":
|
|
4830
4975
|
case "request-revise-design":
|
|
4976
|
+
case "start-design":
|
|
4831
4977
|
return "complete-design";
|
|
4832
4978
|
case "request-write-plan":
|
|
4833
4979
|
case "request-revise-plan":
|
|
4980
|
+
case "start-write-plan":
|
|
4834
4981
|
return "complete-write-plan";
|
|
4835
4982
|
case "request-develop":
|
|
4836
4983
|
case "skip-plan":
|
|
4984
|
+
case "start-develop":
|
|
4837
4985
|
return "complete-develop";
|
|
4838
4986
|
case "request-start-project":
|
|
4987
|
+
case "start-project":
|
|
4839
4988
|
return "complete-project";
|
|
4840
4989
|
case "request-execute-sql":
|
|
4990
|
+
case "start-execute-sql":
|
|
4841
4991
|
return "complete-execute-sql";
|
|
4842
4992
|
case "request-bugfix":
|
|
4993
|
+
case "start-bugfix":
|
|
4843
4994
|
return "complete-bugfix";
|
|
4844
4995
|
case "request-organize-code":
|
|
4845
4996
|
case "request-patch":
|
|
4997
|
+
case "start-organize-code":
|
|
4846
4998
|
return "complete-organize-code";
|
|
4847
4999
|
case "request-accept":
|
|
5000
|
+
case "start-accept":
|
|
4848
5001
|
return "complete-accept";
|
|
4849
5002
|
default:
|
|
4850
5003
|
return null;
|
|
@@ -4855,6 +5008,13 @@ async function webIdeRunAction(cfg2, taskId, action, params) {
|
|
|
4855
5008
|
await api.cli.webideRunAction({ taskId, action, params });
|
|
4856
5009
|
console.log(`[apm] webide runAction ok action=${action} taskId=${taskId}`);
|
|
4857
5010
|
}
|
|
5011
|
+
async function webIdeAttachContinueRun(cfg2, taskId, runId) {
|
|
5012
|
+
const api = createApmApiClient(cfg2);
|
|
5013
|
+
await api.cli.webideAttachContinueRun({ taskId, runId });
|
|
5014
|
+
console.log(
|
|
5015
|
+
`[apm] webide attachContinueRun ok runId=${runId} taskId=${taskId}`
|
|
5016
|
+
);
|
|
5017
|
+
}
|
|
4858
5018
|
async function webIdeSyncTransitionPrepEvents(cfg2, taskId, startAction, prepEvents) {
|
|
4859
5019
|
try {
|
|
4860
5020
|
const api = createApmApiClient(cfg2);
|
|
@@ -4927,8 +5087,11 @@ async function handleWebIdeInboundMessage(cfg2, msg2, signal) {
|
|
|
4927
5087
|
const messageId = msg2.messageId;
|
|
4928
5088
|
const taskId = msg2.taskId;
|
|
4929
5089
|
const branchCacheKey = taskId;
|
|
5090
|
+
const continuePayload = msg2.action === "continue" ? parseWebIdePromptPayload(msg2.content) : null;
|
|
5091
|
+
const previousAction = typeof continuePayload?.previousAction === "string" ? continuePayload.previousAction.trim() : "";
|
|
5092
|
+
const effectiveAction = msg2.action === "continue" && previousAction ? previousAction : msg2.action;
|
|
4930
5093
|
console.log(
|
|
4931
|
-
`[apm] webide-message action=${msg2.action} taskId=${taskId} messageId=${messageId}`
|
|
5094
|
+
`[apm] webide-message action=${msg2.action}${previousAction ? ` previousAction=${previousAction}` : ""} taskId=${taskId} messageId=${messageId}`
|
|
4932
5095
|
);
|
|
4933
5096
|
await updateStatus2(cfg2, messageId, "TYPING");
|
|
4934
5097
|
syncLocalTaskStatus(workdir, taskId, msg2, "TYPING");
|
|
@@ -5031,7 +5194,7 @@ async function handleWebIdeInboundMessage(cfg2, msg2, signal) {
|
|
|
5031
5194
|
eventSession.addCliStep("\u51C6\u5907\u7279\u6027\u5206\u652F", "\u5DF2\u7F13\u5B58\uFF0C\u8DF3\u8FC7", "skip");
|
|
5032
5195
|
await syncPrepLog();
|
|
5033
5196
|
}
|
|
5034
|
-
if (shouldEnsureWebIdePullRequests(
|
|
5197
|
+
if (shouldEnsureWebIdePullRequests(effectiveAction)) {
|
|
5035
5198
|
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
5036
5199
|
await runPrepStep(
|
|
5037
5200
|
"\u9A8C\u6536\u524D\u63A8\u9001",
|
|
@@ -5137,8 +5300,8 @@ async function handleWebIdeInboundMessage(cfg2, msg2, signal) {
|
|
|
5137
5300
|
"running"
|
|
5138
5301
|
);
|
|
5139
5302
|
await syncPrepLog();
|
|
5140
|
-
const startLocalServices = isStartLocalServicesAction(
|
|
5141
|
-
const designAction = isDesignAction(
|
|
5303
|
+
const startLocalServices = isStartLocalServicesAction(effectiveAction);
|
|
5304
|
+
const designAction = isDesignAction(effectiveAction);
|
|
5142
5305
|
const useNewAgent = msg2.useNewAgent === true;
|
|
5143
5306
|
const toolNames = Array.isArray(msg2.tools) ? msg2.tools.map((t) => String(t).trim()).filter(Boolean) : [];
|
|
5144
5307
|
if (useNewAgent && !startLocalServices) {
|
|
@@ -5149,7 +5312,7 @@ async function handleWebIdeInboundMessage(cfg2, msg2, signal) {
|
|
|
5149
5312
|
}
|
|
5150
5313
|
}
|
|
5151
5314
|
const savedAgentId = startLocalServices || useNewAgent ? void 0 : designAction ? loadWebIdeDesignAgentId(workdir, taskId) : loadWebIdeAgentId(workdir, taskId);
|
|
5152
|
-
const promptPayload = toolNames.includes("MysqlExecute") ? parseWebIdePromptPayload(msg2.content) : null;
|
|
5315
|
+
const promptPayload = toolNames.includes("MysqlExecute") ? continuePayload ?? parseWebIdePromptPayload(msg2.content) : null;
|
|
5153
5316
|
const sqlExecutionId = toolNames.includes("MysqlExecute") && typeof promptPayload?.executionId === "string" ? promptPayload.executionId.trim() : void 0;
|
|
5154
5317
|
if (toolNames.includes("MysqlExecute") && !sqlExecutionId) {
|
|
5155
5318
|
console.warn(
|
|
@@ -5239,6 +5402,15 @@ ${assumptionAnswersText}` : msg2.content,
|
|
|
5239
5402
|
eventSession.getCliSteps()
|
|
5240
5403
|
);
|
|
5241
5404
|
await webIdeRunAction(cfg2, taskId, startAction, { runId });
|
|
5405
|
+
} else if (msg2.action === "continue") {
|
|
5406
|
+
try {
|
|
5407
|
+
await webIdeAttachContinueRun(cfg2, taskId, runId);
|
|
5408
|
+
} catch (err) {
|
|
5409
|
+
console.warn(
|
|
5410
|
+
"[apm] attach continue run failed:",
|
|
5411
|
+
err instanceof Error ? err.message : err
|
|
5412
|
+
);
|
|
5413
|
+
}
|
|
5242
5414
|
}
|
|
5243
5415
|
}
|
|
5244
5416
|
}
|
|
@@ -5265,7 +5437,7 @@ ${assumptionAnswersText}` : msg2.content,
|
|
|
5265
5437
|
detail,
|
|
5266
5438
|
tokenUsage
|
|
5267
5439
|
);
|
|
5268
|
-
if (sqlExecutionId &&
|
|
5440
|
+
if (sqlExecutionId && effectiveAction !== "request-bugfix") {
|
|
5269
5441
|
try {
|
|
5270
5442
|
await api.cli.webideFinalizeSqlExecution({
|
|
5271
5443
|
executionId: sqlExecutionId,
|
|
@@ -5290,7 +5462,7 @@ ${assumptionAnswersText}` : msg2.content,
|
|
|
5290
5462
|
"\u5DF2\u53D6\u6D88",
|
|
5291
5463
|
tokenUsage
|
|
5292
5464
|
);
|
|
5293
|
-
if (sqlExecutionId &&
|
|
5465
|
+
if (sqlExecutionId && effectiveAction !== "request-bugfix") {
|
|
5294
5466
|
try {
|
|
5295
5467
|
await api.cli.webideFinalizeSqlExecution({
|
|
5296
5468
|
executionId: sqlExecutionId,
|
|
@@ -5317,7 +5489,7 @@ ${assumptionAnswersText}` : msg2.content,
|
|
|
5317
5489
|
id: messageId,
|
|
5318
5490
|
content: fallback
|
|
5319
5491
|
});
|
|
5320
|
-
if ((
|
|
5492
|
+
if ((effectiveAction === "write-plan" || effectiveAction === "revise-plan" || effectiveAction === "request-write-plan" || effectiveAction === "request-revise-plan" || effectiveAction === "start-write-plan") && outcome.createPlan && outcome.createPlan.trim()) {
|
|
5321
5493
|
try {
|
|
5322
5494
|
await api.cli.webideUpsertPlan({
|
|
5323
5495
|
taskId,
|
|
@@ -5325,12 +5497,12 @@ ${assumptionAnswersText}` : msg2.content,
|
|
|
5325
5497
|
});
|
|
5326
5498
|
} catch (err) {
|
|
5327
5499
|
console.warn(
|
|
5328
|
-
`[apm] ${
|
|
5500
|
+
`[apm] ${effectiveAction} \u8865\u5199\u8BA1\u5212\u5931\u8D25:`,
|
|
5329
5501
|
err instanceof Error ? err.message : err
|
|
5330
5502
|
);
|
|
5331
5503
|
}
|
|
5332
5504
|
}
|
|
5333
|
-
if (isDesignAction(
|
|
5505
|
+
if (isDesignAction(effectiveAction)) {
|
|
5334
5506
|
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
5335
5507
|
try {
|
|
5336
5508
|
const uploaded = await uploadWebIdeDesignArtifacts(
|
|
@@ -5339,7 +5511,7 @@ ${assumptionAnswersText}` : msg2.content,
|
|
|
5339
5511
|
workdir
|
|
5340
5512
|
);
|
|
5341
5513
|
console.log(
|
|
5342
|
-
`[apm] webide \u8BBE\u8BA1\u4EA7\u7269\u4E0A\u4F20 action=${
|
|
5514
|
+
`[apm] webide \u8BBE\u8BA1\u4EA7\u7269\u4E0A\u4F20 action=${effectiveAction} uploaded=${uploaded.uploaded} skipped=${uploaded.skipped} files=${uploaded.artifacts.map((a) => a.name).join(",")}`
|
|
5343
5515
|
);
|
|
5344
5516
|
} catch (err) {
|
|
5345
5517
|
const detail = err instanceof Error ? err.message : String(err);
|
|
@@ -5354,27 +5526,27 @@ ${assumptionAnswersText}` : msg2.content,
|
|
|
5354
5526
|
return;
|
|
5355
5527
|
}
|
|
5356
5528
|
}
|
|
5357
|
-
if (shouldCommitAfterWebIdeMessage(
|
|
5529
|
+
if (shouldCommitAfterWebIdeMessage(effectiveAction)) {
|
|
5358
5530
|
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
5359
5531
|
const committed = await commitWorkspaceReposIfDirty(
|
|
5360
5532
|
workdir,
|
|
5361
|
-
`chore(webide): sync after ${
|
|
5533
|
+
`chore(webide): sync after ${effectiveAction} (${taskId})`
|
|
5362
5534
|
);
|
|
5363
5535
|
console.log(
|
|
5364
|
-
`[apm] webide \u515C\u5E95 commit action=${
|
|
5536
|
+
`[apm] webide \u515C\u5E95 commit action=${effectiveAction} repos=${committed}`
|
|
5365
5537
|
);
|
|
5366
5538
|
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
5367
5539
|
const pushed = await pushWorkspaceRepos(workdir);
|
|
5368
5540
|
console.log(
|
|
5369
|
-
`[apm] webide \u81EA\u52A8 push action=${
|
|
5541
|
+
`[apm] webide \u81EA\u52A8 push action=${effectiveAction} repos=${pushed}`
|
|
5370
5542
|
);
|
|
5371
5543
|
}
|
|
5372
|
-
if (shouldEnsureWebIdePullRequestsAfterAgent(
|
|
5544
|
+
if (shouldEnsureWebIdePullRequestsAfterAgent(effectiveAction)) {
|
|
5373
5545
|
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
5374
|
-
if (!shouldCommitAfterWebIdeMessage(
|
|
5546
|
+
if (!shouldCommitAfterWebIdeMessage(effectiveAction)) {
|
|
5375
5547
|
const pushed = await pushWorkspaceRepos(workdir);
|
|
5376
5548
|
console.log(
|
|
5377
|
-
`[apm] webide create-pr \u524D push action=${
|
|
5549
|
+
`[apm] webide create-pr \u524D push action=${effectiveAction} repos=${pushed}`
|
|
5378
5550
|
);
|
|
5379
5551
|
}
|
|
5380
5552
|
const prResult = await ensureWebIdePullRequests(cfg2, taskId, workdir);
|
|
@@ -5428,20 +5600,20 @@ ${assumptionAnswersText}` : msg2.content,
|
|
|
5428
5600
|
null,
|
|
5429
5601
|
tokenUsage
|
|
5430
5602
|
);
|
|
5431
|
-
const completeAction = completeActionForInbound(
|
|
5603
|
+
const completeAction = completeActionForInbound(effectiveAction);
|
|
5432
5604
|
if (completeAction && !pausedForAssumptions) {
|
|
5433
5605
|
await webIdeRunAction(cfg2, taskId, completeAction);
|
|
5434
5606
|
} else if (pausedForAssumptions) {
|
|
5435
5607
|
console.log(
|
|
5436
|
-
`[apm] \u672C\u8F6E\u505C\u5728\u5F85\u786E\u8BA4\u5047\u8BBE\uFF0C\u8DF3\u8FC7 complete action=${
|
|
5608
|
+
`[apm] \u672C\u8F6E\u505C\u5728\u5F85\u786E\u8BA4\u5047\u8BBE\uFF0C\u8DF3\u8FC7 complete action=${effectiveAction} taskId=${taskId}`
|
|
5437
5609
|
);
|
|
5438
5610
|
}
|
|
5439
5611
|
await updateStatus2(cfg2, messageId, "SUCCESS");
|
|
5440
5612
|
syncLocalTaskStatus(workdir, taskId, msg2, "SUCCESS");
|
|
5441
5613
|
console.log(
|
|
5442
|
-
`[apm] webide-message \u5B8C\u6210 action=${msg2.action} messageId=${messageId} agentId=${outcome.agentId}`
|
|
5614
|
+
`[apm] webide-message \u5B8C\u6210 action=${msg2.action}${previousAction ? ` previousAction=${previousAction}` : ""} messageId=${messageId} agentId=${outcome.agentId}`
|
|
5443
5615
|
);
|
|
5444
|
-
if (
|
|
5616
|
+
if (effectiveAction === "request-accept" || effectiveAction === "start-accept") {
|
|
5445
5617
|
try {
|
|
5446
5618
|
await cleanWebIdeWorkspaceCache(taskId, workdir, cfg2);
|
|
5447
5619
|
} catch (err) {
|
|
@@ -5468,7 +5640,7 @@ ${assumptionAnswersText}` : msg2.content,
|
|
|
5468
5640
|
statusErr instanceof Error ? statusErr.message : statusErr
|
|
5469
5641
|
);
|
|
5470
5642
|
}
|
|
5471
|
-
const completeAction = completeActionForInbound(
|
|
5643
|
+
const completeAction = completeActionForInbound(effectiveAction);
|
|
5472
5644
|
if (completeAction === "complete-assessment" && !pausedForAssumptions) {
|
|
5473
5645
|
try {
|
|
5474
5646
|
await webIdeRunAction(cfg2, taskId, completeAction, { force: true });
|