skills 1.4.4 → 1.4.5
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 +2 -2
- package/dist/cli.mjs +56 -14
- 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 [38 more](#available-agents).
|
|
7
7
|
<!-- agent-list:end -->
|
|
8
8
|
|
|
9
9
|
## Install a Skill
|
|
@@ -214,7 +214,7 @@ Skills can be installed to any of these agents:
|
|
|
214
214
|
| Augment | `augment` | `.augment/skills/` | `~/.augment/skills/` |
|
|
215
215
|
| Claude Code | `claude-code` | `.claude/skills/` | `~/.claude/skills/` |
|
|
216
216
|
| OpenClaw | `openclaw` | `skills/` | `~/.openclaw/skills/` |
|
|
217
|
-
| Cline | `cline` | `.agents/skills/` | `~/.agents/skills/` |
|
|
217
|
+
| Cline, Warp | `cline`, `warp` | `.agents/skills/` | `~/.agents/skills/` |
|
|
218
218
|
| CodeBuddy | `codebuddy` | `.codebuddy/skills/` | `~/.codebuddy/skills/` |
|
|
219
219
|
| Codex | `codex` | `.agents/skills/` | `~/.codex/skills/` |
|
|
220
220
|
| Command Code | `command-code` | `.commandcode/skills/` | `~/.commandcode/skills/` |
|
package/dist/cli.mjs
CHANGED
|
@@ -924,6 +924,15 @@ const agents = {
|
|
|
924
924
|
return existsSync(join(home, ".trae-cn"));
|
|
925
925
|
}
|
|
926
926
|
},
|
|
927
|
+
warp: {
|
|
928
|
+
name: "warp",
|
|
929
|
+
displayName: "Warp",
|
|
930
|
+
skillsDir: ".agents/skills",
|
|
931
|
+
globalSkillsDir: join(home, ".agents/skills"),
|
|
932
|
+
detectInstalled: async () => {
|
|
933
|
+
return existsSync(join(home, ".warp"));
|
|
934
|
+
}
|
|
935
|
+
},
|
|
927
936
|
windsurf: {
|
|
928
937
|
name: "windsurf",
|
|
929
938
|
displayName: "Windsurf",
|
|
@@ -1136,10 +1145,14 @@ async function installSkillForAgent(skill, agentType, options = {}) {
|
|
|
1136
1145
|
}
|
|
1137
1146
|
}
|
|
1138
1147
|
const EXCLUDE_FILES = new Set(["metadata.json"]);
|
|
1139
|
-
const EXCLUDE_DIRS = new Set([
|
|
1148
|
+
const EXCLUDE_DIRS = new Set([
|
|
1149
|
+
".git",
|
|
1150
|
+
"__pycache__",
|
|
1151
|
+
"__pypackages__"
|
|
1152
|
+
]);
|
|
1140
1153
|
const isExcluded = (name, isDirectory = false) => {
|
|
1141
1154
|
if (EXCLUDE_FILES.has(name)) return true;
|
|
1142
|
-
if (name.startsWith("
|
|
1155
|
+
if (name.startsWith(".")) return true;
|
|
1143
1156
|
if (isDirectory && EXCLUDE_DIRS.has(name)) return true;
|
|
1144
1157
|
return false;
|
|
1145
1158
|
};
|
|
@@ -1150,10 +1163,15 @@ async function copyDirectory(src, dest) {
|
|
|
1150
1163
|
const srcPath = join(src, entry.name);
|
|
1151
1164
|
const destPath = join(dest, entry.name);
|
|
1152
1165
|
if (entry.isDirectory()) await copyDirectory(srcPath, destPath);
|
|
1153
|
-
else
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1166
|
+
else try {
|
|
1167
|
+
await cp(srcPath, destPath, {
|
|
1168
|
+
dereference: true,
|
|
1169
|
+
recursive: true
|
|
1170
|
+
});
|
|
1171
|
+
} catch (err) {
|
|
1172
|
+
if (err instanceof Error && "code" in err && err.code === "ENOENT" && entry.isSymbolicLink()) console.warn(`Skipping broken symlink: ${srcPath}`);
|
|
1173
|
+
else throw err;
|
|
1174
|
+
}
|
|
1157
1175
|
}));
|
|
1158
1176
|
}
|
|
1159
1177
|
async function isSkillInstalled(skillName, agentType, options = {}) {
|
|
@@ -1601,6 +1619,8 @@ const AGENTS_DIR$1 = ".agents";
|
|
|
1601
1619
|
const LOCK_FILE$1 = ".skill-lock.json";
|
|
1602
1620
|
const CURRENT_VERSION$1 = 3;
|
|
1603
1621
|
function getSkillLockPath$1() {
|
|
1622
|
+
const xdgStateHome = process.env.XDG_STATE_HOME;
|
|
1623
|
+
if (xdgStateHome) return join(xdgStateHome, "skills", LOCK_FILE$1);
|
|
1604
1624
|
return join(homedir(), AGENTS_DIR$1, LOCK_FILE$1);
|
|
1605
1625
|
}
|
|
1606
1626
|
async function readSkillLock$1() {
|
|
@@ -1773,7 +1793,7 @@ function createEmptyLocalLock() {
|
|
|
1773
1793
|
skills: {}
|
|
1774
1794
|
};
|
|
1775
1795
|
}
|
|
1776
|
-
var version$1 = "1.4.
|
|
1796
|
+
var version$1 = "1.4.5";
|
|
1777
1797
|
const isCancelled$1 = (value) => typeof value === "symbol";
|
|
1778
1798
|
async function isSourcePrivate(source) {
|
|
1779
1799
|
const ownerRepo = parseOwnerRepo(source);
|
|
@@ -2070,7 +2090,8 @@ async function handleWellKnownSkills(source, url, options, spinner) {
|
|
|
2070
2090
|
installGlobally = scope;
|
|
2071
2091
|
}
|
|
2072
2092
|
let installMode = options.copy ? "copy" : "symlink";
|
|
2073
|
-
|
|
2093
|
+
const uniqueDirs = new Set(targetAgents.map((a) => agents[a].skillsDir));
|
|
2094
|
+
if (!options.copy && !options.yes && uniqueDirs.size > 1) {
|
|
2074
2095
|
const modeChoice = await ve({
|
|
2075
2096
|
message: "Installation method",
|
|
2076
2097
|
options: [{
|
|
@@ -2088,7 +2109,7 @@ async function handleWellKnownSkills(source, url, options, spinner) {
|
|
|
2088
2109
|
process.exit(0);
|
|
2089
2110
|
}
|
|
2090
2111
|
installMode = modeChoice;
|
|
2091
|
-
}
|
|
2112
|
+
} else if (uniqueDirs.size <= 1) installMode = "copy";
|
|
2092
2113
|
const cwd = process.cwd();
|
|
2093
2114
|
const summaryLines = [];
|
|
2094
2115
|
targetAgents.map((a) => agents[a].displayName);
|
|
@@ -2462,7 +2483,8 @@ async function runAdd(args, options = {}) {
|
|
|
2462
2483
|
installGlobally = scope;
|
|
2463
2484
|
}
|
|
2464
2485
|
let installMode = options.copy ? "copy" : "symlink";
|
|
2465
|
-
|
|
2486
|
+
const uniqueDirs = new Set(targetAgents.map((a) => agents[a].skillsDir));
|
|
2487
|
+
if (!options.copy && !options.yes && uniqueDirs.size > 1) {
|
|
2466
2488
|
const modeChoice = await ve({
|
|
2467
2489
|
message: "Installation method",
|
|
2468
2490
|
options: [{
|
|
@@ -2481,7 +2503,7 @@ async function runAdd(args, options = {}) {
|
|
|
2481
2503
|
process.exit(0);
|
|
2482
2504
|
}
|
|
2483
2505
|
installMode = modeChoice;
|
|
2484
|
-
}
|
|
2506
|
+
} else if (uniqueDirs.size <= 1) installMode = "copy";
|
|
2485
2507
|
const cwd = process.cwd();
|
|
2486
2508
|
const summaryLines = [];
|
|
2487
2509
|
targetAgents.map((a) => agents[a].displayName);
|
|
@@ -2574,6 +2596,7 @@ async function runAdd(args, options = {}) {
|
|
|
2574
2596
|
skillFiles[skill.name] = relativePath;
|
|
2575
2597
|
}
|
|
2576
2598
|
const normalizedSource = getOwnerRepo(parsed);
|
|
2599
|
+
const lockSource = parsed.url.startsWith("git@") ? parsed.url : normalizedSource;
|
|
2577
2600
|
if (normalizedSource) {
|
|
2578
2601
|
const ownerRepo = parseOwnerRepo(normalizedSource);
|
|
2579
2602
|
if (ownerRepo) {
|
|
@@ -2606,7 +2629,7 @@ async function runAdd(args, options = {}) {
|
|
|
2606
2629
|
if (hash) skillFolderHash = hash;
|
|
2607
2630
|
}
|
|
2608
2631
|
await addSkillToLock(skill.name, {
|
|
2609
|
-
source: normalizedSource,
|
|
2632
|
+
source: lockSource || normalizedSource,
|
|
2610
2633
|
sourceType: parsed.type,
|
|
2611
2634
|
sourceUrl: parsed.url,
|
|
2612
2635
|
skillPath: skillPathValue,
|
|
@@ -2623,7 +2646,7 @@ async function runAdd(args, options = {}) {
|
|
|
2623
2646
|
if (successfulSkillNames.has(skillDisplayName)) try {
|
|
2624
2647
|
const computedHash = await computeSkillFolderHash(skill.path);
|
|
2625
2648
|
await addSkillToLocalLock(skill.name, {
|
|
2626
|
-
source:
|
|
2649
|
+
source: lockSource || parsed.url,
|
|
2627
2650
|
sourceType: parsed.type,
|
|
2628
2651
|
computedHash
|
|
2629
2652
|
}, cwd);
|
|
@@ -2812,7 +2835,7 @@ async function searchSkillsAPI(query) {
|
|
|
2812
2835
|
slug: skill.id,
|
|
2813
2836
|
source: skill.source || "",
|
|
2814
2837
|
installs: skill.installs
|
|
2815
|
-
}));
|
|
2838
|
+
})).sort((a, b) => (b.installs || 0) - (a.installs || 0));
|
|
2816
2839
|
} catch {
|
|
2817
2840
|
return [];
|
|
2818
2841
|
}
|
|
@@ -3368,6 +3391,7 @@ function parseListOptions(args) {
|
|
|
3368
3391
|
for (let i = 0; i < args.length; i++) {
|
|
3369
3392
|
const arg = args[i];
|
|
3370
3393
|
if (arg === "-g" || arg === "--global") options.global = true;
|
|
3394
|
+
else if (arg === "--json") options.json = true;
|
|
3371
3395
|
else if (arg === "-a" || arg === "--agent") {
|
|
3372
3396
|
options.agent = options.agent || [];
|
|
3373
3397
|
while (i + 1 < args.length && !args[i + 1].startsWith("-")) options.agent.push(args[++i]);
|
|
@@ -3393,10 +3417,24 @@ async function runList(args) {
|
|
|
3393
3417
|
global: scope,
|
|
3394
3418
|
agentFilter
|
|
3395
3419
|
});
|
|
3420
|
+
if (options.json) {
|
|
3421
|
+
const jsonOutput = installedSkills.map((skill) => ({
|
|
3422
|
+
name: skill.name,
|
|
3423
|
+
path: skill.canonicalPath,
|
|
3424
|
+
scope: skill.scope,
|
|
3425
|
+
agents: skill.agents.map((a) => agents[a].displayName)
|
|
3426
|
+
}));
|
|
3427
|
+
console.log(JSON.stringify(jsonOutput, null, 2));
|
|
3428
|
+
return;
|
|
3429
|
+
}
|
|
3396
3430
|
const lockedSkills = await getAllLockedSkills();
|
|
3397
3431
|
const cwd = process.cwd();
|
|
3398
3432
|
const scopeLabel = scope ? "Global" : "Project";
|
|
3399
3433
|
if (installedSkills.length === 0) {
|
|
3434
|
+
if (options.json) {
|
|
3435
|
+
console.log("[]");
|
|
3436
|
+
return;
|
|
3437
|
+
}
|
|
3400
3438
|
console.log(`${DIM$1}No ${scopeLabel.toLowerCase()} skills found.${RESET$1}`);
|
|
3401
3439
|
if (scope) console.log(`${DIM$1}Try listing project skills without -g${RESET$1}`);
|
|
3402
3440
|
else console.log(`${DIM$1}Try listing global skills with -g${RESET$1}`);
|
|
@@ -3735,6 +3773,7 @@ ${BOLD}Experimental Sync Options:${RESET}
|
|
|
3735
3773
|
${BOLD}List Options:${RESET}
|
|
3736
3774
|
-g, --global List global skills (default: project)
|
|
3737
3775
|
-a, --agent <agents> Filter by specific agents
|
|
3776
|
+
--json Output as JSON (machine-readable, no ANSI codes)
|
|
3738
3777
|
|
|
3739
3778
|
${BOLD}Options:${RESET}
|
|
3740
3779
|
--help, -h Show this help message
|
|
@@ -3751,6 +3790,7 @@ ${BOLD}Examples:${RESET}
|
|
|
3751
3790
|
${DIM}$${RESET} skills list ${DIM}# list project skills${RESET}
|
|
3752
3791
|
${DIM}$${RESET} skills ls -g ${DIM}# list global skills${RESET}
|
|
3753
3792
|
${DIM}$${RESET} skills ls -a claude-code ${DIM}# filter by agent${RESET}
|
|
3793
|
+
${DIM}$${RESET} skills ls --json ${DIM}# JSON output${RESET}
|
|
3754
3794
|
${DIM}$${RESET} skills find ${DIM}# interactive search${RESET}
|
|
3755
3795
|
${DIM}$${RESET} skills find typescript ${DIM}# search by keyword${RESET}
|
|
3756
3796
|
${DIM}$${RESET} skills check
|
|
@@ -3844,6 +3884,8 @@ const AGENTS_DIR = ".agents";
|
|
|
3844
3884
|
const LOCK_FILE = ".skill-lock.json";
|
|
3845
3885
|
const CURRENT_LOCK_VERSION = 3;
|
|
3846
3886
|
function getSkillLockPath() {
|
|
3887
|
+
const xdgStateHome = process.env.XDG_STATE_HOME;
|
|
3888
|
+
if (xdgStateHome) return join(xdgStateHome, "skills", LOCK_FILE);
|
|
3847
3889
|
return join(homedir(), AGENTS_DIR, LOCK_FILE);
|
|
3848
3890
|
}
|
|
3849
3891
|
function readSkillLock() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skills",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.5",
|
|
4
4
|
"description": "The open agent skills ecosystem",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -71,6 +71,7 @@
|
|
|
71
71
|
"roo",
|
|
72
72
|
"trae",
|
|
73
73
|
"trae-cn",
|
|
74
|
+
"warp",
|
|
74
75
|
"windsurf",
|
|
75
76
|
"zencoder",
|
|
76
77
|
"neovate",
|