ai-project-manage-cli 8.0.18 → 8.1.0

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 CHANGED
@@ -1,30 +1,22 @@
1
1
  #!/usr/bin/env node
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __esm = (fn, res, err) => function __init() {
5
- if (err) throw err[0];
6
- try {
7
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
- } catch (e) {
9
- throw err = [e], e;
10
- }
11
- };
12
- var __export = (target, all) => {
13
- for (var name in all)
14
- __defProp(target, name, { get: all[name], enumerable: true });
15
- };
2
+
3
+ // src/index.ts
4
+ import { Command } from "commander";
16
5
 
17
6
  // src/config.ts
18
7
  import { mkdirSync, readFileSync, writeFileSync } from "fs";
19
8
  import { homedir } from "os";
20
9
  import { join } from "path";
10
+ var APM_CONFIG_DIR = join(homedir(), ".config", "apm");
11
+ var APM_CONFIG_PATH = join(APM_CONFIG_DIR, "config.json");
12
+ var DEFAULT_BASE_URL = "http://127.0.0.1:3000";
21
13
  function resolveClientMachineId(cfg) {
22
14
  return (cfg.clientMachineId ?? cfg.userId ?? "").trim();
23
15
  }
24
16
  function resolveApiKey(cfg) {
25
17
  return (cfg.apiKey ?? cfg.token ?? "").trim();
26
18
  }
