@anytio/pspm 0.4.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,43 @@ All notable changes to the PSPM CLI will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.6.0] - 2026-02-17
9
+
10
+ ### Changed
11
+
12
+ - **Auth-free read operations**: API key is no longer required for non-write operations (`add`, `install`, `update`, `list`, `link`). Only `publish`, `unpublish`, `deprecate`, `access`, and `whoami` now require authentication.
13
+ - Made `apiKey` parameter optional in SDK configuration, eliminating `apiKey ?? ""` workaround patterns
14
+
15
+ ### Fixed
16
+
17
+ - `update` command no longer blocks users without a PSPM API key when they only have GitHub or public packages installed
18
+
19
+ ## [0.5.1] - 2026-02-10
20
+
21
+ ### Changed
22
+
23
+ - Updated skill download endpoint to use OpenAPI route for improved type safety and consistency
24
+
25
+ ## [0.5.0] - 2026-02-10
26
+
27
+ ### Added
28
+
29
+ - **Public skill exploration**: New `/-/explore` endpoint support for browsing public skills without authentication, with search, sorting (downloads/recent/name), and pagination
30
+ - **SKILL.md publish requirement**: CLI now validates that `SKILL.md` exists before publishing, with clear guidance to create one
31
+ - **API key permissions**: SDK types now support granular API key permissions (`read`, `write`, `delete`)
32
+ - **Skill detail with documentation**: Get skill endpoint now returns `skillMd` content from the latest published version
33
+
34
+ ### Changed
35
+
36
+ - **Route structure redesign**: All API routes restructured with `/@user/{username}/` prefix for resource routes and `/-/` prefix for action routes (publish, mine, me, explore)
37
+ - **Username required in operations**: Deprecate, undeprecate, access, delete, and unpublish commands now pass username explicitly in API calls
38
+ - **Reduced tarball max size**: Publish size limit tightened in SDK schema validation
39
+ - **Updated all dependencies**: Bumped all outdated packages including Orval 8.0.3 → 8.2.0
40
+
41
+ ### Fixed
42
+
43
+ - **Username resolution in access command**: Properly resolves username from specifier or config with helpful error messages
44
+
8
45
  ## [0.4.1] - 2026-02-09
9
46
 
10
47
  ### Changed
package/dist/index.js CHANGED
@@ -74,12 +74,12 @@ var init_fetcher = __esm({
74
74
  });
75
75
 
76
76
  // src/sdk/generated/index.ts
