@anytio/pspm 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,33 +1,39 @@
1
1
  #!/usr/bin/env node
2
- import { readFileSync } from 'fs';
3
- import { dirname, join, basename, relative } from 'path';
4
- import { fileURLToPath, URL as URL$1 } from 'url';
5
- import { Command } from 'commander';
6
2
  import { createHash, randomBytes } from 'crypto';
7
3
  import * as semver from 'semver';
8
- import { stat, writeFile, readdir, mkdir, rm, rename, access as access$1, readFile, lstat, cp, unlink, readlink, symlink } from 'fs/promises';
4
+ import { stat, writeFile, readdir, mkdir, rm, rename, access as access$1, readFile, lstat, unlink, cp, readlink, symlink } from 'fs/promises';
9
5
  import { homedir } from 'os';
6
+ import { dirname, join, basename, relative } from 'path';
10
7
  import * as ini from 'ini';
11
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
12
  import { createInterface } from 'readline';
13
13
  import http from 'http';
14
14
  import open from 'open';
15
15
  import { exec as exec$1 } from 'child_process';
16
16
  import { promisify } from 'util';
17
17
 
18
+ var __defProp = Object.defineProperty;
19
+ var __getOwnPropNames = Object.getOwnPropertyNames;
20
+ var __esm = (fn, res) => function __init() {
21
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
22
+ };
23
+ var __export = (target, all) => {
24
+ for (var name in all)
25
+ __defProp(target, name, { get: all[name], enumerable: true });
26
+ };
18
27
  function calculateIntegrity(data) {
19
28
  const hash = createHash("sha256").update(data).digest("base64");
20
29
  return `sha256-${hash}`;
21
30
  }
31
+ var init_integrity = __esm({
32
+ "../../packages/shared/pspm-types/src/integrity.ts"() {
33
+ }
34
+ });
22
35
 
23
36
  // ../../packages/shared/pspm-types/src/manifest.ts
24
- var DEFAULT_SKILL_FILES = [
25
- "SKILL.md",
26
- "runtime",
27
- "scripts",
28
- "data"
29
- ];
30
- var PSPM_SCHEMA_URL = "https://pspm.dev/schema/v1/pspm.json";
31
37
  function validateManifest(manifest) {
32
38
  if (!manifest.name) {
33
39
  return { valid: false, error: "Manifest must have a 'name' field" };
@@ -49,9 +55,20 @@ function validateManifest(manifest) {
49
55
  }
50
56
  return { valid: true };
51
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
+ });
52
70
 
53
71
  // ../../packages/shared/pspm-types/src/specifier.ts
54
- var SPECIFIER_PATTERN = /^@user\/([a-zA-Z0-9_-]+)\/([a-z][a-z0-9_-]*)(?:@(.+))?$/;
55
72
  function parseSkillSpecifier(specifier) {
56
73
  const match = specifier.match(SPECIFIER_PATTERN);
57
74
  if (!match) {
@@ -63,7 +80,6 @@ function parseSkillSpecifier(specifier) {
63
80
  versionRange: match[3]
64
81
  };
65
82
  }
66
- var GITHUB_SPECIFIER_PATTERN = /^github:([a-zA-Z0-9_-]+)\/([a-zA-Z0-9_.-]+)(\/[^@]+)?(?:@(.+))?$/;
67
83
  function parseGitHubSpecifier(specifier) {
68
84
  const match = specifier.match(GITHUB_SPECIFIER_PATTERN);
69
85
  if (!match) {
@@ -98,6 +114,13 @@ function getGitHubSkillName(spec) {
98
114
  function isGitHubSpecifier(specifier) {
99
115
  return specifier.startsWith("github:");
100
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
+ });
101
124
  function resolveVersion(range, availableVersions) {
102
125
  const sorted = availableVersions.filter((v) => semver.valid(v)).sort((a, b) => semver.rcompare(a, b));
103
126
  if (!range || range === "latest" || range === "*") {
@@ -105,9 +128,22 @@ function resolveVersion(range, availableVersions) {
105
128
  }
106
129
  return semver.maxSatisfying(sorted, range);
107
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
+ });
108
145
 
109
146
  // ../../packages/sdk/src/fetchers/cli-fetcher.ts
110
- var config = null;
111
147
  function configure(options) {
112
148
  config = options;
113
149
  }
@@ -146,84 +182,104 @@ async function customFetch(url, options) {
146
182
  headers: response.headers
147
183
  };
148
184
  }
185
+ var config;
186
+ var init_cli_fetcher = __esm({
187
+ "../../packages/sdk/src/fetchers/cli-fetcher.ts"() {
188
+ config = null;
189
+ }
190
+ });
149
191
 
150
192
  // ../../packages/sdk/src/generated/fetch/index.ts
151
- var getMeUrl = () => {
152
- return `/api/skills/me`;
153
- };
154
- var me = async (options) => {
155
- return customFetch(
156
- getMeUrl(),
157
- {
158
- ...options,
159
- method: "GET"
160
- }
161
- );
162
- };
163
- var getListSkillVersionsUrl = (username, name) => {
164
- return `/api/skills/@user/${username}/${name}/versions`;
165
- };
166
- var listSkillVersions = async (username, name, options) => {
167
- return customFetch(
168
- getListSkillVersionsUrl(username, name),
169
- {
170
- ...options,
171
- method: "GET"
172
- }
173
- );
174
- };
175
- var getGetSkillVersionUrl = (username, name, version2) => {
176
- return `/api/skills/@user/${username}/${name}/${version2}`;
177
- };
178
- var getSkillVersion = async (username, name, version2, options) => {
179
- return customFetch(
180
- getGetSkillVersionUrl(username, name, version2),
181
- {
182
- ...options,
183
- method: "GET"
184
- }
185
- );
186
- };
187
- var getPublishSkillUrl = () => {
188
- return `/api/skills/publish`;
189
- };
190
- var publishSkill = async (publishSkillInput, options) => {
191
- return customFetch(
192
- getPublishSkillUrl(),
193
- {
194
- ...options,
195
- method: "POST",
196
- headers: { "Content-Type": "application/json", ...options?.headers },
197
- body: JSON.stringify(
198
- publishSkillInput
199
- )
200
- }
201
- );
202
- };
203
- var getDeleteSkillUrl = (name) => {
204
- return `/api/skills/${name}`;
205
- };
206
- var deleteSkill = async (name, options) => {
207
- return customFetch(
208
- getDeleteSkillUrl(name),
209
- {
210
- ...options,
211
- method: "DELETE"
212
- }
213
- );
214
- };
215
- var getDeleteSkillVersionUrl = (name, version2) => {
216
- return `/api/skills/${name}/${version2}`;
217
- };
218
- var deleteSkillVersion = async (name, version2, options) => {
219
- return customFetch(
220
- getDeleteSkillVersionUrl(name, version2),
221
- {
222
- ...options,
223
- method: "DELETE"
224
- }
225
- );
226
- };
193
+ var getMeUrl, me, getListSkillVersionsUrl, listSkillVersions, getGetSkillVersionUrl, getSkillVersion, getPublishSkillUrl, publishSkill, getDeleteSkillUrl, deleteSkill, getDeleteSkillVersionUrl, deleteSkillVersion;
194
+ var init_fetch = __esm({
195
+ "../../packages/sdk/src/generated/fetch/index.ts"() {
196
+ init_cli_fetcher();
197
+ getMeUrl = () => {
198
+ return `/api/skills/me`;
199
+ };
200
+ me = async (options) => {
201
+ return customFetch(
202
+ getMeUrl(),
203
+ {
204
+ ...options,
205
+ method: "GET"
206
+ }
207
+ );
208
+ };
209
+ getListSkillVersionsUrl = (username, name) => {
210
+ return `/api/skills/@user/${username}/${name}/versions`;
211
+ };
212
+ listSkillVersions = async (username, name, options) => {
213
+ return customFetch(
214
+ getListSkillVersionsUrl(username, name),
215
+ {
216
+ ...options,
217
+ method: "GET"
218
+ }
219
+ );
220
+ };
221
+ getGetSkillVersionUrl = (username, name, version2) => {
222
+ return `/api/skills/@user/${username}/${name}/${version2}`;
223
+ };
224
+ getSkillVersion = async (username, name, version2, options) => {
225
+ return customFetch(
226
+ getGetSkillVersionUrl(username, name, version2),
227
+ {
228
+ ...options,
229
+ method: "GET"
230
+ }
231
+ );
232
+ };
233
+ getPublishSkillUrl = () => {
234
+ return `/api/skills/publish`;
235
+ };
236
+ publishSkill = async (publishSkillInput, options) => {
237
+ return customFetch(
238
+ getPublishSkillUrl(),
239
+ {
240
+ ...options,
241
+ method: "POST",
242
+ headers: { "Content-Type": "application/json", ...options?.headers },
243
+ body: JSON.stringify(
244
+ publishSkillInput
245
+ )
246
+ }
247
+ );
248
+ };
249
+ getDeleteSkillUrl = (name) => {
250
+ return `/api/skills/${name}`;
251
+ };
252
+ deleteSkill = async (name, options) => {
253
+ return customFetch(
254
+ getDeleteSkillUrl(name),
255
+ {
256
+ ...options,
257
+ method: "DELETE"
258
+ }
259
+ );
260
+ };
261
+ getDeleteSkillVersionUrl = (name, version2) => {
262
+ return `/api/skills/${name}/${version2}`;
263
+ };
264
+ deleteSkillVersion = async (name, version2, options) => {
265
+ return customFetch(
266
+ getDeleteSkillVersionUrl(name, version2),
267
+ {
268
+ ...options,
269
+ method: "DELETE"
270
+ }
271
+ );
272
+ };
273
+ }
274
+ });
275
+
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
+ });
227
283
 
