@newlandnpt/pep-cli 0.1.0 → 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 +79 -20
  2. package/package.json +1 -1
package/dist/pep.cjs CHANGED
@@ -21,8 +21,8 @@ function issuerForEnvironment(environment) {
21
21
  }
22
22
  var BUILD_ENVIRONMENT = false ? "development" : "production";
23
23
  var DEFAULT_ISSUER = issuerForEnvironment(BUILD_ENVIRONMENT);
24
- function configuredIssuer(explicitIssuer, savedIssuer) {
25
- return explicitIssuer ?? savedIssuer ?? DEFAULT_ISSUER;
24
+ function configuredIssuer(explicitIssuer) {
25
+ return explicitIssuer ?? DEFAULT_ISSUER;
26
26
  }
27
27
  function configDirectory() {
28
28
  if (process.platform === "win32") return (0, import_node_path.join)((0, import_node_os.homedir)(), "AppData", "Roaming", "PEP");
@@ -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.0";
976
+ var VERSION = "0.1.2";
940
977
  function usage() {
941
978
  return `PEP CLI ${VERSION}
942
979
 
@@ -949,15 +986,22 @@ Usage:
949
986
  pep docs list [--docs-url <url>]
950
987
  pep docs get <path> [--docs-url <url>]
951
988
 
952
- The issuer is built into this executable. Use --issuer only to override it temporarily.
989
+ The issuer is built into this executable. --issuer overrides it for that one command and is
990
+ NOT remembered \u2014 pass it every time you log in against a non-default deployment.
953
991
  --resource names which resource server the token is for (RFC 8707); repeat it for more than
954
992
  one. It defaults to the docs platform \u2014 a token minted without it is rejected by every
955
993
  resource server, and their answer looks exactly like "this token does not exist".
956
994
  Use \`pep auth token\` when another agent needs a fresh bearer token.
957
995
 
958
- \`pep skills sync\` fetches the latest skills from PEP and writes them where Claude Code
959
- looks for them (${defaultSkillsDirectory()} unless --dir says otherwise). It only touches
960
- 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.
961
1005
 
962
1006
  \`pep docs list\` prints the documents this account can read (path + description); feed a path
963
1007
  straight to \`pep docs get\` to print that document as markdown on stdout. The documentation
@@ -982,15 +1026,21 @@ function option(args, name) {
982
1026
  args.splice(index, 2);
983
1027
  return value;
984
1028
  }
985
- async function loginConfig(args) {
986
- const store = fileConfigStore();
987
- const saved = await store.read();
988
- const issuer = configuredIssuer(option(args, "--issuer"), saved?.issuer);
989
- const clientId = option(args, "--client-id") ?? saved?.clientId ?? DEFAULT_CLIENT_ID;
1029
+ async function loginConfig(args, store = fileConfigStore()) {
1030
+ const issuer = configuredIssuer(option(args, "--issuer"));
1031
+ const clientId = option(args, "--client-id") ?? DEFAULT_CLIENT_ID;
990
1032
  const explicit = repeatedOption(args, "--resource");
991
- const resources = explicit.length > 0 ? explicit : saved?.resources ?? [...DEFAULT_RESOURCES];
1033
+ const resources = explicit.length > 0 ? explicit : [...DEFAULT_RESOURCES];
992
1034
  if (args.length > 0) throw new Error(`Unknown option: ${args[0]}`);
993
- return { version: 1, issuer, clientId, redirectUri: DEFAULT_REDIRECT_URI, resources };
1035
+ const saved = await store.read();
1036
+ return {
1037
+ version: 1,
1038
+ issuer,
1039
+ clientId,
1040
+ redirectUri: DEFAULT_REDIRECT_URI,
1041
+ resources,
1042
+ ...saved?.docsUrl !== void 0 ? { docsUrl: saved.docsUrl } : {}
1043
+ };
994
1044
  }
995
1045
  async function main() {
996
1046
  const args = process.argv.slice(2);
@@ -1049,13 +1099,15 @@ ${usage()}`);
1049
1099
  if (command !== "sync") throw new Error(`Unknown skills command.
1050
1100
 
1051
1101
  ${usage()}`);
1052
- const directory = option(args, "--dir") ?? defaultSkillsDirectory();
1102
+ const explicitDirectory = option(args, "--dir");
1103
+ const directory = explicitDirectory ?? defaultSkillsDirectory();
1053
1104
  if (args.length > 0) throw new Error(`Unknown option: ${args[0]}`);
1054
1105
  const authorization = await auth.currentAuthorization();
1055
1106
  const result = await syncSkills({
1056
1107
  issuer: authorization.issuer,
1057
1108
  accessToken: authorization.accessToken,
1058
1109
  directory,
1110
+ ...explicitDirectory === void 0 ? { linkInto: claudeSkillsDirectory() } : {},
1059
1111
  stateStore: fileSkillsStateStore()
1060
1112
  });
1061
1113
  if (result.status === "unchanged") {
@@ -1065,6 +1117,11 @@ ${usage()}`);
1065
1117
  console.log(
1066
1118
  `Wrote ${result.fileCount} file(s) across ${result.skills.length} skill(s) to ${result.directory}`
1067
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
+ }
1068
1125
  if (result.commit) console.log(`Commit: ${result.commit}`);
1069
1126
  if (result.removed.length > 0)
1070
1127
  console.log(`Removed (gone upstream): ${result.removed.join(" ")}`);
@@ -1113,6 +1170,8 @@ ${url}`)
1113
1170
 
1114
1171
  ${usage()}`);
1115
1172
  }
1173
+
1174
+ // src/main.ts
1116
1175
  main().catch((error) => {
1117
1176
  console.error(`pep: ${error.message}`);
1118
1177
  process.exitCode = 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newlandnpt/pep-cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "PEP CLI —— 凭 PEP 身份读取 Newland 开发者文档与 agent skills",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",