@newlandnpt/pep-cli 0.1.1 → 0.1.2

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/pep.cjs +60 -10
  2. package/package.json +1 -1
package/dist/pep.cjs CHANGED
@@ -38,6 +38,9 @@ function skillsStatePath() {
38
38
  return (0, import_node_path.join)(configDirectory(), "skills.json");
39
39
  }
40
40
  function defaultSkillsDirectory() {
41
+ return (0, import_node_path.join)((0, import_node_os.homedir)(), ".agents", "skills");
42
+ }
43
+ function claudeSkillsDirectory() {
41
44
  return (0, import_node_path.join)((0, import_node_os.homedir)(), ".claude", "skills");
42
45
  }
43
46
  function isCliConfig(value) {
@@ -73,7 +76,8 @@ function fileConfigStore(path = configPath()) {
73
76
  function isSkillsState(value) {
74
77
  if (typeof value !== "object" || value === null) return false;
75
78
  const candidate = value;
76
- return candidate.version === 1 && typeof candidate.directory === "string" && Array.isArray(candidate.skills) && candidate.skills.every((one) => typeof one === "string") && (candidate.commit === void 0 || typeof candidate.commit === "string");
79
+ return candidate.version === 1 && typeof candidate.directory === "string" && Array.isArray(candidate.skills) && candidate.skills.every((one) => typeof one === "string") && (candidate.commit === void 0 || typeof candidate.commit === "string") && // 可选:0.1.1 及更早写下的 skills.json 没有这个键,读它们不该报「状态损坏」。
80
+ (candidate.linkedInto === void 0 || typeof candidate.linkedInto === "string");
77
81
  }
78
82
  function fileSkillsStateStore(path = skillsStatePath()) {
79
83
  return {
@@ -763,6 +767,7 @@ async function fetchDocContent(dependencies, path) {
763
767
 
764
768
  // src/skills-service.ts
765
769
  var import_promises3 = require("node:fs/promises");
770
+ var import_node_os2 = require("node:os");
766
771
  var import_node_path3 = require("node:path");
767
772
  var import_node_zlib = require("node:zlib");
768
773
 
@@ -852,11 +857,11 @@ function planSkillFiles(entries) {
852
857
  );
853
858
  }
854
859
  const withoutRoot = segments.slice(1);
855
- const relative = withoutRoot[0] === SKILLS_SEGMENT ? withoutRoot.slice(1) : withoutRoot;
856
- if (relative.length < 2) continue;
860
+ const relative2 = withoutRoot[0] === SKILLS_SEGMENT ? withoutRoot.slice(1) : withoutRoot;
861
+ if (relative2.length < 2) continue;
857
862
  files.push({
858
- skill: relative[0],
859
- path: relative.slice(1).join("/"),
863
+ skill: relative2[0],
864
+ path: relative2.slice(1).join("/"),
860
865
  data: entry.data
861
866
  });
862
867
  }
@@ -876,6 +881,22 @@ function describeFailure2(status) {
876
881
  }
877
882
  return `PEP answered ${status}.`;
878
883
  }
884
+ async function linkSkill(canonicalSkillDir, linkPath) {
885
+ await (0, import_promises3.rm)(linkPath, { recursive: true, force: true });
886
+ await (0, import_promises3.mkdir)((0, import_node_path3.dirname)(linkPath), { recursive: true });
887
+ try {
888
+ const junction = (0, import_node_os2.platform)() === "win32";
889
+ await (0, import_promises3.symlink)(
890
+ junction ? canonicalSkillDir : (0, import_node_path3.relative)((0, import_node_path3.dirname)(linkPath), canonicalSkillDir),
891
+ linkPath,
892
+ junction ? "junction" : void 0
893
+ );
894
+ return "linked";
895
+ } catch {
896
+ await (0, import_promises3.cp)(canonicalSkillDir, linkPath, { recursive: true });
897
+ return "copied";
898
+ }
899
+ }
879
900
  async function syncSkills(dependencies) {
880
901
  const doFetch = dependencies.fetch ?? globalThis.fetch;
881
902
  const response = await doFetch(`${dependencies.issuer}${ARCHIVE_PATH}`, {
@@ -909,6 +930,16 @@ async function syncSkills(dependencies) {
909
930
  await (0, import_promises3.mkdir)((0, import_node_path3.dirname)(target), { recursive: true });
910
931
  await (0, import_promises3.writeFile)(target, file.data);
911
932
  }
933
+ let copiedCount = 0;
934
+ if (dependencies.linkInto !== void 0) {
935
+ for (const skill of skills) {
936
+ const how = await linkSkill(
937
+ (0, import_node_path3.join)(dependencies.directory, skill),
938
+ (0, import_node_path3.join)(dependencies.linkInto, skill)
939
+ );
940
+ if (how === "copied") copiedCount += 1;
941
+ }
942
+ }
912
943
  const removed = (previous?.skills ?? []).filter(
913
944
  (skill) => !skills.includes(skill)
914
945
  );
@@ -917,11 +948,15 @@ async function syncSkills(dependencies) {
917
948
  recursive: true,
918
949
  force: true
919
950
  });
951
+ if (previous?.linkedInto !== void 0) {
952
+ await (0, import_promises3.rm)((0, import_node_path3.join)(previous.linkedInto, skill), { recursive: true, force: true });
953
+ }
920
954
  }
921
955
  const state = {
922
956
  version: 1,
923
957
  skills,
924
958
  directory: dependencies.directory,
959
+ ...dependencies.linkInto !== void 0 ? { linkedInto: dependencies.linkInto } : {},
925
960
  ...commit ? { commit } : {}
926
961
  };
927
962
  await dependencies.stateStore.write(state);
@@ -931,12 +966,14 @@ async function syncSkills(dependencies) {
931
966
  fileCount: files.length,
932
967
  removed,
933
968
  directory: dependencies.directory,
969
+ ...dependencies.linkInto !== void 0 ? { linkedInto: dependencies.linkInto } : {},
970
+ ...copiedCount > 0 ? { copiedCount } : {},
934
971
  ...commit ? { commit } : {}
935
972
  };
936
973
  }
937
974
 
938
975
  // src/cli.ts
939
- var VERSION = "0.1.1";
976
+ var VERSION = "0.1.2";
940
977
  function usage() {
941
978
  return `PEP CLI ${VERSION}
942
979
 
@@ -956,9 +993,15 @@ one. It defaults to the docs platform \u2014 a token minted without it is reject
956
993
  resource server, and their answer looks exactly like "this token does not exist".
957
994
  Use \`pep auth token\` when another agent needs a fresh bearer token.
958
995
 
959
- \`pep skills sync\` fetches the latest skills from PEP and writes them where Claude Code
960
- looks for them (${defaultSkillsDirectory()} unless --dir says otherwise). It only touches
961
- skills it wrote itself; anything you put there by hand is left alone.
996
+ \`pep skills sync\` fetches the latest skills from PEP and writes them to the shared agent
997
+ directory (${defaultSkillsDirectory()}), which Codex, Cursor, Amp and ~20 other agents read
998
+ directly. Claude Code keeps its own directory, so each skill is also linked into
999
+ ${claudeSkillsDirectory()} \u2014 one copy on disk, updated in one place. Where links are not
1000
+ available the skill is copied instead and the run says so.
1001
+
1002
+ --dir <path> writes to that path ONLY and skips the linking, for an agent that reads neither
1003
+ directory. Either way sync only touches skills it wrote itself; anything you put there by
1004
+ hand is left alone.
962
1005
 
963
1006
  \`pep docs list\` prints the documents this account can read (path + description); feed a path
964
1007
  straight to \`pep docs get\` to print that document as markdown on stdout. The documentation
@@ -1056,13 +1099,15 @@ ${usage()}`);
1056
1099
  if (command !== "sync") throw new Error(`Unknown skills command.
1057
1100
 
1058
1101
  ${usage()}`);
1059
- const directory = option(args, "--dir") ?? defaultSkillsDirectory();
1102
+ const explicitDirectory = option(args, "--dir");
1103
+ const directory = explicitDirectory ?? defaultSkillsDirectory();
1060
1104
  if (args.length > 0) throw new Error(`Unknown option: ${args[0]}`);
1061
1105
  const authorization = await auth.currentAuthorization();
1062
1106
  const result = await syncSkills({
1063
1107
  issuer: authorization.issuer,
1064
1108
  accessToken: authorization.accessToken,
1065
1109
  directory,
1110
+ ...explicitDirectory === void 0 ? { linkInto: claudeSkillsDirectory() } : {},
1066
1111
  stateStore: fileSkillsStateStore()
1067
1112
  });
1068
1113
  if (result.status === "unchanged") {
@@ -1072,6 +1117,11 @@ ${usage()}`);
1072
1117
  console.log(
1073
1118
  `Wrote ${result.fileCount} file(s) across ${result.skills.length} skill(s) to ${result.directory}`
1074
1119
  );
1120
+ if (result.linkedInto !== void 0) {
1121
+ console.log(
1122
+ result.copiedCount === void 0 ? `Linked into ${result.linkedInto} for Claude Code` : `Linked into ${result.linkedInto} for Claude Code (${result.copiedCount} copied instead \u2014 links unavailable here)`
1123
+ );
1124
+ }
1075
1125
  if (result.commit) console.log(`Commit: ${result.commit}`);
1076
1126
  if (result.removed.length > 0)
1077
1127
  console.log(`Removed (gone upstream): ${result.removed.join(" ")}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newlandnpt/pep-cli",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "PEP CLI —— 凭 PEP 身份读取 Newland 开发者文档与 agent skills",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",