skills 1.2.2 → 1.2.3
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 +21 -17
- package/dist/cli.d.mts +1 -4
- package/dist/cli.mjs +127 -177
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
The CLI for the open agent skills ecosystem.
|
|
4
4
|
|
|
5
5
|
<!-- agent-list:start -->
|
|
6
|
-
Supports **OpenCode**, **Claude Code**, **Codex**, **Cursor**, and [
|
|
6
|
+
Supports **OpenCode**, **Claude Code**, **Codex**, **Cursor**, and [32 more](#available-agents).
|
|
7
7
|
<!-- agent-list:end -->
|
|
8
8
|
|
|
9
9
|
## Install a Skill
|
|
@@ -39,8 +39,8 @@ npx skills add ./my-local-skills
|
|
|
39
39
|
| Option | Description |
|
|
40
40
|
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
41
41
|
| `-g, --global` | Install to user directory instead of project |
|
|
42
|
-
| `-a, --agent <agents...>` | <!-- agent-names:start -->Target specific agents (e.g., `claude-code`, `codex`).
|
|
43
|
-
| `-s, --skill <skills...>` | Install specific skills by name (
|
|
42
|
+
| `-a, --agent <agents...>` | <!-- agent-names:start -->Target specific agents (e.g., `claude-code`, `codex`). Use `'*'` for all agents<!-- agent-names:end --> |
|
|
43
|
+
| `-s, --skill <skills...>` | Install specific skills by name (use `'*'` for all skills) |
|
|
44
44
|
| `-l, --list` | List available skills without installing |
|
|
45
45
|
| `-y, --yes` | Skip all confirmation prompts |
|
|
46
46
|
| `--all` | Install all skills to all agents without prompts |
|
|
@@ -65,6 +65,12 @@ npx skills add vercel-labs/agent-skills --skill frontend-design -g -a claude-cod
|
|
|
65
65
|
|
|
66
66
|
# Install all skills from a repo to all agents
|
|
67
67
|
npx skills add vercel-labs/agent-skills --all
|
|
68
|
+
|
|
69
|
+
# Install all skills to specific agents
|
|
70
|
+
npx skills add vercel-labs/agent-skills --skill '*' -a claude-code
|
|
71
|
+
|
|
72
|
+
# Install specific skills to all agents
|
|
73
|
+
npx skills add vercel-labs/agent-skills --agent '*' --skill frontend-design
|
|
68
74
|
```
|
|
69
75
|
|
|
70
76
|
### Installation Scope
|
|
@@ -93,7 +99,6 @@ When installing interactively, you can choose:
|
|
|
93
99
|
| `npx skills check` | Check for available skill updates |
|
|
94
100
|
| `npx skills update` | Update all installed skills to latest versions |
|
|
95
101
|
| `npx skills init [name]` | Create a new SKILL.md template |
|
|
96
|
-
| `npx skills generate-lock` | Match installed skills to sources for update tracking |
|
|
97
102
|
|
|
98
103
|
### `skills list`
|
|
99
104
|
|
|
@@ -142,16 +147,6 @@ npx skills init
|
|
|
142
147
|
npx skills init my-skill
|
|
143
148
|
```
|
|
144
149
|
|
|
145
|
-
### `skills generate-lock`
|
|
146
|
-
|
|
147
|
-
```bash
|
|
148
|
-
# Match installed skills to sources for update tracking
|
|
149
|
-
npx skills generate-lock
|
|
150
|
-
|
|
151
|
-
# Preview without writing
|
|
152
|
-
npx skills generate-lock --dry-run
|
|
153
|
-
```
|
|
154
|
-
|
|
155
150
|
### `skills remove`
|
|
156
151
|
|
|
157
152
|
Remove installed skills from agents.
|
|
@@ -173,7 +168,13 @@ npx skills remove --global web-design-guidelines
|
|
|
173
168
|
npx skills remove --agent claude-code cursor my-skill
|
|
174
169
|
|
|
175
170
|
# Remove all installed skills without confirmation
|
|
176
|
-
npx skills remove --all
|
|
171
|
+
npx skills remove --all
|
|
172
|
+
|
|
173
|
+
# Remove all skills from a specific agent
|
|
174
|
+
npx skills remove --skill '*' -a cursor
|
|
175
|
+
|
|
176
|
+
# Remove a specific skill from all agents
|
|
177
|
+
npx skills remove my-skill --agent '*'
|
|
177
178
|
|
|
178
179
|
# Use 'rm' alias
|
|
179
180
|
npx skills rm my-skill
|
|
@@ -182,9 +183,10 @@ npx skills rm my-skill
|
|
|
182
183
|
| Option | Description |
|
|
183
184
|
| ------------------- | ---------------------------------------------------- |
|
|
184
185
|
| `-g, --global` | Remove from global scope (~/) instead of project |
|
|
185
|
-
| `-a, --agent` | Remove from specific agents
|
|
186
|
+
| `-a, --agent` | Remove from specific agents (use `'*'` for all) |
|
|
187
|
+
| `-s, --skill` | Specify skills to remove (use `'*'` for all) |
|
|
186
188
|
| `-y, --yes` | Skip confirmation prompts |
|
|
187
|
-
| `--all` |
|
|
189
|
+
| `--all` | Shorthand for `--skill '*' --agent '*' -y` |
|
|
188
190
|
|
|
189
191
|
## What are Agent Skills?
|
|
190
192
|
|
|
@@ -233,6 +235,7 @@ Skills can be installed to any of these agents:
|
|
|
233
235
|
| Pi | `pi` | `.pi/skills/` | `~/.pi/agent/skills/` |
|
|
234
236
|
| Qoder | `qoder` | `.qoder/skills/` | `~/.qoder/skills/` |
|
|
235
237
|
| Qwen Code | `qwen-code` | `.qwen/skills/` | `~/.qwen/skills/` |
|
|
238
|
+
| Replit | `replit` | `.agent/skills/` | N/A (project-only) |
|
|
236
239
|
| Roo Code | `roo` | `.roo/skills/` | `~/.roo/skills/` |
|
|
237
240
|
| Trae | `trae` | `.trae/skills/` | `~/.trae/skills/` |
|
|
238
241
|
| Trae CN | `trae-cn` | `.trae/skills/` | `~/.trae-cn/skills/` |
|
|
@@ -420,6 +423,7 @@ Telemetry is automatically disabled in CI environments.
|
|
|
420
423
|
- [OpenHands Skills Documentation](https://docs.openhands.ai/modules/usage/how-to/using-skills)
|
|
421
424
|
- [Pi Skills Documentation](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/docs/skills.md)
|
|
422
425
|
- [Qoder Skills Documentation](https://docs.qoder.com/cli/Skills)
|
|
426
|
+
- [Replit Skills Documentation](https://docs.replit.com/replitai/skills)
|
|
423
427
|
- [Roo Code Skills Documentation](https://docs.roocode.com/features/skills)
|
|
424
428
|
- [Trae Skills Documentation](https://docs.trae.ai/ide/skills)
|
|
425
429
|
- [Vercel Agent Skills Repository](https://github.com/vercel-labs/agent-skills)
|
package/dist/cli.d.mts
CHANGED
package/dist/cli.mjs
CHANGED
|
@@ -9,7 +9,7 @@ import { t as require_gray_matter } from "./_chunks/libs/gray-matter.mjs";
|
|
|
9
9
|
import "./_chunks/libs/extend-shallow.mjs";
|
|
10
10
|
import "./_chunks/libs/esprima.mjs";
|
|
11
11
|
import { spawn, spawnSync } from "child_process";
|
|
12
|
-
import { existsSync, mkdirSync, readFileSync,
|
|
12
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
13
13
|
import { basename, dirname, isAbsolute, join, normalize, relative, resolve, sep } from "path";
|
|
14
14
|
import { homedir, platform, tmpdir } from "os";
|
|
15
15
|
import "crypto";
|
|
@@ -266,7 +266,8 @@ async function discoverSkills(basePath, subpath, options) {
|
|
|
266
266
|
const skill = await parseSkillMd(join(searchPath, "SKILL.md"), options);
|
|
267
267
|
if (skill) {
|
|
268
268
|
skills.push(skill);
|
|
269
|
-
|
|
269
|
+
seenNames.add(skill.name);
|
|
270
|
+
if (!options?.fullDepth) return skills;
|
|
270
271
|
}
|
|
271
272
|
}
|
|
272
273
|
const prioritySearchDirs = [
|
|
@@ -360,6 +361,15 @@ const agents = {
|
|
|
360
361
|
return existsSync(join(process.cwd(), ".agent")) || existsSync(join(home, ".gemini/antigravity"));
|
|
361
362
|
}
|
|
362
363
|
},
|
|
364
|
+
augment: {
|
|
365
|
+
name: "augment",
|
|
366
|
+
displayName: "Augment",
|
|
367
|
+
skillsDir: ".augment/rules",
|
|
368
|
+
globalSkillsDir: join(home, ".augment/rules"),
|
|
369
|
+
detectInstalled: async () => {
|
|
370
|
+
return existsSync(join(home, ".augment"));
|
|
371
|
+
}
|
|
372
|
+
},
|
|
363
373
|
"claude-code": {
|
|
364
374
|
name: "claude-code",
|
|
365
375
|
displayName: "Claude Code",
|
|
@@ -531,6 +541,15 @@ const agents = {
|
|
|
531
541
|
return existsSync(join(home, ".mcpjam"));
|
|
532
542
|
}
|
|
533
543
|
},
|
|
544
|
+
"mistral-vibe": {
|
|
545
|
+
name: "mistral-vibe",
|
|
546
|
+
displayName: "Mistral Vibe",
|
|
547
|
+
skillsDir: ".vibe/skills",
|
|
548
|
+
globalSkillsDir: join(home, ".vibe/skills"),
|
|
549
|
+
detectInstalled: async () => {
|
|
550
|
+
return existsSync(join(home, ".vibe"));
|
|
551
|
+
}
|
|
552
|
+
},
|
|
534
553
|
mux: {
|
|
535
554
|
name: "mux",
|
|
536
555
|
displayName: "Mux",
|
|
@@ -594,6 +613,15 @@ const agents = {
|
|
|
594
613
|
return existsSync(join(home, ".qwen"));
|
|
595
614
|
}
|
|
596
615
|
},
|
|
616
|
+
replit: {
|
|
617
|
+
name: "replit",
|
|
618
|
+
displayName: "Replit",
|
|
619
|
+
skillsDir: ".agent/skills",
|
|
620
|
+
globalSkillsDir: void 0,
|
|
621
|
+
detectInstalled: async () => {
|
|
622
|
+
return existsSync(join(process.cwd(), ".agent"));
|
|
623
|
+
}
|
|
624
|
+
},
|
|
597
625
|
roo: {
|
|
598
626
|
name: "roo",
|
|
599
627
|
displayName: "Roo Code",
|
|
@@ -656,6 +684,15 @@ const agents = {
|
|
|
656
684
|
detectInstalled: async () => {
|
|
657
685
|
return existsSync(join(home, ".pochi"));
|
|
658
686
|
}
|
|
687
|
+
},
|
|
688
|
+
adal: {
|
|
689
|
+
name: "adal",
|
|
690
|
+
displayName: "AdaL",
|
|
691
|
+
skillsDir: ".adal/skills",
|
|
692
|
+
globalSkillsDir: join(home, ".adal/skills"),
|
|
693
|
+
detectInstalled: async () => {
|
|
694
|
+
return existsSync(join(home, ".adal"));
|
|
695
|
+
}
|
|
659
696
|
}
|
|
660
697
|
};
|
|
661
698
|
async function detectInstalledAgents() {
|
|
@@ -665,7 +702,7 @@ async function detectInstalledAgents() {
|
|
|
665
702
|
})))).filter((r) => r.installed).map((r) => r.type);
|
|
666
703
|
}
|
|
667
704
|
const AGENTS_DIR$2 = ".agents";
|
|
668
|
-
const SKILLS_SUBDIR
|
|
705
|
+
const SKILLS_SUBDIR = "skills";
|
|
669
706
|
function sanitizeName(name) {
|
|
670
707
|
return name.toLowerCase().replace(/[^a-z0-9._]+/g, "-").replace(/^[.\-]+|[.\-]+$/g, "").substring(0, 255) || "unnamed-skill";
|
|
671
708
|
}
|
|
@@ -675,7 +712,7 @@ function isPathSafe(basePath, targetPath) {
|
|
|
675
712
|
return normalizedTarget.startsWith(normalizedBase + sep) || normalizedTarget === normalizedBase;
|
|
676
713
|
}
|
|
677
714
|
function getCanonicalSkillsDir(global, cwd) {
|
|
678
|
-
return join(global ? homedir() : cwd || process.cwd(), AGENTS_DIR$2, SKILLS_SUBDIR
|
|
715
|
+
return join(global ? homedir() : cwd || process.cwd(), AGENTS_DIR$2, SKILLS_SUBDIR);
|
|
679
716
|
}
|
|
680
717
|
function resolveSymlinkTarget(linkPath, linkTarget) {
|
|
681
718
|
return resolve(dirname(linkPath), linkTarget);
|
|
@@ -715,6 +752,12 @@ async function installSkillForAgent(skill, agentType, options = {}) {
|
|
|
715
752
|
const agent = agents[agentType];
|
|
716
753
|
const isGlobal = options.global ?? false;
|
|
717
754
|
const cwd = options.cwd || process.cwd();
|
|
755
|
+
if (isGlobal && agent.globalSkillsDir === void 0) return {
|
|
756
|
+
success: false,
|
|
757
|
+
path: "",
|
|
758
|
+
mode: options.mode ?? "symlink",
|
|
759
|
+
error: `${agent.displayName} does not support global skill installation`
|
|
760
|
+
};
|
|
718
761
|
const skillName = sanitizeName(skill.name || basename(skill.path));
|
|
719
762
|
const canonicalBase = getCanonicalSkillsDir(isGlobal, cwd);
|
|
720
763
|
const canonicalDir = join(canonicalBase, skillName);
|
|
@@ -795,6 +838,7 @@ async function copyDirectory(src, dest) {
|
|
|
795
838
|
async function isSkillInstalled(skillName, agentType, options = {}) {
|
|
796
839
|
const agent = agents[agentType];
|
|
797
840
|
const sanitized = sanitizeName(skillName);
|
|
841
|
+
if (options.global && agent.globalSkillsDir === void 0) return false;
|
|
798
842
|
const targetBase = options.global ? agent.globalSkillsDir : join(options.cwd || process.cwd(), agent.skillsDir);
|
|
799
843
|
const skillDir = join(targetBase, sanitized);
|
|
800
844
|
if (!isPathSafe(targetBase, skillDir)) return false;
|
|
@@ -809,7 +853,7 @@ function getInstallPath(skillName, agentType, options = {}) {
|
|
|
809
853
|
const agent = agents[agentType];
|
|
810
854
|
const cwd = options.cwd || process.cwd();
|
|
811
855
|
const sanitized = sanitizeName(skillName);
|
|
812
|
-
const targetBase = options.global ? agent.globalSkillsDir : join(cwd, agent.skillsDir);
|
|
856
|
+
const targetBase = options.global && agent.globalSkillsDir !== void 0 ? agent.globalSkillsDir : join(cwd, agent.skillsDir);
|
|
813
857
|
const installPath = join(targetBase, sanitized);
|
|
814
858
|
if (!isPathSafe(targetBase, installPath)) throw new Error("Invalid skill name: potential path traversal detected");
|
|
815
859
|
return installPath;
|
|
@@ -826,6 +870,12 @@ async function installRemoteSkillForAgent(skill, agentType, options = {}) {
|
|
|
826
870
|
const isGlobal = options.global ?? false;
|
|
827
871
|
const cwd = options.cwd || process.cwd();
|
|
828
872
|
const installMode = options.mode ?? "symlink";
|
|
873
|
+
if (isGlobal && agent.globalSkillsDir === void 0) return {
|
|
874
|
+
success: false,
|
|
875
|
+
path: "",
|
|
876
|
+
mode: installMode,
|
|
877
|
+
error: `${agent.displayName} does not support global skill installation`
|
|
878
|
+
};
|
|
829
879
|
const skillName = sanitizeName(skill.installName);
|
|
830
880
|
const canonicalBase = getCanonicalSkillsDir(isGlobal, cwd);
|
|
831
881
|
const canonicalDir = join(canonicalBase, skillName);
|
|
@@ -886,6 +936,12 @@ async function installWellKnownSkillForAgent(skill, agentType, options = {}) {
|
|
|
886
936
|
const isGlobal = options.global ?? false;
|
|
887
937
|
const cwd = options.cwd || process.cwd();
|
|
888
938
|
const installMode = options.mode ?? "symlink";
|
|
939
|
+
if (isGlobal && agent.globalSkillsDir === void 0) return {
|
|
940
|
+
success: false,
|
|
941
|
+
path: "",
|
|
942
|
+
mode: installMode,
|
|
943
|
+
error: `${agent.displayName} does not support global skill installation`
|
|
944
|
+
};
|
|
889
945
|
const skillName = sanitizeName(skill.installName);
|
|
890
946
|
const canonicalBase = getCanonicalSkillsDir(isGlobal, cwd);
|
|
891
947
|
const canonicalDir = join(canonicalBase, skillName);
|
|
@@ -985,6 +1041,7 @@ async function listInstalledSkills(options = {}) {
|
|
|
985
1041
|
const agentsToCheck = options.agentFilter || Object.keys(agents);
|
|
986
1042
|
for (const agentType of agentsToCheck) {
|
|
987
1043
|
const agent = agents[agentType];
|
|
1044
|
+
if (scope.global && agent.globalSkillsDir === void 0) continue;
|
|
988
1045
|
const agentBase = scope.global ? agent.globalSkillsDir : join(cwd, agent.skillsDir);
|
|
989
1046
|
let found = false;
|
|
990
1047
|
const possibleNames = [
|
|
@@ -1382,7 +1439,7 @@ async function readSkillLock$1() {
|
|
|
1382
1439
|
return createEmptyLockFile();
|
|
1383
1440
|
}
|
|
1384
1441
|
}
|
|
1385
|
-
async function writeSkillLock
|
|
1442
|
+
async function writeSkillLock(lock) {
|
|
1386
1443
|
const lockPath = getSkillLockPath$1();
|
|
1387
1444
|
await mkdir(dirname(lockPath), { recursive: true });
|
|
1388
1445
|
await writeFile(lockPath, JSON.stringify(lock, null, 2), "utf-8");
|
|
@@ -1417,13 +1474,13 @@ async function addSkillToLock(skillName, entry) {
|
|
|
1417
1474
|
installedAt: existingEntry?.installedAt ?? now,
|
|
1418
1475
|
updatedAt: now
|
|
1419
1476
|
};
|
|
1420
|
-
await writeSkillLock
|
|
1477
|
+
await writeSkillLock(lock);
|
|
1421
1478
|
}
|
|
1422
1479
|
async function removeSkillFromLock(skillName) {
|
|
1423
1480
|
const lock = await readSkillLock$1();
|
|
1424
1481
|
if (!(skillName in lock.skills)) return false;
|
|
1425
1482
|
delete lock.skills[skillName];
|
|
1426
|
-
await writeSkillLock
|
|
1483
|
+
await writeSkillLock(lock);
|
|
1427
1484
|
return true;
|
|
1428
1485
|
}
|
|
1429
1486
|
async function getSkillFromLock(skillName) {
|
|
@@ -1443,7 +1500,7 @@ async function dismissPrompt(promptKey) {
|
|
|
1443
1500
|
const lock = await readSkillLock$1();
|
|
1444
1501
|
if (!lock.dismissed) lock.dismissed = {};
|
|
1445
1502
|
lock.dismissed[promptKey] = true;
|
|
1446
|
-
await writeSkillLock
|
|
1503
|
+
await writeSkillLock(lock);
|
|
1447
1504
|
}
|
|
1448
1505
|
async function getLastSelectedAgents() {
|
|
1449
1506
|
return (await readSkillLock$1()).lastSelectedAgents;
|
|
@@ -1451,9 +1508,9 @@ async function getLastSelectedAgents() {
|
|
|
1451
1508
|
async function saveSelectedAgents(agents) {
|
|
1452
1509
|
const lock = await readSkillLock$1();
|
|
1453
1510
|
lock.lastSelectedAgents = agents;
|
|
1454
|
-
await writeSkillLock
|
|
1511
|
+
await writeSkillLock(lock);
|
|
1455
1512
|
}
|
|
1456
|
-
var version$1 = "1.2.
|
|
1513
|
+
var version$1 = "1.2.3";
|
|
1457
1514
|
async function isSourcePrivate(source) {
|
|
1458
1515
|
const ownerRepo = parseOwnerRepo(source);
|
|
1459
1516
|
if (!ownerRepo) return false;
|
|
@@ -1583,7 +1640,10 @@ async function handleRemoteSkill(source, url, options, spinner) {
|
|
|
1583
1640
|
}
|
|
1584
1641
|
let targetAgents;
|
|
1585
1642
|
const validAgents = Object.keys(agents);
|
|
1586
|
-
if (options.agent
|
|
1643
|
+
if (options.agent?.includes("*")) {
|
|
1644
|
+
targetAgents = validAgents;
|
|
1645
|
+
M.info(`Installing to all ${targetAgents.length} agents`);
|
|
1646
|
+
} else if (options.agent && options.agent.length > 0) {
|
|
1587
1647
|
const invalidAgents = options.agent.filter((a) => !validAgents.includes(a));
|
|
1588
1648
|
if (invalidAgents.length > 0) {
|
|
1589
1649
|
M.error(`Invalid agents: ${invalidAgents.join(", ")}`);
|
|
@@ -1626,7 +1686,8 @@ async function handleRemoteSkill(source, url, options, spinner) {
|
|
|
1626
1686
|
}
|
|
1627
1687
|
}
|
|
1628
1688
|
let installGlobally = options.global ?? false;
|
|
1629
|
-
|
|
1689
|
+
const supportsGlobal = targetAgents.some((a) => agents[a].globalSkillsDir !== void 0);
|
|
1690
|
+
if (options.global === void 0 && !options.yes && supportsGlobal) {
|
|
1630
1691
|
const scope = await ve({
|
|
1631
1692
|
message: "Installation scope",
|
|
1632
1693
|
options: [{
|
|
@@ -1795,7 +1856,10 @@ async function handleWellKnownSkills(source, url, options, spinner) {
|
|
|
1795
1856
|
process.exit(0);
|
|
1796
1857
|
}
|
|
1797
1858
|
let selectedSkills;
|
|
1798
|
-
if (options.skill
|
|
1859
|
+
if (options.skill?.includes("*")) {
|
|
1860
|
+
selectedSkills = skills;
|
|
1861
|
+
M.info(`Installing all ${skills.length} skills`);
|
|
1862
|
+
} else if (options.skill && options.skill.length > 0) {
|
|
1799
1863
|
selectedSkills = skills.filter((s) => options.skill.some((name) => s.installName.toLowerCase() === name.toLowerCase() || s.name.toLowerCase() === name.toLowerCase()));
|
|
1800
1864
|
if (selectedSkills.length === 0) {
|
|
1801
1865
|
M.error(`No matching skills found for: ${options.skill.join(", ")}`);
|
|
@@ -1829,7 +1893,10 @@ async function handleWellKnownSkills(source, url, options, spinner) {
|
|
|
1829
1893
|
}
|
|
1830
1894
|
let targetAgents;
|
|
1831
1895
|
const validAgents = Object.keys(agents);
|
|
1832
|
-
if (options.agent
|
|
1896
|
+
if (options.agent?.includes("*")) {
|
|
1897
|
+
targetAgents = validAgents;
|
|
1898
|
+
M.info(`Installing to all ${targetAgents.length} agents`);
|
|
1899
|
+
} else if (options.agent && options.agent.length > 0) {
|
|
1833
1900
|
const invalidAgents = options.agent.filter((a) => !validAgents.includes(a));
|
|
1834
1901
|
if (invalidAgents.length > 0) {
|
|
1835
1902
|
M.error(`Invalid agents: ${invalidAgents.join(", ")}`);
|
|
@@ -1837,9 +1904,6 @@ async function handleWellKnownSkills(source, url, options, spinner) {
|
|
|
1837
1904
|
process.exit(1);
|
|
1838
1905
|
}
|
|
1839
1906
|
targetAgents = options.agent;
|
|
1840
|
-
} else if (options.all) {
|
|
1841
|
-
targetAgents = validAgents;
|
|
1842
|
-
M.info(`Installing to all ${targetAgents.length} agents`);
|
|
1843
1907
|
} else {
|
|
1844
1908
|
spinner.start("Detecting installed agents...");
|
|
1845
1909
|
const installedAgents = await detectInstalledAgents();
|
|
@@ -1875,7 +1939,8 @@ async function handleWellKnownSkills(source, url, options, spinner) {
|
|
|
1875
1939
|
}
|
|
1876
1940
|
}
|
|
1877
1941
|
let installGlobally = options.global ?? false;
|
|
1878
|
-
|
|
1942
|
+
const supportsGlobal = targetAgents.some((a) => agents[a].globalSkillsDir !== void 0);
|
|
1943
|
+
if (options.global === void 0 && !options.yes && supportsGlobal) {
|
|
1879
1944
|
const scope = await ve({
|
|
1880
1945
|
message: "Installation scope",
|
|
1881
1946
|
options: [{
|
|
@@ -2070,7 +2135,10 @@ async function handleDirectUrlSkillLegacy(source, url, options, spinner) {
|
|
|
2070
2135
|
}
|
|
2071
2136
|
let targetAgents;
|
|
2072
2137
|
const validAgents = Object.keys(agents);
|
|
2073
|
-
if (options.agent
|
|
2138
|
+
if (options.agent?.includes("*")) {
|
|
2139
|
+
targetAgents = validAgents;
|
|
2140
|
+
M.info(`Installing to all ${targetAgents.length} agents`);
|
|
2141
|
+
} else if (options.agent && options.agent.length > 0) {
|
|
2074
2142
|
const invalidAgents = options.agent.filter((a) => !validAgents.includes(a));
|
|
2075
2143
|
if (invalidAgents.length > 0) {
|
|
2076
2144
|
M.error(`Invalid agents: ${invalidAgents.join(", ")}`);
|
|
@@ -2113,7 +2181,8 @@ async function handleDirectUrlSkillLegacy(source, url, options, spinner) {
|
|
|
2113
2181
|
}
|
|
2114
2182
|
}
|
|
2115
2183
|
let installGlobally = options.global ?? false;
|
|
2116
|
-
|
|
2184
|
+
const supportsGlobal = targetAgents.some((a) => agents[a].globalSkillsDir !== void 0);
|
|
2185
|
+
if (options.global === void 0 && !options.yes && supportsGlobal) {
|
|
2117
2186
|
const scope = await ve({
|
|
2118
2187
|
message: "Installation scope",
|
|
2119
2188
|
options: [{
|
|
@@ -2238,7 +2307,11 @@ async function runAdd(args, options = {}) {
|
|
|
2238
2307
|
console.log();
|
|
2239
2308
|
process.exit(1);
|
|
2240
2309
|
}
|
|
2241
|
-
if (options.all)
|
|
2310
|
+
if (options.all) {
|
|
2311
|
+
options.skill = ["*"];
|
|
2312
|
+
options.agent = ["*"];
|
|
2313
|
+
options.yes = true;
|
|
2314
|
+
}
|
|
2242
2315
|
console.log();
|
|
2243
2316
|
Ie(import_picocolors.default.bgCyan(import_picocolors.default.black(" skills ")));
|
|
2244
2317
|
if (!process.stdin.isTTY) showInstallTip();
|
|
@@ -2278,7 +2351,10 @@ async function runAdd(args, options = {}) {
|
|
|
2278
2351
|
}
|
|
2279
2352
|
const includeInternal = !!(options.skill && options.skill.length > 0);
|
|
2280
2353
|
spinner.start("Discovering skills...");
|
|
2281
|
-
const skills = await discoverSkills(skillsDir, parsed.subpath, {
|
|
2354
|
+
const skills = await discoverSkills(skillsDir, parsed.subpath, {
|
|
2355
|
+
includeInternal,
|
|
2356
|
+
fullDepth: options.fullDepth
|
|
2357
|
+
});
|
|
2282
2358
|
if (skills.length === 0) {
|
|
2283
2359
|
spinner.stop(import_picocolors.default.red("No skills found"));
|
|
2284
2360
|
Se(import_picocolors.default.red("No valid skills found. Skills require a SKILL.md with name and description."));
|
|
@@ -2299,7 +2375,10 @@ async function runAdd(args, options = {}) {
|
|
|
2299
2375
|
process.exit(0);
|
|
2300
2376
|
}
|
|
2301
2377
|
let selectedSkills;
|
|
2302
|
-
if (options.skill
|
|
2378
|
+
if (options.skill?.includes("*")) {
|
|
2379
|
+
selectedSkills = skills;
|
|
2380
|
+
M.info(`Installing all ${skills.length} skills`);
|
|
2381
|
+
} else if (options.skill && options.skill.length > 0) {
|
|
2303
2382
|
selectedSkills = filterSkills(skills, options.skill);
|
|
2304
2383
|
if (selectedSkills.length === 0) {
|
|
2305
2384
|
M.error(`No matching skills found for: ${options.skill.join(", ")}`);
|
|
@@ -2336,7 +2415,10 @@ async function runAdd(args, options = {}) {
|
|
|
2336
2415
|
}
|
|
2337
2416
|
let targetAgents;
|
|
2338
2417
|
const validAgents = Object.keys(agents);
|
|
2339
|
-
if (options.agent
|
|
2418
|
+
if (options.agent?.includes("*")) {
|
|
2419
|
+
targetAgents = validAgents;
|
|
2420
|
+
M.info(`Installing to all ${targetAgents.length} agents`);
|
|
2421
|
+
} else if (options.agent && options.agent.length > 0) {
|
|
2340
2422
|
const invalidAgents = options.agent.filter((a) => !validAgents.includes(a));
|
|
2341
2423
|
if (invalidAgents.length > 0) {
|
|
2342
2424
|
M.error(`Invalid agents: ${invalidAgents.join(", ")}`);
|
|
@@ -2345,9 +2427,6 @@ async function runAdd(args, options = {}) {
|
|
|
2345
2427
|
process.exit(1);
|
|
2346
2428
|
}
|
|
2347
2429
|
targetAgents = options.agent;
|
|
2348
|
-
} else if (options.all) {
|
|
2349
|
-
targetAgents = validAgents;
|
|
2350
|
-
M.info(`Installing to all ${targetAgents.length} agents`);
|
|
2351
2430
|
} else {
|
|
2352
2431
|
spinner.start("Detecting installed agents...");
|
|
2353
2432
|
const installedAgents = await detectInstalledAgents();
|
|
@@ -2385,7 +2464,8 @@ async function runAdd(args, options = {}) {
|
|
|
2385
2464
|
}
|
|
2386
2465
|
}
|
|
2387
2466
|
let installGlobally = options.global ?? false;
|
|
2388
|
-
|
|
2467
|
+
const supportsGlobal = targetAgents.some((a) => agents[a].globalSkillsDir !== void 0);
|
|
2468
|
+
if (options.global === void 0 && !options.yes && supportsGlobal) {
|
|
2389
2469
|
const scope = await ve({
|
|
2390
2470
|
message: "Installation scope",
|
|
2391
2471
|
options: [{
|
|
@@ -2659,7 +2739,8 @@ function parseAddOptions(args) {
|
|
|
2659
2739
|
nextArg = args[i];
|
|
2660
2740
|
}
|
|
2661
2741
|
i--;
|
|
2662
|
-
} else if (arg
|
|
2742
|
+
} else if (arg === "--full-depth") options.fullDepth = true;
|
|
2743
|
+
else if (arg && !arg.startsWith("-")) source.push(arg);
|
|
2663
2744
|
}
|
|
2664
2745
|
return {
|
|
2665
2746
|
source,
|
|
@@ -2961,7 +3042,7 @@ async function removeCommand(skillNames, options) {
|
|
|
2961
3042
|
};
|
|
2962
3043
|
if (isGlobal) {
|
|
2963
3044
|
await scanDir(getCanonicalSkillsDir(true, cwd));
|
|
2964
|
-
for (const agent of Object.values(agents)) await scanDir(agent.globalSkillsDir);
|
|
3045
|
+
for (const agent of Object.values(agents)) if (agent.globalSkillsDir !== void 0) await scanDir(agent.globalSkillsDir);
|
|
2965
3046
|
} else {
|
|
2966
3047
|
await scanDir(getCanonicalSkillsDir(false, cwd));
|
|
2967
3048
|
for (const agent of Object.values(agents)) await scanDir(join(cwd, agent.skillsDir));
|
|
@@ -3120,12 +3201,6 @@ function parseRemoveOptions(args) {
|
|
|
3120
3201
|
options
|
|
3121
3202
|
};
|
|
3122
3203
|
}
|
|
3123
|
-
function formatSkippedMessage(skippedSkills) {
|
|
3124
|
-
if (skippedSkills.length === 0) return null;
|
|
3125
|
-
const lines = [`Skipped ${skippedSkills.length} (reinstall needed):`];
|
|
3126
|
-
for (const skill of skippedSkills) lines.push(` - ${skill}`);
|
|
3127
|
-
return lines.join("\n");
|
|
3128
|
-
}
|
|
3129
3204
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
3130
3205
|
function getVersion() {
|
|
3131
3206
|
try {
|
|
@@ -3195,21 +3270,22 @@ ${BOLD}Commands:${RESET}
|
|
|
3195
3270
|
init [name] Initialize a skill (creates <name>/SKILL.md or ./SKILL.md)
|
|
3196
3271
|
check Check for available skill updates
|
|
3197
3272
|
update Update all skills to latest versions
|
|
3198
|
-
generate-lock Generate lock file from installed skills
|
|
3199
3273
|
|
|
3200
3274
|
${BOLD}Add Options:${RESET}
|
|
3201
3275
|
-g, --global Install skill globally (user-level) instead of project-level
|
|
3202
|
-
-a, --agent <agents> Specify agents to install to
|
|
3203
|
-
-s, --skill <skills> Specify skill names to install (
|
|
3276
|
+
-a, --agent <agents> Specify agents to install to (use '*' for all agents)
|
|
3277
|
+
-s, --skill <skills> Specify skill names to install (use '*' for all skills)
|
|
3204
3278
|
-l, --list List available skills in the repository without installing
|
|
3205
3279
|
-y, --yes Skip confirmation prompts
|
|
3206
|
-
--all
|
|
3280
|
+
--all Shorthand for --skill '*' --agent '*' -y
|
|
3281
|
+
--full-depth Search all subdirectories even when a root SKILL.md exists
|
|
3207
3282
|
|
|
3208
3283
|
${BOLD}Remove Options:${RESET}
|
|
3209
3284
|
-g, --global Remove from global scope
|
|
3210
|
-
-a, --agent <agents> Remove from specific agents
|
|
3285
|
+
-a, --agent <agents> Remove from specific agents (use '*' for all agents)
|
|
3286
|
+
-s, --skill <skills> Specify skills to remove (use '*' for all skills)
|
|
3211
3287
|
-y, --yes Skip confirmation prompts
|
|
3212
|
-
--all
|
|
3288
|
+
--all Shorthand for --skill '*' --agent '*' -y
|
|
3213
3289
|
|
|
3214
3290
|
${BOLD}List Options:${RESET}
|
|
3215
3291
|
-g, --global List global skills (default: project)
|
|
@@ -3218,7 +3294,6 @@ ${BOLD}List Options:${RESET}
|
|
|
3218
3294
|
${BOLD}Options:${RESET}
|
|
3219
3295
|
--help, -h Show this help message
|
|
3220
3296
|
--version, -v Show version number
|
|
3221
|
-
--dry-run Preview changes without writing (generate-lock)
|
|
3222
3297
|
|
|
3223
3298
|
${BOLD}Examples:${RESET}
|
|
3224
3299
|
${DIM}$${RESET} skills add vercel-labs/agent-skills
|
|
@@ -3253,9 +3328,10 @@ ${BOLD}Arguments:${RESET}
|
|
|
3253
3328
|
|
|
3254
3329
|
${BOLD}Options:${RESET}
|
|
3255
3330
|
-g, --global Remove from global scope (~/) instead of project scope
|
|
3256
|
-
-a, --agent Remove from specific agents
|
|
3331
|
+
-a, --agent Remove from specific agents (use '*' for all agents)
|
|
3332
|
+
-s, --skill Specify skills to remove (use '*' for all skills)
|
|
3257
3333
|
-y, --yes Skip confirmation prompts
|
|
3258
|
-
--all
|
|
3334
|
+
--all Shorthand for --skill '*' --agent '*' -y
|
|
3259
3335
|
|
|
3260
3336
|
${BOLD}Examples:${RESET}
|
|
3261
3337
|
${DIM}$${RESET} skills remove ${DIM}# interactive selection${RESET}
|
|
@@ -3263,7 +3339,8 @@ ${BOLD}Examples:${RESET}
|
|
|
3263
3339
|
${DIM}$${RESET} skills remove skill1 skill2 -y ${DIM}# remove multiple skills${RESET}
|
|
3264
3340
|
${DIM}$${RESET} skills remove --global my-skill ${DIM}# remove from global scope${RESET}
|
|
3265
3341
|
${DIM}$${RESET} skills rm --agent claude-code my-skill ${DIM}# remove from specific agent${RESET}
|
|
3266
|
-
${DIM}$${RESET} skills remove --all
|
|
3342
|
+
${DIM}$${RESET} skills remove --all ${DIM}# remove all skills${RESET}
|
|
3343
|
+
${DIM}$${RESET} skills remove --skill '*' -a cursor ${DIM}# remove all skills from cursor${RESET}
|
|
3267
3344
|
|
|
3268
3345
|
Discover more skills at ${TEXT}https://skills.sh/${RESET}
|
|
3269
3346
|
`);
|
|
@@ -3316,9 +3393,7 @@ Describe when this skill should be used.
|
|
|
3316
3393
|
console.log();
|
|
3317
3394
|
}
|
|
3318
3395
|
const AGENTS_DIR = ".agents";
|
|
3319
|
-
const SKILLS_SUBDIR = "skills";
|
|
3320
3396
|
const LOCK_FILE = ".skill-lock.json";
|
|
3321
|
-
const SEARCH_API_URL = "https://skills.sh/api/skills/search";
|
|
3322
3397
|
const CHECK_UPDATES_API_URL = "https://add-skill.vercel.sh/check-updates";
|
|
3323
3398
|
const CURRENT_LOCK_VERSION = 3;
|
|
3324
3399
|
function getSkillLockPath() {
|
|
@@ -3345,115 +3420,6 @@ function readSkillLock() {
|
|
|
3345
3420
|
};
|
|
3346
3421
|
}
|
|
3347
3422
|
}
|
|
3348
|
-
function writeSkillLock(lock) {
|
|
3349
|
-
const lockPath = getSkillLockPath();
|
|
3350
|
-
const dir = join(homedir(), AGENTS_DIR);
|
|
3351
|
-
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
3352
|
-
writeFileSync(lockPath, JSON.stringify(lock, null, 2), "utf-8");
|
|
3353
|
-
}
|
|
3354
|
-
function getInstalledSkillNames() {
|
|
3355
|
-
const skillsDir = join(homedir(), AGENTS_DIR, SKILLS_SUBDIR);
|
|
3356
|
-
const skillNames = [];
|
|
3357
|
-
try {
|
|
3358
|
-
const entries = readdirSync(skillsDir, { withFileTypes: true });
|
|
3359
|
-
for (const entry of entries) if (entry.isDirectory() || entry.isSymbolicLink()) {
|
|
3360
|
-
const skillMdPath = join(skillsDir, entry.name, "SKILL.md");
|
|
3361
|
-
try {
|
|
3362
|
-
if (statSync(skillMdPath).isFile()) skillNames.push(entry.name);
|
|
3363
|
-
} catch {
|
|
3364
|
-
try {
|
|
3365
|
-
if (readdirSync(join(skillsDir, entry.name)).length > 0) skillNames.push(entry.name);
|
|
3366
|
-
} catch {}
|
|
3367
|
-
}
|
|
3368
|
-
}
|
|
3369
|
-
} catch {}
|
|
3370
|
-
return skillNames;
|
|
3371
|
-
}
|
|
3372
|
-
async function fuzzyMatchSkills(skillNames, apiUrl = SEARCH_API_URL) {
|
|
3373
|
-
if (skillNames.length === 0) return {};
|
|
3374
|
-
const response = await fetch(apiUrl, {
|
|
3375
|
-
method: "POST",
|
|
3376
|
-
headers: { "Content-Type": "application/json" },
|
|
3377
|
-
body: JSON.stringify({ skills: skillNames })
|
|
3378
|
-
});
|
|
3379
|
-
if (!response.ok) throw new Error(`API request failed: ${response.status} ${response.statusText}`);
|
|
3380
|
-
return (await response.json()).matches;
|
|
3381
|
-
}
|
|
3382
|
-
function inferSourceType(source) {
|
|
3383
|
-
if (source.startsWith("mintlify/")) return "mintlify";
|
|
3384
|
-
if (source.startsWith("huggingface/")) return "huggingface";
|
|
3385
|
-
return "github";
|
|
3386
|
-
}
|
|
3387
|
-
function buildSourceUrl(source, sourceType) {
|
|
3388
|
-
switch (sourceType) {
|
|
3389
|
-
case "github": return `https://github.com/${source}.git`;
|
|
3390
|
-
case "mintlify": return source;
|
|
3391
|
-
case "huggingface": return `https://huggingface.co/spaces/${source.replace("huggingface/", "").split("/").join("/")}`;
|
|
3392
|
-
default: return source;
|
|
3393
|
-
}
|
|
3394
|
-
}
|
|
3395
|
-
async function runGenerateLock(args) {
|
|
3396
|
-
const dryRun = args.includes("--dry-run");
|
|
3397
|
-
const apiUrlIdx = args.indexOf("--api-url");
|
|
3398
|
-
const apiUrl = apiUrlIdx !== -1 && args[apiUrlIdx + 1] ? args[apiUrlIdx + 1] : SEARCH_API_URL;
|
|
3399
|
-
console.log(`${TEXT}Scanning for installed skills...${RESET}`);
|
|
3400
|
-
const installedSkills = getInstalledSkillNames();
|
|
3401
|
-
if (installedSkills.length === 0) {
|
|
3402
|
-
console.log(`${DIM}No installed skills found.${RESET}`);
|
|
3403
|
-
return;
|
|
3404
|
-
}
|
|
3405
|
-
console.log(`${DIM}Found ${installedSkills.length} installed skill(s)${RESET}`);
|
|
3406
|
-
console.log();
|
|
3407
|
-
const existingLock = readSkillLock();
|
|
3408
|
-
Object.keys(existingLock.skills).length;
|
|
3409
|
-
const skillsToMatch = installedSkills.filter((skill) => !(skill in existingLock.skills));
|
|
3410
|
-
if (skillsToMatch.length === 0) {
|
|
3411
|
-
console.log(`${TEXT}All skills already in lock file.${RESET}`);
|
|
3412
|
-
return;
|
|
3413
|
-
}
|
|
3414
|
-
console.log(`${TEXT}Matching ${skillsToMatch.length} skill(s) against database...${RESET}`);
|
|
3415
|
-
console.log();
|
|
3416
|
-
const matches = await fuzzyMatchSkills(skillsToMatch, apiUrl);
|
|
3417
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3418
|
-
const updatedLock = { ...existingLock };
|
|
3419
|
-
let matchedCount = 0;
|
|
3420
|
-
let skippedCount = 0;
|
|
3421
|
-
const EXACT_MATCH_THRESHOLD = 1e3;
|
|
3422
|
-
for (const skillName of skillsToMatch) {
|
|
3423
|
-
const match = matches[skillName];
|
|
3424
|
-
if (match && match.score >= EXACT_MATCH_THRESHOLD) {
|
|
3425
|
-
matchedCount++;
|
|
3426
|
-
const sourceType = inferSourceType(match.source);
|
|
3427
|
-
const sourceUrl = match.sourceUrl || buildSourceUrl(match.source, sourceType);
|
|
3428
|
-
console.log(`${TEXT}✓${RESET} ${skillName}`);
|
|
3429
|
-
console.log(` ${DIM}source: ${match.source}${RESET}`);
|
|
3430
|
-
updatedLock.skills[skillName] = {
|
|
3431
|
-
source: match.source,
|
|
3432
|
-
sourceType,
|
|
3433
|
-
sourceUrl,
|
|
3434
|
-
skillFolderHash: "",
|
|
3435
|
-
installedAt: now,
|
|
3436
|
-
updatedAt: now
|
|
3437
|
-
};
|
|
3438
|
-
} else skippedCount++;
|
|
3439
|
-
}
|
|
3440
|
-
console.log();
|
|
3441
|
-
console.log(`${TEXT}Matched:${RESET} ${matchedCount}`);
|
|
3442
|
-
console.log(`${DIM}Skipped: ${skippedCount} (no exact match)${RESET}`);
|
|
3443
|
-
console.log();
|
|
3444
|
-
if (matchedCount === 0) {
|
|
3445
|
-
console.log(`${DIM}No new skills to add to lock file.${RESET}`);
|
|
3446
|
-
return;
|
|
3447
|
-
}
|
|
3448
|
-
if (dryRun) {
|
|
3449
|
-
console.log(`${DIM}Dry run - no changes written${RESET}`);
|
|
3450
|
-
console.log();
|
|
3451
|
-
console.log(JSON.stringify(updatedLock, null, 2));
|
|
3452
|
-
} else {
|
|
3453
|
-
writeSkillLock(updatedLock);
|
|
3454
|
-
console.log(`${TEXT}Lock file updated:${RESET} ${DIM}~/.agents/.skill-lock.json${RESET}`);
|
|
3455
|
-
}
|
|
3456
|
-
}
|
|
3457
3423
|
async function runCheck(args = []) {
|
|
3458
3424
|
console.log(`${TEXT}Checking for skill updates...${RESET}`);
|
|
3459
3425
|
console.log();
|
|
@@ -3465,14 +3431,10 @@ async function runCheck(args = []) {
|
|
|
3465
3431
|
return;
|
|
3466
3432
|
}
|
|
3467
3433
|
const checkRequest = { skills: [] };
|
|
3468
|
-
const skippedSkills = [];
|
|
3469
3434
|
for (const skillName of skillNames) {
|
|
3470
3435
|
const entry = lock.skills[skillName];
|
|
3471
3436
|
if (!entry) continue;
|
|
3472
|
-
if (!entry.skillFolderHash)
|
|
3473
|
-
skippedSkills.push(skillName);
|
|
3474
|
-
continue;
|
|
3475
|
-
}
|
|
3437
|
+
if (!entry.skillFolderHash) continue;
|
|
3476
3438
|
checkRequest.skills.push({
|
|
3477
3439
|
name: skillName,
|
|
3478
3440
|
source: entry.source,
|
|
@@ -3480,8 +3442,6 @@ async function runCheck(args = []) {
|
|
|
3480
3442
|
skillFolderHash: entry.skillFolderHash
|
|
3481
3443
|
});
|
|
3482
3444
|
}
|
|
3483
|
-
const skippedMsg = formatSkippedMessage(skippedSkills);
|
|
3484
|
-
if (skippedMsg) console.log(`${DIM}${skippedMsg}${RESET}`);
|
|
3485
3445
|
if (checkRequest.skills.length === 0) {
|
|
3486
3446
|
console.log(`${DIM}No skills to check.${RESET}`);
|
|
3487
3447
|
return;
|
|
@@ -3533,14 +3493,10 @@ async function runUpdate() {
|
|
|
3533
3493
|
return;
|
|
3534
3494
|
}
|
|
3535
3495
|
const checkRequest = { skills: [] };
|
|
3536
|
-
const skippedSkills = [];
|
|
3537
3496
|
for (const skillName of skillNames) {
|
|
3538
3497
|
const entry = lock.skills[skillName];
|
|
3539
3498
|
if (!entry) continue;
|
|
3540
|
-
if (!entry.skillFolderHash)
|
|
3541
|
-
skippedSkills.push(skillName);
|
|
3542
|
-
continue;
|
|
3543
|
-
}
|
|
3499
|
+
if (!entry.skillFolderHash) continue;
|
|
3544
3500
|
checkRequest.skills.push({
|
|
3545
3501
|
name: skillName,
|
|
3546
3502
|
source: entry.source,
|
|
@@ -3548,8 +3504,6 @@ async function runUpdate() {
|
|
|
3548
3504
|
skillFolderHash: entry.skillFolderHash
|
|
3549
3505
|
});
|
|
3550
3506
|
}
|
|
3551
|
-
const skippedMsg = formatSkippedMessage(skippedSkills);
|
|
3552
|
-
if (skippedMsg) console.log(`${DIM}${skippedMsg}${RESET}`);
|
|
3553
3507
|
if (checkRequest.skills.length === 0) {
|
|
3554
3508
|
console.log(`${DIM}No skills to check.${RESET}`);
|
|
3555
3509
|
return;
|
|
@@ -3663,10 +3617,6 @@ async function main() {
|
|
|
3663
3617
|
case "upgrade":
|
|
3664
3618
|
runUpdate();
|
|
3665
3619
|
break;
|
|
3666
|
-
case "generate-lock":
|
|
3667
|
-
case "gen-lock":
|
|
3668
|
-
runGenerateLock(restArgs);
|
|
3669
|
-
break;
|
|
3670
3620
|
case "--help":
|
|
3671
3621
|
case "-h":
|
|
3672
3622
|
showHelp();
|
|
@@ -3681,4 +3631,4 @@ async function main() {
|
|
|
3681
3631
|
}
|
|
3682
3632
|
}
|
|
3683
3633
|
main();
|
|
3684
|
-
export {
|
|
3634
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skills",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.3",
|
|
4
4
|
"description": "The open agent skills ecosystem",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
"pi",
|
|
63
63
|
"qoder",
|
|
64
64
|
"qwen-code",
|
|
65
|
+
"replit",
|
|
65
66
|
"roo",
|
|
66
67
|
"trae",
|
|
67
68
|
"trae-cn",
|