skills 1.3.8 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -212,7 +212,7 @@ Skills can be installed to any of these agents:
212
212
  | Antigravity | `antigravity` | `.agent/skills/` | `~/.gemini/antigravity/skills/` |
213
213
  | Augment | `augment` | `.augment/skills/` | `~/.augment/skills/` |
214
214
  | Claude Code | `claude-code` | `.claude/skills/` | `~/.claude/skills/` |
215
- | OpenClaw | `openclaw` | `skills/` | `~/.moltbot/skills/` |
215
+ | OpenClaw | `openclaw` | `skills/` | `~/.openclaw/skills/` |
216
216
  | Cline | `cline` | `.cline/skills/` | `~/.cline/skills/` |
217
217
  | CodeBuddy | `codebuddy` | `.codebuddy/skills/` | `~/.codebuddy/skills/` |
218
218
  | Codex | `codex` | `.agents/skills/` | `~/.codex/skills/` |
@@ -373,7 +373,7 @@ If no skills are found in standard locations, a recursive search is performed.
373
373
  Skills are generally compatible across agents since they follow a
374
374
  shared [Agent Skills specification](https://agentskills.io). However, some features may be agent-specific:
375
375
 
376
- | Feature | OpenCode | OpenHands | Claude Code | Cline | CodeBuddy | Codex | Command Code | Kiro CLI | Cursor | Antigravity | Roo Code | Github Copilot | Amp | Clawdbot | Neovate | Pi | Qoder | Zencoder |
376
+ | Feature | OpenCode | OpenHands | Claude Code | Cline | CodeBuddy | Codex | Command Code | Kiro CLI | Cursor | Antigravity | Roo Code | Github Copilot | Amp | OpenClaw | Neovate | Pi | Qoder | Zencoder |
377
377
  | --------------- | -------- | --------- | ----------- | ----- | --------- | ----- | ------------ | -------- | ------ | ----------- | -------- | -------------- | --- | -------- | ------- | --- | ----- | -------- |
378
378
  | Basic skills | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
379
379
  | `allowed-tools` | Yes | Yes | Yes | Yes | Yes | Yes | Yes | No | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | No |
@@ -423,7 +423,7 @@ Telemetry is automatically disabled in CI environments.
423
423
  - [Antigravity Skills Documentation](https://antigravity.google/docs/skills)
424
424
  - [Factory AI / Droid Skills Documentation](https://docs.factory.ai/cli/configuration/skills)
425
425
  - [Claude Code Skills Documentation](https://code.claude.com/docs/en/skills)
426
- - [Clawdbot Skills Documentation](https://docs.clawd.bot/tools/skills)
426
+ - [OpenClaw Skills Documentation](https://docs.openclaw.ai/tools/skills)
427
427
  - [Cline Skills Documentation](https://docs.cline.bot/features/skills)
428
428
  - [CodeBuddy Skills Documentation](https://www.codebuddy.ai/docs/ide/Features/Skills)
429
429
  - [Codex Skills Documentation](https://developers.openai.com/codex/skills)
@@ -8,23 +8,6 @@ are set forth below. These licenses and notices are provided for informational p
8
8
  Third Party Code Components
9
9
  --------------------------------------------
10
10
 
11
- ================================================================================
12
- Package: @clack/core@0.4.1
13
- License: MIT
14
- Repository: https://github.com/natemoo-re/clack
15
- --------------------------------------------------------------------------------
16
-
17
- MIT License
18
-
19
- Copyright (c) Nate Moore
20
-
21
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
22
-
23
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
24
-
25
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
-
27
-
28
11
  ================================================================================
29
12
  Package: @clack/prompts@0.11.0
30
13
  License: MIT
@@ -121,35 +104,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
121
104
  SOFTWARE.
122
105
 
123
106
 
124
- ================================================================================
125
- Package: sisteransi@1.0.5
126
- License: MIT
127
- Repository: https://github.com/terkelg/sisteransi
128
- --------------------------------------------------------------------------------
129
-
130
- MIT License
131
-
132
- Copyright (c) 2018 Terkel Gjervig Nielsen
133
-
134
- Permission is hereby granted, free of charge, to any person obtaining a copy
135
- of this software and associated documentation files (the "Software"), to deal
136
- in the Software without restriction, including without limitation the rights
137
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
138
- copies of the Software, and to permit persons to whom the Software is
139
- furnished to do so, subject to the following conditions:
140
-
141
- The above copyright notice and this permission notice shall be included in all
142
- copies or substantial portions of the Software.
143
-
144
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
145
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
146
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
147
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
148
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
149
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
150
- SOFTWARE.
151
-
152
-
153
107
  ================================================================================
154
108
  Package: xdg-basedir@5.1.0
155
109
  License: MIT
package/dist/cli.mjs CHANGED
@@ -58,7 +58,10 @@ function isDirectSkillUrl(input) {
58
58
  if (input.includes("gitlab.com/") && !input.includes("/-/raw/")) return false;
59
59
  return true;
60
60
  }
61
+ const SOURCE_ALIASES = { "coinbase/agentWallet": "coinbase/agentic-wallet-skills" };
61
62
  function parseSource(input) {
63
+ const alias = SOURCE_ALIASES[input];
64
+ if (alias) input = alias;
62
65
  if (isLocalPath(input)) {
63
66
  const resolvedPath = resolve(input);
64
67
  return {
@@ -545,6 +548,12 @@ const home = homedir();
545
548
  const configHome = xdgConfig ?? join(home, ".config");
546
549
  const codexHome = process.env.CODEX_HOME?.trim() || join(home, ".codex");
547
550
  const claudeHome = process.env.CLAUDE_CONFIG_DIR?.trim() || join(home, ".claude");
551
+ function getOpenClawGlobalSkillsDir(homeDir = home, pathExists = existsSync) {
552
+ if (pathExists(join(homeDir, ".openclaw"))) return join(homeDir, ".openclaw/skills");
553
+ if (pathExists(join(homeDir, ".clawdbot"))) return join(homeDir, ".clawdbot/skills");
554
+ if (pathExists(join(homeDir, ".moltbot"))) return join(homeDir, ".moltbot/skills");
555
+ return join(homeDir, ".openclaw/skills");
556
+ }
548
557
  const agents = {
549
558
  amp: {
550
559
  name: "amp",
@@ -586,7 +595,7 @@ const agents = {
586
595
  name: "openclaw",
587
596
  displayName: "OpenClaw",
588
597
  skillsDir: "skills",
589
- globalSkillsDir: existsSync(join(home, ".openclaw")) ? join(home, ".openclaw/skills") : existsSync(join(home, ".clawdbot")) ? join(home, ".clawdbot/skills") : join(home, ".moltbot/skills"),
598
+ globalSkillsDir: getOpenClawGlobalSkillsDir(),
590
599
  detectInstalled: async () => {
591
600
  return existsSync(join(home, ".openclaw")) || existsSync(join(home, ".clawdbot")) || existsSync(join(home, ".moltbot"));
592
601
  }
@@ -1359,6 +1368,7 @@ async function listInstalledSkills(options = {}) {
1359
1368
  return Array.from(skillsMap.values());
1360
1369
  }
1361
1370
  const TELEMETRY_URL = "https://add-skill.vercel.sh/t";
1371
+ const AUDIT_URL = "https://add-skill.vercel.sh/audit";
1362
1372
  let cliVersion = null;
1363
1373
  function isCI() {
1364
1374
  return !!(process.env.CI || process.env.GITHUB_ACTIONS || process.env.GITLAB_CI || process.env.CIRCLECI || process.env.TRAVIS || process.env.BUILDKITE || process.env.JENKINS_URL || process.env.TEAMCITY_VERSION);
@@ -1369,6 +1379,23 @@ function isEnabled() {
1369
1379
  function setVersion(version) {
1370
1380
  cliVersion = version;
1371
1381
  }
1382
+ async function fetchAuditData(source, skillSlugs, timeoutMs = 3e3) {
1383
+ if (skillSlugs.length === 0) return null;
1384
+ try {
1385
+ const params = new URLSearchParams({
1386
+ source,
1387
+ skills: skillSlugs.join(",")
1388
+ });
1389
+ const controller = new AbortController();
1390
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
1391
+ const response = await fetch(`${AUDIT_URL}?${params.toString()}`, { signal: controller.signal });
1392
+ clearTimeout(timeout);
1393
+ if (!response.ok) return null;
1394
+ return await response.json();
1395
+ } catch {
1396
+ return null;
1397
+ }
1398
+ }
1372
1399
  function track(data) {
1373
1400
  if (!isEnabled()) return;
1374
1401
  try {
@@ -1796,7 +1823,7 @@ async function saveSelectedAgents(agents) {
1796
1823
  lock.lastSelectedAgents = agents;
1797
1824
  await writeSkillLock(lock);
1798
1825
  }
1799
- var version$1 = "1.3.8";
1826
+ var version$1 = "1.4.0";
1800
1827
  const isCancelled = (value) => typeof value === "symbol";
1801
1828
  async function isSourcePrivate(source) {
1802
1829
  const ownerRepo = parseOwnerRepo(source);
@@ -1806,6 +1833,48 @@ async function isSourcePrivate(source) {
1806
1833
  function initTelemetry(version) {
1807
1834
  setVersion(version);
1808
1835
  }
1836
+ function riskLabel(risk) {
1837
+ switch (risk) {
1838
+ case "critical": return import_picocolors.default.red(import_picocolors.default.bold("Critical Risk"));
1839
+ case "high": return import_picocolors.default.red("High Risk");
1840
+ case "medium": return import_picocolors.default.yellow("Med Risk");
1841
+ case "low": return import_picocolors.default.green("Low Risk");
1842
+ case "safe": return import_picocolors.default.green("Safe");
1843
+ default: return import_picocolors.default.dim("--");
1844
+ }
1845
+ }
1846
+ function socketLabel(audit) {
1847
+ if (!audit) return import_picocolors.default.dim("--");
1848
+ const count = audit.alerts ?? 0;
1849
+ return count > 0 ? import_picocolors.default.red(`${count} alert${count !== 1 ? "s" : ""}`) : import_picocolors.default.green("0 alerts");
1850
+ }
1851
+ function padEnd(str, width) {
1852
+ const visible = str.replace(/\x1b\[[0-9;]*m/g, "");
1853
+ const pad = Math.max(0, width - visible.length);
1854
+ return str + " ".repeat(pad);
1855
+ }
1856
+ function buildSecurityLines(auditData, skills, source) {
1857
+ if (!auditData) return [];
1858
+ if (!skills.some((s) => {
1859
+ const data = auditData[s.slug];
1860
+ return data && Object.keys(data).length > 0;
1861
+ })) return [];
1862
+ const nameWidth = Math.min(Math.max(...skills.map((s) => s.displayName.length)), 36);
1863
+ const lines = [];
1864
+ const header = padEnd("", nameWidth + 2) + padEnd(import_picocolors.default.dim("Gen"), 18) + padEnd(import_picocolors.default.dim("Socket"), 18) + import_picocolors.default.dim("Snyk");
1865
+ lines.push(header);
1866
+ for (const skill of skills) {
1867
+ const data = auditData[skill.slug];
1868
+ const name = skill.displayName.length > nameWidth ? skill.displayName.slice(0, nameWidth - 1) + "…" : skill.displayName;
1869
+ const ath = data?.ath ? riskLabel(data.ath.risk) : import_picocolors.default.dim("--");
1870
+ const socket = data?.socket ? socketLabel(data.socket) : import_picocolors.default.dim("--");
1871
+ const snyk = data?.snyk ? riskLabel(data.snyk.risk) : import_picocolors.default.dim("--");
1872
+ lines.push(padEnd(import_picocolors.default.cyan(name), nameWidth + 2) + padEnd(ath, 18) + padEnd(socket, 18) + snyk);
1873
+ }
1874
+ lines.push("");
1875
+ lines.push(`${import_picocolors.default.dim("Details:")} ${import_picocolors.default.dim(`https://skills.sh/${source}`)}`);
1876
+ return lines;
1877
+ }
1809
1878
  function shortenPath$1(fullPath, cwd) {
1810
1879
  const home = homedir();
1811
1880
  if (fullPath === home || fullPath.startsWith(home + sep)) return "~" + fullPath.slice(home.length);
@@ -2711,6 +2780,8 @@ async function runAdd(args, options = {}) {
2711
2780
  }
2712
2781
  selectedSkills = selected;
2713
2782
  }
2783
+ const ownerRepoForAudit = getOwnerRepo(parsed);
2784
+ const auditPromise = ownerRepoForAudit ? fetchAuditData(ownerRepoForAudit, selectedSkills.map((s) => getSkillDisplayName(s))) : Promise.resolve(null);
2714
2785
  let targetAgents;
2715
2786
  const validAgents = Object.keys(agents);
2716
2787
  if (options.agent?.includes("*")) {
@@ -2829,6 +2900,16 @@ async function runAdd(args, options = {}) {
2829
2900
  }
2830
2901
  console.log();
2831
2902
  Me(summaryLines.join("\n"), "Installation Summary");
2903
+ try {
2904
+ const auditData = await auditPromise;
2905
+ if (auditData && ownerRepoForAudit) {
2906
+ const securityLines = buildSecurityLines(auditData, selectedSkills.map((s) => ({
2907
+ slug: getSkillDisplayName(s),
2908
+ displayName: getSkillDisplayName(s)
2909
+ })), ownerRepoForAudit);
2910
+ if (securityLines.length > 0) Me(securityLines.join("\n"), "Security Risk Assessments");
2911
+ }
2912
+ } catch {}
2832
2913
  if (!options.yes) {
2833
2914
  const confirmed = await ye({ message: "Proceed with installation?" });
2834
2915
  if (pD(confirmed) || !confirmed) {
@@ -3043,7 +3124,14 @@ const RESET$2 = "\x1B[0m";
3043
3124
  const BOLD$2 = "\x1B[1m";
3044
3125
  const DIM$2 = "\x1B[38;5;102m";
3045
3126
  const TEXT$1 = "\x1B[38;5;145m";
3127
+ const CYAN$1 = "\x1B[36m";
3046
3128
  const SEARCH_API_BASE = process.env.SKILLS_API_URL || "https://skills.sh";
3129
+ function formatInstalls(count) {
3130
+ if (!count || count <= 0) return "";
3131
+ if (count >= 1e6) return `${(count / 1e6).toFixed(1).replace(/\.0$/, "")}M installs`;
3132
+ if (count >= 1e3) return `${(count / 1e3).toFixed(1).replace(/\.0$/, "")}K installs`;
3133
+ return `${count} install${count === 1 ? "" : "s"}`;
3134
+ }
3047
3135
  async function searchSkillsAPI(query) {
3048
3136
  try {
3049
3137
  const url = `${SEARCH_API_BASE}/api/search?q=${encodeURIComponent(query)}&limit=10`;
@@ -3093,8 +3181,10 @@ async function runSearchPrompt(initialQuery = "") {
3093
3181
  const arrow = isSelected ? `${BOLD$2}>${RESET$2}` : " ";
3094
3182
  const name = isSelected ? `${BOLD$2}${skill.name}${RESET$2}` : `${TEXT$1}${skill.name}${RESET$2}`;
3095
3183
  const source = skill.source ? ` ${DIM$2}${skill.source}${RESET$2}` : "";
3184
+ const installs = formatInstalls(skill.installs);
3185
+ const installsBadge = installs ? ` ${CYAN$1}${installs}${RESET$2}` : "";
3096
3186
  const loadingIndicator = loading && i === 0 ? ` ${DIM$2}...${RESET$2}` : "";
3097
- lines.push(` ${arrow} ${name}${source}${loadingIndicator}`);
3187
+ lines.push(` ${arrow} ${name}${source}${installsBadge}${loadingIndicator}`);
3098
3188
  }
3099
3189
  }
3100
3190
  lines.push("");
@@ -3212,7 +3302,8 @@ ${DIM$2} 2) npx skills add <owner/repo@skill>${RESET$2}`;
3212
3302
  console.log();
3213
3303
  for (const skill of results.slice(0, 6)) {
3214
3304
  const pkg = skill.source || skill.slug;
3215
- console.log(`${TEXT$1}${pkg}@${skill.name}${RESET$2}`);
3305
+ const installs = formatInstalls(skill.installs);
3306
+ console.log(`${TEXT$1}${pkg}@${skill.name}${RESET$2}${installs ? ` ${CYAN$1}${installs}${RESET$2}` : ""}`);
3216
3307
  console.log(`${DIM$2}└ https://skills.sh/${skill.slug}${RESET$2}`);
3217
3308
  console.log();
3218
3309
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skills",
3
- "version": "1.3.8",
3
+ "version": "1.4.0",
4
4
  "description": "The open agent skills ecosystem",
5
5
  "type": "module",
6
6
  "bin": {