@anytio/pspm 0.1.1 → 0.2.0
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/CHANGELOG.md +221 -0
- package/CLI_GUIDE.md +465 -0
- package/LICENSE +176 -109
- package/README.md +31 -93
- package/bin/pspm.js +2 -0
- package/dist/index.js +374 -329
- package/dist/index.js.map +1 -1
- package/package.json +41 -38
package/dist/index.js
CHANGED
|
@@ -1,20 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { createHash, randomBytes } from 'crypto';
|
|
3
|
-
import * as semver from 'semver';
|
|
4
|
-
import { stat, writeFile, readdir, mkdir, rm, rename, access as access$1, readFile, lstat, unlink, cp, readlink, symlink } from 'fs/promises';
|
|
5
|
-
import { homedir } from 'os';
|
|
6
|
-
import { dirname, join, basename, relative } from 'path';
|
|
7
|
-
import * as ini from 'ini';
|
|
8
|
-
import { checkbox } from '@inquirer/prompts';
|
|
9
|
-
import { readFileSync } from 'fs';
|
|
10
|
-
import { fileURLToPath, URL as URL$1 } from 'url';
|
|
11
|
-
import { Command } from 'commander';
|
|
12
|
-
import { createInterface } from 'readline';
|
|
13
|
-
import http from 'http';
|
|
14
|
-
import open from 'open';
|
|
15
|
-
import { exec as exec$1 } from 'child_process';
|
|
16
|
-
import { promisify } from 'util';
|
|
17
|
-
|
|
18
2
|
var __defProp = Object.defineProperty;
|
|
19
3
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
20
4
|
var __esm = (fn, res) => function __init() {
|
|
@@ -24,126 +8,8 @@ var __export = (target, all) => {
|
|
|
24
8
|
for (var name in all)
|
|
25
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
26
10
|
};
|
|
27
|
-
function calculateIntegrity(data) {
|
|
28
|
-
const hash = createHash("sha256").update(data).digest("base64");
|
|
29
|
-
return `sha256-${hash}`;
|
|
30
|
-
}
|
|
31
|
-
var init_integrity = __esm({
|
|
32
|
-
"../../packages/shared/pspm-types/src/integrity.ts"() {
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
// ../../packages/shared/pspm-types/src/manifest.ts
|
|
37
|
-
function validateManifest(manifest) {
|
|
38
|
-
if (!manifest.name) {
|
|
39
|
-
return { valid: false, error: "Manifest must have a 'name' field" };
|
|
40
|
-
}
|
|
41
|
-
if (!manifest.version) {
|
|
42
|
-
return { valid: false, error: "Manifest must have a 'version' field" };
|
|
43
|
-
}
|
|
44
|
-
if (!/^[a-z][a-z0-9_-]*$/.test(manifest.name)) {
|
|
45
|
-
return {
|
|
46
|
-
valid: false,
|
|
47
|
-
error: "Name must start with a lowercase letter and contain only lowercase letters, numbers, hyphens, and underscores"
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
if (!/^\d+\.\d+\.\d+/.test(manifest.version)) {
|
|
51
|
-
return {
|
|
52
|
-
valid: false,
|
|
53
|
-
error: "Version must be a valid semantic version (e.g., 1.0.0)"
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
return { valid: true };
|
|
57
|
-
}
|
|
58
|
-
var DEFAULT_SKILL_FILES, PSPM_SCHEMA_URL;
|
|
59
|
-
var init_manifest = __esm({
|
|
60
|
-
"../../packages/shared/pspm-types/src/manifest.ts"() {
|
|
61
|
-
DEFAULT_SKILL_FILES = [
|
|
62
|
-
"SKILL.md",
|
|
63
|
-
"runtime",
|
|
64
|
-
"scripts",
|
|
65
|
-
"data"
|
|
66
|
-
];
|
|
67
|
-
PSPM_SCHEMA_URL = "https://pspm.dev/schema/v1/pspm.json";
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
// ../../packages/shared/pspm-types/src/specifier.ts
|
|
72
|
-
function parseSkillSpecifier(specifier) {
|
|
73
|
-
const match = specifier.match(SPECIFIER_PATTERN);
|
|
74
|
-
if (!match) {
|
|
75
|
-
return null;
|
|
76
|
-
}
|
|
77
|
-
return {
|
|
78
|
-
username: match[1],
|
|
79
|
-
name: match[2],
|
|
80
|
-
versionRange: match[3]
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
function parseGitHubSpecifier(specifier) {
|
|
84
|
-
const match = specifier.match(GITHUB_SPECIFIER_PATTERN);
|
|
85
|
-
if (!match) {
|
|
86
|
-
return null;
|
|
87
|
-
}
|
|
88
|
-
const [, owner, repo, pathWithSlash, ref] = match;
|
|
89
|
-
return {
|
|
90
|
-
owner,
|
|
91
|
-
repo,
|
|
92
|
-
// Remove leading slash from path
|
|
93
|
-
path: pathWithSlash ? pathWithSlash.slice(1) : void 0,
|
|
94
|
-
ref: ref || void 0
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
function formatGitHubSpecifier(spec) {
|
|
98
|
-
let result = `github:${spec.owner}/${spec.repo}`;
|
|
99
|
-
if (spec.path) {
|
|
100
|
-
result += `/${spec.path}`;
|
|
101
|
-
}
|
|
102
|
-
if (spec.ref) {
|
|
103
|
-
result += `@${spec.ref}`;
|
|
104
|
-
}
|
|
105
|
-
return result;
|
|
106
|
-
}
|
|
107
|
-
function getGitHubSkillName(spec) {
|
|
108
|
-
if (spec.path) {
|
|
109
|
-
const segments = spec.path.split("/").filter(Boolean);
|
|
110
|
-
return segments[segments.length - 1];
|
|
111
|
-
}
|
|
112
|
-
return spec.repo;
|
|
113
|
-
}
|
|
114
|
-
function isGitHubSpecifier(specifier) {
|
|
115
|
-
return specifier.startsWith("github:");
|
|
116
|
-
}
|
|
117
|
-
var SPECIFIER_PATTERN, GITHUB_SPECIFIER_PATTERN;
|
|
118
|
-
var init_specifier = __esm({
|
|
119
|
-
"../../packages/shared/pspm-types/src/specifier.ts"() {
|
|
120
|
-
SPECIFIER_PATTERN = /^@user\/([a-zA-Z0-9_-]+)\/([a-z][a-z0-9_-]*)(?:@(.+))?$/;
|
|
121
|
-
GITHUB_SPECIFIER_PATTERN = /^github:([a-zA-Z0-9_-]+)\/([a-zA-Z0-9_.-]+)(\/[^@]+)?(?:@(.+))?$/;
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
function resolveVersion(range, availableVersions) {
|
|
125
|
-
const sorted = availableVersions.filter((v) => semver.valid(v)).sort((a, b) => semver.rcompare(a, b));
|
|
126
|
-
if (!range || range === "latest" || range === "*") {
|
|
127
|
-
return sorted[0] ?? null;
|
|
128
|
-
}
|
|
129
|
-
return semver.maxSatisfying(sorted, range);
|
|
130
|
-
}
|
|
131
|
-
var init_version = __esm({
|
|
132
|
-
"../../packages/shared/pspm-types/src/version.ts"() {
|
|
133
|
-
}
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
// ../../packages/shared/pspm-types/src/index.ts
|
|
137
|
-
var init_src = __esm({
|
|
138
|
-
"../../packages/shared/pspm-types/src/index.ts"() {
|
|
139
|
-
init_integrity();
|
|
140
|
-
init_manifest();
|
|
141
|
-
init_specifier();
|
|
142
|
-
init_version();
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
11
|
|
|
146
|
-
//
|
|
12
|
+
// src/sdk/fetcher.ts
|
|
147
13
|
function configure(options) {
|
|
148
14
|
config = options;
|
|
149
15
|
}
|
|
@@ -183,28 +49,27 @@ async function customFetch(url, options) {
|
|
|
183
49
|
};
|
|
184
50
|
}
|
|
185
51
|
var config;
|
|
186
|
-
var
|
|
187
|
-
"
|
|
52
|
+
var init_fetcher = __esm({
|
|
53
|
+
"src/sdk/fetcher.ts"() {
|
|
54
|
+
"use strict";
|
|
188
55
|
config = null;
|
|
189
56
|
}
|
|
190
57
|
});
|
|
191
58
|
|
|
192
|
-
//
|
|
59
|
+
// src/sdk/generated/index.ts
|
|
193
60
|
var getMeUrl, me, getListSkillVersionsUrl, listSkillVersions, getGetSkillVersionUrl, getSkillVersion, getPublishSkillUrl, publishSkill, getDeleteSkillUrl, deleteSkill, getDeleteSkillVersionUrl, deleteSkillVersion;
|
|
194
|
-
var
|
|
195
|
-
"
|
|
196
|
-
|
|
61
|
+
var init_generated = __esm({
|
|
62
|
+
"src/sdk/generated/index.ts"() {
|
|
63
|
+
"use strict";
|
|
64
|
+
init_fetcher();
|
|
197
65
|
getMeUrl = () => {
|
|
198
|
-
return
|
|
66
|
+
return "/api/skills/me";
|
|
199
67
|
};
|
|
200
68
|
me = async (options) => {
|
|
201
|
-
return customFetch(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
method: "GET"
|
|
206
|
-
}
|
|
207
|
-
);
|
|
69
|
+
return customFetch(getMeUrl(), {
|
|
70
|
+
...options,
|
|
71
|
+
method: "GET"
|
|
72
|
+
});
|
|
208
73
|
};
|
|
209
74
|
getListSkillVersionsUrl = (username, name) => {
|
|
210
75
|
return `/api/skills/@user/${username}/${name}/versions`;
|
|
@@ -231,32 +96,24 @@ var init_fetch = __esm({
|
|
|
231
96
|
);
|
|
232
97
|
};
|
|
233
98
|
getPublishSkillUrl = () => {
|
|
234
|
-
return
|
|
99
|
+
return "/api/skills/publish";
|
|
235
100
|
};
|
|
236
101
|
publishSkill = async (publishSkillInput, options) => {
|
|
237
|
-
return customFetch(
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
body: JSON.stringify(
|
|
244
|
-
publishSkillInput
|
|
245
|
-
)
|
|
246
|
-
}
|
|
247
|
-
);
|
|
102
|
+
return customFetch(getPublishSkillUrl(), {
|
|
103
|
+
...options,
|
|
104
|
+
method: "POST",
|
|
105
|
+
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
106
|
+
body: JSON.stringify(publishSkillInput)
|
|
107
|
+
});
|
|
248
108
|
};
|
|
249
109
|
getDeleteSkillUrl = (name) => {
|
|
250
110
|
return `/api/skills/${name}`;
|
|
251
111
|
};
|
|
252
112
|
deleteSkill = async (name, options) => {
|
|
253
|
-
return customFetch(
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
method: "DELETE"
|
|
258
|
-
}
|
|
259
|
-
);
|
|
113
|
+
return customFetch(getDeleteSkillUrl(name), {
|
|
114
|
+
...options,
|
|
115
|
+
method: "DELETE"
|
|
116
|
+
});
|
|
260
117
|
};
|
|
261
118
|
getDeleteSkillVersionUrl = (name, version2) => {
|
|
262
119
|
return `/api/skills/${name}/${version2}`;
|
|
@@ -273,14 +130,6 @@ var init_fetch = __esm({
|
|
|
273
130
|
}
|
|
274
131
|
});
|
|
275
132
|
|
|
276
|
-
// ../../packages/sdk/src/index.ts
|
|
277
|
-
var init_src2 = __esm({
|
|
278
|
-
"../../packages/sdk/src/index.ts"() {
|
|
279
|
-
init_cli_fetcher();
|
|
280
|
-
init_fetch();
|
|
281
|
-
}
|
|
282
|
-
});
|
|
283
|
-
|
|
284
133
|
// src/api-client.ts
|
|
285
134
|
function registryUrlToBaseUrl(registryUrl) {
|
|
286
135
|
return registryUrl.replace(/\/api\/skills\/?$/, "");
|
|
@@ -403,7 +252,9 @@ async function changeSkillAccess(skillName, input) {
|
|
|
403
252
|
}
|
|
404
253
|
var init_api_client = __esm({
|
|
405
254
|
"src/api-client.ts"() {
|
|
406
|
-
|
|
255
|
+
"use strict";
|
|
256
|
+
init_fetcher();
|
|
257
|
+
init_generated();
|
|
407
258
|
}
|
|
408
259
|
});
|
|
409
260
|
|
|
@@ -413,7 +264,7 @@ function extractApiErrorMessage(response, fallbackMessage) {
|
|
|
413
264
|
if (process.env.PSPM_DEBUG) {
|
|
414
265
|
console.log(`[debug] API response status: ${response.status}`);
|
|
415
266
|
console.log(
|
|
416
|
-
|
|
267
|
+
"[debug] API response data:",
|
|
417
268
|
JSON.stringify(errorData, null, 2)
|
|
418
269
|
);
|
|
419
270
|
}
|
|
@@ -445,6 +296,7 @@ ${issueMessages}`;
|
|
|
445
296
|
var ConfigError, NotLoggedInError;
|
|
446
297
|
var init_errors = __esm({
|
|
447
298
|
"src/errors.ts"() {
|
|
299
|
+
"use strict";
|
|
448
300
|
ConfigError = class extends Error {
|
|
449
301
|
constructor(message) {
|
|
450
302
|
super(message);
|
|
@@ -461,6 +313,12 @@ var init_errors = __esm({
|
|
|
461
313
|
};
|
|
462
314
|
}
|
|
463
315
|
});
|
|
316
|
+
|
|
317
|
+
// src/config.ts
|
|
318
|
+
import { mkdir, readFile, stat, unlink, writeFile } from "fs/promises";
|
|
319
|
+
import { homedir } from "os";
|
|
320
|
+
import { dirname, join } from "path";
|
|
321
|
+
import * as ini from "ini";
|
|
464
322
|
function getConfigPath() {
|
|
465
323
|
return join(homedir(), ".pspmrc");
|
|
466
324
|
}
|
|
@@ -494,7 +352,7 @@ async function readUserConfig() {
|
|
|
494
352
|
const content = await readFile(configPath, "utf-8");
|
|
495
353
|
const parsed = ini.parse(content);
|
|
496
354
|
if (process.env.PSPM_DEBUG) {
|
|
497
|
-
console.log(
|
|
355
|
+
console.log("[config] Parsed config:", JSON.stringify(parsed, null, 2));
|
|
498
356
|
}
|
|
499
357
|
const scopedRegistries = {};
|
|
500
358
|
for (const key of Object.keys(parsed)) {
|
|
@@ -655,7 +513,7 @@ async function resolveConfig() {
|
|
|
655
513
|
apiKey = process.env.PSPM_API_KEY;
|
|
656
514
|
}
|
|
657
515
|
if (process.env.PSPM_DEBUG) {
|
|
658
|
-
console.log(
|
|
516
|
+
console.log("[config] Resolved config:");
|
|
659
517
|
console.log(`[config] registryUrl: ${registryUrl}`);
|
|
660
518
|
console.log(`[config] apiKey: ${apiKey ? "***" : "(not set)"}`);
|
|
661
519
|
console.log(`[config] username: ${username || "(not set)"}`);
|
|
@@ -699,8 +557,8 @@ async function setCredentials(authToken, username, registry) {
|
|
|
699
557
|
}
|
|
700
558
|
async function clearCredentials() {
|
|
701
559
|
const config2 = await readUserConfig();
|
|
702
|
-
|
|
703
|
-
|
|
560
|
+
config2.authToken = void 0;
|
|
561
|
+
config2.username = void 0;
|
|
704
562
|
await writeUserConfig(config2);
|
|
705
563
|
}
|
|
706
564
|
async function isLoggedIn() {
|
|
@@ -715,7 +573,7 @@ async function requireApiKey() {
|
|
|
715
573
|
const resolved = await resolveConfig();
|
|
716
574
|
if (!resolved.apiKey) {
|
|
717
575
|
if (process.env.PSPM_DEBUG) {
|
|
718
|
-
console.log(
|
|
576
|
+
console.log("[config] requireApiKey: No API key found");
|
|
719
577
|
}
|
|
720
578
|
throw new NotLoggedInError();
|
|
721
579
|
}
|
|
@@ -733,10 +591,143 @@ async function getRegistryUrl() {
|
|
|
733
591
|
var DEFAULT_REGISTRY_URL;
|
|
734
592
|
var init_config = __esm({
|
|
735
593
|
"src/config.ts"() {
|
|
594
|
+
"use strict";
|
|
736
595
|
init_errors();
|
|
737
596
|
DEFAULT_REGISTRY_URL = "https://pspm.dev";
|
|
738
597
|
}
|
|
739
598
|
});
|
|
599
|
+
|
|
600
|
+
// src/lib/integrity.ts
|
|
601
|
+
import { createHash } from "crypto";
|
|
602
|
+
function calculateIntegrity(data) {
|
|
603
|
+
const hash = createHash("sha256").update(data).digest("base64");
|
|
604
|
+
return `sha256-${hash}`;
|
|
605
|
+
}
|
|
606
|
+
var init_integrity = __esm({
|
|
607
|
+
"src/lib/integrity.ts"() {
|
|
608
|
+
"use strict";
|
|
609
|
+
}
|
|
610
|
+
});
|
|
611
|
+
|
|
612
|
+
// src/lib/manifest.ts
|
|
613
|
+
function validateManifest(manifest) {
|
|
614
|
+
if (!manifest.name) {
|
|
615
|
+
return { valid: false, error: "Manifest must have a 'name' field" };
|
|
616
|
+
}
|
|
617
|
+
if (!manifest.version) {
|
|
618
|
+
return { valid: false, error: "Manifest must have a 'version' field" };
|
|
619
|
+
}
|
|
620
|
+
if (!/^[a-z][a-z0-9_-]*$/.test(manifest.name)) {
|
|
621
|
+
return {
|
|
622
|
+
valid: false,
|
|
623
|
+
error: "Name must start with a lowercase letter and contain only lowercase letters, numbers, hyphens, and underscores"
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
if (!/^\d+\.\d+\.\d+/.test(manifest.version)) {
|
|
627
|
+
return {
|
|
628
|
+
valid: false,
|
|
629
|
+
error: "Version must be a valid semantic version (e.g., 1.0.0)"
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
return { valid: true };
|
|
633
|
+
}
|
|
634
|
+
var DEFAULT_SKILL_FILES, PSPM_SCHEMA_URL;
|
|
635
|
+
var init_manifest = __esm({
|
|
636
|
+
"src/lib/manifest.ts"() {
|
|
637
|
+
"use strict";
|
|
638
|
+
DEFAULT_SKILL_FILES = [
|
|
639
|
+
"SKILL.md",
|
|
640
|
+
"runtime",
|
|
641
|
+
"scripts",
|
|
642
|
+
"data"
|
|
643
|
+
];
|
|
644
|
+
PSPM_SCHEMA_URL = "https://pspm.dev/schema/v1/pspm.json";
|
|
645
|
+
}
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
// src/lib/specifier.ts
|
|
649
|
+
function parseSkillSpecifier(specifier) {
|
|
650
|
+
const match = specifier.match(SPECIFIER_PATTERN);
|
|
651
|
+
if (!match) {
|
|
652
|
+
return null;
|
|
653
|
+
}
|
|
654
|
+
return {
|
|
655
|
+
username: match[1],
|
|
656
|
+
name: match[2],
|
|
657
|
+
versionRange: match[3]
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
function parseGitHubSpecifier(specifier) {
|
|
661
|
+
const match = specifier.match(GITHUB_SPECIFIER_PATTERN);
|
|
662
|
+
if (!match) {
|
|
663
|
+
return null;
|
|
664
|
+
}
|
|
665
|
+
const [, owner, repo, pathWithSlash, ref] = match;
|
|
666
|
+
return {
|
|
667
|
+
owner,
|
|
668
|
+
repo,
|
|
669
|
+
// Remove leading slash from path
|
|
670
|
+
path: pathWithSlash ? pathWithSlash.slice(1) : void 0,
|
|
671
|
+
ref: ref || void 0
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
function formatGitHubSpecifier(spec) {
|
|
675
|
+
let result = `github:${spec.owner}/${spec.repo}`;
|
|
676
|
+
if (spec.path) {
|
|
677
|
+
result += `/${spec.path}`;
|
|
678
|
+
}
|
|
679
|
+
if (spec.ref) {
|
|
680
|
+
result += `@${spec.ref}`;
|
|
681
|
+
}
|
|
682
|
+
return result;
|
|
683
|
+
}
|
|
684
|
+
function getGitHubSkillName(spec) {
|
|
685
|
+
if (spec.path) {
|
|
686
|
+
const segments = spec.path.split("/").filter(Boolean);
|
|
687
|
+
return segments[segments.length - 1];
|
|
688
|
+
}
|
|
689
|
+
return spec.repo;
|
|
690
|
+
}
|
|
691
|
+
function isGitHubSpecifier(specifier) {
|
|
692
|
+
return specifier.startsWith("github:");
|
|
693
|
+
}
|
|
694
|
+
var SPECIFIER_PATTERN, GITHUB_SPECIFIER_PATTERN;
|
|
695
|
+
var init_specifier = __esm({
|
|
696
|
+
"src/lib/specifier.ts"() {
|
|
697
|
+
"use strict";
|
|
698
|
+
SPECIFIER_PATTERN = /^@user\/([a-zA-Z0-9_-]+)\/([a-z][a-z0-9_-]*)(?:@(.+))?$/;
|
|
699
|
+
GITHUB_SPECIFIER_PATTERN = /^github:([a-zA-Z0-9_-]+)\/([a-zA-Z0-9_.-]+)(\/[^@]+)?(?:@(.+))?$/;
|
|
700
|
+
}
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
// src/lib/version.ts
|
|
704
|
+
import * as semver from "semver";
|
|
705
|
+
function resolveVersion(range, availableVersions) {
|
|
706
|
+
const sorted = availableVersions.filter((v) => semver.valid(v)).sort((a, b) => semver.rcompare(a, b));
|
|
707
|
+
if (!range || range === "latest" || range === "*") {
|
|
708
|
+
return sorted[0] ?? null;
|
|
709
|
+
}
|
|
710
|
+
return semver.maxSatisfying(sorted, range);
|
|
711
|
+
}
|
|
712
|
+
var init_version = __esm({
|
|
713
|
+
"src/lib/version.ts"() {
|
|
714
|
+
"use strict";
|
|
715
|
+
}
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
// src/lib/index.ts
|
|
719
|
+
var init_lib = __esm({
|
|
720
|
+
"src/lib/index.ts"() {
|
|
721
|
+
"use strict";
|
|
722
|
+
init_integrity();
|
|
723
|
+
init_manifest();
|
|
724
|
+
init_specifier();
|
|
725
|
+
init_version();
|
|
726
|
+
}
|
|
727
|
+
});
|
|
728
|
+
|
|
729
|
+
// src/agents.ts
|
|
730
|
+
import { checkbox } from "@inquirer/prompts";
|
|
740
731
|
function resolveAgentConfig(name, overrides) {
|
|
741
732
|
if (overrides?.[name]) {
|
|
742
733
|
return overrides[name];
|
|
@@ -748,7 +739,7 @@ function resolveAgentConfig(name, overrides) {
|
|
|
748
739
|
}
|
|
749
740
|
function parseAgentArg(agentArg) {
|
|
750
741
|
if (!agentArg) {
|
|
751
|
-
return [...
|
|
742
|
+
return [...ALL_AGENTS];
|
|
752
743
|
}
|
|
753
744
|
if (agentArg === "none") {
|
|
754
745
|
return ["none"];
|
|
@@ -776,9 +767,10 @@ async function promptForAgents() {
|
|
|
776
767
|
}
|
|
777
768
|
return selected;
|
|
778
769
|
}
|
|
779
|
-
var AGENT_INFO, DEFAULT_AGENT_CONFIGS, ALL_AGENTS
|
|
770
|
+
var AGENT_INFO, DEFAULT_AGENT_CONFIGS, ALL_AGENTS;
|
|
780
771
|
var init_agents = __esm({
|
|
781
772
|
"src/agents.ts"() {
|
|
773
|
+
"use strict";
|
|
782
774
|
AGENT_INFO = {
|
|
783
775
|
"claude-code": {
|
|
784
776
|
displayName: "Claude Code",
|
|
@@ -821,9 +813,12 @@ var init_agents = __esm({
|
|
|
821
813
|
"kiro",
|
|
822
814
|
"opencode"
|
|
823
815
|
];
|
|
824
|
-
DEFAULT_AGENTS = ALL_AGENTS;
|
|
825
816
|
}
|
|
826
817
|
});
|
|
818
|
+
|
|
819
|
+
// src/github.ts
|
|
820
|
+
import { cp, lstat, mkdir as mkdir2, readdir, rm, writeFile as writeFile2 } from "fs/promises";
|
|
821
|
+
import { join as join2 } from "path";
|
|
827
822
|
function getGitHubHeaders() {
|
|
828
823
|
const headers = {
|
|
829
824
|
Accept: "application/vnd.github+json",
|
|
@@ -838,7 +833,8 @@ function getGitHubHeaders() {
|
|
|
838
833
|
}
|
|
839
834
|
async function resolveGitHubRef(owner, repo, ref) {
|
|
840
835
|
const headers = getGitHubHeaders();
|
|
841
|
-
|
|
836
|
+
let resolvedRef = ref;
|
|
837
|
+
if (!resolvedRef || resolvedRef === "latest") {
|
|
842
838
|
const repoUrl = `https://api.github.com/repos/${owner}/${repo}`;
|
|
843
839
|
const repoResponse = await fetch(repoUrl, { headers });
|
|
844
840
|
if (repoResponse.status === 404) {
|
|
@@ -854,9 +850,9 @@ async function resolveGitHubRef(owner, repo, ref) {
|
|
|
854
850
|
throw new Error(`GitHub API error: ${repoResponse.status}`);
|
|
855
851
|
}
|
|
856
852
|
const repoData = await repoResponse.json();
|
|
857
|
-
|
|
853
|
+
resolvedRef = repoData.default_branch;
|
|
858
854
|
}
|
|
859
|
-
const commitUrl = `https://api.github.com/repos/${owner}/${repo}/commits/${
|
|
855
|
+
const commitUrl = `https://api.github.com/repos/${owner}/${repo}/commits/${resolvedRef}`;
|
|
860
856
|
const commitResponse = await fetch(commitUrl, { headers });
|
|
861
857
|
if (commitResponse.status === 404) {
|
|
862
858
|
throw new GitHubNotFoundError({ owner, repo, ref });
|
|
@@ -898,14 +894,14 @@ async function downloadGitHubPackage(spec) {
|
|
|
898
894
|
return { buffer, commit, integrity };
|
|
899
895
|
}
|
|
900
896
|
async function extractGitHubPackage(spec, buffer, skillsDir) {
|
|
901
|
-
const destPath = spec.path ?
|
|
902
|
-
const tempDir =
|
|
903
|
-
await
|
|
904
|
-
const tempFile =
|
|
897
|
+
const destPath = spec.path ? join2(skillsDir, "_github", spec.owner, spec.repo, spec.path) : join2(skillsDir, "_github", spec.owner, spec.repo);
|
|
898
|
+
const tempDir = join2(skillsDir, "_github", ".temp", `${Date.now()}`);
|
|
899
|
+
await mkdir2(tempDir, { recursive: true });
|
|
900
|
+
const tempFile = join2(tempDir, "archive.tgz");
|
|
905
901
|
try {
|
|
906
|
-
await
|
|
907
|
-
const { exec: exec2 } = await import(
|
|
908
|
-
const { promisify: promisify2 } = await import(
|
|
902
|
+
await writeFile2(tempFile, buffer);
|
|
903
|
+
const { exec: exec2 } = await import("child_process");
|
|
904
|
+
const { promisify: promisify2 } = await import("util");
|
|
909
905
|
const execAsync = promisify2(exec2);
|
|
910
906
|
await execAsync(`tar -xzf "${tempFile}" -C "${tempDir}"`);
|
|
911
907
|
const entries = await readdir(tempDir);
|
|
@@ -915,15 +911,15 @@ async function extractGitHubPackage(spec, buffer, skillsDir) {
|
|
|
915
911
|
if (!extractedDir) {
|
|
916
912
|
throw new Error("Failed to find extracted directory in tarball");
|
|
917
913
|
}
|
|
918
|
-
const sourcePath =
|
|
919
|
-
const copySource = spec.path ?
|
|
914
|
+
const sourcePath = join2(tempDir, extractedDir);
|
|
915
|
+
const copySource = spec.path ? join2(sourcePath, spec.path) : sourcePath;
|
|
920
916
|
if (spec.path) {
|
|
921
917
|
const pathExists = await lstat(copySource).catch(() => null);
|
|
922
918
|
if (!pathExists) {
|
|
923
919
|
const rootEntries = await readdir(sourcePath);
|
|
924
920
|
const dirs = [];
|
|
925
921
|
for (const entry of rootEntries) {
|
|
926
|
-
const stat7 = await lstat(
|
|
922
|
+
const stat7 = await lstat(join2(sourcePath, entry)).catch(() => null);
|
|
927
923
|
if (stat7?.isDirectory() && !entry.startsWith(".")) {
|
|
928
924
|
dirs.push(entry);
|
|
929
925
|
}
|
|
@@ -932,7 +928,7 @@ async function extractGitHubPackage(spec, buffer, skillsDir) {
|
|
|
932
928
|
}
|
|
933
929
|
}
|
|
934
930
|
await rm(destPath, { recursive: true, force: true });
|
|
935
|
-
await
|
|
931
|
+
await mkdir2(destPath, { recursive: true });
|
|
936
932
|
await cp(copySource, destPath, { recursive: true });
|
|
937
933
|
return spec.path ? `.pspm/skills/_github/${spec.owner}/${spec.repo}/${spec.path}` : `.pspm/skills/_github/${spec.owner}/${spec.repo}`;
|
|
938
934
|
} finally {
|
|
@@ -946,14 +942,16 @@ function getGitHubDisplayName(spec, commit) {
|
|
|
946
942
|
}
|
|
947
943
|
if (spec.ref || commit) {
|
|
948
944
|
const ref = spec.ref || "HEAD";
|
|
949
|
-
|
|
945
|
+
const shortCommit = commit ? commit.slice(0, 7) : "";
|
|
946
|
+
name += ` (${ref}${shortCommit ? `@${shortCommit}` : ""})`;
|
|
950
947
|
}
|
|
951
948
|
return name;
|
|
952
949
|
}
|
|
953
950
|
var GitHubRateLimitError, GitHubNotFoundError, GitHubPathNotFoundError;
|
|
954
951
|
var init_github = __esm({
|
|
955
952
|
"src/github.ts"() {
|
|
956
|
-
|
|
953
|
+
"use strict";
|
|
954
|
+
init_lib();
|
|
957
955
|
GitHubRateLimitError = class extends Error {
|
|
958
956
|
constructor() {
|
|
959
957
|
super(
|
|
@@ -985,9 +983,13 @@ Available paths in repository root:
|
|
|
985
983
|
};
|
|
986
984
|
}
|
|
987
985
|
});
|
|
986
|
+
|
|
987
|
+
// src/lockfile.ts
|
|
988
|
+
import { mkdir as mkdir3, readFile as readFile2, stat as stat2, writeFile as writeFile3 } from "fs/promises";
|
|
989
|
+
import { dirname as dirname2 } from "path";
|
|
988
990
|
async function hasLegacyLockfile() {
|
|
989
991
|
try {
|
|
990
|
-
await
|
|
992
|
+
await stat2(getLegacyLockfilePath());
|
|
991
993
|
return true;
|
|
992
994
|
} catch {
|
|
993
995
|
return false;
|
|
@@ -997,26 +999,26 @@ async function migrateLockfileIfNeeded() {
|
|
|
997
999
|
const legacyPath = getLegacyLockfilePath();
|
|
998
1000
|
const newPath = getLockfilePath();
|
|
999
1001
|
try {
|
|
1000
|
-
await
|
|
1002
|
+
await stat2(legacyPath);
|
|
1001
1003
|
} catch {
|
|
1002
1004
|
return false;
|
|
1003
1005
|
}
|
|
1004
1006
|
try {
|
|
1005
|
-
await
|
|
1007
|
+
await stat2(newPath);
|
|
1006
1008
|
return false;
|
|
1007
1009
|
} catch {
|
|
1008
1010
|
}
|
|
1009
1011
|
try {
|
|
1010
|
-
const content = await
|
|
1012
|
+
const content = await readFile2(legacyPath, "utf-8");
|
|
1011
1013
|
const oldLockfile = JSON.parse(content);
|
|
1012
1014
|
const newLockfile = {
|
|
1013
1015
|
lockfileVersion: 2,
|
|
1014
1016
|
registryUrl: oldLockfile.registryUrl,
|
|
1015
1017
|
packages: oldLockfile.skills ?? {}
|
|
1016
1018
|
};
|
|
1017
|
-
await
|
|
1019
|
+
await writeFile3(newPath, `${JSON.stringify(newLockfile, null, 2)}
|
|
1018
1020
|
`);
|
|
1019
|
-
console.log(
|
|
1021
|
+
console.log("Migrated lockfile: skill-lock.json \u2192 pspm-lock.json");
|
|
1020
1022
|
return true;
|
|
1021
1023
|
} catch {
|
|
1022
1024
|
return false;
|
|
@@ -1025,7 +1027,7 @@ async function migrateLockfileIfNeeded() {
|
|
|
1025
1027
|
async function readLockfile() {
|
|
1026
1028
|
const lockfilePath = getLockfilePath();
|
|
1027
1029
|
try {
|
|
1028
|
-
const content = await
|
|
1030
|
+
const content = await readFile2(lockfilePath, "utf-8");
|
|
1029
1031
|
const lockfile = JSON.parse(content);
|
|
1030
1032
|
if (lockfile.lockfileVersion === 1 && lockfile.skills && !lockfile.packages) {
|
|
1031
1033
|
return {
|
|
@@ -1038,7 +1040,7 @@ async function readLockfile() {
|
|
|
1038
1040
|
} catch {
|
|
1039
1041
|
if (await hasLegacyLockfile()) {
|
|
1040
1042
|
try {
|
|
1041
|
-
const content = await
|
|
1043
|
+
const content = await readFile2(getLegacyLockfilePath(), "utf-8");
|
|
1042
1044
|
const legacyLockfile = JSON.parse(content);
|
|
1043
1045
|
return {
|
|
1044
1046
|
lockfileVersion: 2,
|
|
@@ -1054,7 +1056,7 @@ async function readLockfile() {
|
|
|
1054
1056
|
}
|
|
1055
1057
|
async function writeLockfile(lockfile) {
|
|
1056
1058
|
const lockfilePath = getLockfilePath();
|
|
1057
|
-
await
|
|
1059
|
+
await mkdir3(dirname2(lockfilePath), { recursive: true });
|
|
1058
1060
|
const normalized = {
|
|
1059
1061
|
lockfileVersion: 3,
|
|
1060
1062
|
registryUrl: lockfile.registryUrl,
|
|
@@ -1063,7 +1065,7 @@ async function writeLockfile(lockfile) {
|
|
|
1063
1065
|
if (lockfile.githubPackages && Object.keys(lockfile.githubPackages).length > 0) {
|
|
1064
1066
|
normalized.githubPackages = lockfile.githubPackages;
|
|
1065
1067
|
}
|
|
1066
|
-
await
|
|
1068
|
+
await writeFile3(lockfilePath, `${JSON.stringify(normalized, null, 2)}
|
|
1067
1069
|
`);
|
|
1068
1070
|
}
|
|
1069
1071
|
async function createEmptyLockfile() {
|
|
@@ -1144,15 +1146,20 @@ async function listLockfileGitHubPackages() {
|
|
|
1144
1146
|
}
|
|
1145
1147
|
var init_lockfile = __esm({
|
|
1146
1148
|
"src/lockfile.ts"() {
|
|
1149
|
+
"use strict";
|
|
1147
1150
|
init_config();
|
|
1148
1151
|
}
|
|
1149
1152
|
});
|
|
1153
|
+
|
|
1154
|
+
// src/manifest.ts
|
|
1155
|
+
import { readFile as readFile3, writeFile as writeFile4 } from "fs/promises";
|
|
1156
|
+
import { join as join3 } from "path";
|
|
1150
1157
|
function getManifestPath() {
|
|
1151
|
-
return
|
|
1158
|
+
return join3(process.cwd(), "pspm.json");
|
|
1152
1159
|
}
|
|
1153
1160
|
async function readManifest() {
|
|
1154
1161
|
try {
|
|
1155
|
-
const content = await
|
|
1162
|
+
const content = await readFile3(getManifestPath(), "utf-8");
|
|
1156
1163
|
return JSON.parse(content);
|
|
1157
1164
|
} catch {
|
|
1158
1165
|
return null;
|
|
@@ -1160,7 +1167,7 @@ async function readManifest() {
|
|
|
1160
1167
|
}
|
|
1161
1168
|
async function writeManifest(manifest) {
|
|
1162
1169
|
const content = JSON.stringify(manifest, null, 2);
|
|
1163
|
-
await
|
|
1170
|
+
await writeFile4(getManifestPath(), `${content}
|
|
1164
1171
|
`);
|
|
1165
1172
|
}
|
|
1166
1173
|
async function createMinimalManifest() {
|
|
@@ -1220,8 +1227,13 @@ async function removeGitHubDependency(specifier) {
|
|
|
1220
1227
|
}
|
|
1221
1228
|
var init_manifest2 = __esm({
|
|
1222
1229
|
"src/manifest.ts"() {
|
|
1230
|
+
"use strict";
|
|
1223
1231
|
}
|
|
1224
1232
|
});
|
|
1233
|
+
|
|
1234
|
+
// src/symlinks.ts
|
|
1235
|
+
import { lstat as lstat2, mkdir as mkdir4, readlink, rm as rm2, symlink } from "fs/promises";
|
|
1236
|
+
import { dirname as dirname3, join as join4, relative } from "path";
|
|
1225
1237
|
async function createAgentSymlinks(skills, options) {
|
|
1226
1238
|
const { agents, projectRoot, agentConfigs } = options;
|
|
1227
1239
|
if (agents.length === 1 && agents[0] === "none") {
|
|
@@ -1233,26 +1245,26 @@ async function createAgentSymlinks(skills, options) {
|
|
|
1233
1245
|
console.warn(`Warning: Unknown agent "${agentName}", skipping symlinks`);
|
|
1234
1246
|
continue;
|
|
1235
1247
|
}
|
|
1236
|
-
const agentSkillsDir =
|
|
1237
|
-
await
|
|
1248
|
+
const agentSkillsDir = join4(projectRoot, config2.skillsDir);
|
|
1249
|
+
await mkdir4(agentSkillsDir, { recursive: true });
|
|
1238
1250
|
for (const skill of skills) {
|
|
1239
|
-
const symlinkPath =
|
|
1240
|
-
const targetPath =
|
|
1241
|
-
const relativeTarget = relative(
|
|
1251
|
+
const symlinkPath = join4(agentSkillsDir, skill.name);
|
|
1252
|
+
const targetPath = join4(projectRoot, skill.sourcePath);
|
|
1253
|
+
const relativeTarget = relative(dirname3(symlinkPath), targetPath);
|
|
1242
1254
|
await createSymlink(symlinkPath, relativeTarget, skill.name);
|
|
1243
1255
|
}
|
|
1244
1256
|
}
|
|
1245
1257
|
}
|
|
1246
1258
|
async function createSymlink(symlinkPath, target, skillName) {
|
|
1247
1259
|
try {
|
|
1248
|
-
const stats = await
|
|
1260
|
+
const stats = await lstat2(symlinkPath).catch(() => null);
|
|
1249
1261
|
if (stats) {
|
|
1250
1262
|
if (stats.isSymbolicLink()) {
|
|
1251
1263
|
const existingTarget = await readlink(symlinkPath);
|
|
1252
1264
|
if (existingTarget === target) {
|
|
1253
1265
|
return;
|
|
1254
1266
|
}
|
|
1255
|
-
await
|
|
1267
|
+
await rm2(symlinkPath);
|
|
1256
1268
|
} else {
|
|
1257
1269
|
console.warn(
|
|
1258
1270
|
`Warning: File exists at symlink path for "${skillName}", skipping: ${symlinkPath}`
|
|
@@ -1278,11 +1290,11 @@ async function removeAgentSymlinks(skillName, options) {
|
|
|
1278
1290
|
if (!config2) {
|
|
1279
1291
|
continue;
|
|
1280
1292
|
}
|
|
1281
|
-
const symlinkPath =
|
|
1293
|
+
const symlinkPath = join4(projectRoot, config2.skillsDir, skillName);
|
|
1282
1294
|
try {
|
|
1283
|
-
const stats = await
|
|
1295
|
+
const stats = await lstat2(symlinkPath).catch(() => null);
|
|
1284
1296
|
if (stats?.isSymbolicLink()) {
|
|
1285
|
-
await
|
|
1297
|
+
await rm2(symlinkPath);
|
|
1286
1298
|
}
|
|
1287
1299
|
} catch {
|
|
1288
1300
|
}
|
|
@@ -1302,9 +1314,9 @@ async function getLinkedAgents(skillName, agents, projectRoot, agentConfigs) {
|
|
|
1302
1314
|
for (const agentName of agents) {
|
|
1303
1315
|
const config2 = resolveAgentConfig(agentName, agentConfigs);
|
|
1304
1316
|
if (!config2) continue;
|
|
1305
|
-
const symlinkPath =
|
|
1317
|
+
const symlinkPath = join4(projectRoot, config2.skillsDir, skillName);
|
|
1306
1318
|
try {
|
|
1307
|
-
const stats = await
|
|
1319
|
+
const stats = await lstat2(symlinkPath);
|
|
1308
1320
|
if (stats.isSymbolicLink()) {
|
|
1309
1321
|
linkedAgents.push(agentName);
|
|
1310
1322
|
}
|
|
@@ -1315,6 +1327,7 @@ async function getLinkedAgents(skillName, agents, projectRoot, agentConfigs) {
|
|
|
1315
1327
|
}
|
|
1316
1328
|
var init_symlinks = __esm({
|
|
1317
1329
|
"src/symlinks.ts"() {
|
|
1330
|
+
"use strict";
|
|
1318
1331
|
init_agents();
|
|
1319
1332
|
}
|
|
1320
1333
|
});
|
|
@@ -1324,6 +1337,8 @@ var add_exports = {};
|
|
|
1324
1337
|
__export(add_exports, {
|
|
1325
1338
|
add: () => add
|
|
1326
1339
|
});
|
|
1340
|
+
import { mkdir as mkdir5, rm as rm3 } from "fs/promises";
|
|
1341
|
+
import { join as join5 } from "path";
|
|
1327
1342
|
async function add(specifiers, options) {
|
|
1328
1343
|
console.log("Resolving packages...\n");
|
|
1329
1344
|
const resolvedPackages = [];
|
|
@@ -1514,23 +1529,23 @@ async function installRegistryPackage(resolved, options) {
|
|
|
1514
1529
|
throw new Error("Checksum verification failed");
|
|
1515
1530
|
}
|
|
1516
1531
|
const skillsDir = getSkillsDir();
|
|
1517
|
-
const destDir =
|
|
1518
|
-
await
|
|
1519
|
-
const { writeFile: writeFile8 } = await import(
|
|
1520
|
-
const tempFile =
|
|
1532
|
+
const destDir = join5(skillsDir, username, name);
|
|
1533
|
+
await mkdir5(destDir, { recursive: true });
|
|
1534
|
+
const { writeFile: writeFile8 } = await import("fs/promises");
|
|
1535
|
+
const tempFile = join5(destDir, ".temp.tgz");
|
|
1521
1536
|
await writeFile8(tempFile, tarballBuffer);
|
|
1522
|
-
const { exec: exec2 } = await import(
|
|
1523
|
-
const { promisify: promisify2 } = await import(
|
|
1537
|
+
const { exec: exec2 } = await import("child_process");
|
|
1538
|
+
const { promisify: promisify2 } = await import("util");
|
|
1524
1539
|
const execAsync = promisify2(exec2);
|
|
1525
1540
|
try {
|
|
1526
|
-
await
|
|
1527
|
-
await
|
|
1541
|
+
await rm3(destDir, { recursive: true, force: true });
|
|
1542
|
+
await mkdir5(destDir, { recursive: true });
|
|
1528
1543
|
await writeFile8(tempFile, tarballBuffer);
|
|
1529
1544
|
await execAsync(
|
|
1530
1545
|
`tar -xzf "${tempFile}" -C "${destDir}" --strip-components=1`
|
|
1531
1546
|
);
|
|
1532
1547
|
} finally {
|
|
1533
|
-
await
|
|
1548
|
+
await rm3(tempFile, { force: true });
|
|
1534
1549
|
}
|
|
1535
1550
|
const fullName = `@user/${username}/${name}`;
|
|
1536
1551
|
await addToLockfile(fullName, {
|
|
@@ -1603,22 +1618,29 @@ async function installGitHubPackage(resolved, options) {
|
|
|
1603
1618
|
}
|
|
1604
1619
|
var init_add = __esm({
|
|
1605
1620
|
"src/commands/add.ts"() {
|
|
1606
|
-
|
|
1621
|
+
"use strict";
|
|
1607
1622
|
init_agents();
|
|
1608
1623
|
init_api_client();
|
|
1609
1624
|
init_config();
|
|
1610
1625
|
init_errors();
|
|
1611
1626
|
init_github();
|
|
1627
|
+
init_lib();
|
|
1612
1628
|
init_lockfile();
|
|
1613
1629
|
init_manifest2();
|
|
1614
1630
|
init_symlinks();
|
|
1615
1631
|
}
|
|
1616
1632
|
});
|
|
1617
1633
|
|
|
1634
|
+
// src/index.ts
|
|
1635
|
+
import { readFileSync } from "fs";
|
|
1636
|
+
import { dirname as dirname4, join as join12 } from "path";
|
|
1637
|
+
import { fileURLToPath } from "url";
|
|
1638
|
+
import { Command } from "commander";
|
|
1639
|
+
|
|
1618
1640
|
// src/commands/access.ts
|
|
1619
|
-
init_src();
|
|
1620
1641
|
init_api_client();
|
|
1621
1642
|
init_config();
|
|
1643
|
+
init_lib();
|
|
1622
1644
|
async function access(specifier, options) {
|
|
1623
1645
|
try {
|
|
1624
1646
|
const apiKey = await requireApiKey();
|
|
@@ -1643,8 +1665,8 @@ async function access(specifier, options) {
|
|
|
1643
1665
|
}
|
|
1644
1666
|
packageName = parsed.name;
|
|
1645
1667
|
} else {
|
|
1646
|
-
const { readFile: readFile7 } = await import(
|
|
1647
|
-
const { join: join13 } = await import(
|
|
1668
|
+
const { readFile: readFile7 } = await import("fs/promises");
|
|
1669
|
+
const { join: join13 } = await import("path");
|
|
1648
1670
|
let manifest = null;
|
|
1649
1671
|
try {
|
|
1650
1672
|
const content = await readFile7(
|
|
@@ -1702,11 +1724,15 @@ async function access(specifier, options) {
|
|
|
1702
1724
|
|
|
1703
1725
|
// src/commands/index.ts
|
|
1704
1726
|
init_add();
|
|
1727
|
+
|
|
1728
|
+
// src/commands/config/init.ts
|
|
1729
|
+
import { stat as stat3, writeFile as writeFile5 } from "fs/promises";
|
|
1730
|
+
import { join as join6 } from "path";
|
|
1705
1731
|
async function configInit(options) {
|
|
1706
1732
|
try {
|
|
1707
|
-
const configPath =
|
|
1733
|
+
const configPath = join6(process.cwd(), ".pspmrc");
|
|
1708
1734
|
try {
|
|
1709
|
-
await
|
|
1735
|
+
await stat3(configPath);
|
|
1710
1736
|
console.error("Error: .pspmrc already exists in this directory.");
|
|
1711
1737
|
process.exit(1);
|
|
1712
1738
|
} catch {
|
|
@@ -1719,7 +1745,7 @@ async function configInit(options) {
|
|
|
1719
1745
|
lines.push("; registry = https://custom-registry.example.com");
|
|
1720
1746
|
}
|
|
1721
1747
|
lines.push("");
|
|
1722
|
-
await
|
|
1748
|
+
await writeFile5(configPath, lines.join("\n"));
|
|
1723
1749
|
console.log("Created .pspmrc");
|
|
1724
1750
|
console.log("");
|
|
1725
1751
|
console.log("Contents:");
|
|
@@ -1764,9 +1790,9 @@ async function configShow() {
|
|
|
1764
1790
|
}
|
|
1765
1791
|
|
|
1766
1792
|
// src/commands/deprecate.ts
|
|
1767
|
-
init_src();
|
|
1768
1793
|
init_api_client();
|
|
1769
1794
|
init_config();
|
|
1795
|
+
init_lib();
|
|
1770
1796
|
async function deprecate(specifier, message, options) {
|
|
1771
1797
|
try {
|
|
1772
1798
|
const apiKey = await requireApiKey();
|
|
@@ -1831,7 +1857,10 @@ async function deprecate(specifier, message, options) {
|
|
|
1831
1857
|
}
|
|
1832
1858
|
|
|
1833
1859
|
// src/commands/init.ts
|
|
1834
|
-
|
|
1860
|
+
init_lib();
|
|
1861
|
+
import { readFile as readFile4, stat as stat4, writeFile as writeFile6 } from "fs/promises";
|
|
1862
|
+
import { basename, join as join7 } from "path";
|
|
1863
|
+
import { createInterface } from "readline";
|
|
1835
1864
|
function prompt(rl, question, defaultValue) {
|
|
1836
1865
|
return new Promise((resolve) => {
|
|
1837
1866
|
const displayDefault = defaultValue ? ` (${defaultValue})` : "";
|
|
@@ -1842,8 +1871,8 @@ function prompt(rl, question, defaultValue) {
|
|
|
1842
1871
|
}
|
|
1843
1872
|
async function readExistingPackageJson() {
|
|
1844
1873
|
try {
|
|
1845
|
-
const content = await
|
|
1846
|
-
|
|
1874
|
+
const content = await readFile4(
|
|
1875
|
+
join7(process.cwd(), "package.json"),
|
|
1847
1876
|
"utf-8"
|
|
1848
1877
|
);
|
|
1849
1878
|
const pkg = JSON.parse(content);
|
|
@@ -1860,8 +1889,8 @@ async function readExistingPackageJson() {
|
|
|
1860
1889
|
}
|
|
1861
1890
|
async function getGitAuthor() {
|
|
1862
1891
|
try {
|
|
1863
|
-
const { exec: exec2 } = await import(
|
|
1864
|
-
const { promisify: promisify2 } = await import(
|
|
1892
|
+
const { exec: exec2 } = await import("child_process");
|
|
1893
|
+
const { promisify: promisify2 } = await import("util");
|
|
1865
1894
|
const execAsync = promisify2(exec2);
|
|
1866
1895
|
const [nameResult, emailResult] = await Promise.all([
|
|
1867
1896
|
execAsync("git config user.name").catch(() => ({ stdout: "" })),
|
|
@@ -1892,10 +1921,10 @@ function isValidVersion(version2) {
|
|
|
1892
1921
|
}
|
|
1893
1922
|
async function init(options) {
|
|
1894
1923
|
try {
|
|
1895
|
-
const pspmJsonPath =
|
|
1924
|
+
const pspmJsonPath = join7(process.cwd(), "pspm.json");
|
|
1896
1925
|
let exists = false;
|
|
1897
1926
|
try {
|
|
1898
|
-
await
|
|
1927
|
+
await stat4(pspmJsonPath);
|
|
1899
1928
|
exists = true;
|
|
1900
1929
|
} catch {
|
|
1901
1930
|
}
|
|
@@ -2006,9 +2035,9 @@ async function init(options) {
|
|
|
2006
2035
|
throw error;
|
|
2007
2036
|
}
|
|
2008
2037
|
}
|
|
2009
|
-
if (!manifest.description)
|
|
2010
|
-
if (!manifest.author)
|
|
2011
|
-
if (manifest.capabilities?.length === 0)
|
|
2038
|
+
if (!manifest.description) manifest.description = void 0;
|
|
2039
|
+
if (!manifest.author) manifest.author = void 0;
|
|
2040
|
+
if (manifest.capabilities?.length === 0) manifest.capabilities = void 0;
|
|
2012
2041
|
const content = JSON.stringify(manifest, null, 2);
|
|
2013
2042
|
console.log("");
|
|
2014
2043
|
console.log(`About to write to ${pspmJsonPath}:`);
|
|
@@ -2027,10 +2056,10 @@ async function init(options) {
|
|
|
2027
2056
|
process.exit(0);
|
|
2028
2057
|
}
|
|
2029
2058
|
}
|
|
2030
|
-
await
|
|
2059
|
+
await writeFile6(pspmJsonPath, `${content}
|
|
2031
2060
|
`);
|
|
2032
2061
|
try {
|
|
2033
|
-
await
|
|
2062
|
+
await stat4(join7(process.cwd(), "SKILL.md"));
|
|
2034
2063
|
} catch {
|
|
2035
2064
|
console.log(
|
|
2036
2065
|
"Note: Create a SKILL.md file with your skill's prompt content."
|
|
@@ -2049,15 +2078,18 @@ async function init(options) {
|
|
|
2049
2078
|
}
|
|
2050
2079
|
|
|
2051
2080
|
// src/commands/install.ts
|
|
2052
|
-
init_src();
|
|
2053
2081
|
init_agents();
|
|
2054
2082
|
init_api_client();
|
|
2055
2083
|
init_config();
|
|
2056
2084
|
init_errors();
|
|
2057
2085
|
init_github();
|
|
2086
|
+
init_lib();
|
|
2058
2087
|
init_lockfile();
|
|
2059
2088
|
init_manifest2();
|
|
2060
2089
|
init_symlinks();
|
|
2090
|
+
import { createHash as createHash2 } from "crypto";
|
|
2091
|
+
import { mkdir as mkdir6, readFile as readFile5, rm as rm4, writeFile as writeFile7 } from "fs/promises";
|
|
2092
|
+
import { join as join8 } from "path";
|
|
2061
2093
|
function getCacheFilePath(cacheDir, integrity) {
|
|
2062
2094
|
const match = integrity.match(/^sha256-(.+)$/);
|
|
2063
2095
|
if (!match) {
|
|
@@ -2065,15 +2097,15 @@ function getCacheFilePath(cacheDir, integrity) {
|
|
|
2065
2097
|
}
|
|
2066
2098
|
const base64Hash = match[1];
|
|
2067
2099
|
const hexHash = Buffer.from(base64Hash, "base64").toString("hex");
|
|
2068
|
-
return
|
|
2100
|
+
return join8(cacheDir, `sha256-${hexHash}.tgz`);
|
|
2069
2101
|
}
|
|
2070
2102
|
async function readFromCache(cacheDir, integrity) {
|
|
2071
2103
|
try {
|
|
2072
2104
|
const cachePath = getCacheFilePath(cacheDir, integrity);
|
|
2073
|
-
const data = await
|
|
2074
|
-
const actualIntegrity = `sha256-${
|
|
2105
|
+
const data = await readFile5(cachePath);
|
|
2106
|
+
const actualIntegrity = `sha256-${createHash2("sha256").update(data).digest("base64")}`;
|
|
2075
2107
|
if (actualIntegrity !== integrity) {
|
|
2076
|
-
await
|
|
2108
|
+
await rm4(cachePath, { force: true });
|
|
2077
2109
|
return null;
|
|
2078
2110
|
}
|
|
2079
2111
|
return data;
|
|
@@ -2083,9 +2115,9 @@ async function readFromCache(cacheDir, integrity) {
|
|
|
2083
2115
|
}
|
|
2084
2116
|
async function writeToCache(cacheDir, integrity, data) {
|
|
2085
2117
|
try {
|
|
2086
|
-
await
|
|
2118
|
+
await mkdir6(cacheDir, { recursive: true });
|
|
2087
2119
|
const cachePath = getCacheFilePath(cacheDir, integrity);
|
|
2088
|
-
await
|
|
2120
|
+
await writeFile7(cachePath, data);
|
|
2089
2121
|
} catch {
|
|
2090
2122
|
}
|
|
2091
2123
|
}
|
|
@@ -2328,7 +2360,7 @@ Installing ${packageCount} registry skill(s)...
|
|
|
2328
2360
|
continue;
|
|
2329
2361
|
}
|
|
2330
2362
|
tarballBuffer = Buffer.from(await response.arrayBuffer());
|
|
2331
|
-
const actualIntegrity = `sha256-${
|
|
2363
|
+
const actualIntegrity = `sha256-${createHash2("sha256").update(tarballBuffer).digest("base64")}`;
|
|
2332
2364
|
if (actualIntegrity !== entry.integrity) {
|
|
2333
2365
|
console.error(
|
|
2334
2366
|
` Error: Checksum verification failed for ${fullName}`
|
|
@@ -2340,20 +2372,20 @@ Installing ${packageCount} registry skill(s)...
|
|
|
2340
2372
|
}
|
|
2341
2373
|
await writeToCache(cacheDir, entry.integrity, tarballBuffer);
|
|
2342
2374
|
}
|
|
2343
|
-
const destDir =
|
|
2344
|
-
await
|
|
2345
|
-
await
|
|
2346
|
-
const tempFile =
|
|
2347
|
-
await
|
|
2348
|
-
const { exec: exec2 } = await import(
|
|
2349
|
-
const { promisify: promisify2 } = await import(
|
|
2375
|
+
const destDir = join8(skillsDir, username, name);
|
|
2376
|
+
await rm4(destDir, { recursive: true, force: true });
|
|
2377
|
+
await mkdir6(destDir, { recursive: true });
|
|
2378
|
+
const tempFile = join8(destDir, ".temp.tgz");
|
|
2379
|
+
await writeFile7(tempFile, tarballBuffer);
|
|
2380
|
+
const { exec: exec2 } = await import("child_process");
|
|
2381
|
+
const { promisify: promisify2 } = await import("util");
|
|
2350
2382
|
const execAsync = promisify2(exec2);
|
|
2351
2383
|
try {
|
|
2352
2384
|
await execAsync(
|
|
2353
2385
|
`tar -xzf "${tempFile}" -C "${destDir}" --strip-components=1`
|
|
2354
2386
|
);
|
|
2355
2387
|
} finally {
|
|
2356
|
-
await
|
|
2388
|
+
await rm4(tempFile, { force: true });
|
|
2357
2389
|
}
|
|
2358
2390
|
console.log(
|
|
2359
2391
|
` Installed to ${destDir}${fromCache ? " (from cache)" : ""}`
|
|
@@ -2466,8 +2498,8 @@ All ${totalCount} skill(s) installed.`);
|
|
|
2466
2498
|
}
|
|
2467
2499
|
|
|
2468
2500
|
// src/commands/link.ts
|
|
2469
|
-
init_src();
|
|
2470
2501
|
init_agents();
|
|
2502
|
+
init_lib();
|
|
2471
2503
|
init_lockfile();
|
|
2472
2504
|
init_manifest2();
|
|
2473
2505
|
init_symlinks();
|
|
@@ -2543,11 +2575,13 @@ async function link(options) {
|
|
|
2543
2575
|
}
|
|
2544
2576
|
|
|
2545
2577
|
// src/commands/list.ts
|
|
2546
|
-
init_src();
|
|
2547
2578
|
init_agents();
|
|
2579
|
+
init_lib();
|
|
2548
2580
|
init_lockfile();
|
|
2549
2581
|
init_manifest2();
|
|
2550
2582
|
init_symlinks();
|
|
2583
|
+
import { access as access2 } from "fs/promises";
|
|
2584
|
+
import { join as join9 } from "path";
|
|
2551
2585
|
async function list(options) {
|
|
2552
2586
|
try {
|
|
2553
2587
|
const registrySkills = await listLockfileSkills();
|
|
@@ -2562,10 +2596,10 @@ async function list(options) {
|
|
|
2562
2596
|
if (!match) continue;
|
|
2563
2597
|
const [, username, skillName] = match;
|
|
2564
2598
|
const sourcePath = getRegistrySkillPath(username, skillName);
|
|
2565
|
-
const absolutePath =
|
|
2599
|
+
const absolutePath = join9(projectRoot, sourcePath);
|
|
2566
2600
|
let status = "installed";
|
|
2567
2601
|
try {
|
|
2568
|
-
await
|
|
2602
|
+
await access2(absolutePath);
|
|
2569
2603
|
} catch {
|
|
2570
2604
|
status = "missing";
|
|
2571
2605
|
}
|
|
@@ -2595,10 +2629,10 @@ async function list(options) {
|
|
|
2595
2629
|
parsed.repo,
|
|
2596
2630
|
parsed.path
|
|
2597
2631
|
);
|
|
2598
|
-
const absolutePath =
|
|
2632
|
+
const absolutePath = join9(projectRoot, sourcePath);
|
|
2599
2633
|
let status = "installed";
|
|
2600
2634
|
try {
|
|
2601
|
-
await
|
|
2635
|
+
await access2(absolutePath);
|
|
2602
2636
|
} catch {
|
|
2603
2637
|
status = "missing";
|
|
2604
2638
|
}
|
|
@@ -2665,13 +2699,17 @@ Total: ${skills.length} skill(s) (${parts.join(", ")})`);
|
|
|
2665
2699
|
// src/commands/login.ts
|
|
2666
2700
|
init_api_client();
|
|
2667
2701
|
init_config();
|
|
2702
|
+
import { randomBytes } from "crypto";
|
|
2703
|
+
import http from "http";
|
|
2704
|
+
import { URL as URL2 } from "url";
|
|
2705
|
+
import open from "open";
|
|
2668
2706
|
var DEFAULT_WEB_APP_URL = "https://pspm.dev";
|
|
2669
2707
|
function getWebAppUrl(registryUrl) {
|
|
2670
2708
|
if (process.env.PSPM_WEB_URL) {
|
|
2671
2709
|
return process.env.PSPM_WEB_URL.replace(/\/$/, "");
|
|
2672
2710
|
}
|
|
2673
2711
|
try {
|
|
2674
|
-
const url = new
|
|
2712
|
+
const url = new URL2(registryUrl);
|
|
2675
2713
|
return `${url.protocol}//${url.host}`;
|
|
2676
2714
|
} catch {
|
|
2677
2715
|
return DEFAULT_WEB_APP_URL;
|
|
@@ -2679,7 +2717,7 @@ function getWebAppUrl(registryUrl) {
|
|
|
2679
2717
|
}
|
|
2680
2718
|
function getServerUrl(registryUrl) {
|
|
2681
2719
|
try {
|
|
2682
|
-
const url = new
|
|
2720
|
+
const url = new URL2(registryUrl);
|
|
2683
2721
|
return `${url.protocol}//${url.host}`;
|
|
2684
2722
|
} catch {
|
|
2685
2723
|
return DEFAULT_WEB_APP_URL;
|
|
@@ -2711,7 +2749,7 @@ function startCallbackServer(expectedState) {
|
|
|
2711
2749
|
rejectToken = reject;
|
|
2712
2750
|
});
|
|
2713
2751
|
const server = http.createServer((req, res) => {
|
|
2714
|
-
const url = new
|
|
2752
|
+
const url = new URL2(req.url || "/", "http://localhost");
|
|
2715
2753
|
if (url.pathname === "/callback") {
|
|
2716
2754
|
const token = url.searchParams.get("token");
|
|
2717
2755
|
const state = url.searchParams.get("state");
|
|
@@ -2798,7 +2836,7 @@ async function browserLogin() {
|
|
|
2798
2836
|
console.log("Starting browser-based login...");
|
|
2799
2837
|
const { port, tokenPromise, cleanup } = await startCallbackServer(state);
|
|
2800
2838
|
const loginUrl = `${webAppUrl}/cli/login?port=${port}&state=${encodeURIComponent(state)}`;
|
|
2801
|
-
console.log(
|
|
2839
|
+
console.log("Opening browser to authenticate...");
|
|
2802
2840
|
console.log(`If the browser doesn't open, visit: ${loginUrl}`);
|
|
2803
2841
|
try {
|
|
2804
2842
|
await open(loginUrl);
|
|
@@ -2862,6 +2900,7 @@ async function logout() {
|
|
|
2862
2900
|
// src/commands/migrate.ts
|
|
2863
2901
|
init_config();
|
|
2864
2902
|
init_lockfile();
|
|
2903
|
+
import { mkdir as mkdir7, readdir as readdir2, rename, rm as rm5, stat as stat5 } from "fs/promises";
|
|
2865
2904
|
async function migrate(options) {
|
|
2866
2905
|
try {
|
|
2867
2906
|
const legacySkillsDir = getLegacySkillsDir();
|
|
@@ -2872,26 +2911,26 @@ async function migrate(options) {
|
|
|
2872
2911
|
let migrationNeeded = false;
|
|
2873
2912
|
const actions = [];
|
|
2874
2913
|
try {
|
|
2875
|
-
const legacyStats = await
|
|
2914
|
+
const legacyStats = await stat5(legacySkillsDir);
|
|
2876
2915
|
if (legacyStats.isDirectory()) {
|
|
2877
|
-
const contents = await
|
|
2916
|
+
const contents = await readdir2(legacySkillsDir);
|
|
2878
2917
|
if (contents.length > 0) {
|
|
2879
2918
|
migrationNeeded = true;
|
|
2880
|
-
actions.push(
|
|
2919
|
+
actions.push("Move .skills/ \u2192 .pspm/skills/");
|
|
2881
2920
|
}
|
|
2882
2921
|
}
|
|
2883
2922
|
} catch {
|
|
2884
2923
|
}
|
|
2885
2924
|
try {
|
|
2886
|
-
await
|
|
2925
|
+
await stat5(legacyLockfilePath);
|
|
2887
2926
|
try {
|
|
2888
|
-
await
|
|
2927
|
+
await stat5(newLockfilePath);
|
|
2889
2928
|
actions.push(
|
|
2890
|
-
|
|
2929
|
+
"Note: Both skill-lock.json and pspm-lock.json exist. Manual merge may be needed."
|
|
2891
2930
|
);
|
|
2892
2931
|
} catch {
|
|
2893
2932
|
migrationNeeded = true;
|
|
2894
|
-
actions.push(
|
|
2933
|
+
actions.push("Migrate skill-lock.json \u2192 pspm-lock.json");
|
|
2895
2934
|
}
|
|
2896
2935
|
} catch {
|
|
2897
2936
|
}
|
|
@@ -2917,21 +2956,21 @@ async function migrate(options) {
|
|
|
2917
2956
|
console.log(" \u2713 Migrated skill-lock.json \u2192 pspm-lock.json");
|
|
2918
2957
|
}
|
|
2919
2958
|
try {
|
|
2920
|
-
const legacyStats = await
|
|
2959
|
+
const legacyStats = await stat5(legacySkillsDir);
|
|
2921
2960
|
if (legacyStats.isDirectory()) {
|
|
2922
|
-
const contents = await
|
|
2961
|
+
const contents = await readdir2(legacySkillsDir);
|
|
2923
2962
|
if (contents.length > 0) {
|
|
2924
|
-
await
|
|
2963
|
+
await mkdir7(pspmDir, { recursive: true });
|
|
2925
2964
|
try {
|
|
2926
|
-
const newStats = await
|
|
2965
|
+
const newStats = await stat5(newSkillsDir);
|
|
2927
2966
|
if (newStats.isDirectory()) {
|
|
2928
|
-
const newContents = await
|
|
2967
|
+
const newContents = await readdir2(newSkillsDir);
|
|
2929
2968
|
if (newContents.length > 0) {
|
|
2930
2969
|
console.log(
|
|
2931
2970
|
" ! Both .skills/ and .pspm/skills/ have content. Manual merge required."
|
|
2932
2971
|
);
|
|
2933
2972
|
} else {
|
|
2934
|
-
await
|
|
2973
|
+
await rm5(newSkillsDir, { recursive: true, force: true });
|
|
2935
2974
|
await rename(legacySkillsDir, newSkillsDir);
|
|
2936
2975
|
console.log(" \u2713 Moved .skills/ \u2192 .pspm/skills/");
|
|
2937
2976
|
}
|
|
@@ -2963,23 +3002,28 @@ async function migrate(options) {
|
|
|
2963
3002
|
}
|
|
2964
3003
|
|
|
2965
3004
|
// src/commands/publish.ts
|
|
2966
|
-
init_src();
|
|
2967
3005
|
init_api_client();
|
|
2968
3006
|
init_config();
|
|
2969
3007
|
init_errors();
|
|
2970
|
-
|
|
3008
|
+
init_lib();
|
|
3009
|
+
import { exec as execCb } from "child_process";
|
|
3010
|
+
import { createHash as createHash3 } from "crypto";
|
|
3011
|
+
import { readdir as readdir3, readFile as readFile6, stat as stat6 } from "fs/promises";
|
|
3012
|
+
import { join as join10, relative as relative2 } from "path";
|
|
3013
|
+
import { promisify } from "util";
|
|
3014
|
+
var exec = promisify(execCb);
|
|
2971
3015
|
async function detectManifest() {
|
|
2972
3016
|
const cwd = process.cwd();
|
|
2973
|
-
const pspmJsonPath =
|
|
3017
|
+
const pspmJsonPath = join10(cwd, "pspm.json");
|
|
2974
3018
|
try {
|
|
2975
|
-
const content = await
|
|
3019
|
+
const content = await readFile6(pspmJsonPath, "utf-8");
|
|
2976
3020
|
const manifest = JSON.parse(content);
|
|
2977
3021
|
return { type: "pspm.json", manifest, path: pspmJsonPath };
|
|
2978
3022
|
} catch {
|
|
2979
3023
|
}
|
|
2980
|
-
const packageJsonPath =
|
|
3024
|
+
const packageJsonPath = join10(cwd, "package.json");
|
|
2981
3025
|
try {
|
|
2982
|
-
const content = await
|
|
3026
|
+
const content = await readFile6(packageJsonPath, "utf-8");
|
|
2983
3027
|
const packageJson2 = JSON.parse(content);
|
|
2984
3028
|
const manifest = {
|
|
2985
3029
|
name: packageJson2.name,
|
|
@@ -3002,10 +3046,10 @@ function formatBytes(bytes) {
|
|
|
3002
3046
|
async function getFilesWithSizes(dir, baseDir) {
|
|
3003
3047
|
const results = [];
|
|
3004
3048
|
try {
|
|
3005
|
-
const entries = await
|
|
3049
|
+
const entries = await readdir3(dir, { withFileTypes: true });
|
|
3006
3050
|
for (const entry of entries) {
|
|
3007
|
-
const fullPath =
|
|
3008
|
-
const relativePath =
|
|
3051
|
+
const fullPath = join10(dir, entry.name);
|
|
3052
|
+
const relativePath = relative2(baseDir, fullPath);
|
|
3009
3053
|
if (entry.name === "node_modules" || entry.name === ".git") {
|
|
3010
3054
|
continue;
|
|
3011
3055
|
}
|
|
@@ -3013,7 +3057,7 @@ async function getFilesWithSizes(dir, baseDir) {
|
|
|
3013
3057
|
const subFiles = await getFilesWithSizes(fullPath, baseDir);
|
|
3014
3058
|
results.push(...subFiles);
|
|
3015
3059
|
} else {
|
|
3016
|
-
const fileStat = await
|
|
3060
|
+
const fileStat = await stat6(fullPath);
|
|
3017
3061
|
results.push({ path: relativePath, size: fileStat.size });
|
|
3018
3062
|
}
|
|
3019
3063
|
}
|
|
@@ -3046,7 +3090,7 @@ async function publishCommand(options) {
|
|
|
3046
3090
|
files: manifest.files
|
|
3047
3091
|
};
|
|
3048
3092
|
if (options.bump) {
|
|
3049
|
-
const semver2 = await import(
|
|
3093
|
+
const semver2 = await import("semver");
|
|
3050
3094
|
const newVersion = semver2.default.inc(packageJson2.version, options.bump);
|
|
3051
3095
|
if (!newVersion) {
|
|
3052
3096
|
console.error(
|
|
@@ -3059,7 +3103,7 @@ async function publishCommand(options) {
|
|
|
3059
3103
|
}
|
|
3060
3104
|
const safeName = packageJson2.name.replace(/[@/]/g, "-").replace(/^-+/, "");
|
|
3061
3105
|
const tarballName = `${safeName}-${packageJson2.version}.tgz`;
|
|
3062
|
-
const tempDir =
|
|
3106
|
+
const tempDir = join10(process.cwd(), ".pspm-publish");
|
|
3063
3107
|
try {
|
|
3064
3108
|
await exec(`rm -rf "${tempDir}" && mkdir -p "${tempDir}"`);
|
|
3065
3109
|
const files = packageJson2.files || [...DEFAULT_SKILL_FILES];
|
|
@@ -3075,7 +3119,7 @@ async function publishCommand(options) {
|
|
|
3075
3119
|
if (detection.type === "pspm.json") {
|
|
3076
3120
|
await exec(`cp pspm.json "${tempDir}/package/"`);
|
|
3077
3121
|
try {
|
|
3078
|
-
await
|
|
3122
|
+
await stat6(join10(process.cwd(), "package.json"));
|
|
3079
3123
|
await exec(
|
|
3080
3124
|
`cp package.json "${tempDir}/package/" 2>/dev/null || true`
|
|
3081
3125
|
);
|
|
@@ -3084,30 +3128,30 @@ async function publishCommand(options) {
|
|
|
3084
3128
|
} else {
|
|
3085
3129
|
await exec(`cp package.json "${tempDir}/package/"`);
|
|
3086
3130
|
}
|
|
3087
|
-
const packageDir =
|
|
3131
|
+
const packageDir = join10(tempDir, "package");
|
|
3088
3132
|
const tarballContents = await getFilesWithSizes(packageDir, packageDir);
|
|
3089
3133
|
const unpackedSize = tarballContents.reduce((acc, f) => acc + f.size, 0);
|
|
3090
|
-
const tarballPath =
|
|
3134
|
+
const tarballPath = join10(tempDir, tarballName);
|
|
3091
3135
|
await exec(
|
|
3092
3136
|
`tar -czf "${tarballPath}" -C "${tempDir}" --exclude='node_modules' --exclude='.git' package`
|
|
3093
3137
|
);
|
|
3094
|
-
const tarballBuffer = await
|
|
3138
|
+
const tarballBuffer = await readFile6(tarballPath);
|
|
3095
3139
|
const tarballBase64 = tarballBuffer.toString("base64");
|
|
3096
3140
|
const tarballSize = tarballBuffer.length;
|
|
3097
|
-
const shasum =
|
|
3098
|
-
const integrityHash =
|
|
3141
|
+
const shasum = createHash3("sha1").update(tarballBuffer).digest("hex");
|
|
3142
|
+
const integrityHash = createHash3("sha512").update(tarballBuffer).digest("base64");
|
|
3099
3143
|
const integrity = `sha512-${integrityHash}`;
|
|
3100
3144
|
console.log("");
|
|
3101
|
-
console.log(
|
|
3145
|
+
console.log("pspm notice");
|
|
3102
3146
|
console.log(`pspm notice \u{1F4E6} ${packageJson2.name}@${packageJson2.version}`);
|
|
3103
|
-
console.log(
|
|
3147
|
+
console.log("pspm notice Tarball Contents");
|
|
3104
3148
|
tarballContents.sort((a, b) => b.size - a.size);
|
|
3105
3149
|
for (const file of tarballContents) {
|
|
3106
3150
|
console.log(
|
|
3107
3151
|
`pspm notice ${formatBytes(file.size).padStart(8)} ${file.path}`
|
|
3108
3152
|
);
|
|
3109
3153
|
}
|
|
3110
|
-
console.log(
|
|
3154
|
+
console.log("pspm notice Tarball Details");
|
|
3111
3155
|
console.log(`pspm notice name: ${packageJson2.name}`);
|
|
3112
3156
|
console.log(`pspm notice version: ${packageJson2.version}`);
|
|
3113
3157
|
console.log(`pspm notice filename: ${tarballName}`);
|
|
@@ -3118,7 +3162,7 @@ async function publishCommand(options) {
|
|
|
3118
3162
|
`pspm notice integrity: ${integrity.substring(0, 50)}...`
|
|
3119
3163
|
);
|
|
3120
3164
|
console.log(`pspm notice total files: ${tarballContents.length}`);
|
|
3121
|
-
console.log(
|
|
3165
|
+
console.log("pspm notice");
|
|
3122
3166
|
console.log(`pspm notice Publishing to ${registryUrl} with tag latest`);
|
|
3123
3167
|
configure2({ registryUrl, apiKey });
|
|
3124
3168
|
const response = await publishSkill({
|
|
@@ -3128,7 +3172,7 @@ async function publishCommand(options) {
|
|
|
3128
3172
|
if (response.status !== 200) {
|
|
3129
3173
|
const errorMessage = extractApiErrorMessage(response, "Publish failed");
|
|
3130
3174
|
if (errorMessage.includes("must be greater than") || errorMessage.includes("already exists")) {
|
|
3131
|
-
console.error(
|
|
3175
|
+
console.error("pspm error code E403");
|
|
3132
3176
|
console.error(
|
|
3133
3177
|
`pspm error 403 403 Forbidden - You cannot publish over the previously published versions: ${packageJson2.version}.`
|
|
3134
3178
|
);
|
|
@@ -3174,12 +3218,14 @@ Setting visibility to ${options.access}...`);
|
|
|
3174
3218
|
}
|
|
3175
3219
|
|
|
3176
3220
|
// src/commands/remove.ts
|
|
3177
|
-
init_src();
|
|
3178
3221
|
init_agents();
|
|
3179
3222
|
init_config();
|
|
3223
|
+
init_lib();
|
|
3180
3224
|
init_lockfile();
|
|
3181
3225
|
init_manifest2();
|
|
3182
3226
|
init_symlinks();
|
|
3227
|
+
import { rm as rm6 } from "fs/promises";
|
|
3228
|
+
import { join as join11 } from "path";
|
|
3183
3229
|
async function remove(nameOrSpecifier) {
|
|
3184
3230
|
try {
|
|
3185
3231
|
const manifest = await readManifest();
|
|
@@ -3220,9 +3266,9 @@ async function removeRegistry(specifier, agents, agentConfigs) {
|
|
|
3220
3266
|
agentConfigs
|
|
3221
3267
|
});
|
|
3222
3268
|
const skillsDir = getSkillsDir();
|
|
3223
|
-
const destDir =
|
|
3269
|
+
const destDir = join11(skillsDir, username, name);
|
|
3224
3270
|
try {
|
|
3225
|
-
await
|
|
3271
|
+
await rm6(destDir, { recursive: true, force: true });
|
|
3226
3272
|
} catch {
|
|
3227
3273
|
}
|
|
3228
3274
|
console.log(`Removed ${fullName}`);
|
|
@@ -3249,9 +3295,9 @@ async function removeGitHub(specifier, agents, agentConfigs) {
|
|
|
3249
3295
|
});
|
|
3250
3296
|
const skillsDir = getSkillsDir();
|
|
3251
3297
|
const destPath = getGitHubSkillPath(parsed.owner, parsed.repo, parsed.path);
|
|
3252
|
-
const destDir =
|
|
3298
|
+
const destDir = join11(skillsDir, "..", destPath);
|
|
3253
3299
|
try {
|
|
3254
|
-
await
|
|
3300
|
+
await rm6(destDir, { recursive: true, force: true });
|
|
3255
3301
|
} catch {
|
|
3256
3302
|
}
|
|
3257
3303
|
console.log(`Removed ${lockfileKey}`);
|
|
@@ -3281,10 +3327,10 @@ async function removeByShortName(shortName, agents, agentConfigs) {
|
|
|
3281
3327
|
}
|
|
3282
3328
|
|
|
3283
3329
|
// src/commands/unpublish.ts
|
|
3284
|
-
init_src();
|
|
3285
3330
|
init_api_client();
|
|
3286
3331
|
init_config();
|
|
3287
3332
|
init_errors();
|
|
3333
|
+
init_lib();
|
|
3288
3334
|
async function unpublish(specifier, options) {
|
|
3289
3335
|
try {
|
|
3290
3336
|
const apiKey = await requireApiKey();
|
|
@@ -3343,10 +3389,10 @@ async function unpublish(specifier, options) {
|
|
|
3343
3389
|
}
|
|
3344
3390
|
|
|
3345
3391
|
// src/commands/update.ts
|
|
3346
|
-
init_src();
|
|
3347
3392
|
init_api_client();
|
|
3348
3393
|
init_config();
|
|
3349
3394
|
init_errors();
|
|
3395
|
+
init_lib();
|
|
3350
3396
|
init_lockfile();
|
|
3351
3397
|
init_add();
|
|
3352
3398
|
async function update(options) {
|
|
@@ -3448,13 +3494,13 @@ async function whoami() {
|
|
|
3448
3494
|
}
|
|
3449
3495
|
|
|
3450
3496
|
// src/index.ts
|
|
3451
|
-
var __dirname
|
|
3497
|
+
var __dirname = dirname4(fileURLToPath(import.meta.url));
|
|
3452
3498
|
var packageJson = JSON.parse(
|
|
3453
|
-
readFileSync(
|
|
3499
|
+
readFileSync(join12(__dirname, "..", "package.json"), "utf-8")
|
|
3454
3500
|
);
|
|
3455
3501
|
var version = packageJson.version;
|
|
3456
3502
|
var program = new Command();
|
|
3457
|
-
program.name("pspm").description("Prompt Skill Package Manager for
|
|
3503
|
+
program.name("pspm").description("Prompt Skill Package Manager for AI coding agents").version(version);
|
|
3458
3504
|
var configCmd = program.command("config").description("Manage PSPM configuration");
|
|
3459
3505
|
configCmd.command("show").description("Show resolved configuration").action(async () => {
|
|
3460
3506
|
await configShow();
|
|
@@ -3554,5 +3600,4 @@ program.command("deprecate <specifier> [message]").description(
|
|
|
3554
3600
|
await deprecate(specifier, message, { undo: options.undo });
|
|
3555
3601
|
});
|
|
3556
3602
|
program.parse();
|
|
3557
|
-
//# sourceMappingURL=index.js.map
|
|
3558
3603
|
//# sourceMappingURL=index.js.map
|