skillstore 0.0.1 → 0.1.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/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +21 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/commands/install.d.ts +35 -0
- package/dist/commands/install.d.ts.map +1 -0
- package/dist/commands/install.js +272 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/plugin/index.d.ts +3 -0
- package/dist/commands/plugin/index.d.ts.map +1 -0
- package/dist/commands/plugin/index.js +13 -0
- package/dist/commands/plugin/index.js.map +1 -0
- package/dist/commands/plugin/info.d.ts +9 -0
- package/dist/commands/plugin/info.d.ts.map +1 -0
- package/dist/commands/plugin/info.js +75 -0
- package/dist/commands/plugin/info.js.map +1 -0
- package/dist/commands/plugin/install.d.ts +29 -0
- package/dist/commands/plugin/install.d.ts.map +1 -0
- package/dist/commands/plugin/install.js +140 -0
- package/dist/commands/plugin/install.js.map +1 -0
- package/dist/commands/plugin/list.d.ts +22 -0
- package/dist/commands/plugin/list.d.ts.map +1 -0
- package/dist/commands/plugin/list.js +76 -0
- package/dist/commands/plugin/list.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/plugin-api.d.ts +155 -0
- package/dist/lib/plugin-api.d.ts.map +1 -0
- package/dist/lib/plugin-api.js +173 -0
- package/dist/lib/plugin-api.js.map +1 -0
- package/dist/lib/plugin-config.d.ts +56 -0
- package/dist/lib/plugin-config.d.ts.map +1 -0
- package/dist/lib/plugin-config.js +64 -0
- package/dist/lib/plugin-config.js.map +1 -0
- package/dist/lib/plugin-download.d.ts +36 -0
- package/dist/lib/plugin-download.d.ts.map +1 -0
- package/dist/lib/plugin-download.js +134 -0
- package/dist/lib/plugin-download.js.map +1 -0
- package/dist/lib/plugin-logger.d.ts +79 -0
- package/dist/lib/plugin-logger.d.ts.map +1 -0
- package/dist/lib/plugin-logger.js +173 -0
- package/dist/lib/plugin-logger.js.map +1 -0
- package/dist/lib/plugin-verify.d.ts +36 -0
- package/dist/lib/plugin-verify.d.ts.map +1 -0
- package/dist/lib/plugin-verify.js +103 -0
- package/dist/lib/plugin-verify.js.map +1 -0
- package/dist/lib/skill-api.d.ts +33 -0
- package/dist/lib/skill-api.d.ts.map +1 -0
- package/dist/lib/skill-api.js +64 -0
- package/dist/lib/skill-api.js.map +1 -0
- package/package.json +56 -17
- package/src/index.js +0 -16
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { defineCommand, runMain } from 'citty';
|
|
3
|
+
const main = defineCommand({
|
|
4
|
+
meta: {
|
|
5
|
+
name: 'skillstore',
|
|
6
|
+
version: '0.1.0',
|
|
7
|
+
description: 'Skillstore CLI - Manage AI skills for Claude, Codex, and Claude Code',
|
|
8
|
+
},
|
|
9
|
+
subCommands: {
|
|
10
|
+
// Primary command: install skills or plugins
|
|
11
|
+
install: () => import('../commands/install.js').then((m) => m.default),
|
|
12
|
+
// Plugin management (info, list)
|
|
13
|
+
plugin: () => import('../commands/plugin/index.js').then((m) => m.default),
|
|
14
|
+
},
|
|
15
|
+
setup() {
|
|
16
|
+
// NOTE: Do NOT use consola.wrapAll() - it intercepts process.stdout.write
|
|
17
|
+
// in CI mode and adds [log] prefix, breaking machine-readable output
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
runMain(main);
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAE/C,MAAM,IAAI,GAAG,aAAa,CAAC;IAC1B,IAAI,EAAE;QACL,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,OAAO;QAChB,WAAW,EAAE,sEAAsE;KACnF;IACD,WAAW,EAAE;QACZ,6CAA6C;QAC7C,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QACtE,iCAAiC;QACjC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,6BAA6B,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;KAC1E;IACD,KAAK;QACJ,0EAA0E;QAC1E,qEAAqE;IACtE,CAAC;CACD,CAAC,CAAC;AAEH,OAAO,CAAC,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified install command
|
|
3
|
+
*
|
|
4
|
+
* - `skillstore install <slug>` → Install single skill
|
|
5
|
+
* - `skillstore install @<plugin>` → Install plugin (skill collection)
|
|
6
|
+
*/
|
|
7
|
+
declare const _default: import("citty").CommandDef<{
|
|
8
|
+
target: {
|
|
9
|
+
type: "positional";
|
|
10
|
+
description: string;
|
|
11
|
+
required: true;
|
|
12
|
+
};
|
|
13
|
+
dir: {
|
|
14
|
+
type: "string";
|
|
15
|
+
description: string;
|
|
16
|
+
default: string;
|
|
17
|
+
};
|
|
18
|
+
'skip-verify': {
|
|
19
|
+
type: "boolean";
|
|
20
|
+
description: string;
|
|
21
|
+
default: false;
|
|
22
|
+
};
|
|
23
|
+
'dry-run': {
|
|
24
|
+
type: "boolean";
|
|
25
|
+
description: string;
|
|
26
|
+
default: false;
|
|
27
|
+
};
|
|
28
|
+
overwrite: {
|
|
29
|
+
type: "boolean";
|
|
30
|
+
description: string;
|
|
31
|
+
default: false;
|
|
32
|
+
};
|
|
33
|
+
}>;
|
|
34
|
+
export default _default;
|
|
35
|
+
//# sourceMappingURL=install.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAUA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACH,wBA6CG"}
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import { defineCommand } from 'citty';
|
|
2
|
+
import { mkdir, writeFile, access } from 'node:fs/promises';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { getPluginConfig } from '../lib/plugin-config.js';
|
|
5
|
+
import { fetchManifest, reportInstallation, reportSkillInstall, PluginApiError } from '../lib/plugin-api.js';
|
|
6
|
+
import { fetchSkillInfo, downloadSkillZip, SkillApiError } from '../lib/skill-api.js';
|
|
7
|
+
import { verifyManifest } from '../lib/plugin-verify.js';
|
|
8
|
+
import { downloadAllSkills, printDownloadSummary } from '../lib/plugin-download.js';
|
|
9
|
+
import { logger } from '../lib/plugin-logger.js';
|
|
10
|
+
/**
|
|
11
|
+
* Unified install command
|
|
12
|
+
*
|
|
13
|
+
* - `skillstore install <slug>` → Install single skill
|
|
14
|
+
* - `skillstore install @<plugin>` → Install plugin (skill collection)
|
|
15
|
+
*/
|
|
16
|
+
export default defineCommand({
|
|
17
|
+
meta: {
|
|
18
|
+
name: 'install',
|
|
19
|
+
description: 'Install skills or plugins from skillstore.io',
|
|
20
|
+
},
|
|
21
|
+
args: {
|
|
22
|
+
target: {
|
|
23
|
+
type: 'positional',
|
|
24
|
+
description: 'Skill slug or @plugin to install',
|
|
25
|
+
required: true,
|
|
26
|
+
},
|
|
27
|
+
dir: {
|
|
28
|
+
type: 'string',
|
|
29
|
+
description: 'Installation directory (default: .claude/skills)',
|
|
30
|
+
default: '.claude/skills',
|
|
31
|
+
},
|
|
32
|
+
'skip-verify': {
|
|
33
|
+
type: 'boolean',
|
|
34
|
+
description: 'Skip manifest signature verification (plugins only)',
|
|
35
|
+
default: false,
|
|
36
|
+
},
|
|
37
|
+
'dry-run': {
|
|
38
|
+
type: 'boolean',
|
|
39
|
+
description: 'Show what would be installed without actually installing',
|
|
40
|
+
default: false,
|
|
41
|
+
},
|
|
42
|
+
overwrite: {
|
|
43
|
+
type: 'boolean',
|
|
44
|
+
description: 'Overwrite existing files',
|
|
45
|
+
default: false,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
async run({ args }) {
|
|
49
|
+
const { target, dir, 'skip-verify': skipVerify, 'dry-run': dryRun, overwrite } = args;
|
|
50
|
+
// Detect if target is a plugin (@prefix) or skill
|
|
51
|
+
const isPlugin = target.startsWith('@');
|
|
52
|
+
const slug = isPlugin ? target.slice(1) : target;
|
|
53
|
+
if (isPlugin) {
|
|
54
|
+
await installPlugin(slug, { dir, skipVerify, dryRun, overwrite });
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
await installSkill(slug, { dir, dryRun, overwrite });
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
/**
|
|
62
|
+
* Install a single skill
|
|
63
|
+
*/
|
|
64
|
+
async function installSkill(slug, options) {
|
|
65
|
+
const { dir, dryRun, overwrite } = options;
|
|
66
|
+
const config = getPluginConfig({
|
|
67
|
+
installDir: dir,
|
|
68
|
+
dryRun,
|
|
69
|
+
});
|
|
70
|
+
logger.info(`Installing skill: ${slug}`);
|
|
71
|
+
logger.info(`Target directory: ${config.installDir}`);
|
|
72
|
+
if (dryRun) {
|
|
73
|
+
logger.warn('Dry run mode - no files will be written');
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
// Step 1: Fetch skill info
|
|
77
|
+
logger.startSpinner('Fetching skill info...');
|
|
78
|
+
const skillInfo = await fetchSkillInfo(config, slug);
|
|
79
|
+
logger.spinnerSuccess(`Found skill: "${skillInfo.name}"`);
|
|
80
|
+
// Step 2: Show skill info
|
|
81
|
+
logger.box(`Skill: ${skillInfo.name}`, [
|
|
82
|
+
`Slug: ${skillInfo.slug}`,
|
|
83
|
+
`Version: ${skillInfo.version || 'N/A'}`,
|
|
84
|
+
`Author: ${skillInfo.author || 'Unknown'}`,
|
|
85
|
+
`Category: ${skillInfo.category || 'N/A'}`,
|
|
86
|
+
]);
|
|
87
|
+
// Step 3: Check if already installed
|
|
88
|
+
const skillDir = join(config.installDir, slug);
|
|
89
|
+
if (!overwrite) {
|
|
90
|
+
try {
|
|
91
|
+
await access(skillDir);
|
|
92
|
+
logger.warn(`Skill "${slug}" already exists. Use --overwrite to replace.`);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// Directory doesn't exist, continue
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (dryRun) {
|
|
100
|
+
logger.success('Dry run complete - no files were written');
|
|
101
|
+
console.log('');
|
|
102
|
+
console.log(`Would install to: ${skillDir}`);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
// Step 4: Download skill ZIP
|
|
106
|
+
logger.startSpinner('Downloading skill...');
|
|
107
|
+
const zipBuffer = await downloadSkillZip(config, slug);
|
|
108
|
+
logger.spinnerSuccess('Downloaded skill package');
|
|
109
|
+
// Step 5: Extract ZIP
|
|
110
|
+
logger.startSpinner('Extracting files...');
|
|
111
|
+
await extractZip(zipBuffer, config.installDir);
|
|
112
|
+
logger.spinnerSuccess('Extracted files');
|
|
113
|
+
// Step 6: Report installation (non-blocking telemetry)
|
|
114
|
+
try {
|
|
115
|
+
await reportSkillInstall(config, slug);
|
|
116
|
+
logger.debug('Installation telemetry reported');
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
logger.debug('Failed to report telemetry (non-critical)');
|
|
120
|
+
}
|
|
121
|
+
logger.success(`Skill "${skillInfo.name}" installed successfully!`);
|
|
122
|
+
console.log('');
|
|
123
|
+
console.log(`Installed to: ${skillDir}`);
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
logger.stopSpinner();
|
|
127
|
+
if (err instanceof SkillApiError) {
|
|
128
|
+
if (err.statusCode === 404) {
|
|
129
|
+
logger.error(`Skill "${slug}" not found`);
|
|
130
|
+
console.log('');
|
|
131
|
+
console.log('Tip: Use @ prefix to install a plugin, e.g.:');
|
|
132
|
+
console.log(` npx skillstore install @${slug}`);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
logger.error(`API error: ${err.message}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
logger.error('Installation failed', err instanceof Error ? err : undefined);
|
|
140
|
+
}
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Install a plugin (skill collection)
|
|
146
|
+
*/
|
|
147
|
+
async function installPlugin(slug, options) {
|
|
148
|
+
const { dir, skipVerify, dryRun, overwrite } = options;
|
|
149
|
+
const config = getPluginConfig({
|
|
150
|
+
installDir: dir,
|
|
151
|
+
skipVerify,
|
|
152
|
+
dryRun,
|
|
153
|
+
});
|
|
154
|
+
logger.info(`Installing plugin: @${slug}`);
|
|
155
|
+
logger.info(`Target directory: ${config.installDir}`);
|
|
156
|
+
if (dryRun) {
|
|
157
|
+
logger.warn('Dry run mode - no files will be written');
|
|
158
|
+
}
|
|
159
|
+
try {
|
|
160
|
+
// Step 1: Fetch manifest
|
|
161
|
+
logger.startSpinner('Fetching plugin manifest...');
|
|
162
|
+
const manifest = await fetchManifest(config, slug);
|
|
163
|
+
logger.spinnerSuccess(`Fetched manifest for "${manifest.plugin.name}"`);
|
|
164
|
+
// Step 2: Verify manifest
|
|
165
|
+
if (!skipVerify) {
|
|
166
|
+
logger.startSpinner('Verifying manifest signature...');
|
|
167
|
+
const verifyResult = await verifyManifest(manifest, { skipSignature: skipVerify });
|
|
168
|
+
if (!verifyResult.valid) {
|
|
169
|
+
logger.spinnerError('Manifest verification failed');
|
|
170
|
+
logger.error(verifyResult.error || 'Unknown verification error');
|
|
171
|
+
process.exit(1);
|
|
172
|
+
}
|
|
173
|
+
if (verifyResult.error) {
|
|
174
|
+
logger.spinnerSuccess('Manifest structure valid');
|
|
175
|
+
logger.warn(verifyResult.error);
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
logger.spinnerSuccess('Manifest verified');
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
logger.warn('Skipping manifest signature verification');
|
|
183
|
+
}
|
|
184
|
+
// Step 3: Show plugin info
|
|
185
|
+
logger.box(`Plugin: ${manifest.plugin.name}`, [
|
|
186
|
+
`Version: ${manifest.plugin.version}`,
|
|
187
|
+
`Skills: ${manifest.skills.length}`,
|
|
188
|
+
`Generated: ${new Date(manifest.generatedAt).toLocaleDateString()}`,
|
|
189
|
+
]);
|
|
190
|
+
// Step 4: Download skills
|
|
191
|
+
logger.info('');
|
|
192
|
+
const downloadResult = await downloadAllSkills(config, manifest.skills, {
|
|
193
|
+
overwrite,
|
|
194
|
+
verifyHash: !skipVerify,
|
|
195
|
+
});
|
|
196
|
+
// Step 5: Print summary
|
|
197
|
+
printDownloadSummary(downloadResult);
|
|
198
|
+
// Step 6: Report installation (non-blocking)
|
|
199
|
+
if (!dryRun && downloadResult.success > 0) {
|
|
200
|
+
try {
|
|
201
|
+
const reportResult = await reportInstallation(config, slug, 'cli');
|
|
202
|
+
if (reportResult.duplicate) {
|
|
203
|
+
logger.debug('Installation already recorded');
|
|
204
|
+
}
|
|
205
|
+
else if (reportResult.success) {
|
|
206
|
+
logger.debug('Installation reported successfully');
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
logger.debug('Failed to report installation (non-critical)');
|
|
211
|
+
}
|
|
212
|
+
// Report telemetry for each successfully installed skill
|
|
213
|
+
const successfulSkills = downloadResult.results.filter((r) => r.success && !r.skipped);
|
|
214
|
+
if (successfulSkills.length > 0) {
|
|
215
|
+
// Report in parallel, non-blocking
|
|
216
|
+
Promise.all(successfulSkills.map((r) => reportSkillInstall(config, r.slug))).catch(() => {
|
|
217
|
+
logger.debug('Telemetry reporting failed (non-critical)');
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// Final status
|
|
222
|
+
if (downloadResult.failed > 0) {
|
|
223
|
+
logger.warn(`Installation completed with ${downloadResult.failed} failures`);
|
|
224
|
+
process.exit(1);
|
|
225
|
+
}
|
|
226
|
+
else if (dryRun) {
|
|
227
|
+
logger.success('Dry run complete - no files were written');
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
logger.success(`Plugin "@${manifest.plugin.slug}" installed successfully!`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
catch (err) {
|
|
234
|
+
logger.stopSpinner();
|
|
235
|
+
if (err instanceof PluginApiError) {
|
|
236
|
+
if (err.statusCode === 404) {
|
|
237
|
+
logger.error(`Plugin "@${slug}" not found`);
|
|
238
|
+
console.log('');
|
|
239
|
+
console.log('Tip: Without @ prefix to install a single skill, e.g.:');
|
|
240
|
+
console.log(` npx skillstore install ${slug}`);
|
|
241
|
+
}
|
|
242
|
+
else if (err.statusCode === 403) {
|
|
243
|
+
logger.error('Access denied - plugin may be private or require purchase');
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
logger.error(`API error: ${err.message}`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
logger.error('Installation failed', err instanceof Error ? err : undefined);
|
|
251
|
+
}
|
|
252
|
+
process.exit(1);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Extract ZIP buffer to directory
|
|
257
|
+
*/
|
|
258
|
+
async function extractZip(buffer, targetDir) {
|
|
259
|
+
// Use fflate for extraction
|
|
260
|
+
const { unzipSync } = await import('fflate');
|
|
261
|
+
const data = new Uint8Array(buffer);
|
|
262
|
+
const unzipped = unzipSync(data);
|
|
263
|
+
for (const [path, content] of Object.entries(unzipped)) {
|
|
264
|
+
// Skip directories (they end with /)
|
|
265
|
+
if (path.endsWith('/'))
|
|
266
|
+
continue;
|
|
267
|
+
const fullPath = join(targetDir, path);
|
|
268
|
+
await mkdir(dirname(fullPath), { recursive: true });
|
|
269
|
+
await writeFile(fullPath, Buffer.from(content));
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/plugin/index.ts"],"names":[],"mappings":";AAEA,wBAUG"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { defineCommand } from 'citty';
|
|
2
|
+
export default defineCommand({
|
|
3
|
+
meta: {
|
|
4
|
+
name: 'plugin',
|
|
5
|
+
description: 'Plugin management commands - install and manage skill collections',
|
|
6
|
+
},
|
|
7
|
+
subCommands: {
|
|
8
|
+
install: () => import('./install.js').then((m) => m.default),
|
|
9
|
+
info: () => import('./info.js').then((m) => m.default),
|
|
10
|
+
list: () => import('./list.js').then((m) => m.default),
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/plugin/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtC,eAAe,aAAa,CAAC;IAC5B,IAAI,EAAE;QACL,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,mEAAmE;KAChF;IACD,WAAW,EAAE;QACZ,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QAC5D,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QACtD,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;KACtD;CACD,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"info.d.ts","sourceRoot":"","sources":["../../../src/commands/plugin/info.ts"],"names":[],"mappings":";;;;;;;AAKA,wBA2EG"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { defineCommand } from 'citty';
|
|
2
|
+
import { getPluginConfig } from '../../lib/plugin-config.js';
|
|
3
|
+
import { fetchPluginInfo, PluginApiError } from '../../lib/plugin-api.js';
|
|
4
|
+
import { logger } from '../../lib/plugin-logger.js';
|
|
5
|
+
export default defineCommand({
|
|
6
|
+
meta: {
|
|
7
|
+
name: 'info',
|
|
8
|
+
description: 'Show detailed information about a plugin',
|
|
9
|
+
},
|
|
10
|
+
args: {
|
|
11
|
+
slug: {
|
|
12
|
+
type: 'positional',
|
|
13
|
+
description: 'Plugin slug to get info for',
|
|
14
|
+
required: true,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
async run({ args }) {
|
|
18
|
+
const { slug } = args;
|
|
19
|
+
const config = getPluginConfig();
|
|
20
|
+
logger.startSpinner(`Fetching info for plugin: ${slug}`);
|
|
21
|
+
try {
|
|
22
|
+
const info = await fetchPluginInfo(config, slug);
|
|
23
|
+
logger.stopSpinner();
|
|
24
|
+
// Display plugin info
|
|
25
|
+
logger.box(`Plugin: ${info.name}`, [
|
|
26
|
+
`Slug: ${info.slug}`,
|
|
27
|
+
`Type: ${info.pluginType}`,
|
|
28
|
+
`Pricing: ${info.pricing}${info.priceCents > 0 ? ` ($${(info.priceCents / 100).toFixed(2)} ${info.currency})` : ''}`,
|
|
29
|
+
`Visibility: ${info.visibility}`,
|
|
30
|
+
`Skills: ${info.skillCount}`,
|
|
31
|
+
`Installs: ${info.installCount}`,
|
|
32
|
+
]);
|
|
33
|
+
if (info.description) {
|
|
34
|
+
console.log('');
|
|
35
|
+
console.log('Description:');
|
|
36
|
+
console.log(` ${info.description}`);
|
|
37
|
+
}
|
|
38
|
+
if (info.scenarioTags && info.scenarioTags.length > 0) {
|
|
39
|
+
console.log('');
|
|
40
|
+
console.log('Scenario Tags:');
|
|
41
|
+
console.log(` ${info.scenarioTags.join(', ')}`);
|
|
42
|
+
}
|
|
43
|
+
if (info.skills && info.skills.length > 0) {
|
|
44
|
+
console.log('');
|
|
45
|
+
console.log('Skills:');
|
|
46
|
+
for (const skill of info.skills) {
|
|
47
|
+
const score = skill.qualityScore ? ` (score: ${skill.qualityScore})` : '';
|
|
48
|
+
const category = skill.category ? ` [${skill.category}]` : '';
|
|
49
|
+
console.log(` • ${skill.name}${category}${score}`);
|
|
50
|
+
if (skill.description) {
|
|
51
|
+
console.log(` ${skill.description}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
console.log('');
|
|
56
|
+
console.log(`Install with: npx skillstore plugin install ${info.slug}`);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
logger.stopSpinner();
|
|
60
|
+
if (err instanceof PluginApiError) {
|
|
61
|
+
if (err.statusCode === 404) {
|
|
62
|
+
logger.error(`Plugin "${slug}" not found`);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
logger.error(`API error: ${err.message}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
logger.error('Failed to fetch plugin info', err instanceof Error ? err : undefined);
|
|
70
|
+
}
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
//# sourceMappingURL=info.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"info.js","sourceRoot":"","sources":["../../../src/commands/plugin/info.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAEpD,eAAe,aAAa,CAAC;IAC5B,IAAI,EAAE;QACL,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,0CAA0C;KACvD;IACD,IAAI,EAAE;QACL,IAAI,EAAE;YACL,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,6BAA6B;YAC1C,QAAQ,EAAE,IAAI;SACd;KACD;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;QACjB,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;QACtB,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;QAEjC,MAAM,CAAC,YAAY,CAAC,6BAA6B,IAAI,EAAE,CAAC,CAAC;QAEzD,IAAI,CAAC;YACJ,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YACjD,MAAM,CAAC,WAAW,EAAE,CAAC;YAErB,sBAAsB;YACtB,MAAM,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,IAAI,EAAE,EAAE;gBAClC,SAAS,IAAI,CAAC,IAAI,EAAE;gBACpB,SAAS,IAAI,CAAC,UAAU,EAAE;gBAC1B,YAAY,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBACpH,eAAe,IAAI,CAAC,UAAU,EAAE;gBAChC,WAAW,IAAI,CAAC,UAAU,EAAE;gBAC5B,aAAa,IAAI,CAAC,YAAY,EAAE;aAChC,CAAC,CAAC;YAEH,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACtB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAChB,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;gBAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;YACtC,CAAC;YAED,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAChB,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;gBAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAClD,CAAC;YAED,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAChB,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gBACvB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;oBACjC,MAAM,KAAK,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC1E,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC9D,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,IAAI,GAAG,QAAQ,GAAG,KAAK,EAAE,CAAC,CAAC;oBACpD,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;wBACvB,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;oBACzC,CAAC;gBACF,CAAC;YACF,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,+CAA+C,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACzE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,CAAC,WAAW,EAAE,CAAC;YAErB,IAAI,GAAG,YAAY,cAAc,EAAE,CAAC;gBACnC,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;oBAC5B,MAAM,CAAC,KAAK,CAAC,WAAW,IAAI,aAAa,CAAC,CAAC;gBAC5C,CAAC;qBAAM,CAAC;oBACP,MAAM,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC3C,CAAC;YACF,CAAC;iBAAM,CAAC;gBACP,MAAM,CAAC,KAAK,CAAC,6BAA6B,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YACrF,CAAC;YAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;IACF,CAAC;CACD,CAAC,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
declare const _default: import("citty").CommandDef<{
|
|
2
|
+
slug: {
|
|
3
|
+
type: "positional";
|
|
4
|
+
description: string;
|
|
5
|
+
required: true;
|
|
6
|
+
};
|
|
7
|
+
dir: {
|
|
8
|
+
type: "string";
|
|
9
|
+
description: string;
|
|
10
|
+
default: string;
|
|
11
|
+
};
|
|
12
|
+
'skip-verify': {
|
|
13
|
+
type: "boolean";
|
|
14
|
+
description: string;
|
|
15
|
+
default: false;
|
|
16
|
+
};
|
|
17
|
+
'dry-run': {
|
|
18
|
+
type: "boolean";
|
|
19
|
+
description: string;
|
|
20
|
+
default: false;
|
|
21
|
+
};
|
|
22
|
+
overwrite: {
|
|
23
|
+
type: "boolean";
|
|
24
|
+
description: string;
|
|
25
|
+
default: false;
|
|
26
|
+
};
|
|
27
|
+
}>;
|
|
28
|
+
export default _default;
|
|
29
|
+
//# sourceMappingURL=install.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/commands/plugin/install.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,wBAwIG"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { defineCommand } from 'citty';
|
|
2
|
+
import { getPluginConfig } from '../../lib/plugin-config.js';
|
|
3
|
+
import { fetchManifest, reportInstallation, PluginApiError } from '../../lib/plugin-api.js';
|
|
4
|
+
import { verifyManifest } from '../../lib/plugin-verify.js';
|
|
5
|
+
import { downloadAllSkills, printDownloadSummary } from '../../lib/plugin-download.js';
|
|
6
|
+
import { logger } from '../../lib/plugin-logger.js';
|
|
7
|
+
export default defineCommand({
|
|
8
|
+
meta: {
|
|
9
|
+
name: 'install',
|
|
10
|
+
description: 'Install a plugin (collection of skills) to your project',
|
|
11
|
+
},
|
|
12
|
+
args: {
|
|
13
|
+
slug: {
|
|
14
|
+
type: 'positional',
|
|
15
|
+
description: 'Plugin slug to install',
|
|
16
|
+
required: true,
|
|
17
|
+
},
|
|
18
|
+
dir: {
|
|
19
|
+
type: 'string',
|
|
20
|
+
description: 'Installation directory (default: .claude/skills)',
|
|
21
|
+
default: '.claude/skills',
|
|
22
|
+
},
|
|
23
|
+
'skip-verify': {
|
|
24
|
+
type: 'boolean',
|
|
25
|
+
description: 'Skip manifest signature verification',
|
|
26
|
+
default: false,
|
|
27
|
+
},
|
|
28
|
+
'dry-run': {
|
|
29
|
+
type: 'boolean',
|
|
30
|
+
description: 'Show what would be installed without actually installing',
|
|
31
|
+
default: false,
|
|
32
|
+
},
|
|
33
|
+
overwrite: {
|
|
34
|
+
type: 'boolean',
|
|
35
|
+
description: 'Overwrite existing skill files',
|
|
36
|
+
default: false,
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
async run({ args }) {
|
|
40
|
+
const { slug, dir, 'skip-verify': skipVerify, 'dry-run': dryRun, overwrite } = args;
|
|
41
|
+
// Build config from args
|
|
42
|
+
const config = getPluginConfig({
|
|
43
|
+
installDir: dir,
|
|
44
|
+
skipVerify,
|
|
45
|
+
dryRun,
|
|
46
|
+
});
|
|
47
|
+
logger.info(`Installing plugin: ${slug}`);
|
|
48
|
+
logger.info(`Target directory: ${config.installDir}`);
|
|
49
|
+
if (dryRun) {
|
|
50
|
+
logger.warn('Dry run mode - no files will be written');
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
// Step 1: Fetch manifest
|
|
54
|
+
logger.startSpinner('Fetching plugin manifest...');
|
|
55
|
+
const manifest = await fetchManifest(config, slug);
|
|
56
|
+
logger.spinnerSuccess(`Fetched manifest for "${manifest.plugin.name}"`);
|
|
57
|
+
// Step 2: Verify manifest
|
|
58
|
+
if (!skipVerify) {
|
|
59
|
+
logger.startSpinner('Verifying manifest signature...');
|
|
60
|
+
const verifyResult = await verifyManifest(manifest, { skipSignature: skipVerify });
|
|
61
|
+
if (!verifyResult.valid) {
|
|
62
|
+
logger.spinnerError('Manifest verification failed');
|
|
63
|
+
logger.error(verifyResult.error || 'Unknown verification error');
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
if (verifyResult.error) {
|
|
67
|
+
// Warning but continue
|
|
68
|
+
logger.spinnerSuccess('Manifest structure valid');
|
|
69
|
+
logger.warn(verifyResult.error);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
logger.spinnerSuccess('Manifest verified');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
logger.warn('Skipping manifest signature verification');
|
|
77
|
+
}
|
|
78
|
+
// Step 3: Show plugin info
|
|
79
|
+
logger.box(`Plugin: ${manifest.plugin.name}`, [
|
|
80
|
+
`Version: ${manifest.plugin.version}`,
|
|
81
|
+
`Skills: ${manifest.skills.length}`,
|
|
82
|
+
`Generated: ${new Date(manifest.generatedAt).toLocaleDateString()}`,
|
|
83
|
+
]);
|
|
84
|
+
// Step 4: Download skills
|
|
85
|
+
logger.info('');
|
|
86
|
+
const downloadResult = await downloadAllSkills(config, manifest.skills, {
|
|
87
|
+
overwrite,
|
|
88
|
+
verifyHash: !skipVerify,
|
|
89
|
+
});
|
|
90
|
+
// Step 5: Print summary
|
|
91
|
+
printDownloadSummary(downloadResult);
|
|
92
|
+
// Step 6: Report installation (non-blocking)
|
|
93
|
+
if (!dryRun && downloadResult.success > 0) {
|
|
94
|
+
try {
|
|
95
|
+
const reportResult = await reportInstallation(config, slug, 'cli');
|
|
96
|
+
if (reportResult.duplicate) {
|
|
97
|
+
logger.debug('Installation already recorded');
|
|
98
|
+
}
|
|
99
|
+
else if (reportResult.success) {
|
|
100
|
+
logger.debug('Installation reported successfully');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// Don't fail on report error
|
|
105
|
+
logger.debug('Failed to report installation (non-critical)');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Final status
|
|
109
|
+
if (downloadResult.failed > 0) {
|
|
110
|
+
logger.warn(`Installation completed with ${downloadResult.failed} failures`);
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|
|
113
|
+
else if (dryRun) {
|
|
114
|
+
logger.success('Dry run complete - no files were written');
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
logger.success(`Plugin "${manifest.plugin.name}" installed successfully!`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
logger.stopSpinner();
|
|
122
|
+
if (err instanceof PluginApiError) {
|
|
123
|
+
if (err.statusCode === 404) {
|
|
124
|
+
logger.error(`Plugin "${slug}" not found`);
|
|
125
|
+
}
|
|
126
|
+
else if (err.statusCode === 403) {
|
|
127
|
+
logger.error('Access denied - plugin may be private or require purchase');
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
logger.error(`API error: ${err.message}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
logger.error('Installation failed', err instanceof Error ? err : undefined);
|
|
135
|
+
}
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
//# sourceMappingURL=install.js.map
|