ai-project-manage-cli 7.1.31 → 7.1.32
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/README.md +0 -2
- package/dist/index.js +178 -69
- package/dist/webide-message-worker.js +109 -28
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -58,5 +58,3 @@ apm daemon start -f
|
|
|
58
58
|
使用全局 PM2(未安装时会自动执行 `npm install -g pm2`);同一时刻仅允许一个 connect。启动时会自动检测 CLI 更新并刷新守护配置。
|
|
59
59
|
|
|
60
60
|
`apm pull` 会自动将平台登记的**项目文档**同步到 `.apm/project/<项目ID>/`(含 `manifest.json`)。Agent 修改该目录下文件后,`apm connect` 处理完消息会自动推回平台。
|
|
61
|
-
|
|
62
|
-
详见仓库根目录 [docs/CLI.md](../../docs/CLI.md)。
|
package/dist/index.js
CHANGED
|
@@ -216,10 +216,6 @@ var init_request_config = __esm({
|
|
|
216
216
|
method: "PUT",
|
|
217
217
|
path: "/cli/webide/terminals/meta"
|
|
218
218
|
}),
|
|
219
|
-
acquireSteelBrowser: defineEndpoint({
|
|
220
|
-
method: "POST",
|
|
221
|
-
path: "/cli/steel-browser/acquire"
|
|
222
|
-
}),
|
|
223
219
|
branchBaseline: defineEndpoint({
|
|
224
220
|
method: "GET",
|
|
225
221
|
path: "/cli/tasks/branch-baseline"
|
|
@@ -444,14 +440,14 @@ var init_minio = __esm({
|
|
|
444
440
|
async deleteObjectsByPrefix(bucket, prefix) {
|
|
445
441
|
const objectsStream = this.inner.listObjectsV2(bucket, prefix, true);
|
|
446
442
|
const keys = [];
|
|
447
|
-
await new Promise((
|
|
443
|
+
await new Promise((resolve9, reject) => {
|
|
448
444
|
objectsStream.on("data", (obj) => {
|
|
449
445
|
if (obj.name) {
|
|
450
446
|
keys.push(obj.name);
|
|
451
447
|
}
|
|
452
448
|
});
|
|
453
449
|
objectsStream.on("error", reject);
|
|
454
|
-
objectsStream.on("end",
|
|
450
|
+
objectsStream.on("end", resolve9);
|
|
455
451
|
});
|
|
456
452
|
const chunkSize = 500;
|
|
457
453
|
for (let i = 0; i < keys.length; i += chunkSize) {
|
|
@@ -4608,7 +4604,8 @@ function buildConnectPm2Ecosystem(options) {
|
|
|
4608
4604
|
max_restarts: 10,
|
|
4609
4605
|
restart_delay: 3e3,
|
|
4610
4606
|
exp_backoff_restart_delay: 1e3,
|
|
4611
|
-
|
|
4607
|
+
// WebIDE Worker 与主进程同 RSS;8G 机约可到 ~6G,避免把整机打满
|
|
4608
|
+
max_memory_restart: "6G",
|
|
4612
4609
|
kill_timeout: 5e3,
|
|
4613
4610
|
shutdown_with_message: true,
|
|
4614
4611
|
instances: 1,
|
|
@@ -5716,7 +5713,7 @@ function buildSftpConnectOptions(settings) {
|
|
|
5716
5713
|
};
|
|
5717
5714
|
}
|
|
5718
5715
|
async function sleep(ms) {
|
|
5719
|
-
await new Promise((
|
|
5716
|
+
await new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
5720
5717
|
}
|
|
5721
5718
|
async function uploadZipWithRetry(settings, localZip, remoteZipPath) {
|
|
5722
5719
|
let lastError;
|
|
@@ -5760,7 +5757,7 @@ async function ensureRemoteDir(sftp, dir) {
|
|
|
5760
5757
|
}
|
|
5761
5758
|
}
|
|
5762
5759
|
function execCommand(client, command) {
|
|
5763
|
-
return new Promise((
|
|
5760
|
+
return new Promise((resolve9, reject) => {
|
|
5764
5761
|
client.exec(command, (err, stream) => {
|
|
5765
5762
|
if (err) return reject(err);
|
|
5766
5763
|
let stdout = "";
|
|
@@ -5770,7 +5767,7 @@ function execCommand(client, command) {
|
|
|
5770
5767
|
reject(new Error(`\u8FDC\u7A0B\u547D\u4EE4\u5931\u8D25 (${code}): ${stderr || stdout}`));
|
|
5771
5768
|
return;
|
|
5772
5769
|
}
|
|
5773
|
-
|
|
5770
|
+
resolve9(stdout);
|
|
5774
5771
|
}).on("data", (data) => {
|
|
5775
5772
|
stdout += data.toString();
|
|
5776
5773
|
});
|
|
@@ -6245,8 +6242,8 @@ function springbootOutputIndicatesSuccess(action, combined) {
|
|
|
6245
6242
|
async function connectSsh(config) {
|
|
6246
6243
|
const client = new Client2();
|
|
6247
6244
|
log(`\u8FDE\u63A5\u670D\u52A1\u5668 ${config.username}@${config.host}:${config.port}`);
|
|
6248
|
-
await new Promise((
|
|
6249
|
-
client.on("ready", () =>
|
|
6245
|
+
await new Promise((resolve9, reject) => {
|
|
6246
|
+
client.on("ready", () => resolve9()).on("error", (err) => reject(err)).connect({
|
|
6250
6247
|
host: config.host,
|
|
6251
6248
|
port: config.port,
|
|
6252
6249
|
username: config.username,
|
|
@@ -6314,7 +6311,7 @@ async function runRemoteCommand(client, command, options) {
|
|
|
6314
6311
|
const check = options?.check ?? true;
|
|
6315
6312
|
const stream = options?.stream ?? false;
|
|
6316
6313
|
const label = options?.label ?? "\u8FDC\u7A0B\u547D\u4EE4";
|
|
6317
|
-
return new Promise((
|
|
6314
|
+
return new Promise((resolve9, reject) => {
|
|
6318
6315
|
client.exec(command, (err, execStream) => {
|
|
6319
6316
|
if (err) {
|
|
6320
6317
|
reject(err);
|
|
@@ -6344,7 +6341,7 @@ ${errText}`.trim();
|
|
|
6344
6341
|
\u8F93\u51FA: ${combined}` : "")
|
|
6345
6342
|
);
|
|
6346
6343
|
}
|
|
6347
|
-
|
|
6344
|
+
resolve9({ exitCode: code, out: out.trim(), err: errText.trim() });
|
|
6348
6345
|
});
|
|
6349
6346
|
});
|
|
6350
6347
|
});
|
|
@@ -7245,16 +7242,101 @@ function cleanSessionWorkspaceCache(sessionId, workdir) {
|
|
|
7245
7242
|
}
|
|
7246
7243
|
|
|
7247
7244
|
// src/commands/clean-webide-cache.ts
|
|
7248
|
-
import { existsSync as
|
|
7249
|
-
import { resolve as
|
|
7250
|
-
|
|
7245
|
+
import { existsSync as existsSync24, rmSync as rmSync5 } from "node:fs";
|
|
7246
|
+
import { resolve as resolve7 } from "node:path";
|
|
7247
|
+
import { JsonlLocalAgentStore } from "@cursor/sdk";
|
|
7248
|
+
|
|
7249
|
+
// src/commands/connect/webide-agent-registry.ts
|
|
7250
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync10, readFileSync as readFileSync17, writeFileSync as writeFileSync15 } from "node:fs";
|
|
7251
|
+
import { dirname as dirname7, resolve as resolve6 } from "node:path";
|
|
7252
|
+
function registryPath(workdir, taskId) {
|
|
7253
|
+
return resolve6(workdir, ".apm", "webide", taskId, "cursor-agent.json");
|
|
7254
|
+
}
|
|
7255
|
+
function readRegistry(path19) {
|
|
7256
|
+
if (!existsSync23(path19)) {
|
|
7257
|
+
return {};
|
|
7258
|
+
}
|
|
7259
|
+
try {
|
|
7260
|
+
const parsed = JSON.parse(readFileSync17(path19, "utf8"));
|
|
7261
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
7262
|
+
const agentId = parsed.agentId;
|
|
7263
|
+
if (typeof agentId === "string" && agentId.trim()) {
|
|
7264
|
+
return { agentId: agentId.trim() };
|
|
7265
|
+
}
|
|
7266
|
+
}
|
|
7267
|
+
} catch {
|
|
7268
|
+
}
|
|
7269
|
+
return {};
|
|
7270
|
+
}
|
|
7271
|
+
function loadWebIdeAgentId(workdir, taskId) {
|
|
7272
|
+
return readRegistry(registryPath(workdir, taskId)).agentId;
|
|
7273
|
+
}
|
|
7274
|
+
|
|
7275
|
+
// src/commands/clean-webide-cache.ts
|
|
7276
|
+
function cursorAgentStoreDir(workdir) {
|
|
7277
|
+
return resolve7(workdir, ".apm", "cursor-agent-store");
|
|
7278
|
+
}
|
|
7279
|
+
async function purgeCursorAgentStoreForAgent(workdir, agentId) {
|
|
7280
|
+
const trimmedAgentId = agentId.trim();
|
|
7281
|
+
const trimmedWorkdir = workdir.trim();
|
|
7282
|
+
if (!trimmedAgentId || !trimmedWorkdir) return false;
|
|
7283
|
+
const rootDir = cursorAgentStoreDir(trimmedWorkdir);
|
|
7284
|
+
if (!existsSync24(rootDir)) return false;
|
|
7285
|
+
const store = new JsonlLocalAgentStore(rootDir);
|
|
7286
|
+
const runIds = [];
|
|
7287
|
+
let cursor;
|
|
7288
|
+
do {
|
|
7289
|
+
const page = await store.runs.list({
|
|
7290
|
+
filter: {
|
|
7291
|
+
agentIds: [trimmedAgentId],
|
|
7292
|
+
...cursor ? { cursor } : {},
|
|
7293
|
+
limit: 200
|
|
7294
|
+
}
|
|
7295
|
+
});
|
|
7296
|
+
for (const run of page.items) {
|
|
7297
|
+
runIds.push(run.runId);
|
|
7298
|
+
}
|
|
7299
|
+
cursor = page.nextCursor;
|
|
7300
|
+
} while (cursor);
|
|
7301
|
+
if (runIds.length > 0) {
|
|
7302
|
+
await store.runEvents.delete({ filter: { runIds } });
|
|
7303
|
+
}
|
|
7304
|
+
await store.runs.delete({ filter: { agentIds: [trimmedAgentId] } });
|
|
7305
|
+
await store.checkpoints.delete({ filter: { agentIds: [trimmedAgentId] } });
|
|
7306
|
+
await store.agents.delete({ filter: { agentIds: [trimmedAgentId] } });
|
|
7307
|
+
return true;
|
|
7308
|
+
}
|
|
7309
|
+
async function cleanWebIdeWorkspaceCache(taskId, workdir) {
|
|
7251
7310
|
const trimmedTaskId = taskId.trim();
|
|
7252
7311
|
const trimmedWorkdir = workdir.trim();
|
|
7253
7312
|
if (!trimmedTaskId || !trimmedWorkdir) {
|
|
7254
7313
|
return;
|
|
7255
7314
|
}
|
|
7256
|
-
const
|
|
7257
|
-
if (
|
|
7315
|
+
const agentId = loadWebIdeAgentId(trimmedWorkdir, trimmedTaskId);
|
|
7316
|
+
if (agentId) {
|
|
7317
|
+
try {
|
|
7318
|
+
const purged = await purgeCursorAgentStoreForAgent(
|
|
7319
|
+
trimmedWorkdir,
|
|
7320
|
+
agentId
|
|
7321
|
+
);
|
|
7322
|
+
if (purged) {
|
|
7323
|
+
console.log(
|
|
7324
|
+
`[apm] \u5DF2\u6E05\u7406 Cursor agent store agentId=${agentId} taskId=${trimmedTaskId}`
|
|
7325
|
+
);
|
|
7326
|
+
}
|
|
7327
|
+
} catch (err) {
|
|
7328
|
+
console.warn(
|
|
7329
|
+
`[apm] \u6E05\u7406 Cursor agent store \u5931\u8D25 agentId=${agentId}:`,
|
|
7330
|
+
err instanceof Error ? err.message : err
|
|
7331
|
+
);
|
|
7332
|
+
}
|
|
7333
|
+
} else {
|
|
7334
|
+
console.log(
|
|
7335
|
+
`[apm] \u65E0 WebIDE agentId\uFF0C\u8DF3\u8FC7 cursor-agent-store taskId=${trimmedTaskId}`
|
|
7336
|
+
);
|
|
7337
|
+
}
|
|
7338
|
+
const dir = resolve7(trimmedWorkdir, ".apm", "webide", trimmedTaskId);
|
|
7339
|
+
if (existsSync24(dir)) {
|
|
7258
7340
|
rmSync5(dir, { recursive: true, force: true });
|
|
7259
7341
|
console.log(`[apm] \u5DF2\u6E05\u7406 WebIDE \u7F13\u5B58 ${dir}`);
|
|
7260
7342
|
} else {
|
|
@@ -7636,17 +7718,17 @@ ${JSON.stringify(event, null, 2)}
|
|
|
7636
7718
|
}
|
|
7637
7719
|
|
|
7638
7720
|
// src/commands/connect/agent-session-registry.ts
|
|
7639
|
-
import { existsSync as
|
|
7640
|
-
import { dirname as
|
|
7641
|
-
function
|
|
7642
|
-
return
|
|
7721
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync11, readFileSync as readFileSync18, writeFileSync as writeFileSync16 } from "node:fs";
|
|
7722
|
+
import { dirname as dirname8, resolve as resolve8 } from "node:path";
|
|
7723
|
+
function registryPath2(workdir, sessionId) {
|
|
7724
|
+
return resolve8(workdir, ".apm", "sessions", sessionId, "cursor-agents.json");
|
|
7643
7725
|
}
|
|
7644
|
-
function
|
|
7645
|
-
if (!
|
|
7726
|
+
function readRegistry2(path19) {
|
|
7727
|
+
if (!existsSync25(path19)) {
|
|
7646
7728
|
return {};
|
|
7647
7729
|
}
|
|
7648
7730
|
try {
|
|
7649
|
-
const parsed = JSON.parse(
|
|
7731
|
+
const parsed = JSON.parse(readFileSync18(path19, "utf8"));
|
|
7650
7732
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
7651
7733
|
const result = {};
|
|
7652
7734
|
for (const [key, value] of Object.entries(
|
|
@@ -7663,23 +7745,23 @@ function readRegistry(path19) {
|
|
|
7663
7745
|
return {};
|
|
7664
7746
|
}
|
|
7665
7747
|
function writeRegistry(path19, registry) {
|
|
7666
|
-
|
|
7667
|
-
|
|
7748
|
+
mkdirSync11(dirname8(path19), { recursive: true });
|
|
7749
|
+
writeFileSync16(path19, `${JSON.stringify(registry, null, 2)}
|
|
7668
7750
|
`, "utf8");
|
|
7669
7751
|
}
|
|
7670
7752
|
function loadSessionAgentId(workdir, sessionId, user) {
|
|
7671
|
-
const registry =
|
|
7753
|
+
const registry = readRegistry2(registryPath2(workdir, sessionId));
|
|
7672
7754
|
return registry[user];
|
|
7673
7755
|
}
|
|
7674
7756
|
function saveSessionAgentId(workdir, sessionId, user, agentId) {
|
|
7675
|
-
const path19 =
|
|
7676
|
-
const registry =
|
|
7757
|
+
const path19 = registryPath2(workdir, sessionId);
|
|
7758
|
+
const registry = readRegistry2(path19);
|
|
7677
7759
|
registry[user] = agentId;
|
|
7678
7760
|
writeRegistry(path19, registry);
|
|
7679
7761
|
}
|
|
7680
7762
|
function clearSessionAgentId(workdir, sessionId, user) {
|
|
7681
|
-
const path19 =
|
|
7682
|
-
const registry =
|
|
7763
|
+
const path19 = registryPath2(workdir, sessionId);
|
|
7764
|
+
const registry = readRegistry2(path19);
|
|
7683
7765
|
if (!(user in registry)) {
|
|
7684
7766
|
return;
|
|
7685
7767
|
}
|
|
@@ -8267,13 +8349,13 @@ ${WORKSPACE_BOUNDARY_HINT}`;
|
|
|
8267
8349
|
}
|
|
8268
8350
|
|
|
8269
8351
|
// src/commands/connect/local-agent-store.ts
|
|
8270
|
-
import { mkdirSync as
|
|
8352
|
+
import { mkdirSync as mkdirSync12 } from "node:fs";
|
|
8271
8353
|
import { join as join19 } from "node:path";
|
|
8272
|
-
import { JsonlLocalAgentStore } from "@cursor/sdk";
|
|
8354
|
+
import { JsonlLocalAgentStore as JsonlLocalAgentStore2 } from "@cursor/sdk";
|
|
8273
8355
|
function createWorkspaceLocalAgentStore(workdir) {
|
|
8274
8356
|
const rootDir = join19(workdir, ".apm", "cursor-agent-store");
|
|
8275
|
-
|
|
8276
|
-
return new
|
|
8357
|
+
mkdirSync12(rootDir, { recursive: true });
|
|
8358
|
+
return new JsonlLocalAgentStore2(rootDir);
|
|
8277
8359
|
}
|
|
8278
8360
|
|
|
8279
8361
|
// src/commands/connect/cursor-agent.ts
|
|
@@ -8553,7 +8635,7 @@ async function ensureMessageHasReply(cfg, sessionId, messageId, fallback) {
|
|
|
8553
8635
|
}
|
|
8554
8636
|
|
|
8555
8637
|
// src/commands/connect/cli-version-sync.ts
|
|
8556
|
-
import { existsSync as
|
|
8638
|
+
import { existsSync as existsSync26, readFileSync as readFileSync19, writeFileSync as writeFileSync17 } from "fs";
|
|
8557
8639
|
import { join as join20 } from "path";
|
|
8558
8640
|
var CLI_VERSION_FILE = ".cli-version.json";
|
|
8559
8641
|
function manifestPath2(apmDir) {
|
|
@@ -8561,12 +8643,12 @@ function manifestPath2(apmDir) {
|
|
|
8561
8643
|
}
|
|
8562
8644
|
function loadManifest4(apmDir) {
|
|
8563
8645
|
const path19 = toFsPath(manifestPath2(apmDir));
|
|
8564
|
-
if (!
|
|
8646
|
+
if (!existsSync26(path19)) {
|
|
8565
8647
|
return null;
|
|
8566
8648
|
}
|
|
8567
8649
|
try {
|
|
8568
8650
|
const parsed = JSON.parse(
|
|
8569
|
-
|
|
8651
|
+
readFileSync19(path19, "utf8")
|
|
8570
8652
|
);
|
|
8571
8653
|
if (parsed?.version === 1 && typeof parsed.cliVersion === "string" && parsed.cliVersion.trim()) {
|
|
8572
8654
|
return parsed;
|
|
@@ -8577,7 +8659,7 @@ function loadManifest4(apmDir) {
|
|
|
8577
8659
|
}
|
|
8578
8660
|
function saveManifest4(apmDir, cliVersion) {
|
|
8579
8661
|
const manifest = { version: 1, cliVersion };
|
|
8580
|
-
|
|
8662
|
+
writeFileSync17(
|
|
8581
8663
|
toFsPath(manifestPath2(apmDir)),
|
|
8582
8664
|
`${JSON.stringify(manifest, null, 2)}
|
|
8583
8665
|
`,
|
|
@@ -8631,7 +8713,7 @@ function createRunSlotPool(maxConcurrent = DEFAULT_MAX_CONCURRENT, options = {})
|
|
|
8631
8713
|
);
|
|
8632
8714
|
}
|
|
8633
8715
|
const queuedAt = Date.now();
|
|
8634
|
-
return new Promise((
|
|
8716
|
+
return new Promise((resolve9) => {
|
|
8635
8717
|
waiters.push(() => {
|
|
8636
8718
|
active += 1;
|
|
8637
8719
|
const waitedMs = Date.now() - queuedAt;
|
|
@@ -8642,7 +8724,7 @@ function createRunSlotPool(maxConcurrent = DEFAULT_MAX_CONCURRENT, options = {})
|
|
|
8642
8724
|
)}s\uFF0C\u5F53\u524D\u5360\u7528 ${active}/${maxConcurrent}`
|
|
8643
8725
|
);
|
|
8644
8726
|
}
|
|
8645
|
-
|
|
8727
|
+
resolve9();
|
|
8646
8728
|
});
|
|
8647
8729
|
});
|
|
8648
8730
|
};
|
|
@@ -8662,21 +8744,46 @@ function createRunSlotPool(maxConcurrent = DEFAULT_MAX_CONCURRENT, options = {})
|
|
|
8662
8744
|
// src/commands/connect/webide-worker-pool.ts
|
|
8663
8745
|
init_webide_terminal_registry();
|
|
8664
8746
|
import { Worker } from "node:worker_threads";
|
|
8747
|
+
import { totalmem } from "node:os";
|
|
8665
8748
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
8666
|
-
import { dirname as
|
|
8749
|
+
import { dirname as dirname9, join as join21 } from "node:path";
|
|
8667
8750
|
var workerFile = join21(
|
|
8668
|
-
|
|
8751
|
+
dirname9(fileURLToPath3(import.meta.url)),
|
|
8669
8752
|
"webide-message-worker.js"
|
|
8670
8753
|
);
|
|
8754
|
+
var SYSTEM_RESERVE_MB = 3072;
|
|
8755
|
+
var MIN_WEBIDE_WORKER_HEAP_MB = 1536;
|
|
8756
|
+
var MAX_WEBIDE_WORKER_HEAP_MB = 8192;
|
|
8757
|
+
function defaultWebIdeWorkerHeapMb(totalMemoryBytes = totalmem()) {
|
|
8758
|
+
const totalMb = Math.floor(totalMemoryBytes / (1024 * 1024));
|
|
8759
|
+
return Math.min(
|
|
8760
|
+
MAX_WEBIDE_WORKER_HEAP_MB,
|
|
8761
|
+
Math.max(MIN_WEBIDE_WORKER_HEAP_MB, totalMb - SYSTEM_RESERVE_MB)
|
|
8762
|
+
);
|
|
8763
|
+
}
|
|
8764
|
+
function resolveWebIdeWorkerHeapMb(env = process.env, totalMemoryBytes = totalmem()) {
|
|
8765
|
+
const fallback = defaultWebIdeWorkerHeapMb(totalMemoryBytes);
|
|
8766
|
+
const raw = env.APM_WEBIDE_WORKER_HEAP_MB?.trim();
|
|
8767
|
+
if (!raw) return fallback;
|
|
8768
|
+
const n = Number.parseInt(raw, 10);
|
|
8769
|
+
if (!Number.isFinite(n)) return fallback;
|
|
8770
|
+
return Math.min(16384, Math.max(MIN_WEBIDE_WORKER_HEAP_MB, n));
|
|
8771
|
+
}
|
|
8671
8772
|
function spawnWebIdeMessageWorker(cfg, msg) {
|
|
8773
|
+
const maxOldGenerationSizeMb = resolveWebIdeWorkerHeapMb();
|
|
8672
8774
|
const worker = new Worker(workerFile, {
|
|
8673
|
-
workerData: { cfg, msg }
|
|
8775
|
+
workerData: { cfg, msg },
|
|
8776
|
+
// worker_threads 不支持 execArgv 里的 --max-old-space-size,必须用 resourceLimits
|
|
8777
|
+
resourceLimits: { maxOldGenerationSizeMb }
|
|
8674
8778
|
});
|
|
8779
|
+
console.log(
|
|
8780
|
+
`[apm] webide worker spawn messageId=${msg.messageId} heapMb=${maxOldGenerationSizeMb}`
|
|
8781
|
+
);
|
|
8675
8782
|
const registry = getWebIdeTerminalRegistry(cfg);
|
|
8676
8783
|
let settled = false;
|
|
8677
8784
|
let resolveDone;
|
|
8678
|
-
const done = new Promise((
|
|
8679
|
-
resolveDone =
|
|
8785
|
+
const done = new Promise((resolve9) => {
|
|
8786
|
+
resolveDone = resolve9;
|
|
8680
8787
|
});
|
|
8681
8788
|
const failIfStillQueued = async (reason) => {
|
|
8682
8789
|
if (settled) return;
|
|
@@ -8764,10 +8871,12 @@ function spawnWebIdeMessageWorker(cfg, msg) {
|
|
|
8764
8871
|
}
|
|
8765
8872
|
});
|
|
8766
8873
|
worker.on("error", (err) => {
|
|
8874
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
8767
8875
|
console.error("[apm] webide worker crashed:", err);
|
|
8768
|
-
|
|
8769
|
-
|
|
8770
|
-
|
|
8876
|
+
const oomHint = /memory limit|heap out of memory/i.test(detail) ? `\uFF08\u5F53\u524D\u5806\u4E0A\u9650 ${maxOldGenerationSizeMb}MB\uFF1B8G \u53CA\u4EE5\u4E0B\u673A\u5668\u8C03\u9AD8 APM_WEBIDE_WORKER_HEAP_MB \u6613\u89E6\u53D1\u6574\u673A OOM\uFF0C\u5EFA\u8BAE\u52A0\u5185\u5B58/swap \u6216\u7F29\u77ED\u5355\u6B21\u4EFB\u52A1\uFF09` : "";
|
|
8877
|
+
void failIfStillQueued(`WebIDE worker \u5D29\u6E83: ${detail}${oomHint}`).finally(
|
|
8878
|
+
() => resolveDone()
|
|
8879
|
+
);
|
|
8771
8880
|
});
|
|
8772
8881
|
worker.on("exit", (code) => {
|
|
8773
8882
|
if (!settled && code !== 0) {
|
|
@@ -8948,11 +9057,11 @@ async function handleInboundMessage(cfg, msg, signal, ctx) {
|
|
|
8948
9057
|
}
|
|
8949
9058
|
function interruptibleSleep(ms, signal) {
|
|
8950
9059
|
if (signal.aborted) return Promise.resolve();
|
|
8951
|
-
return new Promise((
|
|
8952
|
-
const timer = setTimeout(
|
|
9060
|
+
return new Promise((resolve9) => {
|
|
9061
|
+
const timer = setTimeout(resolve9, ms);
|
|
8953
9062
|
const onAbort = () => {
|
|
8954
9063
|
clearTimeout(timer);
|
|
8955
|
-
|
|
9064
|
+
resolve9();
|
|
8956
9065
|
};
|
|
8957
9066
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
8958
9067
|
});
|
|
@@ -9053,7 +9162,7 @@ function attachWsHandlers(ws, ctx, onOpen) {
|
|
|
9053
9162
|
msg2.taskId,
|
|
9054
9163
|
"cache-cleanup"
|
|
9055
9164
|
);
|
|
9056
|
-
cleanWebIdeWorkspaceCache(msg2.taskId, workdir);
|
|
9165
|
+
await cleanWebIdeWorkspaceCache(msg2.taskId, workdir);
|
|
9057
9166
|
})();
|
|
9058
9167
|
activeTasks.add(task2);
|
|
9059
9168
|
void task2.finally(() => {
|
|
@@ -9182,7 +9291,7 @@ function attachWsHandlers(ws, ctx, onOpen) {
|
|
|
9182
9291
|
});
|
|
9183
9292
|
}
|
|
9184
9293
|
function connectOnce(url, ctx, connectionAbort, onConnected) {
|
|
9185
|
-
return new Promise((
|
|
9294
|
+
return new Promise((resolve9, reject) => {
|
|
9186
9295
|
const ws = new WebSocket(url);
|
|
9187
9296
|
let stopHeartbeat;
|
|
9188
9297
|
let settled = false;
|
|
@@ -9211,7 +9320,7 @@ function connectOnce(url, ctx, connectionAbort, onConnected) {
|
|
|
9211
9320
|
finish(() => reject(new Error("shutdown")));
|
|
9212
9321
|
return;
|
|
9213
9322
|
}
|
|
9214
|
-
finish(
|
|
9323
|
+
finish(resolve9);
|
|
9215
9324
|
});
|
|
9216
9325
|
ws.on("error", (err) => {
|
|
9217
9326
|
console.error("[apm] WebSocket \u9519\u8BEF:", err.message);
|
|
@@ -9706,7 +9815,7 @@ import path15 from "node:path";
|
|
|
9706
9815
|
import Docker from "dockerode";
|
|
9707
9816
|
|
|
9708
9817
|
// src/commands/deploy/internal/backend-deploy/dockerode-client/connection-options.ts
|
|
9709
|
-
import { existsSync as
|
|
9818
|
+
import { existsSync as existsSync27, readFileSync as readFileSync20 } from "node:fs";
|
|
9710
9819
|
import path12 from "node:path";
|
|
9711
9820
|
function asOptionalTlsBuffer(value) {
|
|
9712
9821
|
if (typeof value !== "string") {
|
|
@@ -9718,8 +9827,8 @@ function asOptionalTlsBuffer(value) {
|
|
|
9718
9827
|
if (normalized === "") {
|
|
9719
9828
|
return void 0;
|
|
9720
9829
|
}
|
|
9721
|
-
if (
|
|
9722
|
-
return
|
|
9830
|
+
if (existsSync27(normalized)) {
|
|
9831
|
+
return readFileSync20(normalized);
|
|
9723
9832
|
}
|
|
9724
9833
|
const looksLikePath = /[\\/]/.test(normalized) || normalized.endsWith(".pem");
|
|
9725
9834
|
if (looksLikePath) {
|
|
@@ -9844,17 +9953,17 @@ var DockerodeClient = class {
|
|
|
9844
9953
|
await this.client.getImage(image).remove({ force: true });
|
|
9845
9954
|
}
|
|
9846
9955
|
async pullImage(image, auth) {
|
|
9847
|
-
const stream = await new Promise((
|
|
9956
|
+
const stream = await new Promise((resolve9, reject) => {
|
|
9848
9957
|
const pullOptions = auth ? { authconfig: auth } : void 0;
|
|
9849
9958
|
this.client.pull(image, pullOptions, (err, output) => {
|
|
9850
9959
|
if (err || !output) {
|
|
9851
9960
|
reject(err ?? new Error("docker pull \u8FD4\u56DE\u7A7A\u8F93\u51FA"));
|
|
9852
9961
|
return;
|
|
9853
9962
|
}
|
|
9854
|
-
|
|
9963
|
+
resolve9(output);
|
|
9855
9964
|
});
|
|
9856
9965
|
});
|
|
9857
|
-
await new Promise((
|
|
9966
|
+
await new Promise((resolve9, reject) => {
|
|
9858
9967
|
this.client.modem.followProgress(
|
|
9859
9968
|
stream,
|
|
9860
9969
|
(err) => {
|
|
@@ -9862,7 +9971,7 @@ var DockerodeClient = class {
|
|
|
9862
9971
|
reject(err);
|
|
9863
9972
|
return;
|
|
9864
9973
|
}
|
|
9865
|
-
|
|
9974
|
+
resolve9();
|
|
9866
9975
|
},
|
|
9867
9976
|
() => void 0
|
|
9868
9977
|
);
|
|
@@ -9929,7 +10038,7 @@ var DockerodeClient = class {
|
|
|
9929
10038
|
var createDockerodeClient = (config) => new DockerodeClient(config);
|
|
9930
10039
|
|
|
9931
10040
|
// src/commands/deploy/internal/backend-deploy/dockerode-client/env.ts
|
|
9932
|
-
import { existsSync as
|
|
10041
|
+
import { existsSync as existsSync28, readFileSync as readFileSync21, statSync as statSync11 } from "node:fs";
|
|
9933
10042
|
import path13 from "node:path";
|
|
9934
10043
|
function stripSurroundingQuotes(value) {
|
|
9935
10044
|
const t = value.trim();
|
|
@@ -9946,10 +10055,10 @@ function loadEnvFromFile(envFilePath) {
|
|
|
9946
10055
|
return {};
|
|
9947
10056
|
}
|
|
9948
10057
|
const targetPath = path13.resolve(envFilePath);
|
|
9949
|
-
if (!
|
|
10058
|
+
if (!existsSync28(targetPath) || !statSync11(targetPath).isFile()) {
|
|
9950
10059
|
return {};
|
|
9951
10060
|
}
|
|
9952
|
-
const raw =
|
|
10061
|
+
const raw = readFileSync21(targetPath, "utf-8");
|
|
9953
10062
|
const result = {};
|
|
9954
10063
|
for (const line of raw.split(/\r?\n/)) {
|
|
9955
10064
|
const normalized = line.trim();
|
|
@@ -10120,12 +10229,12 @@ function dockerPushImage(params, cwd) {
|
|
|
10120
10229
|
}
|
|
10121
10230
|
|
|
10122
10231
|
// src/commands/deploy/internal/backend-deploy/resolve-dockerfile.ts
|
|
10123
|
-
import { existsSync as
|
|
10232
|
+
import { existsSync as existsSync29 } from "node:fs";
|
|
10124
10233
|
import path14 from "node:path";
|
|
10125
10234
|
function resolveDockerBuildPaths(cwd) {
|
|
10126
10235
|
const dockerfilePath = path14.join(cwd, "Dockerfile");
|
|
10127
10236
|
Logger.info(`\u67E5\u627EDockerfile\u6587\u4EF6\uFF0C\u8DEF\u5F84: ${dockerfilePath}`);
|
|
10128
|
-
if (!
|
|
10237
|
+
if (!existsSync29(dockerfilePath)) {
|
|
10129
10238
|
throw new Error(`Dockerfile \u4E0D\u5B58\u5728\uFF1A${dockerfilePath}`);
|
|
10130
10239
|
}
|
|
10131
10240
|
Logger.info("\u2713 Dockerfile \u5B58\u5728");
|
|
@@ -120,10 +120,6 @@ var requestConfig = {
|
|
|
120
120
|
method: "PUT",
|
|
121
121
|
path: "/cli/webide/terminals/meta"
|
|
122
122
|
}),
|
|
123
|
-
acquireSteelBrowser: defineEndpoint({
|
|
124
|
-
method: "POST",
|
|
125
|
-
path: "/cli/steel-browser/acquire"
|
|
126
|
-
}),
|
|
127
123
|
branchBaseline: defineEndpoint({
|
|
128
124
|
method: "GET",
|
|
129
125
|
path: "/cli/tasks/branch-baseline"
|
|
@@ -2555,6 +2551,81 @@ function clearWebIdeAgentId(workdir, taskId) {
|
|
|
2555
2551
|
writeRegistry2(path, {});
|
|
2556
2552
|
}
|
|
2557
2553
|
|
|
2554
|
+
// src/commands/clean-webide-cache.ts
|
|
2555
|
+
import { existsSync as existsSync5, rmSync } from "node:fs";
|
|
2556
|
+
import { resolve as resolve6 } from "node:path";
|
|
2557
|
+
import { JsonlLocalAgentStore as JsonlLocalAgentStore2 } from "@cursor/sdk";
|
|
2558
|
+
function cursorAgentStoreDir(workdir) {
|
|
2559
|
+
return resolve6(workdir, ".apm", "cursor-agent-store");
|
|
2560
|
+
}
|
|
2561
|
+
async function purgeCursorAgentStoreForAgent(workdir, agentId) {
|
|
2562
|
+
const trimmedAgentId = agentId.trim();
|
|
2563
|
+
const trimmedWorkdir = workdir.trim();
|
|
2564
|
+
if (!trimmedAgentId || !trimmedWorkdir) return false;
|
|
2565
|
+
const rootDir = cursorAgentStoreDir(trimmedWorkdir);
|
|
2566
|
+
if (!existsSync5(rootDir)) return false;
|
|
2567
|
+
const store = new JsonlLocalAgentStore2(rootDir);
|
|
2568
|
+
const runIds = [];
|
|
2569
|
+
let cursor;
|
|
2570
|
+
do {
|
|
2571
|
+
const page = await store.runs.list({
|
|
2572
|
+
filter: {
|
|
2573
|
+
agentIds: [trimmedAgentId],
|
|
2574
|
+
...cursor ? { cursor } : {},
|
|
2575
|
+
limit: 200
|
|
2576
|
+
}
|
|
2577
|
+
});
|
|
2578
|
+
for (const run of page.items) {
|
|
2579
|
+
runIds.push(run.runId);
|
|
2580
|
+
}
|
|
2581
|
+
cursor = page.nextCursor;
|
|
2582
|
+
} while (cursor);
|
|
2583
|
+
if (runIds.length > 0) {
|
|
2584
|
+
await store.runEvents.delete({ filter: { runIds } });
|
|
2585
|
+
}
|
|
2586
|
+
await store.runs.delete({ filter: { agentIds: [trimmedAgentId] } });
|
|
2587
|
+
await store.checkpoints.delete({ filter: { agentIds: [trimmedAgentId] } });
|
|
2588
|
+
await store.agents.delete({ filter: { agentIds: [trimmedAgentId] } });
|
|
2589
|
+
return true;
|
|
2590
|
+
}
|
|
2591
|
+
async function cleanWebIdeWorkspaceCache(taskId, workdir) {
|
|
2592
|
+
const trimmedTaskId = taskId.trim();
|
|
2593
|
+
const trimmedWorkdir = workdir.trim();
|
|
2594
|
+
if (!trimmedTaskId || !trimmedWorkdir) {
|
|
2595
|
+
return;
|
|
2596
|
+
}
|
|
2597
|
+
const agentId = loadWebIdeAgentId(trimmedWorkdir, trimmedTaskId);
|
|
2598
|
+
if (agentId) {
|
|
2599
|
+
try {
|
|
2600
|
+
const purged = await purgeCursorAgentStoreForAgent(
|
|
2601
|
+
trimmedWorkdir,
|
|
2602
|
+
agentId
|
|
2603
|
+
);
|
|
2604
|
+
if (purged) {
|
|
2605
|
+
console.log(
|
|
2606
|
+
`[apm] \u5DF2\u6E05\u7406 Cursor agent store agentId=${agentId} taskId=${trimmedTaskId}`
|
|
2607
|
+
);
|
|
2608
|
+
}
|
|
2609
|
+
} catch (err) {
|
|
2610
|
+
console.warn(
|
|
2611
|
+
`[apm] \u6E05\u7406 Cursor agent store \u5931\u8D25 agentId=${agentId}:`,
|
|
2612
|
+
err instanceof Error ? err.message : err
|
|
2613
|
+
);
|
|
2614
|
+
}
|
|
2615
|
+
} else {
|
|
2616
|
+
console.log(
|
|
2617
|
+
`[apm] \u65E0 WebIDE agentId\uFF0C\u8DF3\u8FC7 cursor-agent-store taskId=${trimmedTaskId}`
|
|
2618
|
+
);
|
|
2619
|
+
}
|
|
2620
|
+
const dir = resolve6(trimmedWorkdir, ".apm", "webide", trimmedTaskId);
|
|
2621
|
+
if (existsSync5(dir)) {
|
|
2622
|
+
rmSync(dir, { recursive: true, force: true });
|
|
2623
|
+
console.log(`[apm] \u5DF2\u6E05\u7406 WebIDE \u7F13\u5B58 ${dir}`);
|
|
2624
|
+
} else {
|
|
2625
|
+
console.log(`[apm] WebIDE \u7F13\u5B58\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7 ${dir}`);
|
|
2626
|
+
}
|
|
2627
|
+
}
|
|
2628
|
+
|
|
2558
2629
|
// src/commands/connect/webide-ask-question.ts
|
|
2559
2630
|
import { setTimeout as delay } from "node:timers/promises";
|
|
2560
2631
|
var POLL_INTERVAL_MS = 2e3;
|
|
@@ -2669,14 +2740,14 @@ var MinioClient = class {
|
|
|
2669
2740
|
async deleteObjectsByPrefix(bucket, prefix) {
|
|
2670
2741
|
const objectsStream = this.inner.listObjectsV2(bucket, prefix, true);
|
|
2671
2742
|
const keys = [];
|
|
2672
|
-
await new Promise((
|
|
2743
|
+
await new Promise((resolve7, reject) => {
|
|
2673
2744
|
objectsStream.on("data", (obj) => {
|
|
2674
2745
|
if (obj.name) {
|
|
2675
2746
|
keys.push(obj.name);
|
|
2676
2747
|
}
|
|
2677
2748
|
});
|
|
2678
2749
|
objectsStream.on("error", reject);
|
|
2679
|
-
objectsStream.on("end",
|
|
2750
|
+
objectsStream.on("end", resolve7);
|
|
2680
2751
|
});
|
|
2681
2752
|
const chunkSize = 500;
|
|
2682
2753
|
for (let i = 0; i < keys.length; i += chunkSize) {
|
|
@@ -2950,10 +3021,10 @@ ${diagnostic ?? ""}
|
|
|
2950
3021
|
|
|
2951
3022
|
// src/project-documents-sync.ts
|
|
2952
3023
|
import {
|
|
2953
|
-
existsSync as
|
|
3024
|
+
existsSync as existsSync6,
|
|
2954
3025
|
readdirSync as readdirSync3,
|
|
2955
3026
|
readFileSync as readFileSync6,
|
|
2956
|
-
rmSync,
|
|
3027
|
+
rmSync as rmSync2,
|
|
2957
3028
|
writeFileSync as writeFileSync7
|
|
2958
3029
|
} from "fs";
|
|
2959
3030
|
import { createHash } from "crypto";
|
|
@@ -2999,7 +3070,7 @@ function readLocalManifest(apmRoot, projectId) {
|
|
|
2999
3070
|
projectDocumentsDir(apmRoot, projectId),
|
|
3000
3071
|
MANIFEST_FILE
|
|
3001
3072
|
);
|
|
3002
|
-
if (!
|
|
3073
|
+
if (!existsSync6(manifestPath3)) {
|
|
3003
3074
|
return null;
|
|
3004
3075
|
}
|
|
3005
3076
|
try {
|
|
@@ -3012,7 +3083,7 @@ function readLocalManifest(apmRoot, projectId) {
|
|
|
3012
3083
|
}
|
|
3013
3084
|
function listLocalDocumentPaths(apmRoot, projectId) {
|
|
3014
3085
|
const root = projectDocumentsDir(apmRoot, projectId);
|
|
3015
|
-
if (!
|
|
3086
|
+
if (!existsSync6(root)) {
|
|
3016
3087
|
return [];
|
|
3017
3088
|
}
|
|
3018
3089
|
const paths = [];
|
|
@@ -3146,8 +3217,8 @@ ${diagnostic ?? ""}`);
|
|
|
3146
3217
|
const absPath = toFsPath(
|
|
3147
3218
|
projectDocumentLocalPath(targetApmDir, projectId, path)
|
|
3148
3219
|
);
|
|
3149
|
-
if (
|
|
3150
|
-
|
|
3220
|
+
if (existsSync6(absPath)) {
|
|
3221
|
+
rmSync2(absPath, { force: true });
|
|
3151
3222
|
deleted += 1;
|
|
3152
3223
|
}
|
|
3153
3224
|
}
|
|
@@ -3513,17 +3584,17 @@ function readCliVersion() {
|
|
|
3513
3584
|
}
|
|
3514
3585
|
|
|
3515
3586
|
// src/commands/update-skills.ts
|
|
3516
|
-
import { existsSync as
|
|
3587
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync8, statSync as statSync4 } from "fs";
|
|
3517
3588
|
import { join as join10 } from "path";
|
|
3518
3589
|
|
|
3519
3590
|
// src/skills-sync.ts
|
|
3520
3591
|
import {
|
|
3521
3592
|
copyFileSync as copyFileSync2,
|
|
3522
3593
|
cpSync,
|
|
3523
|
-
existsSync as
|
|
3594
|
+
existsSync as existsSync7,
|
|
3524
3595
|
mkdirSync as mkdirSync7,
|
|
3525
3596
|
readdirSync as readdirSync4,
|
|
3526
|
-
rmSync as
|
|
3597
|
+
rmSync as rmSync3,
|
|
3527
3598
|
statSync as statSync3,
|
|
3528
3599
|
writeFileSync as writeFileSync9
|
|
3529
3600
|
} from "fs";
|
|
@@ -3537,20 +3608,20 @@ function sanitizeSkillDirName(name) {
|
|
|
3537
3608
|
return trimmed.replace(/[/\\:*?"<>|]/g, "_");
|
|
3538
3609
|
}
|
|
3539
3610
|
function listBaseSkillDirNames() {
|
|
3540
|
-
if (!
|
|
3611
|
+
if (!existsSync7(BASE_SKILLS_TEMPLATE_DIR)) return [];
|
|
3541
3612
|
return readdirSync4(BASE_SKILLS_TEMPLATE_DIR).filter((name) => {
|
|
3542
3613
|
const path = join9(BASE_SKILLS_TEMPLATE_DIR, name);
|
|
3543
3614
|
return statSync3(path).isDirectory();
|
|
3544
3615
|
});
|
|
3545
3616
|
}
|
|
3546
3617
|
function syncAgentsGuide(apmDir) {
|
|
3547
|
-
if (!
|
|
3618
|
+
if (!existsSync7(AGENTS_TEMPLATE_PATH)) return false;
|
|
3548
3619
|
mkdirSync7(apmDir, { recursive: true });
|
|
3549
3620
|
copyFileSync2(AGENTS_TEMPLATE_PATH, join9(apmDir, "AGENTS.md"));
|
|
3550
3621
|
return true;
|
|
3551
3622
|
}
|
|
3552
3623
|
function listBaseRuleFileNames() {
|
|
3553
|
-
if (!
|
|
3624
|
+
if (!existsSync7(BASE_RULES_TEMPLATE_DIR)) return [];
|
|
3554
3625
|
return readdirSync4(BASE_RULES_TEMPLATE_DIR).filter((name) => {
|
|
3555
3626
|
const path = join9(BASE_RULES_TEMPLATE_DIR, name);
|
|
3556
3627
|
return statSync3(path).isFile();
|
|
@@ -3594,13 +3665,13 @@ function syncSupplementarySkills(skillsDir, list) {
|
|
|
3594
3665
|
written.push(dirName);
|
|
3595
3666
|
}
|
|
3596
3667
|
const removed = [];
|
|
3597
|
-
if (!
|
|
3668
|
+
if (!existsSync7(skillsDir)) return { written, skipped, removed };
|
|
3598
3669
|
for (const entry of readdirSync4(skillsDir)) {
|
|
3599
3670
|
const full = join9(skillsDir, entry);
|
|
3600
3671
|
if (!statSync3(full).isDirectory()) continue;
|
|
3601
3672
|
if (baseNames.has(entry)) continue;
|
|
3602
3673
|
if (apiDirNames.has(entry)) continue;
|
|
3603
|
-
|
|
3674
|
+
rmSync3(full, { recursive: true, force: true });
|
|
3604
3675
|
removed.push(entry);
|
|
3605
3676
|
}
|
|
3606
3677
|
return { written, skipped, removed };
|
|
@@ -3610,7 +3681,7 @@ function syncSupplementarySkills(skillsDir, list) {
|
|
|
3610
3681
|
async function syncWorkspaceSkills(cfg, workdir) {
|
|
3611
3682
|
const apmDir = workspaceApmDir(workdir);
|
|
3612
3683
|
const fsApmDir = toFsPath(apmDir);
|
|
3613
|
-
if (!
|
|
3684
|
+
if (!existsSync8(fsApmDir)) {
|
|
3614
3685
|
throw new Error("[apm] \u672A\u627E\u5230 .apm \u76EE\u5F55\uFF0C\u8BF7\u5148\u6267\u884C apm init");
|
|
3615
3686
|
}
|
|
3616
3687
|
const apmStat = statSync4(fsApmDir);
|
|
@@ -3654,7 +3725,7 @@ async function syncWorkspaceSkills(cfg, workdir) {
|
|
|
3654
3725
|
}
|
|
3655
3726
|
|
|
3656
3727
|
// src/commands/sync-session-attachments.ts
|
|
3657
|
-
import { existsSync as
|
|
3728
|
+
import { existsSync as existsSync9, readFileSync as readFileSync9, writeFileSync as writeFileSync10 } from "fs";
|
|
3658
3729
|
import { join as join11 } from "path";
|
|
3659
3730
|
var MANIFEST_FILE2 = ".sync-manifest.json";
|
|
3660
3731
|
async function downloadAttachment(cfg, attachmentId) {
|
|
@@ -3672,7 +3743,7 @@ async function downloadAttachment(cfg, attachmentId) {
|
|
|
3672
3743
|
}
|
|
3673
3744
|
function loadManifest(dir) {
|
|
3674
3745
|
const path = join11(dir, MANIFEST_FILE2);
|
|
3675
|
-
if (!
|
|
3746
|
+
if (!existsSync9(path)) {
|
|
3676
3747
|
return { version: 1, attachments: {} };
|
|
3677
3748
|
}
|
|
3678
3749
|
try {
|
|
@@ -3695,7 +3766,7 @@ function saveManifest(dir, manifest) {
|
|
|
3695
3766
|
);
|
|
3696
3767
|
}
|
|
3697
3768
|
function isAttachmentUpToDate(entry, item, dest) {
|
|
3698
|
-
if (!entry || !
|
|
3769
|
+
if (!entry || !existsSync9(dest)) return false;
|
|
3699
3770
|
if (entry.name !== item.name) return false;
|
|
3700
3771
|
const createdAt = item.createdAt ?? "";
|
|
3701
3772
|
return entry.createdAt === createdAt;
|
|
@@ -3741,7 +3812,7 @@ async function syncWebIdeAttachments(cfg, taskId, workdir, attachments) {
|
|
|
3741
3812
|
}
|
|
3742
3813
|
|
|
3743
3814
|
// src/commands/connect/cli-version-sync.ts
|
|
3744
|
-
import { existsSync as
|
|
3815
|
+
import { existsSync as existsSync10, readFileSync as readFileSync10, writeFileSync as writeFileSync11 } from "fs";
|
|
3745
3816
|
import { join as join12 } from "path";
|
|
3746
3817
|
var CLI_VERSION_FILE = ".cli-version.json";
|
|
3747
3818
|
function manifestPath2(apmDir) {
|
|
@@ -3749,7 +3820,7 @@ function manifestPath2(apmDir) {
|
|
|
3749
3820
|
}
|
|
3750
3821
|
function loadManifest2(apmDir) {
|
|
3751
3822
|
const path = toFsPath(manifestPath2(apmDir));
|
|
3752
|
-
if (!
|
|
3823
|
+
if (!existsSync10(path)) {
|
|
3753
3824
|
return null;
|
|
3754
3825
|
}
|
|
3755
3826
|
try {
|
|
@@ -4192,6 +4263,16 @@ async function handleWebIdeInboundMessage(cfg, msg, signal, options) {
|
|
|
4192
4263
|
console.log(
|
|
4193
4264
|
`[apm] webide-message \u5B8C\u6210 action=${msg.action} messageId=${messageId} agentId=${outcome.agentId}`
|
|
4194
4265
|
);
|
|
4266
|
+
if (msg.action === "accept") {
|
|
4267
|
+
try {
|
|
4268
|
+
await cleanWebIdeWorkspaceCache(taskId, workdir);
|
|
4269
|
+
} catch (err) {
|
|
4270
|
+
console.warn(
|
|
4271
|
+
"[apm] \u5408\u5E76 PR \u540E\u6E05\u7406 WebIDE agent \u7F13\u5B58\u5931\u8D25:",
|
|
4272
|
+
err instanceof Error ? err.message : err
|
|
4273
|
+
);
|
|
4274
|
+
}
|
|
4275
|
+
}
|
|
4195
4276
|
} catch (err) {
|
|
4196
4277
|
const detail = err instanceof Error ? err.message : String(err);
|
|
4197
4278
|
console.error(`[apm] webide-message \u5931\u8D25: ${detail}`);
|
|
@@ -4225,12 +4306,12 @@ function installTerminalRpcListener() {
|
|
|
4225
4306
|
}
|
|
4226
4307
|
function call(op, args) {
|
|
4227
4308
|
const id = nextId++;
|
|
4228
|
-
return new Promise((
|
|
4309
|
+
return new Promise((resolve7, reject) => {
|
|
4229
4310
|
if (!parentPort) {
|
|
4230
4311
|
reject(new Error("parentPort \u4E0D\u53EF\u7528"));
|
|
4231
4312
|
return;
|
|
4232
4313
|
}
|
|
4233
|
-
pending.set(id, { resolve:
|
|
4314
|
+
pending.set(id, { resolve: resolve7, reject });
|
|
4234
4315
|
parentPort.postMessage({
|
|
4235
4316
|
type: "terminal-rpc",
|
|
4236
4317
|
id,
|