ai-project-manage-cli 7.1.30 → 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 +190 -81
- package/dist/webide-message-worker.js +120 -39
- 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"
|
|
@@ -304,6 +300,10 @@ var init_request_config = __esm({
|
|
|
304
300
|
path: "/cli/deploy-artifact-storage"
|
|
305
301
|
}
|
|
306
302
|
),
|
|
303
|
+
getApmLogStorage: defineEndpoint({
|
|
304
|
+
method: "GET",
|
|
305
|
+
path: "/cli/apm-log-storage"
|
|
306
|
+
}),
|
|
307
307
|
attachTaskDeploymentArtifact: defineEndpoint({
|
|
308
308
|
method: "PUT",
|
|
309
309
|
path: "/cli/task-deployments/artifact"
|
|
@@ -440,14 +440,14 @@ var init_minio = __esm({
|
|
|
440
440
|
async deleteObjectsByPrefix(bucket, prefix) {
|
|
441
441
|
const objectsStream = this.inner.listObjectsV2(bucket, prefix, true);
|
|
442
442
|
const keys = [];
|
|
443
|
-
await new Promise((
|
|
443
|
+
await new Promise((resolve9, reject) => {
|
|
444
444
|
objectsStream.on("data", (obj) => {
|
|
445
445
|
if (obj.name) {
|
|
446
446
|
keys.push(obj.name);
|
|
447
447
|
}
|
|
448
448
|
});
|
|
449
449
|
objectsStream.on("error", reject);
|
|
450
|
-
objectsStream.on("end",
|
|
450
|
+
objectsStream.on("end", resolve9);
|
|
451
451
|
});
|
|
452
452
|
const chunkSize = 500;
|
|
453
453
|
for (let i = 0; i < keys.length; i += chunkSize) {
|
|
@@ -481,8 +481,12 @@ var init_minio = __esm({
|
|
|
481
481
|
});
|
|
482
482
|
|
|
483
483
|
// src/commands/connect/apm-log-minio.ts
|
|
484
|
-
function
|
|
485
|
-
const
|
|
484
|
+
async function fetchApmLogStorage(cfg) {
|
|
485
|
+
const api = createApmApiClient(cfg);
|
|
486
|
+
return api.cli.getApmLogStorage(void 0);
|
|
487
|
+
}
|
|
488
|
+
async function createApmLogMinioClient(cfg) {
|
|
489
|
+
const storage = await fetchApmLogStorage(cfg);
|
|
486
490
|
return {
|
|
487
491
|
client: new MinioClient({
|
|
488
492
|
endPoint: storage.endpoint,
|
|
@@ -494,19 +498,11 @@ function createApmLogMinioClient() {
|
|
|
494
498
|
bucket: storage.bucket
|
|
495
499
|
};
|
|
496
500
|
}
|
|
497
|
-
var APM_LOG_MINIO_CONFIG;
|
|
498
501
|
var init_apm_log_minio = __esm({
|
|
499
502
|
"src/commands/connect/apm-log-minio.ts"() {
|
|
500
503
|
"use strict";
|
|
504
|
+
init_client();
|
|
501
505
|
init_minio();
|
|
502
|
-
APM_LOG_MINIO_CONFIG = {
|
|
503
|
-
endpoint: "objectstorageapi.gzg.sealos.run",
|
|
504
|
-
port: 443,
|
|
505
|
-
useSsl: true,
|
|
506
|
-
accessKey: "428hqav4",
|
|
507
|
-
secretKey: "68b8srk4vdbjdhlc",
|
|
508
|
-
bucket: "428hqav4-apm-log"
|
|
509
|
-
};
|
|
510
506
|
}
|
|
511
507
|
});
|
|
512
508
|
|
|
@@ -647,7 +643,7 @@ var init_webide_terminal_registry = __esm({
|
|
|
647
643
|
bucket = "";
|
|
648
644
|
async ensureMinio() {
|
|
649
645
|
if (this.minio) return;
|
|
650
|
-
const created = createApmLogMinioClient();
|
|
646
|
+
const created = await createApmLogMinioClient(this.cfg);
|
|
651
647
|
this.minio = created.client;
|
|
652
648
|
this.bucket = created.bucket;
|
|
653
649
|
await this.minio.ensureBucket(this.bucket);
|
|
@@ -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"
|
|
@@ -208,6 +204,10 @@ var requestConfig = {
|
|
|
208
204
|
path: "/cli/deploy-artifact-storage"
|
|
209
205
|
}
|
|
210
206
|
),
|
|
207
|
+
getApmLogStorage: defineEndpoint({
|
|
208
|
+
method: "GET",
|
|
209
|
+
path: "/cli/apm-log-storage"
|
|
210
|
+
}),
|
|
211
211
|
attachTaskDeploymentArtifact: defineEndpoint({
|
|
212
212
|
method: "PUT",
|
|
213
213
|
path: "/cli/task-deployments/artifact"
|
|
@@ -2551,6 +2551,81 @@ function clearWebIdeAgentId(workdir, taskId) {
|
|
|
2551
2551
|
writeRegistry2(path, {});
|
|
2552
2552
|
}
|
|
2553
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
|
+
|
|
2554
2629
|
// src/commands/connect/webide-ask-question.ts
|
|
2555
2630
|
import { setTimeout as delay } from "node:timers/promises";
|
|
2556
2631
|
var POLL_INTERVAL_MS = 2e3;
|
|
@@ -2665,14 +2740,14 @@ var MinioClient = class {
|
|
|
2665
2740
|
async deleteObjectsByPrefix(bucket, prefix) {
|
|
2666
2741
|
const objectsStream = this.inner.listObjectsV2(bucket, prefix, true);
|
|
2667
2742
|
const keys = [];
|
|
2668
|
-
await new Promise((
|
|
2743
|
+
await new Promise((resolve7, reject) => {
|
|
2669
2744
|
objectsStream.on("data", (obj) => {
|
|
2670
2745
|
if (obj.name) {
|
|
2671
2746
|
keys.push(obj.name);
|
|
2672
2747
|
}
|
|
2673
2748
|
});
|
|
2674
2749
|
objectsStream.on("error", reject);
|
|
2675
|
-
objectsStream.on("end",
|
|
2750
|
+
objectsStream.on("end", resolve7);
|
|
2676
2751
|
});
|
|
2677
2752
|
const chunkSize = 500;
|
|
2678
2753
|
for (let i = 0; i < keys.length; i += chunkSize) {
|
|
@@ -2704,16 +2779,12 @@ var MinioClient = class {
|
|
|
2704
2779
|
};
|
|
2705
2780
|
|
|
2706
2781
|
// src/commands/connect/apm-log-minio.ts
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
bucket: "428hqav4-apm-log"
|
|
2714
|
-
};
|
|
2715
|
-
function createApmLogMinioClient() {
|
|
2716
|
-
const storage = APM_LOG_MINIO_CONFIG;
|
|
2782
|
+
async function fetchApmLogStorage(cfg) {
|
|
2783
|
+
const api = createApmApiClient(cfg);
|
|
2784
|
+
return api.cli.getApmLogStorage(void 0);
|
|
2785
|
+
}
|
|
2786
|
+
async function createApmLogMinioClient(cfg) {
|
|
2787
|
+
const storage = await fetchApmLogStorage(cfg);
|
|
2717
2788
|
return {
|
|
2718
2789
|
client: new MinioClient({
|
|
2719
2790
|
endPoint: storage.endpoint,
|
|
@@ -2766,7 +2837,7 @@ function createThrottledWebIdeMessageLogSync(cfg, ctx, onError, options) {
|
|
|
2766
2837
|
let firstLogNotified = false;
|
|
2767
2838
|
const ensureMinio = async () => {
|
|
2768
2839
|
if (minio) return;
|
|
2769
|
-
const created = createApmLogMinioClient();
|
|
2840
|
+
const created = await createApmLogMinioClient(cfg);
|
|
2770
2841
|
minio = created.client;
|
|
2771
2842
|
bucket = created.bucket;
|
|
2772
2843
|
await minio.ensureBucket(bucket);
|
|
@@ -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,
|