ai-agent-skills 1.8.0 → 1.9.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/README.md CHANGED
@@ -42,6 +42,9 @@ npx ai-agent-skills browse
42
42
  npx ai-agent-skills install anthropics/skills
43
43
  npx ai-agent-skills install anthropics/skills/pdf # specific skill
44
44
 
45
+ # Install from any git URL (SSH or HTTPS)
46
+ npx ai-agent-skills install git@github.com:anthropics/skills.git
47
+
45
48
  # Install from local path
46
49
  npx ai-agent-skills install ./my-custom-skill
47
50
  ```
@@ -135,6 +138,7 @@ npx ai-agent-skills list --installed --agent cursor
135
138
  npx ai-agent-skills install <name> # installs to ALL agents
136
139
  npx ai-agent-skills install <name> --agent cursor # install to specific agent only
137
140
  npx ai-agent-skills install <owner/repo> # from GitHub (all agents)
141
+ npx ai-agent-skills install <git-url> # from any git URL (ssh/https)
138
142
  npx ai-agent-skills install ./path # from local path (all agents)
139
143
  npx ai-agent-skills install <name> --dry-run # preview only
140
144
 
package/cli.js CHANGED
@@ -620,6 +620,93 @@ function updateFromGitHub(meta, skillName, agent, destPath, dryRun) {
620
620
  }
621
621
  }
622
622
 
623
+ function updateFromGitUrl(meta, skillName, agent, destPath, dryRun) {
624
+ const { execFileSync } = require('child_process');
625
+ const parsed = parseGitUrl(meta.url);
626
+ const url = parsed.url;
627
+ const ref = meta.ref || parsed.ref;
628
+
629
+ // Validate URL from metadata
630
+ try {
631
+ validateGitUrl(url);
632
+ } catch (e) {
633
+ error(`Invalid git URL in metadata: ${e.message}. Try reinstalling the skill.`);
634
+ return false;
635
+ }
636
+
637
+ if (dryRun) {
638
+ log(`\n${colors.bold}Dry Run${colors.reset} (no changes made)\n`);
639
+ info(`Would update: ${skillName} (from git:${url}${ref ? `#${ref}` : ''})`);
640
+ info(`Agent: ${agent}`);
641
+ info(`Path: ${destPath}`);
642
+ return true;
643
+ }
644
+
645
+ // Use secure temp directory creation
646
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ai-skills-update-'));
647
+
648
+ try {
649
+ info(`Updating ${skillName} from ${url}${ref ? `#${ref}` : ''}...`);
650
+ const cloneArgs = ['clone', '--depth', '1'];
651
+ if (ref) {
652
+ cloneArgs.push('--branch', ref);
653
+ }
654
+ cloneArgs.push(url, tempDir);
655
+ execFileSync('git', cloneArgs, { stdio: 'pipe' });
656
+
657
+ let sourcePath;
658
+ if (meta.isRootSkill) {
659
+ sourcePath = tempDir;
660
+ } else if (meta.skillPath) {
661
+ const skillsSubdir = path.join(tempDir, 'skills', meta.skillPath);
662
+ const directPath = path.join(tempDir, meta.skillPath);
663
+ sourcePath = fs.existsSync(skillsSubdir) ? skillsSubdir : directPath;
664
+ } else {
665
+ sourcePath = tempDir;
666
+ }
667
+
668
+ if (!fs.existsSync(sourcePath) || !fs.existsSync(path.join(sourcePath, 'SKILL.md'))) {
669
+ error(`Skill not found in repository ${url}`);
670
+ fs.rmSync(tempDir, { recursive: true });
671
+ return false;
672
+ }
673
+
674
+ fs.rmSync(destPath, { recursive: true });
675
+ copyDir(sourcePath, destPath);
676
+
677
+ // Sanitize URL before storing
678
+ const sanitizedUrl = sanitizeGitUrl(url);
679
+
680
+ writeSkillMeta(destPath, {
681
+ ...meta,
682
+ source: 'git',
683
+ url: sanitizedUrl,
684
+ ref: ref || null
685
+ });
686
+
687
+ fs.rmSync(tempDir, { recursive: true });
688
+
689
+ success(`\nUpdated: ${skillName}`);
690
+ info(`Source: git:${url}${ref ? `#${ref}` : ''}`);
691
+ info(`Agent: ${agent}`);
692
+ info(`Location: ${destPath}`);
693
+ return true;
694
+ } catch (e) {
695
+ // Provide more helpful error messages for common git failures
696
+ let errorMsg = e.message;
697
+ if (e.message.includes('not found') || e.message.includes('Repository not found')) {
698
+ errorMsg = `Repository not found. The URL may have changed or been removed.`;
699
+ } else if (e.message.includes('Authentication failed') || e.message.includes('Permission denied')) {
700
+ errorMsg = `Authentication failed. Check your credentials or SSH key.`;
701
+ } else if (e.message.includes('Could not resolve host')) {
702
+ errorMsg = `Could not resolve host. Check your network connection.`;
703
+ }
704
+ error(`Failed to update from git: ${errorMsg}`);
705
+ try { fs.rmSync(tempDir, { recursive: true }); } catch {}
706
+ return false;
707
+ }
708
+ }
709
+
623
710
  // Update from local path
624
711
  function updateFromLocalPath(meta, skillName, agent, destPath, dryRun) {
625
712
  const sourcePath = meta.path;
@@ -696,6 +783,8 @@ function updateSkill(skillName, agent = 'claude', dryRun = false) {
696
783
  switch (meta.source) {
697
784
  case 'github':
698
785
  return updateFromGitHub(meta, skillName, agent, destPath, dryRun);
786
+ case 'git':
787
+ return updateFromGitUrl(meta, skillName, agent, destPath, dryRun);
699
788
  case 'local':
700
789
  return updateFromLocalPath(meta, skillName, agent, destPath, dryRun);
701
790
  case 'registry':
@@ -991,6 +1080,96 @@ function isGitHubUrl(source) {
991
1080
  !isWindowsPath(source);
992
1081
  }
993
1082
 
1083
+ function isGitUrl(source) {
1084
+ if (!source || typeof source !== 'string') return false;
1085
+
1086
+ // Avoid treating local filesystem paths as git URLs
1087
+ if (isLocalPath(source)) return false;
1088
+
1089
+ // SSH-style: git@host:path (with optional .git suffix and #ref)
1090
+ const sshLike = /^git@[a-zA-Z0-9._-]+:[a-zA-Z0-9._\/-]+(?:\.git)?(?:#[a-zA-Z0-9._\/-]+)?$/;
1091
+ // Protocol URLs: https://, git://, ssh://, file:// (allows @ for user in ssh://git@host)
1092
+ const protocolLike = /^(https?|git|ssh|file):\/\/[a-zA-Z0-9._@:\/-]+(?:#[a-zA-Z0-9._\/-]+)?$/;
1093
+
1094
+ return sshLike.test(source) || protocolLike.test(source);
1095
+ }
1096
+
1097
+ function parseGitUrl(source) {
1098
+ if (!source || typeof source !== 'string') return { url: null, ref: null };
1099
+ // Split on first # only (ref might contain special chars)
1100
+ const hashIndex = source.indexOf('#');
1101
+ if (hashIndex === -1) {
1102
+ return { url: source, ref: null };
1103
+ }
1104
+ return {
1105
+ url: source.slice(0, hashIndex),
1106
+ ref: source.slice(hashIndex + 1) || null
1107
+ };
1108
+ }
1109
+
1110
+ function getRepoNameFromUrl(url) {
1111
+ if (!url || typeof url !== 'string') return null;
1112
+
1113
+ // Remove trailing slashes and .git suffix
1114
+ let cleaned = url.replace(/\/+$/, '').replace(/\.git$/, '');
1115
+
1116
+ // Handle SSH URLs: git@host:org/repo -> extract 'repo'
1117
+ if (cleaned.includes('@') && cleaned.includes(':')) {
1118
+ const colonIndex = cleaned.lastIndexOf(':');
1119
+ const pathPart = cleaned.slice(colonIndex + 1);
1120
+ const segments = pathPart.split('/').filter(Boolean);
1121
+ return segments.length > 0 ? segments[segments.length - 1] : null;
1122
+ }
1123
+
1124
+ // Handle protocol URLs: extract last path segment
1125
+ const segments = cleaned.split('/').filter(Boolean);
1126
+ return segments.length > 0 ? segments[segments.length - 1] : null;
1127
+ }
1128
+
1129
+ // Validate git URL to prevent malformed/malicious input
1130
+ function validateGitUrl(url) {
1131
+ if (!url || typeof url !== 'string') {
1132
+ throw new Error('Invalid git URL: empty or not a string');
1133
+ }
1134
+
1135
+ // Max reasonable URL length
1136
+ if (url.length > 2048) {
1137
+ throw new Error('Git URL too long (max 2048 characters)');
1138
+ }
1139
+
1140
+ // Check for dangerous characters that could cause issues
1141
+ const dangerousChars = /[\x00-\x1f\x7f`$\\]/;
1142
+ if (dangerousChars.test(url)) {
1143
+ throw new Error('Git URL contains invalid characters');
1144
+ }
1145
+
1146
+ // Must match expected patterns
1147
+ if (!isGitUrl(url)) {
1148
+ throw new Error('Invalid git URL format');
1149
+ }
1150
+
1151
+ return true;
1152
+ }
1153
+
1154
+ // Sanitize URL for storage (remove credentials if present)
1155
+ function sanitizeGitUrl(url) {
1156
+ if (!url) return url;
1157
+ try {
1158
+ // Handle protocol URLs
1159
+ if (url.includes('://')) {
1160
+ const parsed = new URL(url);
1161
+ // Remove any embedded credentials
1162
+ parsed.username = '';
1163
+ parsed.password = '';
1164
+ return parsed.toString();
1165
+ }
1166
+ // SSH URLs don't typically have credentials embedded
1167
+ return url;
1168
+ } catch {
1169
+ return url;
1170
+ }
1171
+ }
1172
+
994
1173
  function isWindowsPath(source) {
995
1174
  // Match Windows absolute paths like C:\, D:\, etc.
996
1175
  return /^[a-zA-Z]:[\\\/]/.test(source);
@@ -1184,6 +1363,148 @@ async function installFromGitHub(source, agent = 'claude', dryRun = false) {
1184
1363
  }
1185
1364
  }
