ai-agent-skills 1.1.1 → 1.2.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 +38 -29
- package/cli.js +313 -9
- package/package.json +1 -1
- package/skills.json +1 -1
package/README.md
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
</h1>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
<strong>
|
|
9
|
-
One command.
|
|
8
|
+
<strong>Homebrew for AI agent skills.</strong><br>
|
|
9
|
+
One command. Ten agents. Skills that follow you.
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
@@ -29,13 +29,23 @@
|
|
|
29
29
|
## Quick Start
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
|
-
#
|
|
32
|
+
# Browse skills interactively
|
|
33
|
+
npx ai-agent-skills browse
|
|
34
|
+
|
|
35
|
+
# Install from our curated catalog
|
|
33
36
|
npx ai-agent-skills install frontend-design
|
|
34
37
|
|
|
35
|
-
# Install for
|
|
38
|
+
# Install for specific agents
|
|
36
39
|
npx ai-agent-skills install frontend-design --agent cursor
|
|
37
|
-
npx ai-agent-skills install frontend-design --agent codex
|
|
40
|
+
npx ai-agent-skills install frontend-design --agent codex
|
|
38
41
|
npx ai-agent-skills install frontend-design --agent amp
|
|
42
|
+
|
|
43
|
+
# Install from any GitHub repo
|
|
44
|
+
npx ai-agent-skills install anthropics/skills
|
|
45
|
+
npx ai-agent-skills install anthropics/skills/pdf # specific skill
|
|
46
|
+
|
|
47
|
+
# Install from local path
|
|
48
|
+
npx ai-agent-skills install ./my-custom-skill
|
|
39
49
|
```
|
|
40
50
|
|
|
41
51
|
That's it. The skill installs to the right location for your agent automatically.
|
|
@@ -114,43 +124,32 @@ Works with **Claude Code**, **Cursor**, **Amp**, **VS Code**, **GitHub Copilot**
|
|
|
114
124
|
## Commands
|
|
115
125
|
|
|
116
126
|
```bash
|
|
127
|
+
# Interactive browser (TUI)
|
|
128
|
+
npx ai-agent-skills browse
|
|
129
|
+
|
|
117
130
|
# List all available skills
|
|
118
131
|
npx ai-agent-skills list
|
|
119
|
-
|
|
120
|
-
# Filter by category
|
|
121
132
|
npx ai-agent-skills list --category development
|
|
122
|
-
|
|
123
|
-
# List installed skills for an agent
|
|
124
|
-
npx ai-agent-skills list --installed
|
|
125
133
|
npx ai-agent-skills list --installed --agent cursor
|
|
126
134
|
|
|
127
|
-
# Install
|
|
128
|
-
npx ai-agent-skills install <name>
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
npx ai-agent-skills install
|
|
135
|
+
# Install from catalog, GitHub, or local path
|
|
136
|
+
npx ai-agent-skills install <name> # from catalog
|
|
137
|
+
npx ai-agent-skills install <owner/repo> # from GitHub
|
|
138
|
+
npx ai-agent-skills install <owner/repo/skill> # specific skill from GitHub
|
|
139
|
+
npx ai-agent-skills install ./path # from local path
|
|
140
|
+
npx ai-agent-skills install <name> --agent cursor # for specific agent
|
|
141
|
+
npx ai-agent-skills install <name> --dry-run # preview only
|
|
132
142
|
|
|
133
|
-
#
|
|
134
|
-
npx ai-agent-skills install <name> --agent <agent>
|
|
135
|
-
|
|
136
|
-
# Uninstall a skill
|
|
143
|
+
# Manage installed skills
|
|
137
144
|
npx ai-agent-skills uninstall <name>
|
|
138
|
-
npx ai-agent-skills uninstall <name> --agent cursor
|
|
139
|
-
|
|
140
|
-
# Update a skill to latest version
|
|
141
145
|
npx ai-agent-skills update <name>
|
|
142
|
-
|
|
143
|
-
# Update all installed skills
|
|
144
146
|
npx ai-agent-skills update --all
|
|
145
147
|
|
|
146
|
-
#
|
|
148
|
+
# Discovery
|
|
147
149
|
npx ai-agent-skills search <query>
|
|
148
|
-
|
|
149
|
-
# Get skill details
|
|
150
150
|
npx ai-agent-skills info <name>
|
|
151
151
|
|
|
152
|
-
#
|
|
153
|
-
npx ai-agent-skills config
|
|
152
|
+
# Configuration
|
|
154
153
|
npx ai-agent-skills config --default-agent cursor
|
|
155
154
|
```
|
|
156
155
|
|
|
@@ -216,6 +215,16 @@ We review all contributions for quality and spec compliance.
|
|
|
216
215
|
- [Create Skills](https://skillcreator.ai/build) - Generate skills from plain English
|
|
217
216
|
- [Anthropic Skills](https://github.com/anthropics/skills) - Official example skills
|
|
218
217
|
|
|
218
|
+
## See Also
|
|
219
|
+
|
|
220
|
+
**[openskills](https://github.com/numman-ali/openskills)** - Universal skills loader that inspired parts of this project. openskills focuses on flexibility: install from any GitHub repo, sync to AGENTS.md, works with any agent via CLI calls. Great if you need maximum customization.
|
|
221
|
+
|
|
222
|
+
**We took a different approach**: Homebrew-style simplicity. No global install, no sync step, no AGENTS.md. Just `npx ai-agent-skills install pdf` and it lands in the right folder for your agent. Curated catalog, native paths, zero config.
|
|
223
|
+
|
|
224
|
+
Different tools for different needs.
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
219
228
|
## Credits & Attribution
|
|
220
229
|
|
|
221
230
|
This repository builds upon and curates skills from the open-source community:
|
package/cli.js
CHANGED
|
@@ -659,21 +659,310 @@ function levenshteinDistance(a, b) {
|
|
|
659
659
|
return matrix[b.length][a.length];
|
|
660
660
|
}
|
|
661
661
|
|
|
662
|
+
// ============ INTERACTIVE BROWSE ============
|
|
663
|
+
|
|
664
|
+
async function browseSkills(agent = 'claude') {
|
|
665
|
+
const readline = require('readline');
|
|
666
|
+
const data = loadSkillsJson();
|
|
667
|
+
const skills = data.skills || [];
|
|
668
|
+
|
|
669
|
+
if (skills.length === 0) {
|
|
670
|
+
warn('No skills available');
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
// Group by category
|
|
675
|
+
const categories = [...new Set(skills.map(s => s.category))].sort();
|
|
676
|
+
let currentCategory = 0;
|
|
677
|
+
let currentSkill = 0;
|
|
678
|
+
let mode = 'category'; // 'category' or 'skill'
|
|
679
|
+
|
|
680
|
+
const getSkillsInCategory = (cat) => skills.filter(s => s.category === cat);
|
|
681
|
+
|
|
682
|
+
const render = () => {
|
|
683
|
+
console.clear();
|
|
684
|
+
log(`\n${colors.bold}🔧 AI Agent Skills Browser${colors.reset}`);
|
|
685
|
+
log(`${colors.dim}Use ↑↓ to navigate, Enter to select, q to quit${colors.reset}\n`);
|
|
686
|
+
|
|
687
|
+
if (mode === 'category') {
|
|
688
|
+
log(`${colors.bold}Categories:${colors.reset}\n`);
|
|
689
|
+
categories.forEach((cat, i) => {
|
|
690
|
+
const count = getSkillsInCategory(cat).length;
|
|
691
|
+
const prefix = i === currentCategory ? `${colors.cyan}▶ ` : ' ';
|
|
692
|
+
const suffix = i === currentCategory ? colors.reset : '';
|
|
693
|
+
log(`${prefix}${cat.toUpperCase()} (${count})${suffix}`);
|
|
694
|
+
});
|
|
695
|
+
log(`\n${colors.dim}Press Enter to browse skills in this category${colors.reset}`);
|
|
696
|
+
} else {
|
|
697
|
+
const cat = categories[currentCategory];
|
|
698
|
+
const catSkills = getSkillsInCategory(cat);
|
|
699
|
+
log(`${colors.bold}${cat.toUpperCase()}${colors.reset} ${colors.dim}(← Backspace to go back)${colors.reset}\n`);
|
|
700
|
+
|
|
701
|
+
catSkills.forEach((skill, i) => {
|
|
702
|
+
const prefix = i === currentSkill ? `${colors.green}▶ ` : ' ';
|
|
703
|
+
const suffix = i === currentSkill ? colors.reset : '';
|
|
704
|
+
const featured = skill.featured ? ` ${colors.yellow}★${colors.reset}` : '';
|
|
705
|
+
log(`${prefix}${skill.name}${featured}${suffix}`);
|
|
706
|
+
if (i === currentSkill) {
|
|
707
|
+
log(` ${colors.dim}${skill.description.slice(0, 60)}...${colors.reset}`);
|
|
708
|
+
}
|
|
709
|
+
});
|
|
710
|
+
log(`\n${colors.dim}Press Enter to install, i for info${colors.reset}`);
|
|
711
|
+
}
|
|
712
|
+
};
|
|
713
|
+
|
|
714
|
+
return new Promise((resolve) => {
|
|
715
|
+
readline.emitKeypressEvents(process.stdin);
|
|
716
|
+
if (process.stdin.isTTY) {
|
|
717
|
+
process.stdin.setRawMode(true);
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
render();
|
|
721
|
+
|
|
722
|
+
process.stdin.on('keypress', (str, key) => {
|
|
723
|
+
if (key.name === 'q' || (key.ctrl && key.name === 'c')) {
|
|
724
|
+
console.clear();
|
|
725
|
+
log('Goodbye!');
|
|
726
|
+
process.stdin.setRawMode(false);
|
|
727
|
+
process.exit(0);
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
if (mode === 'category') {
|
|
731
|
+
if (key.name === 'up') {
|
|
732
|
+
currentCategory = Math.max(0, currentCategory - 1);
|
|
733
|
+
} else if (key.name === 'down') {
|
|
734
|
+
currentCategory = Math.min(categories.length - 1, currentCategory + 1);
|
|
735
|
+
} else if (key.name === 'return') {
|
|
736
|
+
mode = 'skill';
|
|
737
|
+
currentSkill = 0;
|
|
738
|
+
}
|
|
739
|
+
} else {
|
|
740
|
+
const catSkills = getSkillsInCategory(categories[currentCategory]);
|
|
741
|
+
if (key.name === 'up') {
|
|
742
|
+
currentSkill = Math.max(0, currentSkill - 1);
|
|
743
|
+
} else if (key.name === 'down') {
|
|
744
|
+
currentSkill = Math.min(catSkills.length - 1, currentSkill + 1);
|
|
745
|
+
} else if (key.name === 'backspace' || key.name === 'escape') {
|
|
746
|
+
mode = 'category';
|
|
747
|
+
} else if (key.name === 'return') {
|
|
748
|
+
const skill = catSkills[currentSkill];
|
|
749
|
+
console.clear();
|
|
750
|
+
process.stdin.setRawMode(false);
|
|
751
|
+
installSkill(skill.name, agent, false);
|
|
752
|
+
resolve();
|
|
753
|
+
return;
|
|
754
|
+
} else if (str === 'i') {
|
|
755
|
+
const skill = catSkills[currentSkill];
|
|
756
|
+
console.clear();
|
|
757
|
+
process.stdin.setRawMode(false);
|
|
758
|
+
showInfo(skill.name);
|
|
759
|
+
resolve();
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
render();
|
|
764
|
+
});
|
|
765
|
+
});
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
// ============ EXTERNAL INSTALL (GitHub/Local) ============
|
|
769
|
+
|
|
770
|
+
function isGitHubUrl(source) {
|
|
771
|
+
return source.includes('/') && !source.startsWith('.') && !source.startsWith('/') && !source.startsWith('~');
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
function isLocalPath(source) {
|
|
775
|
+
return source.startsWith('.') || source.startsWith('/') || source.startsWith('~');
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
function expandPath(p) {
|
|
779
|
+
if (p.startsWith('~')) {
|
|
780
|
+
return path.join(os.homedir(), p.slice(1));
|
|
781
|
+
}
|
|
782
|
+
return path.resolve(p);
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
async function installFromGitHub(source, agent = 'claude', dryRun = false) {
|
|
786
|
+
const { execSync } = require('child_process');
|
|
787
|
+
|
|
788
|
+
// Parse owner/repo format
|
|
789
|
+
const parts = source.split('/');
|
|
790
|
+
if (parts.length < 2) {
|
|
791
|
+
error('Invalid GitHub source. Use format: owner/repo or owner/repo/skill-name');
|
|
792
|
+
return false;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
const owner = parts[0];
|
|
796
|
+
const repo = parts[1];
|
|
797
|
+
const skillName = parts[2]; // Optional specific skill
|
|
798
|
+
|
|
799
|
+
const repoUrl = `https://github.com/${owner}/${repo}.git`;
|
|
800
|
+
const tempDir = path.join(os.tmpdir(), `ai-skills-${Date.now()}`);
|
|
801
|
+
|
|
802
|
+
if (dryRun) {
|
|
803
|
+
log(`\n${colors.bold}Dry Run${colors.reset} (no changes made)\n`);
|
|
804
|
+
info(`Would clone: ${repoUrl}`);
|
|
805
|
+
info(`Would install ${skillName ? `skill: ${skillName}` : 'all skills from repo'}`);
|
|
806
|
+
info(`Agent: ${agent}`);
|
|
807
|
+
return true;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
try {
|
|
811
|
+
info(`Cloning ${owner}/${repo}...`);
|
|
812
|
+
execSync(`git clone --depth 1 ${repoUrl} ${tempDir}`, { stdio: 'pipe' });
|
|
813
|
+
|
|
814
|
+
// Find skills in the cloned repo
|
|
815
|
+
const skillsDir = fs.existsSync(path.join(tempDir, 'skills'))
|
|
816
|
+
? path.join(tempDir, 'skills')
|
|
817
|
+
: tempDir;
|
|
818
|
+
|
|
819
|
+
if (skillName) {
|
|
820
|
+
// Install specific skill
|
|
821
|
+
const skillPath = path.join(skillsDir, skillName);
|
|
822
|
+
if (!fs.existsSync(skillPath) || !fs.existsSync(path.join(skillPath, 'SKILL.md'))) {
|
|
823
|
+
error(`Skill "${skillName}" not found in ${owner}/${repo}`);
|
|
824
|
+
fs.rmSync(tempDir, { recursive: true });
|
|
825
|
+
return false;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
const destDir = AGENT_PATHS[agent] || AGENT_PATHS.claude;
|
|
829
|
+
const destPath = path.join(destDir, skillName);
|
|
830
|
+
|
|
831
|
+
if (!fs.existsSync(destDir)) {
|
|
832
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
copyDir(skillPath, destPath);
|
|
836
|
+
success(`\nInstalled: ${skillName} from ${owner}/${repo}`);
|
|
837
|
+
info(`Location: ${destPath}`);
|
|
838
|
+
} else {
|
|
839
|
+
// Install all skills from repo
|
|
840
|
+
const entries = fs.readdirSync(skillsDir, { withFileTypes: true });
|
|
841
|
+
let installed = 0;
|
|
842
|
+
|
|
843
|
+
for (const entry of entries) {
|
|
844
|
+
if (entry.isDirectory()) {
|
|
845
|
+
const skillPath = path.join(skillsDir, entry.name);
|
|
846
|
+
if (fs.existsSync(path.join(skillPath, 'SKILL.md'))) {
|
|
847
|
+
const destDir = AGENT_PATHS[agent] || AGENT_PATHS.claude;
|
|
848
|
+
const destPath = path.join(destDir, entry.name);
|
|
849
|
+
|
|
850
|
+
if (!fs.existsSync(destDir)) {
|
|
851
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
copyDir(skillPath, destPath);
|
|
855
|
+
log(` ${colors.green}✓${colors.reset} ${entry.name}`);
|
|
856
|
+
installed++;
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
if (installed > 0) {
|
|
862
|
+
success(`\nInstalled ${installed} skill(s) from ${owner}/${repo}`);
|
|
863
|
+
} else {
|
|
864
|
+
warn('No skills found in repository');
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
// Cleanup
|
|
869
|
+
fs.rmSync(tempDir, { recursive: true });
|
|
870
|
+
return true;
|
|
871
|
+
} catch (e) {
|
|
872
|
+
error(`Failed to install from GitHub: ${e.message}`);
|
|
873
|
+
try { fs.rmSync(tempDir, { recursive: true }); } catch {}
|
|
874
|
+
return false;
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
function installFromLocalPath(source, agent = 'claude', dryRun = false) {
|
|
879
|
+
const sourcePath = expandPath(source);
|
|
880
|
+
|
|
881
|
+
if (!fs.existsSync(sourcePath)) {
|
|
882
|
+
error(`Path not found: ${sourcePath}`);
|
|
883
|
+
return false;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
const stat = fs.statSync(sourcePath);
|
|
887
|
+
if (!stat.isDirectory()) {
|
|
888
|
+
error('Source must be a directory');
|
|
889
|
+
return false;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
// Check if it's a single skill or a directory of skills
|
|
893
|
+
const hasSkillMd = fs.existsSync(path.join(sourcePath, 'SKILL.md'));
|
|
894
|
+
|
|
895
|
+
if (dryRun) {
|
|
896
|
+
log(`\n${colors.bold}Dry Run${colors.reset} (no changes made)\n`);
|
|
897
|
+
info(`Would install from: ${sourcePath}`);
|
|
898
|
+
info(`Agent: ${agent}`);
|
|
899
|
+
return true;
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
if (hasSkillMd) {
|
|
903
|
+
// Single skill
|
|
904
|
+
const skillName = path.basename(sourcePath);
|
|
905
|
+
const destDir = AGENT_PATHS[agent] || AGENT_PATHS.claude;
|
|
906
|
+
const destPath = path.join(destDir, skillName);
|
|
907
|
+
|
|
908
|
+
if (!fs.existsSync(destDir)) {
|
|
909
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
copyDir(sourcePath, destPath);
|
|
913
|
+
success(`\nInstalled: ${skillName} from local path`);
|
|
914
|
+
info(`Location: ${destPath}`);
|
|
915
|
+
} else {
|
|
916
|
+
// Directory of skills
|
|
917
|
+
const entries = fs.readdirSync(sourcePath, { withFileTypes: true });
|
|
918
|
+
let installed = 0;
|
|
919
|
+
|
|
920
|
+
for (const entry of entries) {
|
|
921
|
+
if (entry.isDirectory()) {
|
|
922
|
+
const skillPath = path.join(sourcePath, entry.name);
|
|
923
|
+
if (fs.existsSync(path.join(skillPath, 'SKILL.md'))) {
|
|
924
|
+
const destDir = AGENT_PATHS[agent] || AGENT_PATHS.claude;
|
|
925
|
+
const destPath = path.join(destDir, entry.name);
|
|
926
|
+
|
|
927
|
+
if (!fs.existsSync(destDir)) {
|
|
928
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
copyDir(skillPath, destPath);
|
|
932
|
+
log(` ${colors.green}✓${colors.reset} ${entry.name}`);
|
|
933
|
+
installed++;
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
if (installed > 0) {
|
|
939
|
+
success(`\nInstalled ${installed} skill(s) from local path`);
|
|
940
|
+
} else {
|
|
941
|
+
warn('No skills found in directory');
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
return true;
|
|
946
|
+
}
|
|
947
|
+
|
|
662
948
|
// ============ INFO AND HELP ============
|
|
663
949
|
|
|
664
950
|
function showHelp() {
|
|
665
951
|
log(`
|
|
666
952
|
${colors.bold}AI Agent Skills${colors.reset}
|
|
667
|
-
|
|
953
|
+
Homebrew for AI agent skills. One command, every agent.
|
|
668
954
|
|
|
669
955
|
${colors.bold}Usage:${colors.reset}
|
|
670
956
|
npx ai-agent-skills <command> [options]
|
|
671
957
|
|
|
672
958
|
${colors.bold}Commands:${colors.reset}
|
|
959
|
+
${colors.green}browse${colors.reset} Interactive skill browser (TUI)
|
|
673
960
|
${colors.green}list${colors.reset} List all available skills
|
|
674
961
|
${colors.green}list --installed${colors.reset} List installed skills for an agent
|
|
675
962
|
${colors.green}list --category <cat>${colors.reset} Filter by category
|
|
676
|
-
${colors.green}install <name>${colors.reset} Install a skill
|
|
963
|
+
${colors.green}install <name>${colors.reset} Install a skill from catalog
|
|
964
|
+
${colors.green}install <owner/repo>${colors.reset} Install from GitHub repository
|
|
965
|
+
${colors.green}install ./path${colors.reset} Install from local path
|
|
677
966
|
${colors.green}install <name> --dry-run${colors.reset} Preview installation without changes
|
|
678
967
|
${colors.green}uninstall <name>${colors.reset} Remove an installed skill
|
|
679
968
|
${colors.green}update <name>${colors.reset} Update an installed skill to latest
|
|
@@ -706,11 +995,14 @@ ${colors.bold}Categories:${colors.reset}
|
|
|
706
995
|
development, document, creative, business, productivity
|
|
707
996
|
|
|
708
997
|
${colors.bold}Examples:${colors.reset}
|
|
709
|
-
npx ai-agent-skills
|
|
710
|
-
npx ai-agent-skills install
|
|
711
|
-
npx ai-agent-skills install
|
|
998
|
+
npx ai-agent-skills browse # Interactive browser
|
|
999
|
+
npx ai-agent-skills install frontend-design # Install from catalog
|
|
1000
|
+
npx ai-agent-skills install anthropics/skills # Install from GitHub
|
|
1001
|
+
npx ai-agent-skills install anthropics/skills/pdf # Install specific skill from GitHub
|
|
1002
|
+
npx ai-agent-skills install ./my-skill # Install from local path
|
|
1003
|
+
npx ai-agent-skills install pdf --agent cursor # Install for Cursor
|
|
1004
|
+
npx ai-agent-skills install pdf --dry-run # Preview install
|
|
712
1005
|
npx ai-agent-skills list --category development
|
|
713
|
-
npx ai-agent-skills list --installed --agent cursor
|
|
714
1006
|
npx ai-agent-skills search testing
|
|
715
1007
|
npx ai-agent-skills update --all
|
|
716
1008
|
|
|
@@ -826,6 +1118,11 @@ if (command === 'config') {
|
|
|
826
1118
|
}
|
|
827
1119
|
|
|
828
1120
|
switch (command || 'help') {
|
|
1121
|
+
case 'browse':
|
|
1122
|
+
case 'b':
|
|
1123
|
+
browseSkills(agent);
|
|
1124
|
+
break;
|
|
1125
|
+
|
|
829
1126
|
case 'list':
|
|
830
1127
|
case 'ls':
|
|
831
1128
|
if (installed) {
|
|
@@ -839,11 +1136,18 @@ switch (command || 'help') {
|
|
|
839
1136
|
case 'i':
|
|
840
1137
|
case 'add':
|
|
841
1138
|
if (!param) {
|
|
842
|
-
error('Please specify a skill name.');
|
|
843
|
-
log('Usage: npx ai-agent-skills install <skill-name> [--agent <agent>] [--dry-run]');
|
|
1139
|
+
error('Please specify a skill name, GitHub repo, or local path.');
|
|
1140
|
+
log('Usage: npx ai-agent-skills install <skill-name|owner/repo|./path> [--agent <agent>] [--dry-run]');
|
|
844
1141
|
process.exit(1);
|
|
845
1142
|
}
|
|
846
|
-
|
|
1143
|
+
// Smart detection: GitHub URL, local path, or catalog skill
|
|
1144
|
+
if (isLocalPath(param)) {
|
|
1145
|
+
installFromLocalPath(param, agent, dryRun);
|
|
1146
|
+
} else if (isGitHubUrl(param)) {
|
|
1147
|
+
installFromGitHub(param, agent, dryRun);
|
|
1148
|
+
} else {
|
|
1149
|
+
installSkill(param, agent, dryRun);
|
|
1150
|
+
}
|
|
847
1151
|
break;
|
|
848
1152
|
|
|
849
1153
|
case 'uninstall':
|
package/package.json
CHANGED
package/skills.json
CHANGED