ai-project-manage-cli 8.0.17 → 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,162 +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
- webideRecommendPlan: defineEndpoint({
146
- method: "PUT",
147
- path: "/cli/webide/plan-recommendation"
148
- }),
149
- webideUpsertPlan: defineEndpoint({
150
- method: "PUT",
151
- path: "/cli/webide/plan"
152
- }),
153
- webideReplaceTestCases: defineEndpoint({
154
- method: "PUT",
155
- path: "/cli/webide/test-cases"
156
- }),
157
- webideUpsertSqlExecution: defineEndpoint({
158
- method: "PUT",
159
- path: "/cli/webide/sql-executions"
160
- }),
161
- webideFinalizeSqlExecution: defineEndpoint({
162
- method: "PUT",
163
- path: "/cli/webide/sql-executions/finalize"
164
- }),
165
- projectBaseBranch: defineEndpoint(
166
- {
167
- method: "GET",
168
- path: "/cli/tasks/project-base-branch"
169
- }
170
- ),
171
- createWebIdeDraftPullRequest: defineEndpoint({
172
- method: "POST",
173
- path: "/cli/webide/draft-pull-requests"
174
- }),
175
- webideMergePullRequests: defineEndpoint({
176
- method: "POST",
177
- path: "/cli/webide/pull-requests/merge"
178
- }),
179
- getProjectDocumentManifest: defineEndpoint({
180
- method: "GET",
181
- path: "/cli/project-documents/manifest"
182
- }),
183
- listProjectDocuments: defineEndpoint({
184
- method: "GET",
185
- path: "/cli/project-documents"
186
- }),
187
- upsertProjectDocument: defineEndpoint({
188
- method: "PUT",
189
- path: "/cli/project-documents/upsert"
190
- }),
191
- removeProjectDocument: defineEndpoint({
192
- method: "DELETE",
193
- path: "/cli/project-documents"
194
- }),
195
- getApmLogStorage: defineEndpoint({
196
- method: "GET",
197
- path: "/cli/apm-log-storage"
198
- }),
199
- projectPackageUpdateStatus: defineEndpoint({
200
- method: "PUT",
201
- path: "/cli/project-packages/status"
202
- }),
203
- projectPackageAppendContent: defineEndpoint({
204
- method: "PUT",
205
- path: "/cli/project-packages/content"
206
- }),
207
- projectPackageEnsureContent: defineEndpoint({
208
- method: "PUT",
209
- path: "/cli/project-packages/ensure-content"
210
- })
211
- }
212
- };
213
- }
214
- });
215
-
216
- // src/api/client.ts
217
- var client_exports = {};
218
- __export(client_exports, {
219
- createApmApiClient: () => createApmApiClient
220
- });
221
- import { createApiClient } from "listpage-http";
222
- function createApmApiClient(cfg) {
223
- const baseURL = `${cfg.baseUrl.trim().replace(/\/+$/, "")}/api/v1`;
224
- return createApiClient(requestConfig, {
225
- baseURL,
226
- getToken: () => resolveApiKey(cfg) || void 0,
227
- successCodes: [0],
228
- unauthorizedCodes: [401]
229
- });
230
- }
231
- var init_client = __esm({
232
- "src/api/client.ts"() {
233
- "use strict";
234
- init_request_config();
235
- init_config();
236
- }
237
- });
238
-
239
- // src/index.ts
240
- init_config();
241
- import { Command } from "commander";
242
81
 
243
82
  // src/utils/workspace.ts
244
- init_config();
245
83
  import { copyFileSync, existsSync, mkdirSync as mkdirSync2, readdirSync, statSync } from "fs";
246
84
  import { dirname, join as join2, resolve as resolve2 } from "path";
247
85
  import { fileURLToPath } from "url";
@@ -413,9 +251,147 @@ async function runInit() {
413
251
  }
414
252
 
415
253
  // src/commands/login.ts
