agent-skills-cli 1.0.5 ā 1.0.7
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 +47 -26
- package/dist/cli/index.js +357 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +4 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/source-parser.d.ts +32 -0
- package/dist/core/source-parser.d.ts.map +1 -0
- package/dist/core/source-parser.js +214 -0
- package/dist/core/source-parser.js.map +1 -0
- package/dist/core/telemetry.d.ts +59 -0
- package/dist/core/telemetry.d.ts.map +1 -0
- package/dist/core/telemetry.js +98 -0
- package/dist/core/telemetry.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# Agent Skills CLI š
|
|
2
2
|
|
|
3
|
-
> **One CLI.
|
|
3
|
+
> **One CLI. 100,000+ skills. 29 AI agents.**
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/agent-skills-cli)
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
|
|
8
|
-
Install skills from the world's largest marketplace and sync them to **Cursor
|
|
8
|
+
Install skills from the world's largest marketplace and sync them to **29 AI agents** including Cursor, Claude Code, GitHub Copilot, Windsurf, Cline, Gemini CLI, and more ā all with a single command.
|
|
9
9
|
|
|
10
10
|
š **Website:** [agentskills.in](https://agentskills.in)
|
|
11
11
|
|
|
@@ -18,13 +18,14 @@ skills install @anthropic/xlsx
|
|
|
18
18
|
|
|
19
19
|
## ⨠Features
|
|
20
20
|
|
|
21
|
-
- **
|
|
22
|
-
- **
|
|
21
|
+
- **100,000+ Skills** ā Access the largest collection of AI agent skills
|
|
22
|
+
- **Interactive Search** ā Search and install in one command: `skills search python`
|
|
23
|
+
- **29 AI Agents** ā Cursor, Claude, Copilot, Windsurf, Cline, Gemini CLI, and 23 more
|
|
23
24
|
- **Global Install** ā Install globally with `-g` or to project with default
|
|
24
|
-
- **Git URL Support** ā Install from
|
|
25
|
+
- **Git URL Support** ā Install from GitHub, GitLab, or local paths
|
|
25
26
|
- **Platform Targeting** ā Install to specific platforms with `-t claude,cursor`
|
|
26
|
-
- **
|
|
27
|
-
- **
|
|
27
|
+
- **Update Tracking** ā Check installed skills with `skills check`
|
|
28
|
+
- **Privacy-First Telemetry** ā Anonymous usage tracking with opt-out
|
|
28
29
|
|
|
29
30
|
---
|
|
30
31
|
|
|
@@ -59,8 +60,11 @@ skills add vercel-labs/agent-skills
|
|
|
59
60
|
# List skills in a repo
|
|
60
61
|
skills add owner/repo --list
|
|
61
62
|
|
|
62
|
-
# Search
|
|
63
|
-
skills search
|
|
63
|
+
# Search and install skills interactively
|
|
64
|
+
skills search python
|
|
65
|
+
|
|
66
|
+
# Search with JSON output (non-interactive)
|
|
67
|
+
skills search react --json
|
|
64
68
|
```
|
|
65
69
|
|
|
66
70
|
---
|
|
@@ -73,9 +77,9 @@ skills search "machine learning"
|
|
|
73
77
|
|---------|-------------|
|
|
74
78
|
| `skills install <name>` | Install a skill from marketplace |
|
|
75
79
|
| `skills add <source>` | Install from Git repo (owner/repo or URL) |
|
|
76
|
-
| `skills
|
|
77
|
-
| `skills
|
|
78
|
-
| `skills
|
|
80
|
+
| `skills search <query>` | Search and install skills interactively |
|
|
81
|
+
| `skills check` | Check installed skills across all agents |
|
|
82
|
+
| `skills update` | Update installed skills to latest versions |
|
|
79
83
|
| `skills doctor` | Diagnose issues |
|
|
80
84
|
|
|
81
85
|
### Install Options
|
|
@@ -112,20 +116,37 @@ skills info # Show installation status
|
|
|
112
116
|
|
|
113
117
|
---
|
|
114
118
|
|
|
115
|
-
## š¤ Supported Platforms (
|
|
116
|
-
|
|
117
|
-
| Platform | Project Dir | Global Dir |
|
|
118
|
-
|
|
119
|
-
| **Cursor** | `.cursor/skills/` | `~/.cursor/skills/` |
|
|
120
|
-
| **Claude Code** | `.claude/skills/` | `~/.claude/skills/` |
|
|
121
|
-
| **GitHub Copilot** | `.github/skills/` | `~/.github/skills/` |
|
|
122
|
-
| **OpenAI Codex** | `.codex/skills/` | `~/.codex/skills/` |
|
|
123
|
-
| **
|
|
124
|
-
| **
|
|
125
|
-
| **
|
|
126
|
-
| **
|
|
127
|
-
| **
|
|
128
|
-
| **
|
|
119
|
+
## š¤ Supported Platforms (29 Agents)
|
|
120
|
+
|
|
121
|
+
| Platform | Project Dir | Global Dir |
|
|
122
|
+
|----------|-------------|------------|
|
|
123
|
+
| **Cursor** | `.cursor/skills/` | `~/.cursor/skills/` |
|
|
124
|
+
| **Claude Code** | `.claude/skills/` | `~/.claude/skills/` |
|
|
125
|
+
| **GitHub Copilot** | `.github/skills/` | `~/.github/skills/` |
|
|
126
|
+
| **OpenAI Codex** | `.codex/skills/` | `~/.codex/skills/` |
|
|
127
|
+
| **Windsurf** | `.windsurf/skills/` | `~/.codeium/windsurf/skills/` |
|
|
128
|
+
| **Cline** | `.cline/skills/` | `~/.cline/skills/` |
|
|
129
|
+
| **Gemini CLI** | `.gemini/skills/` | `~/.gemini/skills/` |
|
|
130
|
+
| **Antigravity** | `.agent/skills/` | `~/.gemini/antigravity/skills/` |
|
|
131
|
+
| **OpenCode** | `.opencode/skill/` | `~/.config/opencode/skill/` |
|
|
132
|
+
| **Amp** | `.agents/skills/` | `~/.config/agents/skills/` |
|
|
133
|
+
|
|
134
|
+
**+19 more agents:** Kilo, Roo, Goose, CodeBuddy, Continue, Crush, Clawdbot, Droid, Kiro, MCPJam, Mux, OpenHands, Pi, Qoder, Qwen Code, Trae, Zencoder, Neovate, Command Code
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## š Privacy & Telemetry
|
|
139
|
+
|
|
140
|
+
The CLI collects anonymous usage data to improve the product. **No personal data is collected.**
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Opt out of telemetry
|
|
144
|
+
export DISABLE_TELEMETRY=1
|
|
145
|
+
# or
|
|
146
|
+
export DO_NOT_TRACK=1
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Telemetry is automatically disabled in CI environments.
|
|
129
150
|
|
|
130
151
|
---
|
|
131
152
|
|
package/dist/cli/index.js
CHANGED
|
@@ -8,7 +8,9 @@ import chalk from 'chalk';
|
|
|
8
8
|
import inquirer from 'inquirer';
|
|
9
9
|
import ora from 'ora';
|
|
10
10
|
import * as p from '@clack/prompts';
|
|
11
|
-
import { discoverSkills, loadSkill, validateMetadata, validateBody, formatValidationResult, generateSkillsPromptXML, generateFullSkillsContext, listSkillResources, listMarketplaceSkills, installSkill, uninstallSkill, searchSkills, getInstalledSkills, listMarketplaces, addMarketplace, checkUpdates, installFromGitHubUrl, getSkillByScoped, getSkillBaseUrl, fetchAssetManifest, getAssetUrl, fetchAsset, fetchSkillsForCLI
|
|
11
|
+
import { discoverSkills, loadSkill, validateMetadata, validateBody, formatValidationResult, generateSkillsPromptXML, generateFullSkillsContext, listSkillResources, listMarketplaceSkills, installSkill, uninstallSkill, searchSkills, getInstalledSkills, listMarketplaces, addMarketplace, checkUpdates, installFromGitHubUrl, getSkillByScoped, getSkillBaseUrl, fetchAssetManifest, getAssetUrl, fetchAsset, fetchSkillsForCLI,
|
|
12
|
+
// Telemetry
|
|
13
|
+
setVersion, trackSearch } from '../core/index.js';
|
|
12
14
|
import { homedir } from 'os';
|
|
13
15
|
// Centralized agent configuration with project and global paths
|
|
14
16
|
const home = homedir();
|
|
@@ -74,6 +76,121 @@ const AGENTS = {
|
|
|
74
76
|
projectDir: '.goose/skills',
|
|
75
77
|
globalDir: `${home}/.config/goose/skills`,
|
|
76
78
|
},
|
|
79
|
+
// New agents from vercel-labs/skills (19 additional)
|
|
80
|
+
'cline': {
|
|
81
|
+
name: 'cline',
|
|
82
|
+
displayName: 'Cline',
|
|
83
|
+
projectDir: '.cline/skills',
|
|
84
|
+
globalDir: `${home}/.cline/skills`,
|
|
85
|
+
},
|
|
86
|
+
'codebuddy': {
|
|
87
|
+
name: 'codebuddy',
|
|
88
|
+
displayName: 'CodeBuddy',
|
|
89
|
+
projectDir: '.codebuddy/skills',
|
|
90
|
+
globalDir: `${home}/.codebuddy/skills`,
|
|
91
|
+
},
|
|
92
|
+
'command-code': {
|
|
93
|
+
name: 'command-code',
|
|
94
|
+
displayName: 'Command Code',
|
|
95
|
+
projectDir: '.commandcode/skills',
|
|
96
|
+
globalDir: `${home}/.commandcode/skills`,
|
|
97
|
+
},
|
|
98
|
+
'continue': {
|
|
99
|
+
name: 'continue',
|
|
100
|
+
displayName: 'Continue',
|
|
101
|
+
projectDir: '.continue/skills',
|
|
102
|
+
globalDir: `${home}/.continue/skills`,
|
|
103
|
+
},
|
|
104
|
+
'crush': {
|
|
105
|
+
name: 'crush',
|
|
106
|
+
displayName: 'Crush',
|
|
107
|
+
projectDir: '.crush/skills',
|
|
108
|
+
globalDir: `${home}/.config/crush/skills`,
|
|
109
|
+
},
|
|
110
|
+
'clawdbot': {
|
|
111
|
+
name: 'clawdbot',
|
|
112
|
+
displayName: 'Clawdbot',
|
|
113
|
+
projectDir: 'skills',
|
|
114
|
+
globalDir: `${home}/.clawdbot/skills`,
|
|
115
|
+
},
|
|
116
|
+
'droid': {
|
|
117
|
+
name: 'droid',
|
|
118
|
+
displayName: 'Droid',
|
|
119
|
+
projectDir: '.factory/skills',
|
|
120
|
+
globalDir: `${home}/.factory/skills`,
|
|
121
|
+
},
|
|
122
|
+
'gemini-cli': {
|
|
123
|
+
name: 'gemini-cli',
|
|
124
|
+
displayName: 'Gemini CLI',
|
|
125
|
+
projectDir: '.gemini/skills',
|
|
126
|
+
globalDir: `${home}/.gemini/skills`,
|
|
127
|
+
},
|
|
128
|
+
'kiro-cli': {
|
|
129
|
+
name: 'kiro-cli',
|
|
130
|
+
displayName: 'Kiro CLI',
|
|
131
|
+
projectDir: '.kiro/skills',
|
|
132
|
+
globalDir: `${home}/.kiro/skills`,
|
|
133
|
+
},
|
|
134
|
+
'mcpjam': {
|
|
135
|
+
name: 'mcpjam',
|
|
136
|
+
displayName: 'MCPJam',
|
|
137
|
+
projectDir: '.mcpjam/skills',
|
|
138
|
+
globalDir: `${home}/.mcpjam/skills`,
|
|
139
|
+
},
|
|
140
|
+
'mux': {
|
|
141
|
+
name: 'mux',
|
|
142
|
+
displayName: 'Mux',
|
|
143
|
+
projectDir: '.mux/skills',
|
|
144
|
+
globalDir: `${home}/.mux/skills`,
|
|
145
|
+
},
|
|
146
|
+
'openhands': {
|
|
147
|
+
name: 'openhands',
|
|
148
|
+
displayName: 'OpenHands',
|
|
149
|
+
projectDir: '.openhands/skills',
|
|
150
|
+
globalDir: `${home}/.openhands/skills`,
|
|
151
|
+
},
|
|
152
|
+
'pi': {
|
|
153
|
+
name: 'pi',
|
|
154
|
+
displayName: 'Pi',
|
|
155
|
+
projectDir: '.pi/skills',
|
|
156
|
+
globalDir: `${home}/.pi/agent/skills`,
|
|
157
|
+
},
|
|
158
|
+
'qoder': {
|
|
159
|
+
name: 'qoder',
|
|
160
|
+
displayName: 'Qoder',
|
|
161
|
+
projectDir: '.qoder/skills',
|
|
162
|
+
globalDir: `${home}/.qoder/skills`,
|
|
163
|
+
},
|
|
164
|
+
'qwen-code': {
|
|
165
|
+
name: 'qwen-code',
|
|
166
|
+
displayName: 'Qwen Code',
|
|
167
|
+
projectDir: '.qwen/skills',
|
|
168
|
+
globalDir: `${home}/.qwen/skills`,
|
|
169
|
+
},
|
|
170
|
+
'trae': {
|
|
171
|
+
name: 'trae',
|
|
172
|
+
displayName: 'Trae',
|
|
173
|
+
projectDir: '.trae/skills',
|
|
174
|
+
globalDir: `${home}/.trae/skills`,
|
|
175
|
+
},
|
|
176
|
+
'windsurf': {
|
|
177
|
+
name: 'windsurf',
|
|
178
|
+
displayName: 'Windsurf',
|
|
179
|
+
projectDir: '.windsurf/skills',
|
|
180
|
+
globalDir: `${home}/.codeium/windsurf/skills`,
|
|
181
|
+
},
|
|
182
|
+
'zencoder': {
|
|
183
|
+
name: 'zencoder',
|
|
184
|
+
displayName: 'Zencoder',
|
|
185
|
+
projectDir: '.zencoder/skills',
|
|
186
|
+
globalDir: `${home}/.zencoder/skills`,
|
|
187
|
+
},
|
|
188
|
+
'neovate': {
|
|
189
|
+
name: 'neovate',
|
|
190
|
+
displayName: 'Neovate',
|
|
191
|
+
projectDir: '.neovate/skills',
|
|
192
|
+
globalDir: `${home}/.neovate/skills`,
|
|
193
|
+
},
|
|
77
194
|
};
|
|
78
195
|
// Helper to get install path
|
|
79
196
|
function getInstallPath(agent, global) {
|
|
@@ -83,6 +200,8 @@ function getInstallPath(agent, global) {
|
|
|
83
200
|
return global ? config.globalDir : config.projectDir;
|
|
84
201
|
}
|
|
85
202
|
const program = new Command();
|
|
203
|
+
// Initialize telemetry with CLI version
|
|
204
|
+
setVersion('1.0.23');
|
|
86
205
|
// Main flow when running `skills` - go straight to install
|
|
87
206
|
async function showMainMenu() {
|
|
88
207
|
console.log('');
|
|
@@ -827,6 +946,177 @@ program
|
|
|
827
946
|
process.exit(1);
|
|
828
947
|
}
|
|
829
948
|
});
|
|
949
|
+
// ============================================
|
|
950
|
+
// SEARCH COMMAND - Main user-facing search
|
|
951
|
+
// ============================================
|
|
952
|
+
program
|
|
953
|
+
.command('search <query...>')
|
|
954
|
+
.alias('s')
|
|
955
|
+
.description('Search and install skills from marketplace (67K+ skills)')
|
|
956
|
+
.option('-l, --limit <n>', 'Maximum results to show', '20')
|
|
957
|
+
.option('-s, --sort <by>', 'Sort by: stars, recent, name', 'stars')
|
|
958
|
+
.option('--json', 'Output as JSON for scripting (no interactive prompt)')
|
|
959
|
+
.action(async (queryParts, options) => {
|
|
960
|
+
try {
|
|
961
|
+
const query = queryParts.join(' ');
|
|
962
|
+
const limit = parseInt(options.limit) || 20;
|
|
963
|
+
if (!options.json) {
|
|
964
|
+
console.log(chalk.bold(`\nš Searching for "${query}"...\n`));
|
|
965
|
+
}
|
|
966
|
+
// Fetch results from database
|
|
967
|
+
let result;
|
|
968
|
+
try {
|
|
969
|
+
result = await fetchSkillsForCLI({
|
|
970
|
+
search: query,
|
|
971
|
+
limit,
|
|
972
|
+
sortBy: options.sort
|
|
973
|
+
});
|
|
974
|
+
}
|
|
975
|
+
catch {
|
|
976
|
+
// Fallback to GitHub sources
|
|
977
|
+
if (!options.json) {
|
|
978
|
+
console.log(chalk.gray('Falling back to GitHub sources...'));
|
|
979
|
+
}
|
|
980
|
+
const skills = await searchSkills(query);
|
|
981
|
+
result = { skills: skills.slice(0, limit), total: skills.length };
|
|
982
|
+
}
|
|
983
|
+
// Track search telemetry
|
|
984
|
+
trackSearch(query, result.total);
|
|
985
|
+
if (result.skills.length === 0) {
|
|
986
|
+
if (options.json) {
|
|
987
|
+
console.log(JSON.stringify({ skills: [], total: 0, query }));
|
|
988
|
+
}
|
|
989
|
+
else {
|
|
990
|
+
console.log(chalk.yellow(`No skills found matching "${query}"`));
|
|
991
|
+
}
|
|
992
|
+
return;
|
|
993
|
+
}
|
|
994
|
+
// JSON output (non-interactive)
|
|
995
|
+
if (options.json) {
|
|
996
|
+
console.log(JSON.stringify({
|
|
997
|
+
skills: result.skills.map(s => ({
|
|
998
|
+
name: s.name,
|
|
999
|
+
author: s.author,
|
|
1000
|
+
scopedName: s.scopedName || `${s.author}/${s.name}`,
|
|
1001
|
+
description: s.description,
|
|
1002
|
+
stars: s.stars || 0,
|
|
1003
|
+
githubUrl: s.githubUrl
|
|
1004
|
+
})),
|
|
1005
|
+
total: result.total,
|
|
1006
|
+
query
|
|
1007
|
+
}, null, 2));
|
|
1008
|
+
return;
|
|
1009
|
+
}
|
|
1010
|
+
// Display results summary
|
|
1011
|
+
console.log(chalk.gray(`Found ${result.total.toLocaleString()} skills. Select to install:\n`));
|
|
1012
|
+
// Interactive install - always show selection prompt
|
|
1013
|
+
const choices = result.skills.map((skill) => ({
|
|
1014
|
+
name: `${skill.name} ${skill.stars ? chalk.yellow(`ā${skill.stars.toLocaleString()}`) : ''} ${chalk.dim(`@${skill.author || 'unknown'}`)}`,
|
|
1015
|
+
value: {
|
|
1016
|
+
name: skill.name,
|
|
1017
|
+
scopedName: skill.scopedName || `${skill.author}/${skill.name}`,
|
|
1018
|
+
githubUrl: skill.githubUrl || ''
|
|
1019
|
+
},
|
|
1020
|
+
short: skill.name
|
|
1021
|
+
}));
|
|
1022
|
+
const { selectedSkills } = await inquirer.prompt([
|
|
1023
|
+
{
|
|
1024
|
+
type: 'checkbox',
|
|
1025
|
+
name: 'selectedSkills',
|
|
1026
|
+
message: 'Select skills (Space to select, Enter to confirm):',
|
|
1027
|
+
choices,
|
|
1028
|
+
pageSize: 15,
|
|
1029
|
+
loop: false
|
|
1030
|
+
}
|
|
1031
|
+
]);
|
|
1032
|
+
if (selectedSkills.length === 0) {
|
|
1033
|
+
console.log(chalk.yellow('\nNo skills selected.\n'));
|
|
1034
|
+
return;
|
|
1035
|
+
}
|
|
1036
|
+
// Select platforms
|
|
1037
|
+
const agentChoices = Object.entries(AGENTS).map(([key, config]) => ({
|
|
1038
|
+
name: config.displayName,
|
|
1039
|
+
value: key,
|
|
1040
|
+
checked: ['cursor', 'claude', 'copilot', 'antigravity'].includes(key)
|
|
1041
|
+
}));
|
|
1042
|
+
const { platforms } = await inquirer.prompt([
|
|
1043
|
+
{
|
|
1044
|
+
type: 'checkbox',
|
|
1045
|
+
name: 'platforms',
|
|
1046
|
+
message: 'Install to which platforms?',
|
|
1047
|
+
choices: agentChoices,
|
|
1048
|
+
pageSize: 10
|
|
1049
|
+
}
|
|
1050
|
+
]);
|
|
1051
|
+
if (platforms.length === 0) {
|
|
1052
|
+
console.log(chalk.yellow('\nNo platforms selected.\n'));
|
|
1053
|
+
return;
|
|
1054
|
+
}
|
|
1055
|
+
// Install skills
|
|
1056
|
+
const { mkdir, cp, rm } = await import('fs/promises');
|
|
1057
|
+
const { join } = await import('path');
|
|
1058
|
+
const { tmpdir } = await import('os');
|
|
1059
|
+
const { exec } = await import('child_process');
|
|
1060
|
+
const { promisify } = await import('util');
|
|
1061
|
+
const execAsync = promisify(exec);
|
|
1062
|
+
console.log(chalk.bold(`\nš¦ Installing ${selectedSkills.length} skill(s)...\n`));
|
|
1063
|
+
for (const skill of selectedSkills) {
|
|
1064
|
+
const installSpinner = ora(`Installing ${skill.name}...`).start();
|
|
1065
|
+
try {
|
|
1066
|
+
// Fetch skill details
|
|
1067
|
+
const { getSkillByScoped } = await import('../core/skillsdb.js');
|
|
1068
|
+
const dbSkill = await getSkillByScoped(skill.scopedName);
|
|
1069
|
+
if (!dbSkill) {
|
|
1070
|
+
installSpinner.fail(`${skill.name}: Not found`);
|
|
1071
|
+
continue;
|
|
1072
|
+
}
|
|
1073
|
+
const githubUrl = dbSkill.github_url || dbSkill.githubUrl;
|
|
1074
|
+
if (!githubUrl) {
|
|
1075
|
+
installSpinner.fail(`${skill.name}: No GitHub URL`);
|
|
1076
|
+
continue;
|
|
1077
|
+
}
|
|
1078
|
+
// Parse GitHub URL
|
|
1079
|
+
const urlMatch = githubUrl.match(/github\.com\/([^\/]+)\/([^\/]+)/);
|
|
1080
|
+
if (!urlMatch) {
|
|
1081
|
+
installSpinner.fail(`${skill.name}: Invalid GitHub URL`);
|
|
1082
|
+
continue;
|
|
1083
|
+
}
|
|
1084
|
+
const [, owner, repo] = urlMatch;
|
|
1085
|
+
const branch = dbSkill.branch || 'main';
|
|
1086
|
+
const skillPath = (dbSkill.path || '').replace(/\/SKILL\.md$/i, '');
|
|
1087
|
+
// Clone to temp
|
|
1088
|
+
const tempDir = join(tmpdir(), `skill-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
1089
|
+
await mkdir(tempDir, { recursive: true });
|
|
1090
|
+
try {
|
|
1091
|
+
await execAsync(`git clone --depth 1 --branch ${branch} https://github.com/${owner}/${repo}.git .`, { cwd: tempDir });
|
|
1092
|
+
// Copy to each platform
|
|
1093
|
+
for (const platform of platforms) {
|
|
1094
|
+
const agentConfig = AGENTS[platform];
|
|
1095
|
+
if (!agentConfig)
|
|
1096
|
+
continue;
|
|
1097
|
+
const targetDir = agentConfig.projectDir;
|
|
1098
|
+
const skillDir = join(process.cwd(), targetDir, dbSkill.name);
|
|
1099
|
+
await mkdir(skillDir, { recursive: true });
|
|
1100
|
+
const sourceDir = skillPath ? join(tempDir, skillPath) : tempDir;
|
|
1101
|
+
await cp(sourceDir, skillDir, { recursive: true });
|
|
1102
|
+
}
|
|
1103
|
+
installSpinner.succeed(`${skill.name} ā ${platforms.join(', ')}`);
|
|
1104
|
+
}
|
|
1105
|
+
finally {
|
|
1106
|
+
await rm(tempDir, { recursive: true, force: true }).catch(() => { });
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
catch (err) {
|
|
1110
|
+
installSpinner.fail(`${skill.name}: ${err.message || err}`);
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
console.log(chalk.bold.green(`\n⨠Installation complete!\n`));
|
|
1114
|
+
}
|
|
1115
|
+
catch (error) {
|
|
1116
|
+
console.error(chalk.red('Error searching:'), error);
|
|
1117
|
+
process.exit(1);
|
|
1118
|
+
}
|
|
1119
|
+
});
|
|
830
1120
|
// Install - Install a skill by scoped name (e.g., @author/skill or author/skill)
|
|
831
1121
|
program
|
|
832
1122
|
.command('install <scoped-name> [platforms...]')
|
|
@@ -2333,5 +2623,71 @@ program
|
|
|
2333
2623
|
process.exit(1);
|
|
2334
2624
|
}
|
|
2335
2625
|
});
|
|
2626
|
+
// ============================================
|
|
2627
|
+
// CHECK COMMAND - Check for skill updates
|
|
2628
|
+
// ============================================
|
|
2629
|
+
program
|
|
2630
|
+
.command('check')
|
|
2631
|
+
.description('Check for available skill updates')
|
|
2632
|
+
.option('-a, --agent <agent>', 'Check specific agent only')
|
|
2633
|
+
.option('-g, --global', 'Check globally installed skills')
|
|
2634
|
+
.option('--json', 'Output as JSON')
|
|
2635
|
+
.action(async (options) => {
|
|
2636
|
+
try {
|
|
2637
|
+
const spinner = ora('Checking for updates...').start();
|
|
2638
|
+
// Get list of agents to check
|
|
2639
|
+
const agentsToCheck = options.agent
|
|
2640
|
+
? [options.agent]
|
|
2641
|
+
: Object.keys(AGENTS);
|
|
2642
|
+
const updates = [];
|
|
2643
|
+
for (const agentName of agentsToCheck) {
|
|
2644
|
+
const config = AGENTS[agentName];
|
|
2645
|
+
if (!config)
|
|
2646
|
+
continue;
|
|
2647
|
+
const skillsDir = options.global ? config.globalDir : config.projectDir;
|
|
2648
|
+
try {
|
|
2649
|
+
const { existsSync, readdirSync } = await import('fs');
|
|
2650
|
+
if (!existsSync(skillsDir))
|
|
2651
|
+
continue;
|
|
2652
|
+
const skills = readdirSync(skillsDir, { withFileTypes: true })
|
|
2653
|
+
.filter(d => d.isDirectory())
|
|
2654
|
+
.map(d => d.name);
|
|
2655
|
+
for (const skill of skills) {
|
|
2656
|
+
// Check if skill has updates available
|
|
2657
|
+
// For now, just list installed skills
|
|
2658
|
+
updates.push({
|
|
2659
|
+
skill,
|
|
2660
|
+
agent: config.displayName,
|
|
2661
|
+
currentVersion: 'installed',
|
|
2662
|
+
latestVersion: 'check online',
|
|
2663
|
+
path: `${skillsDir}/${skill}`,
|
|
2664
|
+
});
|
|
2665
|
+
}
|
|
2666
|
+
}
|
|
2667
|
+
catch {
|
|
2668
|
+
// Skip if can't read directory
|
|
2669
|
+
}
|
|
2670
|
+
}
|
|
2671
|
+
spinner.stop();
|
|
2672
|
+
if (options.json) {
|
|
2673
|
+
console.log(JSON.stringify({ updates, count: updates.length }, null, 2));
|
|
2674
|
+
return;
|
|
2675
|
+
}
|
|
2676
|
+
if (updates.length === 0) {
|
|
2677
|
+
console.log(chalk.green('ā No skills installed to check.'));
|
|
2678
|
+
return;
|
|
2679
|
+
}
|
|
2680
|
+
console.log(chalk.bold(`\nš¦ Found ${updates.length} installed skill(s):\n`));
|
|
2681
|
+
for (const update of updates) {
|
|
2682
|
+
console.log(` ${chalk.cyan(update.skill)} ${chalk.gray(`(${update.agent})`)}`);
|
|
2683
|
+
console.log(chalk.gray(` ${update.path}`));
|
|
2684
|
+
}
|
|
2685
|
+
console.log(chalk.gray('\nTip: Run `skills update` to update all skills.\n'));
|
|
2686
|
+
}
|
|
2687
|
+
catch (error) {
|
|
2688
|
+
console.error(chalk.red('Error checking for updates:'), error);
|
|
2689
|
+
process.exit(1);
|
|
2690
|
+
}
|
|
2691
|
+
});
|
|
2336
2692
|
program.parse();
|
|
2337
2693
|
//# sourceMappingURL=index.js.map
|