ai-project-manage-cli 6.0.38 → 6.0.39
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 +246 -136
- 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
|
-
|
|
319
|
-
|
|
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
|
|
608
|
-
import { join as
|
|
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
|
-
|
|
937
|
+
writeFileSync6(
|
|
738
938
|
sessionRulePath(trimmedId, apmRoot),
|
|
739
939
|
detail.description ?? "",
|
|
740
940
|
"utf8"
|
|
741
941
|
);
|
|
742
|
-
|
|
942
|
+
writeFileSync6(
|
|
743
943
|
sessionTaskPath(trimmedId, apmRoot),
|
|
744
944
|
detail.task.description ?? "",
|
|
745
945
|
"utf8"
|
|
746
946
|
);
|
|
747
|
-
|
|
947
|
+
writeFileSync6(sessionTodoPath(trimmedId, apmRoot), detail.todo ?? "", "utf8");
|
|
748
948
|
for (const doc of documents) {
|
|
749
949
|
const fileName = documentLocalFileName(doc.name);
|
|
750
|
-
|
|
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
|
-
|
|
967
|
+
writeFileSync6(
|
|
768
968
|
sessionYamlPath(trimmedId, apmRoot),
|
|
769
969
|
sessionYaml.endsWith("\n") ? sessionYaml : `${sessionYaml}
|
|
770
970
|
`,
|
|
771
971
|
"utf8"
|
|
772
972
|
);
|
|
773
|
-
|
|
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
|
|
788
|
-
import { dirname as
|
|
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 =
|
|
794
|
-
const pkgPath =
|
|
795
|
-
const pkg = JSON.parse(
|
|
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
|
|
863
|
-
import { join as
|
|
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 (!
|
|
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 =
|
|
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 =
|
|
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
|
|
1005
|
-
import { basename as
|
|
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
|
|
1009
|
-
import { join as
|
|
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 (!
|
|
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 =
|
|
1027
|
-
const content =
|
|
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 =
|
|
1050
|
-
const content =
|
|
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 (!
|
|
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
|
-
|
|
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
|
|
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 (!
|
|
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 =
|
|
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
|
|
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 (
|
|
2123
|
-
return
|
|
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
|
|
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 (!
|
|
2460
|
+
if (!existsSync10(targetPath) || !statSync4(targetPath).isFile()) {
|
|
2351
2461
|
return {};
|
|
2352
2462
|
}
|
|
2353
|
-
const raw =
|
|
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
|
|
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 (!
|
|
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");
|