ai-project-manage-cli 8.1.20 → 8.1.21
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 +18 -2
- package/dist/index.js +148 -161
- package/dist/worker-script.js +2777 -3445
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,7 +13,14 @@ apm update
|
|
|
13
13
|
## 登录
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
|
|
16
|
+
# 历史兼容:只传一个带端口的 --server → Socket 用该地址,API 去掉端口
|
|
17
|
+
apm login --api-key=cm_xxx --server=https://api.example.com:3334
|
|
18
|
+
# → API https://api.example.com ,Socket wss://api.example.com:3334
|
|
19
|
+
|
|
20
|
+
# 现在:分别传 API 与 Socket(也可用 APM_SERVER / APM_SOCKET_SERVER)
|
|
21
|
+
apm login --api-key=cm_xxx \
|
|
22
|
+
--server=https://api.example.com \
|
|
23
|
+
--socket-server=wss://ws.example.com
|
|
17
24
|
```
|
|
18
25
|
|
|
19
26
|
## 初始化工作区
|
|
@@ -36,9 +43,18 @@ apm update-skills
|
|
|
36
43
|
|
|
37
44
|
```bash
|
|
38
45
|
apm connect
|
|
39
|
-
|
|
46
|
+
# 历史兼容
|
|
47
|
+
apm connect --server https://api.example.com:3334
|
|
48
|
+
# 分别指定
|
|
49
|
+
apm connect --server https://api.example.com --socket-server wss://ws.example.com
|
|
40
50
|
```
|
|
41
51
|
|
|
52
|
+
地址解析:
|
|
53
|
+
|
|
54
|
+
- **历史**:只传 `--server https://host:port` → Socket 用该地址,API 为去掉端口后的 `https://host`
|
|
55
|
+
- **现在**:`--server` + `--socket-server`,或环境变量 `APM_SERVER` + `APM_SOCKET_SERVER`
|
|
56
|
+
- 登录成功后写入 `~/.config/apm/config.json` 的 `baseUrl` / `socketServer`
|
|
57
|
+
|
|
42
58
|
启动前会检测 npm registry 上当前大版本的最新包;若落后则先 `npm install -g` 更新,再以新版本重新连接。跨大版本请手动执行 `apm update --major`。
|
|
43
59
|
|
|
44
60
|
同一时刻仅允许一个 connect。
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,15 @@ function resolveClientMachineId(cfg) {
|
|
|
16
16
|
function resolveApiKey(cfg) {
|
|
17
17
|
return (cfg.apiKey ?? cfg.token ?? "").trim();
|
|
18
18
|
}
|
|
19
|
+
function stripTrailingSlash(raw) {
|
|
20
|
+
return raw.trim().replace(/\/+$/, "");
|
|
21
|
+
}
|
|
22
|
+
function readConfigSocketServer(cfg) {
|
|
23
|
+
const fromNew = typeof cfg.socketServer === "string" ? cfg.socketServer.trim().replace(/\/+$/, "") : "";
|
|
24
|
+
if (fromNew) return fromNew;
|
|
25
|
+
const fromLegacy = typeof cfg.wsUrl === "string" ? cfg.wsUrl.trim().replace(/\/+$/, "") : "";
|
|
26
|
+
return fromLegacy;
|
|
27
|
+
}
|
|
19
28
|
function tryReadApmConfig() {
|
|
20
29
|
try {
|
|
21
30
|
const raw = readFileSync(APM_CONFIG_PATH, "utf8");
|
|
@@ -31,10 +40,12 @@ function tryReadApmConfig() {
|
|
|
31
40
|
if (!apiKey) return null;
|
|
32
41
|
const cfg = v;
|
|
33
42
|
const clientMachineId = resolveClientMachineId(cfg);
|
|
43
|
+
const socketServer = readConfigSocketServer(cfg);
|
|
34
44
|
return {
|
|
35
45
|
baseUrl: cfg.baseUrl.trim().replace(/\/+$/, ""),
|
|
36
46
|
apiKey,
|
|
37
|
-
...clientMachineId ? { clientMachineId } : {}
|
|
47
|
+
...clientMachineId ? { clientMachineId } : {},
|
|
48
|
+
...socketServer ? { socketServer } : {}
|
|
38
49
|
};
|
|
39
50
|
} catch {
|
|
40
51
|
return null;
|
|
@@ -47,11 +58,80 @@ function defaultApmConfig() {
|
|
|
47
58
|
apiKey: ""
|
|
48
59
|
};
|
|
49
60
|
}
|
|
50
|
-
function
|
|
51
|
-
const u =
|
|
61
|
+
function assertHttpBase(raw, label) {
|
|
62
|
+
const u = stripTrailingSlash(raw);
|
|
63
|
+
if (!u.startsWith("https://") && !u.startsWith("http://")) {
|
|
64
|
+
throw new Error(`${label} \u5FC5\u987B\u4EE5 http:// \u6216 https:// \u5F00\u5934`);
|
|
65
|
+
}
|
|
66
|
+
return new URL(u).origin;
|
|
67
|
+
}
|
|
68
|
+
function normalizeSocketBase(raw) {
|
|
69
|
+
const u = stripTrailingSlash(raw);
|
|
70
|
+
if (u.startsWith("https://") || u.startsWith("http://") || u.startsWith("wss://") || u.startsWith("ws://")) {
|
|
71
|
+
return new URL(u).origin;
|
|
72
|
+
}
|
|
73
|
+
throw new Error(
|
|
74
|
+
"socket server \u5FC5\u987B\u4EE5 http://\u3001https://\u3001ws:// \u6216 wss:// \u5F00\u5934"
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
function httpBaseToWsOrigin(httpOrWsBase) {
|
|
78
|
+
const u = stripTrailingSlash(httpOrWsBase);
|
|
79
|
+
if (u.startsWith("wss://") || u.startsWith("ws://")) return u;
|
|
52
80
|
if (u.startsWith("https://")) return "wss://" + u.slice("https://".length);
|
|
53
81
|
if (u.startsWith("http://")) return "ws://" + u.slice("http://".length);
|
|
54
|
-
throw new Error("
|
|
82
|
+
throw new Error("socket server \u5FC5\u987B\u4EE5 http(s):// \u6216 ws(s):// \u5F00\u5934");
|
|
83
|
+
}
|
|
84
|
+
function splitHistoricalServer(server) {
|
|
85
|
+
const url = new URL(assertHttpBase(server, "server"));
|
|
86
|
+
const socketServer = url.origin;
|
|
87
|
+
if (url.port) {
|
|
88
|
+
url.port = "";
|
|
89
|
+
return { baseUrl: url.origin, socketServer };
|
|
90
|
+
}
|
|
91
|
+
return { baseUrl: url.origin, socketServer: url.origin };
|
|
92
|
+
}
|
|
93
|
+
function resolveApmEndpoints(input = {}) {
|
|
94
|
+
const serverOpt = stripTrailingSlash(
|
|
95
|
+
input.server?.trim() || process.env.APM_SERVER?.trim() || ""
|
|
96
|
+
);
|
|
97
|
+
const socketOpt = stripTrailingSlash(
|
|
98
|
+
input.socketServer?.trim() || process.env.APM_SOCKET_SERVER?.trim() || ""
|
|
99
|
+
);
|
|
100
|
+
const configBase = stripTrailingSlash(input.configBaseUrl?.trim() || "");
|
|
101
|
+
const configSocket = stripTrailingSlash(
|
|
102
|
+
input.configSocketServer?.trim() || ""
|
|
103
|
+
);
|
|
104
|
+
if (serverOpt && socketOpt) {
|
|
105
|
+
return {
|
|
106
|
+
baseUrl: assertHttpBase(serverOpt, "server"),
|
|
107
|
+
socketServer: normalizeSocketBase(socketOpt)
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
if (serverOpt) {
|
|
111
|
+
return splitHistoricalServer(serverOpt);
|
|
112
|
+
}
|
|
113
|
+
if (configBase && socketOpt) {
|
|
114
|
+
return {
|
|
115
|
+
baseUrl: assertHttpBase(configBase, "baseUrl"),
|
|
116
|
+
socketServer: normalizeSocketBase(socketOpt)
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
if (configBase && configSocket) {
|
|
120
|
+
return {
|
|
121
|
+
baseUrl: assertHttpBase(configBase, "baseUrl"),
|
|
122
|
+
socketServer: normalizeSocketBase(configSocket)
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
if (configBase) {
|
|
126
|
+
return splitHistoricalServer(configBase);
|
|
127
|
+
}
|
|
128
|
+
if (socketOpt) {
|
|
129
|
+
return {
|
|
130
|
+
baseUrl: assertHttpBase(DEFAULT_BASE_URL, "server"),
|
|
131
|
+
socketServer: normalizeSocketBase(socketOpt)
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
return splitHistoricalServer(DEFAULT_BASE_URL);
|
|
55
135
|
}
|
|
56
136
|
async function ensureApmConfig() {
|
|
57
137
|
const existing = await tryReadApmConfig();
|
|
@@ -63,20 +143,25 @@ async function ensureApmConfig() {
|
|
|
63
143
|
async function writeApmConfig(cfg) {
|
|
64
144
|
const clientMachineId = resolveClientMachineId(cfg);
|
|
65
145
|
const apiKey = resolveApiKey(cfg);
|
|
146
|
+
const socketServer = stripTrailingSlash(
|
|
147
|
+
cfg.socketServer?.trim() || cfg.wsUrl?.trim() || ""
|
|
148
|
+
);
|
|
66
149
|
const normalized = {
|
|
67
150
|
baseUrl: cfg.baseUrl.trim().replace(/\/+$/, ""),
|
|
68
151
|
apiKey,
|
|
69
|
-
...clientMachineId ? { clientMachineId } : {}
|
|
152
|
+
...clientMachineId ? { clientMachineId } : {},
|
|
153
|
+
...socketServer ? { socketServer } : {}
|
|
70
154
|
};
|
|
71
155
|
mkdirSync(APM_CONFIG_DIR, { recursive: true });
|
|
72
156
|
writeFileSync(APM_CONFIG_PATH, JSON.stringify(normalized, null, 2) + "\n", {
|
|
73
157
|
mode: 384
|
|
74
158
|
});
|
|
75
159
|
}
|
|
76
|
-
function buildAgentWsUrl(
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
160
|
+
function buildAgentWsUrl(socketServer, apiKey) {
|
|
161
|
+
const url = new URL(httpBaseToWsOrigin(socketServer));
|
|
162
|
+
url.pathname = "/ws/agent";
|
|
163
|
+
url.search = new URLSearchParams({ apiKey }).toString();
|
|
164
|
+
return url.toString();
|
|
80
165
|
}
|
|
81
166
|
|
|
82
167
|
// src/commands/sync-webide-agent.ts
|
|
@@ -224,18 +309,6 @@ var requestConfig = {
|
|
|
224
309
|
method: "GET",
|
|
225
310
|
path: "/cli/apm-log-storage"
|
|
226
311
|
}),
|
|
227
|
-
projectPackageUpdateStatus: defineEndpoint({
|
|
228
|
-
method: "PUT",
|
|
229
|
-
path: "/cli/project-packages/status"
|
|
230
|
-
}),
|
|
231
|
-
projectPackageAppendContent: defineEndpoint({
|
|
232
|
-
method: "PUT",
|
|
233
|
-
path: "/cli/project-packages/content"
|
|
234
|
-
}),
|
|
235
|
-
projectPackageEnsureContent: defineEndpoint({
|
|
236
|
-
method: "PUT",
|
|
237
|
-
path: "/cli/project-packages/ensure-content"
|
|
238
|
-
}),
|
|
239
312
|
cursorStoreUpsertAgent: defineEndpoint({
|
|
240
313
|
method: "PUT",
|
|
241
314
|
path: "/cli/cursor-store/agents"
|
|
@@ -453,15 +526,20 @@ async function runInit() {
|
|
|
453
526
|
// src/commands/login.ts
|
|
454
527
|
import { ApiError } from "listpage-http";
|
|
455
528
|
async function runLogin(opts) {
|
|
456
|
-
const
|
|
529
|
+
const endpoints = resolveApmEndpoints({
|
|
530
|
+
server: opts.server,
|
|
531
|
+
socketServer: opts.socketServer
|
|
532
|
+
});
|
|
457
533
|
const apiKey = (opts.apiKey?.trim() || process.env.APM_API_KEY?.trim() || "").replace(/^Bearer\s+/i, "");
|
|
458
534
|
if (!apiKey.startsWith("cm_")) {
|
|
459
535
|
console.error("[apm] \u8BF7\u63D0\u4F9B\u6709\u6548\u7684 API Key\uFF08cm_ \u5F00\u5934\uFF09");
|
|
460
|
-
console.error(
|
|
536
|
+
console.error(
|
|
537
|
+
"[apm] \u7528\u6CD5: apm login --api-key cm_xxx [--server URL] [--socket-server URL]"
|
|
538
|
+
);
|
|
461
539
|
process.exit(1);
|
|
462
540
|
}
|
|
463
541
|
const api = createApmApiClient({
|
|
464
|
-
baseUrl,
|
|
542
|
+
baseUrl: endpoints.baseUrl,
|
|
465
543
|
clientMachineId: "",
|
|
466
544
|
apiKey
|
|
467
545
|
});
|
|
@@ -486,7 +564,8 @@ async function runLogin(opts) {
|
|
|
486
564
|
process.exit(1);
|
|
487
565
|
}
|
|
488
566
|
const cfg = {
|
|
489
|
-
baseUrl,
|
|
567
|
+
baseUrl: endpoints.baseUrl,
|
|
568
|
+
socketServer: endpoints.socketServer,
|
|
490
569
|
clientMachineId,
|
|
491
570
|
apiKey
|
|
492
571
|
};
|
|
@@ -497,7 +576,8 @@ async function runLogin(opts) {
|
|
|
497
576
|
{
|
|
498
577
|
clientMachineId: cfg.clientMachineId,
|
|
499
578
|
clientName: data.clientName,
|
|
500
|
-
baseUrl: cfg.baseUrl
|
|
579
|
+
baseUrl: cfg.baseUrl,
|
|
580
|
+
socketServer: cfg.socketServer
|
|
501
581
|
},
|
|
502
582
|
null,
|
|
503
583
|
2
|
|
@@ -712,6 +792,10 @@ function reexecConnectAfterUpdate(options) {
|
|
|
712
792
|
if (server) {
|
|
713
793
|
args.push("--server", server);
|
|
714
794
|
}
|
|
795
|
+
const socketServer = options.socketServer?.trim();
|
|
796
|
+
if (socketServer) {
|
|
797
|
+
args.push("--socket-server", socketServer);
|
|
798
|
+
}
|
|
715
799
|
const result = spawnSync(process.execPath, args, {
|
|
716
800
|
stdio: "inherit",
|
|
717
801
|
env: { ...process.env, [APM_SKIP_SELF_UPDATE_ENV]: "1" }
|
|
@@ -1108,9 +1192,6 @@ import { setTimeout as delay } from "node:timers/promises";
|
|
|
1108
1192
|
function isWebIdeStartProjectTarget(value) {
|
|
1109
1193
|
return value === "frontend" || value === "backend" || value === "mobile";
|
|
1110
1194
|
}
|
|
1111
|
-
function isWebIdePackageTarget(value) {
|
|
1112
|
-
return value === "frontend" || value === "backend";
|
|
1113
|
-
}
|
|
1114
1195
|
function nonEmptyString(v) {
|
|
1115
1196
|
return typeof v === "string" && v.trim().length > 0;
|
|
1116
1197
|
}
|
|
@@ -1270,64 +1351,13 @@ function validateWebIdeStartProjectPush(o) {
|
|
|
1270
1351
|
}
|
|
1271
1352
|
};
|
|
1272
1353
|
}
|
|
1273
|
-
function validateWebIdePackagePush(o) {
|
|
1274
|
-
if (o.type !== "webide-package") {
|
|
1275
|
-
return { ok: false, reason: "\u671F\u671B webide-package" };
|
|
1276
|
-
}
|
|
1277
|
-
if (!nonEmptyString(o.packageId)) {
|
|
1278
|
-
return { ok: false, reason: "webide-package \u7F3A\u5C11 packageId" };
|
|
1279
|
-
}
|
|
1280
|
-
if (!nonEmptyString(o.messageId)) {
|
|
1281
|
-
return { ok: false, reason: "webide-package \u7F3A\u5C11 messageId" };
|
|
1282
|
-
}
|
|
1283
|
-
if (!nonEmptyString(o.projectId)) {
|
|
1284
|
-
return { ok: false, reason: "webide-package \u7F3A\u5C11 projectId" };
|
|
1285
|
-
}
|
|
1286
|
-
if (!isWebIdePackageTarget(o.target)) {
|
|
1287
|
-
return { ok: false, reason: "webide-package \u7F3A\u5C11\u6709\u6548 target" };
|
|
1288
|
-
}
|
|
1289
|
-
if (!nonEmptyString(o.baseBranch)) {
|
|
1290
|
-
return { ok: false, reason: "webide-package \u7F3A\u5C11 baseBranch" };
|
|
1291
|
-
}
|
|
1292
|
-
if (!nonEmptyString(o.content)) {
|
|
1293
|
-
return { ok: false, reason: "webide-package \u7F3A\u5C11 content" };
|
|
1294
|
-
}
|
|
1295
|
-
if (!nonEmptyString(o.model)) {
|
|
1296
|
-
return { ok: false, reason: "webide-package \u7F3A\u5C11 model" };
|
|
1297
|
-
}
|
|
1298
|
-
if (!nonEmptyString(o.apiKey)) {
|
|
1299
|
-
return { ok: false, reason: "webide-package \u7F3A\u5C11 apiKey" };
|
|
1300
|
-
}
|
|
1301
|
-
if (!nonEmptyString(o.workdir)) {
|
|
1302
|
-
return { ok: false, reason: "webide-package \u7F3A\u5C11 workdir" };
|
|
1303
|
-
}
|
|
1304
|
-
if (!nonEmptyString(o.user)) {
|
|
1305
|
-
return { ok: false, reason: "webide-package \u7F3A\u5C11 user" };
|
|
1306
|
-
}
|
|
1307
|
-
return {
|
|
1308
|
-
ok: true,
|
|
1309
|
-
data: {
|
|
1310
|
-
type: "webide-package",
|
|
1311
|
-
packageId: o.packageId.trim(),
|
|
1312
|
-
messageId: o.messageId.trim(),
|
|
1313
|
-
projectId: o.projectId.trim(),
|
|
1314
|
-
target: o.target,
|
|
1315
|
-
baseBranch: o.baseBranch.trim().replace(/^origin\//, ""),
|
|
1316
|
-
content: o.content,
|
|
1317
|
-
model: o.model.trim(),
|
|
1318
|
-
apiKey: o.apiKey.trim(),
|
|
1319
|
-
workdir: o.workdir.trim(),
|
|
1320
|
-
user: o.user.trim()
|
|
1321
|
-
}
|
|
1322
|
-
};
|
|
1323
|
-
}
|
|
1324
1354
|
function validateAgentWsMessage(value, kind) {
|
|
1325
1355
|
if (typeof value !== "object" || value === null) {
|
|
1326
1356
|
return { ok: false, reason: "\u6D88\u606F\u4F53\u4E0D\u662F JSON \u5BF9\u8C61" };
|
|
1327
1357
|
}
|
|
1328
1358
|
const o = value;
|
|
1329
1359
|
const type = o.type;
|
|
1330
|
-
if (type !== "heartbeat" && type !== "webide-message" && type !== "cancel" && type !== "steer" && type !== "webide-start-project" && type !== "webide-stop-terminals"
|
|
1360
|
+
if (type !== "heartbeat" && type !== "webide-message" && type !== "cancel" && type !== "steer" && type !== "webide-start-project" && type !== "webide-stop-terminals") {
|
|
1331
1361
|
return { ok: false, reason: `\u672A\u77E5 type: ${String(type)}` };
|
|
1332
1362
|
}
|
|
1333
1363
|
if (kind === "heartbeat" || type === "heartbeat") {
|
|
@@ -1345,9 +1375,6 @@ function validateAgentWsMessage(value, kind) {
|
|
|
1345
1375
|
if (type === "webide-stop-terminals") {
|
|
1346
1376
|
return validateWebIdeStopTerminals(o);
|
|
1347
1377
|
}
|
|
1348
|
-
if (type === "webide-package") {
|
|
1349
|
-
return validateWebIdePackagePush(o);
|
|
1350
|
-
}
|
|
1351
1378
|
return validateWebIdeMessagePush(o);
|
|
1352
1379
|
}
|
|
1353
1380
|
|
|
@@ -1485,14 +1512,6 @@ var ActionWorker = class {
|
|
|
1485
1512
|
failIfStillQueued = async (reason) => {
|
|
1486
1513
|
if (this.status !== "pending") return;
|
|
1487
1514
|
try {
|
|
1488
|
-
if (this.msg.type === "webide-package") {
|
|
1489
|
-
await this.apmClient.cli.projectPackageUpdateStatus({
|
|
1490
|
-
id: this.msg.packageId,
|
|
1491
|
-
status: "CANCELLED",
|
|
1492
|
-
error: reason
|
|
1493
|
-
});
|
|
1494
|
-
return;
|
|
1495
|
-
}
|
|
1496
1515
|
await this.apmClient.cli.webideSetMessageError({
|
|
1497
1516
|
id: this.msg.messageId,
|
|
1498
1517
|
error: reason,
|
|
@@ -1702,49 +1721,6 @@ function handleStopTerminalsAction(payload, ctx) {
|
|
|
1702
1721
|
trackActionTask(ctx, task);
|
|
1703
1722
|
}
|
|
1704
1723
|
|
|
1705
|
-
// src/commands/connect/actions/package.ts
|
|
1706
|
-
function handleWebIdePackageAction(payload, ctx) {
|
|
1707
|
-
const perMessageController = new AbortController();
|
|
1708
|
-
ctx.activeRuns.set(payload.messageId, perMessageController);
|
|
1709
|
-
if (ctx.pendingCancels.has(payload.messageId)) {
|
|
1710
|
-
ctx.activeRuns.delete(payload.messageId);
|
|
1711
|
-
ctx.pendingCancels.delete(payload.messageId);
|
|
1712
|
-
const cancelTask = (async () => {
|
|
1713
|
-
try {
|
|
1714
|
-
const api = createApmApiClient(ctx.cfg);
|
|
1715
|
-
await api.cli.projectPackageUpdateStatus({
|
|
1716
|
-
id: payload.packageId,
|
|
1717
|
-
status: "CANCELLED",
|
|
1718
|
-
error: "\u5DF2\u53D6\u6D88"
|
|
1719
|
-
});
|
|
1720
|
-
} catch (err) {
|
|
1721
|
-
console.error(
|
|
1722
|
-
`[apm] webide-package \u9884\u53D6\u6D88\u5199\u7EC8\u6001\u5931\u8D25 packageId=${payload.packageId}:`,
|
|
1723
|
-
err instanceof Error ? err.message : err
|
|
1724
|
-
);
|
|
1725
|
-
}
|
|
1726
|
-
})();
|
|
1727
|
-
trackActionTask(ctx, cancelTask);
|
|
1728
|
-
return;
|
|
1729
|
-
}
|
|
1730
|
-
const task = (async () => {
|
|
1731
|
-
const handle = new ActionWorker(payload);
|
|
1732
|
-
registerRunSteer(ctx, payload.messageId, handle);
|
|
1733
|
-
const onAbort = () => handle.cancel(payload.messageId);
|
|
1734
|
-
perMessageController.signal.addEventListener("abort", onAbort, {
|
|
1735
|
-
once: true
|
|
1736
|
-
});
|
|
1737
|
-
try {
|
|
1738
|
-
await handle.done;
|
|
1739
|
-
} finally {
|
|
1740
|
-
perMessageController.signal.removeEventListener("abort", onAbort);
|
|
1741
|
-
unregisterRunSteer(ctx, payload.messageId);
|
|
1742
|
-
ctx.activeRuns.delete(payload.messageId);
|
|
1743
|
-
}
|
|
1744
|
-
})();
|
|
1745
|
-
trackActionTask(ctx, task);
|
|
1746
|
-
}
|
|
1747
|
-
|
|
1748
1724
|
// src/commands/connect/actions/index.ts
|
|
1749
1725
|
function dispatchConnectAction(payload, ctx) {
|
|
1750
1726
|
switch (payload.type) {
|
|
@@ -1765,9 +1741,6 @@ function dispatchConnectAction(payload, ctx) {
|
|
|
1765
1741
|
case "webide-stop-terminals":
|
|
1766
1742
|
handleStopTerminalsAction(payload, ctx);
|
|
1767
1743
|
return;
|
|
1768
|
-
case "webide-package":
|
|
1769
|
-
handleWebIdePackageAction(payload, ctx);
|
|
1770
|
-
return;
|
|
1771
1744
|
}
|
|
1772
1745
|
}
|
|
1773
1746
|
|
|
@@ -1945,27 +1918,20 @@ function connectOnce(url, ctx, connectionAbort, onConnected) {
|
|
|
1945
1918
|
});
|
|
1946
1919
|
});
|
|
1947
1920
|
}
|
|
1948
|
-
function resolveConnectServerOption(options) {
|
|
1949
|
-
const fromOption = options.server?.trim();
|
|
1950
|
-
if (fromOption) {
|
|
1951
|
-
return fromOption.replace(/\/+$/, "");
|
|
1952
|
-
}
|
|
1953
|
-
const fromEnv = process.env.AI_PM_SERVER?.trim();
|
|
1954
|
-
if (fromEnv) {
|
|
1955
|
-
return fromEnv.replace(/\/+$/, "");
|
|
1956
|
-
}
|
|
1957
|
-
return void 0;
|
|
1958
|
-
}
|
|
1959
1921
|
async function runConnect(options) {
|
|
1960
1922
|
const { didUpdate } = await runUpdate({ quietIfCurrent: true });
|
|
1961
1923
|
if (didUpdate) {
|
|
1962
1924
|
reexecConnectAfterUpdate(options);
|
|
1963
1925
|
}
|
|
1964
1926
|
const cfg = await ensureLoggedConfig();
|
|
1965
|
-
const
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1927
|
+
const endpoints = resolveApmEndpoints({
|
|
1928
|
+
server: options.server,
|
|
1929
|
+
socketServer: options.socketServer,
|
|
1930
|
+
configBaseUrl: cfg.baseUrl,
|
|
1931
|
+
configSocketServer: cfg.socketServer
|
|
1932
|
+
});
|
|
1933
|
+
cfg.baseUrl = endpoints.baseUrl;
|
|
1934
|
+
cfg.socketServer = endpoints.socketServer;
|
|
1969
1935
|
const clientMachineId = resolveClientMachineId(cfg);
|
|
1970
1936
|
if (!clientMachineId) {
|
|
1971
1937
|
console.error("[apm] config \u7F3A\u5C11 clientMachineId\uFF0C\u8BF7\u91CD\u65B0 apm login");
|
|
@@ -2024,8 +1990,12 @@ async function runConnect(options) {
|
|
|
2024
1990
|
lifecycleAbort.signal,
|
|
2025
1991
|
currentConnectionAbort.signal
|
|
2026
1992
|
]);
|
|
2027
|
-
const url = buildAgentWsUrl(
|
|
2028
|
-
|
|
1993
|
+
const url = buildAgentWsUrl(
|
|
1994
|
+
cfg.socketServer ?? cfg.baseUrl,
|
|
1995
|
+
resolveApiKey(cfg)
|
|
1996
|
+
);
|
|
1997
|
+
const visible = url.replace(/([?&]apiKey=)[^&]+/, "$1***");
|
|
1998
|
+
console.log(`[apm] \u8FDE\u63A5 ${visible} \u2026`);
|
|
2029
1999
|
try {
|
|
2030
2000
|
await connectOnce(url, connectCtx, connectionSignal, () => {
|
|
2031
2001
|
reconnectDelay = RECONNECT_MIN_MS;
|
|
@@ -2062,13 +2032,21 @@ function buildProgram() {
|
|
|
2062
2032
|
const program = new Command();
|
|
2063
2033
|
program.name("apm").description(
|
|
2064
2034
|
`\u6BD4\u90BB\u661F\u56FE\u547D\u4EE4\u884C\uFF08WebIDE \u5DE5\u4F5C\u533A\u4E0E\u7814\u53D1\u81EA\u52A8\u5316\uFF09\u3002
|
|
2065
|
-
\
|
|
2035
|
+
\u5730\u5740\u53EF\u7528 --server / --socket-server\uFF0C\u6216\u73AF\u5883\u53D8\u91CF APM_SERVER / APM_SOCKET_SERVER\uFF1B\u672A\u8BBE\u7F6E\u65F6\u9ED8\u8BA4 ${DEFAULT_BASE_URL}\u3002`
|
|
2066
2036
|
).version(readCliVersion(), "-V, --version", "\u663E\u793A\u7248\u672C\u53F7").helpOption("-h, --help", "\u663E\u793A\u5E2E\u52A9").showHelpAfterError(true);
|
|
2067
2037
|
program.command("login").description(
|
|
2068
2038
|
"\u9A8C\u8BC1 API Key \u5E76\u5199\u5165 ~/.config/apm/config.json\uFF08GET /api/v1/cli/me\uFF09"
|
|
2069
|
-
).option("--api-key <key>", "\u8FDC\u7A0B\u4E3B\u673A API Key\uFF08cm_ \u5F00\u5934\uFF09").option(
|
|
2070
|
-
|
|
2071
|
-
|
|
2039
|
+
).option("--api-key <key>", "\u8FDC\u7A0B\u4E3B\u673A API Key\uFF08cm_ \u5F00\u5934\uFF09").option(
|
|
2040
|
+
"--server <url>",
|
|
2041
|
+
"API \u6839\u5730\u5740\uFF1B\u82E5\u53EA\u4F20\u6B64\u9879\u4E14\u5E26\u7AEF\u53E3\uFF0C\u5219\u7AEF\u53E3\u89C6\u4E3A Socket \u7AEF\u53E3\uFF08API \u53BB\u6389\u7AEF\u53E3\uFF09"
|
|
2042
|
+
).option(
|
|
2043
|
+
"--socket-server <url>",
|
|
2044
|
+
"Agent WebSocket \u6839\u5730\u5740\uFF08\u53EF\u4E0E API \u4E0D\u540C\uFF09\uFF0C\u4F8B\u5982 wss://ws.example.com"
|
|
2045
|
+
).action(
|
|
2046
|
+
async (opts) => {
|
|
2047
|
+
await runLogin(opts);
|
|
2048
|
+
}
|
|
2049
|
+
);
|
|
2072
2050
|
program.command("init").description("\u5728\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u6309 WebIDE \u5DE5\u4F5C\u533A\u521D\u59CB\u5316\uFF1A\u4ECE\u5E73\u53F0\u5199\u5165\u6307\u5357\u4E0E\u89C4\u5219").action(async () => {
|
|
2073
2051
|
await runInit();
|
|
2074
2052
|
});
|
|
@@ -2092,8 +2070,17 @@ function buildProgram() {
|
|
|
2092
2070
|
});
|
|
2093
2071
|
program.command("connect").description(
|
|
2094
2072
|
"\u8FDE\u63A5\u524D\u68C0\u6D4B\u5E76\u66F4\u65B0\u5230\u5F53\u524D\u5927\u7248\u672C\u6700\u65B0 CLI\uFF0C\u518D\u8FDE\u63A5\u5E73\u53F0 WebSocket\uFF08/ws/agent\uFF09"
|
|
2095
|
-
).option(
|
|
2096
|
-
|
|
2073
|
+
).option(
|
|
2074
|
+
"--server <url>",
|
|
2075
|
+
"API \u6839\u5730\u5740\uFF1B\u82E5\u53EA\u4F20\u6B64\u9879\u4E14\u5E26\u7AEF\u53E3\uFF0C\u5219\u7AEF\u53E3\u89C6\u4E3A Socket \u7AEF\u53E3\uFF08\u8986\u76D6 config / APM_SERVER\uFF09"
|
|
2076
|
+
).option(
|
|
2077
|
+
"--socket-server <url>",
|
|
2078
|
+
"Agent WebSocket \u6839\u5730\u5740\uFF08\u8986\u76D6 config / APM_SOCKET_SERVER\uFF09"
|
|
2079
|
+
).action(async (opts) => {
|
|
2080
|
+
await runConnect({
|
|
2081
|
+
server: opts.server,
|
|
2082
|
+
socketServer: opts.socketServer
|
|
2083
|
+
});
|
|
2097
2084
|
});
|
|
2098
2085
|
return program;
|
|
2099
2086
|
}
|