ai-common-skills 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/README.md +66 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +17 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/info.d.ts +3 -0
- package/dist/commands/info.d.ts.map +1 -0
- package/dist/commands/info.js +36 -0
- package/dist/commands/info.js.map +1 -0
- package/dist/commands/install.d.ts +3 -0
- package/dist/commands/install.d.ts.map +1 -0
- package/dist/commands/install.js +119 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/list.d.ts +3 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +30 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/search.d.ts +3 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +27 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/helpers.d.ts +12 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +21 -0
- package/dist/helpers.js.map +1 -0
- package/dist/indexer.d.ts +4 -0
- package/dist/indexer.d.ts.map +1 -0
- package/dist/indexer.js +42 -0
- package/dist/indexer.js.map +1 -0
- package/dist/validate-all.d.ts +2 -0
- package/dist/validate-all.d.ts.map +1 -0
- package/dist/validate-all.js +35 -0
- package/dist/validate-all.js.map +1 -0
- package/dist/validator.d.ts +34 -0
- package/dist/validator.d.ts.map +1 -0
- package/dist/validator.js +105 -0
- package/dist/validator.js.map +1 -0
- package/package.json +39 -0
- package/skill-index.json +54 -0
- package/skills/openspec-apply-change/SKILL.md +156 -0
- package/skills/openspec-apply-change/metadata.json +6 -0
- package/skills/openspec-archive-change/SKILL.md +114 -0
- package/skills/openspec-archive-change/metadata.json +6 -0
- package/skills/openspec-explore/SKILL.md +288 -0
- package/skills/openspec-explore/metadata.json +6 -0
- package/skills/openspec-propose/SKILL.md +110 -0
- package/skills/openspec-propose/metadata.json +6 -0
package/README.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# ai-common-skills
|
|
2
|
+
|
|
3
|
+
A curated registry of AI agent skills for **Cursor** and **Claude Code**. Install skills to your project with a single command.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g ai-common-skills
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### List available skills
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
ai-skills list
|
|
17
|
+
ai-skills list --tag openspec
|
|
18
|
+
ai-skills list --platform cursor
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Search skills
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
ai-skills search "workflow"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Show skill details
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
ai-skills info openspec-propose
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Install skills to your project
|
|
34
|
+
|
|
35
|
+
Interactive mode — select tools and skills from a checklist:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
ai-skills install
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Direct mode — install a specific skill to one or more targets:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
ai-skills install openspec-propose --target cursor
|
|
45
|
+
ai-skills install openspec-propose --target cursor,claude-code
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Available Skills
|
|
49
|
+
|
|
50
|
+
| Skill | Description |
|
|
51
|
+
|-------|-------------|
|
|
52
|
+
| `openspec-propose` | Propose a new change with all artifacts in one step |
|
|
53
|
+
| `openspec-explore` | Explore ideas, investigate problems, clarify requirements |
|
|
54
|
+
| `openspec-apply-change` | Implement tasks from an OpenSpec change |
|
|
55
|
+
| `openspec-archive-change` | Archive a completed change after implementation |
|
|
56
|
+
|
|
57
|
+
## Contributing
|
|
58
|
+
|
|
59
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for how to add new skills.
|
|
60
|
+
|
|
61
|
+
## Development
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npm run build # Regenerate skill-index.json
|
|
65
|
+
npm run validate # Validate all skills
|
|
66
|
+
```
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { registerListCommand } from './commands/list.js';
|
|
4
|
+
import { registerSearchCommand } from './commands/search.js';
|
|
5
|
+
import { registerInfoCommand } from './commands/info.js';
|
|
6
|
+
import { registerInstallCommand } from './commands/install.js';
|
|
7
|
+
const program = new Command();
|
|
8
|
+
program
|
|
9
|
+
.name('ai-skills')
|
|
10
|
+
.description('Install and manage AI agent skills for Cursor and Claude Code')
|
|
11
|
+
.version('0.1.0');
|
|
12
|
+
registerListCommand(program);
|
|
13
|
+
registerSearchCommand(program);
|
|
14
|
+
registerInfoCommand(program);
|
|
15
|
+
registerInstallCommand(program);
|
|
16
|
+
program.parse();
|
|
17
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,+DAA+D,CAAC;KAC5E,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAEhC,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"info.d.ts","sourceRoot":"","sources":["../../src/commands/info.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoC1D"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { loadIndex, getSkillSourceDir } from '../helpers.js';
|
|
5
|
+
export function registerInfoCommand(program) {
|
|
6
|
+
program
|
|
7
|
+
.command('info <skill-name>')
|
|
8
|
+
.description('Show detailed info about a skill')
|
|
9
|
+
.action((skillName) => {
|
|
10
|
+
const skills = loadIndex();
|
|
11
|
+
const skill = skills.find((s) => s.name === skillName);
|
|
12
|
+
if (!skill) {
|
|
13
|
+
console.log(chalk.red(`Skill "${skillName}" not found.`));
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
console.log(chalk.bold.cyan(`\n ${skill.name}\n`));
|
|
17
|
+
console.log(` ${chalk.bold('Description:')} ${skill.description}`);
|
|
18
|
+
console.log(` ${chalk.bold('Tags:')} ${skill.tags.length > 0 ? skill.tags.join(', ') : chalk.dim('none')}`);
|
|
19
|
+
console.log(` ${chalk.bold('Platforms:')} ${skill.platforms.join(', ')}`);
|
|
20
|
+
const skillMdPath = path.join(getSkillSourceDir(skillName), 'SKILL.md');
|
|
21
|
+
if (fs.existsSync(skillMdPath)) {
|
|
22
|
+
const content = fs.readFileSync(skillMdPath, 'utf-8');
|
|
23
|
+
const preview = content.split('\n').slice(0, 15).join('\n');
|
|
24
|
+
console.log(`\n${chalk.bold(' Preview:')}\n`);
|
|
25
|
+
console.log(preview
|
|
26
|
+
.split('\n')
|
|
27
|
+
.map((l) => ` ${chalk.dim(l)}`)
|
|
28
|
+
.join('\n'));
|
|
29
|
+
if (content.split('\n').length > 15) {
|
|
30
|
+
console.log(chalk.dim(' ...'));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
console.log();
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=info.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"info.js","sourceRoot":"","sources":["../../src/commands/info.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE7D,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,OAAO;SACJ,OAAO,CAAC,mBAAmB,CAAC;SAC5B,WAAW,CAAC,kCAAkC,CAAC;SAC/C,MAAM,CAAC,CAAC,SAAiB,EAAE,EAAE;QAC5B,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;QAEvD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,SAAS,cAAc,CAAC,CAAC,CAAC;YAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;QACrE,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACrH,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAE9E,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,CAAC;QACxE,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/B,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YACtD,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC5D,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YAC/C,OAAO,CAAC,GAAG,CACT,OAAO;iBACJ,KAAK,CAAC,IAAI,CAAC;iBACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;iBACjC,IAAI,CAAC,IAAI,CAAC,CACd,CAAC;YACF,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;gBACpC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqEzC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA4D7D"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { checkbox, confirm } from '@inquirer/prompts';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import fsExtra from 'fs-extra';
|
|
6
|
+
import { loadIndex, getSkillSourceDir, TOOL_TARGETS } from '../helpers.js';
|
|
7
|
+
async function selectTools() {
|
|
8
|
+
const toolKeys = Object.keys(TOOL_TARGETS);
|
|
9
|
+
const choices = [
|
|
10
|
+
{ name: 'Select All', value: '__all__' },
|
|
11
|
+
...toolKeys.map((key) => ({ name: TOOL_TARGETS[key].label, value: key })),
|
|
12
|
+
];
|
|
13
|
+
const selected = await checkbox({
|
|
14
|
+
message: 'Select target tools:',
|
|
15
|
+
choices,
|
|
16
|
+
});
|
|
17
|
+
if (selected.includes('__all__')) {
|
|
18
|
+
return toolKeys;
|
|
19
|
+
}
|
|
20
|
+
return selected.filter((s) => s !== '__all__');
|
|
21
|
+
}
|
|
22
|
+
async function selectSkills(skills) {
|
|
23
|
+
const choices = [
|
|
24
|
+
{ name: 'Select All', value: '__all__' },
|
|
25
|
+
...skills.map((s) => ({
|
|
26
|
+
name: `${s.name} ${chalk.dim('- ' + s.description)}`,
|
|
27
|
+
value: s.name,
|
|
28
|
+
})),
|
|
29
|
+
];
|
|
30
|
+
const selected = await checkbox({
|
|
31
|
+
message: 'Select skills to install:',
|
|
32
|
+
choices,
|
|
33
|
+
});
|
|
34
|
+
if (selected.includes('__all__')) {
|
|
35
|
+
return skills.map((s) => s.name);
|
|
36
|
+
}
|
|
37
|
+
return selected.filter((s) => s !== '__all__');
|
|
38
|
+
}
|
|
39
|
+
async function installSkill(skillName, targetDir) {
|
|
40
|
+
const sourceDir = getSkillSourceDir(skillName);
|
|
41
|
+
const destDir = path.join(process.cwd(), targetDir, skillName);
|
|
42
|
+
if (fs.existsSync(destDir)) {
|
|
43
|
+
const overwrite = await confirm({
|
|
44
|
+
message: `"${skillName}" already exists in ${targetDir}. Overwrite?`,
|
|
45
|
+
default: false,
|
|
46
|
+
});
|
|
47
|
+
if (!overwrite) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
await fsExtra.copy(sourceDir, destDir, { overwrite: true });
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
function parseTargets(targetStr) {
|
|
55
|
+
return targetStr
|
|
56
|
+
.split(',')
|
|
57
|
+
.map((t) => t.trim().toLowerCase())
|
|
58
|
+
.filter((t) => t in TOOL_TARGETS);
|
|
59
|
+
}
|
|
60
|
+
export function registerInstallCommand(program) {
|
|
61
|
+
program
|
|
62
|
+
.command('install [skill-name]')
|
|
63
|
+
.description('Install skills to your project')
|
|
64
|
+
.option('--target <tools>', 'Target tools, comma-separated (cursor, claude-code)')
|
|
65
|
+
.action(async (skillName, opts) => {
|
|
66
|
+
const allSkills = loadIndex();
|
|
67
|
+
if (allSkills.length === 0) {
|
|
68
|
+
console.log(chalk.yellow('No skills available. Run "npm run build" first.'));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
let targets;
|
|
72
|
+
if (opts.target) {
|
|
73
|
+
targets = parseTargets(opts.target);
|
|
74
|
+
if (targets.length === 0) {
|
|
75
|
+
console.log(chalk.red(`Invalid target "${opts.target}". Use: cursor, claude-code`));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
targets = await selectTools();
|
|
81
|
+
if (targets.length === 0) {
|
|
82
|
+
console.log(chalk.yellow('No tools selected.'));
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
let skillNames;
|
|
87
|
+
if (skillName) {
|
|
88
|
+
const exists = allSkills.find((s) => s.name === skillName);
|
|
89
|
+
if (!exists) {
|
|
90
|
+
console.log(chalk.red(`Skill "${skillName}" not found.`));
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
skillNames = [skillName];
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
skillNames = await selectSkills(allSkills);
|
|
97
|
+
if (skillNames.length === 0) {
|
|
98
|
+
console.log(chalk.yellow('No skills selected.'));
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
for (const targetKey of targets) {
|
|
103
|
+
const { label, dir } = TOOL_TARGETS[targetKey];
|
|
104
|
+
let installed = 0;
|
|
105
|
+
for (const name of skillNames) {
|
|
106
|
+
const ok = await installSkill(name, dir);
|
|
107
|
+
if (ok)
|
|
108
|
+
installed++;
|
|
109
|
+
}
|
|
110
|
+
if (installed > 0) {
|
|
111
|
+
console.log(chalk.green(`✔ Installed ${installed} skill(s) to ${dir}/`));
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
console.log(chalk.dim(` Skipped ${label} — no skills installed`));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
//# 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":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgC1D"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { loadIndex } from '../helpers.js';
|
|
3
|
+
export function registerListCommand(program) {
|
|
4
|
+
program
|
|
5
|
+
.command('list')
|
|
6
|
+
.description('List all available skills')
|
|
7
|
+
.option('--tag <tag>', 'Filter by tag')
|
|
8
|
+
.option('--platform <platform>', 'Filter by platform (cursor | claude-code)')
|
|
9
|
+
.action((opts) => {
|
|
10
|
+
let skills = loadIndex();
|
|
11
|
+
if (opts.tag) {
|
|
12
|
+
skills = skills.filter((s) => s.tags.includes(opts.tag));
|
|
13
|
+
}
|
|
14
|
+
if (opts.platform) {
|
|
15
|
+
skills = skills.filter((s) => s.platforms.includes(opts.platform));
|
|
16
|
+
}
|
|
17
|
+
if (skills.length === 0) {
|
|
18
|
+
console.log(chalk.yellow('No skills found.'));
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const nameWidth = Math.max(20, ...skills.map((s) => s.name.length)) + 2;
|
|
22
|
+
console.log(chalk.bold('Name'.padEnd(nameWidth) + 'Description'));
|
|
23
|
+
console.log('─'.repeat(nameWidth + 40));
|
|
24
|
+
for (const skill of skills) {
|
|
25
|
+
console.log(chalk.cyan(skill.name.padEnd(nameWidth)) + (skill.description || ''));
|
|
26
|
+
}
|
|
27
|
+
console.log(`\n${chalk.dim(`${skills.length} skill(s) available`)}`);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,2BAA2B,CAAC;SACxC,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC;SACtC,MAAM,CAAC,uBAAuB,EAAE,2CAA2C,CAAC;SAC5E,MAAM,CAAC,CAAC,IAAyC,EAAE,EAAE;QACpD,IAAI,MAAM,GAAG,SAAS,EAAE,CAAC;QAEzB,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAI,CAAC,CAAC,CAAC;QAC5D,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAS,CAAC,CAAC,CAAC;QACtE,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC;YAC9C,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;QAExE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC;QAClE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC,CAAC;QAExC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC;QACpF,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,qBAAqB,CAAC,EAAE,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6B5D"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { loadIndex } from '../helpers.js';
|
|
3
|
+
export function registerSearchCommand(program) {
|
|
4
|
+
program
|
|
5
|
+
.command('search <query>')
|
|
6
|
+
.description('Search skills by keyword (name, description, tags)')
|
|
7
|
+
.action((query) => {
|
|
8
|
+
const skills = loadIndex();
|
|
9
|
+
const q = query.toLowerCase();
|
|
10
|
+
const matches = skills.filter((s) => {
|
|
11
|
+
const haystack = [s.name, s.description, ...(s.tags || [])].join(' ').toLowerCase();
|
|
12
|
+
return haystack.includes(q);
|
|
13
|
+
});
|
|
14
|
+
if (matches.length === 0) {
|
|
15
|
+
console.log(chalk.yellow(`No skills found matching "${query}"`));
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const nameWidth = Math.max(20, ...matches.map((s) => s.name.length)) + 2;
|
|
19
|
+
console.log(chalk.bold('Name'.padEnd(nameWidth) + 'Description'));
|
|
20
|
+
console.log('─'.repeat(nameWidth + 40));
|
|
21
|
+
for (const skill of matches) {
|
|
22
|
+
console.log(chalk.cyan(skill.name.padEnd(nameWidth)) + (skill.description || ''));
|
|
23
|
+
}
|
|
24
|
+
console.log(`\n${chalk.dim(`${matches.length} result(s)`)}`);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,OAAO;SACJ,OAAO,CAAC,gBAAgB,CAAC;SACzB,WAAW,CAAC,oDAAoD,CAAC;SACjE,MAAM,CAAC,CAAC,KAAa,EAAE,EAAE;QACxB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QAE9B,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YAClC,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;YACpF,OAAO,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,6BAA6B,KAAK,GAAG,CAAC,CAAC,CAAC;YACjE,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;QAEzE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC;QAClE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC,CAAC;QAExC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC;QACpF,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,YAAY,CAAC,EAAE,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SkillMetadata } from './validator.js';
|
|
2
|
+
export declare const SKILLS_DIR: string;
|
|
3
|
+
export declare const INDEX_PATH: string;
|
|
4
|
+
export interface ToolTarget {
|
|
5
|
+
label: string;
|
|
6
|
+
dir: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const TOOL_TARGETS: Record<string, ToolTarget>;
|
|
9
|
+
export type SkillIndexEntry = Pick<SkillMetadata, 'name' | 'description' | 'tags' | 'platforms'>;
|
|
10
|
+
export declare function loadIndex(): SkillIndexEntry[];
|
|
11
|
+
export declare function getSkillSourceDir(skillName: string): string;
|
|
12
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAKpD,eAAO,MAAM,UAAU,QAAoC,CAAC;AAC5D,eAAO,MAAM,UAAU,QAA8C,CAAC;AAEtE,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAGnD,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,aAAa,GAAG,MAAM,GAAG,WAAW,CAAC,CAAC;AAEjG,wBAAgB,SAAS,IAAI,eAAe,EAAE,CAK7C;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE3D"}
|
package/dist/helpers.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
5
|
+
const PROJECT_ROOT = path.resolve(__dirname, '..');
|
|
6
|
+
export const SKILLS_DIR = path.join(PROJECT_ROOT, 'skills');
|
|
7
|
+
export const INDEX_PATH = path.join(PROJECT_ROOT, 'skill-index.json');
|
|
8
|
+
export const TOOL_TARGETS = {
|
|
9
|
+
cursor: { label: 'Cursor', dir: '.cursor/skills' },
|
|
10
|
+
'claude-code': { label: 'Claude Code', dir: '.claude/skills' },
|
|
11
|
+
};
|
|
12
|
+
export function loadIndex() {
|
|
13
|
+
if (!fs.existsSync(INDEX_PATH)) {
|
|
14
|
+
throw new Error('skill-index.json not found. Run "npm run build" first.');
|
|
15
|
+
}
|
|
16
|
+
return JSON.parse(fs.readFileSync(INDEX_PATH, 'utf-8'));
|
|
17
|
+
}
|
|
18
|
+
export function getSkillSourceDir(skillName) {
|
|
19
|
+
return path.join(SKILLS_DIR, skillName);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAEnD,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;AAC5D,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;AAOtE,MAAM,CAAC,MAAM,YAAY,GAA+B;IACtD,MAAM,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,gBAAgB,EAAE;IAClD,aAAa,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,gBAAgB,EAAE;CAC/D,CAAC;AAIF,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,SAAiB;IACjD,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexer.d.ts","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAOpD,wBAAgB,UAAU,CAAC,SAAS,GAAE,MAAmB,GAAG,eAAe,EAAE,CA2B5E;AAED,wBAAgB,UAAU,CAAC,UAAU,GAAE,MAAmB,EAAE,SAAS,GAAE,MAAmB,GAAG,eAAe,EAAE,CAI7G"}
|
package/dist/indexer.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { validateSkillDir } from './validator.js';
|
|
5
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const PROJECT_ROOT = path.resolve(__dirname, '..');
|
|
7
|
+
const SKILLS_DIR = path.join(PROJECT_ROOT, 'skills');
|
|
8
|
+
const INDEX_PATH = path.join(PROJECT_ROOT, 'skill-index.json');
|
|
9
|
+
export function buildIndex(skillsDir = SKILLS_DIR) {
|
|
10
|
+
if (!fs.existsSync(skillsDir)) {
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
const entries = fs.readdirSync(skillsDir, { withFileTypes: true })
|
|
14
|
+
.filter((d) => d.isDirectory())
|
|
15
|
+
.map((d) => d.name)
|
|
16
|
+
.sort();
|
|
17
|
+
const index = [];
|
|
18
|
+
for (const dirName of entries) {
|
|
19
|
+
const skillDir = path.join(skillsDir, dirName);
|
|
20
|
+
const result = validateSkillDir(skillDir);
|
|
21
|
+
if (!result.metadata)
|
|
22
|
+
continue;
|
|
23
|
+
index.push({
|
|
24
|
+
name: result.metadata.name,
|
|
25
|
+
description: result.metadata.description,
|
|
26
|
+
tags: result.metadata.tags || [],
|
|
27
|
+
platforms: result.metadata.platforms || ['cursor', 'claude-code'],
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return index;
|
|
31
|
+
}
|
|
32
|
+
export function writeIndex(outputPath = INDEX_PATH, skillsDir = SKILLS_DIR) {
|
|
33
|
+
const index = buildIndex(skillsDir);
|
|
34
|
+
fs.writeFileSync(outputPath, JSON.stringify(index, null, 2) + '\n');
|
|
35
|
+
return index;
|
|
36
|
+
}
|
|
37
|
+
const isDirectRun = process.argv[1] && fileURLToPath(import.meta.url) === path.resolve(process.argv[1]);
|
|
38
|
+
if (isDirectRun) {
|
|
39
|
+
const index = writeIndex();
|
|
40
|
+
console.log(`Generated skill-index.json with ${index.length} skill(s).`);
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=indexer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexer.js","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGlD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AACnD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;AACrD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;AAE/D,MAAM,UAAU,UAAU,CAAC,YAAoB,UAAU;IACvD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;SAC/D,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;SAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;SAClB,IAAI,EAAE,CAAC;IAEV,MAAM,KAAK,GAAsB,EAAE,CAAC;IAEpC,KAAK,MAAM,OAAO,IAAI,OAAO,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QAE1C,IAAI,CAAC,MAAM,CAAC,QAAQ;YAAE,SAAS;QAE/B,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI;YAC1B,WAAW,EAAE,MAAM,CAAC,QAAQ,CAAC,WAAW;YACxC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,IAAI,EAAE;YAChC,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,SAAS,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC;SAClE,CAAC,CAAC;IACL,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,aAAqB,UAAU,EAAE,YAAoB,UAAU;IACxF,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IACpC,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACpE,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACxG,IAAI,WAAW,EAAE,CAAC;IAChB,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;IAC3B,OAAO,CAAC,GAAG,CAAC,mCAAmC,KAAK,CAAC,MAAM,YAAY,CAAC,CAAC;AAC3E,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-all.d.ts","sourceRoot":"","sources":["../src/validate-all.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { validateSkillDir } from './validator.js';
|
|
5
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const SKILLS_DIR = path.resolve(__dirname, '..', 'skills');
|
|
7
|
+
const entries = fs.readdirSync(SKILLS_DIR, { withFileTypes: true })
|
|
8
|
+
.filter((d) => d.isDirectory())
|
|
9
|
+
.map((d) => d.name)
|
|
10
|
+
.sort();
|
|
11
|
+
let hasErrors = false;
|
|
12
|
+
for (const dirName of entries) {
|
|
13
|
+
const skillDir = path.join(SKILLS_DIR, dirName);
|
|
14
|
+
const result = validateSkillDir(skillDir);
|
|
15
|
+
if (result.errors.length > 0) {
|
|
16
|
+
hasErrors = true;
|
|
17
|
+
console.error(`✗ ${dirName}`);
|
|
18
|
+
for (const e of result.errors)
|
|
19
|
+
console.error(` ERROR: ${e}`);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
console.log(`✓ ${dirName}`);
|
|
23
|
+
}
|
|
24
|
+
for (const w of result.warnings) {
|
|
25
|
+
console.warn(` WARN: ${w}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (hasErrors) {
|
|
29
|
+
console.error('\nValidation failed.');
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
console.log(`\nAll ${entries.length} skill(s) passed validation.`);
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=validate-all.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-all.js","sourceRoot":"","sources":["../src/validate-all.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;AAE3D,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;KAChE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;KAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;KAClB,IAAI,EAAE,CAAC;AAEV,IAAI,SAAS,GAAG,KAAK,CAAC;AAEtB,KAAK,MAAM,OAAO,IAAI,OAAO,EAAE,CAAC;IAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAE1C,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,SAAS,GAAG,IAAI,CAAC;QACjB,OAAO,CAAC,KAAK,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC;QAC9B,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM;YAAE,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;IAClE,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QAChC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC;AACH,CAAC;AAED,IAAI,SAAS,EAAE,CAAC;IACd,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;KAAM,CAAC;IACN,OAAO,CAAC,GAAG,CAAC,SAAS,OAAO,CAAC,MAAM,8BAA8B,CAAC,CAAC;AACrE,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface ValidationResult {
|
|
2
|
+
valid: boolean;
|
|
3
|
+
error?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface SkillMdValidation {
|
|
6
|
+
valid: boolean;
|
|
7
|
+
warnings: string[];
|
|
8
|
+
}
|
|
9
|
+
export interface MetadataValidation {
|
|
10
|
+
valid: boolean;
|
|
11
|
+
errors: string[];
|
|
12
|
+
warnings: string[];
|
|
13
|
+
}
|
|
14
|
+
export interface SkillMetadata {
|
|
15
|
+
name: string;
|
|
16
|
+
description: string;
|
|
17
|
+
tags: string[];
|
|
18
|
+
platforms: string[];
|
|
19
|
+
author?: string;
|
|
20
|
+
version?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface SkillDirValidation {
|
|
23
|
+
valid: boolean;
|
|
24
|
+
errors: string[];
|
|
25
|
+
warnings: string[];
|
|
26
|
+
metadata: SkillMetadata | null;
|
|
27
|
+
}
|
|
28
|
+
export declare function validateSkillName(name: string): ValidationResult;
|
|
29
|
+
export declare function validateSkillMd(content: string): SkillMdValidation;
|
|
30
|
+
export declare function parseSkillMdDescription(content: string): string;
|
|
31
|
+
export declare function validateMetadata(meta: Record<string, unknown>): MetadataValidation;
|
|
32
|
+
export declare function deriveMetadata(skillDir: string, skillMdContent: string): SkillMetadata;
|
|
33
|
+
export declare function validateSkillDir(skillDir: string): SkillDirValidation;
|
|
34
|
+
//# sourceMappingURL=validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;CAChC;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAKhE;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAYlE;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAS/D;AAKD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,kBAAkB,CA2BlF;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,aAAa,CAStF;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,CAqCrE"}
|