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 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
- - 35 skills total
9
- - 10 shelves
10
- - 11 house copies
11
- - 24 cataloged upstream
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 | 4 | Interface systems, web product craft, and frontend execution. |
101
- | Backend | 3 | Infra, tooling, application architecture, and codebase depth. |
102
- | Docs | 6 | Documents, specs, file handling, and long-form output. |
103
- | Testing | 2 | Review, QA, regression work, and keeping product quality sharp. |
104
- | Workflow | 3 | Execution patterns, prompting, ticketing, and operating rhythm. |
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 are small cross-shelf reading lists, not the main taxonomy.
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 "Frontend (Anthropic)"
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` | 13 |
178
+ | `anthropics/skills` | 11 |
169
179
  | `openai/skills` | 9 |
170
- | `ComposioHQ/awesome-claude-skills` | 4 |
180
+ | `Dimillian/Skills` | 4 |
171
181
  | `wshobson/agents` | 4 |
172
- | `MoizIbnYousaf/Ai-Agent-Skills` | 3 |
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 = getCatalogCounts(data);
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 cross-shelf reading lists layered on top of the main work-area shelves.${colors.reset}\n`);
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 install ${source} --skill <name>${colors.reset}`);
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}install <source>${colors.reset} Install skills (from library, GitHub, git URL, or local path)
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, docs, testing, workflow, research, design, business, ai, devops
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 testing Search the catalog
2867
- npx ai-agent-skills curate frontend-design --branch "UI Craft"
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,