1186
1365
 
1366
+ async function installFromGitUrl(source, agent = 'claude', dryRun = false) {
1367
+ const { execFileSync } = require('child_process');
1368
+ const { url, ref } = parseGitUrl(source);
1369
+
1370
+ // Validate URL format and safety
1371
+ try {
1372
+ validateGitUrl(url);
1373
+ if (ref && !/^[a-zA-Z0-9._\/-]+$/.test(ref)) {
1374
+ throw new Error('Invalid ref format');
1375
+ }
1376
+ } catch (e) {
1377
+ error(`Invalid git URL: ${e.message}`);
1378
+ return false;
1379
+ }
1380
+
1381
+ const repoName = getRepoNameFromUrl(url);
1382
+ if (!repoName) {
1383
+ error('Could not determine repository name from git URL');
1384
+ return false;
1385
+ }
1386
+
1387
+ // Use secure temp directory creation
1388
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ai-skills-'));
1389
+
1390
+ if (dryRun) {
1391
+ log(`\n${colors.bold}Dry Run${colors.reset} (no changes made)\n`);
1392
+ info(`Would clone: ${url}${ref ? `#${ref}` : ''}`);
1393
+ info('Would install skills discovered in repository');
1394
+ info(`Agent: ${agent}`);
1395
+ return true;
1396
+ }
1397
+
1398
+ try {
1399
+ info(`Cloning ${url}${ref ? `#${ref}` : ''}...`);
1400
+ const cloneArgs = ['clone', '--depth', '1'];
1401
+ if (ref) {
1402
+ cloneArgs.push('--branch', ref);
1403
+ }
1404
+ cloneArgs.push(url, tempDir);
1405
+ execFileSync('git', cloneArgs, { stdio: 'pipe' });
1406
+
1407
+ const skillsDir = fs.existsSync(path.join(tempDir, 'skills'))
1408
+ ? path.join(tempDir, 'skills')
1409
+ : tempDir;
1410
+
1411
+ const isRootSkill = fs.existsSync(path.join(tempDir, 'SKILL.md'));
1412
+
1413
+ if (isRootSkill) {
1414
+ const skillName = repoName.toLowerCase()
1415
+ .replace(/[^a-z0-9-]/g, '-')
1416
+ .replace(/-+/g, '-')
1417
+ .replace(/^-|-$/g, '');
1418
+
1419
+ try {
1420
+ validateSkillName(skillName);
1421
+ } catch (e) {
1422
+ error(`Cannot install: repo name "${repoName}" cannot be converted to valid skill name`);
1423
+ fs.rmSync(tempDir, { recursive: true });
1424
+ return false;
1425
+ }
1426
+
1427
+ const destDir = AGENT_PATHS[agent] || AGENT_PATHS.claude;
1428
+ const destPath = path.join(destDir, skillName);
1429
+
1430
+ if (!fs.existsSync(destDir)) {
1431
+ fs.mkdirSync(destDir, { recursive: true });
1432
+ }
1433
+
1434
+ copyDir(tempDir, destPath);
1435
+
1436
+ // Sanitize URL before storing in metadata
1437
+ const sanitizedUrl = sanitizeGitUrl(url);
1438
+
1439
+ writeSkillMeta(destPath, {
1440
+ source: 'git',
1441
+ url: sanitizedUrl,
1442
+ ref: ref || null,
1443
+ isRootSkill: true
1444
+ });
1445
+
1446
+ success(`\nInstalled: ${skillName} from ${url}`);
1447
+ info(`Location: ${destPath}`);
1448
+ } else {
1449
+ const entries = fs.readdirSync(skillsDir, { withFileTypes: true });
1450
+ let installed = 0;
1451
+
1452
+ // Sanitize URL before storing in metadata
1453
+ const sanitizedUrl = sanitizeGitUrl(url);
1454
+
1455
+ for (const entry of entries) {
1456
+ if (entry.isDirectory()) {
1457
+ const skillPath = path.join(skillsDir, entry.name);
1458
+ if (fs.existsSync(path.join(skillPath, 'SKILL.md'))) {
1459
+ const destDir = AGENT_PATHS[agent] || AGENT_PATHS.claude;
1460
+ const destPath = path.join(destDir, entry.name);
1461
+
1462
+ if (!fs.existsSync(destDir)) {
1463
+ fs.mkdirSync(destDir, { recursive: true });
1464
+ }
1465
+
1466
+ copyDir(skillPath, destPath);
1467
+
1468
+ writeSkillMeta(destPath, {
1469
+ source: 'git',
1470
+ url: sanitizedUrl,
1471
+ ref: ref || null,
1472
+ skillPath: entry.name
1473
+ });
1474
+
1475
+ log(` ${colors.green}✓${colors.reset} ${entry.name}`);
1476
+ installed++;
1477
+ }
1478
+ }
1479
+ }
1480
+
1481
+ if (installed > 0) {
1482
+ success(`\nInstalled ${installed} skill(s) from ${url}`);
1483
+ } else {
1484
+ warn('No skills found in repository');
1485
+ }
1486
+ }
1487
+
1488
+ fs.rmSync(tempDir, { recursive: true });
1489
+ return true;
1490
+ } catch (e) {
1491
+ // Provide more helpful error messages for common git failures
1492
+ let errorMsg = e.message;
1493
+ if (e.message.includes('not found') || e.message.includes('Repository not found')) {
1494
+ errorMsg = `Repository not found. Check the URL is correct and you have access.`;
1495
+ } else if (e.message.includes('Authentication failed') || e.message.includes('Permission denied')) {
1496
+ errorMsg = `Authentication failed. For SSH URLs, ensure your SSH key is configured. For HTTPS, check credentials.`;
1497
+ } else if (e.message.includes('Could not resolve host')) {
1498
+ errorMsg = `Could not resolve host. Check your network connection and the URL.`;
1499
+ } else if (e.message.includes('Connection refused') || e.message.includes('Connection timed out')) {
1500
+ errorMsg = `Connection failed. Check your network connection.`;
1501
+ }
1502
+ error(`Failed to install from git: ${errorMsg}`);
1503
+ try { fs.rmSync(tempDir, { recursive: true }); } catch {}
1504
+ return false;
1505
+ }
1506
+ }
1507
+
1187
1508
  function installFromLocalPath(source, agent = 'claude', dryRun = false) {
1188
1509
  const sourcePath = expandPath(source);
1189
1510
 
@@ -1286,6 +1607,7 @@ ${colors.bold}Commands:${colors.reset}
1286
1607
  ${colors.green}install <name>${colors.reset} Install to ALL agents (default)
1287
1608
  ${colors.green}install <name> --agent cursor${colors.reset} Install to specific agent only
1288
1609
  ${colors.green}install <owner/repo>${colors.reset} Install from GitHub repository
1610
+ ${colors.green}install <git-url>${colors.reset} Install from any git URL (ssh/https)
1289
1611
  ${colors.green}install ./path${colors.reset} Install from local path
1290
1612
  ${colors.green}install <name> --dry-run${colors.reset} Preview installation without changes
1291
1613
  ${colors.green}uninstall <name>${colors.reset} Remove an installed skill
@@ -1323,13 +1645,14 @@ ${colors.bold}Categories:${colors.reset}
1323
1645
  development, document, creative, business, productivity
1324
1646
 
1325
1647
  ${colors.bold}Examples:${colors.reset}
1326
- npx ai-agent-skills browse # Interactive browser
1327
- npx ai-agent-skills install frontend-design # Install to ALL agents
1328
- npx ai-agent-skills install pdf --agent cursor # Install to Cursor only
1329
- npx ai-agent-skills install pdf --agents claude,cursor # Install to specific agents
1330
- npx ai-agent-skills install anthropics/skills # Install from GitHub
1331
- npx ai-agent-skills install ./my-skill # Install from local path
1332
- npx ai-agent-skills install pdf --dry-run # Preview install
1648
+ npx ai-agent-skills browse # Interactive browser
1649
+ npx ai-agent-skills install frontend-design # Install to ALL agents
1650
+ npx ai-agent-skills install pdf --agent cursor # Install to Cursor only
1651
+ npx ai-agent-skills install pdf --agents claude,cursor # Install to specific agents
1652
+ npx ai-agent-skills install anthropics/skills # Install from GitHub
1653
+ npx ai-agent-skills install git@example.com:user/repo.git # Install from any git URL (ssh/https)
1654
+ npx ai-agent-skills install ./my-skill # Install from local path
1655
+ npx ai-agent-skills install pdf --dry-run # Preview install
1333
1656
  npx ai-agent-skills list --category development
1334
1657
  npx ai-agent-skills search testing
1335
1658
  npx ai-agent-skills update --all
@@ -1488,6 +1811,8 @@ switch (command || 'help') {
1488
1811
  for (const agent of installTargets) {
1489
1812
  if (isLocalPath(param)) {
1490
1813
  installFromLocalPath(param, agent, dryRun);
1814
+ } else if (isGitUrl(param)) {
1815
+ installFromGitUrl(param, agent, dryRun);
1491
1816
  } else if (isGitHubUrl(param)) {
1492
1817
  installFromGitHub(param, agent, dryRun);
1493
1818
  } else {
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "ai-agent-skills",
3
- "version": "1.8.0",
3
+ "version": "1.9.1",
4
4
  "description": "Install curated AI agent skills with one command. Works with Claude Code, Cursor, Codex, Gemini CLI, VS Code, Copilot, and 11+ agents.",
5
5
  "main": "cli.js",
6
6
  "bin": {
7
- "ai-agent-skills": "./cli.js",
8
- "skills": "./cli.js"
7
+ "ai-agent-skills": "cli.js",
8
+ "skills": "cli.js"
9
9
  },
10
10
  "engines": {
11
11
  "node": ">=14.14.0"
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: expo-app-design
3
+ description: Build beautiful cross-platform mobile apps with Expo Router, NativeWind, and React Native.
4
+ author: expo
5
+ category: development
6
+ tags: [expo, react, typescript]
7
+ ---
8
+
9
+ # Expo App Design
10
+
11
+ Build beautiful cross-platform mobile apps with Expo Router, NativeWind, and React Native.
12
+
13
+ ## When to Use
14
+
15
+ - Building mobile apps with Expo
16
+ - Navigation with Expo Router
17
+ - Styling with NativeWind/Tailwind
18
+ - Native tabs and animations
19
+
20
+ ## Source
21
+
22
+ This skill references patterns from [Expo's skills](https://github.com/expo/skills).
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: expo-deployment
3
+ description: Deploy Expo apps to iOS App Store, Android Play Store, and web.
4
+ author: expo
5
+ category: development
6
+ tags: [expo, react, node]
7
+ ---
8
+
9
+ # Expo Deployment
10
+
11
+ Deploy Expo apps to iOS App Store, Android Play Store, and web.
12
+
13
+ ## When to Use
14
+
15
+ - Publishing to App Store / Play Store
16
+ - EAS Build configuration
17
+ - OTA updates
18
+ - CI/CD workflows for mobile
19
+
20
+ ## Source
21
+
22
+ This skill references patterns from [Expo's skills](https://github.com/expo/skills).
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: react-best-practices
3
+ description: React development guidelines with hooks, component patterns, state management, and performance optimization.
4
+ author: vercel
5
+ category: development
6
+ tags: [react, typescript, nextjs]
7
+ ---
8
+
9
+ # React Best Practices
10
+
11
+ Modern React development guidelines covering hooks, component patterns, state management, and performance optimization.
12
+
13
+ ## When to Use
14
+
15
+ - Building React applications
16
+ - Learning React best practices
17
+ - Code reviews for React projects
18
+ - Performance optimization
19
+
20
+ ## Source
21
+
22
+ This skill references patterns from [Vercel's agent-skills](https://github.com/vercel-labs/agent-skills).
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: upgrading-expo
3
+ description: Guidelines for upgrading Expo SDK versions and fixing dependency issues.
4
+ author: expo
5
+ category: development
6
+ tags: [expo, react, typescript]
7
+ ---
8
+
9
+ # Upgrading Expo
10
+
11
+ Guidelines for upgrading Expo SDK versions and fixing dependency issues.
12
+
13
+ ## When to Use
14
+
15
+ - Upgrading Expo SDK versions
16
+ - Fixing dependency conflicts
17
+ - Migration patterns
18
+ - Breaking change handling
19
+
20
+ ## Source
21
+
22
+ This skill references patterns from [Expo's skills](https://github.com/expo/skills).
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: vercel-deploy
3
+ description: Deploy applications to Vercel with edge functions, serverless, and ISR.
4
+ author: vercel
5
+ category: development
6
+ tags: [nextjs, node, typescript]
7
+ ---
8
+
9
+ # Vercel Deploy
10
+
11
+ Deploy applications to Vercel with edge functions, serverless, and ISR.
12
+
13
+ ## When to Use
14
+
15
+ - Deploying Next.js applications
16
+ - Setting up edge functions
17
+ - Configuring ISR (Incremental Static Regeneration)
18
+ - Serverless deployments
19
+
20
+ ## Source
21
+
22
+ This skill references patterns from [Vercel's agent-skills](https://github.com/vercel-labs/agent-skills).
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: web-design-guidelines
3
+ description: Modern web design principles for responsive layouts, accessibility, and visual hierarchy.
4
+ author: vercel
5
+ category: development
6
+ tags: [react, nextjs, typescript]
7
+ ---
8
+
9
+ # Web Design Guidelines
10
+
11
+ Modern web design principles for responsive layouts, accessibility, and visual hierarchy.
12
+
13
+ ## When to Use
14
+
15
+ - Creating polished web interfaces
16
+ - Improving accessibility
17
+ - Responsive design patterns
18
+ - Visual hierarchy decisions
19
+
20
+ ## Source
21
+
22
+ This skill references patterns from [Vercel's agent-skills](https://github.com/vercel-labs/agent-skills).
package/skills.json CHANGED
@@ -1,8 +1,92 @@
1
1
  {
2
- "version": "1.2.2",
3
- "updated": "2026-01-01T00:00:00Z",
4
- "total": 40,
2
+ "version": "1.3.0",
3
+ "updated": "2026-01-16T00:00:00Z",
4
+ "total": 46,
5
5
  "skills": [
6
+ {
7
+ "name": "react-best-practices",
8
+ "description": "React development guidelines with hooks, component patterns, state management, and performance optimization. Use for building React apps with modern best practices.",
9
+ "category": "development",
10
+ "author": "vercel",
11
+ "source": "vercel/skills",
12
+ "license": "MIT",
13
+ "path": "skills/react-best-practices",
14
+ "tags": ["react", "typescript", "nextjs"],
15
+ "stars": 15000,
16
+ "downloads": 2400,
17
+ "featured": true,
18
+ "verified": true
19
+ },
20
+ {
21
+ "name": "web-design-guidelines",
22
+ "description": "Modern web design principles for responsive layouts, accessibility, and visual hierarchy. Use for creating polished web interfaces.",
23
+ "category": "development",
24
+ "author": "vercel",
25
+ "source": "vercel/skills",
26
+ "license": "MIT",
27
+ "path": "skills/web-design-guidelines",
28
+ "tags": ["react", "nextjs", "typescript"],
29
+ "stars": 15000,
30
+ "downloads": 1800,
31
+ "featured": false,
32
+ "verified": true
33
+ },
34
+ {
35
+ "name": "vercel-deploy",
36
+ "description": "Deploy applications to Vercel with edge functions, serverless, and ISR. Use for deploying Next.js and other web applications.",
37
+ "category": "development",
38
+ "author": "vercel",
39
+ "source": "vercel/skills",
40
+ "license": "MIT",
41
+ "path": "skills/vercel-deploy",
42
+ "tags": ["nextjs", "node", "typescript"],
43
+ "stars": 15000,
44
+ "downloads": 2100,
45
+ "featured": true,
46
+ "verified": true
47
+ },
48
+ {
49
+ "name": "expo-app-design",
50
+ "description": "Build beautiful cross-platform mobile apps with Expo Router, NativeWind, and React Native. Covers navigation, styling, animations, and native tabs.",
51
+ "category": "development",
52
+ "author": "expo",
53
+ "source": "expo/skills",
54
+ "license": "MIT",
55
+ "path": "skills/expo-app-design",
56
+ "tags": ["expo", "react", "typescript"],
57
+ "stars": 38000,
58
+ "downloads": 3200,
59
+ "featured": true,
60
+ "verified": true
61
+ },
62
+ {
63
+ "name": "expo-deployment",
64
+ "description": "Deploy Expo apps to iOS App Store, Android Play Store, and web. Covers EAS Build, OTA updates, and CI/CD workflows.",
65
+ "category": "development",
66
+ "author": "expo",
67
+ "source": "expo/skills",
68
+ "license": "MIT",
69
+ "path": "skills/expo-deployment",
70
+ "tags": ["expo", "react", "node"],
71
+ "stars": 38000,
72
+ "downloads": 2800,
73
+ "featured": true,
74
+ "verified": true
75
+ },
76
+ {
77
+ "name": "upgrading-expo",
78
+ "description": "Guidelines for upgrading Expo SDK versions and fixing dependency issues. Safe migration patterns and breaking change handling.",
79
+ "category": "development",
80
+ "author": "expo",
81
+ "source": "expo/skills",
82
+ "license": "MIT",
83
+ "path": "skills/upgrading-expo",
84
+ "tags": ["expo", "react", "typescript"],
85
+ "stars": 38000,
86
+ "downloads": 1500,
87
+ "featured": false,
88
+ "verified": true
89
+ },
6
90
  {
7
91
  "name": "frontend-design",
8
92
  "description": "Create distinctive, production-grade frontend interfaces with high design quality. Use for building web components, pages, dashboards, React components, HTML/CSS layouts, or styling any web UI.",
@@ -11,6 +95,7 @@
11
95
  "source": "anthropics/skills",
12
96
  "license": "Apache-2.0",
13
97
  "path": "skills/frontend-design",
98
+ "tags": ["react", "typescript", "nextjs"],
14
99
  "stars": 21600,
15
100
  "downloads": 1320,
16
101
  "featured": true,
@@ -24,6 +109,7 @@
24
109
  "source": "anthropics/skills",
25
110
  "license": "Apache-2.0",
26
111
  "path": "skills/pdf",
112
+ "tags": ["python"],
27
113
  "stars": 21600,
28
114
  "downloads": 890,
29
115
  "featured": true,
@@ -76,6 +162,7 @@
76
162
  "source": "anthropics/skills",
77
163
  "license": "Apache-2.0",
78
164
  "path": "skills/mcp-builder",
165
+ "tags": ["python", "typescript", "node"],
79
166
  "stars": 21600,
80
167
  "downloads": 1150,
81
168
  "featured": true,
@@ -141,6 +228,7 @@
141
228
  "source": "anthropics/skills",
142
229
  "license": "Apache-2.0",
143
230
  "path": "skills/webapp-testing",
231
+ "tags": ["typescript", "node", "react"],
144
232
  "stars": 21600,
145
233
  "downloads": 620,
146
234
  "featured": false,
@@ -193,6 +281,7 @@
193
281
  "source": "wshobson/agents",
194
282
  "license": "MIT",
195
283
  "path": "skills/python-development",
284
+ "tags": ["python"],
196
285
  "stars": 22900,
197
286
  "downloads": 388,
198
287
  "featured": false,
@@ -206,6 +295,7 @@
206
295
  "source": "wshobson/agents",
207
296
  "license": "MIT",
208
297
  "path": "skills/javascript-typescript",
298
+ "tags": ["typescript", "react", "node"],
209
299
  "stars": 22900,
210
300
  "downloads": 394,
211
301
  "featured": false,
@@ -219,6 +309,7 @@
219
309
  "source": "wshobson/agents",
220
310
  "license": "MIT",
221
311
  "path": "skills/backend-development",
312
+ "tags": ["node", "python", "typescript"],
222
313
  "stars": 22900,
223
314
  "downloads": 320,
224
315
  "featured": false,
@@ -258,6 +349,7 @@
258
349
  "source": "wshobson/agents",
259
350
  "license": "MIT",
260
351
  "path": "skills/llm-application-dev",
352
+ "tags": ["python", "typescript", "node"],
261
353
  "stars": 22900,
262
354
  "downloads": 560,
263
355
  "featured": true,
@@ -297,6 +389,7 @@
297
389
  "source": "skillcreatorai/Ai-Agent-Skills",
298
390
  "license": "MIT",
299
391
  "path": "skills/qa-regression",
392
+ "tags": ["typescript", "node"],
300
393
  "stars": 100,
301
394
  "downloads": 0,
302
395
  "featured": true,
@@ -337,6 +430,7 @@
337
430
  "source": "ComposioHQ/awesome-claude-skills",
338
431
  "license": "Apache-2.0",
339
432
  "path": "skills/artifacts-builder",
433
+ "tags": ["react", "typescript"],
340
434
  "stars": 500,
341
435
  "downloads": 0,
342
436
  "featured": false,