27
- async function tryReadApmConfig() {
19
+ function tryReadApmConfig() {
28
20
  try {
29
21
  const raw = readFileSync(APM_CONFIG_PATH, "utf8");
30
22
  const v = JSON.parse(raw);
@@ -86,170 +78,8 @@ function buildAgentWsUrl(httpBase, apiKey) {
86
78
  const q = new URLSearchParams({ apiKey });
87
79
  return `${origin}/ws/agent?${q.toString()}`;
88
80
  }
89
- var APM_CONFIG_DIR, APM_CONFIG_PATH, DEFAULT_BASE_URL;
90
- var init_config = __esm({
91
- "src/config.ts"() {
92
- "use strict";
93
- APM_CONFIG_DIR = join(homedir(), ".config", "apm");
94
- APM_CONFIG_PATH = join(APM_CONFIG_DIR, "config.json");
95
- DEFAULT_BASE_URL = "http://127.0.0.1:3000";
96
- }
97
- });
98
-
99
- // src/api/request-config.ts
100
- import { defineEndpoint } from "listpage-http";
101
- var requestConfig;
102
- var init_request_config = __esm({
103
- "src/api/request-config.ts"() {
104
- "use strict";
105
- requestConfig = {
106
- cli: {
107
- me: defineEndpoint(
108
- {
109
- method: "GET",
110
- path: "/cli/me"
111
- }
112
- ),
113
- webideAppendMessageContent: defineEndpoint({
114
- method: "PUT",
115
- path: "/cli/webide/messages/content"
116
- }),
117
- webideEnsureMessageContent: defineEndpoint({
118
- method: "PUT",
119
- path: "/cli/webide/messages/ensure-content"
120
- }),
121
- webideSetMessageError: defineEndpoint({
122
- method: "PUT",
123
- path: "/cli/webide/messages/error"
124
- }),
125
- webideUpdateMessageStatus: defineEndpoint({
126
- method: "PUT",
127
- path: "/cli/webide/messages/status"
128
- }),
129
- webideUpsertMessageLog: defineEndpoint({
130
- method: "PUT",
131
- path: "/cli/webide/message-logs"
132
- }),
133
- webideReplaceAssumptions: defineEndpoint({
134
- method: "PUT",
135
- path: "/cli/webide/assumptions"
136
- }),
137
- webideListAssumptions: defineEndpoint({
138
- method: "GET",
139
- path: "/cli/webide/assumptions"
140
- }),
141
- webideListAttachments: defineEndpoint({
142
- method: "GET",
143
- path: "/cli/webide/attachments"
144
- }),
145
- webideListDesignArtifacts: defineEndpoint({
146
- method: "GET",
147
- path: "/cli/webide/design-artifacts"
148
- }),
149
- webideRegisterDesignArtifacts: defineEndpoint({
150
- method: "PUT",
151
- path: "/cli/webide/design-artifacts"
152
- }),
153
- webideRecommendPlan: defineEndpoint({
154
- method: "PUT",
155
- path: "/cli/webide/plan-recommendation"
156
- }),
157
- webideUpsertPlan: defineEndpoint({
158
- method: "PUT",
159
- path: "/cli/webide/plan"
160
- }),
161
- webideReplaceTestCases: defineEndpoint({
162
- method: "PUT",
163
- path: "/cli/webide/test-cases"
164
- }),
165
- webideUpsertSqlExecution: defineEndpoint({
166
- method: "PUT",
167
- path: "/cli/webide/sql-executions"
168
- }),
169
- webideFinalizeSqlExecution: defineEndpoint({
170
- method: "PUT",
171
- path: "/cli/webide/sql-executions/finalize"
172
- }),
173
- projectBaseBranch: defineEndpoint(
174
- {
175
- method: "GET",
176
- path: "/cli/tasks/project-base-branch"
177
- }
178
- ),
179
- createWebIdeDraftPullRequest: defineEndpoint({
180
- method: "POST",
181
- path: "/cli/webide/draft-pull-requests"
182
- }),
183
- webideMergePullRequests: defineEndpoint({
184
- method: "POST",
185
- path: "/cli/webide/pull-requests/merge"
186
- }),
187
- getProjectDocumentManifest: defineEndpoint({
188
- method: "GET",
189
- path: "/cli/project-documents/manifest"
190
- }),
191
- listProjectDocuments: defineEndpoint({
192
- method: "GET",
193
- path: "/cli/project-documents"
194
- }),
195
- upsertProjectDocument: defineEndpoint({
196
- method: "PUT",
197
- path: "/cli/project-documents/upsert"
198
- }),
199
- removeProjectDocument: defineEndpoint({
200
- method: "DELETE",
201
- path: "/cli/project-documents"
202
- }),
203
- getApmLogStorage: defineEndpoint({
204
- method: "GET",
205
- path: "/cli/apm-log-storage"
206
- }),
207
- projectPackageUpdateStatus: defineEndpoint({
208
- method: "PUT",
209
- path: "/cli/project-packages/status"
210
- }),
211
- projectPackageAppendContent: defineEndpoint({
212
- method: "PUT",
213
- path: "/cli/project-packages/content"
214
- }),
215
- projectPackageEnsureContent: defineEndpoint({
216
- method: "PUT",
217
- path: "/cli/project-packages/ensure-content"
218
- })
219
- }
220
- };
221
- }
222
- });
223
-
224
- // src/api/client.ts
225
- var client_exports = {};
226
- __export(client_exports, {
227
- createApmApiClient: () => createApmApiClient
228
- });
229
- import { createApiClient } from "listpage-http";
230
- function createApmApiClient(cfg) {
231
- const baseURL = `${cfg.baseUrl.trim().replace(/\/+$/, "")}/api/v1`;
232
- return createApiClient(requestConfig, {
233
- baseURL,
234
- getToken: () => resolveApiKey(cfg) || void 0,
235
- successCodes: [0],
236
- unauthorizedCodes: [401]
237
- });
238
- }
239
- var init_client = __esm({
240
- "src/api/client.ts"() {
241
- "use strict";
242
- init_request_config();
243
- init_config();
244
- }
245
- });
246
-
247
- // src/index.ts
248
- init_config();
249
- import { Command } from "commander";
250
81
 
251
82
  // src/utils/workspace.ts
252
- init_config();
253
83
  import { copyFileSync, existsSync, mkdirSync as mkdirSync2, readdirSync, statSync } from "fs";
254
84
  import { dirname, join as join2, resolve as resolve2 } from "path";
255
85
  import { fileURLToPath } from "url";
@@ -421,9 +251,147 @@ async function runInit() {
421
251
  }
422
252
 
423
253
  // src/commands/login.ts
424
- init_config();
425
- init_client();
426
254
  import { ApiError } from "listpage-http";
255
+
256
+ // src/api/client.ts
257
+ import { createApiClient } from "listpage-http";
258
+
259
+ // src/api/request-config.ts
260
+ import { defineEndpoint } from "listpage-http";
261
+ var requestConfig = {
262
+ cli: {
263
+ me: defineEndpoint(
264
+ {
265
+ method: "GET",
266
+ path: "/cli/me"
267
+ }
268
+ ),
269
+ webideAppendMessageContent: defineEndpoint({
270
+ method: "PUT",
271
+ path: "/cli/webide/messages/content"
272
+ }),
273
+ webideEnsureMessageContent: defineEndpoint({
274
+ method: "PUT",
275
+ path: "/cli/webide/messages/ensure-content"
276
+ }),
277
+ webideSetMessageError: defineEndpoint({
278
+ method: "PUT",
279
+ path: "/cli/webide/messages/error"
280
+ }),
281
+ webideUpdateMessageStatus: defineEndpoint({
282
+ method: "PUT",
283
+ path: "/cli/webide/messages/status"
284
+ }),
285
+ /** CLI 改工作流状态统一入口(start-/complete- 等) */
286
+ webideRunAction: defineEndpoint({
287
+ method: "POST",
288
+ path: "/cli/webide/actions"
289
+ }),
290
+ webideUpsertMessageLog: defineEndpoint({
291
+ method: "PUT",
292
+ path: "/cli/webide/message-logs"
293
+ }),
294
+ webideReplaceAssumptions: defineEndpoint({
295
+ method: "PUT",
296
+ path: "/cli/webide/assumptions"
297
+ }),
298
+ webideListAssumptions: defineEndpoint({
299
+ method: "GET",
300
+ path: "/cli/webide/assumptions"
301
+ }),
302
+ webideListAttachments: defineEndpoint({
303
+ method: "GET",
304
+ path: "/cli/webide/attachments"
305
+ }),
306
+ webideListDesignArtifacts: defineEndpoint({
307
+ method: "GET",
308
+ path: "/cli/webide/design-artifacts"
309
+ }),
310
+ webideRegisterDesignArtifacts: defineEndpoint({
311
+ method: "PUT",
312
+ path: "/cli/webide/design-artifacts"
313
+ }),
314
+ webideRecommendPlan: defineEndpoint({
315
+ method: "PUT",
316
+ path: "/cli/webide/plan-recommendation"
317
+ }),
318
+ webideUpsertPlan: defineEndpoint({
319
+ method: "PUT",
320
+ path: "/cli/webide/plan"
321
+ }),
322
+ webideReplaceTestCases: defineEndpoint({
323
+ method: "PUT",
324
+ path: "/cli/webide/test-cases"
325
+ }),
326
+ webideUpsertSqlExecution: defineEndpoint({
327
+ method: "PUT",
328
+ path: "/cli/webide/sql-executions"
329
+ }),
330
+ webideFinalizeSqlExecution: defineEndpoint({
331
+ method: "PUT",
332
+ path: "/cli/webide/sql-executions/finalize"
333
+ }),
334
+ projectBaseBranch: defineEndpoint(
335
+ {
336
+ method: "GET",
337
+ path: "/cli/tasks/project-base-branch"
338
+ }
339
+ ),
340
+ createWebIdeDraftPullRequest: defineEndpoint({
341
+ method: "POST",
342
+ path: "/cli/webide/draft-pull-requests"
343
+ }),
344
+ webideMergePullRequests: defineEndpoint({
345
+ method: "POST",
346
+ path: "/cli/webide/pull-requests/merge"
347
+ }),
348
+ getProjectDocumentManifest: defineEndpoint({
349
+ method: "GET",
350
+ path: "/cli/project-documents/manifest"
351
+ }),
352
+ listProjectDocuments: defineEndpoint({
353
+ method: "GET",
354
+ path: "/cli/project-documents"
355
+ }),
356
+ upsertProjectDocument: defineEndpoint({
357
+ method: "PUT",
358
+ path: "/cli/project-documents/upsert"
359
+ }),
360
+ removeProjectDocument: defineEndpoint({
361
+ method: "DELETE",
362
+ path: "/cli/project-documents"
363
+ }),
364
+ getApmLogStorage: defineEndpoint({
365
+ method: "GET",
366
+ path: "/cli/apm-log-storage"
367
+ }),
368
+ projectPackageUpdateStatus: defineEndpoint({
369
+ method: "PUT",
370
+ path: "/cli/project-packages/status"
371
+ }),
372
+ projectPackageAppendContent: defineEndpoint({
373
+ method: "PUT",
374
+ path: "/cli/project-packages/content"
375
+ }),
376
+ projectPackageEnsureContent: defineEndpoint({
377
+ method: "PUT",
378
+ path: "/cli/project-packages/ensure-content"
379
+ })
380
+ }
381
+ };
382
+
383
+ // src/api/client.ts
384
+ function createApmApiClient(cfg) {
385
+ const baseURL = `${cfg.baseUrl.trim().replace(/\/+$/, "")}/api/v1`;
386
+ return createApiClient(requestConfig, {
387
+ baseURL,
388
+ getToken: () => resolveApiKey(cfg) || void 0,
389
+ successCodes: [0],
390
+ unauthorizedCodes: [401]
391
+ });
392
+ }
393
+
394
+ // src/commands/login.ts
427
395
  async function runLogin(opts) {
428
396
  const baseUrl = (opts.server?.trim() || process.env.AI_PM_SERVER?.trim() || DEFAULT_BASE_URL).replace(/\/+$/, "");
429
397
  const apiKey = (opts.apiKey?.trim() || process.env.APM_API_KEY?.trim() || "").replace(/^Bearer\s+/i, "");
@@ -479,8 +447,6 @@ async function runLogin(opts) {
479
447
 
480
448
  // src/commands/update.ts
481
449
  import { spawnSync } from "child_process";
482
- import { existsSync as existsSync2 } from "fs";
483
- import { join as join4 } from "path";
484
450
 
485
451
  // src/version.ts
486
452
  import { readFileSync as readFileSync2 } from "fs";
@@ -603,7 +569,7 @@ async function runUpdate(options = {}) {
603
569
  });
604
570
  if (resolved.action === "skip") {
605
571
  console.log(`[apm] \u5DF2\u662F\u6700\u65B0\u7248\u672C ${current}`);
606
- return { didUpdate: false };
572
+ return;
607
573
  }
608
574
  if (resolved.majorUpgradeAvailable) {
609
575
  console.log(
@@ -640,54 +606,14 @@ async function runUpdate(options = {}) {
640
606
  } else {
641
607
  console.log(`[apm] \u5DF2\u662F\u6700\u65B0\u7248\u672C ${current}`);
642
608
  }
643
- return { didUpdate: expectedBump };
644
- }
645
- function resolveApmEntryPath(entryArg = process.argv[1]) {
646
- const fromArgv = entryArg?.trim();
647
- if (fromArgv && existsSync2(fromArgv)) {
648
- return fromArgv;
649
- }
650
- const npmResult = runNpm(["root", "-g"], {
651
- encoding: "utf8",
652
- stdio: ["ignore", "pipe", "pipe"]
653
- });
654
- if (npmResult.status === 0) {
655
- const globalRoot = npmResult.stdout?.toString().trim();
656
- if (globalRoot) {
657
- const candidate = join4(globalRoot, CLI_PACKAGE_NAME, "dist", "index.js");
658
- if (existsSync2(candidate)) {
659
- return candidate;
660
- }
661
- }
662
- }
663
- if (fromArgv) {
664
- return fromArgv;
665
- }
666
- console.error("[apm] \u65E0\u6CD5\u89E3\u6790 apm \u5165\u53E3\u8DEF\u5F84");
667
- process.exit(1);
668
- }
669
- function reexecConnectAfterUpdate(options) {
670
- console.log("[apm] \u66F4\u65B0\u5B8C\u6210\uFF0C\u6B63\u5728\u4EE5\u65B0\u7248\u672C\u91CD\u65B0\u8FDE\u63A5\u2026");
671
- const apmScript = resolveApmEntryPath();
672
- const args = [apmScript, "connect"];
673
- const server = options.server?.trim();
674
- if (server) {
675
- args.push("--server", server);
676
- }
677
- const result = spawnSync(process.execPath, args, { stdio: "inherit" });
678
- if (result.error) {
679
- console.error("[apm] \u91CD\u542F connect \u5931\u8D25:", result.error.message);
680
- process.exit(1);
681
- }
682
- process.exit(result.status ?? 0);
683
609
  }
684
610
 
685
611
  // src/commands/update-skills.ts
686
- import { existsSync as existsSync3, statSync as statSync2 } from "fs";
612
+ import { existsSync as existsSync2, statSync as statSync2 } from "fs";
687
613
  async function syncWorkspaceSkills(workdir) {
688
614
  const apmDir = workspaceApmDir(workdir);
689
615
  const fsApmDir = toFsPath(apmDir);
690
- if (!existsSync3(fsApmDir)) {
616
+ if (!existsSync2(fsApmDir)) {
691
617
  throw new Error("[apm] \u672A\u627E\u5230 .apm \u76EE\u5F55\uFF0C\u8BF7\u5148\u6267\u884C apm init");
692
618
  }
693
619
  const apmStat = statSync2(fsApmDir);
@@ -699,7 +625,7 @@ async function syncWorkspaceSkills(workdir) {
699
625
  }
700
626
  async function runUpdateSkills() {
701
627
  const apmDir = workspaceApmDir();
702
- if (!existsSync3(apmDir)) {
628
+ if (!existsSync2(apmDir)) {
703
629
  console.error("[apm] \u672A\u627E\u5230 .apm \u76EE\u5F55\uFF0C\u8BF7\u5148\u6267\u884C apm init");
704
630
  process.exit(1);
705
631
  }
@@ -710,21 +636,16 @@ async function runUpdateSkills() {
710
636
  await syncWorkspaceSkills(resolveWorkdirPath());
711
637
  }
712
638
 
713
- // src/commands/sync-project-documents.ts
714
- init_config();
715
-
716
639
  // src/utils/project-documents.ts
717
- init_client();
718
- init_config();
719
640
  import {
720
- existsSync as existsSync4,
641
+ existsSync as existsSync3,
721
642
  readdirSync as readdirSync2,
722
643
  readFileSync as readFileSync3,
723
644
  rmSync,
724
645
  writeFileSync as writeFileSync2
725
646
  } from "fs";
726
647
  import { createHash } from "crypto";
727
- import { dirname as dirname3, join as join5, relative, sep } from "path";
648
+ import { dirname as dirname3, join as join4, relative, sep } from "path";
728
649
 
729
650
  // src/utils/git.ts
730
651
  import { execFile as execFile2 } from "child_process";
@@ -798,11 +719,11 @@ function normalizeProjectIdForPath(projectId) {
798
719
  }
799
720
  function projectDocumentsDir(apmRoot, projectId) {
800
721
  const id = normalizeProjectIdForPath(projectId);
801
- return join5(apmRoot ?? workspaceApmDir(), "project", id);
722
+ return join4(apmRoot ?? workspaceApmDir(), "project", id);
802
723
  }
803
724
  function projectDocumentLocalPath(apmRoot, projectId, documentPath) {
804
725
  const normalized = normalizeLocalDocumentPath(documentPath);
805
- return join5(
726
+ return join4(
806
727
  projectDocumentsDir(apmRoot, projectId),
807
728
  ...normalized.split("/")
808
729
  );
@@ -822,11 +743,11 @@ function hashLocalFileContent(content) {
822
743
  return createHash("sha256").update(content, "utf8").digest("hex");
823
744
  }
824
745
  function readLocalManifest(apmRoot, projectId) {
825
- const manifestPath = join5(
746
+ const manifestPath = join4(
826
747
  projectDocumentsDir(apmRoot, projectId),
827
748
  MANIFEST_FILE
828
749
  );
829
- if (!existsSync4(manifestPath)) {
750
+ if (!existsSync3(manifestPath)) {
830
751
  return null;
831
752
  }
832
753
  try {
@@ -839,13 +760,13 @@ function readLocalManifest(apmRoot, projectId) {
839
760
  }
840
761
  function listLocalDocumentPaths(apmRoot, projectId) {
841
762
  const root = projectDocumentsDir(apmRoot, projectId);
842
- if (!existsSync4(root)) {
763
+ if (!existsSync3(root)) {
843
764
  return [];
844
765
  }
845
766
  const paths = [];
846
767
  const walk = (dir) => {
847
768
  for (const entry of readdirSync2(dir, { withFileTypes: true })) {
848
- const abs = join5(dir, entry.name);
769
+ const abs = join4(dir, entry.name);
849
770
  if (entry.isDirectory()) {
850
771
  walk(abs);
851
772
  continue;
@@ -974,13 +895,13 @@ ${diagnostic ?? ""}`);
974
895
  const absPath = toFsPath(
975
896
  projectDocumentLocalPath(targetApmDir, projectId, path)
976
897
  );
977
- if (existsSync4(absPath)) {
898
+ if (existsSync3(absPath)) {
978
899
  rmSync(absPath, { force: true });
979
900
  deleted += 1;
980
901
  }
981
902
  }
982
903
  writeFileSync2(
983
- toFsPath(join5(docsDir, MANIFEST_FILE)),
904
+ toFsPath(join4(docsDir, MANIFEST_FILE)),
984
905
  `${JSON.stringify(remoteManifest, null, 2)}
985
906
  `,
986
907
  "utf8"
@@ -1064,7 +985,6 @@ async function runSyncProjectDocuments(options) {
1064
985
  // src/commands/connect.ts
1065
986
  import WebSocket from "ws";
1066
987
  import { setTimeout as delay } from "node:timers/promises";
1067
- init_config();
1068
988
 
1069
989
  // src/ws/protocol.ts
1070
990
  function isWebIdeStartProjectTarget(value) {
@@ -1294,18 +1214,13 @@ function handleCancelAction(payload, ctx) {
1294
1214
  ctx.activeRuns.get(messageId)?.abort();
1295
1215
  }
1296
1216
 
1297
- // src/commands/connect/actions/webide-message.ts
1298
- init_client();
1299
-
1300
- // src/commands/connect/webide-worker-pool.ts
1217
+ // src/commands/connect/core/worker/worker.ts
1218
+ import { dirname as dirname4, join as join5 } from "path";
1219
+ import { fileURLToPath as fileURLToPath3 } from "url";
1301
1220
  import { Worker } from "node:worker_threads";
1221
+
1222
+ // src/commands/connect/core/worker/config.ts
1302
1223
  import { totalmem } from "node:os";
1303
- import { fileURLToPath as fileURLToPath3 } from "node:url";
1304
- import { dirname as dirname4, join as join6 } from "node:path";
1305
- var workerFile = join6(
1306
- dirname4(fileURLToPath3(import.meta.url)),
1307
- "webide-message-worker.js"
1308
- );
1309
1224
  var SYSTEM_RESERVE_MB = 3072;
1310
1225
  var MIN_WEBIDE_WORKER_HEAP_MB = 1536;
1311
1226
  var MAX_WEBIDE_WORKER_HEAP_MB = 8192;
@@ -1324,85 +1239,111 @@ function resolveWebIdeWorkerHeapMb(env = process.env, totalMemoryBytes = totalme
1324
1239
  if (!Number.isFinite(n)) return fallback;
1325
1240
  return Math.min(16384, Math.max(MIN_WEBIDE_WORKER_HEAP_MB, n));
1326
1241
  }
1327
- function spawnWebIdeMessageWorker(cfg, msg) {
1328
- const maxOldGenerationSizeMb = resolveWebIdeWorkerHeapMb();
1329
- const worker = new Worker(workerFile, {
1330
- workerData: { cfg, msg },
1331
- // worker_threads 不支持 execArgv 里的 --max-old-space-size,必须用 resourceLimits
1332
- resourceLimits: { maxOldGenerationSizeMb }
1333
- });
1334
- console.log(
1335
- `[apm] webide worker spawn messageId=${msg.messageId} heapMb=${maxOldGenerationSizeMb}`
1336
- );
1337
- let settled = false;
1338
- let resolveDone;
1339
- const done = new Promise((resolve3) => {
1340
- resolveDone = resolve3;
1341
- });
1342
- const failIfStillQueued = async (reason) => {
1343
- if (settled) return;
1344
- try {
1345
- const { createApmApiClient: createApmApiClient2 } = await Promise.resolve().then(() => (init_client(), client_exports));
1346
- const api = createApmApiClient2(cfg);
1347
- if (msg.type === "webide-package") {
1348
- await api.cli.projectPackageUpdateStatus({
1349
- id: msg.packageId,
1350
- status: "CANCELLED",
1351
- error: reason
1352
- });
1353
- return;
1354
- }
1355
- await api.cli.webideSetMessageError({
1356
- id: msg.messageId,
1357
- error: reason,
1358
- asCancelled: true
1359
- });
1360
- } catch (err) {
1361
- console.error(
1362
- `[apm] webide worker \u5931\u8D25\u5199\u7EC8\u6001\u5931\u8D25 messageId=${msg.messageId}:`,
1363
- err instanceof Error ? err.message : err
1364
- );
1242
+
1243
+ // src/commands/connect/core/worker/worker.ts
1244
+ var workerFile = join5(
1245
+ dirname4(fileURLToPath3(import.meta.url)),
1246
+ "worker-script.js"
1247
+ );
1248
+ var ActionWorker = class {
1249
+ worker;
1250
+ _status = "pending";
1251
+ maxOldGenerationSizeMb = resolveWebIdeWorkerHeapMb();
1252
+ apmClient;
1253
+ msg;
1254
+ promise;
1255
+ resolve;
1256
+ reject;
1257
+ constructor(msg) {
1258
+ const cfg = tryReadApmConfig();
1259
+ if (!cfg) {
1260
+ throw new Error("\u672A\u68C0\u6D4B\u5230\u767B\u5F55\u4FE1\u606F\uFF0C\u8BF7\u5148\u6267\u884C apm login");
1365
1261
  }
1366
- };
1367
- worker.on("message", (m) => {
1262
+ this.msg = msg;
1263
+ this.apmClient = createApmApiClient(cfg);
1264
+ this.promise = new Promise((resolve3, reject) => {
1265
+ this.resolve = resolve3;
1266
+ this.reject = reject;
1267
+ });
1268
+ this.worker = new Worker(workerFile, {
1269
+ workerData: { msg, cfg },
1270
+ resourceLimits: { maxOldGenerationSizeMb: this.maxOldGenerationSizeMb }
1271
+ });
1272
+ this.worker.on("message", this.onMessage);
1273
+ this.worker.on("error", this.onError);
1274
+ this.worker.on("exit", this.onExit);
1275
+ }
1276
+ get status() {
1277
+ return this._status;
1278
+ }
1279
+ set status(value) {
1280
+ this._status = value;
1281
+ if (value === "done") {
1282
+ this.resolve();
1283
+ } else if (value === "error") {
1284
+ this.reject();
1285
+ }
1286
+ }
1287
+ onMessage = (m) => {
1368
1288
  if (m?.type === "done" || m?.type === "error") {
1369
- settled = true;
1370
1289
  if (m.type === "error") {
1371
1290
  console.error(
1372
1291
  `[apm] webide worker error messageId=${m.messageId}: ${m.error}`
1373
1292
  );
1374
1293
  }
1375
- void worker.terminate().finally(() => resolveDone());
1294
+ this.worker.terminate().finally(() => {
1295
+ this.resolve();
1296
+ });
1376
1297
  }
1377
- });
1378
- worker.on("error", (err) => {
1298
+ };
1299
+ onError = (err) => {
1379
1300
  const detail = err instanceof Error ? err.message : String(err);
1380
1301
  console.error("[apm] webide worker crashed:", err);
1381
- 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` : "";
1382
- void failIfStillQueued(`WebIDE worker \u5D29\u6E83: ${detail}${oomHint}`).finally(
1383
- () => resolveDone()
1384
- );
1385
- });
1386
- worker.on("exit", (code) => {
1387
- if (!settled && code !== 0) {
1302
+ const oomHint = /memory limit|heap out of memory/i.test(detail) ? `\uFF08\u5F53\u524D\u5806\u4E0A\u9650 ${this.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` : "";
1303
+ this.failIfStillQueued(`WebIDE worker \u5D29\u6E83: ${detail}${oomHint}`);
1304
+ };
1305
+ onExit = async (code) => {
1306
+ if (this.status === "pending" && code !== 0) {
1388
1307
  console.error(`[apm] webide worker exit code=${code}`);
1389
- void failIfStillQueued(`WebIDE worker \u5F02\u5E38\u9000\u51FA code=${code}`).finally(
1390
- () => resolveDone()
1391
- );
1308
+ this.failIfStillQueued(`WebIDE worker \u5F02\u5E38\u9000\u51FA code=${code}`);
1392
1309
  return;
1393
1310
  }
1394
1311
  if (code !== 0) {
1395
1312
  console.error(`[apm] webide worker exit code=${code}`);
1313
+ this.status = "error";
1314
+ return;
1396
1315
  }
1397
- resolveDone();
1398
- });
1399
- return {
1400
- cancel(messageId) {
1401
- worker.postMessage({ type: "cancel", messageId });
1402
- },
1403
- done
1316
+ this.status = "done";
1404
1317
  };
1405
- }
1318
+ failIfStillQueued = async (reason) => {
1319
+ if (this.status !== "pending") return;
1320
+ try {
1321
+ if (this.msg.type === "webide-package") {
1322
+ await this.apmClient.cli.projectPackageUpdateStatus({
1323
+ id: this.msg.packageId,
1324
+ status: "CANCELLED",
1325
+ error: reason
1326
+ });
1327
+ return;
1328
+ }
1329
+ await this.apmClient.cli.webideSetMessageError({
1330
+ id: this.msg.messageId,
1331
+ error: reason,
1332
+ asCancelled: true
1333
+ });
1334
+ } catch (err) {
1335
+ console.error("[apm] WebIDE worker \u5931\u8D25\u5199\u7EC8\u6001\u5931\u8D25:", err);
1336
+ } finally {
1337
+ this.status = "error";
1338
+ }
1339
+ };
1340
+ cancel(msg_id) {
1341
+ this.worker.postMessage({ type: "cancel", messageId: msg_id });
1342
+ }
1343
+ get done() {
1344
+ return this.promise;
1345
+ }
1346
+ };
1406
1347
 
1407
1348
  // src/commands/connect/actions/types.ts
1408
1349
  function trackActionTask(ctx, task) {
@@ -1437,7 +1378,7 @@ function handleWebIdeMessageAction(payload, ctx) {
1437
1378
  return;
1438
1379
  }
1439
1380
  const task = (async () => {
1440
- const handle = spawnWebIdeMessageWorker(ctx.cfg, payload);
1381
+ const handle = new ActionWorker(payload);
1441
1382
  const onAbort = () => handle.cancel(payload.messageId);
1442
1383
  perMessageController.signal.addEventListener("abort", onAbort, {
1443
1384
  once: true
@@ -1453,7 +1394,6 @@ function handleWebIdeMessageAction(payload, ctx) {
1453
1394
  }
1454
1395
 
1455
1396
  // src/commands/connect/actions/start-project.ts
1456
- init_client();
1457
1397
  function handleStartProjectAction(payload, ctx) {
1458
1398
  const perMessageController = new AbortController();
1459
1399
  ctx.activeRuns.set(payload.messageId, perMessageController);
@@ -1478,7 +1418,7 @@ function handleStartProjectAction(payload, ctx) {
1478
1418
  return;
1479
1419
  }
1480
1420
  const task = (async () => {
1481
- const handle = spawnWebIdeMessageWorker(ctx.cfg, payload);
1421
+ const handle = new ActionWorker(payload);
1482
1422
  const onAbort = () => handle.cancel(payload.messageId);
1483
1423
  perMessageController.signal.addEventListener("abort", onAbort, {
1484
1424
  once: true
@@ -1493,8 +1433,7 @@ function handleStartProjectAction(payload, ctx) {
1493
1433
  trackActionTask(ctx, task);
1494
1434
  }
1495
1435
 
1496
- // src/commands/connect/pty-session-mcp.ts
1497
- init_config();
1436
+ // src/commands/connect/mcps/pty-session-mcp.ts
1498
1437
  var DEFAULT_PTY_SESSION_PORT = "7788";
1499
1438
  function resolvePtySessionBaseUrl(env = process.env) {
1500
1439
  const explicit = env.LOCAL_TERMINAL_URL?.trim();
@@ -1590,7 +1529,6 @@ function handleStopTerminalsAction(payload, ctx) {
1590
1529
  }
1591
1530
 
1592
1531
  // src/commands/connect/actions/package.ts
1593
- init_client();
1594
1532
  function handleWebIdePackageAction(payload, ctx) {
1595
1533
  const perMessageController = new AbortController();
1596
1534
  ctx.activeRuns.set(payload.messageId, perMessageController);
@@ -1616,7 +1554,7 @@ function handleWebIdePackageAction(payload, ctx) {
1616
1554
  return;
1617
1555
  }
1618
1556
  const task = (async () => {
1619
- const handle = spawnWebIdeMessageWorker(ctx.cfg, payload);
1557
+ const handle = new ActionWorker(payload);
1620
1558
  const onAbort = () => handle.cancel(payload.messageId);
1621
1559
  perMessageController.signal.addEventListener("abort", onAbort, {
1622
1560
  once: true
@@ -1655,25 +1593,15 @@ function dispatchConnectAction(payload, ctx) {
1655
1593
  }
1656
1594
 
1657
1595
  // src/commands/connect-lock.ts
1658
- init_config();
1659
1596
  import {
1660
- existsSync as existsSync5,
1597
+ existsSync as existsSync4,
1661
1598
  mkdirSync as mkdirSync3,
1662
1599
  readFileSync as readFileSync4,
1663
1600
  unlinkSync,
1664
1601
  writeFileSync as writeFileSync3
1665
1602
  } from "fs";
1666
- import { join as join7 } from "path";
1667
- var CONNECT_LOCK_PATH = join7(APM_CONFIG_DIR, "connect.lock");
1668
- var LEGACY_DAEMON_PID_PATH = join7(APM_CONFIG_DIR, "connect.pid");
1669
- var LEGACY_DAEMON_FILES = [
1670
- LEGACY_DAEMON_PID_PATH,
1671
- join7(APM_CONFIG_DIR, "connect.supervisor.cjs"),
1672
- join7(APM_CONFIG_DIR, "connect.launch.json"),
1673
- join7(APM_CONFIG_DIR, "connect.ecosystem.config.cjs"),
1674
- join7(APM_CONFIG_DIR, "connect.ecosystem.cjs"),
1675
- join7(APM_CONFIG_DIR, "connect.entry.cjs")
1676
- ];
1603
+ import { join as join6 } from "path";
1604
+ var CONNECT_LOCK_PATH = join6(APM_CONFIG_DIR, "connect.lock");
1677
1605
  function isProcessAlive(pid) {
1678
1606
  if (!Number.isInteger(pid) || pid <= 0) return false;
1679
1607
  try {
@@ -1683,30 +1611,8 @@ function isProcessAlive(pid) {
1683
1611
  return false;
1684
1612
  }
1685
1613
  }
1686
- function readLegacyDaemonPid() {
1687
- if (!existsSync5(LEGACY_DAEMON_PID_PATH)) return null;
1688
- try {
1689
- const pid = Number.parseInt(
1690
- readFileSync4(LEGACY_DAEMON_PID_PATH, "utf8").trim(),
1691
- 10
1692
- );
1693
- if (!Number.isInteger(pid) || pid <= 0) return null;
1694
- return pid;
1695
- } catch {
1696
- return null;
1697
- }
1698
- }
1699
- function removeLegacyDaemonFiles() {
1700
- for (const file of LEGACY_DAEMON_FILES) {
1701
- if (!existsSync5(file)) continue;
1702
- try {
1703
- unlinkSync(file);
1704
- } catch {
1705
- }
1706
- }
1707
- }
1708
1614
  function readConnectLock() {
1709
- if (!existsSync5(CONNECT_LOCK_PATH)) return null;
1615
+ if (!existsSync4(CONNECT_LOCK_PATH)) return null;
1710
1616
  try {
1711
1617
  const raw = readFileSync4(CONNECT_LOCK_PATH, "utf8");
1712
1618
  const parsed = JSON.parse(raw);
@@ -1759,24 +1665,6 @@ function releaseConnectLock() {
1759
1665
  } catch {
1760
1666
  }
1761
1667
  }
1762
- function assertConnectNotRunning() {
1763
- pruneStaleConnectLock();
1764
- const lock = readConnectLock();
1765
- if (lock && isProcessAlive(lock.pid) && lock.pid !== process.pid) {
1766
- console.error(
1767
- `[apm] \u5DF2\u6709 apm connect \u5728\u8FD0\u884C (pid=${lock.pid})\uFF0C\u8BF7\u5148\u505C\u6B62\u540E\u518D\u542F\u52A8`
1768
- );
1769
- process.exit(1);
1770
- }
1771
- const legacyPid = readLegacyDaemonPid();
1772
- if (legacyPid && isProcessAlive(legacyPid) && legacyPid !== process.pid) {
1773
- console.error(
1774
- `[apm] \u68C0\u6D4B\u5230\u65E7\u7248\u540E\u53F0 connect (pid=${legacyPid})\uFF0C\u8BF7\u5148\u7ED3\u675F\u8BE5\u8FDB\u7A0B\u540E\u518D\u542F\u52A8`
1775
- );
1776
- process.exit(1);
1777
- }
1778
- removeLegacyDaemonFiles();
1779
- }
1780
1668
 
1781
1669
  // src/commands/connect.ts
1782
1670
  var HEARTBEAT_MS = 3e4;
@@ -1890,10 +1778,6 @@ function resolveConnectServerOption(options) {
1890
1778
  return void 0;
1891
1779
  }
1892
1780
  async function runConnect(options) {
1893
- const { didUpdate } = await runUpdate();
1894
- if (didUpdate) {
1895
- reexecConnectAfterUpdate(options);
1896
- }
1897
1781
  const cfg = await ensureLoggedConfig();
1898
1782
  const serverOverride = resolveConnectServerOption(options);
1899
1783
  if (serverOverride) {
@@ -1904,7 +1788,6 @@ async function runConnect(options) {
1904
1788
  console.error("[apm] config \u7F3A\u5C11 clientMachineId\uFF0C\u8BF7\u91CD\u65B0 apm login");
1905
1789
  process.exit(1);
1906
1790
  }
1907
- assertConnectNotRunning();
1908
1791
  acquireConnectLock();
1909
1792
  process.on("exit", releaseConnectLock);
1910
1793
  let shuttingDown = false;
@@ -2021,7 +1904,7 @@ function buildProgram() {
2021
1904
  await runSyncProjectDocuments(opts);
2022
1905
  });
2023
1906
  program.command("connect").description(
2024
- "\u8FDE\u63A5\u5E73\u53F0 WebSocket\uFF08/ws/agent\uFF09\uFF0C\u7EF4\u6301\u5FC3\u8DF3\u5E76\u5904\u7406\u4E0B\u884C webide-message\uFF1B\u542F\u52A8\u524D\u81EA\u52A8 apm update \u5230\u5F53\u524D\u5927\u7248\u672C\u6700\u65B0\u7248"
1907
+ "\u8FDE\u63A5\u5E73\u53F0 WebSocket\uFF08/ws/agent\uFF09\uFF0C\u7EF4\u6301\u5FC3\u8DF3\u5E76\u5904\u7406\u4E0B\u884C webide-message"
2025
1908
  ).option("--server <url>", "API \u6839\u5730\u5740\uFF0C\u8986\u76D6 config \u4E2D\u7684 baseUrl").action(async (opts) => {
2026
1909
  await runConnect({ server: opts.server });
2027
1910
  });