ai-project-manage-cli 8.0.18 → 8.1.1

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) {
@@ -1123,6 +1043,7 @@ function validateWebIdeMessagePush(o) {
1123
1043
  if (!nonEmptyString(o.user)) {
1124
1044
  return { ok: false, reason: "webide-message \u7F3A\u5C11 user" };
1125
1045
  }
1046
+ const useNewAgent = o.useNewAgent === true;
1126
1047
  return {
1127
1048
  ok: true,
1128
1049
  data: {
@@ -1134,7 +1055,8 @@ function validateWebIdeMessagePush(o) {
1134
1055
  model: o.model.trim(),
1135
1056
  apiKey: o.apiKey.trim(),
1136
1057
  workdir: o.workdir.trim(),
1137
- user: o.user.trim()
1058
+ user: o.user.trim(),
1059
+ ...useNewAgent ? { useNewAgent: true } : {}
1138
1060
  }
1139
1061
  };
1140
1062
  }
@@ -1294,18 +1216,13 @@ function handleCancelAction(payload, ctx) {
1294
1216
  ctx.activeRuns.get(messageId)?.abort();
1295
1217
  }
1296
1218
 
1297
- // src/commands/connect/actions/webide-message.ts
1298
- init_client();
1299
-
1300
- // src/commands/connect/webide-worker-pool.ts
1219
+ // src/commands/connect/core/worker/worker.ts
1220
+ import { dirname as dirname4, join as join5 } from "path";
1221
+ import { fileURLToPath as fileURLToPath3 } from "url";
1301
1222
  import { Worker } from "node:worker_threads";
1223
+
1224
+ // src/commands/connect/core/worker/config.ts
1302
1225
  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
1226
  var SYSTEM_RESERVE_MB = 3072;
1310
1227
  var MIN_WEBIDE_WORKER_HEAP_MB = 1536;
1311
1228
  var MAX_WEBIDE_WORKER_HEAP_MB = 8192;
@@ -1324,85 +1241,111 @@ function resolveWebIdeWorkerHeapMb(env = process.env, totalMemoryBytes = totalme
1324
1241
  if (!Number.isFinite(n)) return fallback;
1325
1242
  return Math.min(16384, Math.max(MIN_WEBIDE_WORKER_HEAP_MB, n));
1326
1243
  }
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
- );
1244
+
1245
+ // src/commands/connect/core/worker/worker.ts
1246
+ var workerFile = join5(
1247
+ dirname4(fileURLToPath3(import.meta.url)),
1248
+ "worker-script.js"
1249
+ );
1250
+ var ActionWorker = class {
1251
+ worker;
1252
+ _status = "pending";
1253
+ maxOldGenerationSizeMb = resolveWebIdeWorkerHeapMb();
1254
+ apmClient;
1255
+ msg;
1256
+ promise;
1257
+ resolve;
1258
+ reject;
1259
+ constructor(msg) {
1260
+ const cfg = tryReadApmConfig();
1261
+ if (!cfg) {
1262
+ throw new Error("\u672A\u68C0\u6D4B\u5230\u767B\u5F55\u4FE1\u606F\uFF0C\u8BF7\u5148\u6267\u884C apm login");
1365
1263
  }
1366
- };
1367
- worker.on("message", (m) => {
1264
+ this.msg = msg;
1265
+ this.apmClient = createApmApiClient(cfg);
1266
+ this.promise = new Promise((resolve3, reject) => {
1267
+ this.resolve = resolve3;
1268
+ this.reject = reject;
1269
+ });
1270
+ this.worker = new Worker(workerFile, {
1271
+ workerData: { msg, cfg },
1272
+ resourceLimits: { maxOldGenerationSizeMb: this.maxOldGenerationSizeMb }
1273
+ });
1274
+ this.worker.on("message", this.onMessage);
1275
+ this.worker.on("error", this.onError);
1276
+ this.worker.on("exit", this.onExit);
1277
+ }
1278
+ get status() {
1279
+ return this._status;
1280
+ }
1281
+ set status(value) {
1282
+ this._status = value;
1283
+ if (value === "done") {
1284
+ this.resolve();
1285
+ } else if (value === "error") {
1286
+ this.reject();
1287
+ }
1288
+ }
1289
+ onMessage = (m) => {
1368
1290
  if (m?.type === "done" || m?.type === "error") {
1369
- settled = true;
1370
1291
  if (m.type === "error") {
1371
1292
  console.error(
1372
1293
  `[apm] webide worker error messageId=${m.messageId}: ${m.error}`
1373
1294
  );
1374
1295
  }
1375
- void worker.terminate().finally(() => resolveDone());
1296
+ this.worker.terminate().finally(() => {
1297
+ this.resolve();
1298
+ });
1376
1299
  }
1377
- });
1378
- worker.on("error", (err) => {
1300
+ };
1301
+ onError = (err) => {
1379
1302
  const detail = err instanceof Error ? err.message : String(err);
1380
1303
  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) {
1304
+ 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` : "";
1305
+ this.failIfStillQueued(`WebIDE worker \u5D29\u6E83: ${detail}${oomHint}`);
1306
+ };
1307
+ onExit = async (code) => {
1308
+ if (this.status === "pending" && code !== 0) {
1388
1309
  console.error(`[apm] webide worker exit code=${code}`);
1389
- void failIfStillQueued(`WebIDE worker \u5F02\u5E38\u9000\u51FA code=${code}`).finally(
1390
- () => resolveDone()
1391
- );
1310
+ this.failIfStillQueued(`WebIDE worker \u5F02\u5E38\u9000\u51FA code=${code}`);
1392
1311
  return;
1393
1312
  }
1394
1313
  if (code !== 0) {
1395
1314
  console.error(`[apm] webide worker exit code=${code}`);
1315
+ this.status = "error";
1316
+ return;
1396
1317
  }
1397
- resolveDone();
1398
- });
1399
- return {
1400
- cancel(messageId) {
1401
- worker.postMessage({ type: "cancel", messageId });
1402
- },
1403
- done
1318
+ this.status = "done";
1404
1319
  };
1405
- }
1320
+ failIfStillQueued = async (reason) => {
1321
+ if (this.status !== "pending") return;
1322
+ try {
1323
+ if (this.msg.type === "webide-package") {
1324
+ await this.apmClient.cli.projectPackageUpdateStatus({
1325
+ id: this.msg.packageId,
1326
+ status: "CANCELLED",
1327
+ error: reason
1328
+ });
1329
+ return;
1330
+ }
1331
+ await this.apmClient.cli.webideSetMessageError({
1332
+ id: this.msg.messageId,
1333
+ error: reason,
1334
+ asCancelled: true
1335
+ });
1336
+ } catch (err) {
1337
+ console.error("[apm] WebIDE worker \u5931\u8D25\u5199\u7EC8\u6001\u5931\u8D25:", err);
1338
+ } finally {
1339
+ this.status = "error";
1340
+ }
1341
+ };
1342
+ cancel(msg_id) {
1343
+ this.worker.postMessage({ type: "cancel", messageId: msg_id });
1344
+ }
1345
+ get done() {
1346
+ return this.promise;
1347
+ }
1348
+ };
1406
1349
 
1407
1350
  // src/commands/connect/actions/types.ts
1408
1351
  function trackActionTask(ctx, task) {
@@ -1437,7 +1380,7 @@ function handleWebIdeMessageAction(payload, ctx) {
1437
1380
  return;
1438
1381
  }
1439
1382
  const task = (async () => {
1440
- const handle = spawnWebIdeMessageWorker(ctx.cfg, payload);
1383
+ const handle = new ActionWorker(payload);
1441
1384
  const onAbort = () => handle.cancel(payload.messageId);
1442
1385
  perMessageController.signal.addEventListener("abort", onAbort, {
1443
1386
  once: true
@@ -1453,7 +1396,6 @@ function handleWebIdeMessageAction(payload, ctx) {
1453
1396
  }
1454
1397
 
1455
1398
  // src/commands/connect/actions/start-project.ts
1456
- init_client();
1457
1399
  function handleStartProjectAction(payload, ctx) {
1458
1400
  const perMessageController = new AbortController();
1459
1401
  ctx.activeRuns.set(payload.messageId, perMessageController);
@@ -1478,7 +1420,7 @@ function handleStartProjectAction(payload, ctx) {
1478
1420
  return;
1479
1421
  }
1480
1422
  const task = (async () => {
1481
- const handle = spawnWebIdeMessageWorker(ctx.cfg, payload);
1423
+ const handle = new ActionWorker(payload);
1482
1424
  const onAbort = () => handle.cancel(payload.messageId);
1483
1425
  perMessageController.signal.addEventListener("abort", onAbort, {
1484
1426
  once: true
@@ -1493,8 +1435,7 @@ function handleStartProjectAction(payload, ctx) {
1493
1435
  trackActionTask(ctx, task);
1494
1436
  }
1495
1437
 
1496
- // src/commands/connect/pty-session-mcp.ts
1497
- init_config();
1438
+ // src/commands/connect/mcps/pty-session-mcp.ts
1498
1439
  var DEFAULT_PTY_SESSION_PORT = "7788";
1499
1440
  function resolvePtySessionBaseUrl(env = process.env) {
1500
1441
  const explicit = env.LOCAL_TERMINAL_URL?.trim();
@@ -1590,7 +1531,6 @@ function handleStopTerminalsAction(payload, ctx) {
1590
1531
  }
1591
1532
 
1592
1533
  // src/commands/connect/actions/package.ts
1593
- init_client();
1594
1534
  function handleWebIdePackageAction(payload, ctx) {
1595
1535
  const perMessageController = new AbortController();
1596
1536
  ctx.activeRuns.set(payload.messageId, perMessageController);
@@ -1616,7 +1556,7 @@ function handleWebIdePackageAction(payload, ctx) {
1616
1556
  return;
1617
1557
  }
1618
1558
  const task = (async () => {
1619
- const handle = spawnWebIdeMessageWorker(ctx.cfg, payload);
1559
+ const handle = new ActionWorker(payload);
1620
1560
  const onAbort = () => handle.cancel(payload.messageId);
1621
1561
  perMessageController.signal.addEventListener("abort", onAbort, {
1622
1562
  once: true
@@ -1655,25 +1595,15 @@ function dispatchConnectAction(payload, ctx) {
1655
1595
  }
1656
1596
 
1657
1597
  // src/commands/connect-lock.ts
1658
- init_config();
1659
1598
  import {
1660
- existsSync as existsSync5,
1599
+ existsSync as existsSync4,
1661
1600
  mkdirSync as mkdirSync3,
1662
1601
  readFileSync as readFileSync4,
1663
1602
  unlinkSync,
1664
1603
  writeFileSync as writeFileSync3
1665
1604
  } 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
- ];
1605
+ import { join as join6 } from "path";
1606
+ var CONNECT_LOCK_PATH = join6(APM_CONFIG_DIR, "connect.lock");
1677
1607
  function isProcessAlive(pid) {
1678
1608
  if (!Number.isInteger(pid) || pid <= 0) return false;
1679
1609
  try {
@@ -1683,30 +1613,8 @@ function isProcessAlive(pid) {
1683
1613
  return false;
1684
1614
  }
1685
1615
  }
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
1616
  function readConnectLock() {
1709
- if (!existsSync5(CONNECT_LOCK_PATH)) return null;
1617
+ if (!existsSync4(CONNECT_LOCK_PATH)) return null;
1710
1618
  try {
1711
1619
  const raw = readFileSync4(CONNECT_LOCK_PATH, "utf8");
1712
1620
  const parsed = JSON.parse(raw);
@@ -1759,24 +1667,6 @@ function releaseConnectLock() {
1759
1667
  } catch {
1760
1668
  }
1761
1669
  }
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
1670
 
1781
1671
  // src/commands/connect.ts
1782
1672
  var HEARTBEAT_MS = 3e4;
@@ -1890,10 +1780,6 @@ function resolveConnectServerOption(options) {
1890
1780
  return void 0;
1891
1781
  }
1892
1782
  async function runConnect(options) {
1893
- const { didUpdate } = await runUpdate();
1894
- if (didUpdate) {
1895
- reexecConnectAfterUpdate(options);
1896
- }
1897
1783
  const cfg = await ensureLoggedConfig();
1898
1784
  const serverOverride = resolveConnectServerOption(options);
1899
1785
  if (serverOverride) {
@@ -1904,7 +1790,6 @@ async function runConnect(options) {
1904
1790
  console.error("[apm] config \u7F3A\u5C11 clientMachineId\uFF0C\u8BF7\u91CD\u65B0 apm login");
1905
1791
  process.exit(1);
1906
1792
  }
1907
- assertConnectNotRunning();
1908
1793
  acquireConnectLock();
1909
1794
  process.on("exit", releaseConnectLock);
1910
1795
  let shuttingDown = false;
@@ -2021,7 +1906,7 @@ function buildProgram() {
2021
1906
  await runSyncProjectDocuments(opts);
2022
1907
  });
2023
1908
  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"
1909
+ "\u8FDE\u63A5\u5E73\u53F0 WebSocket\uFF08/ws/agent\uFF09\uFF0C\u7EF4\u6301\u5FC3\u8DF3\u5E76\u5904\u7406\u4E0B\u884C webide-message"
2025
1910
  ).option("--server <url>", "API \u6839\u5730\u5740\uFF0C\u8986\u76D6 config \u4E2D\u7684 baseUrl").action(async (opts) => {
2026
1911
  await runConnect({ server: opts.server });
2027
1912
  });