ai-project-manage-cli 6.0.38 → 6.0.40

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.
Files changed (2) hide show
  1. package/dist/index.js +246 -136
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -314,10 +314,12 @@ import { createApiClient } from "listpage-http";
314
314
  import { defineEndpoint } from "listpage-http";
315
315
  var requestConfig = {
316
316
  cli: {
317
- me: defineEndpoint({
318
- method: "GET",
319
- path: "/cli/me"
320
- }),
317
+ me: defineEndpoint(
318
+ {
319
+ method: "GET",
320
+ path: "/cli/me"
321
+ }
322
+ ),
321
323
  sessionDetail: defineEndpoint({
322
324
  method: "GET",
323
325
  path: "/cli/sessions/detail"
@@ -367,6 +369,10 @@ var requestConfig = {
367
369
  listSkills: defineEndpoint({
368
370
  method: "GET",
369
371
  path: "/cli/skills"
372
+ }),
373
+ listRules: defineEndpoint({
374
+ method: "GET",
375
+ path: "/cli/rules"
370
376
  })
371
377
  }
372
378
  };
@@ -604,8 +610,8 @@ async function runBranch(sessionId, options = {}) {
604
610
  }
605
611
 
606
612
  // src/commands/pull.ts
607
- import { writeFileSync as writeFileSync4 } from "fs";
608
- import { join as join5 } from "path";
613
+ import { writeFileSync as writeFileSync6 } from "fs";
614
+ import { dirname as dirname2, join as join7 } from "path";
609
615
  import { stringify as yamlStringify } from "yaml";
610
616
 
611
617
  // src/session-messages-xml.ts
@@ -713,7 +719,201 @@ async function syncSessionAttachments(cfg, sessionId, attachments, apmRoot) {
713
719
  saveManifest(dir, nextManifest);
714
720
  }
715
721
 
722
+ // src/rules-sync.ts
723
+ import { basename as basename2, extname as extname2, join as join6 } from "path";
724
+ import { existsSync as existsSync4, readFileSync as readFileSync4, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "fs";
725
+
726
+ // src/skills-sync.ts
727
+ import {
728
+ copyFileSync as copyFileSync2,
729
+ cpSync,
730
+ existsSync as existsSync3,
731
+ mkdirSync as mkdirSync3,
732
+ readdirSync as readdirSync2,
733
+ rmSync,
734
+ statSync as statSync2,
735
+ writeFileSync as writeFileSync4
736
+ } from "fs";
737
+ import { join as join5 } from "path";
738
+ var AGENTS_TEMPLATE_PATH = join5(CLI_TEMPLATE_DIR, "AGENTS.md");
739
+ var BASE_SKILLS_TEMPLATE_DIR = join5(CLI_TEMPLATE_DIR, "skills");
740
+ var BASE_RULES_TEMPLATE_DIR = join5(CLI_TEMPLATE_DIR, "rules");
741
+ function sanitizeSkillDirName(name) {
742
+ const trimmed = name.trim();
743
+ if (!trimmed) return "skill";
744
+ return trimmed.replace(/[/\\:*?"<>|]/g, "_");
745
+ }
746
+ function listBaseSkillDirNames() {
747
+ if (!existsSync3(BASE_SKILLS_TEMPLATE_DIR)) return [];
748
+ return readdirSync2(BASE_SKILLS_TEMPLATE_DIR).filter((name) => {
749
+ const path10 = join5(BASE_SKILLS_TEMPLATE_DIR, name);
750
+ return statSync2(path10).isDirectory();
751
+ });
752
+ }
753
+ function syncAgentsGuide(apmDir) {
754
+ if (!existsSync3(AGENTS_TEMPLATE_PATH)) return false;
755
+ mkdirSync3(apmDir, { recursive: true });
756
+ copyFileSync2(AGENTS_TEMPLATE_PATH, join5(apmDir, "AGENTS.md"));
757
+ return true;
758
+ }
759
+ function listBaseRuleFileNames() {
760
+ if (!existsSync3(BASE_RULES_TEMPLATE_DIR)) return [];
761
+ return readdirSync2(BASE_RULES_TEMPLATE_DIR).filter((name) => {
762
+ const path10 = join5(BASE_RULES_TEMPLATE_DIR, name);
763
+ return statSync2(path10).isFile();
764
+ });
765
+ }
766
+ function syncBaseRules(rulesDir) {
767
+ mkdirSync3(rulesDir, { recursive: true });
768
+ const names = listBaseRuleFileNames();
769
+ for (const name of names) {
770
+ const src = join5(BASE_RULES_TEMPLATE_DIR, name);
771
+ const dest = join5(rulesDir, name);
772
+ copyFileSync2(src, dest);
773
+ }
774
+ return names;
775
+ }
776
+ function syncBaseSkills(skillsDir) {
777
+ mkdirSync3(skillsDir, { recursive: true });
778
+ const names = listBaseSkillDirNames();
779
+ for (const name of names) {
780
+ const src = join5(BASE_SKILLS_TEMPLATE_DIR, name);
781
+ const dest = join5(skillsDir, name);
782
+ cpSync(src, dest, { recursive: true, force: true });
783
+ }
784
+ return names;
785
+ }
786
+ function syncSupplementarySkills(skillsDir, list) {
787
+ const baseNames = new Set(listBaseSkillDirNames());
788
+ const apiDirNames = /* @__PURE__ */ new Set();
789
+ const written = [];
790
+ const skipped = [];
791
+ for (const skill of list) {
792
+ const dirName = sanitizeSkillDirName(skill.name);
793
+ apiDirNames.add(dirName);
794
+ if (baseNames.has(dirName)) {
795
+ skipped.push(dirName);
796
+ continue;
797
+ }
798
+ const skillDir = join5(skillsDir, dirName);
799
+ mkdirSync3(skillDir, { recursive: true });
800
+ writeFileSync4(join5(skillDir, "SKILL.md"), skill.content ?? "", "utf8");
801
+ written.push(dirName);
802
+ }
803
+ const removed = [];
804
+ if (!existsSync3(skillsDir)) return { written, skipped, removed };
805
+ for (const entry of readdirSync2(skillsDir)) {
806
+ const full = join5(skillsDir, entry);
807
+ if (!statSync2(full).isDirectory()) continue;
808
+ if (baseNames.has(entry)) continue;
809
+ if (apiDirNames.has(entry)) continue;
810
+ rmSync(full, { recursive: true, force: true });
811
+ removed.push(entry);
812
+ }
813
+ return { written, skipped, removed };
814
+ }
815
+
816
+ // src/rules-sync.ts
817
+ var MANIFEST_FILE2 = ".rules-sync-manifest.json";
818
+ function ruleLocalFileName(ruleName) {
819
+ const trimmed = ruleName.trim();
820
+ if (!trimmed) return "rule.md";
821
+ const sanitized = trimmed.replace(/[/\\:*?"<>|]/g, "_");
822
+ if (extname2(sanitized).toLowerCase() === ".md") return sanitized;
823
+ return `${sanitized}.md`;
824
+ }
825
+ function loadManifest2(rulesDir) {
826
+ const path10 = join6(rulesDir, MANIFEST_FILE2);
827
+ if (!existsSync4(toFsPath(path10))) {
828
+ return { version: 1, rules: {} };
829
+ }
830
+ try {
831
+ const parsed = JSON.parse(
832
+ readFileSync4(toFsPath(path10), "utf8")
833
+ );
834
+ if (parsed?.version === 1 && parsed.rules && typeof parsed.rules === "object") {
835
+ return parsed;
836
+ }
837
+ } catch {
838
+ }
839
+ return { version: 1, rules: {} };
840
+ }
841
+ function saveManifest2(rulesDir, manifest) {
842
+ writeFileSync5(
843
+ toFsPath(join6(rulesDir, MANIFEST_FILE2)),
844
+ `${JSON.stringify(manifest, null, 2)}
845
+ `,
846
+ "utf8"
847
+ );
848
+ }
849
+ function isBaseRuleFileName(fileName) {
850
+ return listBaseRuleFileNames().includes(basename2(fileName));
851
+ }
852
+ function isRuleUpToDate(entry, rule, dest) {
853
+ if (!entry || !existsSync4(toFsPath(dest))) return false;
854
+ if (entry.fileName !== ruleLocalFileName(rule.name)) return false;
855
+ const updatedAt = rule.updatedAt ?? "";
856
+ if (entry.updatedAt !== updatedAt) return false;
857
+ const localContent = readFileSync4(toFsPath(dest), "utf8");
858
+ return localContent === (rule.content ?? "");
859
+ }
860
+ async function syncPlatformRules(cfg, sessionId, workdirPath, apmRoot) {
861
+ const api = createApmApiClient(cfg);
862
+ const baseline = await api.cli.branchBaseline({ sessionId, workdirPath });
863
+ const repositoryId = baseline.repositoryId;
864
+ const rulesDir = join6(apmRoot ?? workspaceApmDir(workdirPath), "rules");
865
+ await ensureDirExists(rulesDir);
866
+ if (!repositoryId) {
867
+ console.log(
868
+ `[apm] \u672A\u5339\u914D\u5230\u7ED1\u5B9A\u4ED3\u5E93\u7684\u5DE5\u4F5C\u7A7A\u95F4\uFF0C\u8DF3\u8FC7\u5E73\u53F0\u89C4\u5219\u540C\u6B65\uFF08\u8DEF\u5F84\uFF1A${workdirPath}\uFF09`
869
+ );
870
+ return { written: [], skipped: [], removed: [], repositoryId: null };
871
+ }
872
+ const { list } = await api.cli.listRules({ repositoryId });
873
+ const manifest = loadManifest2(rulesDir);
874
+ const nextManifest = { version: 1, rules: {} };
875
+ const remoteIds = /* @__PURE__ */ new Set();
876
+ const written = [];
877
+ const skipped = [];
878
+ for (const rule of list) {
879
+ remoteIds.add(rule.id);
880
+ const fileName = ruleLocalFileName(rule.name);
881
+ const dest = join6(rulesDir, fileName);
882
+ const entry = manifest.rules[rule.id];
883
+ const updatedAt = rule.updatedAt ?? "";
884
+ if (isRuleUpToDate(entry, rule, dest)) {
885
+ nextManifest.rules[rule.id] = entry;
886
+ skipped.push(fileName);
887
+ console.log(`[apm] \u89C4\u5219\u65E0\u53D8\u5316\uFF0C\u5DF2\u8DF3\u8FC7: rules/${fileName}`);
888
+ continue;
889
+ }
890
+ writeFileSync5(toFsPath(dest), rule.content ?? "", "utf8");
891
+ nextManifest.rules[rule.id] = { fileName, updatedAt };
892
+ written.push(fileName);
893
+ console.log(`[apm] \u5DF2\u540C\u6B65\u5E73\u53F0\u89C4\u5219: rules/${fileName}`);
894
+ }
895
+ const removed = [];
896
+ for (const [ruleId, entry] of Object.entries(manifest.rules)) {
897
+ if (remoteIds.has(ruleId)) continue;
898
+ if (isBaseRuleFileName(entry.fileName)) continue;
899
+ const dest = join6(rulesDir, entry.fileName);
900
+ if (existsSync4(toFsPath(dest))) {
901
+ rmSync2(toFsPath(dest), { force: true });
902
+ }
903
+ removed.push(entry.fileName);
904
+ console.log(`[apm] \u5DF2\u79FB\u9664\u5DF2\u4E0B\u7EBF\u7684\u5E73\u53F0\u89C4\u5219: rules/${entry.fileName}`);
905
+ }
906
+ saveManifest2(rulesDir, nextManifest);
907
+ return { written, skipped, removed, repositoryId };
908
+ }
909
+
716
910
  // src/commands/pull.ts
911
+ function resolvePullWorkdir(apmRoot) {
912
+ if (apmRoot) {
913
+ return resolveWorkdirPath(dirname2(apmRoot));
914
+ }
915
+ return resolveWorkdirPath();
916
+ }
717
917
  async function runPull(sessionId, apmRoot) {
718
918
  const trimmedId = sessionId.trim();
719
919
  if (!trimmedId) {
@@ -734,20 +934,20 @@ async function runPull(sessionId, apmRoot) {
734
934
  const dir = sessionDir(trimmedId, apmRoot);
735
935
  const docsDir = sessionDocsDir(trimmedId, apmRoot);
736
936
  await ensureDirExists(docsDir);
737
- writeFileSync4(
937
+ writeFileSync6(
738
938
  sessionRulePath(trimmedId, apmRoot),
739
939
  detail.description ?? "",
740
940
  "utf8"
741
941
  );
742
- writeFileSync4(
942
+ writeFileSync6(
743
943
  sessionTaskPath(trimmedId, apmRoot),
744
944
  detail.task.description ?? "",
745
945
  "utf8"
746
946
  );
747
- writeFileSync4(sessionTodoPath(trimmedId, apmRoot), detail.todo ?? "", "utf8");
947
+ writeFileSync6(sessionTodoPath(trimmedId, apmRoot), detail.todo ?? "", "utf8");
748
948
  for (const doc of documents) {
749
949
  const fileName = documentLocalFileName(doc.name);
750
- writeFileSync4(join5(docsDir, fileName), doc.content ?? "", "utf8");
950
+ writeFileSync6(join7(docsDir, fileName), doc.content ?? "", "utf8");
751
951
  }
752
952
  const sessionYaml = yamlStringify(
753
953
  {
@@ -764,18 +964,20 @@ async function runPull(sessionId, apmRoot) {
764
964
  },
765
965
  { lineWidth: 0 }
766
966
  );
767
- writeFileSync4(
967
+ writeFileSync6(
768
968
  sessionYamlPath(trimmedId, apmRoot),
769
969
  sessionYaml.endsWith("\n") ? sessionYaml : `${sessionYaml}
770
970
  `,
771
971
  "utf8"
772
972
  );
773
- writeFileSync4(
973
+ writeFileSync6(
774
974
  sessionMessagesXmlPath(trimmedId, apmRoot),
775
975
  formatSessionMessagesXml(trimmedId, messages),
776
976
  "utf8"
777
977
  );
778
978
  await syncSessionAttachments(cfg, trimmedId, attachments, apmRoot);
979
+ const workdirPath = resolvePullWorkdir(apmRoot);
980
+ await syncPlatformRules(cfg, trimmedId, workdirPath, apmRoot);
779
981
  console.log(`[apm] \u5DF2\u540C\u6B65\u4F1A\u8BDD\u5DE5\u4F5C\u533A: ${dir}`);
780
982
  return dir;
781
983
  }
@@ -784,15 +986,15 @@ async function runPull(sessionId, apmRoot) {
784
986
  import { spawnSync } from "child_process";
785
987
 
786
988
  // src/version.ts
787
- import { readFileSync as readFileSync4 } from "fs";
788
- import { dirname as dirname2, join as join6 } from "path";
989
+ import { readFileSync as readFileSync5 } from "fs";
990
+ import { dirname as dirname3, join as join8 } from "path";
789
991
  import { fileURLToPath as fileURLToPath2 } from "url";
790
992
  var CLI_PACKAGE_NAME = "ai-project-manage-cli";
791
993
  function readCliVersion() {
792
994
  try {
793
- const dir = dirname2(fileURLToPath2(import.meta.url));
794
- const pkgPath = join6(dir, "..", "package.json");
795
- const pkg = JSON.parse(readFileSync4(pkgPath, "utf8"));
995
+ const dir = dirname3(fileURLToPath2(import.meta.url));
996
+ const pkgPath = join8(dir, "..", "package.json");
997
+ const pkg = JSON.parse(readFileSync5(pkgPath, "utf8"));
796
998
  return pkg.version ?? "0.0.0";
797
999
  } catch {
798
1000
  return "0.0.0";
@@ -859,103 +1061,11 @@ async function runUpdate() {
859
1061
  }
860
1062
 
861
1063
  // src/commands/update-skills.ts
862
- import { existsSync as existsSync4, mkdirSync as mkdirSync4, statSync as statSync3 } from "fs";
863
- import { join as join8 } from "path";
864
-
865
- // src/skills-sync.ts
866
- import {
867
- copyFileSync as copyFileSync2,
868
- cpSync,
869
- existsSync as existsSync3,
870
- mkdirSync as mkdirSync3,
871
- readdirSync as readdirSync2,
872
- rmSync,
873
- statSync as statSync2,
874
- writeFileSync as writeFileSync5
875
- } from "fs";
876
- import { join as join7 } from "path";
877
- var AGENTS_TEMPLATE_PATH = join7(CLI_TEMPLATE_DIR, "AGENTS.md");
878
- var BASE_SKILLS_TEMPLATE_DIR = join7(CLI_TEMPLATE_DIR, "skills");
879
- var BASE_RULES_TEMPLATE_DIR = join7(CLI_TEMPLATE_DIR, "rules");
880
- function sanitizeSkillDirName(name) {
881
- const trimmed = name.trim();
882
- if (!trimmed) return "skill";
883
- return trimmed.replace(/[/\\:*?"<>|]/g, "_");
884
- }
885
- function listBaseSkillDirNames() {
886
- if (!existsSync3(BASE_SKILLS_TEMPLATE_DIR)) return [];
887
- return readdirSync2(BASE_SKILLS_TEMPLATE_DIR).filter((name) => {
888
- const path10 = join7(BASE_SKILLS_TEMPLATE_DIR, name);
889
- return statSync2(path10).isDirectory();
890
- });
891
- }
892
- function syncAgentsGuide(apmDir) {
893
- if (!existsSync3(AGENTS_TEMPLATE_PATH)) return false;
894
- mkdirSync3(apmDir, { recursive: true });
895
- copyFileSync2(AGENTS_TEMPLATE_PATH, join7(apmDir, "AGENTS.md"));
896
- return true;
897
- }
898
- function listBaseRuleFileNames() {
899
- if (!existsSync3(BASE_RULES_TEMPLATE_DIR)) return [];
900
- return readdirSync2(BASE_RULES_TEMPLATE_DIR).filter((name) => {
901
- const path10 = join7(BASE_RULES_TEMPLATE_DIR, name);
902
- return statSync2(path10).isFile();
903
- });
904
- }
905
- function syncBaseRules(rulesDir) {
906
- mkdirSync3(rulesDir, { recursive: true });
907
- const names = listBaseRuleFileNames();
908
- for (const name of names) {
909
- const src = join7(BASE_RULES_TEMPLATE_DIR, name);
910
- const dest = join7(rulesDir, name);
911
- copyFileSync2(src, dest);
912
- }
913
- return names;
914
- }
915
- function syncBaseSkills(skillsDir) {
916
- mkdirSync3(skillsDir, { recursive: true });
917
- const names = listBaseSkillDirNames();
918
- for (const name of names) {
919
- const src = join7(BASE_SKILLS_TEMPLATE_DIR, name);
920
- const dest = join7(skillsDir, name);
921
- cpSync(src, dest, { recursive: true, force: true });
922
- }
923
- return names;
924
- }
925
- function syncSupplementarySkills(skillsDir, list) {
926
- const baseNames = new Set(listBaseSkillDirNames());
927
- const apiDirNames = /* @__PURE__ */ new Set();
928
- const written = [];
929
- const skipped = [];
930
- for (const skill of list) {
931
- const dirName = sanitizeSkillDirName(skill.name);
932
- apiDirNames.add(dirName);
933
- if (baseNames.has(dirName)) {
934
- skipped.push(dirName);
935
- continue;
936
- }
937
- const skillDir = join7(skillsDir, dirName);
938
- mkdirSync3(skillDir, { recursive: true });
939
- writeFileSync5(join7(skillDir, "SKILL.md"), skill.content ?? "", "utf8");
940
- written.push(dirName);
941
- }
942
- const removed = [];
943
- if (!existsSync3(skillsDir)) return { written, skipped, removed };
944
- for (const entry of readdirSync2(skillsDir)) {
945
- const full = join7(skillsDir, entry);
946
- if (!statSync2(full).isDirectory()) continue;
947
- if (baseNames.has(entry)) continue;
948
- if (apiDirNames.has(entry)) continue;
949
- rmSync(full, { recursive: true, force: true });
950
- removed.push(entry);
951
- }
952
- return { written, skipped, removed };
953
- }
954
-
955
- // src/commands/update-skills.ts
1064
+ import { existsSync as existsSync5, mkdirSync as mkdirSync4, statSync as statSync3 } from "fs";
1065
+ import { join as join9 } from "path";
956
1066
  async function runUpdateSkills() {
957
1067
  const apmDir = workspaceApmDir();
958
- if (!existsSync4(apmDir)) {
1068
+ if (!existsSync5(apmDir)) {
959
1069
  console.error("[apm] \u672A\u627E\u5230 .apm \u76EE\u5F55\uFF0C\u8BF7\u5148\u6267\u884C apm init");
960
1070
  process.exit(1);
961
1071
  }
@@ -969,12 +1079,12 @@ async function runUpdateSkills() {
969
1079
  if (syncAgentsGuide(apmDir)) {
970
1080
  console.log("[apm] \u5DF2\u540C\u6B65 APM \u6307\u5357: .apm/AGENTS.md");
971
1081
  }
972
- const rulesDir = join8(apmDir, "rules");
1082
+ const rulesDir = join9(apmDir, "rules");
973
1083
  const ruleNames = syncBaseRules(rulesDir);
974
1084
  for (const name of ruleNames) {
975
1085
  console.log(`[apm] \u5DF2\u540C\u6B65\u57FA\u7840\u89C4\u5219: rules/${name}`);
976
1086
  }
977
- const skillsDir = join8(apmDir, "skills");
1087
+ const skillsDir = join9(apmDir, "skills");
978
1088
  mkdirSync4(skillsDir, { recursive: true });
979
1089
  const baseNames = syncBaseSkills(skillsDir);
980
1090
  for (const name of baseNames) {
@@ -1001,14 +1111,14 @@ async function runUpdateSkills() {
1001
1111
  }
1002
1112
 
1003
1113
  // src/commands/sync-document.ts
1004
- import { existsSync as existsSync6 } from "fs";
1005
- import { basename as basename2 } from "path";
1114
+ import { existsSync as existsSync7 } from "fs";
1115
+ import { basename as basename3 } from "path";
1006
1116
 
1007
1117
  // src/commands/sync-session-documents.ts
1008
- import { existsSync as existsSync5, readdirSync as readdirSync3, readFileSync as readFileSync5 } from "fs";
1009
- import { join as join9 } from "path";
1118
+ import { existsSync as existsSync6, readdirSync as readdirSync3, readFileSync as readFileSync6 } from "fs";
1119
+ import { join as join10 } from "path";
1010
1120
  function listLocalMarkdownFiles(docsDir) {
1011
- if (!existsSync5(docsDir)) {
1121
+ if (!existsSync6(docsDir)) {
1012
1122
  return [];
1013
1123
  }
1014
1124
  return readdirSync3(docsDir).filter(
@@ -1023,8 +1133,8 @@ function remoteDocumentByLocalName(remoteDocuments, localFileName) {
1023
1133
  });
1024
1134
  }
1025
1135
  async function upsertLocalDocumentFile(api, sessionId, docsDir, fileName) {
1026
- const absPath = join9(docsDir, fileName);
1027
- const content = readFileSync5(absPath, "utf8");
1136
+ const absPath = join10(docsDir, fileName);
1137
+ const content = readFileSync6(absPath, "utf8");
1028
1138
  const name = documentPlatformName(absPath);
1029
1139
  return api.cli.upsertDocument({
1030
1140
  sessionId,
@@ -1046,8 +1156,8 @@ async function syncSessionDocuments(cfg, sessionId, apmRoot, options) {
1046
1156
  const remoteDocuments = options?.remoteDocuments ?? await api.cli.listDocuments({ sessionId: trimmedSessionId });
1047
1157
  let synced = 0;
1048
1158
  for (const fileName of localFiles) {
1049
- const absPath = join9(docsDir, fileName);
1050
- const content = readFileSync5(absPath, "utf8");
1159
+ const absPath = join10(docsDir, fileName);
1160
+ const content = readFileSync6(absPath, "utf8");
1051
1161
  const remote = remoteDocumentByLocalName(remoteDocuments, fileName);
1052
1162
  if (remote && remote.content === content) {
1053
1163
  continue;
@@ -1080,7 +1190,7 @@ async function runSyncDocument(sessionId, options) {
1080
1190
  process.exit(1);
1081
1191
  }
1082
1192
  const absPath = resolveSessionDocumentPath(trimmedSessionId, fileArg);
1083
- if (!existsSync6(absPath)) {
1193
+ if (!existsSync7(absPath)) {
1084
1194
  const docsDir2 = sessionDocsDir(trimmedSessionId);
1085
1195
  console.error(
1086
1196
  `[apm] \u6587\u6863\u4E0D\u5B58\u5728: ${absPath}
@@ -1095,7 +1205,7 @@ async function runSyncDocument(sessionId, options) {
1095
1205
  api,
1096
1206
  trimmedSessionId,
1097
1207
  docsDir,
1098
- basename2(absPath)
1208
+ basename3(absPath)
1099
1209
  );
1100
1210
  console.log(`[apm] \u5DF2\u540C\u6B65\u6587\u6863: ${doc.name} (id=${doc.id})`);
1101
1211
  }
@@ -1973,19 +2083,19 @@ async function runConnect(options) {
1973
2083
  import path5 from "node:path";
1974
2084
 
1975
2085
  // src/commands/deploy/internal/apm-config.ts
1976
- import { existsSync as existsSync7, readFileSync as readFileSync6 } from "node:fs";
2086
+ import { existsSync as existsSync8, readFileSync as readFileSync7 } from "node:fs";
1977
2087
  import { resolve as resolve4 } from "node:path";
1978
2088
  function loadApmConfig(options) {
1979
2089
  const p = resolve4(
1980
2090
  process.cwd(),
1981
2091
  options?.configPath ?? resolve4(workspaceApmDir(), "apm.config.json")
1982
2092
  );
1983
- if (!existsSync7(p)) {
2093
+ if (!existsSync8(p)) {
1984
2094
  console.error(`\u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6\uFF1A${p}`);
1985
2095
  process.exit(1);
1986
2096
  }
1987
2097
  try {
1988
- const raw = readFileSync6(p, "utf8");
2098
+ const raw = readFileSync7(p, "utf8");
1989
2099
  return JSON.parse(raw);
1990
2100
  } catch (e) {
1991
2101
  console.error(`\u65E0\u6CD5\u89E3\u6790 apm.config.json\uFF1A${p}`, e);
@@ -2107,7 +2217,7 @@ import path4 from "node:path";
2107
2217
  import Docker from "dockerode";
2108
2218
 
2109
2219
  // src/commands/deploy/internal/backend-deploy/dockerode-client/connection-options.ts
2110
- import { existsSync as existsSync8, readFileSync as readFileSync7 } from "node:fs";
2220
+ import { existsSync as existsSync9, readFileSync as readFileSync8 } from "node:fs";
2111
2221
  import path from "node:path";
2112
2222
  function asOptionalTlsBuffer(value) {
2113
2223
  if (typeof value !== "string") {
@@ -2119,8 +2229,8 @@ function asOptionalTlsBuffer(value) {
2119
2229
  if (normalized === "") {
2120
2230
  return void 0;
2121
2231
  }
2122
- if (existsSync8(normalized)) {
2123
- return readFileSync7(normalized);
2232
+ if (existsSync9(normalized)) {
2233
+ return readFileSync8(normalized);
2124
2234
  }
2125
2235
  const looksLikePath = /[\\/]/.test(normalized) || normalized.endsWith(".pem");
2126
2236
  if (looksLikePath) {
@@ -2330,7 +2440,7 @@ var DockerodeClient = class {
2330
2440
  var createDockerodeClient = (config) => new DockerodeClient(config);
2331
2441
 
2332
2442
  // src/commands/deploy/internal/backend-deploy/dockerode-client/env.ts
2333
- import { existsSync as existsSync9, readFileSync as readFileSync8, statSync as statSync4 } from "node:fs";
2443
+ import { existsSync as existsSync10, readFileSync as readFileSync9, statSync as statSync4 } from "node:fs";
2334
2444
  import path2 from "node:path";
2335
2445
  function stripSurroundingQuotes(value) {
2336
2446
  const t = value.trim();
@@ -2347,10 +2457,10 @@ function loadEnvFromFile(envFilePath) {
2347
2457
  return {};
2348
2458
  }
2349
2459
  const targetPath = path2.resolve(envFilePath);
2350
- if (!existsSync9(targetPath) || !statSync4(targetPath).isFile()) {
2460
+ if (!existsSync10(targetPath) || !statSync4(targetPath).isFile()) {
2351
2461
  return {};
2352
2462
  }
2353
- const raw = readFileSync8(targetPath, "utf-8");
2463
+ const raw = readFileSync9(targetPath, "utf-8");
2354
2464
  const result = {};
2355
2465
  for (const line of raw.split(/\r?\n/)) {
2356
2466
  const normalized = line.trim();
@@ -2521,12 +2631,12 @@ function dockerPushImage(params, cwd) {
2521
2631
  }
2522
2632
 
2523
2633
  // src/commands/deploy/internal/backend-deploy/resolve-dockerfile.ts
2524
- import { existsSync as existsSync10 } from "node:fs";
2634
+ import { existsSync as existsSync11 } from "node:fs";
2525
2635
  import path3 from "node:path";
2526
2636
  function resolveDockerBuildPaths(cwd) {
2527
2637
  const dockerfilePath = path3.join(cwd, "Dockerfile");
2528
2638
  Logger.info(`\u67E5\u627EDockerfile\u6587\u4EF6\uFF0C\u8DEF\u5F84: ${dockerfilePath}`);
2529
- if (!existsSync10(dockerfilePath)) {
2639
+ if (!existsSync11(dockerfilePath)) {
2530
2640
  throw new Error(`Dockerfile \u4E0D\u5B58\u5728\uFF1A${dockerfilePath}`);
2531
2641
  }
2532
2642
  Logger.info("\u2713 Dockerfile \u5B58\u5728");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-project-manage-cli",
3
- "version": "6.0.38",
3
+ "version": "6.0.40",
4
4
  "description": "命令行工具:后续用于调用平台后端 API 完成运维与自动化操作",
5
5
  "type": "module",
6
6
  "private": false,