77
- var getMeUrl, me, getListSkillVersionsUrl, listSkillVersions, getGetSkillVersionUrl, getSkillVersion, getPublishSkillUrl, publishSkill, getDeleteSkillUrl, deleteSkill, getDeleteSkillVersionUrl, deleteSkillVersion;
77
+ var getMeUrl, me, getDeleteSkillUrl, deleteSkill, getListSkillVersionsUrl, listSkillVersions, getGetSkillVersionUrl, getSkillVersion, getDeleteSkillVersionUrl, deleteSkillVersion, getPublishSkillUrl, publishSkill;
78
78
  var init_generated = __esm({
79
79
  "src/sdk/generated/index.ts"() {
80
80
  init_fetcher();
81
81
  getMeUrl = () => {
82
- return `/api/skills/me`;
82
+ return `/api/skills/-/me`;
83
83
  };
84
84
  me = async (options) => {
85
85
  return customFetch(
@@ -90,6 +90,18 @@ var init_generated = __esm({
90
90
  }
91
91
  );
92
92
  };
93
+ getDeleteSkillUrl = (username, name) => {
94
+ return `/api/skills/@user/${username}/${name}`;
95
+ };
96
+ deleteSkill = async (username, name, options) => {
97
+ return customFetch(
98
+ getDeleteSkillUrl(username, name),
99
+ {
100
+ ...options,
101
+ method: "DELETE"
102
+ }
103
+ );
104
+ };
93
105
  getListSkillVersionsUrl = (username, name) => {
94
106
  return `/api/skills/@user/${username}/${name}/versions`;
95
107
  };
@@ -103,7 +115,7 @@ var init_generated = __esm({
103
115
  );
104
116
  };
105
117
  getGetSkillVersionUrl = (username, name, version3) => {
106
- return `/api/skills/@user/${username}/${name}/${version3}`;
118
+ return `/api/skills/@user/${username}/${name}/versions/${version3}`;
107
119
  };
108
120
  getSkillVersion = async (username, name, version3, options) => {
109
121
  return customFetch(
@@ -114,43 +126,31 @@ var init_generated = __esm({
114
126
  }
115
127
  );
116
128
  };
117
- getPublishSkillUrl = () => {
118
- return `/api/skills/publish`;
119
- };
120
- publishSkill = async (publishSkillInput, options) => {
121
- return customFetch(
122
- getPublishSkillUrl(),
123
- {
124
- ...options,
125
- method: "POST",
126
- headers: { "Content-Type": "application/json", ...options?.headers },
127
- body: JSON.stringify(
128
- publishSkillInput
129
- )
130
- }
131
- );
132
- };
133
- getDeleteSkillUrl = (name) => {
134
- return `/api/skills/${name}`;
129
+ getDeleteSkillVersionUrl = (username, name, version3) => {
130
+ return `/api/skills/@user/${username}/${name}/versions/${version3}`;
135
131
  };
136
- deleteSkill = async (name, options) => {
132
+ deleteSkillVersion = async (username, name, version3, options) => {
137
133
  return customFetch(
138
- getDeleteSkillUrl(name),
134
+ getDeleteSkillVersionUrl(username, name, version3),
139
135
  {
140
136
  ...options,
141
137
  method: "DELETE"
142
138
  }
143
139
  );
144
140
  };
145
- getDeleteSkillVersionUrl = (name, version3) => {
146
- return `/api/skills/${name}/${version3}`;
141
+ getPublishSkillUrl = () => {
142
+ return `/api/skills/-/publish`;
147
143
  };
148
- deleteSkillVersion = async (name, version3, options) => {
144
+ publishSkill = async (publishSkillInput, options) => {
149
145
  return customFetch(
150
- getDeleteSkillVersionUrl(name, version3),
146
+ getPublishSkillUrl(),
151
147
  {
152
148
  ...options,
153
- method: "DELETE"
149
+ method: "POST",
150
+ headers: { "Content-Type": "application/json", ...options?.headers },
151
+ body: JSON.stringify(
152
+ publishSkillInput
153
+ )
154
154
  }
155
155
  );
156
156
  };
@@ -181,14 +181,14 @@ async function whoamiRequest(registryUrl, apiKey) {
181
181
  return null;
182
182
  }
183
183
  }
184
- async function deprecateSkillVersion(skillName, version3, message) {
184
+ async function deprecateSkillVersion(username, skillName, version3, message) {
185
185
  const config2 = getConfig();
186
186
  if (!config2) {
187
187
  return { status: 401, error: "SDK not configured" };
188
188
  }
189
189
  try {
190
190
  const response = await fetch(
191
- `${config2.baseUrl}/api/skills/${skillName}/${version3}/deprecate`,
191
+ `${config2.baseUrl}/api/skills/@user/${username}/${skillName}/versions/${version3}/deprecate`,
192
192
  {
193
193
  method: "POST",
194
194
  headers: {
@@ -211,14 +211,14 @@ async function deprecateSkillVersion(skillName, version3, message) {
211
211
  };
212
212
  }
213
213
  }
214
- async function undeprecateSkillVersion(skillName, version3) {
214
+ async function undeprecateSkillVersion(username, skillName, version3) {
215
215
  const config2 = getConfig();
216
216
  if (!config2) {
217
217
  return { status: 401, error: "SDK not configured" };
218
218
  }
219
219
  try {
220
220
  const response = await fetch(
221
- `${config2.baseUrl}/api/skills/${skillName}/${version3}/deprecate`,
221
+ `${config2.baseUrl}/api/skills/@user/${username}/${skillName}/versions/${version3}/deprecate`,
222
222
  {
223
223
  method: "DELETE",
224
224
  headers: {
@@ -239,14 +239,14 @@ async function undeprecateSkillVersion(skillName, version3) {
239
239
  };
240
240
  }
241
241
  }
242
- async function changeSkillAccess(skillName, input) {
242
+ async function changeSkillAccess(username, skillName, input) {
243
243
  const config2 = getConfig();
244
244
  if (!config2) {
245
245
  return { status: 401, error: "SDK not configured" };
246
246
  }
247
247
  try {
248
248
  const response = await fetch(
249
- `${config2.baseUrl}/api/skills/${skillName}/access`,
249
+ `${config2.baseUrl}/api/skills/@user/${username}/${skillName}/access`,
250
250
  {
251
251
  method: "POST",
252
252
  headers: {
@@ -772,7 +772,7 @@ async function resolveRecursive(rootDeps, config2) {
772
772
  };
773
773
  configure2({
774
774
  registryUrl: config2.registryUrl,
775
- apiKey: config2.apiKey ?? ""
775
+ apiKey: config2.apiKey
776
776
  });
777
777
  const rangesByPackage = /* @__PURE__ */ new Map();
778
778
  const queue = [];
@@ -2047,7 +2047,7 @@ async function validateRegistryPackage(specifier) {
2047
2047
  );
2048
2048
  }
2049
2049
  const { username, name, versionRange } = parsed;
2050
- configure2({ registryUrl, apiKey: apiKey ?? "" });
2050
+ configure2({ registryUrl, apiKey });
2051
2051
  console.log(`Resolving ${specifier}...`);
2052
2052
  const versionsResponse = await listSkillVersions(username, name);
2053
2053
  if (versionsResponse.status !== 200) {
@@ -2288,6 +2288,7 @@ async function access(specifier, options) {
2288
2288
  }
2289
2289
  const visibility = options.public ? "public" : "private";
2290
2290
  let packageName;
2291
+ let packageUsername;
2291
2292
  if (specifier) {
2292
2293
  if (isGitHubSpecifier(specifier)) {
2293
2294
  const ghSpec = parseGitHubSpecifier(specifier);
@@ -2328,6 +2329,7 @@ async function access(specifier, options) {
2328
2329
  process.exit(1);
2329
2330
  }
2330
2331
  packageName = parsed.name;
2332
+ packageUsername = parsed.username;
2331
2333
  } else {
2332
2334
  const { readFile: readFile8 } = await import('fs/promises');
2333
2335
  const { join: join14 } = await import('path');
@@ -2361,9 +2363,21 @@ async function access(specifier, options) {
2361
2363
  }
2362
2364
  packageName = manifest.name;
2363
2365
  }
2366
+ if (!packageUsername) {
2367
+ const config2 = await resolveConfig();
2368
+ packageUsername = config2.username;
2369
+ }
2370
+ if (!packageUsername) {
2371
+ console.error(
2372
+ "Error: Could not determine username. Please use the full specifier: @user/{username}/{name}"
2373
+ );
2374
+ process.exit(1);
2375
+ }
2364
2376
  configure2({ registryUrl, apiKey });
2365
2377
  console.log(`Setting ${packageName} to ${visibility}...`);
2366
- const response = await changeSkillAccess(packageName, { visibility });
2378
+ const response = await changeSkillAccess(packageUsername, packageName, {
2379
+ visibility
2380
+ });
2367
2381
  if (response.status !== 200 || !response.data) {
2368
2382
  const errorMessage = response.error ?? "Failed to change visibility";
2369
2383
  console.error(`Error: ${errorMessage}`);
@@ -2476,7 +2490,11 @@ async function deprecate(specifier, message, options) {
2476
2490
  console.log(
2477
2491
  `Removing deprecation from @user/${username}/${name}@${versionRange}...`
2478
2492
  );
2479
- const response = await undeprecateSkillVersion(name, versionRange);
2493
+ const response = await undeprecateSkillVersion(
2494
+ username,
2495
+ name,
2496
+ versionRange
2497
+ );
2480
2498
  if (response.status !== 200) {
2481
2499
  console.error(
2482
2500
  `Error: ${response.error || "Failed to remove deprecation"}`
@@ -2494,7 +2512,12 @@ async function deprecate(specifier, message, options) {
2494
2512
  process.exit(1);
2495
2513
  }
2496
2514
  console.log(`Deprecating @user/${username}/${name}@${versionRange}...`);
2497
- const response = await deprecateSkillVersion(name, versionRange, message);
2515
+ const response = await deprecateSkillVersion(
2516
+ username,
2517
+ name,
2518
+ versionRange,
2519
+ message
2520
+ );
2498
2521
  if (response.status !== 200) {
2499
2522
  console.error(
2500
2523
  `Error: ${response.error || "Failed to deprecate version"}`
@@ -2820,7 +2843,7 @@ async function installFromLockfile(options) {
2820
2843
  }
2821
2844
  console.log(`Resolving ${missingDeps.length} new dependency(ies)...
2822
2845
  `);
2823
- configure2({ registryUrl, apiKey: apiKey ?? "" });
2846
+ configure2({ registryUrl, apiKey });
2824
2847
  for (const { fullName, versionRange } of missingDeps) {
2825
2848
  const parsed = parseSkillSpecifier(fullName);
2826
2849
  if (!parsed) {
@@ -4076,7 +4099,7 @@ async function unpublish(specifier, options) {
4076
4099
  );
4077
4100
  process.exit(1);
4078
4101
  }
4079
- const response = await deleteSkillVersion(name, versionRange);
4102
+ const response = await deleteSkillVersion(username, name, versionRange);
4080
4103
  if (response.status !== 200) {
4081
4104
  const errorMessage = extractApiErrorMessage(
4082
4105
  response,
@@ -4094,7 +4117,7 @@ async function unpublish(specifier, options) {
4094
4117
  );
4095
4118
  process.exit(1);
4096
4119
  }
4097
- const response = await deleteSkill(name);
4120
+ const response = await deleteSkill(username, name);
4098
4121
  if (response.status !== 200) {
4099
4122
  const errorMessage = extractApiErrorMessage(
4100
4123
  response,
@@ -4121,8 +4144,9 @@ init_lockfile2();
4121
4144
  init_add();
4122
4145
  async function update(options) {
4123
4146
  try {
4124
- const apiKey = await requireApiKey();
4125
- const registryUrl = await getRegistryUrl();
4147
+ const config2 = await resolveConfig();
4148
+ const registryUrl = config2.registryUrl;
4149
+ const apiKey = getTokenForRegistry(config2, registryUrl);
4126
4150
  const skills = await listLockfileSkills();
4127
4151
  if (skills.length === 0) {
4128
4152
  console.log("No skills installed.");