ai-project-manage-cli 8.1.7 → 8.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -22,7 +22,7 @@ apm login --api-key=cm_xxx --server=http://127.0.0.1:3000
22
22
  apm init
23
23
  ```
24
24
 
25
- WebIDE 工作区写入 `.apm/AGENTS.md` 与 `webide*` 规则。
25
+ 从平台拉取指南与规则,写入 `.apm/AGENTS.md` 与 `.apm/rules/`。需要先 `apm login`。
26
26
 
27
27
  ## 常用命令
28
28
 
package/dist/index.js CHANGED
@@ -79,179 +79,9 @@ function buildAgentWsUrl(httpBase, apiKey) {
79
79
  return `${origin}/ws/agent?${q.toString()}`;
80
80
  }
81
81
 
82
- // src/utils/workspace.ts
83
- import { copyFileSync, existsSync, mkdirSync as mkdirSync2, readdirSync, statSync } from "fs";
84
- import { dirname, join as join2, resolve as resolve2 } from "path";
85
- import { fileURLToPath } from "url";
86
-
87
- // src/utils/path.ts
88
- import { realpathSync } from "fs";
89
- import { platform } from "os";
90
- import { resolve } from "path";
91
- function toFsPath(inputPath) {
92
- const absolute = resolve(inputPath);
93
- if (platform() !== "win32") return absolute;
94
- if (absolute.startsWith("\\\\?\\")) return absolute;
95
- const normalized = absolute.replace(/\//g, "\\");
96
- if (normalized.startsWith("\\\\")) {
97
- return `\\\\?\\UNC\\${normalized.slice(2)}`;
98
- }
99
- return `\\\\?\\${normalized}`;
100
- }
101
- function normalizeWorkdirPath(path) {
102
- let normalized = path.trim().replace(/\\/g, "/").normalize("NFC");
103
- if (normalized.startsWith("//?/")) {
104
- normalized = normalized.slice(4);
105
- }
106
- const windowsDrive = /^([A-Za-z]:)\/*(.*)$/.exec(normalized);
107
- if (windowsDrive) {
108
- const drive = windowsDrive[1].toLowerCase();
109
- const rest = windowsDrive[2].replace(/\/+/g, "/").replace(/\/$/, "");
110
- return rest ? `${drive}/${rest}` : drive;
111
- }
112
- normalized = normalized.replace(/\/+/g, "/");
113
- if (normalized.length > 1 && normalized.endsWith("/")) {
114
- normalized = normalized.slice(0, -1);
115
- }
116
- return normalized;
117
- }
118
- function resolveWorkdirPath(cwd = process.cwd()) {
119
- const absolute = resolve(cwd);
120
- try {
121
- return normalizeWorkdirPath(realpathSync.native(absolute));
122
- } catch {
123
- return normalizeWorkdirPath(absolute);
124
- }
125
- }
126
-
127
- // src/utils/workspace.ts
128
- var __dirname = dirname(fileURLToPath(import.meta.url));
129
- var CLI_TEMPLATE_DIR = resolve2(__dirname, "../template");
130
- function workspaceApmDir(cwd = resolveWorkdirPath()) {
131
- return resolve2(resolve2(cwd), ".apm");
132
- }
133
- async function ensureLoggedConfig() {
134
- const cfg = await ensureApmConfig();
135
- if (!resolveApiKey(cfg)) {
136
- console.error(
137
- "[apm] \u672A\u68C0\u6D4B\u5230 API Key\uFF0C\u8BF7\u5148\u6267\u884C: apm login --api-key cm_xxx"
138
- );
139
- process.exit(1);
140
- }
141
- return cfg;
142
- }
143
- async function ensureDirExists(dir) {
144
- mkdirSync2(dir, { recursive: true });
145
- }
146
- async function ensureWorkspaceApmDirForInit(cwd = resolveWorkdirPath()) {
147
- const dir = workspaceApmDir(cwd);
148
- const fsDir = toFsPath(dir);
149
- if (existsSync(fsDir) && !statSync(fsDir).isDirectory()) {
150
- throw new Error(`[apm] \u8DEF\u5F84\u5DF2\u5B58\u5728\u4F46\u4E0D\u662F\u76EE\u5F55: ${dir}`);
151
- }
152
- mkdirSync2(fsDir, { recursive: true });
153
- }
154
- var WEBIDE_AGENTS_TEMPLATE_NAME = "AGENTS.webide.md";
155
- function shouldSkipTemplateEntry(name) {
156
- return name === ".DS_Store" || name === "Thumbs.db";
157
- }
158
- function isWebIdeRuleFileName(name) {
159
- return name.startsWith("webide");
160
- }
161
- function copyTemplateEntry(src, dest) {
162
- const fsSrc = toFsPath(src);
163
- const fsDest = toFsPath(dest);
164
- const st = statSync(fsSrc);
165
- if (st.isDirectory()) {
166
- mkdirSync2(fsDest, { recursive: true });
167
- for (const name of readdirSync(fsSrc)) {
168
- if (shouldSkipTemplateEntry(name)) continue;
169
- copyTemplateEntry(join2(src, name), join2(dest, name));
170
- }
171
- return;
172
- }
173
- if (!st.isFile()) return;
174
- mkdirSync2(toFsPath(dirname(dest)), { recursive: true });
175
- copyFileSync(fsSrc, fsDest);
176
- }
177
- function listWebIdeRuleFileNames(rulesDir) {
178
- const fsRulesDir = toFsPath(rulesDir);
179
- if (!existsSync(fsRulesDir) || !statSync(fsRulesDir).isDirectory()) {
180
- return [];
181
- }
182
- return readdirSync(fsRulesDir).filter((name) => {
183
- if (shouldSkipTemplateEntry(name) || !isWebIdeRuleFileName(name)) {
184
- return false;
185
- }
186
- return statSync(toFsPath(join2(rulesDir, name))).isFile();
187
- });
188
- }
189
- function assertWebIdeTemplateCopiedToApm(apmDir, workdir) {
190
- const required = ["AGENTS.md", "rules"];
191
- for (const item of required) {
192
- const path = join2(apmDir, item);
193
- if (!existsSync(toFsPath(path))) {
194
- throw new Error(`[apm] WebIDE \u521D\u59CB\u5316\u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5C11: ${path}`);
195
- }
196
- }
197
- const rulesDir = join2(apmDir, "rules");
198
- const ruleNames = listWebIdeRuleFileNames(rulesDir);
199
- if (ruleNames.length === 0) {
200
- throw new Error(`[apm] WebIDE \u521D\u59CB\u5316\u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5C11 webide \u89C4\u5219: ${rulesDir}`);
201
- }
202
- const leakedRules = join2(workdir, "rules");
203
- const apmRules = join2(apmDir, "rules");
204
- if (existsSync(toFsPath(leakedRules)) && !existsSync(toFsPath(join2(apmRules, "webide_reply.md")))) {
205
- throw new Error(
206
- `[apm] \u6A21\u677F\u88AB\u590D\u5236\u5230\u9519\u8BEF\u4F4D\u7F6E: ${leakedRules}\uFF08\u5E94\u5728 ${apmRules}\uFF09`
207
- );
208
- }
209
- }
210
- async function copyWebIdeTemplateFiles(targetDir, workdir = resolveWorkdirPath()) {
211
- const resolvedTarget = resolve2(targetDir);
212
- const templateDir = resolve2(CLI_TEMPLATE_DIR);
213
- const fsTemplateDir = toFsPath(templateDir);
214
- if (!existsSync(fsTemplateDir) || !statSync(fsTemplateDir).isDirectory()) {
215
- throw new Error(`[apm] \u672A\u627E\u5230 CLI \u6A21\u677F\u76EE\u5F55: ${templateDir}`);
216
- }
217
- const agentsSrc = join2(templateDir, WEBIDE_AGENTS_TEMPLATE_NAME);
218
- if (!existsSync(toFsPath(agentsSrc))) {
219
- throw new Error(`[apm] \u672A\u627E\u5230 WebIDE \u6307\u5357: ${agentsSrc}`);
220
- }
221
- const rulesSrc = join2(templateDir, "rules");
222
- const ruleNames = listWebIdeRuleFileNames(rulesSrc);
223
- if (ruleNames.length === 0) {
224
- throw new Error(`[apm] CLI \u6A21\u677F\u4E2D\u6CA1\u6709 webide \u89C4\u5219: ${rulesSrc}`);
225
- }
226
- mkdirSync2(toFsPath(resolvedTarget), { recursive: true });
227
- copyFileSync(
228
- toFsPath(agentsSrc),
229
- toFsPath(join2(resolvedTarget, "AGENTS.md"))
230
- );
231
- const rulesDest = join2(resolvedTarget, "rules");
232
- mkdirSync2(toFsPath(rulesDest), { recursive: true });
233
- for (const name of ruleNames) {
234
- copyTemplateEntry(join2(rulesSrc, name), join2(rulesDest, name));
235
- }
236
- assertWebIdeTemplateCopiedToApm(resolvedTarget, resolve2(workdir));
237
- }
238
-
239
- // src/commands/init.ts
240
- async function initializeWorkspace(workdir) {
241
- await ensureWorkspaceApmDirForInit(workdir);
242
- const apmDir = workspaceApmDir(workdir);
243
- await copyWebIdeTemplateFiles(apmDir, workdir);
244
- console.log(`[apm] \u5DF2\u6309 WebIDE \u521D\u59CB\u5316\u5DE5\u4F5C\u533A\uFF1A${apmDir}`);
245
- return { didInit: true };
246
- }
247
- async function runInit() {
248
- const workdir = resolveWorkdirPath();
249
- await initializeWorkspace(workdir);
250
- console.log(`[apm] \u5DE5\u4F5C\u76EE\u5F55\u8DEF\u5F84\uFF1A${workdir}`);
251
- }
252
-
253
- // src/commands/login.ts
254
- import { ApiError } from "listpage-http";
82
+ // src/commands/sync-webide-agent.ts
83
+ import { existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
84
+ import { join as join3 } from "path";
255
85
 
256
86
  // src/api/client.ts
257
87
  import { createApiClient } from "listpage-http";
@@ -266,6 +96,10 @@ var requestConfig = {
266
96
  path: "/cli/me"
267
97
  }
268
98
  ),
99
+ webideAgentConfig: defineEndpoint({
100
+ method: "GET",
101
+ path: "/cli/webide/agent-config"
102
+ }),
269
103
  webideAppendMessageContent: defineEndpoint({
270
104
  method: "PUT",
271
105
  path: "/cli/webide/messages/content"
@@ -464,7 +298,157 @@ function createApmApiClient(cfg) {
464
298
  });
465
299
  }
466
300
 
301
+ // src/utils/path.ts
302
+ import { realpathSync } from "fs";
303
+ import { platform } from "os";
304
+ import { resolve } from "path";
305
+ function toFsPath(inputPath) {
306
+ const absolute = resolve(inputPath);
307
+ if (platform() !== "win32") return absolute;
308
+ if (absolute.startsWith("\\\\?\\")) return absolute;
309
+ const normalized = absolute.replace(/\//g, "\\");
310
+ if (normalized.startsWith("\\\\")) {
311
+ return `\\\\?\\UNC\\${normalized.slice(2)}`;
312
+ }
313
+ return `\\\\?\\${normalized}`;
314
+ }
315
+ function normalizeWorkdirPath(path) {
316
+ let normalized = path.trim().replace(/\\/g, "/").normalize("NFC");
317
+ if (normalized.startsWith("//?/")) {
318
+ normalized = normalized.slice(4);
319
+ }
320
+ const windowsDrive = /^([A-Za-z]:)\/*(.*)$/.exec(normalized);
321
+ if (windowsDrive) {
322
+ const drive = windowsDrive[1].toLowerCase();
323
+ const rest = windowsDrive[2].replace(/\/+/g, "/").replace(/\/$/, "");
324
+ return rest ? `${drive}/${rest}` : drive;
325
+ }
326
+ normalized = normalized.replace(/\/+/g, "/");
327
+ if (normalized.length > 1 && normalized.endsWith("/")) {
328
+ normalized = normalized.slice(0, -1);
329
+ }
330
+ return normalized;
331
+ }
332
+ function resolveWorkdirPath(cwd = process.cwd()) {
333
+ const absolute = resolve(cwd);
334
+ try {
335
+ return normalizeWorkdirPath(realpathSync.native(absolute));
336
+ } catch {
337
+ return normalizeWorkdirPath(absolute);
338
+ }
339
+ }
340
+
341
+ // src/utils/workspace.ts
342
+ import { existsSync, mkdirSync as mkdirSync2, readdirSync, statSync } from "fs";
343
+ import { join as join2, resolve as resolve2 } from "path";
344
+ function workspaceApmDir(cwd = resolveWorkdirPath()) {
345
+ return resolve2(resolve2(cwd), ".apm");
346
+ }
347
+ async function ensureLoggedConfig() {
348
+ const cfg = await ensureApmConfig();
349
+ if (!resolveApiKey(cfg)) {
350
+ console.error(
351
+ "[apm] \u672A\u68C0\u6D4B\u5230 API Key\uFF0C\u8BF7\u5148\u6267\u884C: apm login --api-key cm_xxx"
352
+ );
353
+ process.exit(1);
354
+ }
355
+ return cfg;
356
+ }
357
+ async function ensureDirExists(dir) {
358
+ mkdirSync2(dir, { recursive: true });
359
+ }
360
+ async function ensureWorkspaceApmDirForInit(cwd = resolveWorkdirPath()) {
361
+ const dir = workspaceApmDir(cwd);
362
+ const fsDir = toFsPath(dir);
363
+ if (existsSync(fsDir) && !statSync(fsDir).isDirectory()) {
364
+ throw new Error(`[apm] \u8DEF\u5F84\u5DF2\u5B58\u5728\u4F46\u4E0D\u662F\u76EE\u5F55: ${dir}`);
365
+ }
366
+ mkdirSync2(fsDir, { recursive: true });
367
+ }
368
+
369
+ // src/commands/sync-webide-agent.ts
370
+ var REVISION_FILE = ".webide-agent.json";
371
+ var RULE_KEY = /^webide_[a-z0-9_]+$/;
372
+ function withTrailingNewline(text) {
373
+ return text.endsWith("\n") ? text : `${text}
374
+ `;
375
+ }
376
+ function readRevision(apmDir) {
377
+ const path = toFsPath(join3(apmDir, REVISION_FILE));
378
+ if (!existsSync2(path)) return null;
379
+ try {
380
+ const parsed = JSON.parse(readFileSync2(path, "utf8"));
381
+ if (parsed?.version === 1 && parsed.revision?.trim()) {
382
+ return parsed.revision.trim();
383
+ }
384
+ } catch {
385
+ return null;
386
+ }
387
+ return null;
388
+ }
389
+ function writeRevision(apmDir, revision) {
390
+ writeFileSync2(
391
+ toFsPath(join3(apmDir, REVISION_FILE)),
392
+ `${JSON.stringify({ version: 1, revision }, null, 2)}
393
+ `,
394
+ "utf8"
395
+ );
396
+ }
397
+ async function syncWebIdeAgentFiles(workdir, cfg) {
398
+ const api = createApmApiClient(cfg);
399
+ const bundle = await api.cli.webideAgentConfig();
400
+ const revision = bundle.revision?.trim();
401
+ if (!revision) {
402
+ throw new Error("[apm] \u5E73\u53F0\u672A\u8FD4\u56DE WebIDE \u89C4\u5219\u7248\u672C");
403
+ }
404
+ const apmDir = workspaceApmDir(workdir);
405
+ mkdirSync3(toFsPath(apmDir), { recursive: true });
406
+ if (readRevision(apmDir) === revision) {
407
+ return { revision, wrote: false, ruleCount: bundle.rules?.length ?? 0 };
408
+ }
409
+ const rulesDir = join3(apmDir, "rules");
410
+ mkdirSync3(toFsPath(rulesDir), { recursive: true });
411
+ writeFileSync2(
412
+ toFsPath(join3(apmDir, "AGENTS.md")),
413
+ withTrailingNewline(bundle.guide ?? ""),
414
+ "utf8"
415
+ );
416
+ for (const rule of bundle.rules ?? []) {
417
+ const key = rule.key?.trim() ?? "";
418
+ if (!RULE_KEY.test(key)) {
419
+ throw new Error(`[apm] \u975E\u6CD5\u89C4\u5219\u540D: ${key || "(\u7A7A)"}`);
420
+ }
421
+ writeFileSync2(
422
+ toFsPath(join3(rulesDir, `${key}.md`)),
423
+ withTrailingNewline(rule.body ?? ""),
424
+ "utf8"
425
+ );
426
+ }
427
+ writeRevision(apmDir, revision);
428
+ return {
429
+ revision,
430
+ wrote: true,
431
+ ruleCount: bundle.rules?.length ?? 0
432
+ };
433
+ }
434
+
435
+ // src/commands/init.ts
436
+ async function initializeWorkspace(workdir, cfg) {
437
+ await ensureWorkspaceApmDirForInit(workdir);
438
+ await syncWebIdeAgentFiles(workdir, cfg);
439
+ const apmDir = workspaceApmDir(workdir);
440
+ console.log(`[apm] \u5DF2\u6309 WebIDE \u521D\u59CB\u5316\u5DE5\u4F5C\u533A\uFF1A${apmDir}`);
441
+ return { didInit: true };
442
+ }
443
+ async function runInit() {
444
+ const workdir = resolveWorkdirPath();
445
+ const cfg = await ensureLoggedConfig();
446
+ await initializeWorkspace(workdir, cfg);
447
+ console.log(`[apm] \u5DE5\u4F5C\u76EE\u5F55\u8DEF\u5F84\uFF1A${workdir}`);
448
+ }
449
+
467
450
  // src/commands/login.ts
451
+ import { ApiError } from "listpage-http";
468
452
  async function runLogin(opts) {
469
453
  const baseUrl = (opts.server?.trim() || process.env.AI_PM_SERVER?.trim() || DEFAULT_BASE_URL).replace(/\/+$/, "");
470
454
  const apiKey = (opts.apiKey?.trim() || process.env.APM_API_KEY?.trim() || "").replace(/^Bearer\s+/i, "");
@@ -520,19 +504,19 @@ async function runLogin(opts) {
520
504
 
521
505
  // src/commands/update.ts
522
506
  import { spawnSync } from "child_process";
523
- import { existsSync as existsSync2 } from "fs";
524
- import { join as join4 } from "path";
507
+ import { existsSync as existsSync3 } from "fs";
508
+ import { join as join5 } from "path";
525
509
 
526
510
  // src/version.ts
527
- import { readFileSync as readFileSync2 } from "fs";
528
- import { dirname as dirname2, join as join3 } from "path";
529
- import { fileURLToPath as fileURLToPath2 } from "url";
511
+ import { readFileSync as readFileSync3 } from "fs";
512
+ import { dirname, join as join4 } from "path";
513
+ import { fileURLToPath } from "url";
530
514
  var CLI_PACKAGE_NAME = "ai-project-manage-cli";
531
515
  function readCliVersion() {
532
516
  try {
533
- const dir = dirname2(fileURLToPath2(import.meta.url));
534
- const pkgPath = join3(dir, "..", "package.json");
535
- const pkg = JSON.parse(readFileSync2(pkgPath, "utf8"));
517
+ const dir = dirname(fileURLToPath(import.meta.url));
518
+ const pkgPath = join4(dir, "..", "package.json");
519
+ const pkg = JSON.parse(readFileSync3(pkgPath, "utf8"));
536
520
  return pkg.version ?? "0.0.0";
537
521
  } catch {
538
522
  return "0.0.0";
@@ -701,14 +685,14 @@ function resolveApmEntryPath(entryArg = process.argv[1]) {
701
685
  if (npmResult.status === 0) {
702
686
  const globalRoot = npmResult.stdout?.toString().trim();
703
687
  if (globalRoot) {
704
- const candidate = join4(globalRoot, CLI_PACKAGE_NAME, "dist", "index.js");
705
- if (existsSync2(candidate)) {
688
+ const candidate = join5(globalRoot, CLI_PACKAGE_NAME, "dist", "index.js");
689
+ if (existsSync3(candidate)) {
706
690
  return candidate;
707
691
  }
708
692
  }
709
693
  }
710
694
  const fromArgv = entryArg?.trim();
711
- if (fromArgv && existsSync2(fromArgv)) {
695
+ if (fromArgv && existsSync3(fromArgv)) {
712
696
  return fromArgv;
713
697
  }
714
698
  if (fromArgv) {
@@ -737,23 +721,26 @@ function reexecConnectAfterUpdate(options) {
737
721
  }
738
722
 
739
723
  // src/commands/update-skills.ts
740
- import { existsSync as existsSync3, statSync as statSync2 } from "fs";
724
+ import { existsSync as existsSync4, statSync as statSync2 } from "fs";
741
725
  async function syncWorkspaceSkills(workdir) {
742
726
  const apmDir = workspaceApmDir(workdir);
743
727
  const fsApmDir = toFsPath(apmDir);
744
- if (!existsSync3(fsApmDir)) {
728
+ if (!existsSync4(fsApmDir)) {
745
729
  throw new Error("[apm] \u672A\u627E\u5230 .apm \u76EE\u5F55\uFF0C\u8BF7\u5148\u6267\u884C apm init");
746
730
  }
747
731
  const apmStat = statSync2(fsApmDir);
748
732
  if (!apmStat.isDirectory()) {
749
733
  throw new Error(`[apm] \u8DEF\u5F84\u5DF2\u5B58\u5728\u4F46\u4E0D\u662F\u76EE\u5F55: ${apmDir}`);
750
734
  }
751
- await copyWebIdeTemplateFiles(apmDir, workdir);
752
- console.log("[apm] \u5DF2\u540C\u6B65 WebIDE \u6307\u5357\u4E0E\u89C4\u5219");
735
+ const cfg = await ensureLoggedConfig();
736
+ const result = await syncWebIdeAgentFiles(workdir, cfg);
737
+ console.log(
738
+ result.wrote ? `[apm] \u5DF2\u540C\u6B65 WebIDE \u6307\u5357\u4E0E ${result.ruleCount} \u6761\u89C4\u5219` : "[apm] WebIDE \u6307\u5357\u4E0E\u89C4\u5219\u672A\u53D8\u5316"
739
+ );
753
740
  }
754
741
  async function runUpdateSkills() {
755
742
  const apmDir = workspaceApmDir();
756
- if (!existsSync3(apmDir)) {
743
+ if (!existsSync4(apmDir)) {
757
744
  console.error("[apm] \u672A\u627E\u5230 .apm \u76EE\u5F55\uFF0C\u8BF7\u5148\u6267\u884C apm init");
758
745
  process.exit(1);
759
746
  }
@@ -766,14 +753,14 @@ async function runUpdateSkills() {
766
753
 
767
754
  // src/utils/project-documents.ts
768
755
  import {
769
- existsSync as existsSync4,
756
+ existsSync as existsSync5,
770
757
  readdirSync as readdirSync2,
771
- readFileSync as readFileSync3,
758
+ readFileSync as readFileSync4,
772
759
  rmSync,
773
- writeFileSync as writeFileSync2
760
+ writeFileSync as writeFileSync3
774
761
  } from "fs";
775
762
  import { createHash } from "crypto";
776
- import { dirname as dirname3, join as join5, relative, sep } from "path";
763
+ import { dirname as dirname2, join as join6, relative, sep } from "path";
777
764
 
778
765
  // src/utils/git.ts
779
766
  import { execFile as execFile2 } from "child_process";
@@ -847,11 +834,11 @@ function normalizeProjectIdForPath(projectId) {
847
834
  }
848
835
  function projectDocumentsDir(apmRoot, projectId) {
849
836
  const id = normalizeProjectIdForPath(projectId);
850
- return join5(apmRoot ?? workspaceApmDir(), "project", id);
837
+ return join6(apmRoot ?? workspaceApmDir(), "project", id);
851
838
  }
852
839
  function projectDocumentLocalPath(apmRoot, projectId, documentPath) {
853
840
  const normalized = normalizeLocalDocumentPath(documentPath);
854
- return join5(
841
+ return join6(
855
842
  projectDocumentsDir(apmRoot, projectId),
856
843
  ...normalized.split("/")
857
844
  );
@@ -871,16 +858,16 @@ function hashLocalFileContent(content) {
871
858
  return createHash("sha256").update(content, "utf8").digest("hex");
872
859
  }
873
860
  function readLocalManifest(apmRoot, projectId) {
874
- const manifestPath = join5(
861
+ const manifestPath = join6(
875
862
  projectDocumentsDir(apmRoot, projectId),
876
863
  MANIFEST_FILE
877
864
  );
878
- if (!existsSync4(manifestPath)) {
865
+ if (!existsSync5(manifestPath)) {
879
866
  return null;
880
867
  }
881
868
  try {
882
869
  return JSON.parse(
883
- readFileSync3(manifestPath, "utf8")
870
+ readFileSync4(manifestPath, "utf8")
884
871
  );
885
872
  } catch {
886
873
  return null;
@@ -888,13 +875,13 @@ function readLocalManifest(apmRoot, projectId) {
888
875
  }
889
876
  function listLocalDocumentPaths(apmRoot, projectId) {
890
877
  const root = projectDocumentsDir(apmRoot, projectId);
891
- if (!existsSync4(root)) {
878
+ if (!existsSync5(root)) {
892
879
  return [];
893
880
  }
894
881
  const paths = [];
895
882
  const walk = (dir) => {
896
883
  for (const entry of readdirSync2(dir, { withFileTypes: true })) {
897
- const abs = join5(dir, entry.name);
884
+ const abs = join6(dir, entry.name);
898
885
  if (entry.isDirectory()) {
899
886
  walk(abs);
900
887
  continue;
@@ -1013,8 +1000,8 @@ ${diagnostic ?? ""}`);
1013
1000
  const absPath = toFsPath(
1014
1001
  projectDocumentLocalPath(targetApmDir, projectId, doc.path)
1015
1002
  );