416
- init_config();
417
- init_client();
418
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
419
395
  async function runLogin(opts) {
420
396
  const baseUrl = (opts.server?.trim() || process.env.AI_PM_SERVER?.trim() || DEFAULT_BASE_URL).replace(/\/+$/, "");
421
397
  const apiKey = (opts.apiKey?.trim() || process.env.APM_API_KEY?.trim() || "").replace(/^Bearer\s+/i, "");
@@ -471,8 +447,6 @@ async function runLogin(opts) {
471
447
 
472
448
  // src/commands/update.ts
473
449
  import { spawnSync } from "child_process";
474
- import { existsSync as existsSync2 } from "fs";
475
- import { join as join4 } from "path";
476
450
 
477
451
  // src/version.ts
478
452
  import { readFileSync as readFileSync2 } from "fs";
@@ -595,7 +569,7 @@ async function runUpdate(options = {}) {
595
569
  });
596
570
  if (resolved.action === "skip") {
597
571
  console.log(`[apm] \u5DF2\u662F\u6700\u65B0\u7248\u672C ${current}`);
598
- return { didUpdate: false };
572
+ return;
599
573
  }
600
574
  if (resolved.majorUpgradeAvailable) {
601
575
  console.log(
@@ -632,54 +606,14 @@ async function runUpdate(options = {}) {
632
606
  } else {
633
607
  console.log(`[apm] \u5DF2\u662F\u6700\u65B0\u7248\u672C ${current}`);
634
608
  }
635
- return { didUpdate: expectedBump };
636
- }
637
- function resolveApmEntryPath(entryArg = process.argv[1]) {
638
- const fromArgv = entryArg?.trim();
639
- if (fromArgv && existsSync2(fromArgv)) {
640
- return fromArgv;
641
- }
642
- const npmResult = runNpm(["root", "-g"], {
643
- encoding: "utf8",
644
- stdio: ["ignore", "pipe", "pipe"]
645
- });
646
- if (npmResult.status === 0) {
647
- const globalRoot = npmResult.stdout?.toString().trim();
648
- if (globalRoot) {
649
- const candidate = join4(globalRoot, CLI_PACKAGE_NAME, "dist", "index.js");
650
- if (existsSync2(candidate)) {
651
- return candidate;
652
- }
653
- }
654
- }
655
- if (fromArgv) {
656
- return fromArgv;
657
- }
658
- console.error("[apm] \u65E0\u6CD5\u89E3\u6790 apm \u5165\u53E3\u8DEF\u5F84");
659
- process.exit(1);
660
- }
661
- function reexecConnectAfterUpdate(options) {
662
- console.log("[apm] \u66F4\u65B0\u5B8C\u6210\uFF0C\u6B63\u5728\u4EE5\u65B0\u7248\u672C\u91CD\u65B0\u8FDE\u63A5\u2026");
663
- const apmScript = resolveApmEntryPath();
664
- const args = [apmScript, "connect"];
665
- const server = options.server?.trim();
666
- if (server) {
667
- args.push("--server", server);
668
- }
669
- const result = spawnSync(process.execPath, args, { stdio: "inherit" });
670
- if (result.error) {
671
- console.error("[apm] \u91CD\u542F connect \u5931\u8D25:", result.error.message);
672
- process.exit(1);
673
- }
674
- process.exit(result.status ?? 0);
675
609
  }
676
610
 
677
611
  // src/commands/update-skills.ts
678
- import { existsSync as existsSync3, statSync as statSync2 } from "fs";
612
+ import { existsSync as existsSync2, statSync as statSync2 } from "fs";
679
613
  async function syncWorkspaceSkills(workdir) {
680
614
  const apmDir = workspaceApmDir(workdir);
681
615
  const fsApmDir = toFsPath(apmDir);
682
- if (!existsSync3(fsApmDir)) {
616
+ if (!existsSync2(fsApmDir)) {
683
617
  throw new Error("[apm] \u672A\u627E\u5230 .apm \u76EE\u5F55\uFF0C\u8BF7\u5148\u6267\u884C apm init");
684
618
  }
685
619
  const apmStat = statSync2(fsApmDir);
@@ -691,7 +625,7 @@ async function syncWorkspaceSkills(workdir) {
691
625
  }
692
626
  async function runUpdateSkills() {
693
627
  const apmDir = workspaceApmDir();
694
- if (!existsSync3(apmDir)) {
628
+ if (!existsSync2(apmDir)) {
695
629
  console.error("[apm] \u672A\u627E\u5230 .apm \u76EE\u5F55\uFF0C\u8BF7\u5148\u6267\u884C apm init");
696
630
  process.exit(1);
697
631
  }
@@ -702,21 +636,16 @@ async function runUpdateSkills() {
702
636
  await syncWorkspaceSkills(resolveWorkdirPath());
703
637
  }
704
638
 
705
- // src/commands/sync-project-documents.ts
706
- init_config();
707
-
708
639
  // src/utils/project-documents.ts
709
- init_client();
710
- init_config();
711
640
  import {
712
- existsSync as existsSync4,
641
+ existsSync as existsSync3,
713
642
  readdirSync as readdirSync2,
714
643
  readFileSync as readFileSync3,
715
644
  rmSync,
716
645
  writeFileSync as writeFileSync2
717
646
  } from "fs";
718
647
  import { createHash } from "crypto";
719
- import { dirname as dirname3, join as join5, relative, sep } from "path";
648
+ import { dirname as dirname3, join as join4, relative, sep } from "path";
720
649
 
721
650
  // src/utils/git.ts
722
651
  import { execFile as execFile2 } from "child_process";
@@ -790,11 +719,11 @@ function normalizeProjectIdForPath(projectId) {
790
719
  }
791
720
  function projectDocumentsDir(apmRoot, projectId) {
792
721
  const id = normalizeProjectIdForPath(projectId);
793
- return join5(apmRoot ?? workspaceApmDir(), "project", id);
722
+ return join4(apmRoot ?? workspaceApmDir(), "project", id);
794
723
  }
795
724
  function projectDocumentLocalPath(apmRoot, projectId, documentPath) {
796
725
  const normalized = normalizeLocalDocumentPath(documentPath);
797
- return join5(
726
+ return join4(
798
727
  projectDocumentsDir(apmRoot, projectId),
799
728
  ...normalized.split("/")
800
729
  );
@@ -814,11 +743,11 @@ function hashLocalFileContent(content) {
814
743
  return createHash("sha256").update(content, "utf8").digest("hex");
815
744
  }
816
745
  function readLocalManifest(apmRoot, projectId) {
817
- const manifestPath = join5(
746
+ const manifestPath = join4(
818
747
  projectDocumentsDir(apmRoot, projectId),
819
748
  MANIFEST_FILE
820
749
  );
821
- if (!existsSync4(manifestPath)) {
750
+ if (!existsSync3(manifestPath)) {
822
751
  return null;
823
752
  }
824
753
  try {
@@ -831,13 +760,13 @@ function readLocalManifest(apmRoot, projectId) {
831
760
  }
832
761
  function listLocalDocumentPaths(apmRoot, projectId) {
833
762
  const root = projectDocumentsDir(apmRoot, projectId);
834
- if (!existsSync4(root)) {
763
+ if (!existsSync3(root)) {
835
764
  return [];
836
765
  }
837
766
  const paths = [];
838
767
  const walk = (dir) => {
839
768
  for (const entry of readdirSync2(dir, { withFileTypes: true })) {
840
- const abs = join5(dir, entry.name);
769
+ const abs = join4(dir, entry.name);
841
770
  if (entry.isDirectory()) {
842
771
  walk(abs);
843
772
  continue;
@@ -966,13 +895,13 @@ ${diagnostic ?? ""}`);
966
895
  const absPath = toFsPath(
967
896
  projectDocumentLocalPath(targetApmDir, projectId, path)
968
897
  );
969
- if (existsSync4(absPath)) {
898
+ if (existsSync3(absPath)) {
970
899
  rmSync(absPath, { force: true });
971
900
  deleted += 1;
972
901
  }
973
902
  }
974
903
  writeFileSync2(
975
- toFsPath(join5(docsDir, MANIFEST_FILE)),
904
+ toFsPath(join4(docsDir, MANIFEST_FILE)),
976
905
  `${JSON.stringify(remoteManifest, null, 2)}
977
906
  `,
978
907
  "utf8"
@@ -1056,7 +985,6 @@ async function runSyncProjectDocuments(options) {
1056
985
  // src/commands/connect.ts
1057
986
  import WebSocket from "ws";
1058
987
  import { setTimeout as delay } from "node:timers/promises";
1059
- init_config();
1060
988
 
1061
989
  // src/ws/protocol.ts
1062
990
  function isWebIdeStartProjectTarget(value) {
@@ -1286,18 +1214,13 @@ function handleCancelAction(payload, ctx) {
1286
1214
  ctx.activeRuns.get(messageId)?.abort();
1287
1215
  }
1288
1216
 
1289
- // src/commands/connect/actions/webide-message.ts
1290
- init_client();
1291
-
1292
- // 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";
1293
1220
  import { Worker } from "node:worker_threads";
1221
+
1222
+ // src/commands/connect/core/worker/config.ts
1294
1223
  import { totalmem } from "node:os";
1295
- import { fileURLToPath as fileURLToPath3 } from "node:url";
1296
- import { dirname as dirname4, join as join6 } from "node:path";
1297
- var workerFile = join6(
1298
- dirname4(fileURLToPath3(import.meta.url)),
1299
- "webide-message-worker.js"
1300
- );
1301
1224
  var SYSTEM_RESERVE_MB = 3072;
1302
1225
  var MIN_WEBIDE_WORKER_HEAP_MB = 1536;
1303
1226
  var MAX_WEBIDE_WORKER_HEAP_MB = 8192;
@@ -1316,85 +1239,111 @@ function resolveWebIdeWorkerHeapMb(env = process.env, totalMemoryBytes = totalme
1316
1239
  if (!Number.isFinite(n)) return fallback;
1317
1240
  return Math.min(16384, Math.max(MIN_WEBIDE_WORKER_HEAP_MB, n));
1318
1241
  }
1319
- function spawnWebIdeMessageWorker(cfg, msg) {
1320
- const maxOldGenerationSizeMb = resolveWebIdeWorkerHeapMb();
1321
- const worker = new Worker(workerFile, {
1322
- workerData: { cfg, msg },
1323
- // worker_threads 不支持 execArgv 里的 --max-old-space-size,必须用 resourceLimits
1324
- resourceLimits: { maxOldGenerationSizeMb }
1325
- });
1326
- console.log(
1327
- `[apm] webide worker spawn messageId=${msg.messageId} heapMb=${maxOldGenerationSizeMb}`
1328
- );
1329
- let settled = false;
1330
- let resolveDone;
1331
- const done = new Promise((resolve3) => {
1332
- resolveDone = resolve3;
1333
- });
1334
- const failIfStillQueued = async (reason) => {
1335
- if (settled) return;
1336
- try {
1337
- const { createApmApiClient: createApmApiClient2 } = await Promise.resolve().then(() => (init_client(), client_exports));
1338
- const api = createApmApiClient2(cfg);
1339
- if (msg.type === "webide-package") {
1340
- await api.cli.projectPackageUpdateStatus({
1341
- id: msg.packageId,
1342
- status: "CANCELLED",
1343
- error: reason
1344
- });
1345
- return;
1346
- }
1347
- await api.cli.webideSetMessageError({
1348
- id: msg.messageId,
1349
- error: reason,
1350
- asCancelled: true
1351
- });
1352
- } catch (err) {
1353
- console.error(
1354
- `[apm] webide worker \u5931\u8D25\u5199\u7EC8\u6001\u5931\u8D25 messageId=${msg.messageId}:`,
1355
- err instanceof Error ? err.message : err
1356
- );
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");
1357
1261
  }
1358
- };
1359
- 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) => {
1360
1288
  if (m?.type === "done" || m?.type === "error") {
1361
- settled = true;
1362
1289
  if (m.type === "error") {
1363
1290
  console.error(
1364
1291
  `[apm] webide worker error messageId=${m.messageId}: ${m.error}`
1365
1292
  );
1366
1293
  }
1367
- void worker.terminate().finally(() => resolveDone());
1294
+ this.worker.terminate().finally(() => {
1295
+ this.resolve();
1296
+ });
1368
1297
  }
1369
- });
1370
- worker.on("error", (err) => {
1298
+ };
1299
+ onError = (err) => {
1371
1300
  const detail = err instanceof Error ? err.message : String(err);
1372
1301
  console.error("[apm] webide worker crashed:", err);
1373
- 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` : "";
1374
- void failIfStillQueued(`WebIDE worker \u5D29\u6E83: ${detail}${oomHint}`).finally(
1375
- () => resolveDone()
1376
- );
1377
- });
1378
- worker.on("exit", (code) => {
1379
- 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) {
1380
1307
  console.error(`[apm] webide worker exit code=${code}`);
1381
- void failIfStillQueued(`WebIDE worker \u5F02\u5E38\u9000\u51FA code=${code}`).finally(
1382
- () => resolveDone()
1383
- );
1308
+ this.failIfStillQueued(`WebIDE worker \u5F02\u5E38\u9000\u51FA code=${code}`);
1384
1309
  return;
1385
1310
  }
1386
1311
  if (code !== 0) {
1387
1312
  console.error(`[apm] webide worker exit code=${code}`);
1313
+ this.status = "error";
1314
+ return;
1388
1315
  }
1389
- resolveDone();
1390
- });
1391
- return {
1392
- cancel(messageId) {
1393
- worker.postMessage({ type: "cancel", messageId });
1394
- },
1395
- done
1316
+ this.status = "done";
1396
1317
  };
1397
- }
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
+ };
1398
1347
 
1399
1348
  // src/commands/connect/actions/types.ts
1400
1349
  function trackActionTask(ctx, task) {
@@ -1429,7 +1378,7 @@ function handleWebIdeMessageAction(payload, ctx) {
1429
1378
  return;
1430
1379
  }
1431
1380
  const task = (async () => {
1432
- const handle = spawnWebIdeMessageWorker(ctx.cfg, payload);
1381
+ const handle = new ActionWorker(payload);
1433
1382
  const onAbort = () => handle.cancel(payload.messageId);
1434
1383
  perMessageController.signal.addEventListener("abort", onAbort, {
1435
1384
  once: true
@@ -1445,7 +1394,6 @@ function handleWebIdeMessageAction(payload, ctx) {
1445
1394
  }
1446
1395
 
1447
1396
  // src/commands/connect/actions/start-project.ts
1448
- init_client();
1449
1397
  function handleStartProjectAction(payload, ctx) {
1450
1398
  const perMessageController = new AbortController();
1451
1399
  ctx.activeRuns.set(payload.messageId, perMessageController);
@@ -1470,7 +1418,7 @@ function handleStartProjectAction(payload, ctx) {
1470
1418
  return;
1471
1419
  }
1472
1420
  const task = (async () => {
1473
- const handle = spawnWebIdeMessageWorker(ctx.cfg, payload);
1421
+ const handle = new ActionWorker(payload);
1474
1422
  const onAbort = () => handle.cancel(payload.messageId);
1475
1423
  perMessageController.signal.addEventListener("abort", onAbort, {
1476
1424
  once: true
@@ -1485,8 +1433,7 @@ function handleStartProjectAction(payload, ctx) {
1485
1433
  trackActionTask(ctx, task);
1486
1434
  }
1487
1435
 
1488
- // src/commands/connect/pty-session-mcp.ts
1489
- init_config();
1436
+ // src/commands/connect/mcps/pty-session-mcp.ts
1490
1437
  var DEFAULT_PTY_SESSION_PORT = "7788";
1491
1438
  function resolvePtySessionBaseUrl(env = process.env) {
1492
1439
  const explicit = env.LOCAL_TERMINAL_URL?.trim();
@@ -1582,7 +1529,6 @@ function handleStopTerminalsAction(payload, ctx) {
1582
1529
  }
1583
1530
 
1584
1531
  // src/commands/connect/actions/package.ts
1585
- init_client();
1586
1532
  function handleWebIdePackageAction(payload, ctx) {
1587
1533
  const perMessageController = new AbortController();
1588
1534
  ctx.activeRuns.set(payload.messageId, perMessageController);
@@ -1608,7 +1554,7 @@ function handleWebIdePackageAction(payload, ctx) {
1608
1554
  return;
1609
1555
  }
1610
1556
  const task = (async () => {
1611
- const handle = spawnWebIdeMessageWorker(ctx.cfg, payload);
1557
+ const handle = new ActionWorker(payload);
1612
1558
  const onAbort = () => handle.cancel(payload.messageId);
1613
1559
  perMessageController.signal.addEventListener("abort", onAbort, {
1614
1560
  once: true
@@ -1647,25 +1593,15 @@ function dispatchConnectAction(payload, ctx) {
1647
1593
  }
1648
1594
 
1649
1595
  // src/commands/connect-lock.ts
1650
- init_config();
1651
1596
  import {
1652
- existsSync as existsSync5,
1597
+ existsSync as existsSync4,
1653
1598
  mkdirSync as mkdirSync3,
1654
1599
  readFileSync as readFileSync4,
1655
1600
  unlinkSync,
1656
1601
  writeFileSync as writeFileSync3
1657
1602
  } from "fs";
1658
- import { join as join7 } from "path";
1659
- var CONNECT_LOCK_PATH = join7(APM_CONFIG_DIR, "connect.lock");
1660
- var LEGACY_DAEMON_PID_PATH = join7(APM_CONFIG_DIR, "connect.pid");
1661
- var LEGACY_DAEMON_FILES = [
1662
- LEGACY_DAEMON_PID_PATH,
1663
- join7(APM_CONFIG_DIR, "connect.supervisor.cjs"),
1664
- join7(APM_CONFIG_DIR, "connect.launch.json"),
1665
- join7(APM_CONFIG_DIR, "connect.ecosystem.config.cjs"),
1666
- join7(APM_CONFIG_DIR, "connect.ecosystem.cjs"),
1667
- join7(APM_CONFIG_DIR, "connect.entry.cjs")
1668
- ];
1603
+ import { join as join6 } from "path";
1604
+ var CONNECT_LOCK_PATH = join6(APM_CONFIG_DIR, "connect.lock");
1669
1605
  function isProcessAlive(pid) {
1670
1606
  if (!Number.isInteger(pid) || pid <= 0) return false;
1671
1607
  try {
@@ -1675,30 +1611,8 @@ function isProcessAlive(pid) {
1675
1611
  return false;
1676
1612
  }
1677
1613
  }
1678
- function readLegacyDaemonPid() {
1679
- if (!existsSync5(LEGACY_DAEMON_PID_PATH)) return null;
1680
- try {
1681
- const pid = Number.parseInt(
1682
- readFileSync4(LEGACY_DAEMON_PID_PATH, "utf8").trim(),
1683
- 10
1684
- );
1685
- if (!Number.isInteger(pid) || pid <= 0) return null;
1686
- return pid;
1687
- } catch {
1688
- return null;
1689
- }
1690
- }
1691
- function removeLegacyDaemonFiles() {
1692
- for (const file of LEGACY_DAEMON_FILES) {
1693
- if (!existsSync5(file)) continue;
1694
- try {
1695
- unlinkSync(file);
1696
- } catch {
1697
- }
1698
- }
1699
- }
1700
1614
  function readConnectLock() {
1701
- if (!existsSync5(CONNECT_LOCK_PATH)) return null;
1615
+ if (!existsSync4(CONNECT_LOCK_PATH)) return null;
1702
1616
  try {
1703
1617
  const raw = readFileSync4(CONNECT_LOCK_PATH, "utf8");
1704
1618
  const parsed = JSON.parse(raw);
@@ -1751,24 +1665,6 @@ function releaseConnectLock() {
1751
1665
  } catch {
1752
1666
  }
1753
1667
  }
1754
- function assertConnectNotRunning() {
1755
- pruneStaleConnectLock();
1756
- const lock = readConnectLock();
1757
- if (lock && isProcessAlive(lock.pid) && lock.pid !== process.pid) {
1758
- console.error(
1759
- `[apm] \u5DF2\u6709 apm connect \u5728\u8FD0\u884C (pid=${lock.pid})\uFF0C\u8BF7\u5148\u505C\u6B62\u540E\u518D\u542F\u52A8`
1760
- );
1761
- process.exit(1);
1762
- }
1763
- const legacyPid = readLegacyDaemonPid();
1764
- if (legacyPid && isProcessAlive(legacyPid) && legacyPid !== process.pid) {
1765
- console.error(
1766
- `[apm] \u68C0\u6D4B\u5230\u65E7\u7248\u540E\u53F0 connect (pid=${legacyPid})\uFF0C\u8BF7\u5148\u7ED3\u675F\u8BE5\u8FDB\u7A0B\u540E\u518D\u542F\u52A8`
1767
- );
1768
- process.exit(1);
1769
- }
1770
- removeLegacyDaemonFiles();
1771
- }
1772
1668
 
1773
1669
  // src/commands/connect.ts
1774
1670
  var HEARTBEAT_MS = 3e4;
@@ -1882,10 +1778,6 @@ function resolveConnectServerOption(options) {
1882
1778
  return void 0;
1883
1779
  }
1884
1780
  async function runConnect(options) {
1885
- const { didUpdate } = await runUpdate();
1886
- if (didUpdate) {
1887
- reexecConnectAfterUpdate(options);
1888
- }
1889
1781
  const cfg = await ensureLoggedConfig();
1890
1782
  const serverOverride = resolveConnectServerOption(options);
1891
1783
  if (serverOverride) {
@@ -1896,7 +1788,6 @@ async function runConnect(options) {
1896
1788
  console.error("[apm] config \u7F3A\u5C11 clientMachineId\uFF0C\u8BF7\u91CD\u65B0 apm login");
1897
1789
  process.exit(1);
1898
1790
  }
1899
- assertConnectNotRunning();
1900
1791
  acquireConnectLock();
1901
1792
  process.on("exit", releaseConnectLock);
1902
1793
  let shuttingDown = false;
@@ -2013,7 +1904,7 @@ function buildProgram() {
2013
1904
  await runSyncProjectDocuments(opts);
2014
1905
  });
2015
1906
  program.command("connect").description(
2016
- "\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"
2017
1908
  ).option("--server <url>", "API \u6839\u5730\u5740\uFF0C\u8986\u76D6 config \u4E2D\u7684 baseUrl").action(async (opts) => {
2018
1909
  await runConnect({ server: opts.server });
2019
1910
  });