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.
Files changed (54) hide show
  1. package/dist/cli/index.d.ts +3 -0
  2. package/dist/cli/index.d.ts.map +1 -0
  3. package/dist/cli/index.js +21 -0
  4. package/dist/cli/index.js.map +1 -0
  5. package/dist/commands/install.d.ts +35 -0
  6. package/dist/commands/install.d.ts.map +1 -0
  7. package/dist/commands/install.js +272 -0
  8. package/dist/commands/install.js.map +1 -0
  9. package/dist/commands/plugin/index.d.ts +3 -0
  10. package/dist/commands/plugin/index.d.ts.map +1 -0
  11. package/dist/commands/plugin/index.js +13 -0
  12. package/dist/commands/plugin/index.js.map +1 -0
  13. package/dist/commands/plugin/info.d.ts +9 -0
  14. package/dist/commands/plugin/info.d.ts.map +1 -0
  15. package/dist/commands/plugin/info.js +75 -0
  16. package/dist/commands/plugin/info.js.map +1 -0
  17. package/dist/commands/plugin/install.d.ts +29 -0
  18. package/dist/commands/plugin/install.d.ts.map +1 -0
  19. package/dist/commands/plugin/install.js +140 -0
  20. package/dist/commands/plugin/install.js.map +1 -0
  21. package/dist/commands/plugin/list.d.ts +22 -0
  22. package/dist/commands/plugin/list.d.ts.map +1 -0
  23. package/dist/commands/plugin/list.js +76 -0
  24. package/dist/commands/plugin/list.js.map +1 -0
  25. package/dist/index.d.ts +11 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +13 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/lib/plugin-api.d.ts +155 -0
  30. package/dist/lib/plugin-api.d.ts.map +1 -0
  31. package/dist/lib/plugin-api.js +173 -0
  32. package/dist/lib/plugin-api.js.map +1 -0
  33. package/dist/lib/plugin-config.d.ts +56 -0
  34. package/dist/lib/plugin-config.d.ts.map +1 -0
  35. package/dist/lib/plugin-config.js +64 -0
  36. package/dist/lib/plugin-config.js.map +1 -0
  37. package/dist/lib/plugin-download.d.ts +36 -0
  38. package/dist/lib/plugin-download.d.ts.map +1 -0
  39. package/dist/lib/plugin-download.js +134 -0
  40. package/dist/lib/plugin-download.js.map +1 -0
  41. package/dist/lib/plugin-logger.d.ts +79 -0
  42. package/dist/lib/plugin-logger.d.ts.map +1 -0
  43. package/dist/lib/plugin-logger.js +173 -0
  44. package/dist/lib/plugin-logger.js.map +1 -0
  45. package/dist/lib/plugin-verify.d.ts +36 -0
  46. package/dist/lib/plugin-verify.d.ts.map +1 -0
  47. package/dist/lib/plugin-verify.js +103 -0
  48. package/dist/lib/plugin-verify.js.map +1 -0
  49. package/dist/lib/skill-api.d.ts +33 -0
  50. package/dist/lib/skill-api.d.ts.map +1 -0
  51. package/dist/lib/skill-api.js +64 -0
  52. package/dist/lib/skill-api.js.map +1 -0
  53. package/package.json +56 -17
  54. package/src/index.js +0 -16
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -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,3 @@
1
+ declare const _default: import("citty").CommandDef<import("citty").ArgsDef>;
2
+ export default _default;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -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,9 @@
1
+ declare const _default: import("citty").CommandDef<{
2
+ slug: {
3
+ type: "positional";
4
+ description: string;
5
+ required: true;
6
+ };
7
+ }>;
8
+ export default _default;
9
+ //# sourceMappingURL=info.d.ts.map
@@ -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":"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"}
@@ -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