@newlandnpt/pep-cli 0.1.1 → 0.1.3
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/pep.cjs +78 -19
- 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 {
|
|
@@ -192,12 +196,12 @@ async function waitForAuthorizationCallback(args) {
|
|
|
192
196
|
throw new Error("CLI redirect URI must be an http://localhost URL with an explicit port.");
|
|
193
197
|
}
|
|
194
198
|
let server;
|
|
195
|
-
return new Promise((
|
|
199
|
+
return new Promise((resolve2, reject) => {
|
|
196
200
|
const finish = (error, code) => {
|
|
197
201
|
clearTimeout(timeout);
|
|
198
202
|
server?.close();
|
|
199
203
|
if (error) reject(error);
|
|
200
|
-
else
|
|
204
|
+
else resolve2(code);
|
|
201
205
|
};
|
|
202
206
|
const timeout = setTimeout(
|
|
203
207
|
() => finish(new Error("Login timed out while waiting for the browser callback.")),
|
|
@@ -240,7 +244,7 @@ async function waitForAuthorizationCallback(args) {
|
|
|
240
244
|
function openBrowser(url) {
|
|
241
245
|
const command = process.platform === "win32" ? "rundll32.exe" : process.platform === "darwin" ? "open" : "xdg-open";
|
|
242
246
|
const commandArgs = process.platform === "win32" ? ["url.dll,FileProtocolHandler", url] : [url];
|
|
243
|
-
return new Promise((
|
|
247
|
+
return new Promise((resolve2, reject) => {
|
|
244
248
|
const child = (0, import_node_child_process.spawn)(command, commandArgs, {
|
|
245
249
|
detached: true,
|
|
246
250
|
stdio: "ignore",
|
|
@@ -249,7 +253,7 @@ function openBrowser(url) {
|
|
|
249
253
|
child.once("error", reject);
|
|
250
254
|
child.once("spawn", () => {
|
|
251
255
|
child.unref();
|
|
252
|
-
|
|
256
|
+
resolve2();
|
|
253
257
|
});
|
|
254
258
|
});
|
|
255
259
|
}
|
|
@@ -360,7 +364,7 @@ var REFRESH_EARLY_MS = 60 * 1e3;
|
|
|
360
364
|
var LOCK_STALE_MS = 30 * 1e3;
|
|
361
365
|
var LOCK_WAIT_MS = 10 * 1e3;
|
|
362
366
|
async function delay(milliseconds) {
|
|
363
|
-
await new Promise((
|
|
367
|
+
await new Promise((resolve2) => setTimeout(resolve2, milliseconds));
|
|
364
368
|
}
|
|
365
369
|
async function withAuthorizationLock(path, action) {
|
|
366
370
|
await (0, import_promises2.mkdir)((0, import_node_path2.dirname)(path), { recursive: true });
|
|
@@ -554,7 +558,7 @@ function encodedPowerShell(script) {
|
|
|
554
558
|
return Buffer.from(script, "utf16le").toString("base64");
|
|
555
559
|
}
|
|
556
560
|
async function runPowerShell(script, input) {
|
|
557
|
-
return new Promise((
|
|
561
|
+
return new Promise((resolve2, reject) => {
|
|
558
562
|
const child = (0, import_node_child_process2.spawn)(
|
|
559
563
|
"powershell.exe",
|
|
560
564
|
[
|
|
@@ -577,7 +581,7 @@ async function runPowerShell(script, input) {
|
|
|
577
581
|
);
|
|
578
582
|
child.once("close", (code) => {
|
|
579
583
|
clearTimeout(timeout);
|
|
580
|
-
if (code === 0)
|
|
584
|
+
if (code === 0) resolve2(stdout.trim());
|
|
581
585
|
else
|
|
582
586
|
reject(
|
|
583
587
|
new Error(
|
|
@@ -627,7 +631,7 @@ $raw = [Console]::In.ReadToEnd()
|
|
|
627
631
|
}
|
|
628
632
|
var SECURITY_NOT_FOUND = 44;
|
|
629
633
|
async function runSecurity(args) {
|
|
630
|
-
return new Promise((
|
|
634
|
+
return new Promise((resolve2, reject) => {
|
|
631
635
|
const child = (0, import_node_child_process2.spawn)("/usr/bin/security", [...args], {
|
|
632
636
|
stdio: ["ignore", "pipe", "pipe"]
|
|
633
637
|
});
|
|
@@ -642,7 +646,7 @@ async function runSecurity(args) {
|
|
|
642
646
|
);
|
|
643
647
|
child.once("close", (code) => {
|
|
644
648
|
clearTimeout(timeout);
|
|
645
|
-
|
|
649
|
+
resolve2({ code: code ?? -1, stdout, stderr });
|
|
646
650
|
});
|
|
647
651
|
});
|
|
648
652
|
}
|
|
@@ -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
|
|
856
|
-
if (
|
|
860
|
+
const relative2 = withoutRoot[0] === SKILLS_SEGMENT ? withoutRoot.slice(1) : withoutRoot;
|
|
861
|
+
if (relative2.length < 2) continue;
|
|
857
862
|
files.push({
|
|
858
|
-
skill:
|
|
859
|
-
path:
|
|
863
|
+
skill: relative2[0],
|
|
864
|
+
path: relative2.slice(1).join("/"),
|
|
860
865
|
data: entry.data
|
|
861
866
|
});
|
|
862
867
|
}
|
|
@@ -876,6 +881,31 @@ function describeFailure2(status) {
|
|
|
876
881
|
}
|
|
877
882
|
return `PEP answered ${status}.`;
|
|
878
883
|
}
|
|
884
|
+
async function physicalDir(path) {
|
|
885
|
+
const absolute = (0, import_node_path3.resolve)(path);
|
|
886
|
+
try {
|
|
887
|
+
return (0, import_node_path3.join)(await (0, import_promises3.realpath)((0, import_node_path3.dirname)(absolute)), (0, import_node_path3.basename)(absolute));
|
|
888
|
+
} catch {
|
|
889
|
+
return absolute;
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
async function linkSkill(canonicalSkillDir, linkPath) {
|
|
893
|
+
await (0, import_promises3.rm)(linkPath, { recursive: true, force: true });
|
|
894
|
+
const linkDir = (0, import_node_path3.dirname)(linkPath);
|
|
895
|
+
await (0, import_promises3.mkdir)(linkDir, { recursive: true });
|
|
896
|
+
try {
|
|
897
|
+
const junction = (0, import_node_os2.platform)() === "win32";
|
|
898
|
+
await (0, import_promises3.symlink)(
|
|
899
|
+
junction ? canonicalSkillDir : (0, import_node_path3.relative)(await physicalDir(linkDir), canonicalSkillDir),
|
|
900
|
+
linkPath,
|
|
901
|
+
junction ? "junction" : void 0
|
|
902
|
+
);
|
|
903
|
+
return "linked";
|
|
904
|
+
} catch {
|
|
905
|
+
await (0, import_promises3.cp)(canonicalSkillDir, linkPath, { recursive: true });
|
|
906
|
+
return "copied";
|
|
907
|
+
}
|
|
908
|
+
}
|
|
879
909
|
async function syncSkills(dependencies) {
|
|
880
910
|
const doFetch = dependencies.fetch ?? globalThis.fetch;
|
|
881
911
|
const response = await doFetch(`${dependencies.issuer}${ARCHIVE_PATH}`, {
|
|
@@ -909,6 +939,16 @@ async function syncSkills(dependencies) {
|
|
|
909
939
|
await (0, import_promises3.mkdir)((0, import_node_path3.dirname)(target), { recursive: true });
|
|
910
940
|
await (0, import_promises3.writeFile)(target, file.data);
|
|
911
941
|
}
|
|
942
|
+
let copiedCount = 0;
|
|
943
|
+
if (dependencies.linkInto !== void 0) {
|
|
944
|
+
for (const skill of skills) {
|
|
945
|
+
const how = await linkSkill(
|
|
946
|
+
(0, import_node_path3.join)(dependencies.directory, skill),
|
|
947
|
+
(0, import_node_path3.join)(dependencies.linkInto, skill)
|
|
948
|
+
);
|
|
949
|
+
if (how === "copied") copiedCount += 1;
|
|
950
|
+
}
|
|
951
|
+
}
|
|
912
952
|
const removed = (previous?.skills ?? []).filter(
|
|
913
953
|
(skill) => !skills.includes(skill)
|
|
914
954
|
);
|
|
@@ -917,11 +957,15 @@ async function syncSkills(dependencies) {
|
|
|
917
957
|
recursive: true,
|
|
918
958
|
force: true
|
|
919
959
|
});
|
|
960
|
+
if (previous?.linkedInto !== void 0) {
|
|
961
|
+
await (0, import_promises3.rm)((0, import_node_path3.join)(previous.linkedInto, skill), { recursive: true, force: true });
|
|
962
|
+
}
|
|
920
963
|
}
|
|
921
964
|
const state = {
|
|
922
965
|
version: 1,
|
|
923
966
|
skills,
|
|
924
967
|
directory: dependencies.directory,
|
|
968
|
+
...dependencies.linkInto !== void 0 ? { linkedInto: dependencies.linkInto } : {},
|
|
925
969
|
...commit ? { commit } : {}
|
|
926
970
|
};
|
|
927
971
|
await dependencies.stateStore.write(state);
|
|
@@ -931,12 +975,14 @@ async function syncSkills(dependencies) {
|
|
|
931
975
|
fileCount: files.length,
|
|
932
976
|
removed,
|
|
933
977
|
directory: dependencies.directory,
|
|
978
|
+
...dependencies.linkInto !== void 0 ? { linkedInto: dependencies.linkInto } : {},
|
|
979
|
+
...copiedCount > 0 ? { copiedCount } : {},
|
|
934
980
|
...commit ? { commit } : {}
|
|
935
981
|
};
|
|
936
982
|
}
|
|
937
983
|
|
|
938
984
|
// src/cli.ts
|
|
939
|
-
var VERSION = "0.1.
|
|
985
|
+
var VERSION = "0.1.3";
|
|
940
986
|
function usage() {
|
|
941
987
|
return `PEP CLI ${VERSION}
|
|
942
988
|
|
|
@@ -956,9 +1002,15 @@ one. It defaults to the docs platform \u2014 a token minted without it is reject
|
|
|
956
1002
|
resource server, and their answer looks exactly like "this token does not exist".
|
|
957
1003
|
Use \`pep auth token\` when another agent needs a fresh bearer token.
|
|
958
1004
|
|
|
959
|
-
\`pep skills sync\` fetches the latest skills from PEP and writes them
|
|
960
|
-
|
|
961
|
-
|
|
1005
|
+
\`pep skills sync\` fetches the latest skills from PEP and writes them to the shared agent
|
|
1006
|
+
directory (${defaultSkillsDirectory()}), which Codex, Cursor, Amp and ~20 other agents read
|
|
1007
|
+
directly. Claude Code keeps its own directory, so each skill is also linked into
|
|
1008
|
+
${claudeSkillsDirectory()} \u2014 one copy on disk, updated in one place. Where links are not
|
|
1009
|
+
available the skill is copied instead and the run says so.
|
|
1010
|
+
|
|
1011
|
+
--dir <path> writes to that path ONLY and skips the linking, for an agent that reads neither
|
|
1012
|
+
directory. Either way sync only touches skills it wrote itself; anything you put there by
|
|
1013
|
+
hand is left alone.
|
|
962
1014
|
|
|
963
1015
|
\`pep docs list\` prints the documents this account can read (path + description); feed a path
|
|
964
1016
|
straight to \`pep docs get\` to print that document as markdown on stdout. The documentation
|
|
@@ -1056,13 +1108,15 @@ ${usage()}`);
|
|
|
1056
1108
|
if (command !== "sync") throw new Error(`Unknown skills command.
|
|
1057
1109
|
|
|
1058
1110
|
${usage()}`);
|
|
1059
|
-
const
|
|
1111
|
+
const explicitDirectory = option(args, "--dir");
|
|
1112
|
+
const directory = explicitDirectory ?? defaultSkillsDirectory();
|
|
1060
1113
|
if (args.length > 0) throw new Error(`Unknown option: ${args[0]}`);
|
|
1061
1114
|
const authorization = await auth.currentAuthorization();
|
|
1062
1115
|
const result = await syncSkills({
|
|
1063
1116
|
issuer: authorization.issuer,
|
|
1064
1117
|
accessToken: authorization.accessToken,
|
|
1065
1118
|
directory,
|
|
1119
|
+
...explicitDirectory === void 0 ? { linkInto: claudeSkillsDirectory() } : {},
|
|
1066
1120
|
stateStore: fileSkillsStateStore()
|
|
1067
1121
|
});
|
|
1068
1122
|
if (result.status === "unchanged") {
|
|
@@ -1072,6 +1126,11 @@ ${usage()}`);
|
|
|
1072
1126
|
console.log(
|
|
1073
1127
|
`Wrote ${result.fileCount} file(s) across ${result.skills.length} skill(s) to ${result.directory}`
|
|
1074
1128
|
);
|
|
1129
|
+
if (result.linkedInto !== void 0) {
|
|
1130
|
+
console.log(
|
|
1131
|
+
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)`
|
|
1132
|
+
);
|
|
1133
|
+
}
|
|
1075
1134
|
if (result.commit) console.log(`Commit: ${result.commit}`);
|
|
1076
1135
|
if (result.removed.length > 0)
|
|
1077
1136
|
console.log(`Removed (gone upstream): ${result.removed.join(" ")}`);
|