228
284
  // src/api-client.ts
229
285
  function registryUrlToBaseUrl(registryUrl) {
@@ -345,22 +401,13 @@ async function changeSkillAccess(skillName, input) {
345
401
  };
346
402
  }
347
403
  }
404
+ var init_api_client = __esm({
405
+ "src/api-client.ts"() {
406
+ init_src2();
407
+ }
408
+ });
348
409
 
349
410
  // src/errors.ts
350
- var ConfigError = class extends Error {
351
- constructor(message) {
352
- super(message);
353
- this.name = "ConfigError";
354
- }
355
- };
356
- var NotLoggedInError = class extends ConfigError {
357
- constructor() {
358
- super(
359
- "Not logged in. Run 'pspm login --api-key <key>' first, or set PSPM_API_KEY env var."
360
- );
361
- this.name = "NotLoggedInError";
362
- }
363
- };
364
411
  function extractApiErrorMessage(response, fallbackMessage) {
365
412
  const errorData = response.data;
366
413
  if (process.env.PSPM_DEBUG) {
@@ -395,9 +442,25 @@ ${issueMessages}`;
395
442
  }
396
443
  return errorMessage;
397
444
  }
398
-
399
- // src/config.ts
400
- var DEFAULT_REGISTRY_URL = "https://pspm.dev";
445
+ var ConfigError, NotLoggedInError;
446
+ var init_errors = __esm({
447
+ "src/errors.ts"() {
448
+ ConfigError = class extends Error {
449
+ constructor(message) {
450
+ super(message);
451
+ this.name = "ConfigError";
452
+ }
453
+ };
454
+ NotLoggedInError = class extends ConfigError {
455
+ constructor() {
456
+ super(
457
+ "Not logged in. Run 'pspm login --api-key <key>' first, or set PSPM_API_KEY env var."
458
+ );
459
+ this.name = "NotLoggedInError";
460
+ }
461
+ };
462
+ }
463
+ });
401
464
  function getConfigPath() {
402
465
  return join(homedir(), ".pspmrc");
403
466
  }
@@ -667,131 +730,13 @@ async function getRegistryUrl() {
667
730
  const resolved = await resolveConfig();
668
731
  return resolved.registryUrl;
669
732
  }
670
-
671
- // src/commands/access.ts
672
- async function access(specifier, options) {
673
- try {
674
- const apiKey = await requireApiKey();
675
- const registryUrl = await getRegistryUrl();
676
- if (options.public && options.private) {
677
- console.error("Error: Cannot specify both --public and --private");
678
- process.exit(1);
679
- }
680
- if (!options.public && !options.private) {
681
- console.error("Error: Must specify either --public or --private");
682
- process.exit(1);
683
- }
684
- const visibility = options.public ? "public" : "private";
685
- let packageName;
686
- if (specifier) {
687
- const parsed = parseSkillSpecifier(specifier);
688
- if (!parsed) {
689
- console.error(
690
- `Error: Invalid skill specifier "${specifier}". Use format: @user/{username}/{name}`
691
- );
692
- process.exit(1);
693
- }
694
- packageName = parsed.name;
695
- } else {
696
- const { readFile: readFile7 } = await import('fs/promises');
697
- const { join: join13 } = await import('path');
698
- let manifest = null;
699
- try {
700
- const content = await readFile7(
701
- join13(process.cwd(), "pspm.json"),
702
- "utf-8"
703
- );
704
- manifest = JSON.parse(content);
705
- } catch {
706
- try {
707
- const content = await readFile7(
708
- join13(process.cwd(), "package.json"),
709
- "utf-8"
710
- );
711
- manifest = JSON.parse(content);
712
- } catch {
713
- console.error(
714
- "Error: No pspm.json or package.json found in current directory"
715
- );
716
- console.error(
717
- "Either run this command in a package directory or specify a package name"
718
- );
719
- process.exit(1);
720
- }
721
- }
722
- if (!manifest?.name) {
723
- console.error("Error: Package manifest is missing 'name' field");
724
- process.exit(1);
725
- }
726
- packageName = manifest.name;
727
- }
728
- configure2({ registryUrl, apiKey });
729
- console.log(`Setting ${packageName} to ${visibility}...`);
730
- const response = await changeSkillAccess(packageName, { visibility });
731
- if (response.status !== 200 || !response.data) {
732
- const errorMessage = response.error ?? "Failed to change visibility";
733
- console.error(`Error: ${errorMessage}`);
734
- process.exit(1);
735
- }
736
- const result = response.data;
737
- console.log(
738
- `+ @user/${result.username}/${result.name} is now ${result.visibility}`
739
- );
740
- if (visibility === "public") {
741
- console.log("");
742
- console.log(
743
- "Note: This action is irreversible. Public packages cannot be made private."
744
- );
745
- }
746
- } catch (error) {
747
- const message = error instanceof Error ? error.message : "Unknown error";
748
- console.error(`Error: ${message}`);
749
- process.exit(1);
750
- }
751
- }
752
- var AGENT_INFO = {
753
- "claude-code": {
754
- displayName: "Claude Code",
755
- skillsDir: ".claude/skills"
756
- },
757
- codex: {
758
- displayName: "Codex",
759
- skillsDir: ".codex/skills"
760
- },
761
- cursor: {
762
- displayName: "Cursor",
763
- skillsDir: ".cursor/skills"
764
- },
765
- gemini: {
766
- displayName: "Gemini CLI",
767
- skillsDir: ".gemini/skills"
768
- },
769
- kiro: {
770
- displayName: "Kiro CLI",
771
- skillsDir: ".kiro/skills"
772
- },
773
- opencode: {
774
- displayName: "OpenCode",
775
- skillsDir: ".opencode/skills"
733
+ var DEFAULT_REGISTRY_URL;
734
+ var init_config = __esm({
735
+ "src/config.ts"() {
736
+ init_errors();
737
+ DEFAULT_REGISTRY_URL = "https://pspm.dev";
776
738
  }
777
- };
778
- var DEFAULT_AGENT_CONFIGS = {
779
- "claude-code": { skillsDir: AGENT_INFO["claude-code"].skillsDir },
780
- codex: { skillsDir: AGENT_INFO.codex.skillsDir },
781
- cursor: { skillsDir: AGENT_INFO.cursor.skillsDir },
782
- gemini: { skillsDir: AGENT_INFO.gemini.skillsDir },
783
- kiro: { skillsDir: AGENT_INFO.kiro.skillsDir },
784
- opencode: { skillsDir: AGENT_INFO.opencode.skillsDir }
785
- };
786
- var DEFAULT_AGENT = "claude-code";
787
- var ALL_AGENTS = [
788
- "claude-code",
789
- "codex",
790
- "cursor",
791
- "gemini",
792
- "kiro",
793
- "opencode"
794
- ];
739
+ });
795
740
  function resolveAgentConfig(name, overrides) {
796
741
  if (overrides?.[name]) {
797
742
  return overrides[name];
@@ -803,7 +748,7 @@ function resolveAgentConfig(name, overrides) {
803
748
  }
804
749
  function parseAgentArg(agentArg) {
805
750
  if (!agentArg) {
806
- return [DEFAULT_AGENT];
751
+ return [...DEFAULT_AGENTS];
807
752
  }
808
753
  if (agentArg === "none") {
809
754
  return ["none"];
@@ -831,35 +776,54 @@ async function promptForAgents() {
831
776
  }
832
777
  return selected;
833
778
  }
834
- var GitHubRateLimitError = class extends Error {
835
- constructor() {
836
- super(
837
- "GitHub API rate limit exceeded. Set GITHUB_TOKEN environment variable for higher limits."
838
- );
839
- this.name = "GitHubRateLimitError";
840
- }
841
- };
842
- var GitHubNotFoundError = class extends Error {
843
- constructor(spec) {
844
- const path = spec.path ? `/${spec.path}` : "";
845
- const ref = spec.ref ? `@${spec.ref}` : "";
846
- super(
847
- `GitHub repository not found: ${spec.owner}/${spec.repo}${path}${ref}`
848
- );
849
- this.name = "GitHubNotFoundError";
850
- }
851
- };
852
- var GitHubPathNotFoundError = class extends Error {
853
- constructor(spec, availablePaths) {
854
- const pathInfo = availablePaths?.length ? `
855
- Available paths in repository root:
856
- ${availablePaths.join("\n ")}` : "";
857
- super(
858
- `Path "${spec.path}" not found in ${spec.owner}/${spec.repo}${pathInfo}`
859
- );
860
- this.name = "GitHubPathNotFoundError";
779
+ var AGENT_INFO, DEFAULT_AGENT_CONFIGS, ALL_AGENTS, DEFAULT_AGENTS;
780
+ var init_agents = __esm({
781
+ "src/agents.ts"() {
782
+ AGENT_INFO = {
783
+ "claude-code": {
784
+ displayName: "Claude Code",
785
+ skillsDir: ".claude/skills"
786
+ },
787
+ codex: {
788
+ displayName: "Codex",
789
+ skillsDir: ".codex/skills"
790
+ },
791
+ cursor: {
792
+ displayName: "Cursor",
793
+ skillsDir: ".cursor/skills"
794
+ },
795
+ gemini: {
796
+ displayName: "Gemini CLI",
797
+ skillsDir: ".gemini/skills"
798
+ },
799
+ kiro: {
800
+ displayName: "Kiro CLI",
801
+ skillsDir: ".kiro/skills"
802
+ },
803
+ opencode: {
804
+ displayName: "OpenCode",
805
+ skillsDir: ".opencode/skills"
806
+ }
807
+ };
808
+ DEFAULT_AGENT_CONFIGS = {
809
+ "claude-code": { skillsDir: AGENT_INFO["claude-code"].skillsDir },
810
+ codex: { skillsDir: AGENT_INFO.codex.skillsDir },
811
+ cursor: { skillsDir: AGENT_INFO.cursor.skillsDir },
812
+ gemini: { skillsDir: AGENT_INFO.gemini.skillsDir },
813
+ kiro: { skillsDir: AGENT_INFO.kiro.skillsDir },
814
+ opencode: { skillsDir: AGENT_INFO.opencode.skillsDir }
815
+ };
816
+ ALL_AGENTS = [
817
+ "claude-code",
818
+ "codex",
819
+ "cursor",
820
+ "gemini",
821
+ "kiro",
822
+ "opencode"
823
+ ];
824
+ DEFAULT_AGENTS = ALL_AGENTS;
861
825
  }
862
- };
826
+ });
863
827
  function getGitHubHeaders() {
864
828
  const headers = {
865
829
  Accept: "application/vnd.github+json",
@@ -986,6 +950,41 @@ function getGitHubDisplayName(spec, commit) {
986
950
  }
987
951
  return name;
988
952
  }
953
+ var GitHubRateLimitError, GitHubNotFoundError, GitHubPathNotFoundError;
954
+ var init_github = __esm({
955
+ "src/github.ts"() {
956
+ init_src();
957
+ GitHubRateLimitError = class extends Error {
958
+ constructor() {
959
+ super(
960
+ "GitHub API rate limit exceeded. Set GITHUB_TOKEN environment variable for higher limits."
961
+ );
962
+ this.name = "GitHubRateLimitError";
963
+ }
964
+ };
965
+ GitHubNotFoundError = class extends Error {
966
+ constructor(spec) {
967
+ const path = spec.path ? `/${spec.path}` : "";
968
+ const ref = spec.ref ? `@${spec.ref}` : "";
969
+ super(
970
+ `GitHub repository not found: ${spec.owner}/${spec.repo}${path}${ref}`
971
+ );
972
+ this.name = "GitHubNotFoundError";
973
+ }
974
+ };
975
+ GitHubPathNotFoundError = class extends Error {
976
+ constructor(spec, availablePaths) {
977
+ const pathInfo = availablePaths?.length ? `
978
+ Available paths in repository root:
979
+ ${availablePaths.join("\n ")}` : "";
980
+ super(
981
+ `Path "${spec.path}" not found in ${spec.owner}/${spec.repo}${pathInfo}`
982
+ );
983
+ this.name = "GitHubPathNotFoundError";
984
+ }
985
+ };
986
+ }
987
+ });
989
988
  async function hasLegacyLockfile() {
990
989
  try {
991
990
  await stat(getLegacyLockfilePath());
@@ -1143,6 +1142,11 @@ async function listLockfileGitHubPackages() {
1143
1142
  entry
1144
1143
  }));
1145
1144
  }
1145
+ var init_lockfile = __esm({
1146
+ "src/lockfile.ts"() {
1147
+ init_config();
1148
+ }
1149
+ });
1146
1150
  function getManifestPath() {
1147
1151
  return join(process.cwd(), "pspm.json");
1148
1152
  }
@@ -1214,6 +1218,10 @@ async function removeGitHubDependency(specifier) {
1214
1218
  await writeManifest(manifest);
1215
1219
  return true;
1216
1220
  }
1221
+ var init_manifest2 = __esm({
1222
+ "src/manifest.ts"() {
1223
+ }
1224
+ });
1217
1225
  async function createAgentSymlinks(skills, options) {
1218
1226
  const { agents, projectRoot, agentConfigs } = options;
1219
1227
  if (agents.length === 1 && agents[0] === "none") {
@@ -1305,9 +1313,47 @@ async function getLinkedAgents(skillName, agents, projectRoot, agentConfigs) {
1305
1313
  }
1306
1314
  return linkedAgents;
1307
1315
  }
1316
+ var init_symlinks = __esm({
1317
+ "src/symlinks.ts"() {
1318
+ init_agents();
1319
+ }
1320
+ });
1308
1321
 
1309
1322
  // src/commands/add.ts
1310
- async function add(specifier, options) {
1323
+ var add_exports = {};
1324
+ __export(add_exports, {
1325
+ add: () => add
1326
+ });
1327
+ async function add(specifiers, options) {
1328
+ console.log("Resolving packages...\n");
1329
+ const resolvedPackages = [];
1330
+ const validationErrors = [];
1331
+ for (const specifier of specifiers) {
1332
+ try {
1333
+ if (isGitHubSpecifier(specifier)) {
1334
+ const resolved = await validateGitHubPackage(specifier);
1335
+ resolvedPackages.push(resolved);
1336
+ } else {
1337
+ const resolved = await validateRegistryPackage(specifier);
1338
+ resolvedPackages.push(resolved);
1339
+ }
1340
+ } catch (error) {
1341
+ const message = error instanceof Error ? error.message : "Unknown error";
1342
+ validationErrors.push({ specifier, error: message });
1343
+ console.error(`Failed to resolve ${specifier}: ${message}
1344
+ `);
1345
+ }
1346
+ }
1347
+ if (resolvedPackages.length === 0) {
1348
+ console.error("No packages could be resolved.");
1349
+ process.exit(1);
1350
+ }
1351
+ if (validationErrors.length > 0) {
1352
+ console.log(
1353
+ `Resolved ${resolvedPackages.length} of ${specifiers.length} packages.
1354
+ `
1355
+ );
1356
+ }
1311
1357
  let agents;
1312
1358
  const manifest = await readManifest();
1313
1359
  if (options.agent) {
@@ -1319,211 +1365,343 @@ async function add(specifier, options) {
1319
1365
  } else {
1320
1366
  console.log("No pspm.json found. Let's set up your project.\n");
1321
1367
  agents = await promptForAgents();
1368
+ console.log();
1322
1369
  }
1323
- if (isGitHubSpecifier(specifier)) {
1324
- await addGitHub(specifier, { ...options, resolvedAgents: agents });
1325
- } else {
1326
- await addRegistry(specifier, { ...options, resolvedAgents: agents });
1370
+ const results = [];
1371
+ for (const resolved of resolvedPackages) {
1372
+ try {
1373
+ if (resolved.type === "github") {
1374
+ await installGitHubPackage(resolved, {
1375
+ ...options,
1376
+ resolvedAgents: agents
1377
+ });
1378
+ } else {
1379
+ await installRegistryPackage(resolved, {
1380
+ ...options,
1381
+ resolvedAgents: agents
1382
+ });
1383
+ }
1384
+ results.push({ specifier: resolved.specifier, success: true });
1385
+ } catch (error) {
1386
+ const message = error instanceof Error ? error.message : "Unknown error";
1387
+ results.push({
1388
+ specifier: resolved.specifier,
1389
+ success: false,
1390
+ error: message
1391
+ });
1392
+ console.error(`Failed to install ${resolved.specifier}: ${message}
1393
+ `);
1394
+ }
1395
+ }
1396
+ if (specifiers.length > 1) {
1397
+ const succeeded = results.filter((r) => r.success).length;
1398
+ const failed = results.filter((r) => !r.success).length + validationErrors.length;
1399
+ console.log(`
1400
+ Summary: ${succeeded} added, ${failed} failed`);
1401
+ if (failed > 0) {
1402
+ process.exit(1);
1403
+ }
1327
1404
  }
1328
1405
  }
1329
- async function addRegistry(specifier, options) {
1330
- try {
1331
- const config2 = await resolveConfig();
1332
- const registryUrl = config2.registryUrl;
1333
- const apiKey = getTokenForRegistry(config2, registryUrl);
1334
- const parsed = parseSkillSpecifier(specifier);
1335
- if (!parsed) {
1336
- console.error(
1337
- `Error: Invalid skill specifier "${specifier}". Use format: @user/{username}/{name}[@{version}]`
1406
+ async function validateRegistryPackage(specifier) {
1407
+ const config2 = await resolveConfig();
1408
+ const registryUrl = config2.registryUrl;
1409
+ const apiKey = getTokenForRegistry(config2, registryUrl);
1410
+ const parsed = parseSkillSpecifier(specifier);
1411
+ if (!parsed) {
1412
+ throw new Error(
1413
+ `Invalid skill specifier "${specifier}". Use format: @user/{username}/{name}[@{version}]`
1414
+ );
1415
+ }
1416
+ const { username, name, versionRange } = parsed;
1417
+ configure2({ registryUrl, apiKey: apiKey ?? "" });
1418
+ console.log(`Resolving ${specifier}...`);
1419
+ const versionsResponse = await listSkillVersions(username, name);
1420
+ if (versionsResponse.status !== 200) {
1421
+ if (versionsResponse.status === 401) {
1422
+ if (!apiKey) {
1423
+ throw new Error(
1424
+ `Package @user/${username}/${name} requires authentication. Please run 'pspm login' to authenticate`
1425
+ );
1426
+ }
1427
+ throw new Error(
1428
+ `Access denied to @user/${username}/${name}. You may not have permission to access this private package.`
1338
1429
  );
1430
+ }
1431
+ const errorMessage = extractApiErrorMessage(
1432
+ versionsResponse,
1433
+ `Skill @user/${username}/${name} not found`
1434
+ );
1435
+ throw new Error(errorMessage);
1436
+ }
1437
+ const versions = versionsResponse.data;
1438
+ if (versions.length === 0) {
1439
+ throw new Error(`Skill @user/${username}/${name} not found`);
1440
+ }
1441
+ const versionStrings = versions.map((v) => v.version);
1442
+ const resolvedVersion = resolveVersion(versionRange || "*", versionStrings);
1443
+ if (!resolvedVersion) {
1444
+ throw new Error(
1445
+ `No version matching "${versionRange || "latest"}" found for @user/${username}/${name}. Available versions: ${versionStrings.join(", ")}`
1446
+ );
1447
+ }
1448
+ const versionResponse = await getSkillVersion(
1449
+ username,
1450
+ name,
1451
+ resolvedVersion
1452
+ );
1453
+ if (versionResponse.status !== 200 || !versionResponse.data) {
1454
+ const errorMessage = extractApiErrorMessage(
1455
+ versionResponse,
1456
+ `Version ${resolvedVersion} not found`
1457
+ );
1458
+ throw new Error(errorMessage);
1459
+ }
1460
+ console.log(`Resolved @user/${username}/${name}@${resolvedVersion}`);
1461
+ return {
1462
+ type: "registry",
1463
+ specifier,
1464
+ username,
1465
+ name,
1466
+ versionRange,
1467
+ resolvedVersion,
1468
+ versionInfo: {
1469
+ downloadUrl: versionResponse.data.downloadUrl,
1470
+ checksum: versionResponse.data.checksum
1471
+ }
1472
+ };
1473
+ }
1474
+ async function validateGitHubPackage(specifier) {
1475
+ const parsed = parseGitHubSpecifier(specifier);
1476
+ if (!parsed) {
1477
+ throw new Error(
1478
+ `Invalid GitHub specifier "${specifier}". Use format: github:{owner}/{repo}[/{path}][@{ref}]`
1479
+ );
1480
+ }
1481
+ const ref = parsed.ref || "HEAD";
1482
+ console.log(`Resolving ${getGitHubDisplayName(parsed)}...`);
1483
+ const result = await downloadGitHubPackage(parsed);
1484
+ console.log(`Resolved ${specifier} (${ref}@${result.commit.slice(0, 7)})`);
1485
+ return {
1486
+ type: "github",
1487
+ specifier,
1488
+ parsed,
1489
+ ref,
1490
+ downloadResult: result
1491
+ };
1492
+ }
1493
+ async function installRegistryPackage(resolved, options) {
1494
+ const { username, name, versionRange, resolvedVersion, versionInfo } = resolved;
1495
+ console.log(`Installing @user/${username}/${name}@${resolvedVersion}...`);
1496
+ const config2 = await resolveConfig();
1497
+ const apiKey = getTokenForRegistry(config2, config2.registryUrl);
1498
+ const isPresignedUrl = versionInfo.downloadUrl.includes(".r2.cloudflarestorage.com") || versionInfo.downloadUrl.includes("X-Amz-Signature");
1499
+ const downloadHeaders = {};
1500
+ if (!isPresignedUrl && apiKey) {
1501
+ downloadHeaders.Authorization = `Bearer ${apiKey}`;
1502
+ }
1503
+ const tarballResponse = await fetch(versionInfo.downloadUrl, {
1504
+ headers: downloadHeaders,
1505
+ redirect: "follow"
1506
+ });
1507
+ if (!tarballResponse.ok) {
1508
+ throw new Error(`Failed to download tarball (${tarballResponse.status})`);
1509
+ }
1510
+ const tarballBuffer = Buffer.from(await tarballResponse.arrayBuffer());
1511
+ const integrity = calculateIntegrity(tarballBuffer);
1512
+ const expectedIntegrity = `sha256-${Buffer.from(versionInfo.checksum, "hex").toString("base64")}`;
1513
+ if (integrity !== expectedIntegrity) {
1514
+ throw new Error("Checksum verification failed");
1515
+ }
1516
+ const skillsDir = getSkillsDir();
1517
+ const destDir = join(skillsDir, username, name);
1518
+ await mkdir(destDir, { recursive: true });
1519
+ const { writeFile: writeFile8 } = await import('fs/promises');
1520
+ const tempFile = join(destDir, ".temp.tgz");
1521
+ await writeFile8(tempFile, tarballBuffer);
1522
+ const { exec: exec2 } = await import('child_process');
1523
+ const { promisify: promisify2 } = await import('util');
1524
+ const execAsync = promisify2(exec2);
1525
+ try {
1526
+ await rm(destDir, { recursive: true, force: true });
1527
+ await mkdir(destDir, { recursive: true });
1528
+ await writeFile8(tempFile, tarballBuffer);
1529
+ await execAsync(
1530
+ `tar -xzf "${tempFile}" -C "${destDir}" --strip-components=1`
1531
+ );
1532
+ } finally {
1533
+ await rm(tempFile, { force: true });
1534
+ }
1535
+ const fullName = `@user/${username}/${name}`;
1536
+ await addToLockfile(fullName, {
1537
+ version: resolvedVersion,
1538
+ resolved: versionInfo.downloadUrl,
1539
+ integrity
1540
+ });
1541
+ const dependencyRange = versionRange || `^${resolvedVersion}`;
1542
+ await addDependency(fullName, dependencyRange);
1543
+ const agents = options.resolvedAgents;
1544
+ if (agents[0] !== "none") {
1545
+ const skillManifest = await readManifest();
1546
+ const skillInfo = {
1547
+ name,
1548
+ sourcePath: getRegistrySkillPath(username, name)
1549
+ };
1550
+ await createAgentSymlinks([skillInfo], {
1551
+ agents,
1552
+ projectRoot: process.cwd(),
1553
+ agentConfigs: skillManifest?.agents
1554
+ });
1555
+ }
1556
+ console.log(`Installed @user/${username}/${name}@${resolvedVersion}`);
1557
+ console.log(`Location: ${destDir}`);
1558
+ }
1559
+ async function installGitHubPackage(resolved, options) {
1560
+ const { specifier, parsed, ref, downloadResult } = resolved;
1561
+ console.log(
1562
+ `Installing ${specifier} (${ref}@${downloadResult.commit.slice(0, 7)})...`
1563
+ );
1564
+ const skillsDir = getSkillsDir();
1565
+ const destPath = await extractGitHubPackage(
1566
+ parsed,
1567
+ downloadResult.buffer,
1568
+ skillsDir
1569
+ );
1570
+ const lockfileSpecifier = formatGitHubSpecifier({
1571
+ owner: parsed.owner,
1572
+ repo: parsed.repo,
1573
+ path: parsed.path
1574
+ // Don't include ref in the specifier key, it's stored in gitRef
1575
+ });
1576
+ const entry = {
1577
+ version: downloadResult.commit.slice(0, 7),
1578
+ resolved: `https://github.com/${parsed.owner}/${parsed.repo}`,
1579
+ integrity: downloadResult.integrity,
1580
+ gitCommit: downloadResult.commit,
1581
+ gitRef: ref
1582
+ };
1583
+ await addGitHubToLockfile(lockfileSpecifier, entry);
1584
+ await addGitHubDependency(lockfileSpecifier, ref);
1585
+ const agents = options.resolvedAgents;
1586
+ if (agents[0] !== "none") {
1587
+ const manifest = await readManifest();
1588
+ const skillName = getGitHubSkillName(parsed);
1589
+ const skillInfo = {
1590
+ name: skillName,
1591
+ sourcePath: getGitHubSkillPath(parsed.owner, parsed.repo, parsed.path)
1592
+ };
1593
+ await createAgentSymlinks([skillInfo], {
1594
+ agents,
1595
+ projectRoot: process.cwd(),
1596
+ agentConfigs: manifest?.agents
1597
+ });
1598
+ }
1599
+ console.log(
1600
+ `Installed ${specifier} (${ref}@${downloadResult.commit.slice(0, 7)})`
1601
+ );
1602
+ console.log(`Location: ${destPath}`);
1603
+ }
1604
+ var init_add = __esm({
1605
+ "src/commands/add.ts"() {
1606
+ init_src();
1607
+ init_agents();
1608
+ init_api_client();
1609
+ init_config();
1610
+ init_errors();
1611
+ init_github();
1612
+ init_lockfile();
1613
+ init_manifest2();
1614
+ init_symlinks();
1615
+ }
1616
+ });
1617
+
1618
+ // src/commands/access.ts
1619
+ init_src();
1620
+ init_api_client();
1621
+ init_config();
1622
+ async function access(specifier, options) {
1623
+ try {
1624
+ const apiKey = await requireApiKey();
1625
+ const registryUrl = await getRegistryUrl();
1626
+ if (options.public && options.private) {
1627
+ console.error("Error: Cannot specify both --public and --private");
1339
1628
  process.exit(1);
1340
1629
  }
1341
- const { username, name, versionRange } = parsed;
1342
- configure2({ registryUrl, apiKey: apiKey ?? "" });
1343
- console.log(`Resolving ${specifier}...`);
1344
- const versionsResponse = await listSkillVersions(username, name);
1345
- if (versionsResponse.status !== 200) {
1346
- if (versionsResponse.status === 401) {
1347
- if (!apiKey) {
1630
+ if (!options.public && !options.private) {
1631
+ console.error("Error: Must specify either --public or --private");
1632
+ process.exit(1);
1633
+ }
1634
+ const visibility = options.public ? "public" : "private";
1635
+ let packageName;
1636
+ if (specifier) {
1637
+ const parsed = parseSkillSpecifier(specifier);
1638
+ if (!parsed) {
1639
+ console.error(
1640
+ `Error: Invalid skill specifier "${specifier}". Use format: @user/{username}/{name}`
1641
+ );
1642
+ process.exit(1);
1643
+ }
1644
+ packageName = parsed.name;
1645
+ } else {
1646
+ const { readFile: readFile7 } = await import('fs/promises');
1647
+ const { join: join13 } = await import('path');
1648
+ let manifest = null;
1649
+ try {
1650
+ const content = await readFile7(
1651
+ join13(process.cwd(), "pspm.json"),
1652
+ "utf-8"
1653
+ );
1654
+ manifest = JSON.parse(content);
1655
+ } catch {
1656
+ try {
1657
+ const content = await readFile7(
1658
+ join13(process.cwd(), "package.json"),
1659
+ "utf-8"
1660
+ );
1661
+ manifest = JSON.parse(content);
1662
+ } catch {
1348
1663
  console.error(
1349
- `Error: Package @user/${username}/${name} requires authentication`
1664
+ "Error: No pspm.json or package.json found in current directory"
1350
1665
  );
1351
- console.error("Please run 'pspm login' to authenticate");
1352
- } else {
1353
1666
  console.error(
1354
- `Error: Access denied to @user/${username}/${name}. You may not have permission to access this private package.`
1667
+ "Either run this command in a package directory or specify a package name"
1355
1668
  );
1669
+ process.exit(1);
1356
1670
  }
1671
+ }
1672
+ if (!manifest?.name) {
1673
+ console.error("Error: Package manifest is missing 'name' field");
1357
1674
  process.exit(1);
1358
1675
  }
1359
- const errorMessage = extractApiErrorMessage(
1360
- versionsResponse,
1361
- `Skill @user/${username}/${name} not found`
1362
- );
1363
- console.error(`Error: ${errorMessage}`);
1364
- process.exit(1);
1365
- }
1366
- const versions = versionsResponse.data;
1367
- if (versions.length === 0) {
1368
- console.error(`Error: Skill @user/${username}/${name} not found`);
1369
- process.exit(1);
1370
- }
1371
- const versionStrings = versions.map((v) => v.version);
1372
- const resolved = resolveVersion(versionRange || "*", versionStrings);
1373
- if (!resolved) {
1374
- console.error(
1375
- `Error: No version matching "${versionRange || "latest"}" found for @user/${username}/${name}`
1376
- );
1377
- console.error(`Available versions: ${versionStrings.join(", ")}`);
1378
- process.exit(1);
1676
+ packageName = manifest.name;
1379
1677
  }
1380
- console.log(`Installing @user/${username}/${name}@${resolved}...`);
1381
- const versionResponse = await getSkillVersion(username, name, resolved);
1382
- if (versionResponse.status !== 200 || !versionResponse.data) {
1383
- const errorMessage = extractApiErrorMessage(
1384
- versionResponse,
1385
- `Version ${resolved} not found`
1386
- );
1678
+ configure2({ registryUrl, apiKey });
1679
+ console.log(`Setting ${packageName} to ${visibility}...`);
1680
+ const response = await changeSkillAccess(packageName, { visibility });
1681
+ if (response.status !== 200 || !response.data) {
1682
+ const errorMessage = response.error ?? "Failed to change visibility";
1387
1683
  console.error(`Error: ${errorMessage}`);
1388
1684
  process.exit(1);
1389
1685
  }
1390
- const versionInfo = versionResponse.data;
1391
- const isPresignedUrl = versionInfo.downloadUrl.includes(".r2.cloudflarestorage.com") || versionInfo.downloadUrl.includes("X-Amz-Signature");
1392
- const downloadHeaders = {};
1393
- if (!isPresignedUrl && apiKey) {
1394
- downloadHeaders.Authorization = `Bearer ${apiKey}`;
1395
- }
1396
- const tarballResponse = await fetch(versionInfo.downloadUrl, {
1397
- headers: downloadHeaders,
1398
- redirect: "follow"
1399
- });
1400
- if (!tarballResponse.ok) {
1401
- console.error(
1402
- `Error: Failed to download tarball (${tarballResponse.status})`
1403
- );
1404
- process.exit(1);
1405
- }
1406
- const tarballBuffer = Buffer.from(await tarballResponse.arrayBuffer());
1407
- const integrity = calculateIntegrity(tarballBuffer);
1408
- const expectedIntegrity = `sha256-${Buffer.from(versionInfo.checksum, "hex").toString("base64")}`;
1409
- if (integrity !== expectedIntegrity) {
1410
- console.error("Error: Checksum verification failed");
1411
- process.exit(1);
1412
- }
1413
- const skillsDir = getSkillsDir();
1414
- const destDir = join(skillsDir, username, name);
1415
- await mkdir(destDir, { recursive: true });
1416
- const { writeFile: writeFile8 } = await import('fs/promises');
1417
- const tempFile = join(destDir, ".temp.tgz");
1418
- await writeFile8(tempFile, tarballBuffer);
1419
- const { exec: exec2 } = await import('child_process');
1420
- const { promisify: promisify2 } = await import('util');
1421
- const execAsync = promisify2(exec2);
1422
- try {
1423
- await rm(destDir, { recursive: true, force: true });
1424
- await mkdir(destDir, { recursive: true });
1425
- await writeFile8(tempFile, tarballBuffer);
1426
- await execAsync(
1427
- `tar -xzf "${tempFile}" -C "${destDir}" --strip-components=1`
1686
+ const result = response.data;
1687
+ console.log(
1688
+ `+ @user/${result.username}/${result.name} is now ${result.visibility}`
1689
+ );
1690
+ if (visibility === "public") {
1691
+ console.log("");
1692
+ console.log(
1693
+ "Note: This action is irreversible. Public packages cannot be made private."
1428
1694
  );
1429
- } finally {
1430
- await rm(tempFile, { force: true });
1431
- }
1432
- const fullName = `@user/${username}/${name}`;
1433
- await addToLockfile(fullName, {
1434
- version: resolved,
1435
- resolved: versionInfo.downloadUrl,
1436
- integrity
1437
- });
1438
- const dependencyRange = versionRange || `^${resolved}`;
1439
- await addDependency(fullName, dependencyRange);
1440
- const agents = options.resolvedAgents;
1441
- if (agents[0] !== "none") {
1442
- const skillManifest = await readManifest();
1443
- const skillInfo = {
1444
- name,
1445
- sourcePath: getRegistrySkillPath(username, name)
1446
- };
1447
- await createAgentSymlinks([skillInfo], {
1448
- agents,
1449
- projectRoot: process.cwd(),
1450
- agentConfigs: skillManifest?.agents
1451
- });
1452
1695
  }
1453
- console.log(`Installed @user/${username}/${name}@${resolved}`);
1454
- console.log(`Location: ${destDir}`);
1455
1696
  } catch (error) {
1456
1697
  const message = error instanceof Error ? error.message : "Unknown error";
1457
1698
  console.error(`Error: ${message}`);
1458
1699
  process.exit(1);
1459
1700
  }
1460
1701
  }
1461
- async function addGitHub(specifier, options) {
1462
- try {
1463
- const parsed = parseGitHubSpecifier(specifier);
1464
- if (!parsed) {
1465
- console.error(
1466
- `Error: Invalid GitHub specifier "${specifier}". Use format: github:{owner}/{repo}[/{path}][@{ref}]`
1467
- );
1468
- process.exit(1);
1469
- }
1470
- const ref = parsed.ref || "HEAD";
1471
- console.log(`Resolving ${getGitHubDisplayName(parsed)}...`);
1472
- const result = await downloadGitHubPackage(parsed);
1473
- console.log(
1474
- `Installing ${specifier} (${ref}@${result.commit.slice(0, 7)})...`
1475
- );
1476
- const skillsDir = getSkillsDir();
1477
- const destPath = await extractGitHubPackage(
1478
- parsed,
1479
- result.buffer,
1480
- skillsDir
1481
- );
1482
- const lockfileSpecifier = formatGitHubSpecifier({
1483
- owner: parsed.owner,
1484
- repo: parsed.repo,
1485
- path: parsed.path
1486
- // Don't include ref in the specifier key, it's stored in gitRef
1487
- });
1488
- const entry = {
1489
- version: result.commit.slice(0, 7),
1490
- resolved: `https://github.com/${parsed.owner}/${parsed.repo}`,
1491
- integrity: result.integrity,
1492
- gitCommit: result.commit,
1493
- gitRef: ref
1494
- };
1495
- await addGitHubToLockfile(lockfileSpecifier, entry);
1496
- await addGitHubDependency(lockfileSpecifier, ref);
1497
- const agents = options.resolvedAgents;
1498
- if (agents[0] !== "none") {
1499
- const manifest = await readManifest();
1500
- const skillName = getGitHubSkillName(parsed);
1501
- const skillInfo = {
1502
- name: skillName,
1503
- sourcePath: getGitHubSkillPath(parsed.owner, parsed.repo, parsed.path)
1504
- };
1505
- await createAgentSymlinks([skillInfo], {
1506
- agents,
1507
- projectRoot: process.cwd(),
1508
- agentConfigs: manifest?.agents
1509
- });
1510
- }
1511
- console.log(`Installed ${specifier} (${ref}@${result.commit.slice(0, 7)})`);
1512
- console.log(`Location: ${destPath}`);
1513
- } catch (error) {
1514
- if (error instanceof GitHubRateLimitError) {
1515
- console.error(`Error: ${error.message}`);
1516
- } else if (error instanceof GitHubPathNotFoundError) {
1517
- console.error(`Error: ${error.message}`);
1518
- } else if (error instanceof GitHubNotFoundError) {
1519
- console.error(`Error: ${error.message}`);
1520
- } else {
1521
- const message = error instanceof Error ? error.message : "Unknown error";
1522
- console.error(`Error: ${message}`);
1523
- }
1524
- process.exit(1);
1525
- }
1526
- }
1702
+
1703
+ // src/commands/index.ts
1704
+ init_add();
1527
1705
  async function configInit(options) {
1528
1706
  try {
1529
1707
  const configPath = join(process.cwd(), ".pspmrc");
@@ -1556,6 +1734,7 @@ async function configInit(options) {
1556
1734
  }
1557
1735
 
1558
1736
  // src/commands/config/show.ts
1737
+ init_config();
1559
1738
  async function configShow() {
1560
1739
  try {
1561
1740
  const resolved = await resolveConfig();
@@ -1585,6 +1764,9 @@ async function configShow() {
1585
1764
  }
1586
1765
 
1587
1766
  // src/commands/deprecate.ts
1767
+ init_src();
1768
+ init_api_client();
1769
+ init_config();
1588
1770
  async function deprecate(specifier, message, options) {
1589
1771
  try {
1590
1772
  const apiKey = await requireApiKey();
@@ -1647,6 +1829,9 @@ async function deprecate(specifier, message, options) {
1647
1829
  process.exit(1);
1648
1830
  }
1649
1831
  }
1832
+
1833
+ // src/commands/init.ts
1834
+ init_src();
1650
1835
  function prompt(rl, question, defaultValue) {
1651
1836
  return new Promise((resolve) => {
1652
1837
  const displayDefault = defaultValue ? ` (${defaultValue})` : "";
@@ -1862,6 +2047,17 @@ async function init(options) {
1862
2047
  process.exit(1);
1863
2048
  }
1864
2049
  }
2050
+
2051
+ // src/commands/install.ts
2052
+ init_src();
2053
+ init_agents();
2054
+ init_api_client();
2055
+ init_config();
2056
+ init_errors();
2057
+ init_github();
2058
+ init_lockfile();
2059
+ init_manifest2();
2060
+ init_symlinks();
1865
2061
  function getCacheFilePath(cacheDir, integrity) {
1866
2062
  const match = integrity.match(/^sha256-(.+)$/);
1867
2063
  if (!match) {
@@ -1893,26 +2089,25 @@ async function writeToCache(cacheDir, integrity, data) {
1893
2089
  } catch {
1894
2090
  }
1895
2091
  }
1896
- async function install(options) {
2092
+ async function install(specifiers, options) {
2093
+ if (specifiers.length > 0) {
2094
+ const { add: add2 } = await Promise.resolve().then(() => (init_add(), add_exports));
2095
+ await add2(specifiers, {
2096
+ save: true,
2097
+ agent: options.agent,
2098
+ yes: options.yes
2099
+ });
2100
+ return;
2101
+ }
2102
+ await installFromLockfile(options);
2103
+ }
2104
+ async function installFromLockfile(options) {
1897
2105
  try {
1898
2106
  const config2 = await resolveConfig();
1899
2107
  const registryUrl = config2.registryUrl;
1900
2108
  const apiKey = getTokenForRegistry(config2, registryUrl);
1901
2109
  const skillsDir = options.dir || getSkillsDir();
1902
2110
  const cacheDir = getCacheDir();
1903
- const manifest = await readManifest();
1904
- const agentConfigs = manifest?.agents;
1905
- let agents;
1906
- if (options.agent) {
1907
- agents = parseAgentArg(options.agent);
1908
- } else if (manifest) {
1909
- agents = parseAgentArg(void 0);
1910
- } else if (options.yes) {
1911
- agents = parseAgentArg(void 0);
1912
- } else {
1913
- console.log("No pspm.json found. Let's set up your project.\n");
1914
- agents = await promptForAgents();
1915
- }
1916
2111
  await migrateLockfileIfNeeded();
1917
2112
  let lockfile = await readLockfile();
1918
2113
  const manifestDeps = await getDependencies();
@@ -2069,6 +2264,20 @@ Resolving ${missingGitHubDeps.length} GitHub dependency(ies)...
2069
2264
  }
2070
2265
  lockfile = await readLockfile();
2071
2266
  }
2267
+ const manifest = await readManifest();
2268
+ const agentConfigs = manifest?.agents;
2269
+ let agents;
2270
+ if (options.agent) {
2271
+ agents = parseAgentArg(options.agent);
2272
+ } else if (manifest) {
2273
+ agents = parseAgentArg(void 0);
2274
+ } else if (options.yes) {
2275
+ agents = parseAgentArg(void 0);
2276
+ } else {
2277
+ console.log("\nNo pspm.json found. Let's set up your project.\n");
2278
+ agents = await promptForAgents();
2279
+ console.log();
2280
+ }
2072
2281
  const packages = lockfile?.packages ?? lockfile?.skills ?? {};
2073
2282
  const packageCount = Object.keys(packages).length;
2074
2283
  if (packageCount > 0) {
@@ -2257,6 +2466,11 @@ All ${totalCount} skill(s) installed.`);
2257
2466
  }
2258
2467
 
2259
2468
  // src/commands/link.ts
2469
+ init_src();
2470
+ init_agents();
2471
+ init_lockfile();
2472
+ init_manifest2();
2473
+ init_symlinks();
2260
2474
  async function link(options) {
2261
2475
  try {
2262
2476
  const manifest = await readManifest();
@@ -2327,6 +2541,13 @@ async function link(options) {
2327
2541
  process.exit(1);
2328
2542
  }
2329
2543
  }
2544
+
2545
+ // src/commands/list.ts
2546
+ init_src();
2547
+ init_agents();
2548
+ init_lockfile();
2549
+ init_manifest2();
2550
+ init_symlinks();
2330
2551
  async function list(options) {
2331
2552
  try {
2332
2553
  const registrySkills = await listLockfileSkills();
@@ -2440,6 +2661,10 @@ Total: ${skills.length} skill(s) (${parts.join(", ")})`);
2440
2661
  process.exit(1);
2441
2662
  }
2442
2663
  }
2664
+
2665
+ // src/commands/login.ts
2666
+ init_api_client();
2667
+ init_config();
2443
2668
  var DEFAULT_WEB_APP_URL = "https://pspm.dev";
2444
2669
  function getWebAppUrl(registryUrl) {
2445
2670
  if (process.env.PSPM_WEB_URL) {
@@ -2617,6 +2842,7 @@ async function login(options) {
2617
2842
  }
2618
2843
 
2619
2844
  // src/commands/logout.ts
2845
+ init_config();
2620
2846
  async function logout() {
2621
2847
  try {
2622
2848
  const loggedIn = await isLoggedIn();
@@ -2632,6 +2858,10 @@ async function logout() {
2632
2858
  process.exit(1);
2633
2859
  }
2634
2860
  }
2861
+
2862
+ // src/commands/migrate.ts
2863
+ init_config();
2864
+ init_lockfile();
2635
2865
  async function migrate(options) {
2636
2866
  try {
2637
2867
  const legacySkillsDir = getLegacySkillsDir();
@@ -2731,6 +2961,12 @@ async function migrate(options) {
2731
2961
  process.exit(1);
2732
2962
  }
2733
2963
  }
2964
+
2965
+ // src/commands/publish.ts
2966
+ init_src();
2967
+ init_api_client();
2968
+ init_config();
2969
+ init_errors();
2734
2970
  var exec = promisify(exec$1);
2735
2971
  async function detectManifest() {
2736
2972
  const cwd = process.cwd();
@@ -2936,6 +3172,14 @@ Setting visibility to ${options.access}...`);
2936
3172
  process.exit(1);
2937
3173
  }
2938
3174
  }
3175
+
3176
+ // src/commands/remove.ts
3177
+ init_src();
3178
+ init_agents();
3179
+ init_config();
3180
+ init_lockfile();
3181
+ init_manifest2();
3182
+ init_symlinks();
2939
3183
  async function remove(nameOrSpecifier) {
2940
3184
  try {
2941
3185
  const manifest = await readManifest();
@@ -3037,6 +3281,10 @@ async function removeByShortName(shortName, agents, agentConfigs) {
3037
3281
  }
3038
3282
 
3039
3283
  // src/commands/unpublish.ts
3284
+ init_src();
3285
+ init_api_client();
3286
+ init_config();
3287
+ init_errors();
3040
3288
  async function unpublish(specifier, options) {
3041
3289
  try {
3042
3290
  const apiKey = await requireApiKey();
@@ -3095,6 +3343,12 @@ async function unpublish(specifier, options) {
3095
3343
  }
3096
3344
 
3097
3345
  // src/commands/update.ts
3346
+ init_src();
3347
+ init_api_client();
3348
+ init_config();
3349
+ init_errors();
3350
+ init_lockfile();
3351
+ init_add();
3098
3352
  async function update(options) {
3099
3353
  try {
3100
3354
  const apiKey = await requireApiKey();
@@ -3156,7 +3410,7 @@ async function update(options) {
3156
3410
  if (!match) continue;
3157
3411
  const [, username, skillName] = match;
3158
3412
  const specifier = `@user/${username}/${skillName}@${latest}`;
3159
- await add(specifier, {});
3413
+ await add([specifier], {});
3160
3414
  }
3161
3415
  console.log("\nAll skills updated.");
3162
3416
  } catch (error) {
@@ -3167,6 +3421,8 @@ async function update(options) {
3167
3421
  }
3168
3422
 
3169
3423
  // src/commands/whoami.ts
3424
+ init_api_client();
3425
+ init_config();
3170
3426
  async function whoami() {
3171
3427
  try {
3172
3428
  const resolved = await resolveConfig();
@@ -3234,13 +3490,13 @@ program.command("migrate").description(
3234
3490
  ).option("--dry-run", "Show what would be migrated without making changes").action(async (options) => {
3235
3491
  await migrate({ dryRun: options.dryRun });
3236
3492
  });
3237
- program.command("add <specifier>").description(
3238
- "Add a skill (e.g., @user/bsheng/vite_slides@^2.0.0 or github:owner/repo/path@ref)"
3493
+ program.command("add <specifiers...>").description(
3494
+ "Add one or more skills (e.g., @user/bsheng/vite_slides@^2.0.0 or github:owner/repo/path@ref)"
3239
3495
  ).option("--save", "Save to lockfile (default)").option(
3240
3496
  "--agent <agents>",
3241
- 'Comma-separated agents for symlinks (default: "claude-code", use "none" to skip)'
3242
- ).option("-y, --yes", "Skip agent selection prompt and use defaults").action(async (specifier, options) => {
3243
- await add(specifier, {
3497
+ 'Comma-separated agents for symlinks (default: all agents, use "none" to skip)'
3498
+ ).option("-y, --yes", "Skip agent selection prompt and use defaults").action(async (specifiers, options) => {
3499
+ await add(specifiers, {
3244
3500
  save: options.save ?? true,
3245
3501
  agent: options.agent,
3246
3502
  yes: options.yes
@@ -3252,11 +3508,13 @@ program.command("remove <name>").alias("rm").description("Remove an installed sk
3252
3508
  program.command("list").alias("ls").description("List installed skills").option("--json", "Output as JSON").action(async (options) => {
3253
3509
  await list({ json: options.json });
3254
3510
  });
3255
- program.command("install").alias("i").description("Install all skills from lockfile").option("--frozen-lockfile", "Fail if lockfile is missing or outdated").option("--dir <path>", "Install skills to a specific directory").option(
3511
+ program.command("install [specifiers...]").alias("i").description(
3512
+ "Install skills from lockfile, or add and install specific packages"
3513
+ ).option("--frozen-lockfile", "Fail if lockfile is missing or outdated").option("--dir <path>", "Install skills to a specific directory").option(
3256
3514
  "--agent <agents>",
3257
- 'Comma-separated agents for symlinks (default: "claude-code", use "none" to skip)'
3258
- ).option("-y, --yes", "Skip agent selection prompt and use defaults").action(async (options) => {
3259
- await install({
3515
+ 'Comma-separated agents for symlinks (default: all agents, use "none" to skip)'
3516
+ ).option("-y, --yes", "Skip agent selection prompt and use defaults").action(async (specifiers, options) => {
3517
+ await install(specifiers, {
3260
3518
  frozenLockfile: options.frozenLockfile,
3261
3519
  dir: options.dir,
3262
3520
  agent: options.agent,
@@ -3265,7 +3523,7 @@ program.command("install").alias("i").description("Install all skills from lockf
3265
3523
  });
3266
3524
  program.command("link").description("Recreate agent symlinks without reinstalling").option(
3267
3525
  "--agent <agents>",
3268
- 'Comma-separated agents for symlinks (default: "claude-code", use "none" to skip)'
3526
+ 'Comma-separated agents for symlinks (default: all agents, use "none" to skip)'
3269
3527
  ).option("-y, --yes", "Skip agent selection prompt and use defaults").action(async (options) => {
3270
3528
  await link({ agent: options.agent, yes: options.yes });
3271
3529
  });