@olegkoval/agent-skills 1.0.0-beta.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/.claude-plugin/marketplace.json +58 -0
- package/.cursor-plugin/index.json +55 -0
- package/LICENSE +21 -0
- package/README.md +181 -0
- package/catalog/skills.json +202 -0
- package/collections/creative-tools.json +5 -0
- package/collections/docs-tools.json +5 -0
- package/collections/git-tools.json +5 -0
- package/collections/marketing.json +5 -0
- package/collections/music.json +5 -0
- package/collections/photography.json +5 -0
- package/collections/product-tools.json +5 -0
- package/collections/prompt-tools.json +5 -0
- package/collections/release-tools.json +5 -0
- package/collections/software-development.json +13 -0
- package/package.json +47 -0
- package/packages/marketing/viral-launch/SKILL.md +101 -0
- package/packages/marketing/viral-launch/adapters/claude/plugin.json +10 -0
- package/packages/marketing/viral-launch/adapters/codex/README.md +3 -0
- package/packages/marketing/viral-launch/adapters/cursor/plugin.json +6 -0
- package/packages/marketing/viral-launch/adapters/cursor/skills/viral-launch/SKILL.md +103 -0
- package/packages/marketing/viral-launch/references/external-skills.md +12 -0
- package/packages/marketing/viral-launch/references/launch-checklist.md +42 -0
- package/packages/music/fill-music-player/LICENSE +21 -0
- package/packages/music/fill-music-player/SKILL.md +108 -0
- package/packages/music/fill-music-player/adapters/claude/plugin.json +10 -0
- package/packages/music/fill-music-player/adapters/codex/README.md +3 -0
- package/packages/music/fill-music-player/adapters/cursor/plugin.json +6 -0
- package/packages/music/fill-music-player/adapters/cursor/skills/fill-music-player/SKILL.md +110 -0
- package/packages/photography/gallery/.skillfish.json +10 -0
- package/packages/photography/gallery/SKILL.md +233 -0
- package/packages/photography/gallery/adapters/claude/plugin.json +10 -0
- package/packages/photography/gallery/adapters/codex/README.md +3 -0
- package/packages/photography/gallery/adapters/cursor/plugin.json +6 -0
- package/packages/photography/gallery/adapters/cursor/skills/gallery/SKILL.md +235 -0
- package/packages/software-development/changelog-generator/SKILL.md +111 -0
- package/packages/software-development/changelog-generator/adapters/claude/plugin.json +10 -0
- package/packages/software-development/changelog-generator/adapters/codex/README.md +3 -0
- package/packages/software-development/changelog-generator/adapters/cursor/plugin.json +6 -0
- package/packages/software-development/changelog-generator/adapters/cursor/skills/changelog-generator/SKILL.md +113 -0
- package/packages/software-development/docs-index-keeper/SKILL.md +62 -0
- package/packages/software-development/docs-index-keeper/adapters/claude/plugin.json +10 -0
- package/packages/software-development/docs-index-keeper/adapters/codex/README.md +5 -0
- package/packages/software-development/docs-index-keeper/adapters/cursor/plugin.json +6 -0
- package/packages/software-development/docs-index-keeper/adapters/cursor/skills/docs-index-keeper/SKILL.md +64 -0
- package/packages/software-development/gh-cli/SKILL.md +2196 -0
- package/packages/software-development/gh-cli/adapters/claude/plugin.json +10 -0
- package/packages/software-development/gh-cli/adapters/codex/README.md +3 -0
- package/packages/software-development/gh-cli/adapters/cursor/plugin.json +6 -0
- package/packages/software-development/gh-cli/adapters/cursor/skills/gh-cli/SKILL.md +2198 -0
- package/packages/software-development/git-commit/SKILL.md +131 -0
- package/packages/software-development/git-commit/adapters/claude/plugin.json +10 -0
- package/packages/software-development/git-commit/adapters/codex/README.md +3 -0
- package/packages/software-development/git-commit/adapters/cursor/plugin.json +6 -0
- package/packages/software-development/git-commit/adapters/cursor/skills/git-commit/SKILL.md +133 -0
- package/packages/software-development/product-builder/LICENSE +21 -0
- package/packages/software-development/product-builder/SKILL.md +221 -0
- package/packages/software-development/product-builder/adapters/claude/plugin.json +10 -0
- package/packages/software-development/product-builder/adapters/codex/README.md +3 -0
- package/packages/software-development/product-builder/adapters/cursor/plugin.json +6 -0
- package/packages/software-development/product-builder/adapters/cursor/skills/product-builder/SKILL.md +223 -0
- package/packages/software-development/promptctl/SKILL.md +86 -0
- package/packages/software-development/promptctl/adapters/claude/plugin.json +10 -0
- package/packages/software-development/promptctl/adapters/codex/README.md +3 -0
- package/packages/software-development/promptctl/adapters/cursor/plugin.json +6 -0
- package/packages/software-development/promptctl/adapters/cursor/skills/promptctl/SKILL.md +88 -0
- package/packages/software-development/semantic-release-beta/SKILL.md +55 -0
- package/packages/software-development/semantic-release-beta/adapters/claude/plugin.json +10 -0
- package/packages/software-development/semantic-release-beta/adapters/codex/README.md +3 -0
- package/packages/software-development/semantic-release-beta/adapters/cursor/plugin.json +6 -0
- package/packages/software-development/semantic-release-beta/adapters/cursor/skills/semantic-release-beta/SKILL.md +57 -0
- package/packages/software-development/semantic-release-beta/references/github-actions.md +16 -0
- package/packages/software-development/semantic-release-beta/references/node-semantic-release.md +13 -0
- package/packages/software-development/semantic-release-beta/references/preset.md +47 -0
- package/packages/software-development/semantic-release-beta/references/validation.md +17 -0
- package/scripts/build-adapters.sh +115 -0
- package/scripts/install-codex-symlinks.sh +37 -0
- package/scripts/sync-from-sources.sh +44 -0
- package/scripts/validate-catalog.sh +90 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
set -eu
|
|
3
|
+
|
|
4
|
+
node <<'EOF'
|
|
5
|
+
const fs = require('fs')
|
|
6
|
+
const path = require('path')
|
|
7
|
+
|
|
8
|
+
const root = process.cwd()
|
|
9
|
+
const catalogPath = path.join(root, 'catalog', 'skills.json')
|
|
10
|
+
const catalog = JSON.parse(fs.readFileSync(catalogPath, 'utf8'))
|
|
11
|
+
const projectName = catalog.name
|
|
12
|
+
const lookupNameFor = (pkg) => pkg.lookupName || pkg.name
|
|
13
|
+
const skillPathFor = (pkg) => path.join(root, pkg.path, 'SKILL.md')
|
|
14
|
+
const promptNameFor = (pkg) => `${pkg.name}.prompt.md`
|
|
15
|
+
const generatedHeader = '<!-- Generated by scripts/build-adapters.sh. Do not edit directly. -->'
|
|
16
|
+
const stripFrontmatter = (content) => content.replace(/^---\n[\s\S]*?\n---\n?/, '')
|
|
17
|
+
const stripTrailingLineWhitespace = (content) => content.replace(/[ \t]+$/gm, '')
|
|
18
|
+
|
|
19
|
+
const plugins = catalog.packages.map((pkg) => ({
|
|
20
|
+
name: lookupNameFor(pkg),
|
|
21
|
+
source: `./${pkg.path}/adapters/claude`,
|
|
22
|
+
description: pkg.description,
|
|
23
|
+
}))
|
|
24
|
+
|
|
25
|
+
const cursorPlugins = catalog.packages.map((pkg) => ({
|
|
26
|
+
name: lookupNameFor(pkg),
|
|
27
|
+
source: `./${pkg.path}/adapters/cursor`,
|
|
28
|
+
description: pkg.description,
|
|
29
|
+
}))
|
|
30
|
+
|
|
31
|
+
fs.mkdirSync(path.join(root, '.claude-plugin'), { recursive: true })
|
|
32
|
+
fs.mkdirSync(path.join(root, '.cursor-plugin'), { recursive: true })
|
|
33
|
+
fs.mkdirSync(path.join(root, '.github', 'prompts'), { recursive: true })
|
|
34
|
+
|
|
35
|
+
fs.writeFileSync(
|
|
36
|
+
path.join(root, '.claude-plugin', 'marketplace.json'),
|
|
37
|
+
JSON.stringify(
|
|
38
|
+
{
|
|
39
|
+
name: projectName,
|
|
40
|
+
owner: { name: 'Oleg Koval' },
|
|
41
|
+
plugins,
|
|
42
|
+
},
|
|
43
|
+
null,
|
|
44
|
+
2,
|
|
45
|
+
) + '\n',
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
fs.writeFileSync(
|
|
49
|
+
path.join(root, '.cursor-plugin', 'index.json'),
|
|
50
|
+
JSON.stringify(
|
|
51
|
+
{
|
|
52
|
+
name: projectName,
|
|
53
|
+
plugins: cursorPlugins,
|
|
54
|
+
},
|
|
55
|
+
null,
|
|
56
|
+
2,
|
|
57
|
+
) + '\n',
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
const copilotInstructions = [
|
|
61
|
+
generatedHeader,
|
|
62
|
+
'',
|
|
63
|
+
'# Agent Skills Repository Instructions',
|
|
64
|
+
'',
|
|
65
|
+
'This repository is an opinionated agent skill catalog. Skills encode concrete defaults, preferred tools, and repeatable workflows.',
|
|
66
|
+
'',
|
|
67
|
+
'- Treat `catalog/skills.json` as the source of truth for package metadata.',
|
|
68
|
+
'- Keep canonical skill instructions in `packages/{category}/{skill}/SKILL.md`.',
|
|
69
|
+
'- Keep generated adapter files in sync by running `./scripts/build-adapters.sh` after catalog or skill metadata changes (includes Cursor `skills/*/SKILL.md` copies from each canonical `SKILL.md`).',
|
|
70
|
+
'- Run `./scripts/validate-catalog.sh` before release.',
|
|
71
|
+
'- Prefer small, scoped updates that preserve existing package structure.',
|
|
72
|
+
'',
|
|
73
|
+
'Available reusable prompt files:',
|
|
74
|
+
...catalog.packages.map((pkg) => `- ${pkg.name}: .github/prompts/${promptNameFor(pkg)}`),
|
|
75
|
+
'',
|
|
76
|
+
].join('\n')
|
|
77
|
+
|
|
78
|
+
fs.writeFileSync(path.join(root, '.github', 'copilot-instructions.md'), copilotInstructions)
|
|
79
|
+
|
|
80
|
+
for (const pkg of catalog.packages) {
|
|
81
|
+
if (!pkg.adapters.includes('copilot')) {
|
|
82
|
+
continue
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const skillBody = stripFrontmatter(fs.readFileSync(skillPathFor(pkg), 'utf8')).trimEnd()
|
|
86
|
+
const prompt = stripTrailingLineWhitespace([
|
|
87
|
+
generatedHeader,
|
|
88
|
+
'',
|
|
89
|
+
'---',
|
|
90
|
+
`description: ${JSON.stringify(pkg.description)}`,
|
|
91
|
+
'---',
|
|
92
|
+
'',
|
|
93
|
+
`Use the ${lookupNameFor(pkg)} skill.`,
|
|
94
|
+
'',
|
|
95
|
+
skillBody,
|
|
96
|
+
'',
|
|
97
|
+
].join('\n'))
|
|
98
|
+
|
|
99
|
+
fs.writeFileSync(path.join(root, '.github', 'prompts', promptNameFor(pkg)), prompt)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
for (const pkg of catalog.packages) {
|
|
103
|
+
if (!pkg.adapters.includes('cursor')) {
|
|
104
|
+
continue
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const canonical = fs.readFileSync(skillPathFor(pkg), 'utf8').trimEnd()
|
|
108
|
+
const destDir = path.join(root, pkg.path, 'adapters', 'cursor', 'skills', pkg.name)
|
|
109
|
+
const destPath = path.join(destDir, 'SKILL.md')
|
|
110
|
+
fs.mkdirSync(destDir, { recursive: true })
|
|
111
|
+
fs.writeFileSync(destPath, [generatedHeader, '', canonical, ''].join('\n'))
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
console.log('generated marketplace manifests, Copilot prompts, and Cursor adapter SKILL.md files')
|
|
115
|
+
EOF
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
set -eu
|
|
3
|
+
|
|
4
|
+
CODEX_SKILLS_DIR="${CODEX_HOME:-$HOME/.codex}/skills"
|
|
5
|
+
ROOT="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)"
|
|
6
|
+
CATALOG="$ROOT/catalog/skills.json"
|
|
7
|
+
|
|
8
|
+
mkdir -p "$CODEX_SKILLS_DIR"
|
|
9
|
+
|
|
10
|
+
node - "$CATALOG" "$ROOT" "$CODEX_SKILLS_DIR" <<'EOF'
|
|
11
|
+
const fs = require('fs')
|
|
12
|
+
const path = require('path')
|
|
13
|
+
|
|
14
|
+
const [, , catalogPath, root, codexSkillsDir] = process.argv
|
|
15
|
+
const catalog = JSON.parse(fs.readFileSync(catalogPath, 'utf8'))
|
|
16
|
+
|
|
17
|
+
for (const pkg of catalog.packages) {
|
|
18
|
+
const target = path.join(root, pkg.path)
|
|
19
|
+
const lookupName = pkg.lookupName || `olko:${pkg.name}`
|
|
20
|
+
const linkPath = path.join(codexSkillsDir, lookupName)
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const stat = fs.lstatSync(linkPath)
|
|
24
|
+
if (!stat.isSymbolicLink()) {
|
|
25
|
+
throw new Error(`${linkPath} exists and is not a symlink`)
|
|
26
|
+
}
|
|
27
|
+
fs.unlinkSync(linkPath)
|
|
28
|
+
} catch (error) {
|
|
29
|
+
if (error.code !== 'ENOENT') {
|
|
30
|
+
throw error
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
fs.symlinkSync(target, linkPath, 'dir')
|
|
35
|
+
console.log(`linked ${lookupName} -> ${target}`)
|
|
36
|
+
}
|
|
37
|
+
EOF
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
set -eu
|
|
3
|
+
|
|
4
|
+
node <<'EOF'
|
|
5
|
+
const fs = require('fs')
|
|
6
|
+
const path = require('path')
|
|
7
|
+
|
|
8
|
+
const root = process.cwd()
|
|
9
|
+
const catalog = JSON.parse(fs.readFileSync(path.join(root, 'catalog', 'skills.json'), 'utf8'))
|
|
10
|
+
let synced = 0
|
|
11
|
+
|
|
12
|
+
const copyIfPresent = (source, target) => {
|
|
13
|
+
if (!fs.existsSync(source)) {
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
fs.rmSync(target, { force: true, recursive: true })
|
|
18
|
+
fs.cpSync(source, target, { recursive: true })
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
for (const pkg of catalog.packages) {
|
|
22
|
+
if (!pkg.sourcePath) {
|
|
23
|
+
continue
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const sourcePath = path.resolve(root, pkg.sourcePath)
|
|
27
|
+
const targetPath = path.resolve(root, pkg.path)
|
|
28
|
+
|
|
29
|
+
if (!fs.existsSync(sourcePath)) {
|
|
30
|
+
throw new Error(`sourcePath for ${pkg.name} does not exist: ${pkg.sourcePath}`)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
fs.mkdirSync(targetPath, { recursive: true })
|
|
34
|
+
copyIfPresent(path.join(sourcePath, 'SKILL.md'), path.join(targetPath, 'SKILL.md'))
|
|
35
|
+
copyIfPresent(path.join(sourcePath, 'references'), path.join(targetPath, 'references'))
|
|
36
|
+
copyIfPresent(path.join(sourcePath, 'LICENSE'), path.join(targetPath, 'LICENSE'))
|
|
37
|
+
synced += 1
|
|
38
|
+
console.log(`synced ${pkg.name} from ${pkg.sourcePath}`)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (synced === 0) {
|
|
42
|
+
console.log('no package sourcePath entries configured; nothing to sync')
|
|
43
|
+
}
|
|
44
|
+
EOF
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
set -eu
|
|
3
|
+
|
|
4
|
+
test -f catalog/skills.json
|
|
5
|
+
test -f collections/software-development.json
|
|
6
|
+
test -f collections/marketing.json
|
|
7
|
+
test -f collections/music.json
|
|
8
|
+
test -f collections/photography.json
|
|
9
|
+
test -f collections/docs-tools.json
|
|
10
|
+
test -f collections/release-tools.json
|
|
11
|
+
test -f .claude-plugin/marketplace.json
|
|
12
|
+
test -f .cursor-plugin/index.json
|
|
13
|
+
test -f .github/copilot-instructions.md
|
|
14
|
+
|
|
15
|
+
node <<'EOF'
|
|
16
|
+
const fs = require('fs')
|
|
17
|
+
const path = require('path')
|
|
18
|
+
|
|
19
|
+
const categories = new Set(['software-development', 'marketing', 'music', 'photography'])
|
|
20
|
+
const adapterFiles = {
|
|
21
|
+
claude: (pkg) => path.join(pkg.path, 'adapters', 'claude', 'plugin.json'),
|
|
22
|
+
codex: (pkg) => path.join(pkg.path, 'adapters', 'codex', 'README.md'),
|
|
23
|
+
cursor: (pkg) => path.join(pkg.path, 'adapters', 'cursor', 'plugin.json'),
|
|
24
|
+
copilot: (pkg) => path.join('.github', 'prompts', `${pkg.name}.prompt.md`),
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const catalog = JSON.parse(fs.readFileSync('catalog/skills.json', 'utf8'))
|
|
28
|
+
const packagesByName = new Map(catalog.packages.map((pkg) => [pkg.name, pkg]))
|
|
29
|
+
const claudeManifest = JSON.parse(fs.readFileSync('.claude-plugin/marketplace.json', 'utf8'))
|
|
30
|
+
const cursorManifest = JSON.parse(fs.readFileSync('.cursor-plugin/index.json', 'utf8'))
|
|
31
|
+
|
|
32
|
+
for (const pkg of catalog.packages) {
|
|
33
|
+
if (!pkg.name || !pkg.lookupName || !pkg.path || !pkg.description) {
|
|
34
|
+
throw new Error(`package metadata is incomplete: ${JSON.stringify(pkg)}`)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (!categories.has(pkg.category)) {
|
|
38
|
+
throw new Error(`unknown category for ${pkg.name}: ${pkg.category}`)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const skillPath = path.join(pkg.path, 'SKILL.md')
|
|
42
|
+
if (!fs.existsSync(skillPath)) {
|
|
43
|
+
throw new Error(`missing SKILL.md for ${pkg.name}: ${skillPath}`)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
for (const adapter of pkg.adapters || []) {
|
|
47
|
+
const adapterFileFor = adapterFiles[adapter]
|
|
48
|
+
if (!adapterFileFor) {
|
|
49
|
+
throw new Error(`unknown adapter for ${pkg.name}: ${adapter}`)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const adapterFile = adapterFileFor(pkg)
|
|
53
|
+
if (!fs.existsSync(adapterFile)) {
|
|
54
|
+
throw new Error(`missing ${adapter} adapter for ${pkg.name}: ${adapterFile}`)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
for (const collectionPath of fs.readdirSync('collections').map((name) => path.join('collections', name))) {
|
|
60
|
+
const collection = JSON.parse(fs.readFileSync(collectionPath, 'utf8'))
|
|
61
|
+
for (const packageName of collection.packages || []) {
|
|
62
|
+
if (!packagesByName.has(packageName)) {
|
|
63
|
+
throw new Error(`${collectionPath} references unknown package: ${packageName}`)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
for (const plugin of claudeManifest.plugins || []) {
|
|
69
|
+
const source = plugin.source.replace(/^\.\//, '')
|
|
70
|
+
if (!fs.existsSync(source)) {
|
|
71
|
+
throw new Error(`Claude manifest source does not exist: ${plugin.source}`)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
for (const plugin of cursorManifest.plugins || []) {
|
|
76
|
+
const source = plugin.source.replace(/^\.\//, '')
|
|
77
|
+
if (!fs.existsSync(source)) {
|
|
78
|
+
throw new Error(`Cursor manifest source does not exist: ${plugin.source}`)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
for (const pkg of catalog.packages) {
|
|
83
|
+
const oldFlatPath = path.join('packages', pkg.name, 'SKILL.md')
|
|
84
|
+
if (fs.existsSync(oldFlatPath)) {
|
|
85
|
+
throw new Error(`stale flat package path exists: ${oldFlatPath}`)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
EOF
|
|
89
|
+
|
|
90
|
+
echo "catalog validation passed"
|