ai-agent-skills 3.4.3 → 3.5.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 +52 -19
- package/cli.js +239 -15
- package/lib/catalog-mutations.cjs +64 -0
- package/package.json +1 -1
- package/skills.json +1056 -205
- package/tui/catalog.cjs +1 -0
- package/tui/index.mjs +6 -6
- package/skills/job-application/SKILL.md +0 -90
- package/skills/lead-research-assistant/SKILL.md +0 -199
- package/skills/video-downloader/SKILL.md +0 -106
package/README.md
CHANGED
|
@@ -5,10 +5,10 @@ My curated agent skills library.
|
|
|
5
5
|
There are a lot of skills now. These are the ones I actually keep around.
|
|
6
6
|
|
|
7
7
|
<!-- GENERATED:library-stats:start -->
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
8
|
+
- 55 skills total
|
|
9
|
+
- 5 shelves
|
|
10
|
+
- 8 house copies
|
|
11
|
+
- 47 cataloged upstream
|
|
12
12
|
<!-- GENERATED:library-stats:end -->
|
|
13
13
|
|
|
14
14
|
The point is not to be a registry. The point is to be a bookshelf.
|
|
@@ -61,9 +61,18 @@ npx ai-agent-skills list
|
|
|
61
61
|
# Install a skill from the library
|
|
62
62
|
npx ai-agent-skills install frontend-design
|
|
63
63
|
|
|
64
|
+
# Install the Swift hub straight to Claude + Codex
|
|
65
|
+
npx ai-agent-skills swift
|
|
66
|
+
|
|
67
|
+
# Install an entire curated pack
|
|
68
|
+
npx ai-agent-skills install --collection swift-agent-skills -p
|
|
69
|
+
|
|
64
70
|
# Install to the project shelf
|
|
65
71
|
npx ai-agent-skills install pdf -p
|
|
66
72
|
|
|
73
|
+
# Install all skills from an upstream repo straight to Claude + Codex
|
|
74
|
+
npx ai-agent-skills anthropics/skills
|
|
75
|
+
|
|
67
76
|
# Browse a repo before adding or installing from it
|
|
68
77
|
npx ai-agent-skills install openai/skills --list
|
|
69
78
|
```
|
|
@@ -88,6 +97,7 @@ Secondary surfaces still exist, but they are not the main taxonomy:
|
|
|
88
97
|
|
|
89
98
|
- `npx ai-agent-skills browse` for the TUI
|
|
90
99
|
- `npx ai-agent-skills list --collection my-picks` for a cross-shelf starter stack
|
|
100
|
+
- `npx ai-agent-skills install --collection swift-agent-skills -p` for an installable curated pack
|
|
91
101
|
- `npx ai-agent-skills curate review` for the curator cleanup queue
|
|
92
102
|
|
|
93
103
|
## Shelves
|
|
@@ -97,29 +107,25 @@ These are the shelves. They are the product.
|
|
|
97
107
|
<!-- GENERATED:shelf-table:start -->
|
|
98
108
|
| Shelf | Skills | What it covers |
|
|
99
109
|
| --- | --- | --- |
|
|
100
|
-
| Frontend |
|
|
101
|
-
| Backend |
|
|
102
|
-
|
|
|
103
|
-
|
|
|
104
|
-
|
|
|
105
|
-
| Research | 2 | Competitive scans, discovery work, and synthesis that helps decisions. |
|
|
106
|
-
| Design | 4 | Visual systems, thematic work, creative direction, and media craft. |
|
|
107
|
-
| Business | 3 | Brand, hiring, ops, and communication work around the product. |
|
|
108
|
-
| AI | 6 | LLM applications, MCP servers, agent building, prompt engineering, and skills development. |
|
|
109
|
-
| DevOps | 2 | CI/CD, observability, deployment, and release infrastructure. |
|
|
110
|
+
| Frontend | 10 | Interfaces, design systems, browser work, and product polish. |
|
|
111
|
+
| Backend | 5 | Systems, data, security, and runtime operations. |
|
|
112
|
+
| Mobile | 24 | Swift, SwiftUI, iOS, and Apple-platform development, with room for future React Native branches. |
|
|
113
|
+
| Workflow | 10 | Files, docs, planning, release work, and research-to-output flows. |
|
|
114
|
+
| Agent Engineering | 6 | MCP, skill-building, prompting discipline, and LLM application work. |
|
|
110
115
|
<!-- GENERATED:shelf-table:end -->
|
|
111
116
|
|
|
112
117
|
The full map lives in [WORK_AREAS.md](./WORK_AREAS.md).
|
|
113
118
|
|
|
114
119
|
## Collections
|
|
115
120
|
|
|
116
|
-
Collections still exist, but they are secondary. They
|
|
121
|
+
Collections still exist, but they are secondary. They can be starter stacks or installable packs, but shelves are still the main taxonomy.
|
|
117
122
|
|
|
118
123
|
<!-- GENERATED:collection-table:start -->
|
|
119
124
|
| Collection | Why it exists | Start here |
|
|
120
125
|
| --- | --- | --- |
|
|
121
126
|
| `my-picks` | The smallest cross-shelf starter stack: the skills I would reach for first on a fresh setup. | `frontend-design`, `mcp-builder`, `pdf` |
|
|
122
127
|
| `build-apps` | Frontend and design implementation skills for shipping polished product work. | `frontend-design`, `frontend-skill`, `shadcn` |
|
|
128
|
+
| `swift-agent-skills` | A curated Swift and Apple-platform hub inside ai-agent-skills, collecting the main upstream Swift skills as one installable set. | `swiftui-pro`, `swiftui-ui-patterns`, `swiftui-design-principles` |
|
|
123
129
|
| `build-systems` | Architecture, MCP, backend, and security picks for deeper engineering work. | `mcp-builder`, `backend-development`, `database-design` |
|
|
124
130
|
| `test-and-debug` | The shelf for QA, regression, CI cleanup, observability, and debugging discipline. | `playwright`, `webapp-testing`, `gh-fix-ci` |
|
|
125
131
|
| `docs-and-research` | File-heavy work, writing, docs, and research flows that end in something usable. | `pdf`, `doc-coauthoring`, `docx` |
|
|
@@ -133,6 +139,7 @@ The `catalog` command is how I pull from upstream repos without vendoring everyt
|
|
|
133
139
|
npx ai-agent-skills catalog openai/skills --list
|
|
134
140
|
npx ai-agent-skills catalog openai/skills --skill linear --area workflow --branch Linear
|
|
135
141
|
npx ai-agent-skills catalog openai/skills --skill security-best-practices --area backend --branch Security
|
|
142
|
+
npx ai-agent-skills catalog conorluddy/ios-simulator-skill --skill ios-simulator-skill --area mobile --branch "Swift / Tools" --collection swift-agent-skills
|
|
136
143
|
npx ai-agent-skills catalog shadcn-ui/ui --skill shadcn --area frontend --branch Components
|
|
137
144
|
```
|
|
138
145
|
|
|
@@ -147,7 +154,9 @@ It adds metadata and editorial placement:
|
|
|
147
154
|
For existing picks, `curate` is the fast loop:
|
|
148
155
|
|
|
149
156
|
```bash
|
|
150
|
-
npx ai-agent-skills curate frontend-design --branch
|
|
157
|
+
npx ai-agent-skills curate frontend-design --branch Implementation
|
|
158
|
+
npx ai-agent-skills curate ios-simulator-skill --collection swift-agent-skills
|
|
159
|
+
npx ai-agent-skills curate ios-simulator-skill --remove-from-collection swift-agent-skills
|
|
151
160
|
npx ai-agent-skills curate frontend-design --why "A stronger note that matches how I actually use it."
|
|
152
161
|
npx ai-agent-skills curate review
|
|
153
162
|
```
|
|
@@ -156,6 +165,7 @@ When I explicitly want a new house copy, `vendor` is the only path that does it:
|
|
|
156
165
|
|
|
157
166
|
```bash
|
|
158
167
|
npx ai-agent-skills vendor <repo-or-path> --skill <name> --area <shelf> --branch <branch> --why "Why this deserves a local copy."
|
|
168
|
+
npx ai-agent-skills vendor <repo-or-path> --skill <name> --area mobile --branch "Swift / Tools" --collection swift-agent-skills --why "Why this deserves a place in the Swift pack."
|
|
159
169
|
```
|
|
160
170
|
|
|
161
171
|
## Source Repos
|
|
@@ -165,13 +175,33 @@ Current source mix:
|
|
|
165
175
|
<!-- GENERATED:source-table:start -->
|
|
166
176
|
| Source repo | Skills |
|
|
167
177
|
| --- | --- |
|
|
168
|
-
| `anthropics/skills` |
|
|
178
|
+
| `anthropics/skills` | 11 |
|
|
169
179
|
| `openai/skills` | 9 |
|
|
170
|
-
| `
|
|
180
|
+
| `Dimillian/Skills` | 4 |
|
|
171
181
|
| `wshobson/agents` | 4 |
|
|
172
|
-
| `
|
|
182
|
+
| `rgmez/apple-accessibility-skills` | 3 |
|
|
183
|
+
| `ComposioHQ/awesome-claude-skills` | 2 |
|
|
184
|
+
| `MoizIbnYousaf/Ai-Agent-Skills` | 2 |
|
|
185
|
+
| `andrewgleave/skills` | 1 |
|
|
186
|
+
| `arjitj2/swiftui-design-principles` | 1 |
|
|
187
|
+
| `AvdLee/Core-Data-Agent-Skill` | 1 |
|
|
188
|
+
| `AvdLee/Swift-Concurrency-Agent-Skill` | 1 |
|
|
189
|
+
| `AvdLee/Swift-Testing-Agent-Skill` | 1 |
|
|
190
|
+
| `bocato/swift-testing-agent-skill` | 1 |
|
|
191
|
+
| `conorluddy/ios-simulator-skill` | 1 |
|
|
192
|
+
| `dadederk/iOS-Accessibility-Agent-Skill` | 1 |
|
|
193
|
+
| `efremidze/swift-architecture-skill` | 1 |
|
|
173
194
|
| `emilkowalski/skill` | 1 |
|
|
195
|
+
| `Erikote04/Swift-API-Design-Guidelines-Agent-Skill` | 1 |
|
|
196
|
+
| `ivan-magda/swift-security-skill` | 1 |
|
|
197
|
+
| `PasqualeVittoriosi/swift-accessibility-skill` | 1 |
|
|
198
|
+
| `raphaelsalaja/userinterface-wiki` | 1 |
|
|
174
199
|
| `shadcn-ui/ui` | 1 |
|
|
200
|
+
| `twostraws/Swift-Concurrency-Agent-Skill` | 1 |
|
|
201
|
+
| `twostraws/Swift-Testing-Agent-Skill` | 1 |
|
|
202
|
+
| `twostraws/SwiftData-Agent-Skill` | 1 |
|
|
203
|
+
| `twostraws/SwiftUI-Agent-Skill` | 1 |
|
|
204
|
+
| `vanab/swiftdata-agent-skill` | 1 |
|
|
175
205
|
<!-- GENERATED:source-table:end -->
|
|
176
206
|
|
|
177
207
|
The two major upstream publishers in this library are Anthropic and OpenAI.
|
|
@@ -192,7 +222,10 @@ npx ai-agent-skills preview pdf
|
|
|
192
222
|
|
|
193
223
|
# Install
|
|
194
224
|
npx ai-agent-skills install <skill-name>
|
|
225
|
+
npx ai-agent-skills swift
|
|
195
226
|
npx ai-agent-skills install <skill-name> -p
|
|
227
|
+
npx ai-agent-skills install --collection swift-agent-skills -p
|
|
228
|
+
npx ai-agent-skills <owner/repo>
|
|
196
229
|
npx ai-agent-skills install <owner/repo>
|
|
197
230
|
npx ai-agent-skills install <owner/repo>@<skill-name>
|
|
198
231
|
npx ai-agent-skills install <owner/repo> --skill <name>
|
package/cli.js
CHANGED
|
@@ -100,6 +100,9 @@ const LEGACY_COLLECTION_ALIASES = {
|
|
|
100
100
|
}
|
|
101
101
|
};
|
|
102
102
|
|
|
103
|
+
const SWIFT_SHORTCUT = 'swift';
|
|
104
|
+
const UNIVERSAL_DEFAULT_AGENTS = ['claude', 'codex'];
|
|
105
|
+
|
|
103
106
|
function log(msg) { console.log(msg); }
|
|
104
107
|
function success(msg) { console.log(`${colors.green}${colors.bold}${msg}${colors.reset}`); }
|
|
105
108
|
function info(msg) { console.log(`${colors.cyan}${msg}${colors.reset}`); }
|
|
@@ -303,6 +306,10 @@ function resolveCollection(data, collectionId) {
|
|
|
303
306
|
};
|
|
304
307
|
}
|
|
305
308
|
|
|
309
|
+
function uniquePaths(paths) {
|
|
310
|
+
return [...new Set((paths || []).filter(Boolean))];
|
|
311
|
+
}
|
|
312
|
+
|
|
306
313
|
function getCollectionsForSkill(data, skillName) {
|
|
307
314
|
return getCollections(data).filter(collection =>
|
|
308
315
|
Array.isArray(collection.skills) && collection.skills.includes(skillName)
|
|
@@ -549,6 +556,7 @@ function parseArgs(args) {
|
|
|
549
556
|
category: null,
|
|
550
557
|
workArea: null,
|
|
551
558
|
collection: null,
|
|
559
|
+
collectionRemove: null,
|
|
552
560
|
skillFilters: [], // v3: --skill flag values
|
|
553
561
|
listMode: false, // v3: --list flag
|
|
554
562
|
yes: false, // v3: --yes flag (non-interactive)
|
|
@@ -675,6 +683,10 @@ function parseArgs(args) {
|
|
|
675
683
|
result.collection = args[i + 1];
|
|
676
684
|
i++;
|
|
677
685
|
}
|
|
686
|
+
else if (arg === '--remove-from-collection') {
|
|
687
|
+
result.collectionRemove = args[i + 1];
|
|
688
|
+
i++;
|
|
689
|
+
}
|
|
678
690
|
else if (arg.startsWith('--')) {
|
|
679
691
|
const potentialAgent = arg.replace(/^--/, '');
|
|
680
692
|
if (validAgents.includes(potentialAgent)) {
|
|
@@ -708,18 +720,22 @@ function parseArgs(args) {
|
|
|
708
720
|
}
|
|
709
721
|
|
|
710
722
|
// v3: resolve install target path from scope/agent flags
|
|
711
|
-
function resolveInstallPath(parsed) {
|
|
723
|
+
function resolveInstallPath(parsed, options = {}) {
|
|
712
724
|
// 1. Explicit legacy --agent override
|
|
713
725
|
if (parsed.explicitAgent && parsed.agents.length > 0) {
|
|
714
|
-
return parsed.agents.map(a => AGENT_PATHS[a] || SCOPES.global);
|
|
726
|
+
return uniquePaths(parsed.agents.map(a => AGENT_PATHS[a] || SCOPES.global));
|
|
715
727
|
}
|
|
716
728
|
// 2. --all installs to both scopes
|
|
717
729
|
if (parsed.all) {
|
|
718
|
-
return [SCOPES.global, SCOPES.project];
|
|
730
|
+
return uniquePaths([SCOPES.global, SCOPES.project]);
|
|
719
731
|
}
|
|
720
732
|
// 3. Explicit scope flag
|
|
721
733
|
if (parsed.scope === 'project') return [SCOPES.project];
|
|
722
734
|
if (parsed.scope === 'global') return [SCOPES.global];
|
|
735
|
+
// 4. Optional default agents for direct source shortcuts
|
|
736
|
+
if (Array.isArray(options.defaultAgents) && options.defaultAgents.length > 0) {
|
|
737
|
+
return uniquePaths(options.defaultAgents.map((agent) => AGENT_PATHS[agent] || SCOPES.global));
|
|
738
|
+
}
|
|
723
739
|
// 4. Default: global
|
|
724
740
|
return [SCOPES.global];
|
|
725
741
|
}
|
|
@@ -753,6 +769,37 @@ function resolveScopeLabel(targetPath) {
|
|
|
753
769
|
return 'legacy';
|
|
754
770
|
}
|
|
755
771
|
|
|
772
|
+
function isKnownCommand(command) {
|
|
773
|
+
return new Set([
|
|
774
|
+
'browse', 'b',
|
|
775
|
+
SWIFT_SHORTCUT,
|
|
776
|
+
'list', 'ls',
|
|
777
|
+
'collections',
|
|
778
|
+
'install', 'i', 'add',
|
|
779
|
+
'uninstall', 'remove', 'rm',
|
|
780
|
+
'update', 'upgrade',
|
|
781
|
+
'search', 's', 'find',
|
|
782
|
+
'info', 'show',
|
|
783
|
+
'preview',
|
|
784
|
+
'catalog',
|
|
785
|
+
'curate',
|
|
786
|
+
'vendor',
|
|
787
|
+
'check',
|
|
788
|
+
'doctor',
|
|
789
|
+
'validate',
|
|
790
|
+
'init',
|
|
791
|
+
'config',
|
|
792
|
+
'help',
|
|
793
|
+
'--help',
|
|
794
|
+
'-h',
|
|
795
|
+
]).has(command);
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
function isImplicitSourceCommand(command) {
|
|
799
|
+
const parsed = parseSource(command);
|
|
800
|
+
return parsed.type !== 'catalog';
|
|
801
|
+
}
|
|
802
|
+
|
|
756
803
|
// ============ SAFE FILE OPERATIONS ============
|
|
757
804
|
|
|
758
805
|
function copyDir(src, dest, currentSize = { total: 0 }, rootSrc = null) {
|
|
@@ -985,6 +1032,133 @@ function installSkillToScope(skillName, scopePath, scopeLabel, dryRun = false) {
|
|
|
985
1032
|
}
|
|
986
1033
|
}
|
|
987
1034
|
|
|
1035
|
+
function getCollectionSkillsInOrder(data, collection) {
|
|
1036
|
+
const orderedSkills = [];
|
|
1037
|
+
for (const skillName of collection.skills || []) {
|
|
1038
|
+
const skill = findSkillByName(data, skillName);
|
|
1039
|
+
if (skill) {
|
|
1040
|
+
orderedSkills.push(skill);
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
return orderedSkills;
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
function buildCollectionInstallOperations(skills) {
|
|
1047
|
+
const operations = [];
|
|
1048
|
+
|
|
1049
|
+
for (const skill of skills) {
|
|
1050
|
+
if (!skill) continue;
|
|
1051
|
+
|
|
1052
|
+
if (skill.tier !== 'upstream' || !skill.source) {
|
|
1053
|
+
operations.push({
|
|
1054
|
+
type: 'skill',
|
|
1055
|
+
skills: [skill],
|
|
1056
|
+
});
|
|
1057
|
+
continue;
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
const previous = operations[operations.length - 1];
|
|
1061
|
+
if (previous && previous.type === 'upstream' && previous.source === skill.source) {
|
|
1062
|
+
previous.skills.push(skill);
|
|
1063
|
+
continue;
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
operations.push({
|
|
1067
|
+
type: 'upstream',
|
|
1068
|
+
source: skill.source,
|
|
1069
|
+
skills: [skill],
|
|
1070
|
+
});
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
return operations;
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
async function installCollection(collectionId, parsed, installPaths) {
|
|
1077
|
+
const data = loadSkillsJson();
|
|
1078
|
+
const resolution = resolveCollection(data, collectionId);
|
|
1079
|
+
|
|
1080
|
+
if (!resolution.collection) {
|
|
1081
|
+
warn(resolution.message);
|
|
1082
|
+
if (resolution.unknown) {
|
|
1083
|
+
printCollectionSuggestions(data);
|
|
1084
|
+
}
|
|
1085
|
+
return false;
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
if (resolution.message) {
|
|
1089
|
+
info(resolution.message);
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
const orderedSkills = getCollectionSkillsInOrder(data, resolution.collection);
|
|
1093
|
+
if (orderedSkills.length === 0) {
|
|
1094
|
+
warn(`Collection "${resolution.collection.id}" has no installable skills.`);
|
|
1095
|
+
return false;
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
const operations = buildCollectionInstallOperations(orderedSkills);
|
|
1099
|
+
const targetList = installPaths.join(', ');
|
|
1100
|
+
|
|
1101
|
+
if (parsed.dryRun) {
|
|
1102
|
+
log(`\n${colors.bold}Dry Run${colors.reset} (no changes made)\n`);
|
|
1103
|
+
info(`Would install collection: ${resolution.collection.title} [${resolution.collection.id}]`);
|
|
1104
|
+
info(`Skills: ${orderedSkills.length}`);
|
|
1105
|
+
info(`Targets: ${targetList}`);
|
|
1106
|
+
orderedSkills.forEach((skill) => {
|
|
1107
|
+
const sourceLabel = skill.tier === 'upstream'
|
|
1108
|
+
? `live from ${skill.installSource || skill.source}`
|
|
1109
|
+
: 'bundled house copy';
|
|
1110
|
+
log(` ${colors.green}${skill.name}${colors.reset} ${colors.dim}(${sourceLabel})${colors.reset}`);
|
|
1111
|
+
});
|
|
1112
|
+
return true;
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
log(`\n${colors.bold}Installing Collection${colors.reset}`);
|
|
1116
|
+
info(`${resolution.collection.title} [${resolution.collection.id}]`);
|
|
1117
|
+
info(`Targets: ${targetList}`);
|
|
1118
|
+
|
|
1119
|
+
let completed = 0;
|
|
1120
|
+
let failed = 0;
|
|
1121
|
+
|
|
1122
|
+
for (const operation of operations) {
|
|
1123
|
+
if (operation.type === 'upstream') {
|
|
1124
|
+
const success = await installFromSource(
|
|
1125
|
+
operation.source,
|
|
1126
|
+
parseSource(operation.source),
|
|
1127
|
+
installPaths,
|
|
1128
|
+
operation.skills.map((skill) => skill.name),
|
|
1129
|
+
false,
|
|
1130
|
+
true,
|
|
1131
|
+
false,
|
|
1132
|
+
);
|
|
1133
|
+
|
|
1134
|
+
if (success) completed += operation.skills.length;
|
|
1135
|
+
else failed += operation.skills.length;
|
|
1136
|
+
continue;
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
for (const skill of operation.skills) {
|
|
1140
|
+
let skillSucceeded = true;
|
|
1141
|
+
for (const targetPath of installPaths) {
|
|
1142
|
+
if (!installSkill(skill.name, null, false, targetPath)) {
|
|
1143
|
+
skillSucceeded = false;
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
if (skillSucceeded) completed += 1;
|
|
1148
|
+
else failed += 1;
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
if (completed > 0) {
|
|
1153
|
+
success(`\nCollection install finished: ${completed} skill${completed === 1 ? '' : 's'} completed`);
|
|
1154
|
+
}
|
|
1155
|
+
if (failed > 0) {
|
|
1156
|
+
warn(`${failed} skill${failed === 1 ? '' : 's'} failed during collection install`);
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
return completed > 0;
|
|
1160
|
+
}
|
|
1161
|
+
|
|
988
1162
|
function showAgentInstructions(agent, skillName, destPath) {
|
|
989
1163
|
const instructions = {
|
|
990
1164
|
claude: `The skill is now available in Claude Code.\nJust mention "${skillName}" in your prompt and Claude will use it.`,
|
|
@@ -1607,7 +1781,11 @@ function listSkills(category = null, tags = null, collectionId = null, workArea
|
|
|
1607
1781
|
...Object.keys(byWorkArea).filter(area => !getWorkAreaMeta(data, area)).sort()
|
|
1608
1782
|
].filter((area, index, array) => array.indexOf(area) === index && byWorkArea[area]);
|
|
1609
1783
|
|
|
1610
|
-
const counts =
|
|
1784
|
+
const counts = {
|
|
1785
|
+
total: skills.length,
|
|
1786
|
+
house: skills.filter((skill) => getTier(skill) === 'house').length,
|
|
1787
|
+
upstream: skills.filter((skill) => getTier(skill) !== 'house').length,
|
|
1788
|
+
};
|
|
1611
1789
|
log(`\n${colors.bold}Curated Library${colors.reset}`);
|
|
1612
1790
|
log(`${colors.dim}${formatCount(counts.total, 'pick')} on ${formatCount(orderedAreas.length, 'shelf', 'shelves')} · ${formatCount(counts.house, 'house copy', 'house copies')} · ${formatCount(counts.upstream, 'cataloged upstream pick', 'cataloged upstream picks')}${colors.reset}`);
|
|
1613
1791
|
log(`${colors.dim}Small enough to scan. Opinionated enough to trust.${colors.reset}\n`);
|
|
@@ -1747,7 +1925,7 @@ function showCollections() {
|
|
|
1747
1925
|
}
|
|
1748
1926
|
|
|
1749
1927
|
log(`\n${colors.bold}Curated Collections${colors.reset} (${collections.length} total)\n`);
|
|
1750
|
-
log(`${colors.dim}These are
|
|
1928
|
+
log(`${colors.dim}These are curated sets layered on top of the main work-area shelves. Some are starter stacks; some are full installable packs.${colors.reset}\n`);
|
|
1751
1929
|
|
|
1752
1930
|
collections.forEach(collection => {
|
|
1753
1931
|
const startHere = getCollectionStartHere(collection);
|
|
@@ -1759,6 +1937,7 @@ function showCollections() {
|
|
|
1759
1937
|
log(` ${colors.dim}Start here:${colors.reset} ${startHere.join(', ')}`);
|
|
1760
1938
|
log(` ${colors.green}${collection.skills.length} skills${colors.reset} · ${sample}${more}`);
|
|
1761
1939
|
log(` ${colors.dim}npx ai-agent-skills list --collection ${collection.id}${colors.reset}\n`);
|
|
1940
|
+
log(` ${colors.dim}npx ai-agent-skills install --collection ${collection.id} -p${colors.reset}\n`);
|
|
1762
1941
|
});
|
|
1763
1942
|
}
|
|
1764
1943
|
|
|
@@ -1954,6 +2133,11 @@ async function promptForEditorialFields(initialFields, options = {}) {
|
|
|
1954
2133
|
'Labels (comma-separated)',
|
|
1955
2134
|
Array.isArray(fields.labels) ? fields.labels.join(', ') : fields.labels || ''
|
|
1956
2135
|
);
|
|
2136
|
+
fields.collections = await promptLine(
|
|
2137
|
+
rl,
|
|
2138
|
+
'Collections (comma-separated)',
|
|
2139
|
+
Array.isArray(fields.collections) ? fields.collections.join(', ') : fields.collections || ''
|
|
2140
|
+
);
|
|
1957
2141
|
fields.notes = await promptLine(rl, 'Notes', fields.notes || '');
|
|
1958
2142
|
fields.trust = await promptLine(rl, 'Trust', fields.trust || 'listed');
|
|
1959
2143
|
if (!fields.description && options.allowDescriptionPrompt) {
|
|
@@ -2016,6 +2200,8 @@ function buildCurateChanges(parsed) {
|
|
|
2016
2200
|
if (parsed.featured !== null) changes.featured = parsed.featured;
|
|
2017
2201
|
if (parsed.lastVerified !== null) changes.lastVerified = parsed.lastVerified;
|
|
2018
2202
|
if (parsed.clearVerified) changes.clearVerified = true;
|
|
2203
|
+
if (parsed.collection !== null) changes.collectionsAdd = parsed.collection;
|
|
2204
|
+
if (parsed.collectionRemove !== null) changes.collectionsRemove = parsed.collectionRemove;
|
|
2019
2205
|
|
|
2020
2206
|
return changes;
|
|
2021
2207
|
}
|
|
@@ -2360,6 +2546,7 @@ async function catalogSkills(source, options = {}) {
|
|
|
2360
2546
|
labels: options.labels || '',
|
|
2361
2547
|
notes: options.notes || '',
|
|
2362
2548
|
trust: options.trust || 'listed',
|
|
2549
|
+
collections: options.collections || '',
|
|
2363
2550
|
}, {
|
|
2364
2551
|
mode: 'catalog',
|
|
2365
2552
|
title: 'Add upstream skill to the library',
|
|
@@ -2478,6 +2665,7 @@ async function vendorSkill(source, options = {}) {
|
|
|
2478
2665
|
lastVerified: options.lastVerified || '',
|
|
2479
2666
|
notes: options.notes || '',
|
|
2480
2667
|
labels: options.labels || '',
|
|
2668
|
+
collections: options.collections || '',
|
|
2481
2669
|
lastCurated: currentCatalogTimestamp(),
|
|
2482
2670
|
}, {
|
|
2483
2671
|
mode: 'vendor',
|
|
@@ -2581,7 +2769,7 @@ function runCurateCommand(skillName, parsed) {
|
|
|
2581
2769
|
const changes = buildCurateChanges(parsed);
|
|
2582
2770
|
if (Object.keys(changes).length === 0) {
|
|
2583
2771
|
error('No curator edits specified.');
|
|
2584
|
-
log('Use flags like --area, --branch, --why, --notes, --tags, --labels, --trust, --feature, or --remove --yes.');
|
|
2772
|
+
log('Use flags like --area, --branch, --why, --notes, --tags, --labels, --collection, --remove-from-collection, --trust, --feature, or --remove --yes.');
|
|
2585
2773
|
process.exitCode = 1;
|
|
2586
2774
|
return false;
|
|
2587
2775
|
}
|
|
@@ -2659,7 +2847,7 @@ async function installFromSource(source, parsed, installPaths, skillFilters, lis
|
|
|
2659
2847
|
log(` ${colors.dim}${skill.description}${colors.reset}`);
|
|
2660
2848
|
}
|
|
2661
2849
|
}
|
|
2662
|
-
log(`\n${colors.dim}Install: npx ai-agent-skills
|
|
2850
|
+
log(`\n${colors.dim}Install: npx ai-agent-skills ${source} --skill <name>${colors.reset}`);
|
|
2663
2851
|
return true;
|
|
2664
2852
|
}
|
|
2665
2853
|
|
|
@@ -2810,7 +2998,8 @@ ${colors.bold}Usage:${colors.reset}
|
|
|
2810
2998
|
|
|
2811
2999
|
${colors.bold}Commands:${colors.reset}
|
|
2812
3000
|
${colors.green}browse${colors.reset} Browse the library in the terminal
|
|
2813
|
-
${colors.green}
|
|
3001
|
+
${colors.green}swift${colors.reset} Install the curated Swift hub
|
|
3002
|
+
${colors.green}install <source>${colors.reset} Install skills from the library, a collection, GitHub, git URL, or a local path
|
|
2814
3003
|
${colors.green}list${colors.reset} List catalog skills
|
|
2815
3004
|
${colors.green}search <query>${colors.reset} Search the catalog
|
|
2816
3005
|
${colors.green}info <name>${colors.reset} Show skill details and provenance
|
|
@@ -2832,7 +3021,11 @@ ${colors.bold}Scopes:${colors.reset}
|
|
|
2832
3021
|
${colors.cyan}-p, --project${colors.reset} .agents/skills/ Project, committed with your repo
|
|
2833
3022
|
|
|
2834
3023
|
${colors.bold}Source formats:${colors.reset}
|
|
3024
|
+
swift Install the Swift hub (defaults to Claude + Codex)
|
|
2835
3025
|
install pdf From this library
|
|
3026
|
+
install --collection swift-agent-skills Install a curated collection
|
|
3027
|
+
anthropics/skills Direct repo install (defaults to Claude + Codex)
|
|
3028
|
+
./local-path Direct local repo install (defaults to Claude + Codex)
|
|
2836
3029
|
install anthropics/skills All skills from a GitHub repo
|
|
2837
3030
|
install anthropics/skills@frontend-design One skill from a repo
|
|
2838
3031
|
install anthropics/skills --skill pdf Select specific skills
|
|
@@ -2842,6 +3035,7 @@ ${colors.bold}Source formats:${colors.reset}
|
|
|
2842
3035
|
${colors.bold}Options:${colors.reset}
|
|
2843
3036
|
${colors.cyan}-g, --global${colors.reset} Install to global scope (default)
|
|
2844
3037
|
${colors.cyan}-p, --project${colors.reset} Install to project scope (.agents/skills/)
|
|
3038
|
+
${colors.cyan}--collection <id>${colors.reset} Install or filter a curated collection
|
|
2845
3039
|
${colors.cyan}--skill <name>${colors.reset} Select specific skills from a source
|
|
2846
3040
|
${colors.cyan}--list${colors.reset} List available skills without installing
|
|
2847
3041
|
${colors.cyan}--yes${colors.reset} Skip prompts (for CI/CD)
|
|
@@ -2853,18 +3047,21 @@ ${colors.bold}Categories:${colors.reset}
|
|
|
2853
3047
|
development, document, creative, business, productivity
|
|
2854
3048
|
|
|
2855
3049
|
${colors.bold}Work areas:${colors.reset}
|
|
2856
|
-
frontend, backend,
|
|
3050
|
+
frontend, backend, mobile, workflow, agent-engineering
|
|
2857
3051
|
|
|
2858
3052
|
${colors.bold}Collections:${colors.reset}
|
|
2859
|
-
my-picks, build-apps, build-systems, test-and-debug, docs-and-research
|
|
3053
|
+
my-picks, build-apps, build-systems, test-and-debug, docs-and-research, swift-agent-skills
|
|
2860
3054
|
|
|
2861
3055
|
${colors.bold}Examples:${colors.reset}
|
|
2862
3056
|
npx ai-agent-skills Launch the terminal browser
|
|
3057
|
+
npx ai-agent-skills swift Install the Swift hub to Claude + Codex
|
|
2863
3058
|
npx ai-agent-skills install frontend-design Install to ~/.claude/skills/
|
|
2864
3059
|
npx ai-agent-skills install pdf -p Install to .agents/skills/
|
|
3060
|
+
npx ai-agent-skills install --collection swift-agent-skills -p
|
|
3061
|
+
npx ai-agent-skills anthropics/skills Install repo skills to Claude + Codex
|
|
2865
3062
|
npx ai-agent-skills install anthropics/skills Install all skills from repo
|
|
2866
|
-
npx ai-agent-skills search
|
|
2867
|
-
npx ai-agent-skills curate frontend-design --branch
|
|
3063
|
+
npx ai-agent-skills search workflow Search the catalog
|
|
3064
|
+
npx ai-agent-skills curate frontend-design --branch Implementation
|
|
2868
3065
|
npx ai-agent-skills curate review
|
|
2869
3066
|
npx ai-agent-skills vendor ~/repo --skill my-skill --area frontend --branch React --why "I want the local copy."
|
|
2870
3067
|
|
|
@@ -3184,6 +3381,24 @@ async function main() {
|
|
|
3184
3381
|
return;
|
|
3185
3382
|
}
|
|
3186
3383
|
|
|
3384
|
+
if (command === SWIFT_SHORTCUT) {
|
|
3385
|
+
if (listMode) {
|
|
3386
|
+
listSkills(category, tags, 'swift-agent-skills', workArea);
|
|
3387
|
+
return;
|
|
3388
|
+
}
|
|
3389
|
+
|
|
3390
|
+
const swiftInstallPaths = resolveInstallPath(parsed, { defaultAgents: UNIVERSAL_DEFAULT_AGENTS });
|
|
3391
|
+
await installCollection('swift-agent-skills', parsed, swiftInstallPaths);
|
|
3392
|
+
return;
|
|
3393
|
+
}
|
|
3394
|
+
|
|
3395
|
+
if (!isKnownCommand(command) && isImplicitSourceCommand(command)) {
|
|
3396
|
+
const source = parseSource(command);
|
|
3397
|
+
const installPaths = resolveInstallPath(parsed, { defaultAgents: UNIVERSAL_DEFAULT_AGENTS });
|
|
3398
|
+
await installFromSource(command, source, installPaths, skillFilters, listMode, yes, dryRun);
|
|
3399
|
+
return;
|
|
3400
|
+
}
|
|
3401
|
+
|
|
3187
3402
|
// Handle config commands specially
|
|
3188
3403
|
if (command === 'config') {
|
|
3189
3404
|
const configArgs = args.slice(1);
|
|
@@ -3251,14 +3466,21 @@ async function main() {
|
|
|
3251
3466
|
case 'install':
|
|
3252
3467
|
case 'i':
|
|
3253
3468
|
case 'add': {
|
|
3254
|
-
if (!param) {
|
|
3255
|
-
error('Please specify a skill name, GitHub repo, or local path.');
|
|
3469
|
+
if (!param && !collection) {
|
|
3470
|
+
error('Please specify a skill name, collection, GitHub repo, or local path.');
|
|
3256
3471
|
log('Usage: npx ai-agent-skills install <source> [-p]');
|
|
3472
|
+
log(' npx ai-agent-skills install --collection <id> [-p]');
|
|
3257
3473
|
process.exit(1);
|
|
3258
3474
|
}
|
|
3259
|
-
const source = parseSource(param);
|
|
3260
3475
|
const installPaths = resolveInstallPath(parsed);
|
|
3261
3476
|
|
|
3477
|
+
if (collection) {
|
|
3478
|
+
await installCollection(collection, parsed, installPaths);
|
|
3479
|
+
return;
|
|
3480
|
+
}
|
|
3481
|
+
|
|
3482
|
+
const source = parseSource(param);
|
|
3483
|
+
|
|
3262
3484
|
if (source.type === 'catalog') {
|
|
3263
3485
|
// Install from bundled library (original flow)
|
|
3264
3486
|
for (const targetPath of installPaths) {
|
|
@@ -3353,6 +3575,7 @@ async function main() {
|
|
|
3353
3575
|
trust,
|
|
3354
3576
|
whyHere: why,
|
|
3355
3577
|
description,
|
|
3578
|
+
collections: collection,
|
|
3356
3579
|
});
|
|
3357
3580
|
return;
|
|
3358
3581
|
}
|
|
@@ -3381,6 +3604,7 @@ async function main() {
|
|
|
3381
3604
|
trust,
|
|
3382
3605
|
whyHere: why,
|
|
3383
3606
|
description,
|
|
3607
|
+
collections: collection,
|
|
3384
3608
|
lastVerified,
|
|
3385
3609
|
featured,
|
|
3386
3610
|
clearVerified,
|