@anytio/pspm 0.10.0 → 0.11.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 +14 -0
- package/README.md +4 -0
- package/dist/index.js +184 -2
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,20 @@ 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.11.0] - 2026-03-17
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Skill list install**: Install all skills from a curated skill list with `pspm install --list @user/username/list-name`
|
|
13
|
+
- Supports both user and org lists: `@user/{username}/{list-name}` or `@org/{orgname}/{list-name}`
|
|
14
|
+
- Fetches list from the registry API and resolves items to registry specifiers
|
|
15
|
+
- Respects pinned versions when specified in the list
|
|
16
|
+
- Can be combined with explicit specifiers for additional packages
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Updated all dependencies to latest versions
|
|
21
|
+
|
|
8
22
|
## [0.10.0] - 2026-03-14
|
|
9
23
|
|
|
10
24
|
### Added
|
package/README.md
CHANGED
|
@@ -146,6 +146,10 @@ pspm install --dir ./custom-path
|
|
|
146
146
|
|
|
147
147
|
# Install specific packages
|
|
148
148
|
pspm install @user/alice/skill1 github:org/repo
|
|
149
|
+
|
|
150
|
+
# Install all skills from a skill list
|
|
151
|
+
pspm install --list @user/alice/my-favorites
|
|
152
|
+
pspm install --list @org/myorg/team-skills
|
|
149
153
|
```
|
|
150
154
|
|
|
151
155
|
### `pspm search`
|
package/dist/index.js
CHANGED
|
@@ -37,6 +37,9 @@ function getConfig() {
|
|
|
37
37
|
}
|
|
38
38
|
return config;
|
|
39
39
|
}
|
|
40
|
+
function isConfigured() {
|
|
41
|
+
return config !== null;
|
|
42
|
+
}
|
|
40
43
|
async function customFetch(url, options) {
|
|
41
44
|
const { baseUrl, apiKey } = getConfig();
|
|
42
45
|
const fullUrl = `${baseUrl}${url}`;
|
|
@@ -66,18 +69,42 @@ async function customFetch(url, options) {
|
|
|
66
69
|
headers: response.headers
|
|
67
70
|
};
|
|
68
71
|
}
|
|
69
|
-
var config;
|
|
72
|
+
var config, SDKError;
|
|
70
73
|
var init_fetcher = __esm({
|
|
71
74
|
"src/sdk/fetcher.ts"() {
|
|
72
75
|
config = null;
|
|
76
|
+
SDKError = class extends Error {
|
|
77
|
+
constructor(message, status, body) {
|
|
78
|
+
super(message);
|
|
79
|
+
this.status = status;
|
|
80
|
+
this.body = body;
|
|
81
|
+
this.name = "SDKError";
|
|
82
|
+
}
|
|
83
|
+
};
|
|
73
84
|
}
|
|
74
85
|
});
|
|
75
86
|
|
|
76
87
|
// src/sdk/generated/index.ts
|
|
77
|
-
var getMeUrl, me, getExplorePublicSkillsUrl, explorePublicSkills, getDeleteSkillUrl, deleteSkill, getListSkillVersionsUrl, listSkillVersions, getGetSkillVersionUrl, getSkillVersion, getDeleteSkillVersionUrl, deleteSkillVersion, getPublishSkillUrl, publishSkill, getListOrgSkillVersionsUrl, listOrgSkillVersions, getGetOrgSkillVersionUrl, getOrgSkillVersion, getPublishOrgSkillUrl, publishOrgSkill;
|
|
88
|
+
var getExchangeCliTokenUrl, exchangeCliToken, getMeUrl, me, getExplorePublicSkillsUrl, explorePublicSkills, getListMySkillsUrl, listMySkills, getListUserSkillsUrl, listUserSkills, getGetSkillUrl, getSkill, getDeleteSkillUrl, deleteSkill, getListSkillVersionsUrl, listSkillVersions, getGetSkillVersionUrl, getSkillVersion, getDeleteSkillVersionUrl, deleteSkillVersion, getPublishSkillUrl, publishSkill, getListOrgSkillVersionsUrl, listOrgSkillVersions, getGetOrgSkillVersionUrl, getOrgSkillVersion, getPublishOrgSkillUrl, publishOrgSkill;
|
|
78
89
|
var init_generated = __esm({
|
|
79
90
|
"src/sdk/generated/index.ts"() {
|
|
80
91
|
init_fetcher();
|
|
92
|
+
getExchangeCliTokenUrl = () => {
|
|
93
|
+
return `/api/api-keys/cli-token-exchange`;
|
|
94
|
+
};
|
|
95
|
+
exchangeCliToken = async (exchangeCliTokenInput, options) => {
|
|
96
|
+
return customFetch(
|
|
97
|
+
getExchangeCliTokenUrl(),
|
|
98
|
+
{
|
|
99
|
+
...options,
|
|
100
|
+
method: "POST",
|
|
101
|
+
headers: { "Content-Type": "application/json", ...options?.headers },
|
|
102
|
+
body: JSON.stringify(
|
|
103
|
+
exchangeCliTokenInput
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
};
|
|
81
108
|
getMeUrl = () => {
|
|
82
109
|
return `/api/skills/-/me`;
|
|
83
110
|
};
|
|
@@ -109,6 +136,42 @@ var init_generated = __esm({
|
|
|
109
136
|
}
|
|
110
137
|
);
|
|
111
138
|
};
|
|
139
|
+
getListMySkillsUrl = () => {
|
|
140
|
+
return `/api/skills/-/mine`;
|
|
141
|
+
};
|
|
142
|
+
listMySkills = async (options) => {
|
|
143
|
+
return customFetch(
|
|
144
|
+
getListMySkillsUrl(),
|
|
145
|
+
{
|
|
146
|
+
...options,
|
|
147
|
+
method: "GET"
|
|
148
|
+
}
|
|
149
|
+
);
|
|
150
|
+
};
|
|
151
|
+
getListUserSkillsUrl = (username) => {
|
|
152
|
+
return `/api/skills/@user/${username}`;
|
|
153
|
+
};
|
|
154
|
+
listUserSkills = async (username, options) => {
|
|
155
|
+
return customFetch(
|
|
156
|
+
getListUserSkillsUrl(username),
|
|
157
|
+
{
|
|
158
|
+
...options,
|
|
159
|
+
method: "GET"
|
|
160
|
+
}
|
|
161
|
+
);
|
|
162
|
+
};
|
|
163
|
+
getGetSkillUrl = (username, name) => {
|
|
164
|
+
return `/api/skills/@user/${username}/${name}`;
|
|
165
|
+
};
|
|
166
|
+
getSkill = async (username, name, options) => {
|
|
167
|
+
return customFetch(
|
|
168
|
+
getGetSkillUrl(username, name),
|
|
169
|
+
{
|
|
170
|
+
...options,
|
|
171
|
+
method: "GET"
|
|
172
|
+
}
|
|
173
|
+
);
|
|
174
|
+
};
|
|
112
175
|
getDeleteSkillUrl = (username, name) => {
|
|
113
176
|
return `/api/skills/@user/${username}/${name}`;
|
|
114
177
|
};
|
|
@@ -217,6 +280,33 @@ var init_generated = __esm({
|
|
|
217
280
|
});
|
|
218
281
|
|
|
219
282
|
// src/api-client.ts
|
|
283
|
+
var api_client_exports = {};
|
|
284
|
+
__export(api_client_exports, {
|
|
285
|
+
SDKError: () => SDKError,
|
|
286
|
+
changeSkillAccess: () => changeSkillAccess,
|
|
287
|
+
configure: () => configure2,
|
|
288
|
+
deleteSkill: () => deleteSkill,
|
|
289
|
+
deleteSkillVersion: () => deleteSkillVersion,
|
|
290
|
+
deprecateSkillVersion: () => deprecateSkillVersion,
|
|
291
|
+
exchangeCliToken: () => exchangeCliToken,
|
|
292
|
+
fetchSkillList: () => fetchSkillList,
|
|
293
|
+
getConfig: () => getConfig,
|
|
294
|
+
getGithubSkillVersion: () => getGithubSkillVersion,
|
|
295
|
+
getOrgSkillVersion: () => getOrgSkillVersion,
|
|
296
|
+
getSkill: () => getSkill,
|
|
297
|
+
getSkillVersion: () => getSkillVersion,
|
|
298
|
+
isConfigured: () => isConfigured,
|
|
299
|
+
listGithubSkillVersions: () => listGithubSkillVersions,
|
|
300
|
+
listMySkills: () => listMySkills,
|
|
301
|
+
listOrgSkillVersions: () => listOrgSkillVersions,
|
|
302
|
+
listSkillVersions: () => listSkillVersions,
|
|
303
|
+
listUserSkills: () => listUserSkills,
|
|
304
|
+
me: () => me,
|
|
305
|
+
publishOrgSkill: () => publishOrgSkill,
|
|
306
|
+
publishSkill: () => publishSkill,
|
|
307
|
+
undeprecateSkillVersion: () => undeprecateSkillVersion,
|
|
308
|
+
whoamiRequest: () => whoamiRequest
|
|
309
|
+
});
|
|
220
310
|
function registryUrlToBaseUrl(registryUrl) {
|
|
221
311
|
return registryUrl.replace(/\/api\/skills\/?$/, "");
|
|
222
312
|
}
|
|
@@ -298,6 +388,32 @@ async function undeprecateSkillVersion(username, skillName, version3) {
|
|
|
298
388
|
};
|
|
299
389
|
}
|
|
300
390
|
}
|
|
391
|
+
async function fetchSkillList(ownerType, ownerName, listName) {
|
|
392
|
+
const config2 = getConfig();
|
|
393
|
+
try {
|
|
394
|
+
const response = await fetch(
|
|
395
|
+
`${config2.baseUrl}/api/skill-lists/lists/@${ownerType}/${ownerName}/${listName}`,
|
|
396
|
+
{
|
|
397
|
+
method: "GET",
|
|
398
|
+
headers: {
|
|
399
|
+
"Content-Type": "application/json",
|
|
400
|
+
...config2.apiKey ? { Authorization: `Bearer ${config2.apiKey}` } : {}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
);
|
|
404
|
+
if (!response.ok) {
|
|
405
|
+
const error = await response.text();
|
|
406
|
+
return { status: response.status, error };
|
|
407
|
+
}
|
|
408
|
+
const data = await response.json();
|
|
409
|
+
return { status: response.status, data };
|
|
410
|
+
} catch (error) {
|
|
411
|
+
return {
|
|
412
|
+
status: 500,
|
|
413
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
}
|
|
301
417
|
async function listGithubSkillVersions(owner, repo, name) {
|
|
302
418
|
const config2 = getConfig();
|
|
303
419
|
try {
|
|
@@ -3951,6 +4067,22 @@ async function install(specifiers, options) {
|
|
|
3951
4067
|
const { setGlobalMode: setGlobalMode2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
3952
4068
|
setGlobalMode2(true);
|
|
3953
4069
|
}
|
|
4070
|
+
if (options.list) {
|
|
4071
|
+
const listSpecifiers = await resolveListToSpecifiers(options.list);
|
|
4072
|
+
if (listSpecifiers.length === 0) {
|
|
4073
|
+
console.log("No skills in the list to install.");
|
|
4074
|
+
return;
|
|
4075
|
+
}
|
|
4076
|
+
const allSpecifiers = [...specifiers, ...listSpecifiers];
|
|
4077
|
+
const { add: add2 } = await Promise.resolve().then(() => (init_add(), add_exports));
|
|
4078
|
+
await add2(allSpecifiers, {
|
|
4079
|
+
save: true,
|
|
4080
|
+
agent: options.agent,
|
|
4081
|
+
yes: options.yes,
|
|
4082
|
+
global: options.global
|
|
4083
|
+
});
|
|
4084
|
+
return;
|
|
4085
|
+
}
|
|
3954
4086
|
if (specifiers.length > 0) {
|
|
3955
4087
|
const { add: add2 } = await Promise.resolve().then(() => (init_add(), add_exports));
|
|
3956
4088
|
await add2(specifiers, {
|
|
@@ -3963,6 +4095,52 @@ async function install(specifiers, options) {
|
|
|
3963
4095
|
}
|
|
3964
4096
|
await installFromLockfile(options);
|
|
3965
4097
|
}
|
|
4098
|
+
async function resolveListToSpecifiers(listSpec) {
|
|
4099
|
+
const match = listSpec.match(/^@(user|org)\/([^/]+)\/([^/]+)$/);
|
|
4100
|
+
if (!match) {
|
|
4101
|
+
console.error(
|
|
4102
|
+
`Error: Invalid list specifier "${listSpec}". Use format: @user/{username}/{list-name} or @org/{orgname}/{list-name}`
|
|
4103
|
+
);
|
|
4104
|
+
process.exit(1);
|
|
4105
|
+
}
|
|
4106
|
+
const [, ownerType, ownerName, listName] = match;
|
|
4107
|
+
const config2 = await resolveConfig();
|
|
4108
|
+
configure2({
|
|
4109
|
+
registryUrl: config2.registryUrl,
|
|
4110
|
+
apiKey: getTokenForRegistry(config2, config2.registryUrl)
|
|
4111
|
+
});
|
|
4112
|
+
console.log(
|
|
4113
|
+
`Fetching skill list @${ownerType}/${ownerName}/${listName}...
|
|
4114
|
+
`
|
|
4115
|
+
);
|
|
4116
|
+
const { fetchSkillList: fetchSkillList2 } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
|
|
4117
|
+
const response = await fetchSkillList2(
|
|
4118
|
+
ownerType,
|
|
4119
|
+
ownerName,
|
|
4120
|
+
listName
|
|
4121
|
+
);
|
|
4122
|
+
if (response.status !== 200 || !response.data) {
|
|
4123
|
+
const errorMsg = response.status === 404 ? `List "@${ownerType}/${ownerName}/${listName}" not found or is private.` : response.error || "Failed to fetch list";
|
|
4124
|
+
console.error(`Error: ${errorMsg}`);
|
|
4125
|
+
process.exit(1);
|
|
4126
|
+
}
|
|
4127
|
+
const list2 = response.data;
|
|
4128
|
+
console.log(
|
|
4129
|
+
`List: ${list2.name}${list2.description ? ` \u2014 ${list2.description}` : ""}`
|
|
4130
|
+
);
|
|
4131
|
+
console.log(`Skills: ${list2.items.length}
|
|
4132
|
+
`);
|
|
4133
|
+
const specifiers = [];
|
|
4134
|
+
for (const item of list2.items) {
|
|
4135
|
+
const ns = item.namespace === "org" ? "org" : "user";
|
|
4136
|
+
let spec = `@${ns}/${item.ownerName}/${item.skillName}`;
|
|
4137
|
+
if (item.pinnedVersion) {
|
|
4138
|
+
spec += `@${item.pinnedVersion}`;
|
|
4139
|
+
}
|
|
4140
|
+
specifiers.push(spec);
|
|
4141
|
+
}
|
|
4142
|
+
return specifiers;
|
|
4143
|
+
}
|
|
3966
4144
|
async function installFromLockfile(options) {
|
|
3967
4145
|
try {
|
|
3968
4146
|
const config2 = await resolveConfig();
|
|
@@ -6100,11 +6278,15 @@ program.command("install [specifiers...]").alias("i").description(
|
|
|
6100
6278
|
).option("--frozen-lockfile", "Fail if lockfile is missing or outdated").option("--dir <path>", "Install skills to a specific directory").option(
|
|
6101
6279
|
"--agent <agents>",
|
|
6102
6280
|
'Comma-separated agents for symlinks (default: all agents, use "none" to skip)'
|
|
6281
|
+
).option(
|
|
6282
|
+
"--list <specifier>",
|
|
6283
|
+
"Install all skills from a skill list (e.g. @user/username/list-name)"
|
|
6103
6284
|
).option("-g, --global", "Install to user home directory instead of project").option("-y, --yes", "Skip agent selection prompt and use defaults").action(async (specifiers, options) => {
|
|
6104
6285
|
await install(specifiers, {
|
|
6105
6286
|
frozenLockfile: options.frozenLockfile,
|
|
6106
6287
|
dir: options.dir,
|
|
6107
6288
|
agent: options.agent,
|
|
6289
|
+
list: options.list,
|
|
6108
6290
|
yes: options.yes,
|
|
6109
6291
|
global: options.global
|
|
6110
6292
|
});
|