ai-project-manage-cli 7.1.27 → 7.1.29
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 +217 -129
- package/dist/webide-message-worker.js +235 -83
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -314,6 +314,10 @@ var init_request_config = __esm({
|
|
|
314
314
|
});
|
|
315
315
|
|
|
316
316
|
// src/api/client.ts
|
|
317
|
+
var client_exports = {};
|
|
318
|
+
__export(client_exports, {
|
|
319
|
+
createApmApiClient: () => createApmApiClient
|
|
320
|
+
});
|
|
317
321
|
import { createApiClient } from "listpage-http";
|
|
318
322
|
function createApmApiClient(cfg) {
|
|
319
323
|
const baseURL = `${cfg.baseUrl.trim().replace(/\/+$/, "")}/api/v1`;
|
|
@@ -476,123 +480,33 @@ var init_minio = __esm({
|
|
|
476
480
|
}
|
|
477
481
|
});
|
|
478
482
|
|
|
479
|
-
// src/commands/
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
}
|
|
485
|
-
function sanitizeDeployProjectName(name) {
|
|
486
|
-
const trimmed = name.trim().replace(/\\/g, "/");
|
|
487
|
-
const base = trimmed.split("/").filter(Boolean).pop() ?? trimmed;
|
|
488
|
-
try {
|
|
489
|
-
return sanitizeRelativePath(base.replace(/[/\\:*?"<>|]/g, "_"));
|
|
490
|
-
} catch {
|
|
491
|
-
return "project";
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
function buildDeployArtifactFileName(kind, projectName, timestamp = formatDeployArtifactTimestamp()) {
|
|
495
|
-
const safeName = sanitizeDeployProjectName(projectName);
|
|
496
|
-
const suffix = kind === "frontend" ? "dist.zip" : "jar.zip";
|
|
497
|
-
return `${timestamp}-${safeName}.${suffix}`;
|
|
498
|
-
}
|
|
499
|
-
function buildDeployArtifactObjectKey(projectName, fileName) {
|
|
500
|
-
const safeProject = sanitizeDeployProjectName(projectName);
|
|
501
|
-
return `deploy/${safeProject}/${fileName}`;
|
|
502
|
-
}
|
|
503
|
-
function resolveDeploymentRunIdFromEnv() {
|
|
504
|
-
const raw = process.env[APM_DEPLOYMENT_RUN_ID_ENV]?.trim();
|
|
505
|
-
return raw || null;
|
|
506
|
-
}
|
|
507
|
-
async function fetchDeployArtifactStorage(api) {
|
|
508
|
-
return api.cli.getDeployArtifactStorage(void 0);
|
|
509
|
-
}
|
|
510
|
-
async function uploadDeployArtifactZip(options) {
|
|
511
|
-
const deploymentRunId = options.deploymentRunId ?? resolveDeploymentRunIdFromEnv();
|
|
512
|
-
if (!deploymentRunId && !options.uploadWithoutRunId) {
|
|
513
|
-
return null;
|
|
514
|
-
}
|
|
515
|
-
const cfg = await tryReadApmConfig();
|
|
516
|
-
if (!cfg || !resolveApiKey(cfg)) {
|
|
517
|
-
console.warn("[apm] \u672A\u767B\u5F55\uFF0C\u8DF3\u8FC7 MinIO \u90E8\u7F72\u4EA7\u7269\u5F52\u6863");
|
|
518
|
-
return null;
|
|
519
|
-
}
|
|
520
|
-
const api = options.api ?? createApmApiClient(cfg);
|
|
521
|
-
let storage;
|
|
522
|
-
try {
|
|
523
|
-
storage = await fetchDeployArtifactStorage(api);
|
|
524
|
-
} catch (error) {
|
|
525
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
526
|
-
console.warn(`[apm] \u83B7\u53D6 MinIO \u914D\u7F6E\u5931\u8D25\uFF0C\u8DF3\u8FC7\u90E8\u7F72\u4EA7\u7269\u5F52\u6863: ${detail}`);
|
|
527
|
-
return null;
|
|
528
|
-
}
|
|
529
|
-
const fileName = buildDeployArtifactFileName(
|
|
530
|
-
options.kind,
|
|
531
|
-
options.projectName,
|
|
532
|
-
options.timestamp
|
|
533
|
-
);
|
|
534
|
-
const objectKey = buildDeployArtifactObjectKey(options.projectName, fileName);
|
|
535
|
-
let body;
|
|
536
|
-
try {
|
|
537
|
-
body = await readFile2(options.zipPath);
|
|
538
|
-
} catch (error) {
|
|
539
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
540
|
-
console.warn(`[apm] \u8BFB\u53D6\u90E8\u7F72\u4EA7\u7269 zip \u5931\u8D25\uFF0C\u8DF3\u8FC7 MinIO \u5F52\u6863: ${detail}`);
|
|
541
|
-
return null;
|
|
542
|
-
}
|
|
543
|
-
try {
|
|
544
|
-
const client = new MinioClient({
|
|
483
|
+
// src/commands/connect/apm-log-minio.ts
|
|
484
|
+
function createApmLogMinioClient() {
|
|
485
|
+
const storage = APM_LOG_MINIO_CONFIG;
|
|
486
|
+
return {
|
|
487
|
+
client: new MinioClient({
|
|
545
488
|
endPoint: storage.endpoint,
|
|
546
489
|
port: storage.port,
|
|
547
490
|
useSSL: storage.useSsl,
|
|
548
491
|
accessKey: storage.accessKey,
|
|
549
492
|
secretKey: storage.secretKey
|
|
550
|
-
})
|
|
551
|
-
await client.ensureBucket(storage.bucket);
|
|
552
|
-
await client.putObject(storage.bucket, objectKey, body, {
|
|
553
|
-
"Content-Type": "application/zip"
|
|
554
|
-
});
|
|
555
|
-
console.error(
|
|
556
|
-
`[apm] \u672C\u5730\u76F4\u4F20 MinIO\uFF08\u4E0D\u7ECF\u5E73\u53F0\u670D\u52A1\u5668\uFF09: ${storage.endpoint}:${storage.port}/${storage.bucket}/${objectKey} (${(body.length / 1024 / 1024).toFixed(
|
|
557
|
-
2
|
|
558
|
-
)} MB)`
|
|
559
|
-
);
|
|
560
|
-
} catch (error) {
|
|
561
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
562
|
-
console.warn(`[apm] MinIO \u90E8\u7F72\u4EA7\u7269\u5F52\u6863\u5931\u8D25: ${detail}`);
|
|
563
|
-
return null;
|
|
564
|
-
}
|
|
565
|
-
if (deploymentRunId) {
|
|
566
|
-
try {
|
|
567
|
-
await api.cli.attachTaskDeploymentArtifact({
|
|
568
|
-
id: deploymentRunId,
|
|
569
|
-
artifactObjectKey: objectKey,
|
|
570
|
-
artifactFileName: fileName
|
|
571
|
-
});
|
|
572
|
-
console.error(
|
|
573
|
-
`[apm] \u5DF2\u7ED1\u5B9A\u90E8\u7F72\u4EA7\u7269\u5230\u8BB0\u5F55 id=${deploymentRunId} file=${fileName}`
|
|
574
|
-
);
|
|
575
|
-
} catch (error) {
|
|
576
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
577
|
-
console.warn(`[apm] \u7ED1\u5B9A\u90E8\u7F72\u4EA7\u7269\u5230\u8BB0\u5F55\u5931\u8D25: ${detail}`);
|
|
578
|
-
return null;
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
return {
|
|
582
|
-
objectKey,
|
|
583
|
-
fileName,
|
|
493
|
+
}),
|
|
584
494
|
bucket: storage.bucket
|
|
585
495
|
};
|
|
586
496
|
}
|
|
587
|
-
var
|
|
588
|
-
var
|
|
589
|
-
"src/commands/
|
|
497
|
+
var APM_LOG_MINIO_CONFIG;
|
|
498
|
+
var init_apm_log_minio = __esm({
|
|
499
|
+
"src/commands/connect/apm-log-minio.ts"() {
|
|
590
500
|
"use strict";
|
|
591
|
-
init_client();
|
|
592
|
-
init_config();
|
|
593
|
-
init_minio();
|
|
594
501
|
init_minio();
|
|
595
|
-
|
|
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
|
+
};
|
|
596
510
|
}
|
|
597
511
|
});
|
|
598
512
|
|
|
@@ -715,8 +629,7 @@ var init_webide_terminal_registry = __esm({
|
|
|
715
629
|
"src/commands/connect/webide-terminal-registry.ts"() {
|
|
716
630
|
"use strict";
|
|
717
631
|
init_client();
|
|
718
|
-
|
|
719
|
-
init_minio();
|
|
632
|
+
init_apm_log_minio();
|
|
720
633
|
execFileAsync3 = promisify3(execFile3);
|
|
721
634
|
WEBIDE_TERMINAL_LINES_PER_CHUNK = 50;
|
|
722
635
|
SYNC_INTERVAL_MS = 400;
|
|
@@ -734,17 +647,9 @@ var init_webide_terminal_registry = __esm({
|
|
|
734
647
|
bucket = "";
|
|
735
648
|
async ensureMinio() {
|
|
736
649
|
if (this.minio) return;
|
|
737
|
-
const
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
this.minio = new MinioClient({
|
|
741
|
-
endPoint: storage.endpoint,
|
|
742
|
-
port: storage.port,
|
|
743
|
-
useSSL: storage.useSsl,
|
|
744
|
-
accessKey: storage.accessKey,
|
|
745
|
-
secretKey: storage.secretKey
|
|
746
|
-
});
|
|
747
|
-
this.bucket = storage.bucket;
|
|
650
|
+
const created = createApmLogMinioClient();
|
|
651
|
+
this.minio = created.client;
|
|
652
|
+
this.bucket = created.bucket;
|
|
748
653
|
await this.minio.ensureBucket(this.bucket);
|
|
749
654
|
}
|
|
750
655
|
listLocal(taskId) {
|
|
@@ -4370,11 +4275,124 @@ var DeployExecutionError = class extends Error {
|
|
|
4370
4275
|
};
|
|
4371
4276
|
|
|
4372
4277
|
// src/commands/deploy/deploy-debug-log.ts
|
|
4373
|
-
init_deploy_artifact_minio();
|
|
4374
4278
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
4375
4279
|
import { existsSync as existsSync17 } from "node:fs";
|
|
4376
4280
|
import { dirname as dirname6, join as join18 } from "node:path";
|
|
4377
4281
|
|
|
4282
|
+
// src/commands/deploy/internal/deploy-artifact-minio.ts
|
|
4283
|
+
init_client();
|
|
4284
|
+
init_config();
|
|
4285
|
+
init_minio();
|
|
4286
|
+
init_minio();
|
|
4287
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
4288
|
+
var APM_DEPLOYMENT_RUN_ID_ENV = "APM_DEPLOYMENT_RUN_ID";
|
|
4289
|
+
function formatDeployArtifactTimestamp(date = /* @__PURE__ */ new Date()) {
|
|
4290
|
+
const pad2 = (n) => String(n).padStart(2, "0");
|
|
4291
|
+
return `${date.getFullYear()}${pad2(date.getMonth() + 1)}${pad2(date.getDate())}${pad2(date.getHours())}${pad2(date.getMinutes())}${pad2(date.getSeconds())}`;
|
|
4292
|
+
}
|
|
4293
|
+
function sanitizeDeployProjectName(name) {
|
|
4294
|
+
const trimmed = name.trim().replace(/\\/g, "/");
|
|
4295
|
+
const base = trimmed.split("/").filter(Boolean).pop() ?? trimmed;
|
|
4296
|
+
try {
|
|
4297
|
+
return sanitizeRelativePath(base.replace(/[/\\:*?"<>|]/g, "_"));
|
|
4298
|
+
} catch {
|
|
4299
|
+
return "project";
|
|
4300
|
+
}
|
|
4301
|
+
}
|
|
4302
|
+
function buildDeployArtifactFileName(kind, projectName, timestamp = formatDeployArtifactTimestamp()) {
|
|
4303
|
+
const safeName = sanitizeDeployProjectName(projectName);
|
|
4304
|
+
const suffix = kind === "frontend" ? "dist.zip" : "jar.zip";
|
|
4305
|
+
return `${timestamp}-${safeName}.${suffix}`;
|
|
4306
|
+
}
|
|
4307
|
+
function buildDeployArtifactObjectKey(projectName, fileName) {
|
|
4308
|
+
const safeProject = sanitizeDeployProjectName(projectName);
|
|
4309
|
+
return `deploy/${safeProject}/${fileName}`;
|
|
4310
|
+
}
|
|
4311
|
+
function resolveDeploymentRunIdFromEnv() {
|
|
4312
|
+
const raw = process.env[APM_DEPLOYMENT_RUN_ID_ENV]?.trim();
|
|
4313
|
+
return raw || null;
|
|
4314
|
+
}
|
|
4315
|
+
async function fetchDeployArtifactStorage(api) {
|
|
4316
|
+
return api.cli.getDeployArtifactStorage(void 0);
|
|
4317
|
+
}
|
|
4318
|
+
async function uploadDeployArtifactZip(options) {
|
|
4319
|
+
const deploymentRunId = options.deploymentRunId ?? resolveDeploymentRunIdFromEnv();
|
|
4320
|
+
if (!deploymentRunId && !options.uploadWithoutRunId) {
|
|
4321
|
+
return null;
|
|
4322
|
+
}
|
|
4323
|
+
const cfg = await tryReadApmConfig();
|
|
4324
|
+
if (!cfg || !resolveApiKey(cfg)) {
|
|
4325
|
+
console.warn("[apm] \u672A\u767B\u5F55\uFF0C\u8DF3\u8FC7 MinIO \u90E8\u7F72\u4EA7\u7269\u5F52\u6863");
|
|
4326
|
+
return null;
|
|
4327
|
+
}
|
|
4328
|
+
const api = options.api ?? createApmApiClient(cfg);
|
|
4329
|
+
let storage;
|
|
4330
|
+
try {
|
|
4331
|
+
storage = await fetchDeployArtifactStorage(api);
|
|
4332
|
+
} catch (error) {
|
|
4333
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
4334
|
+
console.warn(`[apm] \u83B7\u53D6 MinIO \u914D\u7F6E\u5931\u8D25\uFF0C\u8DF3\u8FC7\u90E8\u7F72\u4EA7\u7269\u5F52\u6863: ${detail}`);
|
|
4335
|
+
return null;
|
|
4336
|
+
}
|
|
4337
|
+
const fileName = buildDeployArtifactFileName(
|
|
4338
|
+
options.kind,
|
|
4339
|
+
options.projectName,
|
|
4340
|
+
options.timestamp
|
|
4341
|
+
);
|
|
4342
|
+
const objectKey = buildDeployArtifactObjectKey(options.projectName, fileName);
|
|
4343
|
+
let body;
|
|
4344
|
+
try {
|
|
4345
|
+
body = await readFile2(options.zipPath);
|
|
4346
|
+
} catch (error) {
|
|
4347
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
4348
|
+
console.warn(`[apm] \u8BFB\u53D6\u90E8\u7F72\u4EA7\u7269 zip \u5931\u8D25\uFF0C\u8DF3\u8FC7 MinIO \u5F52\u6863: ${detail}`);
|
|
4349
|
+
return null;
|
|
4350
|
+
}
|
|
4351
|
+
try {
|
|
4352
|
+
const client = new MinioClient({
|
|
4353
|
+
endPoint: storage.endpoint,
|
|
4354
|
+
port: storage.port,
|
|
4355
|
+
useSSL: storage.useSsl,
|
|
4356
|
+
accessKey: storage.accessKey,
|
|
4357
|
+
secretKey: storage.secretKey
|
|
4358
|
+
});
|
|
4359
|
+
await client.ensureBucket(storage.bucket);
|
|
4360
|
+
await client.putObject(storage.bucket, objectKey, body, {
|
|
4361
|
+
"Content-Type": "application/zip"
|
|
4362
|
+
});
|
|
4363
|
+
console.error(
|
|
4364
|
+
`[apm] \u672C\u5730\u76F4\u4F20 MinIO\uFF08\u4E0D\u7ECF\u5E73\u53F0\u670D\u52A1\u5668\uFF09: ${storage.endpoint}:${storage.port}/${storage.bucket}/${objectKey} (${(body.length / 1024 / 1024).toFixed(
|
|
4365
|
+
2
|
|
4366
|
+
)} MB)`
|
|
4367
|
+
);
|
|
4368
|
+
} catch (error) {
|
|
4369
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
4370
|
+
console.warn(`[apm] MinIO \u90E8\u7F72\u4EA7\u7269\u5F52\u6863\u5931\u8D25: ${detail}`);
|
|
4371
|
+
return null;
|
|
4372
|
+
}
|
|
4373
|
+
if (deploymentRunId) {
|
|
4374
|
+
try {
|
|
4375
|
+
await api.cli.attachTaskDeploymentArtifact({
|
|
4376
|
+
id: deploymentRunId,
|
|
4377
|
+
artifactObjectKey: objectKey,
|
|
4378
|
+
artifactFileName: fileName
|
|
4379
|
+
});
|
|
4380
|
+
console.error(
|
|
4381
|
+
`[apm] \u5DF2\u7ED1\u5B9A\u90E8\u7F72\u4EA7\u7269\u5230\u8BB0\u5F55 id=${deploymentRunId} file=${fileName}`
|
|
4382
|
+
);
|
|
4383
|
+
} catch (error) {
|
|
4384
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
4385
|
+
console.warn(`[apm] \u7ED1\u5B9A\u90E8\u7F72\u4EA7\u7269\u5230\u8BB0\u5F55\u5931\u8D25: ${detail}`);
|
|
4386
|
+
return null;
|
|
4387
|
+
}
|
|
4388
|
+
}
|
|
4389
|
+
return {
|
|
4390
|
+
objectKey,
|
|
4391
|
+
fileName,
|
|
4392
|
+
bucket: storage.bucket
|
|
4393
|
+
};
|
|
4394
|
+
}
|
|
4395
|
+
|
|
4378
4396
|
// src/commands/deploy/internal/deploy-shell-env.ts
|
|
4379
4397
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
4380
4398
|
import { existsSync as existsSync16 } from "node:fs";
|
|
@@ -5523,7 +5541,6 @@ function runDeployShellCommand(command, cwd, captureOutput) {
|
|
|
5523
5541
|
|
|
5524
5542
|
// src/commands/deploy/internal/wisdom-backend/index.ts
|
|
5525
5543
|
import path9 from "node:path";
|
|
5526
|
-
init_deploy_artifact_minio();
|
|
5527
5544
|
|
|
5528
5545
|
// src/commands/deploy/internal/wisdom-backend/jar-incremental.ts
|
|
5529
5546
|
import {
|
|
@@ -5592,7 +5609,6 @@ import SftpClient from "ssh2-sftp-client";
|
|
|
5592
5609
|
import { readdir as readdir2, readFile as readFile3, unlink, writeFile } from "node:fs/promises";
|
|
5593
5610
|
import path3 from "node:path";
|
|
5594
5611
|
import JSZip from "jszip";
|
|
5595
|
-
init_deploy_artifact_minio();
|
|
5596
5612
|
init_minio();
|
|
5597
5613
|
async function addDirToZip(dir, zipFolder) {
|
|
5598
5614
|
const entries = await readdir2(dir, { withFileTypes: true });
|
|
@@ -5682,7 +5698,6 @@ async function packDirectoryWithMinioArchive(input) {
|
|
|
5682
5698
|
}
|
|
5683
5699
|
|
|
5684
5700
|
// src/commands/deploy/internal/wisdom-sftp.ts
|
|
5685
|
-
init_deploy_artifact_minio();
|
|
5686
5701
|
var SFTP_UPLOAD_MAX_ATTEMPTS = 3;
|
|
5687
5702
|
var SFTP_FAST_PUT_OPTIONS = {
|
|
5688
5703
|
chunkSize: 64 * 1024,
|
|
@@ -6892,9 +6907,6 @@ function printDeployExecutionError(error) {
|
|
|
6892
6907
|
console.error(error.message);
|
|
6893
6908
|
}
|
|
6894
6909
|
|
|
6895
|
-
// src/commands/deploy/platform/deploy-run-coordinator.ts
|
|
6896
|
-
init_deploy_artifact_minio();
|
|
6897
|
-
|
|
6898
6910
|
// src/commands/deploy/platform/deploy-console-capture.ts
|
|
6899
6911
|
function captureDeployConsole(logSyncer) {
|
|
6900
6912
|
const chunks = [];
|
|
@@ -7424,6 +7436,37 @@ var EventSession = class {
|
|
|
7424
7436
|
});
|
|
7425
7437
|
this.markDirty(this.events.length - 1);
|
|
7426
7438
|
}
|
|
7439
|
+
/**
|
|
7440
|
+
* CLI 本地准备步骤(工作区/分支/文档等),写入日志供 WebIDE 查看。
|
|
7441
|
+
* 同名 step 原地更新(进行中→完成合并为一行),终态时写入 durationMs。
|
|
7442
|
+
*/
|
|
7443
|
+
addCliStep(step, text, status = "ok") {
|
|
7444
|
+
const existingIndex = this.events.findIndex(
|
|
7445
|
+
(e) => e.type === "cli_step" && e.step === step
|
|
7446
|
+
);
|
|
7447
|
+
const now = Date.now();
|
|
7448
|
+
if (existingIndex >= 0) {
|
|
7449
|
+
const existing = this.events[existingIndex];
|
|
7450
|
+
existing.status = status;
|
|
7451
|
+
existing.text = text;
|
|
7452
|
+
if (status !== "running") {
|
|
7453
|
+
const startedAt = typeof existing.at === "string" ? Date.parse(existing.at) : NaN;
|
|
7454
|
+
if (Number.isFinite(startedAt)) {
|
|
7455
|
+
existing.durationMs = Math.max(0, now - startedAt);
|
|
7456
|
+
}
|
|
7457
|
+
}
|
|
7458
|
+
this.markDirty(existingIndex);
|
|
7459
|
+
return;
|
|
7460
|
+
}
|
|
7461
|
+
this.events.push({
|
|
7462
|
+
type: "cli_step",
|
|
7463
|
+
step,
|
|
7464
|
+
status,
|
|
7465
|
+
text,
|
|
7466
|
+
at: new Date(now).toISOString()
|
|
7467
|
+
});
|
|
7468
|
+
this.markDirty(this.events.length - 1);
|
|
7469
|
+
}
|
|
7427
7470
|
formatEvent(event) {
|
|
7428
7471
|
switch (event.type) {
|
|
7429
7472
|
case "assistant": {
|
|
@@ -8351,7 +8394,7 @@ async function runCursorAgent(cfg, ctx, options) {
|
|
|
8351
8394
|
customTools,
|
|
8352
8395
|
enableSandbox
|
|
8353
8396
|
});
|
|
8354
|
-
const eventSession = new EventSession(prompt);
|
|
8397
|
+
const eventSession = options?.eventSession ?? new EventSession(prompt);
|
|
8355
8398
|
const syncRemoteLog = options?.createRemoteLogSync ? options.createRemoteLogSync(agent.agentId) : options?.skipRemoteLogSync ? noopRemoteLogSync : createThrottledCursorMessageLogSync(
|
|
8356
8399
|
cfg,
|
|
8357
8400
|
logCtx(ctx, agent.agentId),
|
|
@@ -8630,10 +8673,27 @@ function spawnWebIdeMessageWorker(cfg, msg) {
|
|
|
8630
8673
|
workerData: { cfg, msg }
|
|
8631
8674
|
});
|
|
8632
8675
|
const registry = getWebIdeTerminalRegistry(cfg);
|
|
8676
|
+
let settled = false;
|
|
8633
8677
|
let resolveDone;
|
|
8634
8678
|
const done = new Promise((resolve8) => {
|
|
8635
8679
|
resolveDone = resolve8;
|
|
8636
8680
|
});
|
|
8681
|
+
const failIfStillQueued = async (reason) => {
|
|
8682
|
+
if (settled) return;
|
|
8683
|
+
try {
|
|
8684
|
+
const { createApmApiClient: createApmApiClient2 } = await Promise.resolve().then(() => (init_client(), client_exports));
|
|
8685
|
+
const api = createApmApiClient2(cfg);
|
|
8686
|
+
await api.cli.webideSetMessageError({
|
|
8687
|
+
id: msg.messageId,
|
|
8688
|
+
error: reason
|
|
8689
|
+
});
|
|
8690
|
+
} catch (err) {
|
|
8691
|
+
console.error(
|
|
8692
|
+
`[apm] webide worker \u5931\u8D25\u5199\u7EC8\u6001\u5931\u8D25 messageId=${msg.messageId}:`,
|
|
8693
|
+
err instanceof Error ? err.message : err
|
|
8694
|
+
);
|
|
8695
|
+
}
|
|
8696
|
+
};
|
|
8637
8697
|
worker.on("message", (m) => {
|
|
8638
8698
|
if (m?.type === "terminal-rpc") {
|
|
8639
8699
|
const rpc = m;
|
|
@@ -8693,6 +8753,7 @@ function spawnWebIdeMessageWorker(cfg, msg) {
|
|
|
8693
8753
|
return;
|
|
8694
8754
|
}
|
|
8695
8755
|
if (m?.type === "done" || m?.type === "error") {
|
|
8756
|
+
settled = true;
|
|
8696
8757
|
if (m.type === "error") {
|
|
8697
8758
|
console.error(
|
|
8698
8759
|
`[apm] webide worker error messageId=${m.messageId}: ${m.error}`
|
|
@@ -8703,9 +8764,18 @@ function spawnWebIdeMessageWorker(cfg, msg) {
|
|
|
8703
8764
|
});
|
|
8704
8765
|
worker.on("error", (err) => {
|
|
8705
8766
|
console.error("[apm] webide worker crashed:", err);
|
|
8706
|
-
|
|
8767
|
+
void failIfStillQueued(
|
|
8768
|
+
`WebIDE worker \u5D29\u6E83: ${err instanceof Error ? err.message : String(err)}`
|
|
8769
|
+
).finally(() => resolveDone());
|
|
8707
8770
|
});
|
|
8708
8771
|
worker.on("exit", (code) => {
|
|
8772
|
+
if (!settled && code !== 0) {
|
|
8773
|
+
console.error(`[apm] webide worker exit code=${code}`);
|
|
8774
|
+
void failIfStillQueued(`WebIDE worker \u5F02\u5E38\u9000\u51FA code=${code}`).finally(
|
|
8775
|
+
() => resolveDone()
|
|
8776
|
+
);
|
|
8777
|
+
return;
|
|
8778
|
+
}
|
|
8709
8779
|
if (code !== 0) {
|
|
8710
8780
|
console.error(`[apm] webide worker exit code=${code}`);
|
|
8711
8781
|
}
|
|
@@ -9012,6 +9082,24 @@ function attachWsHandlers(ws, ctx, onOpen) {
|
|
|
9012
9082
|
if (pendingCancels.has(msg2.messageId)) {
|
|
9013
9083
|
activeRuns.delete(msg2.messageId);
|
|
9014
9084
|
pendingCancels.delete(msg2.messageId);
|
|
9085
|
+
const cancelTask = (async () => {
|
|
9086
|
+
try {
|
|
9087
|
+
const api = createApmApiClient(cfg);
|
|
9088
|
+
await api.cli.webideUpdateMessageStatus({
|
|
9089
|
+
id: msg2.messageId,
|
|
9090
|
+
status: "CANCELLED"
|
|
9091
|
+
});
|
|
9092
|
+
} catch (err) {
|
|
9093
|
+
console.error(
|
|
9094
|
+
`[apm] webide-message \u9884\u53D6\u6D88\u5199\u7EC8\u6001\u5931\u8D25 messageId=${msg2.messageId}:`,
|
|
9095
|
+
err instanceof Error ? err.message : err
|
|
9096
|
+
);
|
|
9097
|
+
}
|
|
9098
|
+
})();
|
|
9099
|
+
activeTasks.add(cancelTask);
|
|
9100
|
+
void cancelTask.finally(() => {
|
|
9101
|
+
activeTasks.delete(cancelTask);
|
|
9102
|
+
});
|
|
9015
9103
|
return;
|
|
9016
9104
|
}
|
|
9017
9105
|
const task2 = (async () => {
|
|
@@ -1362,6 +1362,37 @@ var EventSession = class {
|
|
|
1362
1362
|
});
|
|
1363
1363
|
this.markDirty(this.events.length - 1);
|
|
1364
1364
|
}
|
|
1365
|
+
/**
|
|
1366
|
+
* CLI 本地准备步骤(工作区/分支/文档等),写入日志供 WebIDE 查看。
|
|
1367
|
+
* 同名 step 原地更新(进行中→完成合并为一行),终态时写入 durationMs。
|
|
1368
|
+
*/
|
|
1369
|
+
addCliStep(step, text, status = "ok") {
|
|
1370
|
+
const existingIndex = this.events.findIndex(
|
|
1371
|
+
(e) => e.type === "cli_step" && e.step === step
|
|
1372
|
+
);
|
|
1373
|
+
const now = Date.now();
|
|
1374
|
+
if (existingIndex >= 0) {
|
|
1375
|
+
const existing = this.events[existingIndex];
|
|
1376
|
+
existing.status = status;
|
|
1377
|
+
existing.text = text;
|
|
1378
|
+
if (status !== "running") {
|
|
1379
|
+
const startedAt = typeof existing.at === "string" ? Date.parse(existing.at) : NaN;
|
|
1380
|
+
if (Number.isFinite(startedAt)) {
|
|
1381
|
+
existing.durationMs = Math.max(0, now - startedAt);
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
this.markDirty(existingIndex);
|
|
1385
|
+
return;
|
|
1386
|
+
}
|
|
1387
|
+
this.events.push({
|
|
1388
|
+
type: "cli_step",
|
|
1389
|
+
step,
|
|
1390
|
+
status,
|
|
1391
|
+
text,
|
|
1392
|
+
at: new Date(now).toISOString()
|
|
1393
|
+
});
|
|
1394
|
+
this.markDirty(this.events.length - 1);
|
|
1395
|
+
}
|
|
1365
1396
|
formatEvent(event) {
|
|
1366
1397
|
switch (event.type) {
|
|
1367
1398
|
case "assistant": {
|
|
@@ -2360,7 +2391,7 @@ async function runCursorAgent(cfg, ctx, options) {
|
|
|
2360
2391
|
customTools,
|
|
2361
2392
|
enableSandbox
|
|
2362
2393
|
});
|
|
2363
|
-
const eventSession = new EventSession(prompt);
|
|
2394
|
+
const eventSession = options?.eventSession ?? new EventSession(prompt);
|
|
2364
2395
|
const syncRemoteLog = options?.createRemoteLogSync ? options.createRemoteLogSync(agent.agentId) : options?.skipRemoteLogSync ? noopRemoteLogSync : createThrottledCursorMessageLogSync(
|
|
2365
2396
|
cfg,
|
|
2366
2397
|
logCtx(ctx, agent.agentId),
|
|
@@ -2672,9 +2703,27 @@ var MinioClient = class {
|
|
|
2672
2703
|
}
|
|
2673
2704
|
};
|
|
2674
2705
|
|
|
2675
|
-
// src/commands/
|
|
2676
|
-
|
|
2677
|
-
|
|
2706
|
+
// src/commands/connect/apm-log-minio.ts
|
|
2707
|
+
var APM_LOG_MINIO_CONFIG = {
|
|
2708
|
+
endpoint: "objectstorageapi.gzg.sealos.run",
|
|
2709
|
+
port: 443,
|
|
2710
|
+
useSsl: true,
|
|
2711
|
+
accessKey: "428hqav4",
|
|
2712
|
+
secretKey: "68b8srk4vdbjdhlc",
|
|
2713
|
+
bucket: "428hqav4-apm-log"
|
|
2714
|
+
};
|
|
2715
|
+
function createApmLogMinioClient() {
|
|
2716
|
+
const storage = APM_LOG_MINIO_CONFIG;
|
|
2717
|
+
return {
|
|
2718
|
+
client: new MinioClient({
|
|
2719
|
+
endPoint: storage.endpoint,
|
|
2720
|
+
port: storage.port,
|
|
2721
|
+
useSSL: storage.useSsl,
|
|
2722
|
+
accessKey: storage.accessKey,
|
|
2723
|
+
secretKey: storage.secretKey
|
|
2724
|
+
}),
|
|
2725
|
+
bucket: storage.bucket
|
|
2726
|
+
};
|
|
2678
2727
|
}
|
|
2679
2728
|
|
|
2680
2729
|
// src/commands/connect/webide-message-log.ts
|
|
@@ -2707,26 +2756,31 @@ async function upsertLogHeader(cfg, ctx, patch) {
|
|
|
2707
2756
|
...patch
|
|
2708
2757
|
});
|
|
2709
2758
|
}
|
|
2710
|
-
function createThrottledWebIdeMessageLogSync(cfg, ctx, onError) {
|
|
2759
|
+
function createThrottledWebIdeMessageLogSync(cfg, ctx, onError, options) {
|
|
2711
2760
|
let lastRunAt = 0;
|
|
2712
2761
|
let timer;
|
|
2713
2762
|
let latestSession;
|
|
2714
2763
|
let syncChain = Promise.resolve();
|
|
2715
2764
|
let minio;
|
|
2716
2765
|
let bucket = "";
|
|
2766
|
+
let firstLogNotified = false;
|
|
2717
2767
|
const ensureMinio = async () => {
|
|
2718
2768
|
if (minio) return;
|
|
2719
|
-
const
|
|
2720
|
-
minio =
|
|
2721
|
-
|
|
2722
|
-
port: storage.port,
|
|
2723
|
-
useSSL: storage.useSsl,
|
|
2724
|
-
accessKey: storage.accessKey,
|
|
2725
|
-
secretKey: storage.secretKey
|
|
2726
|
-
});
|
|
2727
|
-
bucket = storage.bucket;
|
|
2769
|
+
const created = createApmLogMinioClient();
|
|
2770
|
+
minio = created.client;
|
|
2771
|
+
bucket = created.bucket;
|
|
2728
2772
|
await minio.ensureBucket(bucket);
|
|
2729
2773
|
};
|
|
2774
|
+
const notifyFirstLog = async () => {
|
|
2775
|
+
if (firstLogNotified) return;
|
|
2776
|
+
firstLogNotified = true;
|
|
2777
|
+
try {
|
|
2778
|
+
await options?.onFirstLogSynced?.();
|
|
2779
|
+
} catch (err) {
|
|
2780
|
+
firstLogNotified = false;
|
|
2781
|
+
onError(err);
|
|
2782
|
+
}
|
|
2783
|
+
};
|
|
2730
2784
|
const syncDirtyEventsOnce = async (session) => {
|
|
2731
2785
|
const events = session.getDirtyEvents();
|
|
2732
2786
|
if (events.length === 0) return;
|
|
@@ -2739,6 +2793,7 @@ function createThrottledWebIdeMessageLogSync(cfg, ctx, onError) {
|
|
|
2739
2793
|
eventCount: session.getEventCount()
|
|
2740
2794
|
});
|
|
2741
2795
|
session.clearDirtyIfUnchanged(events);
|
|
2796
|
+
await notifyFirstLog();
|
|
2742
2797
|
} catch (err) {
|
|
2743
2798
|
onError(err);
|
|
2744
2799
|
}
|
|
@@ -3768,98 +3823,189 @@ async function handleWebIdeInboundMessage(cfg, msg, signal, options) {
|
|
|
3768
3823
|
`[apm] webide-message action=${msg.action} taskId=${taskId} messageId=${messageId}`
|
|
3769
3824
|
);
|
|
3770
3825
|
await updateStatus(cfg, messageId, "TYPING");
|
|
3826
|
+
const eventSession = new EventSession(msg.content);
|
|
3827
|
+
const prepAgentId = loadWebIdeAgentId(workdir, taskId) ?? "webide-cli-prep";
|
|
3828
|
+
const logSyncRef = {
|
|
3829
|
+
current: createThrottledWebIdeMessageLogSync(
|
|
3830
|
+
cfg,
|
|
3831
|
+
{ taskId, messageId, agentId: prepAgentId },
|
|
3832
|
+
(err) => {
|
|
3833
|
+
console.warn(
|
|
3834
|
+
"[apm] WebIDE \u65E5\u5FD7\u540C\u6B65\u5931\u8D25:",
|
|
3835
|
+
err instanceof Error ? err.message : err
|
|
3836
|
+
);
|
|
3837
|
+
}
|
|
3838
|
+
)
|
|
3839
|
+
};
|
|
3840
|
+
const syncPrepLog = async () => {
|
|
3841
|
+
const sync = logSyncRef.current;
|
|
3842
|
+
if (!sync) return;
|
|
3843
|
+
sync.schedule(eventSession);
|
|
3844
|
+
await sync.flush(eventSession);
|
|
3845
|
+
};
|
|
3846
|
+
const runPrepStep = async (step, work, formatOk) => {
|
|
3847
|
+
eventSession.addCliStep(step, "\u8FDB\u884C\u4E2D\u2026", "running");
|
|
3848
|
+
await syncPrepLog();
|
|
3849
|
+
try {
|
|
3850
|
+
const result = await work();
|
|
3851
|
+
eventSession.addCliStep(step, formatOk(result), "ok");
|
|
3852
|
+
await syncPrepLog();
|
|
3853
|
+
return result;
|
|
3854
|
+
} catch (err) {
|
|
3855
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
3856
|
+
eventSession.addCliStep(step, detail, "error");
|
|
3857
|
+
await syncPrepLog();
|
|
3858
|
+
throw err;
|
|
3859
|
+
}
|
|
3860
|
+
};
|
|
3771
3861
|
try {
|
|
3772
3862
|
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3863
|
+
await runPrepStep(
|
|
3864
|
+
"\u521D\u59CB\u5316\u5DE5\u4F5C\u533A",
|
|
3865
|
+
async () => {
|
|
3866
|
+
const { didInit } = await ensureWorkspaceInitialized(workdir);
|
|
3867
|
+
if (!didInit) {
|
|
3868
|
+
assertApmGitignoredInRepo(workdir);
|
|
3869
|
+
}
|
|
3870
|
+
return didInit;
|
|
3871
|
+
},
|
|
3872
|
+
(didInit) => didInit ? "\u5DF2\u521D\u59CB\u5316\u5DE5\u4F5C\u533A" : "\u5DE5\u4F5C\u533A\u5DF2\u5C31\u7EEA"
|
|
3873
|
+
);
|
|
3777
3874
|
const cliVersion = readCliVersion();
|
|
3778
3875
|
if (shouldSyncSkillsForCliVersion(workdir, cliVersion)) {
|
|
3779
3876
|
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
3780
|
-
|
|
3781
|
-
|
|
3877
|
+
await runPrepStep(
|
|
3878
|
+
"\u540C\u6B65 Skills",
|
|
3879
|
+
async () => {
|
|
3880
|
+
await syncWorkspaceSkills(cfg, workdir);
|
|
3881
|
+
markSkillsSyncedForCliVersion(workdir, cliVersion);
|
|
3882
|
+
return cliVersion;
|
|
3883
|
+
},
|
|
3884
|
+
(version) => `\u5DF2\u540C\u6B65\u81F3 CLI ${version}`
|
|
3782
3885
|
);
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
await enrichWorkspaceReposRemoteUrls(workspaceRepos);
|
|
3789
|
-
} catch (err) {
|
|
3790
|
-
console.warn(
|
|
3791
|
-
"[apm] \u8865\u9F50 workspace-repos remoteUrl \u5931\u8D25:",
|
|
3792
|
-
err instanceof Error ? err.message : err
|
|
3886
|
+
} else {
|
|
3887
|
+
eventSession.addCliStep(
|
|
3888
|
+
"\u540C\u6B65 Skills",
|
|
3889
|
+
`\u7248\u672C\u4E00\u81F4\uFF08${cliVersion}\uFF09\uFF0C\u8DF3\u8FC7`,
|
|
3890
|
+
"skip"
|
|
3793
3891
|
);
|
|
3892
|
+
await syncPrepLog();
|
|
3794
3893
|
}
|
|
3894
|
+
await runPrepStep(
|
|
3895
|
+
"\u5DE5\u4F5C\u533A\u4ED3\u5E93\u6E05\u5355",
|
|
3896
|
+
async () => {
|
|
3897
|
+
const workspaceRepos = resolveWorkspaceRepos(workdir);
|
|
3898
|
+
try {
|
|
3899
|
+
await enrichWorkspaceReposRemoteUrls(workspaceRepos);
|
|
3900
|
+
} catch (err) {
|
|
3901
|
+
console.warn(
|
|
3902
|
+
"[apm] \u8865\u9F50 workspace-repos remoteUrl \u5931\u8D25:",
|
|
3903
|
+
err instanceof Error ? err.message : err
|
|
3904
|
+
);
|
|
3905
|
+
}
|
|
3906
|
+
return workspaceRepos;
|
|
3907
|
+
},
|
|
3908
|
+
(repos) => `kind=${repos.kind} repos=${repos.repos.length}`
|
|
3909
|
+
);
|
|
3795
3910
|
if (shouldRunBranch(branchCacheKey, workdir)) {
|
|
3796
3911
|
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3912
|
+
await runPrepStep(
|
|
3913
|
+
"\u51C6\u5907\u7279\u6027\u5206\u652F",
|
|
3914
|
+
async () => runTaskBranch(taskId, { cwd: workdir }),
|
|
3915
|
+
(branchResult) => {
|
|
3916
|
+
markBranchDone(branchCacheKey, workdir);
|
|
3917
|
+
return `kind=${branchResult.kind} branch=${branchResult.branch} repos=${branchResult.repos.length}`;
|
|
3918
|
+
}
|
|
3801
3919
|
);
|
|
3802
3920
|
} else {
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
);
|
|
3921
|
+
eventSession.addCliStep("\u51C6\u5907\u7279\u6027\u5206\u652F", "\u5DF2\u7F13\u5B58\uFF0C\u8DF3\u8FC7", "skip");
|
|
3922
|
+
await syncPrepLog();
|
|
3806
3923
|
}
|
|
3807
3924
|
if (shouldEnsureWebIdePullRequests(msg.action)) {
|
|
3808
3925
|
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3926
|
+
await runPrepStep(
|
|
3927
|
+
"\u6D4B\u8BD5\u524D\u63A8\u9001",
|
|
3928
|
+
async () => pushWorkspaceRepos(workdir),
|
|
3929
|
+
(pushed) => `\u5DF2 push ${pushed} \u4E2A\u4ED3\u5E93`
|
|
3812
3930
|
);
|
|
3813
3931
|
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
3814
|
-
await
|
|
3932
|
+
await runPrepStep(
|
|
3933
|
+
"\u786E\u4FDD PR",
|
|
3934
|
+
async () => {
|
|
3935
|
+
await ensureWebIdePullRequests(cfg, taskId, workdir);
|
|
3936
|
+
return true;
|
|
3937
|
+
},
|
|
3938
|
+
() => "PR \u68C0\u67E5\u5B8C\u6210"
|
|
3939
|
+
);
|
|
3815
3940
|
}
|
|
3816
3941
|
if (signal.aborted) throw new Error("\u4EFB\u52A1\u5DF2\u53D6\u6D88");
|
|
3817
3942
|
const api = createApmApiClient(cfg);
|
|
3818
3943
|
let projectId = null;
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
projectId
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3944
|
+
await runPrepStep(
|
|
3945
|
+
"\u540C\u6B65\u9879\u76EE\u6587\u6863",
|
|
3946
|
+
async () => {
|
|
3947
|
+
try {
|
|
3948
|
+
const baseline = await api.cli.projectBaseBranch({ taskId });
|
|
3949
|
+
projectId = baseline.projectId?.trim() || null;
|
|
3950
|
+
if (!projectId) {
|
|
3951
|
+
return { synced: false, reason: "\u65E0 projectId" };
|
|
3952
|
+
}
|
|
3953
|
+
const docs = await syncProjectDocumentsPull(workdir, void 0, {
|
|
3954
|
+
projectId
|
|
3955
|
+
});
|
|
3956
|
+
return {
|
|
3957
|
+
synced: docs.synced,
|
|
3958
|
+
downloaded: docs.downloaded,
|
|
3959
|
+
deleted: docs.deleted
|
|
3960
|
+
};
|
|
3961
|
+
} catch (err) {
|
|
3962
|
+
console.warn(
|
|
3963
|
+
"[apm] WebIDE \u9879\u76EE\u6587\u6863\u540C\u6B65\u5931\u8D25:",
|
|
3964
|
+
err instanceof Error ? err.message : err
|
|
3829
3965
|
);
|
|
3966
|
+
return {
|
|
3967
|
+
synced: false,
|
|
3968
|
+
reason: err instanceof Error ? err.message : String(err)
|
|
3969
|
+
};
|
|
3830
3970
|
}
|
|
3831
|
-
}
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
"[apm] WebIDE \u9879\u76EE\u6587\u6863\u540C\u6B65\u5931\u8D25:",
|
|
3839
|
-
err instanceof Error ? err.message : err
|
|
3840
|
-
);
|
|
3841
|
-
}
|
|
3842
|
-
try {
|
|
3843
|
-
const attachments = await api.cli.webideListAttachments({ taskId });
|
|
3844
|
-
const names = await syncWebIdeAttachments(
|
|
3845
|
-
cfg,
|
|
3846
|
-
taskId,
|
|
3847
|
-
workdir,
|
|
3848
|
-
attachments ?? []
|
|
3849
|
-
);
|
|
3850
|
-
if (names.length > 0) {
|
|
3851
|
-
console.log(
|
|
3852
|
-
`[apm] webide \u9644\u4EF6\u5DF2\u5C31\u7EEA count=${names.length} dir=.apm/webide/${taskId}/attachments`
|
|
3853
|
-
);
|
|
3971
|
+
},
|
|
3972
|
+
(result) => {
|
|
3973
|
+
if ("reason" in result && result.reason) {
|
|
3974
|
+
return `\u8DF3\u8FC7\uFF1A${result.reason}`;
|
|
3975
|
+
}
|
|
3976
|
+
if (!result.synced) return "\u65E0\u9700\u540C\u6B65";
|
|
3977
|
+
return `downloaded=${result.downloaded ?? 0} deleted=${result.deleted ?? 0}`;
|
|
3854
3978
|
}
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3979
|
+
);
|
|
3980
|
+
await runPrepStep(
|
|
3981
|
+
"\u540C\u6B65\u4EFB\u52A1\u9644\u4EF6",
|
|
3982
|
+
async () => {
|
|
3983
|
+
try {
|
|
3984
|
+
const attachments = await api.cli.webideListAttachments({ taskId });
|
|
3985
|
+
const names = await syncWebIdeAttachments(
|
|
3986
|
+
cfg,
|
|
3987
|
+
taskId,
|
|
3988
|
+
workdir,
|
|
3989
|
+
attachments ?? []
|
|
3990
|
+
);
|
|
3991
|
+
return names;
|
|
3992
|
+
} catch (err) {
|
|
3993
|
+
console.warn(
|
|
3994
|
+
"[apm] WebIDE \u9644\u4EF6\u540C\u6B65\u5931\u8D25:",
|
|
3995
|
+
err instanceof Error ? err.message : err
|
|
3996
|
+
);
|
|
3997
|
+
return [];
|
|
3998
|
+
}
|
|
3999
|
+
},
|
|
4000
|
+
(names) => names.length > 0 ? `\u5DF2\u540C\u6B65 ${names.length} \u4E2A\u9644\u4EF6` : "\u65E0\u9644\u4EF6\u6216\u540C\u6B65\u8DF3\u8FC7"
|
|
4001
|
+
);
|
|
4002
|
+
eventSession.addCliStep(
|
|
4003
|
+
"\u542F\u52A8 Cursor Agent",
|
|
4004
|
+
"\u51C6\u5907 resume/create\u2026",
|
|
4005
|
+
"running"
|
|
4006
|
+
);
|
|
4007
|
+
await syncPrepLog();
|
|
3861
4008
|
const savedAgentId = loadWebIdeAgentId(workdir, taskId);
|
|
3862
|
-
const logSyncRef = { current: null };
|
|
3863
4009
|
const outcome = await runCursorAgent(
|
|
3864
4010
|
cfg,
|
|
3865
4011
|
{
|
|
@@ -3874,8 +4020,8 @@ async function handleWebIdeInboundMessage(cfg, msg, signal, options) {
|
|
|
3874
4020
|
},
|
|
3875
4021
|
{
|
|
3876
4022
|
signal,
|
|
3877
|
-
// IDE 重启/异常中断后 Cursor 可能仍认为旧 run active;强制清残留再 send
|
|
3878
4023
|
forceSend: true,
|
|
4024
|
+
eventSession,
|
|
3879
4025
|
appendMessageContent: (content) => appendContent(cfg, messageId, content),
|
|
3880
4026
|
askQuestionExecute: createWebIdeAskQuestionExecute({
|
|
3881
4027
|
cfg,
|
|
@@ -3883,7 +4029,6 @@ async function handleWebIdeInboundMessage(cfg, msg, signal, options) {
|
|
|
3883
4029
|
signal
|
|
3884
4030
|
}),
|
|
3885
4031
|
enableWebIdePlanTools: true,
|
|
3886
|
-
// 本地 SDK sandbox 会拦截 custom-user-tools MCP,WebIDE 先关闭
|
|
3887
4032
|
enableSandbox: false,
|
|
3888
4033
|
taskId,
|
|
3889
4034
|
terminalRpc: options?.terminalRpc,
|
|
@@ -3903,7 +4048,14 @@ async function handleWebIdeInboundMessage(cfg, msg, signal, options) {
|
|
|
3903
4048
|
},
|
|
3904
4049
|
onRunStarted: async ({ agentId, runId }) => {
|
|
3905
4050
|
saveWebIdeAgentId(workdir, taskId, agentId);
|
|
4051
|
+
eventSession.addCliStep(
|
|
4052
|
+
"\u542F\u52A8 Cursor Agent",
|
|
4053
|
+
`agentId=${agentId} runId=${runId}`,
|
|
4054
|
+
"ok"
|
|
4055
|
+
);
|
|
4056
|
+
logSyncRef.current?.schedule(eventSession);
|
|
3906
4057
|
await logSyncRef.current?.markRun(runId, "running");
|
|
4058
|
+
await logSyncRef.current?.flush(eventSession);
|
|
3907
4059
|
}
|
|
3908
4060
|
}
|
|
3909
4061
|
);
|