@anytio/pspm 0.0.2 → 0.0.4
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/README.md +265 -0
- package/dist/index.js +477 -622
- package/dist/index.js.map +1 -1
- package/package.json +14 -6
package/dist/index.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { readFileSync } from 'fs';
|
|
3
|
-
import { dirname, join } from 'path';
|
|
3
|
+
import { dirname, join, relative } from 'path';
|
|
4
4
|
import { fileURLToPath, URL } from 'url';
|
|
5
5
|
import { Command } from 'commander';
|
|
6
|
-
import { stat, writeFile, mkdir, rm, access, readFile } from 'fs/promises';
|
|
7
|
-
import {
|
|
6
|
+
import { stat, writeFile, mkdir, rm, access, readFile, readdir, unlink } from 'fs/promises';
|
|
7
|
+
import { createHash, randomBytes } from 'crypto';
|
|
8
8
|
import * as semver from 'semver';
|
|
9
9
|
import { homedir } from 'os';
|
|
10
|
+
import * as ini from 'ini';
|
|
10
11
|
import http from 'http';
|
|
11
12
|
import open from 'open';
|
|
12
13
|
import { exec as exec$1 } from 'child_process';
|
|
@@ -38,7 +39,7 @@ function resolveVersion(range, availableVersions) {
|
|
|
38
39
|
return semver.maxSatisfying(sorted, range);
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
// ../../packages/sdk/src/
|
|
42
|
+
// ../../packages/sdk/src/fetchers/cli-fetcher.ts
|
|
42
43
|
var config = null;
|
|
43
44
|
function configure(options) {
|
|
44
45
|
config = options;
|
|
@@ -49,18 +50,10 @@ function getConfig() {
|
|
|
49
50
|
}
|
|
50
51
|
return config;
|
|
51
52
|
}
|
|
52
|
-
|
|
53
|
-
constructor(message, status, body) {
|
|
54
|
-
super(message);
|
|
55
|
-
this.status = status;
|
|
56
|
-
this.body = body;
|
|
57
|
-
this.name = "SDKError";
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
async function apiFetch(path, options = {}) {
|
|
53
|
+
async function customFetch(url, options) {
|
|
61
54
|
const { baseUrl, apiKey } = getConfig();
|
|
62
|
-
const
|
|
63
|
-
const response = await fetch(
|
|
55
|
+
const fullUrl = `${baseUrl}${url}`;
|
|
56
|
+
const response = await fetch(fullUrl, {
|
|
64
57
|
...options,
|
|
65
58
|
headers: {
|
|
66
59
|
...options.headers,
|
|
@@ -68,67 +61,116 @@ async function apiFetch(path, options = {}) {
|
|
|
68
61
|
"Content-Type": "application/json"
|
|
69
62
|
}
|
|
70
63
|
});
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
64
|
+
const text = await response.text();
|
|
65
|
+
let data = null;
|
|
66
|
+
if (text) {
|
|
74
67
|
try {
|
|
75
|
-
|
|
76
|
-
if (errorJson.message) {
|
|
77
|
-
errorMessage = errorJson.message;
|
|
78
|
-
} else if (errorJson.error) {
|
|
79
|
-
errorMessage = errorJson.error;
|
|
80
|
-
}
|
|
68
|
+
data = JSON.parse(text);
|
|
81
69
|
} catch {
|
|
82
|
-
|
|
83
|
-
errorMessage = errorText;
|
|
84
|
-
}
|
|
70
|
+
data = text;
|
|
85
71
|
}
|
|
86
|
-
throw new SDKError(errorMessage, response.status, errorText);
|
|
87
72
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
async function me() {
|
|
95
|
-
return apiFetch("/me", { method: "GET" });
|
|
73
|
+
return {
|
|
74
|
+
data,
|
|
75
|
+
status: response.status,
|
|
76
|
+
headers: response.headers
|
|
77
|
+
};
|
|
96
78
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
79
|
+
|
|
80
|
+
// ../../packages/sdk/src/generated/fetch/index.ts
|
|
81
|
+
var getMeUrl = () => {
|
|
82
|
+
return `/api/skills/me`;
|
|
83
|
+
};
|
|
84
|
+
var me = async (options) => {
|
|
85
|
+
return customFetch(
|
|
86
|
+
getMeUrl(),
|
|
87
|
+
{
|
|
88
|
+
...options,
|
|
89
|
+
method: "GET"
|
|
90
|
+
}
|
|
101
91
|
);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return
|
|
105
|
-
|
|
106
|
-
|
|
92
|
+
};
|
|
93
|
+
var getListSkillVersionsUrl = (username, name) => {
|
|
94
|
+
return `/api/skills/@user/${username}/${name}/versions`;
|
|
95
|
+
};
|
|
96
|
+
var listSkillVersions = async (username, name, options) => {
|
|
97
|
+
return customFetch(
|
|
98
|
+
getListSkillVersionsUrl(username, name),
|
|
99
|
+
{
|
|
100
|
+
...options,
|
|
101
|
+
method: "GET"
|
|
102
|
+
}
|
|
107
103
|
);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
104
|
+
};
|
|
105
|
+
var getGetSkillVersionUrl = (username, name, version2) => {
|
|
106
|
+
return `/api/skills/@user/${username}/${name}/${version2}`;
|
|
107
|
+
};
|
|
108
|
+
var getSkillVersion = async (username, name, version2, options) => {
|
|
109
|
+
return customFetch(
|
|
110
|
+
getGetSkillVersionUrl(username, name, version2),
|
|
111
|
+
{
|
|
112
|
+
...options,
|
|
113
|
+
method: "GET"
|
|
114
|
+
}
|
|
115
|
+
);
|
|
116
|
+
};
|
|
117
|
+
var getPublishSkillUrl = () => {
|
|
118
|
+
return `/api/skills/publish`;
|
|
119
|
+
};
|
|
120
|
+
var 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
|
+
var getDeleteSkillUrl = (name) => {
|
|
134
|
+
return `/api/skills/${name}`;
|
|
135
|
+
};
|
|
136
|
+
var deleteSkill = async (name, options) => {
|
|
137
|
+
return customFetch(
|
|
138
|
+
getDeleteSkillUrl(name),
|
|
139
|
+
{
|
|
140
|
+
...options,
|
|
141
|
+
method: "DELETE"
|
|
142
|
+
}
|
|
143
|
+
);
|
|
144
|
+
};
|
|
145
|
+
var getDeleteSkillVersionUrl = (name, version2) => {
|
|
146
|
+
return `/api/skills/${name}/${version2}`;
|
|
147
|
+
};
|
|
148
|
+
var deleteSkillVersion = async (name, version2, options) => {
|
|
149
|
+
return customFetch(
|
|
150
|
+
getDeleteSkillVersionUrl(name, version2),
|
|
151
|
+
{
|
|
152
|
+
...options,
|
|
153
|
+
method: "DELETE"
|
|
154
|
+
}
|
|
155
|
+
);
|
|
156
|
+
};
|
|
123
157
|
|
|
124
158
|
// src/api-client.ts
|
|
159
|
+
function registryUrlToBaseUrl(registryUrl) {
|
|
160
|
+
return registryUrl.replace(/\/api\/skills\/?$/, "");
|
|
161
|
+
}
|
|
162
|
+
function configure2(options) {
|
|
163
|
+
const baseUrl = registryUrlToBaseUrl(options.registryUrl);
|
|
164
|
+
configure({ baseUrl, apiKey: options.apiKey });
|
|
165
|
+
}
|
|
125
166
|
async function whoamiRequest(registryUrl, apiKey) {
|
|
126
167
|
try {
|
|
127
|
-
|
|
128
|
-
const
|
|
129
|
-
if (!
|
|
168
|
+
configure2({ registryUrl, apiKey });
|
|
169
|
+
const response = await me();
|
|
170
|
+
if (response.status !== 200 || !response.data) {
|
|
130
171
|
return null;
|
|
131
172
|
}
|
|
173
|
+
const user = response.data;
|
|
132
174
|
return {
|
|
133
175
|
username: user.username,
|
|
134
176
|
userId: user.userId
|
|
@@ -145,14 +187,6 @@ var ConfigError = class extends Error {
|
|
|
145
187
|
this.name = "ConfigError";
|
|
146
188
|
}
|
|
147
189
|
};
|
|
148
|
-
var ProfileNotFoundError = class extends ConfigError {
|
|
149
|
-
constructor(profileName) {
|
|
150
|
-
super(
|
|
151
|
-
`Profile "${profileName}" not found. Run 'pspm config list' to see available profiles.`
|
|
152
|
-
);
|
|
153
|
-
this.name = "ProfileNotFoundError";
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
190
|
var NotLoggedInError = class extends ConfigError {
|
|
157
191
|
constructor() {
|
|
158
192
|
super(
|
|
@@ -161,10 +195,47 @@ var NotLoggedInError = class extends ConfigError {
|
|
|
161
195
|
this.name = "NotLoggedInError";
|
|
162
196
|
}
|
|
163
197
|
};
|
|
198
|
+
function extractApiErrorMessage(response, fallbackMessage) {
|
|
199
|
+
const errorData = response.data;
|
|
200
|
+
if (process.env.PSPM_DEBUG) {
|
|
201
|
+
console.log(`[debug] API response status: ${response.status}`);
|
|
202
|
+
console.log(
|
|
203
|
+
`[debug] API response data:`,
|
|
204
|
+
JSON.stringify(errorData, null, 2)
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
if (!errorData) {
|
|
208
|
+
return `${fallbackMessage} (HTTP ${response.status})`;
|
|
209
|
+
}
|
|
210
|
+
let errorMessage = errorData.message || fallbackMessage;
|
|
211
|
+
if (errorData.code === "VALIDATION_ERROR" && errorData.details) {
|
|
212
|
+
const issues = errorData.details.issues;
|
|
213
|
+
if (issues && Array.isArray(issues)) {
|
|
214
|
+
const issueMessages = issues.map((issue) => {
|
|
215
|
+
const path = issue.path?.join(".") || "input";
|
|
216
|
+
const msg = issue.message || "invalid value";
|
|
217
|
+
return ` - ${path}: ${msg}`;
|
|
218
|
+
}).join("\n");
|
|
219
|
+
errorMessage = `Validation failed:
|
|
220
|
+
${issueMessages}`;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (errorData.code && !errorMessage.includes(errorData.code)) {
|
|
224
|
+
errorMessage = `[${errorData.code}] ${errorMessage}`;
|
|
225
|
+
}
|
|
226
|
+
if (errorData.requestId) {
|
|
227
|
+
errorMessage += `
|
|
228
|
+
(Request ID: ${errorData.requestId})`;
|
|
229
|
+
}
|
|
230
|
+
return errorMessage;
|
|
231
|
+
}
|
|
164
232
|
|
|
165
233
|
// src/config.ts
|
|
166
|
-
var DEFAULT_REGISTRY_URL = "https://pspm.dev
|
|
234
|
+
var DEFAULT_REGISTRY_URL = "https://pspm.dev";
|
|
167
235
|
function getConfigPath() {
|
|
236
|
+
return join(homedir(), ".pspmrc");
|
|
237
|
+
}
|
|
238
|
+
function getLegacyConfigPath() {
|
|
168
239
|
return join(homedir(), ".pspm", "config.json");
|
|
169
240
|
}
|
|
170
241
|
function getSkillsDir() {
|
|
@@ -173,33 +244,6 @@ function getSkillsDir() {
|
|
|
173
244
|
function getLockfilePath() {
|
|
174
245
|
return join(process.cwd(), "skill-lock.json");
|
|
175
246
|
}
|
|
176
|
-
function createDefaultV2Config() {
|
|
177
|
-
return {
|
|
178
|
-
version: 2,
|
|
179
|
-
defaultProfile: "default",
|
|
180
|
-
profiles: {
|
|
181
|
-
default: {
|
|
182
|
-
registryUrl: DEFAULT_REGISTRY_URL
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
function migrateV1ToV2(v1Config) {
|
|
188
|
-
return {
|
|
189
|
-
version: 2,
|
|
190
|
-
defaultProfile: "default",
|
|
191
|
-
profiles: {
|
|
192
|
-
default: {
|
|
193
|
-
registryUrl: v1Config.registryUrl || DEFAULT_REGISTRY_URL,
|
|
194
|
-
apiKey: v1Config.apiKey,
|
|
195
|
-
username: v1Config.username
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
function isV2Config(config2) {
|
|
201
|
-
return typeof config2 === "object" && config2 !== null && "version" in config2 && config2.version === 2;
|
|
202
|
-
}
|
|
203
247
|
async function readUserConfig() {
|
|
204
248
|
const configPath = getConfigPath();
|
|
205
249
|
if (process.env.PSPM_DEBUG) {
|
|
@@ -207,48 +251,42 @@ async function readUserConfig() {
|
|
|
207
251
|
}
|
|
208
252
|
try {
|
|
209
253
|
const content = await readFile(configPath, "utf-8");
|
|
254
|
+
const parsed = ini.parse(content);
|
|
210
255
|
if (process.env.PSPM_DEBUG) {
|
|
211
|
-
|
|
212
|
-
if (apiKeyMatch) {
|
|
213
|
-
console.log(
|
|
214
|
-
`[config] Raw apiKey from file: ${apiKeyMatch[1].substring(
|
|
215
|
-
0,
|
|
216
|
-
15
|
|
217
|
-
)}...`
|
|
218
|
-
);
|
|
219
|
-
}
|
|
256
|
+
console.log(`[config] Parsed config:`, JSON.stringify(parsed, null, 2));
|
|
220
257
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
console.log(
|
|
227
|
-
`[config] Profiles found: ${Object.keys(
|
|
228
|
-
parsed.profiles || {}
|
|
229
|
-
).join(", ")}`
|
|
230
|
-
);
|
|
231
|
-
}
|
|
232
|
-
if (isV2Config(parsed)) {
|
|
233
|
-
return parsed;
|
|
234
|
-
}
|
|
235
|
-
const v2Config = migrateV1ToV2(parsed);
|
|
236
|
-
await writeUserConfig(v2Config);
|
|
237
|
-
return v2Config;
|
|
258
|
+
return {
|
|
259
|
+
registry: parsed.registry,
|
|
260
|
+
authToken: parsed.authToken,
|
|
261
|
+
username: parsed.username
|
|
262
|
+
};
|
|
238
263
|
} catch (error) {
|
|
239
264
|
if (process.env.PSPM_DEBUG) {
|
|
240
265
|
console.log(
|
|
241
266
|
`[config] Error reading config: ${error instanceof Error ? error.message : String(error)}`
|
|
242
267
|
);
|
|
243
|
-
console.log(`[config] Falling back to default config`);
|
|
244
268
|
}
|
|
245
|
-
return
|
|
269
|
+
return {};
|
|
246
270
|
}
|
|
247
271
|
}
|
|
248
272
|
async function writeUserConfig(config2) {
|
|
249
273
|
const configPath = getConfigPath();
|
|
274
|
+
const lines = ["; PSPM Configuration", ""];
|
|
275
|
+
if (config2.registry) {
|
|
276
|
+
lines.push(`registry = ${config2.registry}`);
|
|
277
|
+
}
|
|
278
|
+
if (config2.authToken) {
|
|
279
|
+
lines.push(`authToken = ${config2.authToken}`);
|
|
280
|
+
}
|
|
281
|
+
if (config2.username) {
|
|
282
|
+
lines.push(`username = ${config2.username}`);
|
|
283
|
+
}
|
|
284
|
+
lines.push("");
|
|
250
285
|
await mkdir(dirname(configPath), { recursive: true });
|
|
251
|
-
await writeFile(configPath,
|
|
286
|
+
await writeFile(configPath, lines.join("\n"));
|
|
287
|
+
if (process.env.PSPM_DEBUG) {
|
|
288
|
+
console.log(`[config] Wrote config to: ${configPath}`);
|
|
289
|
+
}
|
|
252
290
|
}
|
|
253
291
|
async function findProjectConfig() {
|
|
254
292
|
let currentDir = process.cwd();
|
|
@@ -259,7 +297,26 @@ async function findProjectConfig() {
|
|
|
259
297
|
const stats = await stat(configPath);
|
|
260
298
|
if (stats.isFile()) {
|
|
261
299
|
const content = await readFile(configPath, "utf-8");
|
|
262
|
-
|
|
300
|
+
try {
|
|
301
|
+
const parsed = ini.parse(content);
|
|
302
|
+
if (process.env.PSPM_DEBUG) {
|
|
303
|
+
console.log(
|
|
304
|
+
`[config] Found project config at ${configPath}:`,
|
|
305
|
+
JSON.stringify(parsed, null, 2)
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
return {
|
|
309
|
+
registry: parsed.registry
|
|
310
|
+
};
|
|
311
|
+
} catch {
|
|
312
|
+
try {
|
|
313
|
+
const jsonConfig = JSON.parse(content);
|
|
314
|
+
return {
|
|
315
|
+
registry: jsonConfig.registryUrl
|
|
316
|
+
};
|
|
317
|
+
} catch {
|
|
318
|
+
}
|
|
319
|
+
}
|
|
263
320
|
}
|
|
264
321
|
} catch {
|
|
265
322
|
}
|
|
@@ -267,49 +324,61 @@ async function findProjectConfig() {
|
|
|
267
324
|
}
|
|
268
325
|
return null;
|
|
269
326
|
}
|
|
270
|
-
async function
|
|
271
|
-
const
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
} else {
|
|
288
|
-
profileName = "default";
|
|
289
|
-
profileSource = "default";
|
|
290
|
-
}
|
|
291
|
-
const profile = userConfig.profiles[profileName];
|
|
292
|
-
if (!profile) {
|
|
293
|
-
if (process.env.PSPM_DEBUG) {
|
|
327
|
+
async function migrateFromLegacyConfig() {
|
|
328
|
+
const legacyPath = getLegacyConfigPath();
|
|
329
|
+
try {
|
|
330
|
+
const content = await readFile(legacyPath, "utf-8");
|
|
331
|
+
const parsed = JSON.parse(content);
|
|
332
|
+
let config2 = {};
|
|
333
|
+
if (parsed.version === 2 && parsed.profiles) {
|
|
334
|
+
const v2Config = parsed;
|
|
335
|
+
const defaultProfileName = v2Config.defaultProfile || "default";
|
|
336
|
+
const profile = v2Config.profiles[defaultProfileName];
|
|
337
|
+
if (profile) {
|
|
338
|
+
config2 = {
|
|
339
|
+
registry: profile.registryUrl !== DEFAULT_REGISTRY_URL ? profile.registryUrl : void 0,
|
|
340
|
+
authToken: profile.apiKey,
|
|
341
|
+
username: profile.username
|
|
342
|
+
};
|
|
343
|
+
}
|
|
294
344
|
console.log(
|
|
295
|
-
`
|
|
296
|
-
userConfig.profiles
|
|
297
|
-
).join(", ")}`
|
|
345
|
+
`Migrating from legacy config (profile: ${defaultProfileName})...`
|
|
298
346
|
);
|
|
347
|
+
} else {
|
|
348
|
+
const v1Config = parsed;
|
|
349
|
+
config2 = {
|
|
350
|
+
registry: v1Config.registryUrl !== DEFAULT_REGISTRY_URL ? v1Config.registryUrl : void 0,
|
|
351
|
+
authToken: v1Config.apiKey,
|
|
352
|
+
username: v1Config.username
|
|
353
|
+
};
|
|
354
|
+
console.log("Migrating from legacy config...");
|
|
299
355
|
}
|
|
300
|
-
|
|
356
|
+
await writeUserConfig(config2);
|
|
357
|
+
console.log(`Created new config at: ${getConfigPath()}`);
|
|
358
|
+
await unlink(legacyPath);
|
|
359
|
+
console.log(`Removed legacy config: ${legacyPath}`);
|
|
360
|
+
return config2;
|
|
361
|
+
} catch {
|
|
362
|
+
return null;
|
|
301
363
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
364
|
+
}
|
|
365
|
+
async function resolveConfig() {
|
|
366
|
+
const newConfigPath = getConfigPath();
|
|
367
|
+
try {
|
|
368
|
+
await stat(newConfigPath);
|
|
369
|
+
} catch {
|
|
370
|
+
await migrateFromLegacyConfig();
|
|
371
|
+
}
|
|
372
|
+
const userConfig = await readUserConfig();
|
|
373
|
+
const projectConfig = await findProjectConfig();
|
|
374
|
+
let registryUrl = DEFAULT_REGISTRY_URL;
|
|
375
|
+
let apiKey = userConfig.authToken;
|
|
376
|
+
const username = userConfig.username;
|
|
377
|
+
if (userConfig.registry) {
|
|
378
|
+
registryUrl = userConfig.registry;
|
|
307
379
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
const username = profile.username;
|
|
311
|
-
if (projectConfig?.registryUrl) {
|
|
312
|
-
registryUrl = projectConfig.registryUrl;
|
|
380
|
+
if (projectConfig?.registry) {
|
|
381
|
+
registryUrl = projectConfig.registry;
|
|
313
382
|
}
|
|
314
383
|
if (process.env.PSPM_REGISTRY_URL) {
|
|
315
384
|
registryUrl = process.env.PSPM_REGISTRY_URL;
|
|
@@ -317,117 +386,62 @@ async function resolveConfig(globalOptions) {
|
|
|
317
386
|
if (process.env.PSPM_API_KEY) {
|
|
318
387
|
apiKey = process.env.PSPM_API_KEY;
|
|
319
388
|
}
|
|
389
|
+
if (process.env.PSPM_DEBUG) {
|
|
390
|
+
console.log(`[config] Resolved config:`);
|
|
391
|
+
console.log(`[config] registryUrl: ${registryUrl}`);
|
|
392
|
+
console.log(`[config] apiKey: ${apiKey ? "***" : "(not set)"}`);
|
|
393
|
+
console.log(`[config] username: ${username || "(not set)"}`);
|
|
394
|
+
}
|
|
320
395
|
return {
|
|
321
|
-
profileName,
|
|
322
|
-
profileSource,
|
|
323
396
|
registryUrl,
|
|
324
397
|
apiKey,
|
|
325
398
|
username
|
|
326
399
|
};
|
|
327
400
|
}
|
|
328
|
-
async function
|
|
329
|
-
const
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
const userConfig = await readUserConfig();
|
|
334
|
-
return Object.keys(userConfig.profiles);
|
|
335
|
-
}
|
|
336
|
-
async function setProfile(profileName, config2) {
|
|
337
|
-
const userConfig = await readUserConfig();
|
|
338
|
-
const existing = userConfig.profiles[profileName] || {
|
|
339
|
-
registryUrl: DEFAULT_REGISTRY_URL
|
|
340
|
-
};
|
|
341
|
-
userConfig.profiles[profileName] = {
|
|
342
|
-
...existing,
|
|
343
|
-
...config2
|
|
344
|
-
};
|
|
345
|
-
await writeUserConfig(userConfig);
|
|
346
|
-
}
|
|
347
|
-
async function deleteProfile(profileName) {
|
|
348
|
-
const userConfig = await readUserConfig();
|
|
349
|
-
if (!userConfig.profiles[profileName]) {
|
|
350
|
-
return false;
|
|
401
|
+
async function setCredentials(authToken, username, registry) {
|
|
402
|
+
const config2 = await readUserConfig();
|
|
403
|
+
config2.authToken = authToken;
|
|
404
|
+
if (username) {
|
|
405
|
+
config2.username = username;
|
|
351
406
|
}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
const remainingProfiles = Object.keys(userConfig.profiles);
|
|
355
|
-
userConfig.defaultProfile = remainingProfiles[0] || "default";
|
|
407
|
+
if (registry && registry !== DEFAULT_REGISTRY_URL) {
|
|
408
|
+
config2.registry = registry;
|
|
356
409
|
}
|
|
357
|
-
await writeUserConfig(
|
|
358
|
-
return true;
|
|
410
|
+
await writeUserConfig(config2);
|
|
359
411
|
}
|
|
360
|
-
async function
|
|
361
|
-
const
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
userConfig.defaultProfile = profileName;
|
|
366
|
-
await writeUserConfig(userConfig);
|
|
412
|
+
async function clearCredentials() {
|
|
413
|
+
const config2 = await readUserConfig();
|
|
414
|
+
delete config2.authToken;
|
|
415
|
+
delete config2.username;
|
|
416
|
+
await writeUserConfig(config2);
|
|
367
417
|
}
|
|
368
|
-
async function
|
|
369
|
-
const userConfig = await readUserConfig();
|
|
370
|
-
return userConfig.defaultProfile;
|
|
371
|
-
}
|
|
372
|
-
({
|
|
373
|
-
registryUrl: process.env.PSPM_REGISTRY_URL || DEFAULT_REGISTRY_URL
|
|
374
|
-
});
|
|
375
|
-
async function isLoggedIn(globalOptions) {
|
|
418
|
+
async function isLoggedIn() {
|
|
376
419
|
try {
|
|
377
|
-
const resolved = await resolveConfig(
|
|
420
|
+
const resolved = await resolveConfig();
|
|
378
421
|
return !!resolved.apiKey;
|
|
379
422
|
} catch {
|
|
380
423
|
return false;
|
|
381
424
|
}
|
|
382
425
|
}
|
|
383
|
-
async function requireApiKey(
|
|
384
|
-
const resolved = await resolveConfig(
|
|
426
|
+
async function requireApiKey() {
|
|
427
|
+
const resolved = await resolveConfig();
|
|
385
428
|
if (!resolved.apiKey) {
|
|
386
429
|
if (process.env.PSPM_DEBUG) {
|
|
387
|
-
console.log(
|
|
388
|
-
`[config] requireApiKey: No API key found for profile "${resolved.profileName}"`
|
|
389
|
-
);
|
|
430
|
+
console.log(`[config] requireApiKey: No API key found`);
|
|
390
431
|
}
|
|
391
432
|
throw new NotLoggedInError();
|
|
392
433
|
}
|
|
393
434
|
if (process.env.PSPM_DEBUG) {
|
|
394
435
|
console.log(
|
|
395
|
-
`[config] requireApiKey: Got API key (${resolved.apiKey.substring(
|
|
396
|
-
0,
|
|
397
|
-
10
|
|
398
|
-
)}...)`
|
|
436
|
+
`[config] requireApiKey: Got API key (${resolved.apiKey.substring(0, 10)}...)`
|
|
399
437
|
);
|
|
400
438
|
}
|
|
401
439
|
return resolved.apiKey;
|
|
402
440
|
}
|
|
403
|
-
async function getRegistryUrl(
|
|
404
|
-
const resolved = await resolveConfig(
|
|
441
|
+
async function getRegistryUrl() {
|
|
442
|
+
const resolved = await resolveConfig();
|
|
405
443
|
return resolved.registryUrl;
|
|
406
444
|
}
|
|
407
|
-
async function clearProfileCredentials(profileName) {
|
|
408
|
-
const userConfig = await readUserConfig();
|
|
409
|
-
if (userConfig.profiles[profileName]) {
|
|
410
|
-
userConfig.profiles[profileName].apiKey = void 0;
|
|
411
|
-
userConfig.profiles[profileName].username = void 0;
|
|
412
|
-
await writeUserConfig(userConfig);
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
async function setProfileCredentials(profileName, apiKey, username, registryUrl) {
|
|
416
|
-
const userConfig = await readUserConfig();
|
|
417
|
-
if (!userConfig.profiles[profileName]) {
|
|
418
|
-
userConfig.profiles[profileName] = {
|
|
419
|
-
registryUrl: registryUrl || DEFAULT_REGISTRY_URL
|
|
420
|
-
};
|
|
421
|
-
}
|
|
422
|
-
userConfig.profiles[profileName].apiKey = apiKey;
|
|
423
|
-
if (username) {
|
|
424
|
-
userConfig.profiles[profileName].username = username;
|
|
425
|
-
}
|
|
426
|
-
if (registryUrl) {
|
|
427
|
-
userConfig.profiles[profileName].registryUrl = registryUrl;
|
|
428
|
-
}
|
|
429
|
-
await writeUserConfig(userConfig);
|
|
430
|
-
}
|
|
431
445
|
async function readLockfile() {
|
|
432
446
|
const lockfilePath = getLockfilePath();
|
|
433
447
|
try {
|
|
@@ -480,10 +494,10 @@ async function listLockfileSkills() {
|
|
|
480
494
|
}
|
|
481
495
|
|
|
482
496
|
// src/commands/add.ts
|
|
483
|
-
async function add(specifier, _options
|
|
497
|
+
async function add(specifier, _options) {
|
|
484
498
|
try {
|
|
485
|
-
const apiKey = await requireApiKey(
|
|
486
|
-
const registryUrl = await getRegistryUrl(
|
|
499
|
+
const apiKey = await requireApiKey();
|
|
500
|
+
const registryUrl = await getRegistryUrl();
|
|
487
501
|
const parsed = parseSkillSpecifier(specifier);
|
|
488
502
|
if (!parsed) {
|
|
489
503
|
console.error(
|
|
@@ -492,9 +506,18 @@ async function add(specifier, _options, globalOptions) {
|
|
|
492
506
|
process.exit(1);
|
|
493
507
|
}
|
|
494
508
|
const { username, name, versionRange } = parsed;
|
|
495
|
-
|
|
509
|
+
configure2({ registryUrl, apiKey });
|
|
496
510
|
console.log(`Resolving ${specifier}...`);
|
|
497
|
-
const
|
|
511
|
+
const versionsResponse = await listSkillVersions(username, name);
|
|
512
|
+
if (versionsResponse.status !== 200) {
|
|
513
|
+
const errorMessage = extractApiErrorMessage(
|
|
514
|
+
versionsResponse,
|
|
515
|
+
`Skill @user/${username}/${name} not found`
|
|
516
|
+
);
|
|
517
|
+
console.error(`Error: ${errorMessage}`);
|
|
518
|
+
process.exit(1);
|
|
519
|
+
}
|
|
520
|
+
const versions = versionsResponse.data;
|
|
498
521
|
if (versions.length === 0) {
|
|
499
522
|
console.error(`Error: Skill @user/${username}/${name} not found`);
|
|
500
523
|
process.exit(1);
|
|
@@ -509,15 +532,16 @@ async function add(specifier, _options, globalOptions) {
|
|
|
509
532
|
process.exit(1);
|
|
510
533
|
}
|
|
511
534
|
console.log(`Installing @user/${username}/${name}@${resolved}...`);
|
|
512
|
-
const
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
console.error(`Error:
|
|
535
|
+
const versionResponse = await getSkillVersion(username, name, resolved);
|
|
536
|
+
if (versionResponse.status !== 200 || !versionResponse.data) {
|
|
537
|
+
const errorMessage = extractApiErrorMessage(
|
|
538
|
+
versionResponse,
|
|
539
|
+
`Version ${resolved} not found`
|
|
540
|
+
);
|
|
541
|
+
console.error(`Error: ${errorMessage}`);
|
|
519
542
|
process.exit(1);
|
|
520
543
|
}
|
|
544
|
+
const versionInfo = versionResponse.data;
|
|
521
545
|
const downloadUrl = `${registryUrl}/@user/${username}/${name}/${resolved}/download`;
|
|
522
546
|
const tarballResponse = await fetch(downloadUrl, {
|
|
523
547
|
headers: {
|
|
@@ -571,68 +595,6 @@ async function add(specifier, _options, globalOptions) {
|
|
|
571
595
|
process.exit(1);
|
|
572
596
|
}
|
|
573
597
|
}
|
|
574
|
-
|
|
575
|
-
// src/commands/config/add.ts
|
|
576
|
-
async function configAdd(name, options) {
|
|
577
|
-
try {
|
|
578
|
-
const existing = await getProfile(name);
|
|
579
|
-
if (existing) {
|
|
580
|
-
console.error(`Error: Profile "${name}" already exists.`);
|
|
581
|
-
console.log("Use 'pspm config set' to modify it.");
|
|
582
|
-
process.exit(1);
|
|
583
|
-
}
|
|
584
|
-
await setProfile(name, {
|
|
585
|
-
registryUrl: options.registryUrl || "https://pspm.dev/api/skills"
|
|
586
|
-
});
|
|
587
|
-
console.log(`Created profile "${name}".`);
|
|
588
|
-
if (options.registryUrl) {
|
|
589
|
-
console.log(` Registry URL: ${options.registryUrl}`);
|
|
590
|
-
}
|
|
591
|
-
console.log("");
|
|
592
|
-
console.log(
|
|
593
|
-
`To set credentials, run: pspm login --api-key <key> --profile ${name}`
|
|
594
|
-
);
|
|
595
|
-
console.log(`To make this the default, run: pspm config use ${name}`);
|
|
596
|
-
} catch (error) {
|
|
597
|
-
const message = error instanceof Error ? error.message : "Unknown error";
|
|
598
|
-
console.error(`Error: ${message}`);
|
|
599
|
-
process.exit(1);
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
// src/commands/config/delete.ts
|
|
604
|
-
async function configDelete(name) {
|
|
605
|
-
try {
|
|
606
|
-
const profiles = await listProfiles();
|
|
607
|
-
const defaultProfile = await getDefaultProfileName();
|
|
608
|
-
if (!profiles.includes(name)) {
|
|
609
|
-
console.error(`Error: Profile "${name}" not found.`);
|
|
610
|
-
console.log("Run 'pspm config list' to see available profiles.");
|
|
611
|
-
process.exit(1);
|
|
612
|
-
}
|
|
613
|
-
if (profiles.length === 1) {
|
|
614
|
-
console.error("Error: Cannot delete the last profile.");
|
|
615
|
-
console.log("Create another profile first, then delete this one.");
|
|
616
|
-
process.exit(1);
|
|
617
|
-
}
|
|
618
|
-
const wasDefault = name === defaultProfile;
|
|
619
|
-
const success = await deleteProfile(name);
|
|
620
|
-
if (success) {
|
|
621
|
-
console.log(`Deleted profile "${name}".`);
|
|
622
|
-
if (wasDefault) {
|
|
623
|
-
const newDefault = await getDefaultProfileName();
|
|
624
|
-
console.log(`Default profile is now "${newDefault}".`);
|
|
625
|
-
}
|
|
626
|
-
} else {
|
|
627
|
-
console.error(`Error: Failed to delete profile "${name}".`);
|
|
628
|
-
process.exit(1);
|
|
629
|
-
}
|
|
630
|
-
} catch (error) {
|
|
631
|
-
const message = error instanceof Error ? error.message : "Unknown error";
|
|
632
|
-
console.error(`Error: ${message}`);
|
|
633
|
-
process.exit(1);
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
598
|
async function configInit(options) {
|
|
637
599
|
try {
|
|
638
600
|
const configPath = join(process.cwd(), ".pspmrc");
|
|
@@ -642,23 +604,19 @@ async function configInit(options) {
|
|
|
642
604
|
process.exit(1);
|
|
643
605
|
} catch {
|
|
644
606
|
}
|
|
645
|
-
const
|
|
646
|
-
if (options.
|
|
647
|
-
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
}
|
|
652
|
-
if (Object.keys(config2).length === 0) {
|
|
653
|
-
config2.profile = "development";
|
|
607
|
+
const lines = ["; Project-specific PSPM configuration", ""];
|
|
608
|
+
if (options.registry) {
|
|
609
|
+
lines.push(`registry = ${options.registry}`);
|
|
610
|
+
} else {
|
|
611
|
+
lines.push("; Uncomment to use a custom registry:");
|
|
612
|
+
lines.push("; registry = https://custom-registry.example.com");
|
|
654
613
|
}
|
|
655
|
-
|
|
656
|
-
|
|
614
|
+
lines.push("");
|
|
615
|
+
await writeFile(configPath, lines.join("\n"));
|
|
657
616
|
console.log("Created .pspmrc");
|
|
658
617
|
console.log("");
|
|
659
618
|
console.log("Contents:");
|
|
660
|
-
console.log(
|
|
661
|
-
console.log("");
|
|
619
|
+
console.log(lines.join("\n"));
|
|
662
620
|
console.log("Note: .pspmrc should be committed to version control.");
|
|
663
621
|
console.log("API keys should NOT be stored here - use pspm login instead.");
|
|
664
622
|
} catch (error) {
|
|
@@ -668,129 +626,38 @@ async function configInit(options) {
|
|
|
668
626
|
}
|
|
669
627
|
}
|
|
670
628
|
|
|
671
|
-
// src/commands/config/list.ts
|
|
672
|
-
async function configList() {
|
|
673
|
-
try {
|
|
674
|
-
const profiles = await listProfiles();
|
|
675
|
-
const defaultProfile = await getDefaultProfileName();
|
|
676
|
-
if (profiles.length === 0) {
|
|
677
|
-
console.log("No profiles configured.");
|
|
678
|
-
console.log("Run 'pspm config add <name>' to create one.");
|
|
679
|
-
return;
|
|
680
|
-
}
|
|
681
|
-
console.log("Profiles:\n");
|
|
682
|
-
for (const name of profiles) {
|
|
683
|
-
const marker = name === defaultProfile ? " (default)" : "";
|
|
684
|
-
console.log(` ${name}${marker}`);
|
|
685
|
-
}
|
|
686
|
-
console.log("");
|
|
687
|
-
} catch (error) {
|
|
688
|
-
const message = error instanceof Error ? error.message : "Unknown error";
|
|
689
|
-
console.error(`Error: ${message}`);
|
|
690
|
-
process.exit(1);
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
// src/commands/config/set.ts
|
|
695
|
-
var VALID_KEYS = ["registryUrl", "apiKey", "username"];
|
|
696
|
-
async function configSet(profile, key, value) {
|
|
697
|
-
try {
|
|
698
|
-
if (!VALID_KEYS.includes(key)) {
|
|
699
|
-
console.error(`Error: Invalid key "${key}".`);
|
|
700
|
-
console.log(`Valid keys: ${VALID_KEYS.join(", ")}`);
|
|
701
|
-
process.exit(1);
|
|
702
|
-
}
|
|
703
|
-
const existing = await getProfile(profile);
|
|
704
|
-
if (!existing) {
|
|
705
|
-
console.error(`Error: Profile "${profile}" not found.`);
|
|
706
|
-
console.log("Run 'pspm config add' to create it first.");
|
|
707
|
-
process.exit(1);
|
|
708
|
-
}
|
|
709
|
-
await setProfile(profile, { [key]: value });
|
|
710
|
-
console.log(`Updated ${key} for profile "${profile}".`);
|
|
711
|
-
} catch (error) {
|
|
712
|
-
const message = error instanceof Error ? error.message : "Unknown error";
|
|
713
|
-
console.error(`Error: ${message}`);
|
|
714
|
-
process.exit(1);
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
|
|
718
629
|
// src/commands/config/show.ts
|
|
719
|
-
async function configShow(
|
|
720
|
-
try {
|
|
721
|
-
if (options.name) {
|
|
722
|
-
const profile = await getProfile(options.name);
|
|
723
|
-
if (!profile) {
|
|
724
|
-
console.error(`Error: Profile "${options.name}" not found.`);
|
|
725
|
-
console.log("Run 'pspm config list' to see available profiles.");
|
|
726
|
-
process.exit(1);
|
|
727
|
-
}
|
|
728
|
-
const defaultProfile = await getDefaultProfileName();
|
|
729
|
-
const isDefault = options.name === defaultProfile;
|
|
730
|
-
console.log(`Profile: ${options.name}${isDefault ? " (default)" : ""}
|
|
731
|
-
`);
|
|
732
|
-
console.log(` Registry URL: ${profile.registryUrl}`);
|
|
733
|
-
console.log(` API Key: ${profile.apiKey ? "***" : "(not set)"}`);
|
|
734
|
-
console.log(` Username: ${profile.username || "(not set)"}`);
|
|
735
|
-
} else {
|
|
736
|
-
const resolved = await resolveConfig(globalOptions);
|
|
737
|
-
const projectConfig = await findProjectConfig();
|
|
738
|
-
const configPath = getConfigPath();
|
|
739
|
-
console.log("Resolved Configuration:\n");
|
|
740
|
-
console.log(` Active Profile: ${resolved.profileName}`);
|
|
741
|
-
console.log(` Profile Source: ${formatSource(resolved.profileSource)}`);
|
|
742
|
-
console.log(` Registry URL: ${resolved.registryUrl}`);
|
|
743
|
-
console.log(` API Key: ${resolved.apiKey ? "***" : "(not set)"}`);
|
|
744
|
-
console.log(` Username: ${resolved.username || "(not set)"}`);
|
|
745
|
-
console.log("");
|
|
746
|
-
console.log("Config Locations:");
|
|
747
|
-
console.log(` User config: ${configPath}`);
|
|
748
|
-
console.log(` Project config: ${projectConfig ? ".pspmrc" : "(none)"}`);
|
|
749
|
-
}
|
|
750
|
-
} catch (error) {
|
|
751
|
-
const message = error instanceof Error ? error.message : "Unknown error";
|
|
752
|
-
console.error(`Error: ${message}`);
|
|
753
|
-
process.exit(1);
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
function formatSource(source) {
|
|
757
|
-
switch (source) {
|
|
758
|
-
case "cli":
|
|
759
|
-
return "--profile flag";
|
|
760
|
-
case "env":
|
|
761
|
-
return "PSPM_PROFILE env var";
|
|
762
|
-
case "project":
|
|
763
|
-
return ".pspmrc file";
|
|
764
|
-
case "user":
|
|
765
|
-
return "user config default";
|
|
766
|
-
case "default":
|
|
767
|
-
return "fallback default";
|
|
768
|
-
default:
|
|
769
|
-
return source;
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
|
|
773
|
-
// src/commands/config/use.ts
|
|
774
|
-
async function configUse(name) {
|
|
630
|
+
async function configShow() {
|
|
775
631
|
try {
|
|
776
|
-
const
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
console.log(
|
|
632
|
+
const resolved = await resolveConfig();
|
|
633
|
+
const projectConfig = await findProjectConfig();
|
|
634
|
+
const configPath = getConfigPath();
|
|
635
|
+
console.log("Resolved Configuration:\n");
|
|
636
|
+
console.log(` Registry URL: ${resolved.registryUrl}`);
|
|
637
|
+
console.log(` API Key: ${resolved.apiKey ? "***" : "(not set)"}`);
|
|
638
|
+
console.log(` Username: ${resolved.username || "(not set)"}`);
|
|
639
|
+
console.log("");
|
|
640
|
+
console.log("Config Locations:");
|
|
641
|
+
console.log(` User config: ${configPath}`);
|
|
642
|
+
console.log(` Project config: ${projectConfig ? ".pspmrc" : "(none)"}`);
|
|
643
|
+
console.log("");
|
|
644
|
+
console.log("Environment Variables:");
|
|
645
|
+
console.log(
|
|
646
|
+
` PSPM_REGISTRY_URL: ${process.env.PSPM_REGISTRY_URL || "(not set)"}`
|
|
647
|
+
);
|
|
648
|
+
console.log(
|
|
649
|
+
` PSPM_API_KEY: ${process.env.PSPM_API_KEY ? "***" : "(not set)"}`
|
|
650
|
+
);
|
|
784
651
|
} catch (error) {
|
|
785
652
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
786
653
|
console.error(`Error: ${message}`);
|
|
787
654
|
process.exit(1);
|
|
788
655
|
}
|
|
789
656
|
}
|
|
790
|
-
async function install(options
|
|
657
|
+
async function install(options) {
|
|
791
658
|
try {
|
|
792
|
-
const apiKey = await requireApiKey(
|
|
793
|
-
await getRegistryUrl(
|
|
659
|
+
const apiKey = await requireApiKey();
|
|
660
|
+
await getRegistryUrl();
|
|
794
661
|
const skillsDir = options.dir || getSkillsDir();
|
|
795
662
|
const lockfile = await readLockfile();
|
|
796
663
|
if (!lockfile) {
|
|
@@ -832,8 +699,8 @@ async function install(options, globalOptions) {
|
|
|
832
699
|
continue;
|
|
833
700
|
}
|
|
834
701
|
const tarballBuffer = Buffer.from(await response.arrayBuffer());
|
|
835
|
-
const { createHash:
|
|
836
|
-
const actualIntegrity = `sha256-${
|
|
702
|
+
const { createHash: createHash3 } = await import('crypto');
|
|
703
|
+
const actualIntegrity = `sha256-${createHash3("sha256").update(tarballBuffer).digest("base64")}`;
|
|
837
704
|
if (actualIntegrity !== entry.integrity) {
|
|
838
705
|
console.error(` Error: Checksum verification failed for ${fullName}`);
|
|
839
706
|
if (options.frozenLockfile) {
|
|
@@ -924,9 +791,9 @@ function getServerUrl(registryUrl) {
|
|
|
924
791
|
return DEFAULT_WEB_APP_URL;
|
|
925
792
|
}
|
|
926
793
|
}
|
|
927
|
-
async function
|
|
794
|
+
async function exchangeCliToken2(registryUrl, token) {
|
|
928
795
|
const serverUrl = getServerUrl(registryUrl);
|
|
929
|
-
const rpcUrl = `${serverUrl}/api/api-keys/
|
|
796
|
+
const rpcUrl = `${serverUrl}/api/api-keys/cli-token-exchange`;
|
|
930
797
|
const response = await fetch(rpcUrl, {
|
|
931
798
|
method: "POST",
|
|
932
799
|
headers: {
|
|
@@ -1030,9 +897,8 @@ function startCallbackServer(expectedState) {
|
|
|
1030
897
|
);
|
|
1031
898
|
});
|
|
1032
899
|
}
|
|
1033
|
-
async function browserLogin(
|
|
1034
|
-
const
|
|
1035
|
-
const registryUrl = await getRegistryUrl(globalOptions);
|
|
900
|
+
async function browserLogin() {
|
|
901
|
+
const registryUrl = await getRegistryUrl();
|
|
1036
902
|
const webAppUrl = getWebAppUrl(registryUrl);
|
|
1037
903
|
const state = randomBytes(32).toString("base64url");
|
|
1038
904
|
console.log("Starting browser-based login...");
|
|
@@ -1050,42 +916,29 @@ async function browserLogin(globalOptions) {
|
|
|
1050
916
|
const token = await tokenPromise;
|
|
1051
917
|
cleanup();
|
|
1052
918
|
console.log("Received token, exchanging for API key...");
|
|
1053
|
-
const { apiKey, username } = await
|
|
1054
|
-
await
|
|
1055
|
-
resolved.profileName,
|
|
1056
|
-
apiKey,
|
|
1057
|
-
username,
|
|
1058
|
-
registryUrl
|
|
1059
|
-
);
|
|
919
|
+
const { apiKey, username } = await exchangeCliToken2(registryUrl, token);
|
|
920
|
+
await setCredentials(apiKey, username, registryUrl);
|
|
1060
921
|
console.log(`Logged in as ${username}`);
|
|
1061
|
-
console.log(`Profile: ${resolved.profileName}`);
|
|
1062
922
|
console.log(`Registry: ${registryUrl}`);
|
|
1063
923
|
}
|
|
1064
|
-
async function directLogin(apiKey
|
|
924
|
+
async function directLogin(apiKey) {
|
|
1065
925
|
console.log("Verifying API key...");
|
|
1066
|
-
const
|
|
1067
|
-
const registryUrl = await getRegistryUrl(globalOptions);
|
|
926
|
+
const registryUrl = await getRegistryUrl();
|
|
1068
927
|
const user = await whoamiRequest(registryUrl, apiKey);
|
|
1069
928
|
if (!user) {
|
|
1070
929
|
console.error("Error: Invalid API key or not authenticated");
|
|
1071
930
|
process.exit(1);
|
|
1072
931
|
}
|
|
1073
|
-
await
|
|
1074
|
-
resolved.profileName,
|
|
1075
|
-
apiKey,
|
|
1076
|
-
user.username,
|
|
1077
|
-
registryUrl
|
|
1078
|
-
);
|
|
932
|
+
await setCredentials(apiKey, user.username, registryUrl);
|
|
1079
933
|
console.log(`Logged in as ${user.username}`);
|
|
1080
|
-
console.log(`Profile: ${resolved.profileName}`);
|
|
1081
934
|
console.log(`Registry: ${registryUrl}`);
|
|
1082
935
|
}
|
|
1083
|
-
async function login(options
|
|
936
|
+
async function login(options) {
|
|
1084
937
|
try {
|
|
1085
938
|
if (options.apiKey) {
|
|
1086
|
-
await directLogin(options.apiKey
|
|
939
|
+
await directLogin(options.apiKey);
|
|
1087
940
|
} else {
|
|
1088
|
-
await browserLogin(
|
|
941
|
+
await browserLogin();
|
|
1089
942
|
}
|
|
1090
943
|
} catch (error) {
|
|
1091
944
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
@@ -1095,16 +948,15 @@ async function login(options, globalOptions) {
|
|
|
1095
948
|
}
|
|
1096
949
|
|
|
1097
950
|
// src/commands/logout.ts
|
|
1098
|
-
async function logout(
|
|
951
|
+
async function logout() {
|
|
1099
952
|
try {
|
|
1100
|
-
const
|
|
1101
|
-
const loggedIn = await isLoggedIn(globalOptions);
|
|
953
|
+
const loggedIn = await isLoggedIn();
|
|
1102
954
|
if (!loggedIn) {
|
|
1103
|
-
console.log(
|
|
955
|
+
console.log("Not logged in.");
|
|
1104
956
|
return;
|
|
1105
957
|
}
|
|
1106
|
-
await
|
|
1107
|
-
console.log(
|
|
958
|
+
await clearCredentials();
|
|
959
|
+
console.log("Logged out successfully.");
|
|
1108
960
|
} catch (error) {
|
|
1109
961
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
1110
962
|
console.error(`Error: ${message}`);
|
|
@@ -1112,10 +964,37 @@ async function logout(globalOptions) {
|
|
|
1112
964
|
}
|
|
1113
965
|
}
|
|
1114
966
|
var exec = promisify(exec$1);
|
|
1115
|
-
|
|
967
|
+
function formatBytes(bytes) {
|
|
968
|
+
if (bytes < 1024) return `${bytes}B`;
|
|
969
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}kB`;
|
|
970
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
971
|
+
}
|
|
972
|
+
async function getFilesWithSizes(dir, baseDir) {
|
|
973
|
+
const results = [];
|
|
1116
974
|
try {
|
|
1117
|
-
const
|
|
1118
|
-
const
|
|
975
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
976
|
+
for (const entry of entries) {
|
|
977
|
+
const fullPath = join(dir, entry.name);
|
|
978
|
+
const relativePath = relative(baseDir, fullPath);
|
|
979
|
+
if (entry.name === "node_modules" || entry.name === ".git") {
|
|
980
|
+
continue;
|
|
981
|
+
}
|
|
982
|
+
if (entry.isDirectory()) {
|
|
983
|
+
const subFiles = await getFilesWithSizes(fullPath, baseDir);
|
|
984
|
+
results.push(...subFiles);
|
|
985
|
+
} else {
|
|
986
|
+
const fileStat = await stat(fullPath);
|
|
987
|
+
results.push({ path: relativePath, size: fileStat.size });
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
} catch {
|
|
991
|
+
}
|
|
992
|
+
return results;
|
|
993
|
+
}
|
|
994
|
+
async function publishCommand(options) {
|
|
995
|
+
try {
|
|
996
|
+
const apiKey = await requireApiKey();
|
|
997
|
+
const registryUrl = await getRegistryUrl();
|
|
1119
998
|
const packageJsonPath = join(process.cwd(), "package.json");
|
|
1120
999
|
let packageJson2;
|
|
1121
1000
|
try {
|
|
@@ -1145,8 +1024,6 @@ async function publishCommand(options, globalOptions) {
|
|
|
1145
1024
|
packageJson2.version = newVersion;
|
|
1146
1025
|
console.log(`Bumped version to ${newVersion}`);
|
|
1147
1026
|
}
|
|
1148
|
-
console.log(`Registry: ${registryUrl}`);
|
|
1149
|
-
console.log(`Publishing ${packageJson2.name}@${packageJson2.version}...`);
|
|
1150
1027
|
const safeName = packageJson2.name.replace(/[@/]/g, "-").replace(/^-+/, "");
|
|
1151
1028
|
const tarballName = `${safeName}-${packageJson2.version}.tgz`;
|
|
1152
1029
|
const tempDir = join(process.cwd(), ".pspm-publish");
|
|
@@ -1169,20 +1046,60 @@ async function publishCommand(options, globalOptions) {
|
|
|
1169
1046
|
}
|
|
1170
1047
|
}
|
|
1171
1048
|
await exec(`cp package.json "${tempDir}/package/"`);
|
|
1049
|
+
const packageDir = join(tempDir, "package");
|
|
1050
|
+
const tarballContents = await getFilesWithSizes(packageDir, packageDir);
|
|
1051
|
+
const unpackedSize = tarballContents.reduce((acc, f) => acc + f.size, 0);
|
|
1172
1052
|
const tarballPath = join(tempDir, tarballName);
|
|
1173
1053
|
await exec(
|
|
1174
1054
|
`tar -czf "${tarballPath}" -C "${tempDir}" --exclude='node_modules' --exclude='.git' package`
|
|
1175
1055
|
);
|
|
1176
1056
|
const tarballBuffer = await readFile(tarballPath);
|
|
1177
1057
|
const tarballBase64 = tarballBuffer.toString("base64");
|
|
1178
|
-
|
|
1179
|
-
const
|
|
1058
|
+
const tarballSize = tarballBuffer.length;
|
|
1059
|
+
const shasum = createHash("sha1").update(tarballBuffer).digest("hex");
|
|
1060
|
+
const integrityHash = createHash("sha512").update(tarballBuffer).digest("base64");
|
|
1061
|
+
const integrity = `sha512-${integrityHash}`;
|
|
1062
|
+
console.log("");
|
|
1063
|
+
console.log(`pspm notice`);
|
|
1064
|
+
console.log(`pspm notice \u{1F4E6} ${packageJson2.name}@${packageJson2.version}`);
|
|
1065
|
+
console.log(`pspm notice Tarball Contents`);
|
|
1066
|
+
tarballContents.sort((a, b) => b.size - a.size);
|
|
1067
|
+
for (const file of tarballContents) {
|
|
1068
|
+
console.log(
|
|
1069
|
+
`pspm notice ${formatBytes(file.size).padStart(8)} ${file.path}`
|
|
1070
|
+
);
|
|
1071
|
+
}
|
|
1072
|
+
console.log(`pspm notice Tarball Details`);
|
|
1073
|
+
console.log(`pspm notice name: ${packageJson2.name}`);
|
|
1074
|
+
console.log(`pspm notice version: ${packageJson2.version}`);
|
|
1075
|
+
console.log(`pspm notice filename: ${tarballName}`);
|
|
1076
|
+
console.log(`pspm notice package size: ${formatBytes(tarballSize)}`);
|
|
1077
|
+
console.log(`pspm notice unpacked size: ${formatBytes(unpackedSize)}`);
|
|
1078
|
+
console.log(`pspm notice shasum: ${shasum}`);
|
|
1079
|
+
console.log(
|
|
1080
|
+
`pspm notice integrity: ${integrity.substring(0, 50)}...`
|
|
1081
|
+
);
|
|
1082
|
+
console.log(`pspm notice total files: ${tarballContents.length}`);
|
|
1083
|
+
console.log(`pspm notice`);
|
|
1084
|
+
console.log(`pspm notice Publishing to ${registryUrl} with tag latest`);
|
|
1085
|
+
configure2({ registryUrl, apiKey });
|
|
1086
|
+
const response = await publishSkill({
|
|
1180
1087
|
manifest: packageJson2,
|
|
1181
1088
|
tarballBase64
|
|
1182
1089
|
});
|
|
1090
|
+
if (response.status !== 200) {
|
|
1091
|
+
const errorMessage = extractApiErrorMessage(response, "Publish failed");
|
|
1092
|
+
if (errorMessage.includes("must be greater than") || errorMessage.includes("already exists")) {
|
|
1093
|
+
console.error(`pspm error code E403`);
|
|
1094
|
+
console.error(
|
|
1095
|
+
`pspm error 403 403 Forbidden - You cannot publish over the previously published versions: ${packageJson2.version}.`
|
|
1096
|
+
);
|
|
1097
|
+
}
|
|
1098
|
+
throw new Error(errorMessage);
|
|
1099
|
+
}
|
|
1100
|
+
const result = response.data;
|
|
1183
1101
|
console.log(
|
|
1184
|
-
`
|
|
1185
|
-
Published @user/${result.skill.username}/${result.skill.name}@${result.version.version}`
|
|
1102
|
+
`+ @user/${result.skill.username}/${result.skill.name}@${result.version.version}`
|
|
1186
1103
|
);
|
|
1187
1104
|
console.log(`Checksum: ${result.version.checksum}`);
|
|
1188
1105
|
} finally {
|
|
@@ -1192,37 +1109,9 @@ Published @user/${result.skill.username}/${result.skill.name}@${result.version.v
|
|
|
1192
1109
|
} catch (error) {
|
|
1193
1110
|
if (error instanceof Error) {
|
|
1194
1111
|
console.error(`Error: ${error.message}`);
|
|
1195
|
-
const anyError = error;
|
|
1196
|
-
if (anyError.cause?.response) {
|
|
1197
|
-
try {
|
|
1198
|
-
const text = await anyError.cause.response.text();
|
|
1199
|
-
console.error(`Response body: ${text}`);
|
|
1200
|
-
} catch {
|
|
1201
|
-
}
|
|
1202
|
-
}
|
|
1203
|
-
if (anyError.cause?.body) {
|
|
1204
|
-
console.error(
|
|
1205
|
-
`Cause body: ${JSON.stringify(anyError.cause.body, null, 2)}`
|
|
1206
|
-
);
|
|
1207
|
-
}
|
|
1208
|
-
if (anyError.body) {
|
|
1209
|
-
console.error(`Error body: ${JSON.stringify(anyError.body, null, 2)}`);
|
|
1210
|
-
}
|
|
1211
|
-
if (anyError.data) {
|
|
1212
|
-
console.error(`Error data: ${JSON.stringify(anyError.data, null, 2)}`);
|
|
1213
|
-
}
|
|
1214
|
-
if (process.env.PSPM_DEBUG) {
|
|
1215
|
-
console.error("\nFull error details:");
|
|
1216
|
-
console.error(error);
|
|
1217
|
-
if (error.stack) {
|
|
1218
|
-
console.error("\nStack trace:");
|
|
1219
|
-
console.error(error.stack);
|
|
1220
|
-
}
|
|
1221
|
-
}
|
|
1222
1112
|
} else {
|
|
1223
1113
|
console.error(`Error: ${String(error)}`);
|
|
1224
1114
|
}
|
|
1225
|
-
console.error("\nTip: Set PSPM_DEBUG=1 for more detailed error output");
|
|
1226
1115
|
process.exit(1);
|
|
1227
1116
|
}
|
|
1228
1117
|
}
|
|
@@ -1283,10 +1172,10 @@ async function remove(nameOrSpecifier) {
|
|
|
1283
1172
|
}
|
|
1284
1173
|
|
|
1285
1174
|
// src/commands/unpublish.ts
|
|
1286
|
-
async function unpublish(specifier, options
|
|
1175
|
+
async function unpublish(specifier, options) {
|
|
1287
1176
|
try {
|
|
1288
|
-
const apiKey = await requireApiKey(
|
|
1289
|
-
const registryUrl = await getRegistryUrl(
|
|
1177
|
+
const apiKey = await requireApiKey();
|
|
1178
|
+
const registryUrl = await getRegistryUrl();
|
|
1290
1179
|
const parsed = parseSkillSpecifier(specifier);
|
|
1291
1180
|
if (!parsed) {
|
|
1292
1181
|
console.error(
|
|
@@ -1295,7 +1184,7 @@ async function unpublish(specifier, options, globalOptions) {
|
|
|
1295
1184
|
process.exit(1);
|
|
1296
1185
|
}
|
|
1297
1186
|
const { username, name, versionRange } = parsed;
|
|
1298
|
-
|
|
1187
|
+
configure2({ registryUrl, apiKey });
|
|
1299
1188
|
if (versionRange) {
|
|
1300
1189
|
console.log(`Unpublishing ${specifier}...`);
|
|
1301
1190
|
if (!options.force) {
|
|
@@ -1304,16 +1193,16 @@ async function unpublish(specifier, options, globalOptions) {
|
|
|
1304
1193
|
);
|
|
1305
1194
|
process.exit(1);
|
|
1306
1195
|
}
|
|
1307
|
-
const
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
console.error(`Error: Failed to unpublish. Version may not exist.`);
|
|
1196
|
+
const response = await deleteSkillVersion(name, versionRange);
|
|
1197
|
+
if (response.status !== 200) {
|
|
1198
|
+
const errorMessage = extractApiErrorMessage(
|
|
1199
|
+
response,
|
|
1200
|
+
"Failed to unpublish. Version may not exist."
|
|
1201
|
+
);
|
|
1202
|
+
console.error(`Error: ${errorMessage}`);
|
|
1315
1203
|
process.exit(1);
|
|
1316
1204
|
}
|
|
1205
|
+
console.log(`Unpublished @user/${username}/${name}@${versionRange}`);
|
|
1317
1206
|
} else {
|
|
1318
1207
|
console.log(`Unpublishing all versions of @user/${username}/${name}...`);
|
|
1319
1208
|
if (!options.force) {
|
|
@@ -1322,13 +1211,16 @@ async function unpublish(specifier, options, globalOptions) {
|
|
|
1322
1211
|
);
|
|
1323
1212
|
process.exit(1);
|
|
1324
1213
|
}
|
|
1325
|
-
const
|
|
1326
|
-
if (
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1214
|
+
const response = await deleteSkill(name);
|
|
1215
|
+
if (response.status !== 200) {
|
|
1216
|
+
const errorMessage = extractApiErrorMessage(
|
|
1217
|
+
response,
|
|
1218
|
+
"Failed to unpublish. Skill may not exist."
|
|
1219
|
+
);
|
|
1220
|
+
console.error(`Error: ${errorMessage}`);
|
|
1330
1221
|
process.exit(1);
|
|
1331
1222
|
}
|
|
1223
|
+
console.log(`Unpublished @user/${username}/${name} (all versions)`);
|
|
1332
1224
|
}
|
|
1333
1225
|
} catch (error) {
|
|
1334
1226
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
@@ -1338,16 +1230,16 @@ async function unpublish(specifier, options, globalOptions) {
|
|
|
1338
1230
|
}
|
|
1339
1231
|
|
|
1340
1232
|
// src/commands/update.ts
|
|
1341
|
-
async function update(options
|
|
1233
|
+
async function update(options) {
|
|
1342
1234
|
try {
|
|
1343
|
-
const apiKey = await requireApiKey(
|
|
1344
|
-
const registryUrl = await getRegistryUrl(
|
|
1235
|
+
const apiKey = await requireApiKey();
|
|
1236
|
+
const registryUrl = await getRegistryUrl();
|
|
1345
1237
|
const skills = await listLockfileSkills();
|
|
1346
1238
|
if (skills.length === 0) {
|
|
1347
1239
|
console.log("No skills installed.");
|
|
1348
1240
|
return;
|
|
1349
1241
|
}
|
|
1350
|
-
|
|
1242
|
+
configure2({ registryUrl, apiKey });
|
|
1351
1243
|
const updates = [];
|
|
1352
1244
|
console.log("Checking for updates...\n");
|
|
1353
1245
|
for (const { name, entry } of skills) {
|
|
@@ -1355,10 +1247,16 @@ async function update(options, globalOptions) {
|
|
|
1355
1247
|
if (!match) continue;
|
|
1356
1248
|
const [, username, skillName] = match;
|
|
1357
1249
|
try {
|
|
1358
|
-
const
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1250
|
+
const versionsResponse = await listSkillVersions(username, skillName);
|
|
1251
|
+
if (versionsResponse.status !== 200) {
|
|
1252
|
+
const errorMessage = extractApiErrorMessage(
|
|
1253
|
+
versionsResponse,
|
|
1254
|
+
"Failed to fetch versions"
|
|
1255
|
+
);
|
|
1256
|
+
console.warn(` Warning: ${name}: ${errorMessage}`);
|
|
1257
|
+
continue;
|
|
1258
|
+
}
|
|
1259
|
+
const versions = versionsResponse.data;
|
|
1362
1260
|
if (versions.length === 0) continue;
|
|
1363
1261
|
const versionStrings = versions.map(
|
|
1364
1262
|
(v) => v.version
|
|
@@ -1393,7 +1291,7 @@ async function update(options, globalOptions) {
|
|
|
1393
1291
|
if (!match) continue;
|
|
1394
1292
|
const [, username, skillName] = match;
|
|
1395
1293
|
const specifier = `@user/${username}/${skillName}@${latest}`;
|
|
1396
|
-
await add(specifier, {}
|
|
1294
|
+
await add(specifier, {});
|
|
1397
1295
|
}
|
|
1398
1296
|
console.log("\nAll skills updated.");
|
|
1399
1297
|
} catch (error) {
|
|
@@ -1404,21 +1302,19 @@ async function update(options, globalOptions) {
|
|
|
1404
1302
|
}
|
|
1405
1303
|
|
|
1406
1304
|
// src/commands/whoami.ts
|
|
1407
|
-
async function whoami(
|
|
1305
|
+
async function whoami() {
|
|
1408
1306
|
try {
|
|
1409
|
-
const resolved = await resolveConfig(
|
|
1410
|
-
const apiKey = await requireApiKey(
|
|
1411
|
-
const registryUrl = await getRegistryUrl(
|
|
1307
|
+
const resolved = await resolveConfig();
|
|
1308
|
+
const apiKey = await requireApiKey();
|
|
1309
|
+
const registryUrl = await getRegistryUrl();
|
|
1412
1310
|
const user = await whoamiRequest(registryUrl, apiKey);
|
|
1413
1311
|
if (user) {
|
|
1414
1312
|
console.log(`Username: ${user.username}`);
|
|
1415
1313
|
console.log(`User ID: ${user.userId}`);
|
|
1416
1314
|
console.log(`Registry: ${registryUrl}`);
|
|
1417
|
-
console.log(`Profile: ${resolved.profileName}`);
|
|
1418
1315
|
} else if (resolved.username) {
|
|
1419
1316
|
console.log(`Username: ${resolved.username} (cached)`);
|
|
1420
1317
|
console.log(`Registry: ${registryUrl}`);
|
|
1421
|
-
console.log(`Profile: ${resolved.profileName}`);
|
|
1422
1318
|
} else {
|
|
1423
1319
|
console.error("Could not determine current user.");
|
|
1424
1320
|
process.exit(1);
|
|
@@ -1437,61 +1333,30 @@ var packageJson = JSON.parse(
|
|
|
1437
1333
|
);
|
|
1438
1334
|
var version = packageJson.version;
|
|
1439
1335
|
var program = new Command();
|
|
1440
|
-
program.name("pspm").description("Prompt Skill Package Manager for AnyT").version(version)
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
current = current.parent;
|
|
1445
|
-
}
|
|
1446
|
-
const opts = current.opts();
|
|
1447
|
-
return {
|
|
1448
|
-
profile: opts.profile
|
|
1449
|
-
};
|
|
1450
|
-
}
|
|
1451
|
-
var configCmd = program.command("config").description("Manage PSPM configuration and profiles");
|
|
1452
|
-
configCmd.command("list").description("List all profiles").action(async () => {
|
|
1453
|
-
await configList();
|
|
1454
|
-
});
|
|
1455
|
-
configCmd.command("show [name]").description("Show resolved config or a specific profile").action(async (name, _options, cmd) => {
|
|
1456
|
-
const globalOptions = getGlobalOptions(cmd);
|
|
1457
|
-
await configShow({ name }, globalOptions);
|
|
1458
|
-
});
|
|
1459
|
-
configCmd.command("add <name>").description("Create a new profile").option("--registry-url <url>", "Registry URL for the profile").action(async (name, options) => {
|
|
1460
|
-
await configAdd(name, { registryUrl: options.registryUrl });
|
|
1461
|
-
});
|
|
1462
|
-
configCmd.command("use <name>").description("Set the default profile").action(async (name) => {
|
|
1463
|
-
await configUse(name);
|
|
1464
|
-
});
|
|
1465
|
-
configCmd.command("set <profile> <key> <value>").description("Set a profile field (registryUrl, apiKey, username)").action(async (profile, key, value) => {
|
|
1466
|
-
await configSet(profile, key, value);
|
|
1336
|
+
program.name("pspm").description("Prompt Skill Package Manager for AnyT").version(version);
|
|
1337
|
+
var configCmd = program.command("config").description("Manage PSPM configuration");
|
|
1338
|
+
configCmd.command("show").description("Show resolved configuration").action(async () => {
|
|
1339
|
+
await configShow();
|
|
1467
1340
|
});
|
|
1468
|
-
configCmd.command("
|
|
1469
|
-
await configDelete(name);
|
|
1470
|
-
});
|
|
1471
|
-
configCmd.command("init").description("Create a .pspmrc file in the current directory").option("--profile <name>", "Profile to use for this project").option("--registry-url <url>", "Registry URL override").action(async (options) => {
|
|
1341
|
+
configCmd.command("init").description("Create a .pspmrc file in the current directory").option("--registry <url>", "Registry URL override").action(async (options) => {
|
|
1472
1342
|
await configInit({
|
|
1473
|
-
|
|
1474
|
-
registryUrl: options.registryUrl
|
|
1343
|
+
registry: options.registry
|
|
1475
1344
|
});
|
|
1476
1345
|
});
|
|
1477
1346
|
program.command("login").description("Log in via browser or with an API key").option(
|
|
1478
1347
|
"--api-key <key>",
|
|
1479
1348
|
"API key for direct authentication (skips browser)"
|
|
1480
|
-
).action(async (options
|
|
1481
|
-
|
|
1482
|
-
await login({ apiKey: options.apiKey }, globalOptions);
|
|
1349
|
+
).action(async (options) => {
|
|
1350
|
+
await login({ apiKey: options.apiKey });
|
|
1483
1351
|
});
|
|
1484
|
-
program.command("logout").description("Log out and clear stored credentials").action(async (
|
|
1485
|
-
|
|
1486
|
-
await logout(globalOptions);
|
|
1352
|
+
program.command("logout").description("Log out and clear stored credentials").action(async () => {
|
|
1353
|
+
await logout();
|
|
1487
1354
|
});
|
|
1488
|
-
program.command("whoami").description("Show current user information").action(async (
|
|
1489
|
-
|
|
1490
|
-
await whoami(globalOptions);
|
|
1355
|
+
program.command("whoami").description("Show current user information").action(async () => {
|
|
1356
|
+
await whoami();
|
|
1491
1357
|
});
|
|
1492
|
-
program.command("add <specifier>").description("Add a skill (e.g., @user/bsheng/vite_slides@^2.0.0)").option("--save", "Save to lockfile (default)").action(async (specifier, options
|
|
1493
|
-
|
|
1494
|
-
await add(specifier, { save: options.save ?? true }, globalOptions);
|
|
1358
|
+
program.command("add <specifier>").description("Add a skill (e.g., @user/bsheng/vite_slides@^2.0.0)").option("--save", "Save to lockfile (default)").action(async (specifier, options) => {
|
|
1359
|
+
await add(specifier, { save: options.save ?? true });
|
|
1495
1360
|
});
|
|
1496
1361
|
program.command("remove <name>").alias("rm").description("Remove an installed skill").action(async (name) => {
|
|
1497
1362
|
await remove(name);
|
|
@@ -1499,33 +1364,23 @@ program.command("remove <name>").alias("rm").description("Remove an installed sk
|
|
|
1499
1364
|
program.command("list").alias("ls").description("List installed skills").option("--json", "Output as JSON").action(async (options) => {
|
|
1500
1365
|
await list({ json: options.json });
|
|
1501
1366
|
});
|
|
1502
|
-
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").action(async (options
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
dir: options.dir
|
|
1508
|
-
},
|
|
1509
|
-
globalOptions
|
|
1510
|
-
);
|
|
1367
|
+
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").action(async (options) => {
|
|
1368
|
+
await install({
|
|
1369
|
+
frozenLockfile: options.frozenLockfile,
|
|
1370
|
+
dir: options.dir
|
|
1371
|
+
});
|
|
1511
1372
|
});
|
|
1512
|
-
program.command("update").description("Update all skills to latest compatible versions").option("--dry-run", "Show what would be updated without making changes").action(async (options
|
|
1513
|
-
|
|
1514
|
-
await update({ dryRun: options.dryRun }, globalOptions);
|
|
1373
|
+
program.command("update").description("Update all skills to latest compatible versions").option("--dry-run", "Show what would be updated without making changes").action(async (options) => {
|
|
1374
|
+
await update({ dryRun: options.dryRun });
|
|
1515
1375
|
});
|
|
1516
|
-
program.command("publish").description("Publish current directory as a skill").option("--bump <level>", "Bump version (major, minor, patch)").option("--tag <tag>", "Tag for the release").action(async (options
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
tag: options.tag
|
|
1522
|
-
},
|
|
1523
|
-
globalOptions
|
|
1524
|
-
);
|
|
1376
|
+
program.command("publish").description("Publish current directory as a skill").option("--bump <level>", "Bump version (major, minor, patch)").option("--tag <tag>", "Tag for the release").action(async (options) => {
|
|
1377
|
+
await publishCommand({
|
|
1378
|
+
bump: options.bump,
|
|
1379
|
+
tag: options.tag
|
|
1380
|
+
});
|
|
1525
1381
|
});
|
|
1526
|
-
program.command("unpublish <specifier>").description("Remove a published skill version").option("--force", "Confirm destructive action").action(async (specifier, options
|
|
1527
|
-
|
|
1528
|
-
await unpublish(specifier, { force: options.force }, globalOptions);
|
|
1382
|
+
program.command("unpublish <specifier>").description("Remove a published skill version").option("--force", "Confirm destructive action").action(async (specifier, options) => {
|
|
1383
|
+
await unpublish(specifier, { force: options.force });
|
|
1529
1384
|
});
|
|
1530
1385
|
program.parse();
|
|
1531
1386
|
//# sourceMappingURL=index.js.map
|