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