skills 1.4.4 → 1.4.5-snapshot.2

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
@@ -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 [37 more](#available-agents).
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/` |
@@ -8,6 +8,23 @@ 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
+
11
28
  ================================================================================
12
29
  Package: @clack/prompts@0.11.0
13
30
  License: MIT
@@ -104,6 +121,35 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
104
121
  SOFTWARE.
105
122
 
106
123
 
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
+
107
153
  ================================================================================
108
154
  Package: xdg-basedir@5.1.0
109
155
  License: MIT
@@ -0,0 +1,132 @@
1
+ import { n as __require, t as __commonJSMin } from "../../rolldown-runtime.mjs";
2
+ var require_dist = /* @__PURE__ */ __commonJSMin(((exports, module) => {
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all) __defProp(target, name, {
9
+ get: all[name],
10
+ enumerable: true
11
+ });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
16
+ get: () => from[key],
17
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
18
+ });
19
+ }
20
+ return to;
21
+ };
22
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
23
+ var src_exports = {};
24
+ __export(src_exports, {
25
+ KNOWN_AGENTS: () => KNOWN_AGENTS,
26
+ determineAgent: () => determineAgent
27
+ });
28
+ module.exports = __toCommonJS(src_exports);
29
+ var import_promises = __require("node:fs/promises");
30
+ var import_node_fs = __require("node:fs");
31
+ const DEVIN_LOCAL_PATH = "/opt/.devin";
32
+ const CURSOR = "cursor";
33
+ const CURSOR_CLI = "cursor-cli";
34
+ const CLAUDE = "claude";
35
+ const COWORK = "cowork";
36
+ const DEVIN = "devin";
37
+ const REPLIT = "replit";
38
+ const GEMINI = "gemini";
39
+ const CODEX = "codex";
40
+ const ANTIGRAVITY = "antigravity";
41
+ const AUGMENT_CLI = "augment-cli";
42
+ const OPENCODE = "opencode";
43
+ const GITHUB_COPILOT = "github-copilot";
44
+ const GITHUB_COPILOT_CLI = "github-copilot-cli";
45
+ const KNOWN_AGENTS = {
46
+ CURSOR,
47
+ CURSOR_CLI,
48
+ CLAUDE,
49
+ COWORK,
50
+ DEVIN,
51
+ REPLIT,
52
+ GEMINI,
53
+ CODEX,
54
+ ANTIGRAVITY,
55
+ AUGMENT_CLI,
56
+ OPENCODE,
57
+ GITHUB_COPILOT
58
+ };
59
+ async function determineAgent() {
60
+ if (process.env.AI_AGENT) {
61
+ const name = process.env.AI_AGENT.trim();
62
+ if (name) {
63
+ if (name === GITHUB_COPILOT || name === GITHUB_COPILOT_CLI) return {
64
+ isAgent: true,
65
+ agent: { name: GITHUB_COPILOT }
66
+ };
67
+ return {
68
+ isAgent: true,
69
+ agent: { name }
70
+ };
71
+ }
72
+ }
73
+ if (process.env.CURSOR_TRACE_ID) return {
74
+ isAgent: true,
75
+ agent: { name: CURSOR }
76
+ };
77
+ if (process.env.CURSOR_AGENT) return {
78
+ isAgent: true,
79
+ agent: { name: CURSOR_CLI }
80
+ };
81
+ if (process.env.GEMINI_CLI) return {
82
+ isAgent: true,
83
+ agent: { name: GEMINI }
84
+ };
85
+ if (process.env.CODEX_SANDBOX || process.env.CODEX_CI || process.env.CODEX_THREAD_ID) return {
86
+ isAgent: true,
87
+ agent: { name: CODEX }
88
+ };
89
+ if (process.env.ANTIGRAVITY_AGENT) return {
90
+ isAgent: true,
91
+ agent: { name: ANTIGRAVITY }
92
+ };
93
+ if (process.env.AUGMENT_AGENT) return {
94
+ isAgent: true,
95
+ agent: { name: AUGMENT_CLI }
96
+ };
97
+ if (process.env.OPENCODE_CLIENT) return {
98
+ isAgent: true,
99
+ agent: { name: OPENCODE }
100
+ };
101
+ if (process.env.CLAUDECODE || process.env.CLAUDE_CODE) {
102
+ if (process.env.CLAUDE_CODE_IS_COWORK) return {
103
+ isAgent: true,
104
+ agent: { name: COWORK }
105
+ };
106
+ return {
107
+ isAgent: true,
108
+ agent: { name: CLAUDE }
109
+ };
110
+ }
111
+ if (process.env.REPL_ID) return {
112
+ isAgent: true,
113
+ agent: { name: REPLIT }
114
+ };
115
+ if (process.env.COPILOT_MODEL || process.env.COPILOT_ALLOW_ALL || process.env.COPILOT_GITHUB_TOKEN) return {
116
+ isAgent: true,
117
+ agent: { name: GITHUB_COPILOT }
118
+ };
119
+ try {
120
+ await (0, import_promises.access)(DEVIN_LOCAL_PATH, import_node_fs.constants.F_OK);
121
+ return {
122
+ isAgent: true,
123
+ agent: { name: DEVIN }
124
+ };
125
+ } catch (_error) {}
126
+ return {
127
+ isAgent: false,
128
+ agent: void 0
129
+ };
130
+ }
131
+ }));
132
+ export { require_dist as t };
package/dist/cli.mjs CHANGED
@@ -9,6 +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 { t as xdgConfig } from "./_chunks/libs/xdg-basedir.mjs";
12
+ import { t as require_dist } from "./_chunks/libs/@vercel/detect-agent.mjs";
12
13
  import { execSync, spawn, spawnSync } from "child_process";
13
14
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
14
15
  import { basename, dirname, isAbsolute, join, normalize, relative, resolve, sep } from "path";
@@ -924,6 +925,15 @@ const agents = {
924
925
  return existsSync(join(home, ".trae-cn"));
925
926
  }
926
927
  },
928
+ warp: {
929
+ name: "warp",
930
+ displayName: "Warp",
931
+ skillsDir: ".agents/skills",
932
+ globalSkillsDir: join(home, ".agents/skills"),
933
+ detectInstalled: async () => {
934
+ return existsSync(join(home, ".warp"));
935
+ }
936
+ },
927
937
  windsurf: {
928
938
  name: "windsurf",
929
939
  displayName: "Windsurf",
@@ -1136,10 +1146,14 @@ async function installSkillForAgent(skill, agentType, options = {}) {
1136
1146
  }
1137
1147
  }
1138
1148
  const EXCLUDE_FILES = new Set(["metadata.json"]);
1139
- const EXCLUDE_DIRS = new Set([".git"]);
1149
+ const EXCLUDE_DIRS = new Set([
1150
+ ".git",
1151
+ "__pycache__",
1152
+ "__pypackages__"
1153
+ ]);
1140
1154
  const isExcluded = (name, isDirectory = false) => {
1141
1155
  if (EXCLUDE_FILES.has(name)) return true;
1142
- if (name.startsWith("_")) return true;
1156
+ if (name.startsWith(".")) return true;
1143
1157
  if (isDirectory && EXCLUDE_DIRS.has(name)) return true;
1144
1158
  return false;
1145
1159
  };
@@ -1150,10 +1164,15 @@ async function copyDirectory(src, dest) {
1150
1164
  const srcPath = join(src, entry.name);
1151
1165
  const destPath = join(dest, entry.name);
1152
1166
  if (entry.isDirectory()) await copyDirectory(srcPath, destPath);
1153
- else await cp(srcPath, destPath, {
1154
- dereference: true,
1155
- recursive: true
1156
- });
1167
+ else try {
1168
+ await cp(srcPath, destPath, {
1169
+ dereference: true,
1170
+ recursive: true
1171
+ });
1172
+ } catch (err) {
1173
+ if (err instanceof Error && "code" in err && err.code === "ENOENT" && entry.isSymbolicLink()) console.warn(`Skipping broken symlink: ${srcPath}`);
1174
+ else throw err;
1175
+ }
1157
1176
  }));
1158
1177
  }
1159
1178
  async function isSkillInstalled(skillName, agentType, options = {}) {
@@ -1380,6 +1399,10 @@ async function listInstalledSkills(options = {}) {
1380
1399
  const TELEMETRY_URL = "https://add-skill.vercel.sh/t";
1381
1400
  const AUDIT_URL = "https://add-skill.vercel.sh/audit";
1382
1401
  let cliVersion = null;
1402
+ let detectedAgentName = null;
1403
+ function setDetectedAgent(agentName) {
1404
+ detectedAgentName = agentName;
1405
+ }
1383
1406
  function isCI() {
1384
1407
  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);
1385
1408
  }
@@ -1412,10 +1435,39 @@ function track(data) {
1412
1435
  const params = new URLSearchParams();
1413
1436
  if (cliVersion) params.set("v", cliVersion);
1414
1437
  if (isCI()) params.set("ci", "1");
1438
+ if (detectedAgentName) params.set("agent", detectedAgentName);
1415
1439
  for (const [key, value] of Object.entries(data)) if (value !== void 0 && value !== null) params.set(key, String(value));
1416
1440
  fetch(`${TELEMETRY_URL}?${params.toString()}`).catch(() => {});
1417
1441
  } catch {}
1418
1442
  }
1443
+ var import_dist = require_dist();
1444
+ let cachedResult = null;
1445
+ const agentNameToType = {
1446
+ cursor: "cursor",
1447
+ "cursor-cli": "cursor",
1448
+ claude: "claude-code",
1449
+ cowork: "claude-code",
1450
+ devin: "universal",
1451
+ replit: "replit",
1452
+ gemini: "gemini-cli",
1453
+ codex: "codex",
1454
+ antigravity: "antigravity",
1455
+ "augment-cli": "augment",
1456
+ opencode: "opencode",
1457
+ "github-copilot": "github-copilot"
1458
+ };
1459
+ async function detectAgent() {
1460
+ if (cachedResult) return cachedResult;
1461
+ cachedResult = await (0, import_dist.determineAgent)();
1462
+ if (cachedResult.isAgent) setDetectedAgent(cachedResult.agent.name);
1463
+ return cachedResult;
1464
+ }
1465
+ async function isRunningInAgent() {
1466
+ return (await detectAgent()).isAgent;
1467
+ }
1468
+ function getAgentType(agentName) {
1469
+ return agentNameToType[agentName] ?? null;
1470
+ }
1419
1471
  var ProviderRegistryImpl = class {
1420
1472
  providers = [];
1421
1473
  register(provider) {
@@ -1601,6 +1653,8 @@ const AGENTS_DIR$1 = ".agents";
1601
1653
  const LOCK_FILE$1 = ".skill-lock.json";
1602
1654
  const CURRENT_VERSION$1 = 3;
1603
1655
  function getSkillLockPath$1() {
1656
+ const xdgStateHome = process.env.XDG_STATE_HOME;
1657
+ if (xdgStateHome) return join(xdgStateHome, "skills", LOCK_FILE$1);
1604
1658
  return join(homedir(), AGENTS_DIR$1, LOCK_FILE$1);
1605
1659
  }
1606
1660
  async function readSkillLock$1() {
@@ -1773,7 +1827,7 @@ function createEmptyLocalLock() {
1773
1827
  skills: {}
1774
1828
  };
1775
1829
  }
1776
- var version$1 = "1.4.4";
1830
+ var version$1 = "1.4.5-snapshot.2";
1777
1831
  const isCancelled$1 = (value) => typeof value === "symbol";
1778
1832
  async function isSourcePrivate(source) {
1779
1833
  const ownerRepo = parseOwnerRepo(source);
@@ -2070,7 +2124,8 @@ async function handleWellKnownSkills(source, url, options, spinner) {
2070
2124
  installGlobally = scope;
2071
2125
  }
2072
2126
  let installMode = options.copy ? "copy" : "symlink";
2073
- if (!options.copy && !options.yes) {
2127
+ const uniqueDirs = new Set(targetAgents.map((a) => agents[a].skillsDir));
2128
+ if (!options.copy && !options.yes && uniqueDirs.size > 1) {
2074
2129
  const modeChoice = await ve({
2075
2130
  message: "Installation method",
2076
2131
  options: [{
@@ -2088,7 +2143,7 @@ async function handleWellKnownSkills(source, url, options, spinner) {
2088
2143
  process.exit(0);
2089
2144
  }
2090
2145
  installMode = modeChoice;
2091
- }
2146
+ } else if (uniqueDirs.size <= 1) installMode = "copy";
2092
2147
  const cwd = process.cwd();
2093
2148
  const summaryLines = [];
2094
2149
  targetAgents.map((a) => agents[a].displayName);
@@ -2244,9 +2299,18 @@ async function runAdd(args, options = {}) {
2244
2299
  options.agent = ["*"];
2245
2300
  options.yes = true;
2246
2301
  }
2302
+ const agentResult = await detectAgent();
2303
+ if (agentResult.isAgent) {
2304
+ options.yes = true;
2305
+ if (!options.agent || options.agent.length === 0) {
2306
+ const mappedAgent = getAgentType(agentResult.agent.name);
2307
+ if (mappedAgent) options.agent = [mappedAgent];
2308
+ }
2309
+ }
2247
2310
  console.log();
2248
- Ie(import_picocolors.default.bgCyan(import_picocolors.default.black(" skills ")));
2249
- if (!process.stdin.isTTY) showInstallTip();
2311
+ if (!agentResult.isAgent) Ie(import_picocolors.default.bgCyan(import_picocolors.default.black(" skills ")));
2312
+ if (agentResult.isAgent) M.info(import_picocolors.default.dim(`Detected running in ${import_picocolors.default.cyan(agentResult.agent.name)}, skipping prompts`));
2313
+ else if (!process.stdin.isTTY) showInstallTip();
2250
2314
  let tempDir = null;
2251
2315
  try {
2252
2316
  const spinner = Y();
@@ -2462,7 +2526,8 @@ async function runAdd(args, options = {}) {
2462
2526
  installGlobally = scope;
2463
2527
  }
2464
2528
  let installMode = options.copy ? "copy" : "symlink";
2465
- if (!options.copy && !options.yes) {
2529
+ const uniqueDirs = new Set(targetAgents.map((a) => agents[a].skillsDir));
2530
+ if (!options.copy && !options.yes && uniqueDirs.size > 1) {
2466
2531
  const modeChoice = await ve({
2467
2532
  message: "Installation method",
2468
2533
  options: [{
@@ -2481,7 +2546,7 @@ async function runAdd(args, options = {}) {
2481
2546
  process.exit(0);
2482
2547
  }
2483
2548
  installMode = modeChoice;
2484
- }
2549
+ } else if (uniqueDirs.size <= 1) installMode = "copy";
2485
2550
  const cwd = process.cwd();
2486
2551
  const summaryLines = [];
2487
2552
  targetAgents.map((a) => agents[a].displayName);
@@ -2574,6 +2639,7 @@ async function runAdd(args, options = {}) {
2574
2639
  skillFiles[skill.name] = relativePath;
2575
2640
  }
2576
2641
  const normalizedSource = getOwnerRepo(parsed);
2642
+ const lockSource = parsed.url.startsWith("git@") ? parsed.url : normalizedSource;
2577
2643
  if (normalizedSource) {
2578
2644
  const ownerRepo = parseOwnerRepo(normalizedSource);
2579
2645
  if (ownerRepo) {
@@ -2606,7 +2672,7 @@ async function runAdd(args, options = {}) {
2606
2672
  if (hash) skillFolderHash = hash;
2607
2673
  }
2608
2674
  await addSkillToLock(skill.name, {
2609
- source: normalizedSource,
2675
+ source: lockSource || normalizedSource,
2610
2676
  sourceType: parsed.type,
2611
2677
  sourceUrl: parsed.url,
2612
2678
  skillPath: skillPathValue,
@@ -2623,7 +2689,7 @@ async function runAdd(args, options = {}) {
2623
2689
  if (successfulSkillNames.has(skillDisplayName)) try {
2624
2690
  const computedHash = await computeSkillFolderHash(skill.path);
2625
2691
  await addSkillToLocalLock(skill.name, {
2626
- source: normalizedSource || parsed.url,
2692
+ source: lockSource || parsed.url,
2627
2693
  sourceType: parsed.type,
2628
2694
  computedHash
2629
2695
  }, cwd);
@@ -2812,7 +2878,7 @@ async function searchSkillsAPI(query) {
2812
2878
  slug: skill.id,
2813
2879
  source: skill.source || "",
2814
2880
  installs: skill.installs
2815
- }));
2881
+ })).sort((a, b) => (b.installs || 0) - (a.installs || 0));
2816
2882
  } catch {
2817
2883
  return [];
2818
2884
  }
@@ -2979,9 +3045,11 @@ ${DIM$2} 2) npx skills add <owner/repo@skill>${RESET$2}`;
2979
3045
  }