1016
- await ensureDirExists(dirname3(absPath));
1017
- writeFileSync2(absPath, doc.content, "utf8");
1003
+ await ensureDirExists(dirname2(absPath));
1004
+ writeFileSync3(absPath, doc.content, "utf8");
1018
1005
  downloaded += 1;
1019
1006
  }
1020
1007
  }
@@ -1023,13 +1010,13 @@ ${diagnostic ?? ""}`);
1023
1010
  const absPath = toFsPath(
1024
1011
  projectDocumentLocalPath(targetApmDir, projectId, path)
1025
1012
  );
1026
- if (existsSync4(absPath)) {
1013
+ if (existsSync5(absPath)) {
1027
1014
  rmSync(absPath, { force: true });
1028
1015
  deleted += 1;
1029
1016
  }
1030
1017
  }
1031
- writeFileSync2(
1032
- toFsPath(join5(docsDir, MANIFEST_FILE)),
1018
+ writeFileSync3(
1019
+ toFsPath(join6(docsDir, MANIFEST_FILE)),
1033
1020
  `${JSON.stringify(remoteManifest, null, 2)}
1034
1021
  `,
1035
1022
  "utf8"
@@ -1072,7 +1059,7 @@ async function syncProjectDocumentsPush(cfg, workdirPath, apmRoot, options) {
1072
1059
  const absPath = toFsPath(
1073
1060
  projectDocumentLocalPath(targetApmDir, projectId, path)
1074
1061
  );
1075
- const content = readFileSync3(absPath, "utf8");
1062
+ const content = readFileSync4(absPath, "utf8");
1076
1063
  const contentHash = hashLocalFileContent(content);
1077
1064
  if (remoteHashByPath.get(path) === contentHash) {
1078
1065
  continue;
@@ -1347,8 +1334,8 @@ function handleCancelAction(payload, ctx) {
1347
1334
  }
1348
1335
 
1349
1336
  // src/commands/connect/core/worker/worker.ts
1350
- import { dirname as dirname4, join as join6 } from "path";
1351
- import { fileURLToPath as fileURLToPath3 } from "url";
1337
+ import { dirname as dirname3, join as join7 } from "path";
1338
+ import { fileURLToPath as fileURLToPath2 } from "url";
1352
1339
  import { Worker } from "node:worker_threads";
1353
1340
 
1354
1341
  // src/commands/connect/core/worker/config.ts
@@ -1373,8 +1360,8 @@ function resolveWebIdeWorkerHeapMb(env = process.env, totalMemoryBytes = totalme
1373
1360
  }
1374
1361
 
1375
1362
  // src/commands/connect/core/worker/worker.ts
1376
- var workerFile = join6(
1377
- dirname4(fileURLToPath3(import.meta.url)),
1363
+ var workerFile = join7(
1364
+ dirname3(fileURLToPath2(import.meta.url)),
1378
1365
  "worker-script.js"
1379
1366
  );
1380
1367
  var ActionWorker = class {
@@ -1726,14 +1713,14 @@ function dispatchConnectAction(payload, ctx) {
1726
1713
 
1727
1714
  // src/commands/connect-lock.ts
1728
1715
  import {
1729
- existsSync as existsSync5,
1730
- mkdirSync as mkdirSync3,
1731
- readFileSync as readFileSync4,
1716
+ existsSync as existsSync6,
1717
+ mkdirSync as mkdirSync4,
1718
+ readFileSync as readFileSync5,
1732
1719
  unlinkSync,
1733
- writeFileSync as writeFileSync3
1720
+ writeFileSync as writeFileSync4
1734
1721
  } from "fs";
1735
- import { join as join7 } from "path";
1736
- var CONNECT_LOCK_PATH = join7(APM_CONFIG_DIR, "connect.lock");
1722
+ import { join as join8 } from "path";
1723
+ var CONNECT_LOCK_PATH = join8(APM_CONFIG_DIR, "connect.lock");
1737
1724
  function isProcessAlive(pid) {
1738
1725
  if (!Number.isInteger(pid) || pid <= 0) return false;
1739
1726
  try {
@@ -1744,9 +1731,9 @@ function isProcessAlive(pid) {
1744
1731
  }
1745
1732
  }
1746
1733
  function readConnectLock() {
1747
- if (!existsSync5(CONNECT_LOCK_PATH)) return null;
1734
+ if (!existsSync6(CONNECT_LOCK_PATH)) return null;
1748
1735
  try {
1749
- const raw = readFileSync4(CONNECT_LOCK_PATH, "utf8");
1736
+ const raw = readFileSync5(CONNECT_LOCK_PATH, "utf8");
1750
1737
  const parsed = JSON.parse(raw);
1751
1738
  if (typeof parsed.pid !== "number" || typeof parsed.startedAt !== "string") {
1752
1739
  return null;
@@ -1778,12 +1765,12 @@ function acquireConnectLock() {
1778
1765
  console.error(`[apm] \u5DF2\u6709 apm connect \u5728\u8FD0\u884C (pid=${existing.pid})`);
1779
1766
  process.exit(1);
1780
1767
  }
1781
- mkdirSync3(APM_CONFIG_DIR, { recursive: true });
1768
+ mkdirSync4(APM_CONFIG_DIR, { recursive: true });
1782
1769
  const lock = {
1783
1770
  pid: process.pid,
1784
1771
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
1785
1772
  };
1786
- writeFileSync3(
1773
+ writeFileSync4(
1787
1774
  CONNECT_LOCK_PATH,
1788
1775
  JSON.stringify(lock, null, 2) + "\n",
1789
1776
  "utf8"
@@ -2018,7 +2005,7 @@ function buildProgram() {
2018
2005
  ).option("--api-key <key>", "\u8FDC\u7A0B\u4E3B\u673A API Key\uFF08cm_ \u5F00\u5934\uFF09").option("--server <url>", "API \u6839\u5730\u5740\uFF0C\u4F8B\u5982 http://127.0.0.1:3000").action(async (opts) => {
2019
2006
  await runLogin(opts);
2020
2007
  });
2021
- program.command("init").description("\u5728\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u6309 WebIDE \u5DE5\u4F5C\u533A\u521D\u59CB\u5316\uFF1A\u5199\u5165\u6307\u5357\u4E0E webide \u89C4\u5219").action(async () => {
2008
+ program.command("init").description("\u5728\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u6309 WebIDE \u5DE5\u4F5C\u533A\u521D\u59CB\u5316\uFF1A\u4ECE\u5E73\u53F0\u5199\u5165\u6307\u5357\u4E0E\u89C4\u5219").action(async () => {
2022
2009
  await runInit();
2023
2010
  });
2024
2011
  program.command("update").description(
@@ -2031,7 +2018,7 @@ function buildProgram() {
2031
2018
  ).action(async (opts) => {
2032
2019
  await runUpdate({ allowMajorUpgrade: opts.major === true });
2033
2020
  });
2034
- program.command("update-skills").description("\u540C\u6B65 .apm/ \u4E0B\u7684 WebIDE \u6307\u5357\u4E0E\u89C4\u5219").action(async () => {
2021
+ program.command("update-skills").description("\u4ECE\u5E73\u53F0\u540C\u6B65 .apm/ \u4E0B\u7684 WebIDE \u6307\u5357\u4E0E\u89C4\u5219").action(async () => {
2035
2022
  await runUpdateSkills();
2036
2023
  });
2037
2024
  program.command("sync-project-documents").description(