skillstore 0.0.1 → 0.1.1
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 +199 -0
- 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 +35 -0
- package/dist/lib/plugin-verify.d.ts.map +1 -0
- package/dist/lib/plugin-verify.js +97 -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
package/README.md
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# skillstore
|
|
2
|
+
|
|
3
|
+
CLI and SDK for installing AI skills from [skillstore.io](https://skillstore.io) - the skills marketplace for Claude Code, Codex, and Claude.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Use directly with npx (recommended)
|
|
9
|
+
npx skillstore install <skill-or-plugin>
|
|
10
|
+
|
|
11
|
+
# Or install globally
|
|
12
|
+
npm install -g skillstore
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## CLI Usage
|
|
16
|
+
|
|
17
|
+
### Install a Single Skill
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx skillstore install <skill-slug>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Example:
|
|
24
|
+
```bash
|
|
25
|
+
npx skillstore install react-component-generator
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Install a Plugin (Skill Collection)
|
|
29
|
+
|
|
30
|
+
Use the `@` prefix to install all skills from a plugin:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npx skillstore install @<plugin-slug>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Example:
|
|
37
|
+
```bash
|
|
38
|
+
npx skillstore install @frontend-essentials
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Options
|
|
42
|
+
|
|
43
|
+
| Option | Description |
|
|
44
|
+
|--------|-------------|
|
|
45
|
+
| `--dir <path>` | Installation directory (default: `.claude/skills`) |
|
|
46
|
+
| `--overwrite` | Overwrite existing files |
|
|
47
|
+
| `--skip-verify` | Skip manifest signature verification (plugins only) |
|
|
48
|
+
| `--dry-run` | Preview without writing files |
|
|
49
|
+
|
|
50
|
+
### Plugin Commands
|
|
51
|
+
|
|
52
|
+
#### List Available Plugins
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npx skillstore plugin list [options]
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Options:
|
|
59
|
+
- `--type <type>` - Filter by type: `curated`, `scenario`, or `user`
|
|
60
|
+
- `--pricing <pricing>` - Filter by pricing: `free` or `paid`
|
|
61
|
+
- `--limit <n>` - Number of plugins to show (default: 10)
|
|
62
|
+
- `--page <n>` - Page number for pagination
|
|
63
|
+
|
|
64
|
+
#### Get Plugin Info
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npx skillstore plugin info <slug>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
#### Install Plugin (Alternative)
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npx skillstore plugin install <slug> [options]
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## SDK Usage
|
|
77
|
+
|
|
78
|
+
Use the SDK to integrate skillstore into your own tools:
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
import {
|
|
82
|
+
fetchSkillInfo,
|
|
83
|
+
downloadSkillZip,
|
|
84
|
+
fetchManifest,
|
|
85
|
+
fetchPluginList,
|
|
86
|
+
getPluginConfig,
|
|
87
|
+
} from 'skillstore';
|
|
88
|
+
|
|
89
|
+
// Get default configuration
|
|
90
|
+
const config = getPluginConfig({
|
|
91
|
+
installDir: '.claude/skills',
|
|
92
|
+
timeout: 30000,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Fetch skill info
|
|
96
|
+
const skill = await fetchSkillInfo(config, 'my-skill');
|
|
97
|
+
console.log(skill.name, skill.description);
|
|
98
|
+
|
|
99
|
+
// Download skill as ZIP
|
|
100
|
+
const zipBuffer = await downloadSkillZip(config, 'my-skill');
|
|
101
|
+
|
|
102
|
+
// List available plugins
|
|
103
|
+
const plugins = await fetchPluginList(config, {
|
|
104
|
+
type: 'curated',
|
|
105
|
+
pricing: 'free',
|
|
106
|
+
limit: 20,
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Fetch plugin manifest for installation
|
|
110
|
+
const manifest = await fetchManifest(config, 'my-plugin');
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### SDK Exports
|
|
114
|
+
|
|
115
|
+
#### Plugin API
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
import {
|
|
119
|
+
fetchManifest,
|
|
120
|
+
fetchPluginInfo,
|
|
121
|
+
fetchPluginList,
|
|
122
|
+
downloadSkill,
|
|
123
|
+
reportInstallation,
|
|
124
|
+
reportSkillTelemetry,
|
|
125
|
+
PluginApiError,
|
|
126
|
+
} from 'skillstore';
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
#### Skill API
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
import {
|
|
133
|
+
fetchSkillInfo,
|
|
134
|
+
downloadSkillZip,
|
|
135
|
+
SkillApiError,
|
|
136
|
+
} from 'skillstore';
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
#### Configuration
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
import {
|
|
143
|
+
getPluginConfig,
|
|
144
|
+
getSkillPath,
|
|
145
|
+
DEFAULT_INSTALL_DIR,
|
|
146
|
+
API_BASE_URL,
|
|
147
|
+
} from 'skillstore';
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
#### Verification
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
import {
|
|
154
|
+
verifyManifest,
|
|
155
|
+
verifyManifestSignature,
|
|
156
|
+
verifyContentHash,
|
|
157
|
+
} from 'skillstore';
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
#### Download Manager
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
import {
|
|
164
|
+
downloadAllSkills,
|
|
165
|
+
printDownloadSummary,
|
|
166
|
+
} from 'skillstore';
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Configuration
|
|
170
|
+
|
|
171
|
+
### Environment Variables
|
|
172
|
+
|
|
173
|
+
| Variable | Description |
|
|
174
|
+
|----------|-------------|
|
|
175
|
+
| `SKILLSTORE_API_URL` | Custom API base URL (default: `https://skillstore.io/api`) |
|
|
176
|
+
| `SKILLSTORE_VERIFY_KEY` | Override built-in manifest verification key (optional) |
|
|
177
|
+
| `DEBUG` | Enable debug logging |
|
|
178
|
+
|
|
179
|
+
> **Note**: Manifest signature verification is enabled by default using a built-in key. You don't need to configure anything for verification to work.
|
|
180
|
+
|
|
181
|
+
## Directory Structure
|
|
182
|
+
|
|
183
|
+
Skills are installed to `.claude/skills/` by default:
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
.claude/
|
|
187
|
+
└── skills/
|
|
188
|
+
├── skill-one.md
|
|
189
|
+
├── skill-two.md
|
|
190
|
+
└── ...
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Requirements
|
|
194
|
+
|
|
195
|
+
- Node.js >= 18.0.0
|
|
196
|
+
|
|
197
|
+
## License
|
|
198
|
+
|
|
199
|
+
MIT
|
|
@@ -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
|