2980
3046
  return;
2981
3047
  }
2982
- if (isNonInteractive) {
3048
+ if (isNonInteractive || await isRunningInAgent()) {
2983
3049
  console.log(agentTip);
2984
3050
  console.log();
3051
+ console.log(`${DIM$2}Usage: npx skills find <query>${RESET$2}`);
3052
+ return;
2985
3053
  }
2986
3054
  const selected = await runSearchPrompt();
2987
3055
  track({
@@ -3085,8 +3153,17 @@ async function discoverNodeModuleSkills(cwd) {
3085
3153
  }
3086
3154
  async function runSync(args, options = {}) {
3087
3155
  const cwd = process.cwd();
3156
+ const agentResult = await detectAgent();
3157
+ if (agentResult.isAgent) {
3158
+ options.yes = true;
3159
+ if (!options.agent || options.agent.length === 0) {
3160
+ const mappedAgent = getAgentType(agentResult.agent.name);
3161
+ if (mappedAgent) options.agent = [mappedAgent];
3162
+ }
3163
+ }
3088
3164
  console.log();
3089
- Ie(import_picocolors.default.bgCyan(import_picocolors.default.black(" skills experimental_sync ")));
3165
+ if (!agentResult.isAgent) Ie(import_picocolors.default.bgCyan(import_picocolors.default.black(" skills experimental_sync ")));
3166
+ if (agentResult.isAgent) M.info(import_picocolors.default.dim(`Detected running in ${import_picocolors.default.cyan(agentResult.agent.name)}, skipping prompts`));
3090
3167
  const spinner = Y();
3091
3168
  spinner.start("Scanning node_modules for skills...");
3092
3169
  const discoveredSkills = await discoverNodeModuleSkills(cwd);
@@ -3368,6 +3445,7 @@ function parseListOptions(args) {
3368
3445
  for (let i = 0; i < args.length; i++) {
3369
3446
  const arg = args[i];
3370
3447
  if (arg === "-g" || arg === "--global") options.global = true;
3448
+ else if (arg === "--json") options.json = true;
3371
3449
  else if (arg === "-a" || arg === "--agent") {
3372
3450
  options.agent = options.agent || [];
3373
3451
  while (i + 1 < args.length && !args[i + 1].startsWith("-")) options.agent.push(args[++i]);
@@ -3393,10 +3471,24 @@ async function runList(args) {
3393
3471
  global: scope,
3394
3472
  agentFilter
3395
3473
  });
3474
+ if (options.json) {
3475
+ const jsonOutput = installedSkills.map((skill) => ({
3476
+ name: skill.name,
3477
+ path: skill.canonicalPath,
3478
+ scope: skill.scope,
3479
+ agents: skill.agents.map((a) => agents[a].displayName)
3480
+ }));
3481
+ console.log(JSON.stringify(jsonOutput, null, 2));
3482
+ return;
3483
+ }
3396
3484
  const lockedSkills = await getAllLockedSkills();
3397
3485
  const cwd = process.cwd();
3398
3486
  const scopeLabel = scope ? "Global" : "Project";
3399
3487
  if (installedSkills.length === 0) {
3488
+ if (options.json) {
3489
+ console.log("[]");
3490
+ return;
3491
+ }
3400
3492
  console.log(`${DIM$1}No ${scopeLabel.toLowerCase()} skills found.${RESET$1}`);
3401
3493
  if (scope) console.log(`${DIM$1}Try listing project skills without -g${RESET$1}`);
3402
3494
  else console.log(`${DIM$1}Try listing global skills with -g${RESET$1}`);
@@ -3442,6 +3534,11 @@ async function runList(args) {
3442
3534
  }
3443
3535
  }
3444
3536
  async function removeCommand(skillNames, options) {
3537
+ const agentResult = await detectAgent();
3538
+ if (agentResult.isAgent) {
3539
+ options.yes = true;
3540
+ M.info(import_picocolors.default.dim(`Detected running in ${import_picocolors.default.cyan(agentResult.agent.name)}, skipping prompts`));
3541
+ }
3445
3542
  const isGlobal = options.global ?? false;
3446
3543
  const cwd = process.cwd();
3447
3544
  const spinner = Y();
@@ -3735,6 +3832,7 @@ ${BOLD}Experimental Sync Options:${RESET}
3735
3832
  ${BOLD}List Options:${RESET}
3736
3833
  -g, --global List global skills (default: project)
3737
3834
  -a, --agent <agents> Filter by specific agents
3835
+ --json Output as JSON (machine-readable, no ANSI codes)
3738
3836
 
3739
3837
  ${BOLD}Options:${RESET}
3740
3838
  --help, -h Show this help message
@@ -3751,6 +3849,7 @@ ${BOLD}Examples:${RESET}
3751
3849
  ${DIM}$${RESET} skills list ${DIM}# list project skills${RESET}
3752
3850
  ${DIM}$${RESET} skills ls -g ${DIM}# list global skills${RESET}
3753
3851
  ${DIM}$${RESET} skills ls -a claude-code ${DIM}# filter by agent${RESET}
3852
+ ${DIM}$${RESET} skills ls --json ${DIM}# JSON output${RESET}
3754
3853
  ${DIM}$${RESET} skills find ${DIM}# interactive search${RESET}
3755
3854
  ${DIM}$${RESET} skills find typescript ${DIM}# search by keyword${RESET}
3756
3855
  ${DIM}$${RESET} skills check
@@ -3844,6 +3943,8 @@ const AGENTS_DIR = ".agents";
3844
3943
  const LOCK_FILE = ".skill-lock.json";
3845
3944
  const CURRENT_LOCK_VERSION = 3;
3846
3945
  function getSkillLockPath() {
3946
+ const xdgStateHome = process.env.XDG_STATE_HOME;
3947
+ if (xdgStateHome) return join(xdgStateHome, "skills", LOCK_FILE);
3847
3948
  return join(homedir(), AGENTS_DIR, LOCK_FILE);
3848
3949
  }
3849
3950
  function readSkillLock() {
@@ -4061,8 +4162,9 @@ async function runUpdate() {
4061
4162
  }
4062
4163
  async function main() {
4063
4164
  const args = process.argv.slice(2);
4165
+ const inAgent = await isRunningInAgent();
4064
4166
  if (args.length === 0) {
4065
- showBanner();
4167
+ if (!inAgent) showBanner();
4066
4168
  return;
4067
4169
  }
4068
4170
  const command = args[0];
@@ -4072,24 +4174,24 @@ async function main() {
4072
4174
  case "search":
4073
4175
  case "f":
4074
4176
  case "s":
4075
- showLogo();
4177
+ if (!inAgent) showLogo();
4076
4178
  console.log();
4077
4179
  await runFind(restArgs);
4078
4180
  break;
4079
4181
  case "init":
4080
- showLogo();
4182
+ if (!inAgent) showLogo();
4081
4183
  console.log();
4082
4184
  runInit(restArgs);
4083
4185
  break;
4084
4186
  case "experimental_install":
4085
- showLogo();
4187
+ if (!inAgent) showLogo();
4086
4188
  await runInstallFromLock(restArgs);
4087
4189
  break;
4088
4190
  case "i":
4089
4191
  case "install":
4090
4192
  case "a":
4091
4193
  case "add": {
4092
- showLogo();
4194
+ if (!inAgent) showLogo();
4093
4195
  const { source: addSource, options: addOpts } = parseAddOptions(restArgs);
4094
4196
  await runAdd(addSource, addOpts);
4095
4197
  break;
@@ -4105,7 +4207,7 @@ async function main() {
4105
4207
  await removeCommand(skills, removeOptions);
4106
4208
  break;
4107
4209
  case "experimental_sync": {
4108
- showLogo();
4210
+ if (!inAgent) showLogo();
4109
4211
  const { options: syncOptions } = parseSyncOptions(restArgs);
4110
4212
  await runSync(restArgs, syncOptions);
4111
4213
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skills",
3
- "version": "1.4.4",
3
+ "version": "1.4.5-snapshot.2",
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",
@@ -92,6 +93,7 @@
92
93
  "@clack/prompts": "^0.11.0",
93
94
  "@types/bun": "latest",
94
95
  "@types/node": "^22.10.0",
96
+ "@vercel/detect-agent": "^1.2.1",
95
97
  "gray-matter": "^4.0.3",
96
98
  "husky": "^9.1.7",
97
99
  "lint-staged": "^16.2.7",