@anytio/pspm 0.13.0 → 0.14.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.
@@ -0,0 +1,2 @@
1
+ import { t as install } from "./install-lNvqIk5c.js";
2
+ export { install };
@@ -0,0 +1,479 @@
1
+ import { g as listSkillVersions, m as getSkillVersion, n as configure } from "./api-client-DBXUpGoX.js";
2
+ import { T as extractApiErrorMessage, f as resolveConfig, g as getEncryptionKey, l as getSkillsDir, r as getCacheDir, u as isGlobalMode, y as getTokenForRegistry } from "./config-BQy_Rjip.js";
3
+ import { A as getDependencies, C as downloadGitHubPackage, N as readManifest, R as parseAgentArg, S as GitHubRateLimitError, T as getGitHubDisplayName, U as getGitHubSkillName, Y as parseGitHubSpecifier, Z as parseRegistrySpecifier, _ as readLockfile, a as getRegistrySkillPath, b as GitHubNotFoundError, c as addGitHubToLockfile, et as resolveVersion, g as migrateLockfileIfNeeded, j as getGitHubDependencies, n as getGitHubSkillPath, ot as calculateIntegrity, t as createAgentSymlinks, tt as computeInstallOrder, u as addToLockfile, ut as decryptBuffer, w as extractGitHubPackage, x as GitHubPathNotFoundError, z as promptForAgents } from "./symlinks-BTw8X0GG.js";
4
+ import { join } from "node:path";
5
+ import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
6
+ import { homedir } from "node:os";
7
+ import { createHash } from "node:crypto";
8
+ //#region src/commands/install-cache.ts
9
+ /**
10
+ * Get cache file path from integrity hash.
11
+ */
12
+ function getCacheFilePath(cacheDir, integrity) {
13
+ const match = integrity.match(/^sha256-(.+)$/);
14
+ if (!match) throw new Error(`Invalid integrity format: ${integrity}`);
15
+ const base64Hash = match[1];
16
+ return join(cacheDir, `sha256-${Buffer.from(base64Hash, "base64").toString("hex")}.tgz`);
17
+ }
18
+ /**
19
+ * Try to read tarball from cache.
20
+ *
21
+ * Returns null when the cache file is absent or corrupt (in which case it is
22
+ * deleted so subsequent runs cannot keep serving bad data).
23
+ */
24
+ async function readFromCache(cacheDir, integrity) {
25
+ try {
26
+ const cachePath = getCacheFilePath(cacheDir, integrity);
27
+ const data = await readFile(cachePath);
28
+ if (`sha256-${createHash("sha256").update(data).digest("base64")}` !== integrity) {
29
+ await rm(cachePath, { force: true });
30
+ return null;
31
+ }
32
+ return data;
33
+ } catch {
34
+ return null;
35
+ }
36
+ }
37
+ /**
38
+ * Write tarball to cache. Cache write failures are non-fatal.
39
+ */
40
+ async function writeToCache(cacheDir, integrity, data) {
41
+ try {
42
+ await mkdir(cacheDir, { recursive: true });
43
+ await writeFile(getCacheFilePath(cacheDir, integrity), data);
44
+ } catch {}
45
+ }
46
+ //#endregion
47
+ //#region src/commands/install-phases.ts
48
+ /**
49
+ * Phase 3: install registry packages from the lockfile in topological order.
50
+ */
51
+ async function installRegistryPackagesFromLockfile(packages, installedSkills, apiKey, cacheDir, skillsDir, frozenLockfile) {
52
+ const packageCount = Object.keys(packages).length;
53
+ console.log(`\nInstalling ${packageCount} registry skill(s)...\n`);
54
+ const entries = computeInstallOrder(packages).filter((name) => packages[name]).map((name) => [name, packages[name]]);
55
+ for (const [fullName, entry] of entries) await installOneRegistryPackage(fullName, entry, installedSkills, apiKey, cacheDir, skillsDir, frozenLockfile);
56
+ }
57
+ async function installOneRegistryPackage(fullName, entry, installedSkills, apiKey, cacheDir, skillsDir, frozenLockfile) {
58
+ const parsedName = parseRegistrySpecifier(fullName);
59
+ if (!parsedName) {
60
+ console.warn(`Warning: Invalid skill name in lockfile: ${fullName}`);
61
+ return;
62
+ }
63
+ const { namespace: ns, owner: pkgOwner, name, subname } = parsedName;
64
+ console.log(`Installing ${fullName}@${entry.version}...`);
65
+ let tarballBuffer;
66
+ let fromCache = false;
67
+ const cachedTarball = await readFromCache(cacheDir, entry.integrity);
68
+ if (cachedTarball) {
69
+ tarballBuffer = cachedTarball;
70
+ fromCache = true;
71
+ } else {
72
+ const downloaded = await downloadRegistryTarball(fullName, entry, apiKey, frozenLockfile);
73
+ if (!downloaded) return;
74
+ tarballBuffer = downloaded;
75
+ await writeToCache(cacheDir, entry.integrity, tarballBuffer);
76
+ }
77
+ if (entry.encryption) {
78
+ const decrypted = await decryptLockfileTarball(fullName, tarballBuffer, entry.encryption);
79
+ if (!decrypted) return;
80
+ tarballBuffer = decrypted;
81
+ }
82
+ const effectiveSkillName = subname ?? name;
83
+ const destDir = resolveRegistryDestDir(ns, pkgOwner, name, subname, effectiveSkillName, skillsDir);
84
+ await extractRegistryTarball(destDir, tarballBuffer);
85
+ console.log(` Installed to ${destDir}${fromCache ? " (from cache)" : ""}`);
86
+ const pathSkillName = ns === "github" && subname ? `${name}/${subname}` : name;
87
+ installedSkills.push({
88
+ name: effectiveSkillName,
89
+ sourcePath: getRegistrySkillPath(ns, pkgOwner, pathSkillName)
90
+ });
91
+ }
92
+ async function downloadRegistryTarball(fullName, entry, apiKey, frozenLockfile) {
93
+ const isPresignedUrl = entry.resolved.includes(".r2.cloudflarestorage.com") || entry.resolved.includes("X-Amz-Signature");
94
+ const downloadHeaders = {};
95
+ if (!isPresignedUrl && apiKey) downloadHeaders.Authorization = `Bearer ${apiKey}`;
96
+ const response = await fetch(entry.resolved, {
97
+ headers: downloadHeaders,
98
+ redirect: "follow"
99
+ });
100
+ if (!response.ok) {
101
+ if (response.status === 401) if (!apiKey) console.error(` Error: ${fullName} requires authentication. Run 'pspm login' first.`);
102
+ else console.error(` Error: Access denied to ${fullName}. You may not have permission to access this private package.`);
103
+ else console.error(` Error: Failed to download ${fullName} (${response.status})`);
104
+ return null;
105
+ }
106
+ const tarballBuffer = Buffer.from(await response.arrayBuffer());
107
+ if (`sha256-${createHash("sha256").update(tarballBuffer).digest("base64")}` !== entry.integrity) {
108
+ console.error(` Error: Checksum verification failed for ${fullName}`);
109
+ if (frozenLockfile) process.exit(1);
110
+ return null;
111
+ }
112
+ return tarballBuffer;
113
+ }
114
+ async function decryptLockfileTarball(fullName, tarballBuffer, encryption) {
115
+ const scope = encryption.scope;
116
+ const encKey = await getEncryptionKey(scope);
117
+ if (!encKey) {
118
+ console.error(` Error: Package ${fullName} is encrypted. Set the key: pspm config set-encryption-key ${scope} <passphrase>`);
119
+ return null;
120
+ }
121
+ try {
122
+ return decryptBuffer(tarballBuffer, encKey, encryption);
123
+ } catch {
124
+ console.error(` Error: Failed to decrypt ${fullName}. Wrong encryption key for scope "${scope}".`);
125
+ return null;
126
+ }
127
+ }
128
+ function resolveRegistryDestDir(ns, pkgOwner, name, subname, effectiveSkillName, skillsDir) {
129
+ if (ns === "org") return join(skillsDir, "_org", pkgOwner, effectiveSkillName);
130
+ if (ns === "github" && subname) return join(skillsDir, "_github-registry", pkgOwner, name, subname);
131
+ return join(skillsDir, pkgOwner, effectiveSkillName);
132
+ }
133
+ async function extractRegistryTarball(destDir, tarballBuffer) {
134
+ await rm(destDir, {
135
+ recursive: true,
136
+ force: true
137
+ });
138
+ await mkdir(destDir, { recursive: true });
139
+ const tempFile = join(destDir, ".temp.tgz");
140
+ await writeFile(tempFile, tarballBuffer);
141
+ const { exec } = await import("node:child_process");
142
+ const { promisify } = await import("node:util");
143
+ const execAsync = promisify(exec);
144
+ try {
145
+ await execAsync(`tar -xzf "${tempFile}" -C "${destDir}" --strip-components=1`);
146
+ } finally {
147
+ await rm(tempFile, { force: true });
148
+ }
149
+ }
150
+ /**
151
+ * Phase 4: install GitHub packages from the lockfile.
152
+ */
153
+ async function installGitHubPackagesFromLockfile(githubPackages, installedSkills, cacheDir, skillsDir, frozenLockfile) {
154
+ const githubCount = Object.keys(githubPackages).length;
155
+ console.log(`\nInstalling ${githubCount} GitHub skill(s)...\n`);
156
+ for (const [specifier, entry] of Object.entries(githubPackages)) await installOneGitHubPackage(specifier, entry, installedSkills, cacheDir, skillsDir, frozenLockfile);
157
+ }
158
+ async function installOneGitHubPackage(specifier, entry, installedSkills, cacheDir, skillsDir, frozenLockfile) {
159
+ const parsed = parseGitHubSpecifier(specifier);
160
+ if (!parsed) {
161
+ console.warn(`Warning: Invalid GitHub specifier in lockfile: ${specifier}`);
162
+ return;
163
+ }
164
+ console.log(`Installing ${specifier} (${entry.gitRef}@${entry.gitCommit.slice(0, 7)})...`);
165
+ let tarballBuffer;
166
+ let fromCache = false;
167
+ const cachedTarball = await readFromCache(cacheDir, entry.integrity);
168
+ if (cachedTarball) {
169
+ tarballBuffer = cachedTarball;
170
+ fromCache = true;
171
+ } else try {
172
+ const result = await downloadGitHubPackage({
173
+ ...parsed,
174
+ ref: entry.gitCommit
175
+ });
176
+ tarballBuffer = result.buffer;
177
+ if (result.integrity !== entry.integrity) {
178
+ console.error(` Error: Checksum verification failed for ${specifier}`);
179
+ if (frozenLockfile) process.exit(1);
180
+ return;
181
+ }
182
+ await writeToCache(cacheDir, entry.integrity, tarballBuffer);
183
+ } catch (error) {
184
+ reportGitHubDownloadError(specifier, error);
185
+ return;
186
+ }
187
+ try {
188
+ const destPath = await extractGitHubPackage(parsed, tarballBuffer, skillsDir);
189
+ console.log(` Installed to ${destPath}${fromCache ? " (from cache)" : ""}`);
190
+ const skillName = getGitHubSkillName(parsed);
191
+ installedSkills.push({
192
+ name: skillName,
193
+ sourcePath: getGitHubSkillPath(parsed.owner, parsed.repo, parsed.path)
194
+ });
195
+ } catch (error) {
196
+ const message = error instanceof Error ? error.message : String(error);
197
+ console.error(` Error extracting ${specifier}: ${message}`);
198
+ }
199
+ }
200
+ function reportGitHubDownloadError(specifier, error) {
201
+ if (error instanceof GitHubRateLimitError) console.error(` Error: ${error.message}`);
202
+ else if (error instanceof GitHubPathNotFoundError) console.error(` Error: ${error.message}`);
203
+ else if (error instanceof GitHubNotFoundError) console.error(` Error: ${error.message}`);
204
+ else {
205
+ const message = error instanceof Error ? error.message : String(error);
206
+ console.error(` Error downloading ${specifier}: ${message}`);
207
+ }
208
+ }
209
+ //#endregion
210
+ //#region src/commands/install-resolve.ts
211
+ /**
212
+ * Phase 1: resolve registry dependencies declared in pspm.json that are
213
+ * missing from the lockfile.
214
+ */
215
+ async function resolveMissingRegistryDeps(missingDeps, ctx) {
216
+ if (missingDeps.length === 0) return;
217
+ if (ctx.frozenLockfile) {
218
+ console.error("Error: Dependencies in pspm.json are not in lockfile. Cannot install with --frozen-lockfile");
219
+ console.error("Missing dependencies:");
220
+ for (const dep of missingDeps) console.error(` - ${dep.fullName}@${dep.versionRange}`);
221
+ process.exit(1);
222
+ }
223
+ console.log(`Resolving ${missingDeps.length} new dependency(ies)...\n`);
224
+ configure({
225
+ registryUrl: ctx.registryUrl,
226
+ apiKey: ctx.apiKey
227
+ });
228
+ for (const { fullName, versionRange } of missingDeps) await resolveOneRegistryDep(fullName, versionRange, ctx);
229
+ }
230
+ async function resolveOneRegistryDep(fullName, versionRange, ctx) {
231
+ const parsed = parseRegistrySpecifier(fullName);
232
+ if (!parsed) {
233
+ console.error(`Error: Invalid dependency specifier: ${fullName}`);
234
+ return;
235
+ }
236
+ const { owner, name } = parsed;
237
+ console.log(`Resolving ${fullName}@${versionRange}...`);
238
+ const versionsResponse = await listSkillVersions(owner, name);
239
+ if (versionsResponse.status !== 200) {
240
+ const errorMessage = extractApiErrorMessage(versionsResponse, `Skill ${fullName} not found`);
241
+ console.error(`Error: ${errorMessage}`);
242
+ return;
243
+ }
244
+ const versions = versionsResponse.data;
245
+ if (versions.length === 0) {
246
+ console.error(`Error: Skill ${fullName} not found`);
247
+ return;
248
+ }
249
+ const versionStrings = versions.map((v) => v.version);
250
+ const resolved = resolveVersion(versionRange || "*", versionStrings);
251
+ if (!resolved) {
252
+ console.error(`Error: No version matching "${versionRange}" for ${fullName}`);
253
+ return;
254
+ }
255
+ const versionResponse = await getSkillVersion(owner, name, resolved);
256
+ if (versionResponse.status !== 200 || !versionResponse.data) {
257
+ const errorMessage = extractApiErrorMessage(versionResponse, `Version ${resolved} not found`);
258
+ console.error(`Error: ${errorMessage}`);
259
+ return;
260
+ }
261
+ const versionInfo = versionResponse.data;
262
+ const isPresignedUrl = versionInfo.downloadUrl.includes(".r2.cloudflarestorage.com") || versionInfo.downloadUrl.includes("X-Amz-Signature");
263
+ const downloadHeaders = {};
264
+ if (!isPresignedUrl && ctx.apiKey) downloadHeaders.Authorization = `Bearer ${ctx.apiKey}`;
265
+ const tarballResponse = await fetch(versionInfo.downloadUrl, {
266
+ headers: downloadHeaders,
267
+ redirect: "follow"
268
+ });
269
+ if (!tarballResponse.ok) {
270
+ console.error(`Error: Failed to download tarball for ${fullName} (${tarballResponse.status})`);
271
+ return;
272
+ }
273
+ const tarballBuffer = Buffer.from(await tarballResponse.arrayBuffer());
274
+ const integrity = calculateIntegrity(tarballBuffer);
275
+ const lockfileEntry = {
276
+ version: resolved,
277
+ resolved: versionInfo.downloadUrl,
278
+ integrity
279
+ };
280
+ if (versionInfo.manifest?.encryption) lockfileEntry.encryption = versionInfo.manifest.encryption;
281
+ await addToLockfile(fullName, lockfileEntry);
282
+ await writeToCache(ctx.cacheDir, integrity, tarballBuffer);
283
+ console.log(` Resolved ${fullName}@${resolved}`);
284
+ }
285
+ /**
286
+ * Phase 2: resolve GitHub dependencies declared in pspm.json that are
287
+ * missing from the lockfile.
288
+ */
289
+ async function resolveMissingGitHubDeps(missingGitHubDeps, ctx) {
290
+ if (missingGitHubDeps.length === 0) return;
291
+ if (ctx.frozenLockfile) {
292
+ console.error("Error: GitHub dependencies in pspm.json are not in lockfile. Cannot install with --frozen-lockfile");
293
+ console.error("Missing GitHub dependencies:");
294
+ for (const dep of missingGitHubDeps) console.error(` - ${dep.specifier}@${dep.ref}`);
295
+ process.exit(1);
296
+ }
297
+ console.log(`\nResolving ${missingGitHubDeps.length} GitHub dependency(ies)...\n`);
298
+ for (const { specifier, ref } of missingGitHubDeps) await resolveOneGitHubDep(specifier, ref, ctx);
299
+ }
300
+ async function resolveOneGitHubDep(specifier, ref, ctx) {
301
+ const parsed = parseGitHubSpecifier(specifier);
302
+ if (!parsed) {
303
+ console.error(`Error: Invalid GitHub specifier: ${specifier}`);
304
+ return;
305
+ }
306
+ parsed.ref = parsed.ref || ref;
307
+ console.log(`Resolving ${getGitHubDisplayName(parsed)}...`);
308
+ try {
309
+ const result = await downloadGitHubPackage(parsed);
310
+ await extractGitHubPackage(parsed, result.buffer, ctx.skillsDir);
311
+ await addGitHubToLockfile(specifier, {
312
+ version: result.commit.slice(0, 7),
313
+ resolved: `https://github.com/${parsed.owner}/${parsed.repo}`,
314
+ integrity: result.integrity,
315
+ gitCommit: result.commit,
316
+ gitRef: ref || "HEAD"
317
+ });
318
+ await writeToCache(ctx.cacheDir, result.integrity, result.buffer);
319
+ console.log(` Resolved ${specifier} (${ref}@${result.commit.slice(0, 7)})`);
320
+ } catch (error) {
321
+ if (error instanceof GitHubRateLimitError) console.error(`Error: ${error.message}`);
322
+ else if (error instanceof GitHubPathNotFoundError) console.error(`Error: ${error.message}`);
323
+ else if (error instanceof GitHubNotFoundError) console.error(`Error: ${error.message}`);
324
+ else {
325
+ const message = error instanceof Error ? error.message : String(error);
326
+ console.error(`Error resolving ${specifier}: ${message}`);
327
+ }
328
+ }
329
+ }
330
+ //#endregion
331
+ //#region src/commands/install.ts
332
+ async function install(specifiers, options) {
333
+ if (options.global) {
334
+ const { setGlobalMode } = await import("./config-BZJ6_GsC.js");
335
+ setGlobalMode(true);
336
+ }
337
+ if (options.list) {
338
+ const listSpecifiers = await resolveListToSpecifiers(options.list);
339
+ if (listSpecifiers.length === 0) {
340
+ console.log("No skills in the list to install.");
341
+ return;
342
+ }
343
+ const allSpecifiers = [...specifiers, ...listSpecifiers];
344
+ const { add } = await import("./add-Cnn-OR9g.js");
345
+ await add(allSpecifiers, {
346
+ save: true,
347
+ agent: options.agent,
348
+ yes: options.yes,
349
+ global: options.global
350
+ });
351
+ return;
352
+ }
353
+ if (specifiers.length > 0) {
354
+ const { add } = await import("./add-Cnn-OR9g.js");
355
+ await add(specifiers, {
356
+ save: true,
357
+ agent: options.agent,
358
+ yes: options.yes,
359
+ global: options.global
360
+ });
361
+ return;
362
+ }
363
+ await installFromLockfile(options);
364
+ }
365
+ /**
366
+ * Parse a list specifier and fetch skills from the API.
367
+ * Formats: @user/username/list-name, @org/orgname/list-name
368
+ */
369
+ async function resolveListToSpecifiers(listSpec) {
370
+ const match = listSpec.match(/^@(user|org)\/([^/]+)\/([^/]+)$/);
371
+ if (!match) {
372
+ console.error(`Error: Invalid list specifier "${listSpec}". Use format: @user/{username}/{list-name} or @org/{orgname}/{list-name}`);
373
+ process.exit(1);
374
+ }
375
+ const [, ownerType, ownerName, listName] = match;
376
+ const config = await resolveConfig();
377
+ configure({
378
+ registryUrl: config.registryUrl,
379
+ apiKey: getTokenForRegistry(config, config.registryUrl)
380
+ });
381
+ console.log(`Fetching skill list @${ownerType}/${ownerName}/${listName}...\n`);
382
+ const { fetchSkillList } = await import("./api-client-CBTk37gh.js");
383
+ const response = await fetchSkillList(ownerType, ownerName, listName);
384
+ if (response.status !== 200 || !response.data) {
385
+ const errorMsg = response.status === 404 ? `List "@${ownerType}/${ownerName}/${listName}" not found or is private.` : response.error || "Failed to fetch list";
386
+ console.error(`Error: ${errorMsg}`);
387
+ process.exit(1);
388
+ }
389
+ const list = response.data;
390
+ console.log(`List: ${list.name}${list.description ? ` — ${list.description}` : ""}`);
391
+ console.log(`Skills: ${list.items.length}\n`);
392
+ const specifiers = [];
393
+ for (const item of list.items) {
394
+ let spec = `@${item.namespace === "org" ? "org" : "user"}/${item.ownerName}/${item.skillName}`;
395
+ if (item.pinnedVersion) spec += `@${item.pinnedVersion}`;
396
+ specifiers.push(spec);
397
+ }
398
+ return specifiers;
399
+ }
400
+ async function installFromLockfile(options) {
401
+ try {
402
+ const config = await resolveConfig();
403
+ const registryUrl = config.registryUrl;
404
+ const apiKey = getTokenForRegistry(config, registryUrl);
405
+ const skillsDir = options.dir || getSkillsDir();
406
+ const cacheDir = getCacheDir();
407
+ await migrateLockfileIfNeeded();
408
+ let lockfile = await readLockfile();
409
+ const manifestDeps = await getDependencies();
410
+ const manifestGitHubDeps = await getGitHubDependencies();
411
+ const lockfilePackages = lockfile?.packages ?? lockfile?.skills ?? {};
412
+ const lockfileGitHubPackages = lockfile?.githubPackages ?? {};
413
+ const installedSkills = [];
414
+ const missingDeps = [];
415
+ for (const [fullName, versionRange] of Object.entries(manifestDeps)) if (!lockfilePackages[fullName]) missingDeps.push({
416
+ fullName,
417
+ versionRange
418
+ });
419
+ const resolveCtx = {
420
+ registryUrl,
421
+ apiKey,
422
+ cacheDir,
423
+ skillsDir,
424
+ frozenLockfile: options.frozenLockfile
425
+ };
426
+ if (missingDeps.length > 0) {
427
+ await resolveMissingRegistryDeps(missingDeps, resolveCtx);
428
+ lockfile = await readLockfile();
429
+ }
430
+ const missingGitHubDeps = [];
431
+ for (const [specifier, ref] of Object.entries(manifestGitHubDeps)) if (!lockfileGitHubPackages[specifier]) missingGitHubDeps.push({
432
+ specifier,
433
+ ref
434
+ });
435
+ if (missingGitHubDeps.length > 0) {
436
+ await resolveMissingGitHubDeps(missingGitHubDeps, resolveCtx);
437
+ lockfile = await readLockfile();
438
+ }
439
+ const manifest = await readManifest();
440
+ const agentConfigs = manifest?.agents;
441
+ let agents;
442
+ if (options.agent) agents = parseAgentArg(options.agent);
443
+ else if (manifest) agents = parseAgentArg(void 0);
444
+ else if (options.yes) agents = parseAgentArg(void 0);
445
+ else {
446
+ console.log("\nNo pspm.json found. Let's set up your project.\n");
447
+ agents = await promptForAgents();
448
+ console.log();
449
+ }
450
+ const packages = lockfile?.packages ?? lockfile?.skills ?? {};
451
+ const packageCount = Object.keys(packages).length;
452
+ if (packageCount > 0) await installRegistryPackagesFromLockfile(packages, installedSkills, apiKey, cacheDir, skillsDir, options.frozenLockfile);
453
+ const githubPackages = lockfile?.githubPackages ?? {};
454
+ const githubCount = Object.keys(githubPackages).length;
455
+ if (githubCount > 0) await installGitHubPackagesFromLockfile(githubPackages, installedSkills, cacheDir, skillsDir, options.frozenLockfile);
456
+ if (installedSkills.length > 0 && agents[0] !== "none") {
457
+ const globalMode = isGlobalMode();
458
+ console.log(`\nCreating symlinks for agent(s): ${agents.join(", ")}${globalMode ? " (global)" : ""}...`);
459
+ await createAgentSymlinks(installedSkills, {
460
+ agents,
461
+ projectRoot: globalMode ? homedir() : process.cwd(),
462
+ agentConfigs,
463
+ global: globalMode
464
+ });
465
+ console.log(" Symlinks created.");
466
+ }
467
+ const totalCount = packageCount + githubCount;
468
+ if (totalCount === 0) console.log("No skills to install.");
469
+ else console.log(`\nAll ${totalCount} skill(s) installed.`);
470
+ } catch (error) {
471
+ const message = error instanceof Error ? error.message : "Unknown error";
472
+ console.error(`Error: ${message}`);
473
+ process.exit(1);
474
+ }
475
+ }
476
+ //#endregion
477
+ export { install as t };
478
+
479
+ //# sourceMappingURL=install-lNvqIk5c.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-lNvqIk5c.js","names":[],"sources":["../src/commands/install-cache.ts","../src/commands/install-phases.ts","../src/commands/install-resolve.ts","../src/commands/install.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\n/**\n * Get cache file path from integrity hash.\n */\nexport function getCacheFilePath(cacheDir: string, integrity: string): string {\n const match = integrity.match(/^sha256-(.+)$/);\n if (!match) {\n throw new Error(`Invalid integrity format: ${integrity}`);\n }\n const base64Hash = match[1];\n const hexHash = Buffer.from(base64Hash, \"base64\").toString(\"hex\");\n return join(cacheDir, `sha256-${hexHash}.tgz`);\n}\n\n/**\n * Try to read tarball from cache.\n *\n * Returns null when the cache file is absent or corrupt (in which case it is\n * deleted so subsequent runs cannot keep serving bad data).\n */\nexport async function readFromCache(\n cacheDir: string,\n integrity: string,\n): Promise<Buffer | null> {\n try {\n const cachePath = getCacheFilePath(cacheDir, integrity);\n const data = await readFile(cachePath);\n\n const actualIntegrity = `sha256-${createHash(\"sha256\").update(data).digest(\"base64\")}`;\n if (actualIntegrity !== integrity) {\n await rm(cachePath, { force: true });\n return null;\n }\n\n return data;\n } catch {\n return null;\n }\n}\n\n/**\n * Write tarball to cache. Cache write failures are non-fatal.\n */\nexport async function writeToCache(\n cacheDir: string,\n integrity: string,\n data: Buffer,\n): Promise<void> {\n try {\n await mkdir(cacheDir, { recursive: true });\n const cachePath = getCacheFilePath(cacheDir, integrity);\n await writeFile(cachePath, data);\n } catch {\n // Cache write failures are non-fatal\n }\n}\n","import { createHash } from \"node:crypto\";\nimport { mkdir, rm, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { getEncryptionKey } from \"@/config\";\nimport {\n downloadGitHubPackage,\n extractGitHubPackage,\n GitHubNotFoundError,\n GitHubPathNotFoundError,\n GitHubRateLimitError,\n} from \"@/github\";\nimport { decryptBuffer } from \"@/lib/encryption\";\nimport {\n computeInstallOrder,\n type GitHubLockfileEntry,\n getGitHubSkillName,\n type PspmLockfileEntry,\n parseGitHubSpecifier,\n parseRegistrySpecifier,\n} from \"@/lib/index\";\nimport {\n getGitHubSkillPath,\n getRegistrySkillPath,\n type SkillInfo,\n} from \"@/symlinks\";\nimport { readFromCache, writeToCache } from \"./install-cache\";\n\n/**\n * Phase 3: install registry packages from the lockfile in topological order.\n */\nexport async function installRegistryPackagesFromLockfile(\n packages: Record<string, PspmLockfileEntry>,\n installedSkills: SkillInfo[],\n apiKey: string | undefined,\n cacheDir: string,\n skillsDir: string,\n frozenLockfile: boolean | undefined,\n): Promise<void> {\n const packageCount = Object.keys(packages).length;\n console.log(`\\nInstalling ${packageCount} registry skill(s)...\\n`);\n\n const installOrder = computeInstallOrder(packages);\n const entries: [string, PspmLockfileEntry][] = installOrder\n .filter((name) => packages[name])\n .map((name) => [name, packages[name]]);\n\n for (const [fullName, entry] of entries) {\n await installOneRegistryPackage(\n fullName,\n entry,\n installedSkills,\n apiKey,\n cacheDir,\n skillsDir,\n frozenLockfile,\n );\n }\n}\n\nasync function installOneRegistryPackage(\n fullName: string,\n entry: PspmLockfileEntry,\n installedSkills: SkillInfo[],\n apiKey: string | undefined,\n cacheDir: string,\n skillsDir: string,\n frozenLockfile: boolean | undefined,\n): Promise<void> {\n const parsedName = parseRegistrySpecifier(fullName);\n if (!parsedName) {\n console.warn(`Warning: Invalid skill name in lockfile: ${fullName}`);\n return;\n }\n\n const { namespace: ns, owner: pkgOwner, name, subname } = parsedName;\n console.log(`Installing ${fullName}@${entry.version}...`);\n\n let tarballBuffer: Buffer;\n let fromCache = false;\n\n const cachedTarball = await readFromCache(cacheDir, entry.integrity);\n if (cachedTarball) {\n tarballBuffer = cachedTarball;\n fromCache = true;\n } else {\n const downloaded = await downloadRegistryTarball(\n fullName,\n entry,\n apiKey,\n frozenLockfile,\n );\n if (!downloaded) return;\n tarballBuffer = downloaded;\n await writeToCache(cacheDir, entry.integrity, tarballBuffer);\n }\n\n if (entry.encryption) {\n const decrypted = await decryptLockfileTarball(\n fullName,\n tarballBuffer,\n entry.encryption,\n );\n if (!decrypted) return;\n tarballBuffer = decrypted;\n }\n\n const effectiveSkillName = subname ?? name;\n const destDir = resolveRegistryDestDir(\n ns,\n pkgOwner,\n name,\n subname,\n effectiveSkillName,\n skillsDir,\n );\n await extractRegistryTarball(destDir, tarballBuffer);\n\n console.log(` Installed to ${destDir}${fromCache ? \" (from cache)\" : \"\"}`);\n\n const pathSkillName =\n ns === \"github\" && subname ? `${name}/${subname}` : name;\n installedSkills.push({\n name: effectiveSkillName,\n sourcePath: getRegistrySkillPath(ns, pkgOwner, pathSkillName),\n });\n}\n\nasync function downloadRegistryTarball(\n fullName: string,\n entry: PspmLockfileEntry,\n apiKey: string | undefined,\n frozenLockfile: boolean | undefined,\n): Promise<Buffer | null> {\n const isPresignedUrl =\n entry.resolved.includes(\".r2.cloudflarestorage.com\") ||\n entry.resolved.includes(\"X-Amz-Signature\");\n\n const downloadHeaders: Record<string, string> = {};\n if (!isPresignedUrl && apiKey) {\n downloadHeaders.Authorization = `Bearer ${apiKey}`;\n }\n\n const response = await fetch(entry.resolved, {\n headers: downloadHeaders,\n redirect: \"follow\",\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n if (!apiKey) {\n console.error(\n ` Error: ${fullName} requires authentication. Run 'pspm login' first.`,\n );\n } else {\n console.error(\n ` Error: Access denied to ${fullName}. You may not have permission to access this private package.`,\n );\n }\n } else {\n console.error(\n ` Error: Failed to download ${fullName} (${response.status})`,\n );\n }\n return null;\n }\n\n const tarballBuffer = Buffer.from(await response.arrayBuffer());\n\n const actualIntegrity = `sha256-${createHash(\"sha256\").update(tarballBuffer).digest(\"base64\")}`;\n\n if (actualIntegrity !== entry.integrity) {\n console.error(` Error: Checksum verification failed for ${fullName}`);\n if (frozenLockfile) {\n process.exit(1);\n }\n return null;\n }\n\n return tarballBuffer;\n}\n\nasync function decryptLockfileTarball(\n fullName: string,\n tarballBuffer: Buffer,\n encryption: NonNullable<PspmLockfileEntry[\"encryption\"]>,\n): Promise<Buffer | null> {\n const scope = encryption.scope;\n const encKey = await getEncryptionKey(scope);\n if (!encKey) {\n console.error(\n ` Error: Package ${fullName} is encrypted. Set the key: pspm config set-encryption-key ${scope} <passphrase>`,\n );\n return null;\n }\n try {\n return decryptBuffer(tarballBuffer, encKey, encryption);\n } catch {\n console.error(\n ` Error: Failed to decrypt ${fullName}. Wrong encryption key for scope \"${scope}\".`,\n );\n return null;\n }\n}\n\nfunction resolveRegistryDestDir(\n ns: string,\n pkgOwner: string,\n name: string,\n subname: string | undefined,\n effectiveSkillName: string,\n skillsDir: string,\n): string {\n if (ns === \"org\") {\n return join(skillsDir, \"_org\", pkgOwner, effectiveSkillName);\n }\n if (ns === \"github\" && subname) {\n return join(skillsDir, \"_github-registry\", pkgOwner, name, subname);\n }\n return join(skillsDir, pkgOwner, effectiveSkillName);\n}\n\nasync function extractRegistryTarball(\n destDir: string,\n tarballBuffer: Buffer,\n): Promise<void> {\n await rm(destDir, { recursive: true, force: true });\n await mkdir(destDir, { recursive: true });\n\n const tempFile = join(destDir, \".temp.tgz\");\n await writeFile(tempFile, tarballBuffer);\n\n const { exec } = await import(\"node:child_process\");\n const { promisify } = await import(\"node:util\");\n const execAsync = promisify(exec);\n\n try {\n await execAsync(\n `tar -xzf \"${tempFile}\" -C \"${destDir}\" --strip-components=1`,\n );\n } finally {\n await rm(tempFile, { force: true });\n }\n}\n\n/**\n * Phase 4: install GitHub packages from the lockfile.\n */\nexport async function installGitHubPackagesFromLockfile(\n githubPackages: Record<string, GitHubLockfileEntry>,\n installedSkills: SkillInfo[],\n cacheDir: string,\n skillsDir: string,\n frozenLockfile: boolean | undefined,\n): Promise<void> {\n const githubCount = Object.keys(githubPackages).length;\n console.log(`\\nInstalling ${githubCount} GitHub skill(s)...\\n`);\n\n for (const [specifier, entry] of Object.entries(githubPackages)) {\n await installOneGitHubPackage(\n specifier,\n entry,\n installedSkills,\n cacheDir,\n skillsDir,\n frozenLockfile,\n );\n }\n}\n\nasync function installOneGitHubPackage(\n specifier: string,\n entry: GitHubLockfileEntry,\n installedSkills: SkillInfo[],\n cacheDir: string,\n skillsDir: string,\n frozenLockfile: boolean | undefined,\n): Promise<void> {\n const parsed = parseGitHubSpecifier(specifier);\n if (!parsed) {\n console.warn(`Warning: Invalid GitHub specifier in lockfile: ${specifier}`);\n return;\n }\n\n console.log(\n `Installing ${specifier} (${entry.gitRef}@${entry.gitCommit.slice(0, 7)})...`,\n );\n\n let tarballBuffer: Buffer;\n let fromCache = false;\n\n const cachedTarball = await readFromCache(cacheDir, entry.integrity);\n if (cachedTarball) {\n tarballBuffer = cachedTarball;\n fromCache = true;\n } else {\n try {\n const specWithCommit = { ...parsed, ref: entry.gitCommit };\n const result = await downloadGitHubPackage(specWithCommit);\n tarballBuffer = result.buffer;\n\n if (result.integrity !== entry.integrity) {\n console.error(` Error: Checksum verification failed for ${specifier}`);\n if (frozenLockfile) {\n process.exit(1);\n }\n return;\n }\n\n await writeToCache(cacheDir, entry.integrity, tarballBuffer);\n } catch (error) {\n reportGitHubDownloadError(specifier, error);\n return;\n }\n }\n\n try {\n const destPath = await extractGitHubPackage(\n parsed,\n tarballBuffer,\n skillsDir,\n );\n console.log(\n ` Installed to ${destPath}${fromCache ? \" (from cache)\" : \"\"}`,\n );\n\n const skillName = getGitHubSkillName(parsed);\n installedSkills.push({\n name: skillName,\n sourcePath: getGitHubSkillPath(parsed.owner, parsed.repo, parsed.path),\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.error(` Error extracting ${specifier}: ${message}`);\n }\n}\n\nfunction reportGitHubDownloadError(specifier: string, error: unknown): void {\n if (error instanceof GitHubRateLimitError) {\n console.error(` Error: ${error.message}`);\n } else if (error instanceof GitHubPathNotFoundError) {\n console.error(` Error: ${error.message}`);\n } else if (error instanceof GitHubNotFoundError) {\n console.error(` Error: ${error.message}`);\n } else {\n const message = error instanceof Error ? error.message : String(error);\n console.error(` Error downloading ${specifier}: ${message}`);\n }\n}\n","import { configure, getSkillVersion, listSkillVersions } from \"@/api-client\";\nimport { extractApiErrorMessage } from \"@/errors\";\nimport {\n downloadGitHubPackage,\n extractGitHubPackage,\n GitHubNotFoundError,\n GitHubPathNotFoundError,\n GitHubRateLimitError,\n getGitHubDisplayName,\n} from \"@/github\";\nimport {\n calculateIntegrity,\n type GitHubLockfileEntry,\n type PspmLockfileEntry,\n parseGitHubSpecifier,\n parseRegistrySpecifier,\n resolveVersion,\n} from \"@/lib/index\";\nimport { addGitHubToLockfile, addToLockfile } from \"@/lockfile\";\nimport { writeToCache } from \"./install-cache\";\n\ninterface ResolveContext {\n registryUrl: string;\n apiKey: string | undefined;\n cacheDir: string;\n skillsDir: string;\n frozenLockfile?: boolean;\n}\n\n/**\n * Phase 1: resolve registry dependencies declared in pspm.json that are\n * missing from the lockfile.\n */\nexport async function resolveMissingRegistryDeps(\n missingDeps: Array<{ fullName: string; versionRange: string }>,\n ctx: ResolveContext,\n): Promise<void> {\n if (missingDeps.length === 0) return;\n\n if (ctx.frozenLockfile) {\n console.error(\n \"Error: Dependencies in pspm.json are not in lockfile. Cannot install with --frozen-lockfile\",\n );\n console.error(\"Missing dependencies:\");\n for (const dep of missingDeps) {\n console.error(` - ${dep.fullName}@${dep.versionRange}`);\n }\n process.exit(1);\n }\n\n console.log(`Resolving ${missingDeps.length} new dependency(ies)...\\n`);\n configure({ registryUrl: ctx.registryUrl, apiKey: ctx.apiKey });\n\n for (const { fullName, versionRange } of missingDeps) {\n await resolveOneRegistryDep(fullName, versionRange, ctx);\n }\n}\n\nasync function resolveOneRegistryDep(\n fullName: string,\n versionRange: string,\n ctx: ResolveContext,\n): Promise<void> {\n const parsed = parseRegistrySpecifier(fullName);\n if (!parsed) {\n console.error(`Error: Invalid dependency specifier: ${fullName}`);\n return;\n }\n\n const { owner, name } = parsed;\n console.log(`Resolving ${fullName}@${versionRange}...`);\n\n const versionsResponse = await listSkillVersions(owner, name);\n if (versionsResponse.status !== 200) {\n const errorMessage = extractApiErrorMessage(\n versionsResponse,\n `Skill ${fullName} not found`,\n );\n console.error(`Error: ${errorMessage}`);\n return;\n }\n\n const versions = versionsResponse.data;\n if (versions.length === 0) {\n console.error(`Error: Skill ${fullName} not found`);\n return;\n }\n\n const versionStrings = versions.map((v: { version: string }) => v.version);\n const resolved = resolveVersion(versionRange || \"*\", versionStrings);\n\n if (!resolved) {\n console.error(\n `Error: No version matching \"${versionRange}\" for ${fullName}`,\n );\n return;\n }\n\n const versionResponse = await getSkillVersion(owner, name, resolved);\n if (versionResponse.status !== 200 || !versionResponse.data) {\n const errorMessage = extractApiErrorMessage(\n versionResponse,\n `Version ${resolved} not found`,\n );\n console.error(`Error: ${errorMessage}`);\n return;\n }\n const versionInfo = versionResponse.data;\n\n const isPresignedUrl =\n versionInfo.downloadUrl.includes(\".r2.cloudflarestorage.com\") ||\n versionInfo.downloadUrl.includes(\"X-Amz-Signature\");\n\n const downloadHeaders: Record<string, string> = {};\n if (!isPresignedUrl && ctx.apiKey) {\n downloadHeaders.Authorization = `Bearer ${ctx.apiKey}`;\n }\n\n const tarballResponse = await fetch(versionInfo.downloadUrl, {\n headers: downloadHeaders,\n redirect: \"follow\",\n });\n\n if (!tarballResponse.ok) {\n console.error(\n `Error: Failed to download tarball for ${fullName} (${tarballResponse.status})`,\n );\n return;\n }\n\n const tarballBuffer = Buffer.from(await tarballResponse.arrayBuffer());\n const integrity = calculateIntegrity(tarballBuffer);\n\n const lockfileEntry: PspmLockfileEntry = {\n version: resolved,\n resolved: versionInfo.downloadUrl,\n integrity,\n };\n if (versionInfo.manifest?.encryption) {\n lockfileEntry.encryption = versionInfo.manifest.encryption;\n }\n await addToLockfile(fullName, lockfileEntry);\n\n await writeToCache(ctx.cacheDir, integrity, tarballBuffer);\n\n console.log(` Resolved ${fullName}@${resolved}`);\n}\n\n/**\n * Phase 2: resolve GitHub dependencies declared in pspm.json that are\n * missing from the lockfile.\n */\nexport async function resolveMissingGitHubDeps(\n missingGitHubDeps: Array<{ specifier: string; ref: string }>,\n ctx: ResolveContext,\n): Promise<void> {\n if (missingGitHubDeps.length === 0) return;\n\n if (ctx.frozenLockfile) {\n console.error(\n \"Error: GitHub dependencies in pspm.json are not in lockfile. Cannot install with --frozen-lockfile\",\n );\n console.error(\"Missing GitHub dependencies:\");\n for (const dep of missingGitHubDeps) {\n console.error(` - ${dep.specifier}@${dep.ref}`);\n }\n process.exit(1);\n }\n\n console.log(\n `\\nResolving ${missingGitHubDeps.length} GitHub dependency(ies)...\\n`,\n );\n\n for (const { specifier, ref } of missingGitHubDeps) {\n await resolveOneGitHubDep(specifier, ref, ctx);\n }\n}\n\nasync function resolveOneGitHubDep(\n specifier: string,\n ref: string,\n ctx: ResolveContext,\n): Promise<void> {\n const parsed = parseGitHubSpecifier(specifier);\n if (!parsed) {\n console.error(`Error: Invalid GitHub specifier: ${specifier}`);\n return;\n }\n\n parsed.ref = parsed.ref || ref;\n\n console.log(`Resolving ${getGitHubDisplayName(parsed)}...`);\n\n try {\n const result = await downloadGitHubPackage(parsed);\n\n await extractGitHubPackage(parsed, result.buffer, ctx.skillsDir);\n\n const entry: GitHubLockfileEntry = {\n version: result.commit.slice(0, 7),\n resolved: `https://github.com/${parsed.owner}/${parsed.repo}`,\n integrity: result.integrity,\n gitCommit: result.commit,\n gitRef: ref || \"HEAD\",\n };\n\n await addGitHubToLockfile(specifier, entry);\n\n await writeToCache(ctx.cacheDir, result.integrity, result.buffer);\n\n console.log(\n ` Resolved ${specifier} (${ref}@${result.commit.slice(0, 7)})`,\n );\n } catch (error) {\n if (error instanceof GitHubRateLimitError) {\n console.error(`Error: ${error.message}`);\n } else if (error instanceof GitHubPathNotFoundError) {\n console.error(`Error: ${error.message}`);\n } else if (error instanceof GitHubNotFoundError) {\n console.error(`Error: ${error.message}`);\n } else {\n const message = error instanceof Error ? error.message : String(error);\n console.error(`Error resolving ${specifier}: ${message}`);\n }\n }\n}\n","import { homedir } from \"node:os\";\nimport { parseAgentArg, promptForAgents } from \"@/agents\";\nimport { configure } from \"@/api-client\";\nimport {\n getCacheDir,\n getSkillsDir,\n getTokenForRegistry,\n isGlobalMode,\n resolveConfig,\n} from \"@/config\";\nimport { migrateLockfileIfNeeded, readLockfile } from \"@/lockfile\";\nimport {\n getDependencies,\n getGitHubDependencies,\n readManifest,\n} from \"@/manifest\";\nimport { createAgentSymlinks, type SkillInfo } from \"@/symlinks\";\nimport {\n installGitHubPackagesFromLockfile,\n installRegistryPackagesFromLockfile,\n} from \"./install-phases\";\nimport {\n resolveMissingGitHubDeps,\n resolveMissingRegistryDeps,\n} from \"./install-resolve\";\n\nexport interface InstallOptions {\n frozenLockfile?: boolean;\n dir?: string;\n agent?: string;\n /** Install all skills from a skill list (e.g. @user/username/list-name) */\n list?: string;\n yes?: boolean;\n /** Install globally (to ~/.pspm/ with global agent paths) */\n global?: boolean;\n}\n\nexport async function install(\n specifiers: string[],\n options: InstallOptions,\n): Promise<void> {\n if (options.global) {\n const { setGlobalMode } = await import(\"@/config\");\n setGlobalMode(true);\n }\n\n if (options.list) {\n const listSpecifiers = await resolveListToSpecifiers(options.list);\n if (listSpecifiers.length === 0) {\n console.log(\"No skills in the list to install.\");\n return;\n }\n const allSpecifiers = [...specifiers, ...listSpecifiers];\n const { add } = await import(\"./add.js\");\n await add(allSpecifiers, {\n save: true,\n agent: options.agent,\n yes: options.yes,\n global: options.global,\n });\n return;\n }\n\n if (specifiers.length > 0) {\n const { add } = await import(\"./add.js\");\n await add(specifiers, {\n save: true,\n agent: options.agent,\n yes: options.yes,\n global: options.global,\n });\n return;\n }\n\n await installFromLockfile(options);\n}\n\n/**\n * Parse a list specifier and fetch skills from the API.\n * Formats: @user/username/list-name, @org/orgname/list-name\n */\nasync function resolveListToSpecifiers(listSpec: string): Promise<string[]> {\n const match = listSpec.match(/^@(user|org)\\/([^/]+)\\/([^/]+)$/);\n if (!match) {\n console.error(\n `Error: Invalid list specifier \"${listSpec}\". Use format: @user/{username}/{list-name} or @org/{orgname}/{list-name}`,\n );\n process.exit(1);\n }\n\n const [, ownerType, ownerName, listName] = match;\n\n const config = await resolveConfig();\n configure({\n registryUrl: config.registryUrl,\n apiKey: getTokenForRegistry(config, config.registryUrl),\n });\n\n console.log(\n `Fetching skill list @${ownerType}/${ownerName}/${listName}...\\n`,\n );\n\n const { fetchSkillList } = await import(\"@/api-client\");\n const response = await fetchSkillList(\n ownerType as \"user\" | \"org\",\n ownerName,\n listName,\n );\n\n if (response.status !== 200 || !response.data) {\n const errorMsg =\n response.status === 404\n ? `List \"@${ownerType}/${ownerName}/${listName}\" not found or is private.`\n : response.error || \"Failed to fetch list\";\n console.error(`Error: ${errorMsg}`);\n process.exit(1);\n }\n\n const list = response.data;\n console.log(\n `List: ${list.name}${list.description ? ` — ${list.description}` : \"\"}`,\n );\n console.log(`Skills: ${list.items.length}\\n`);\n\n const specifiers: string[] = [];\n for (const item of list.items) {\n const ns = item.namespace === \"org\" ? \"org\" : \"user\";\n let spec = `@${ns}/${item.ownerName}/${item.skillName}`;\n if (item.pinnedVersion) {\n spec += `@${item.pinnedVersion}`;\n }\n specifiers.push(spec);\n }\n\n return specifiers;\n}\n\nasync function installFromLockfile(options: InstallOptions): Promise<void> {\n try {\n const config = await resolveConfig();\n const registryUrl = config.registryUrl;\n const apiKey = getTokenForRegistry(config, registryUrl);\n const skillsDir = options.dir || getSkillsDir();\n const cacheDir = getCacheDir();\n\n await migrateLockfileIfNeeded();\n\n let lockfile = await readLockfile();\n const manifestDeps = await getDependencies();\n const manifestGitHubDeps = await getGitHubDependencies();\n const lockfilePackages = lockfile?.packages ?? lockfile?.skills ?? {};\n const lockfileGitHubPackages = lockfile?.githubPackages ?? {};\n\n const installedSkills: SkillInfo[] = [];\n\n const missingDeps: Array<{ fullName: string; versionRange: string }> = [];\n for (const [fullName, versionRange] of Object.entries(manifestDeps)) {\n if (!lockfilePackages[fullName]) {\n missingDeps.push({ fullName, versionRange });\n }\n }\n\n const resolveCtx = {\n registryUrl,\n apiKey,\n cacheDir,\n skillsDir,\n frozenLockfile: options.frozenLockfile,\n };\n\n if (missingDeps.length > 0) {\n await resolveMissingRegistryDeps(missingDeps, resolveCtx);\n lockfile = await readLockfile();\n }\n\n const missingGitHubDeps: Array<{ specifier: string; ref: string }> = [];\n for (const [specifier, ref] of Object.entries(manifestGitHubDeps)) {\n if (!lockfileGitHubPackages[specifier]) {\n missingGitHubDeps.push({ specifier, ref });\n }\n }\n\n if (missingGitHubDeps.length > 0) {\n await resolveMissingGitHubDeps(missingGitHubDeps, resolveCtx);\n lockfile = await readLockfile();\n }\n\n const manifest = await readManifest();\n const agentConfigs = manifest?.agents;\n\n let agents: string[];\n if (options.agent) {\n agents = parseAgentArg(options.agent);\n } else if (manifest) {\n agents = parseAgentArg(undefined);\n } else if (options.yes) {\n agents = parseAgentArg(undefined);\n } else {\n console.log(\"\\nNo pspm.json found. Let's set up your project.\\n\");\n agents = await promptForAgents();\n console.log();\n }\n\n const packages = lockfile?.packages ?? lockfile?.skills ?? {};\n const packageCount = Object.keys(packages).length;\n\n if (packageCount > 0) {\n await installRegistryPackagesFromLockfile(\n packages,\n installedSkills,\n apiKey,\n cacheDir,\n skillsDir,\n options.frozenLockfile,\n );\n }\n\n const githubPackages = lockfile?.githubPackages ?? {};\n const githubCount = Object.keys(githubPackages).length;\n\n if (githubCount > 0) {\n await installGitHubPackagesFromLockfile(\n githubPackages,\n installedSkills,\n cacheDir,\n skillsDir,\n options.frozenLockfile,\n );\n }\n\n if (installedSkills.length > 0 && agents[0] !== \"none\") {\n const globalMode = isGlobalMode();\n console.log(\n `\\nCreating symlinks for agent(s): ${agents.join(\", \")}${globalMode ? \" (global)\" : \"\"}...`,\n );\n\n await createAgentSymlinks(installedSkills, {\n agents,\n projectRoot: globalMode ? homedir() : process.cwd(),\n agentConfigs,\n global: globalMode,\n });\n\n console.log(\" Symlinks created.\");\n }\n\n const totalCount = packageCount + githubCount;\n if (totalCount === 0) {\n console.log(\"No skills to install.\");\n } else {\n console.log(`\\nAll ${totalCount} skill(s) installed.`);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n console.error(`Error: ${message}`);\n process.exit(1);\n }\n}\n"],"mappings":"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"}