@empjs/skill 1.0.5 → 1.0.7

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/dist/index.cjs CHANGED
@@ -23,87 +23,27 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
23
  mod
24
24
  ));
25
25
 
26
- // node_modules/tsup/assets/cjs_shims.js
26
+ // ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/cjs_shims.js
27
27
  var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
28
28
  var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
29
29
 
30
30
  // src/index.ts
31
31
  var import_commander = require("commander");
32
32
  var import_fs = require("fs");
33
- var import_url = require("url");
34
33
  var import_path = require("path");
34
+ var import_url = require("url");
35
35
 
36
- // src/commands/install.ts
37
- var import_node_child_process2 = require("child_process");
38
- var import_node_util2 = require("util");
39
- var import_node_fs4 = __toESM(require("fs"), 1);
40
- var import_node_path5 = __toESM(require("path"), 1);
36
+ // src/commands/agents.ts
37
+ var import_node_fs2 = __toESM(require("fs"), 1);
41
38
  var import_node_os2 = __toESM(require("os"), 1);
42
-
43
- // src/utils/logger.ts
44
39
  var import_chalk = __toESM(require("chalk"), 1);
45
- var import_ora = __toESM(require("ora"), 1);
46
- var Logger = class {
47
- spinner = null;
48
- info(message) {
49
- if (this.spinner) this.spinner.stop();
50
- console.log(import_chalk.default.blue("\u2139"), message);
51
- }
52
- success(message) {
53
- if (this.spinner) this.spinner.stop();
54
- console.log(import_chalk.default.green("\u2713"), message);
55
- }
56
- warn(message) {
57
- if (this.spinner) this.spinner.stop();
58
- console.log(import_chalk.default.yellow("\u26A0"), message);
59
- }
60
- error(message) {
61
- if (this.spinner) this.spinner.stop();
62
- console.log(import_chalk.default.red("\u2717"), message);
63
- }
64
- start(message) {
65
- if (this.spinner) this.spinner.stop();
66
- this.spinner = (0, import_ora.default)(message).start();
67
- return this.spinner;
68
- }
69
- stopSpinner() {
70
- if (this.spinner) {
71
- this.spinner.stop();
72
- this.spinner = null;
73
- }
74
- }
75
- /**
76
- * Update spinner text without stopping it
77
- */
78
- updateSpinner(message) {
79
- if (this.spinner) {
80
- this.spinner.text = message;
81
- }
82
- }
83
- /**
84
- * Log info without stopping spinner (for background info)
85
- */
86
- infoWithoutStop(message) {
87
- if (this.spinner) {
88
- const currentText = this.spinner.text;
89
- this.spinner.stop();
90
- console.log(import_chalk.default.blue("\u2139"), message);
91
- this.spinner.start(currentText);
92
- } else {
93
- console.log(import_chalk.default.blue("\u2139"), message);
94
- }
95
- }
96
- };
97
- var logger = new Logger();
98
-
99
- // src/utils/paths.ts
100
- var import_node_fs = __toESM(require("fs"), 1);
101
- var import_node_path2 = __toESM(require("path"), 1);
102
40
 
103
41
  // src/config/agents.ts
42
+ var import_node_fs = __toESM(require("fs"), 1);
104
43
  var import_node_os = __toESM(require("os"), 1);
105
44
  var import_node_path = __toESM(require("path"), 1);
106
45
  var HOME = import_node_os.default.homedir();
46
+ var CONFIG_HOME = process.env.XDG_CONFIG_HOME || import_node_path.default.join(HOME, ".config");
107
47
  function getAgentSkillsDirs(agent, cwd) {
108
48
  if (agent.skillsDirs) {
109
49
  if (typeof agent.skillsDirs === "function") {
@@ -118,21 +58,44 @@ function getAgentSkillsDirs(agent, cwd) {
118
58
  }
119
59
  var AGENTS = [
120
60
  {
121
- name: "claude",
122
- displayName: "Claude Code",
123
- skillsDir: import_node_path.default.join(HOME, ".claude", "skills"),
61
+ name: "amp",
62
+ displayName: "AMP",
63
+ skillsDirs: (cwd) => {
64
+ const dirs = [import_node_path.default.join(CONFIG_HOME, "agents", "skills")];
65
+ if (cwd) dirs.push(import_node_path.default.join(cwd, ".agents", "skills"));
66
+ return dirs;
67
+ },
124
68
  enabled: true
125
69
  },
126
70
  {
127
- name: "cursor",
128
- displayName: "Cursor",
129
- skillsDir: import_node_path.default.join(HOME, ".cursor", "skills"),
71
+ name: "antigravity",
72
+ displayName: "Antigravity",
73
+ skillsDirs: (cwd) => {
74
+ const dirs = [import_node_path.default.join(HOME, ".gemini", "antigravity", "skills")];
75
+ if (cwd) dirs.push(import_node_path.default.join(cwd, ".agent", "skills"));
76
+ if (cwd) dirs.push(import_node_path.default.join(cwd, ".shared", "skills"));
77
+ return dirs;
78
+ },
130
79
  enabled: true
131
80
  },
132
81
  {
133
- name: "windsurf",
134
- displayName: "Windsurf",
135
- skillsDir: import_node_path.default.join(HOME, ".windsurf", "skills"),
82
+ name: "claude",
83
+ displayName: "Claude Code",
84
+ skillsDir: import_node_path.default.join(process.env.CLAUDE_CONFIG_DIR?.trim() || import_node_path.default.join(HOME, ".claude"), "skills"),
85
+ enabled: true
86
+ },
87
+ {
88
+ name: "clawdbot",
89
+ displayName: "ClawdBot",
90
+ skillsDirs: () => {
91
+ const openclaw = import_node_path.default.join(HOME, ".openclaw", "skills");
92
+ const clawdbot = import_node_path.default.join(HOME, ".clawdbot", "skills");
93
+ const moltbot = import_node_path.default.join(HOME, ".moltbot", "skills");
94
+ if (import_node_fs.default.existsSync(import_node_path.default.join(HOME, ".openclaw"))) return [openclaw];
95
+ if (import_node_fs.default.existsSync(import_node_path.default.join(HOME, ".clawdbot"))) return [clawdbot];
96
+ if (import_node_fs.default.existsSync(import_node_path.default.join(HOME, ".moltbot"))) return [moltbot];
97
+ return [openclaw];
98
+ },
136
99
  enabled: true
137
100
  },
138
101
  {
@@ -141,9 +104,27 @@ var AGENTS = [
141
104
  skillsDir: import_node_path.default.join(HOME, ".cline", "skills"),
142
105
  enabled: true
143
106
  },
107
+ {
108
+ name: "codex",
109
+ displayName: "Codex",
110
+ skillsDir: import_node_path.default.join(process.env.CODEX_HOME?.trim() || import_node_path.default.join(HOME, ".codex"), "skills"),
111
+ enabled: true
112
+ },
113
+ {
114
+ name: "cursor",
115
+ displayName: "Cursor",
116
+ skillsDir: import_node_path.default.join(HOME, ".cursor", "skills"),
117
+ enabled: true
118
+ },
119
+ {
120
+ name: "droid",
121
+ displayName: "Droid",
122
+ skillsDir: import_node_path.default.join(HOME, ".factory", "skills"),
123
+ enabled: true
124
+ },
144
125
  {
145
126
  name: "gemini",
146
- displayName: "Gemini Code",
127
+ displayName: "Gemini",
147
128
  skillsDir: import_node_path.default.join(HOME, ".gemini", "skills"),
148
129
  enabled: true
149
130
  },
@@ -154,47 +135,31 @@ var AGENTS = [
154
135
  enabled: true
155
136
  },
156
137
  {
157
- name: "opencode",
158
- displayName: "OpenCode",
159
- skillsDir: import_node_path.default.join(HOME, ".opencode", "skills"),
138
+ name: "goose",
139
+ displayName: "Goose",
140
+ skillsDir: import_node_path.default.join(CONFIG_HOME, "goose", "skills"),
160
141
  enabled: true
161
142
  },
162
143
  {
163
- name: "antigravity",
164
- displayName: "Antigravity",
165
- skillsDirs: (cwd) => {
166
- const dirs = [];
167
- dirs.push(import_node_path.default.join(HOME, ".gemini", "antigravity", "skills"));
168
- if (cwd) {
169
- dirs.push(import_node_path.default.join(cwd, ".agent", "skills"));
170
- }
171
- if (cwd) {
172
- dirs.push(import_node_path.default.join(cwd, ".shared", "skills"));
173
- }
174
- return dirs;
175
- },
144
+ name: "kilo",
145
+ displayName: "Kilo Code",
146
+ skillsDir: import_node_path.default.join(HOME, ".kilocode", "skills"),
176
147
  enabled: true
177
148
  },
178
149
  {
179
150
  name: "kiro",
180
- displayName: "Kiro",
151
+ displayName: "Kiro CLI",
181
152
  skillsDir: import_node_path.default.join(HOME, ".kiro", "skills"),
182
153
  enabled: true
183
154
  },
184
155
  {
185
- name: "codex",
186
- displayName: "Codex CLI",
187
- skillsDir: import_node_path.default.join(HOME, ".codex", "skills"),
188
- enabled: true
189
- },
190
- {
191
- name: "qoder",
192
- displayName: "Qoder",
193
- skillsDir: import_node_path.default.join(HOME, ".qoder", "skills"),
156
+ name: "opencode",
157
+ displayName: "OpenCode",
158
+ skillsDir: import_node_path.default.join(CONFIG_HOME, "opencode", "skills"),
194
159
  enabled: true
195
160
  },
196
161
  {
197
- name: "roocode",
162
+ name: "roo",
198
163
  displayName: "Roo Code",
199
164
  skillsDir: import_node_path.default.join(HOME, ".roo", "skills"),
200
165
  enabled: true
@@ -205,18 +170,246 @@ var AGENTS = [
205
170
  skillsDir: import_node_path.default.join(HOME, ".trae", "skills"),
206
171
  enabled: true
207
172
  },
173
+ {
174
+ name: "windsurf",
175
+ displayName: "Windsurf",
176
+ skillsDirs: () => {
177
+ const dirs = [];
178
+ dirs.push(import_node_path.default.join(HOME, ".windsurf", "skills"));
179
+ dirs.push(import_node_path.default.join(HOME, ".codeium", "windsurf", "skills"));
180
+ return dirs;
181
+ },
182
+ enabled: true
183
+ },
184
+ // Additional agents
185
+ {
186
+ name: "qoder",
187
+ displayName: "Qoder",
188
+ skillsDir: import_node_path.default.join(HOME, ".qoder", "skills"),
189
+ enabled: true
190
+ },
208
191
  {
209
192
  name: "continue",
210
193
  displayName: "Continue",
211
194
  skillsDir: import_node_path.default.join(HOME, ".continue", "skills"),
212
195
  enabled: true
213
196
  }
214
- ];
215
- var SHARED_SKILLS_DIR = import_node_path.default.join(HOME, ".emp-agent", "skills");
216
- var CONFIG_FILE = import_node_path.default.join(HOME, ".emp-agent", "config.json");
217
- var CACHE_DIR = import_node_path.default.join(HOME, ".emp-agent", "cache");
197
+ ];
198
+ var SHARED_SKILLS_DIR = import_node_path.default.join(HOME, ".emp-agent", "skills");
199
+ var CONFIG_FILE = import_node_path.default.join(HOME, ".emp-agent", "config.json");
200
+ var CACHE_DIR = import_node_path.default.join(HOME, ".emp-agent", "cache");
201
+
202
+ // src/commands/agents.ts
203
+ function agents() {
204
+ const cwd = process.cwd();
205
+ console.log(import_chalk.default.bold("\n\u{1F4CB} Supported AI Agents:\n"));
206
+ for (const agent of AGENTS) {
207
+ const skillsDirs = getAgentSkillsDirs(agent, cwd);
208
+ const dirsInfo = skillsDirs.length > 1 ? ` (${skillsDirs.length} directories)` : "";
209
+ console.log(import_chalk.default.bold(agent.displayName));
210
+ console.log(import_chalk.default.gray(` Name: ${agent.name}`));
211
+ if (skillsDirs.length === 0) {
212
+ console.log(import_chalk.default.yellow(" \u26A0\uFE0F No directories configured"));
213
+ } else {
214
+ console.log(import_chalk.default.gray(` Directories${dirsInfo}:`));
215
+ for (const dir of skillsDirs) {
216
+ const exists = import_node_fs2.default.existsSync(dir);
217
+ const status = exists ? import_chalk.default.green("\u2713") : import_chalk.default.gray("\u25CB");
218
+ const pathColor = exists ? import_chalk.default.white : import_chalk.default.gray;
219
+ console.log(` ${status} ${pathColor(dir)}`);
220
+ }
221
+ }
222
+ console.log("");
223
+ }
224
+ console.log(import_chalk.default.bold("\u{1F4E6} Shared Skills Directory:"));
225
+ const sharedExists = import_node_fs2.default.existsSync(SHARED_SKILLS_DIR);
226
+ const sharedStatus = sharedExists ? import_chalk.default.green("\u2713") : import_chalk.default.gray("\u25CB");
227
+ const sharedPathColor = sharedExists ? import_chalk.default.white : import_chalk.default.gray;
228
+ console.log(` ${sharedStatus} ${sharedPathColor(SHARED_SKILLS_DIR)}`);
229
+ console.log("");
230
+ const home = import_node_os2.default.homedir();
231
+ if (cwd !== home) {
232
+ console.log(import_chalk.default.gray(`Current working directory: ${cwd}`));
233
+ console.log(import_chalk.default.gray("(Project-level directories are shown above)\n"));
234
+ }
235
+ }
236
+
237
+ // src/commands/install.ts
238
+ var import_node_child_process2 = require("child_process");
239
+ var import_node_fs6 = __toESM(require("fs"), 1);
240
+ var import_node_os3 = __toESM(require("os"), 1);
241
+ var import_node_path5 = __toESM(require("path"), 1);
242
+ var import_node_util2 = require("util");
243
+
244
+ // src/utils/git.ts
245
+ function parseGitUrl(url) {
246
+ const githubPatterns = [
247
+ // https://github.com/owner/repo/tree/branch/path/to/dir
248
+ /^https?:\/\/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)(?:\/(.+))?$/,
249
+ // https://github.com/owner/repo
250
+ /^https?:\/\/github\.com\/([^/]+)\/([^/]+)(?:\/)?$/,
251
+ // git@github.com:owner/repo.git
252
+ /^git@github\.com:([^/]+)\/([^/]+)(?:\.git)?$/
253
+ ];
254
+ const gitlabPatterns = [
255
+ // https://host/group/repo/-/tree/branch/path (self-hosted + gitlab.com)
256
+ /^https?:\/\/([^/]+)\/(.+)\/-\/tree\/([^/]+)(?:\/(.+))?$/,
257
+ // https://gitlab.com/owner/repo
258
+ /^https?:\/\/gitlab\.com\/([^/]+)\/([^/]+)(?:\/)?$/,
259
+ // git@gitlab.com:owner/repo.git or git@host:group/repo.git
260
+ /^git@([^:]+):(.+)(?:\.git)?$/
261
+ ];
262
+ for (let i = 0; i < githubPatterns.length; i++) {
263
+ const pattern = githubPatterns[i];
264
+ const match = url.match(pattern);
265
+ if (match) {
266
+ const owner = match[1];
267
+ const repo = match[2].replace(/\.git$/, "");
268
+ let branch;
269
+ let path7;
270
+ if (i === 0) {
271
+ branch = match[3];
272
+ path7 = match[4];
273
+ } else if (i === 1) {
274
+ branch = "main";
275
+ } else {
276
+ branch = "main";
277
+ }
278
+ const gitUrl = `https://github.com/${owner}/${repo}.git`;
279
+ return {
280
+ type: "github",
281
+ owner,
282
+ repo,
283
+ branch,
284
+ path: path7,
285
+ gitUrl,
286
+ installUrl: gitUrl
287
+ // Will be used for git clone
288
+ };
289
+ }
290
+ }
291
+ for (let i = 0; i < gitlabPatterns.length; i++) {
292
+ const pattern = gitlabPatterns[i];
293
+ const match = url.match(pattern);
294
+ if (match) {
295
+ let owner;
296
+ let repo;
297
+ let branch;
298
+ let path7;
299
+ let gitUrl;
300
+ if (i === 0) {
301
+ const host = match[1];
302
+ const repoPath = match[2].replace(/\.git$/, "");
303
+ branch = match[3];
304
+ path7 = match[4];
305
+ const parts = repoPath.split("/");
306
+ repo = parts.pop() || repoPath;
307
+ owner = parts.join("/") || repo;
308
+ gitUrl = `https://${host}/${repoPath}.git`;
309
+ } else if (i === 1) {
310
+ owner = match[1];
311
+ repo = match[2].replace(/\.git$/, "");
312
+ branch = "main";
313
+ gitUrl = `https://gitlab.com/${owner}/${repo}.git`;
314
+ } else {
315
+ const host = match[1];
316
+ const repoPath = match[2].replace(/\.git$/, "");
317
+ branch = "main";
318
+ const parts = repoPath.split("/");
319
+ repo = parts.pop() || repoPath;
320
+ owner = parts.join("/") || repo;
321
+ gitUrl = `https://${host}/${repoPath}.git`;
322
+ }
323
+ return {
324
+ type: "gitlab",
325
+ owner,
326
+ repo,
327
+ branch,
328
+ path: path7,
329
+ gitUrl,
330
+ installUrl: gitUrl
331
+ };
332
+ }
333
+ }
334
+ if (url.startsWith("git+") || url.startsWith("git://")) {
335
+ return {
336
+ type: "other",
337
+ owner: "",
338
+ repo: "",
339
+ gitUrl: url.replace(/^git\+/, ""),
340
+ installUrl: url.startsWith("git+") ? url : `git+${url}`
341
+ };
342
+ }
343
+ return null;
344
+ }
345
+ function isGitUrl(str) {
346
+ return str.includes("github.com") || str.includes("gitlab.com") || str.includes("/-/tree/") || // GitLab web URL pattern (self-hosted)
347
+ str.startsWith("git@") || str.startsWith("git+") || str.startsWith("git://");
348
+ }
349
+
350
+ // src/utils/logger.ts
351
+ var import_chalk2 = __toESM(require("chalk"), 1);
352
+ var import_ora = __toESM(require("ora"), 1);
353
+ var Logger = class {
354
+ spinner = null;
355
+ info(message) {
356
+ if (this.spinner) this.spinner.stop();
357
+ console.log(import_chalk2.default.blue("\u2139"), message);
358
+ }
359
+ success(message) {
360
+ if (this.spinner) this.spinner.stop();
361
+ console.log(import_chalk2.default.green("\u2713"), message);
362
+ }
363
+ warn(message) {
364
+ if (this.spinner) this.spinner.stop();
365
+ console.log(import_chalk2.default.yellow("\u26A0"), message);
366
+ }
367
+ error(message) {
368
+ if (this.spinner) this.spinner.stop();
369
+ console.log(import_chalk2.default.red("\u2717"), message);
370
+ }
371
+ dim(message) {
372
+ if (this.spinner) this.spinner.stop();
373
+ console.log(import_chalk2.default.dim(" " + message));
374
+ }
375
+ start(message) {
376
+ if (this.spinner) this.spinner.stop();
377
+ this.spinner = (0, import_ora.default)(message).start();
378
+ return this.spinner;
379
+ }
380
+ stopSpinner() {
381
+ if (this.spinner) {
382
+ this.spinner.stop();
383
+ this.spinner = null;
384
+ }
385
+ }
386
+ /**
387
+ * Update spinner text without stopping it
388
+ */
389
+ updateSpinner(message) {
390
+ if (this.spinner) {
391
+ this.spinner.text = message;
392
+ }
393
+ }
394
+ /**
395
+ * Log info without stopping spinner (for background info)
396
+ */
397
+ infoWithoutStop(message) {
398
+ if (this.spinner) {
399
+ const currentText = this.spinner.text;
400
+ this.spinner.stop();
401
+ console.log(import_chalk2.default.blue("\u2139"), message);
402
+ this.spinner.start(currentText);
403
+ } else {
404
+ console.log(import_chalk2.default.blue("\u2139"), message);
405
+ }
406
+ }
407
+ };
408
+ var logger = new Logger();
218
409
 
219
410
  // src/utils/paths.ts
411
+ var import_node_fs3 = __toESM(require("fs"), 1);
412
+ var import_node_path2 = __toESM(require("path"), 1);
220
413
  function getSharedSkillPath(skillName) {
221
414
  return import_node_path2.default.join(SHARED_SKILLS_DIR, skillName);
222
415
  }
@@ -229,8 +422,8 @@ function getAgentSkillPaths(agentName, skillName, cwd) {
229
422
  return skillsDirs.map((dir) => import_node_path2.default.join(dir, skillName));
230
423
  }
231
424
  function ensureSharedDir() {
232
- if (!import_node_fs.default.existsSync(SHARED_SKILLS_DIR)) {
233
- import_node_fs.default.mkdirSync(SHARED_SKILLS_DIR, { recursive: true });
425
+ if (!import_node_fs3.default.existsSync(SHARED_SKILLS_DIR)) {
426
+ import_node_fs3.default.mkdirSync(SHARED_SKILLS_DIR, { recursive: true });
234
427
  }
235
428
  }
236
429
  function detectInstalledAgents(cwd) {
@@ -238,7 +431,7 @@ function detectInstalledAgents(cwd) {
238
431
  try {
239
432
  const skillsDirs = getAgentSkillsDirs(agent, cwd);
240
433
  return skillsDirs.some((dir) => {
241
- return import_node_fs.default.existsSync(dir) || import_node_fs.default.existsSync(import_node_path2.default.dirname(dir));
434
+ return import_node_fs3.default.existsSync(dir) || import_node_fs3.default.existsSync(import_node_path2.default.dirname(dir));
242
435
  });
243
436
  } catch {
244
437
  return false;
@@ -257,32 +450,93 @@ function extractSkillName(nameOrPath) {
257
450
  return import_node_path2.default.basename(nameOrPath);
258
451
  }
259
452
 
260
- // src/utils/symlink.ts
261
- var import_node_fs2 = __toESM(require("fs"), 1);
453
+ // src/utils/registry.ts
454
+ var import_node_child_process = require("child_process");
455
+ var import_node_fs4 = __toESM(require("fs"), 1);
262
456
  var import_node_path3 = __toESM(require("path"), 1);
457
+ var import_node_util = require("util");
458
+ var execAsync = (0, import_node_util.promisify)(import_node_child_process.exec);
459
+ function findNpmrc(startDir) {
460
+ let currentDir = import_node_path3.default.resolve(startDir);
461
+ while (currentDir !== import_node_path3.default.dirname(currentDir)) {
462
+ const npmrcPath = import_node_path3.default.join(currentDir, ".npmrc");
463
+ if (import_node_fs4.default.existsSync(npmrcPath)) {
464
+ return npmrcPath;
465
+ }
466
+ currentDir = import_node_path3.default.dirname(currentDir);
467
+ }
468
+ return null;
469
+ }
470
+ function parseNpmrc(npmrcPath) {
471
+ try {
472
+ const content = import_node_fs4.default.readFileSync(npmrcPath, "utf-8");
473
+ const lines = content.split("\n");
474
+ for (const line of lines) {
475
+ const trimmed = line.trim();
476
+ if (!trimmed || trimmed.startsWith("#")) {
477
+ continue;
478
+ }
479
+ const registryMatch = trimmed.match(/^(?:@[^:]+:)?registry\s*=\s*(.+)$/);
480
+ if (registryMatch) {
481
+ return registryMatch[1].trim();
482
+ }
483
+ }
484
+ } catch (error) {
485
+ }
486
+ return null;
487
+ }
488
+ async function getGlobalRegistry() {
489
+ try {
490
+ const { stdout } = await execAsync("npm config get registry");
491
+ const registry = stdout.trim();
492
+ if (registry && registry !== "undefined") {
493
+ return registry;
494
+ }
495
+ } catch (error) {
496
+ }
497
+ return null;
498
+ }
499
+ async function getRegistry(cwd = process.cwd()) {
500
+ const npmrcPath = findNpmrc(cwd);
501
+ if (npmrcPath) {
502
+ const registry = parseNpmrc(npmrcPath);
503
+ if (registry) {
504
+ return registry;
505
+ }
506
+ }
507
+ const globalRegistry = await getGlobalRegistry();
508
+ if (globalRegistry) {
509
+ return globalRegistry;
510
+ }
511
+ return "https://registry.npmjs.org/";
512
+ }
513
+
514
+ // src/utils/symlink.ts
515
+ var import_node_fs5 = __toESM(require("fs"), 1);
516
+ var import_node_path4 = __toESM(require("path"), 1);
263
517
  function createSymlink(skillName, agent, cwd) {
264
518
  const source = getSharedSkillPath(skillName);
265
- if (!import_node_fs2.default.existsSync(source)) {
519
+ if (!import_node_fs5.default.existsSync(source)) {
266
520
  logger.error(`Skill not found: ${source}`);
267
521
  return false;
268
522
  }
269
523
  const targets = getAgentSkillPaths(agent.name, skillName, cwd);
270
524
  let successCount = 0;
271
525
  for (const target of targets) {
272
- const targetDir = import_node_path3.default.dirname(target);
273
- if (!import_node_fs2.default.existsSync(targetDir)) {
526
+ const targetDir = import_node_path4.default.dirname(target);
527
+ if (!import_node_fs5.default.existsSync(targetDir)) {
274
528
  try {
275
- import_node_fs2.default.mkdirSync(targetDir, { recursive: true });
529
+ import_node_fs5.default.mkdirSync(targetDir, { recursive: true });
276
530
  } catch (error) {
277
531
  logger.error(`Failed to create directory ${targetDir}: ${error.message}`);
278
532
  continue;
279
533
  }
280
534
  }
281
- if (import_node_fs2.default.existsSync(target)) {
535
+ if (import_node_fs5.default.existsSync(target)) {
282
536
  try {
283
- const stats = import_node_fs2.default.lstatSync(target);
537
+ const stats = import_node_fs5.default.lstatSync(target);
284
538
  if (stats.isSymbolicLink()) {
285
- import_node_fs2.default.unlinkSync(target);
539
+ import_node_fs5.default.unlinkSync(target);
286
540
  } else {
287
541
  logger.warn(`Target exists but is not a symlink, skipping: ${target}`);
288
542
  continue;
@@ -293,7 +547,7 @@ function createSymlink(skillName, agent, cwd) {
293
547
  }
294
548
  }
295
549
  try {
296
- import_node_fs2.default.symlinkSync(source, target, "dir");
550
+ import_node_fs5.default.symlinkSync(source, target, "dir");
297
551
  successCount++;
298
552
  } catch (error) {
299
553
  logger.error(`Failed to create symlink at ${target}: ${error.message}`);
@@ -310,13 +564,13 @@ function removeSymlink(skillName, agent, cwd) {
310
564
  const targets = getAgentSkillPaths(agent.name, skillName, cwd);
311
565
  let removedCount = 0;
312
566
  for (const target of targets) {
313
- if (!import_node_fs2.default.existsSync(target)) {
567
+ if (!import_node_fs5.default.existsSync(target)) {
314
568
  continue;
315
569
  }
316
570
  try {
317
- const stats = import_node_fs2.default.lstatSync(target);
571
+ const stats = import_node_fs5.default.lstatSync(target);
318
572
  if (stats.isSymbolicLink()) {
319
- import_node_fs2.default.unlinkSync(target);
573
+ import_node_fs5.default.unlinkSync(target);
320
574
  removedCount++;
321
575
  } else {
322
576
  logger.warn(`Not a symlink: ${target}`);
@@ -334,7 +588,7 @@ function removeSymlink(skillName, agent, cwd) {
334
588
  }
335
589
  function isSymlink(filePath) {
336
590
  try {
337
- const stats = import_node_fs2.default.lstatSync(filePath);
591
+ const stats = import_node_fs5.default.lstatSync(filePath);
338
592
  return stats.isSymbolicLink();
339
593
  } catch {
340
594
  return false;
@@ -342,164 +596,12 @@ function isSymlink(filePath) {
342
596
  }
343
597
  function readSymlink(filePath) {
344
598
  try {
345
- return import_node_fs2.default.readlinkSync(filePath);
599
+ return import_node_fs5.default.readlinkSync(filePath);
346
600
  } catch {
347
601
  return null;
348
602
  }
349
603
  }
350
604
 
351
- // src/utils/registry.ts
352
- var import_node_child_process = require("child_process");
353
- var import_node_util = require("util");
354
- var import_node_fs3 = __toESM(require("fs"), 1);
355
- var import_node_path4 = __toESM(require("path"), 1);
356
- var execAsync = (0, import_node_util.promisify)(import_node_child_process.exec);
357
- function findNpmrc(startDir) {
358
- let currentDir = import_node_path4.default.resolve(startDir);
359
- while (currentDir !== import_node_path4.default.dirname(currentDir)) {
360
- const npmrcPath = import_node_path4.default.join(currentDir, ".npmrc");
361
- if (import_node_fs3.default.existsSync(npmrcPath)) {
362
- return npmrcPath;
363
- }
364
- currentDir = import_node_path4.default.dirname(currentDir);
365
- }
366
- return null;
367
- }
368
- function parseNpmrc(npmrcPath) {
369
- try {
370
- const content = import_node_fs3.default.readFileSync(npmrcPath, "utf-8");
371
- const lines = content.split("\n");
372
- for (const line of lines) {
373
- const trimmed = line.trim();
374
- if (!trimmed || trimmed.startsWith("#")) {
375
- continue;
376
- }
377
- const registryMatch = trimmed.match(/^(?:@[^:]+:)?registry\s*=\s*(.+)$/);
378
- if (registryMatch) {
379
- return registryMatch[1].trim();
380
- }
381
- }
382
- } catch (error) {
383
- }
384
- return null;
385
- }
386
- async function getGlobalRegistry() {
387
- try {
388
- const { stdout } = await execAsync("npm config get registry");
389
- const registry = stdout.trim();
390
- if (registry && registry !== "undefined") {
391
- return registry;
392
- }
393
- } catch (error) {
394
- }
395
- return null;
396
- }
397
- async function getRegistry(cwd = process.cwd()) {
398
- const npmrcPath = findNpmrc(cwd);
399
- if (npmrcPath) {
400
- const registry = parseNpmrc(npmrcPath);
401
- if (registry) {
402
- return registry;
403
- }
404
- }
405
- const globalRegistry = await getGlobalRegistry();
406
- if (globalRegistry) {
407
- return globalRegistry;
408
- }
409
- return "https://registry.npmjs.org/";
410
- }
411
-
412
- // src/utils/git.ts
413
- function parseGitUrl(url) {
414
- const githubPatterns = [
415
- // https://github.com/owner/repo/tree/branch/path/to/dir
416
- /^https?:\/\/github\.com\/([^\/]+)\/([^\/]+)\/tree\/([^\/]+)(?:\/(.+))?$/,
417
- // https://github.com/owner/repo
418
- /^https?:\/\/github\.com\/([^\/]+)\/([^\/]+)(?:\/)?$/,
419
- // git@github.com:owner/repo.git
420
- /^git@github\.com:([^\/]+)\/([^\/]+)(?:\.git)?$/
421
- ];
422
- const gitlabPatterns = [
423
- // https://gitlab.com/owner/repo/-/tree/branch/path/to/dir
424
- /^https?:\/\/gitlab\.com\/([^\/]+)\/([^\/]+)\/-\/tree\/([^\/]+)(?:\/(.+))?$/,
425
- // https://gitlab.com/owner/repo
426
- /^https?:\/\/gitlab\.com\/([^\/]+)\/([^\/]+)(?:\/)?$/,
427
- // git@gitlab.com:owner/repo.git
428
- /^git@gitlab\.com:([^\/]+)\/([^\/]+)(?:\.git)?$/
429
- ];
430
- for (let i = 0; i < githubPatterns.length; i++) {
431
- const pattern = githubPatterns[i];
432
- const match = url.match(pattern);
433
- if (match) {
434
- const owner = match[1];
435
- const repo = match[2].replace(/\.git$/, "");
436
- let branch;
437
- let path7;
438
- if (i === 0) {
439
- branch = match[3];
440
- path7 = match[4];
441
- } else if (i === 1) {
442
- branch = "main";
443
- } else {
444
- branch = "main";
445
- }
446
- const gitUrl = `https://github.com/${owner}/${repo}.git`;
447
- return {
448
- type: "github",
449
- owner,
450
- repo,
451
- branch,
452
- path: path7,
453
- gitUrl,
454
- installUrl: gitUrl
455
- // Will be used for git clone
456
- };
457
- }
458
- }
459
- for (let i = 0; i < gitlabPatterns.length; i++) {
460
- const pattern = gitlabPatterns[i];
461
- const match = url.match(pattern);
462
- if (match) {
463
- const owner = match[1];
464
- const repo = match[2].replace(/\.git$/, "");
465
- let branch;
466
- let path7;
467
- if (i === 0) {
468
- branch = match[3];
469
- path7 = match[4];
470
- } else if (i === 1) {
471
- branch = "main";
472
- } else {
473
- branch = "main";
474
- }
475
- const gitUrl = `https://gitlab.com/${owner}/${repo}.git`;
476
- return {
477
- type: "gitlab",
478
- owner,
479
- repo,
480
- branch,
481
- path: path7,
482
- gitUrl,
483
- installUrl: gitUrl
484
- // Will be used for git clone
485
- };
486
- }
487
- }
488
- if (url.startsWith("git+") || url.startsWith("git://")) {
489
- return {
490
- type: "other",
491
- owner: "",
492
- repo: "",
493
- gitUrl: url.replace(/^git\+/, ""),
494
- installUrl: url.startsWith("git+") ? url : `git+${url}`
495
- };
496
- }
497
- return null;
498
- }
499
- function isGitUrl(str) {
500
- return str.includes("github.com") || str.includes("gitlab.com") || str.startsWith("git@") || str.startsWith("git+") || str.startsWith("git://");
501
- }
502
-
503
605
  // src/commands/install.ts
504
606
  var execAsync2 = (0, import_node_util2.promisify)(import_node_child_process2.exec);
505
607
  async function execWithTimeout(command, timeout = 12e4, env) {
@@ -511,10 +613,7 @@ async function execWithTimeout(command, timeout = 12e4, env) {
511
613
  });
512
614
  try {
513
615
  const execOptions = env ? { env } : {};
514
- const result = await Promise.race([
515
- execAsync2(command, execOptions),
516
- timeoutPromise
517
- ]);
616
+ const result = await Promise.race([execAsync2(command, execOptions), timeoutPromise]);
518
617
  if (timeoutId) {
519
618
  clearTimeout(timeoutId);
520
619
  }
@@ -526,12 +625,25 @@ async function execWithTimeout(command, timeout = 12e4, env) {
526
625
  throw error;
527
626
  }
528
627
  }
628
+ function shortenPath(p) {
629
+ const home = import_node_os3.default.homedir();
630
+ return p.startsWith(home) ? p.replace(home, "~") : p;
631
+ }
529
632
  async function install(skillNameOrPath, options = {}) {
530
- logger.info(`Installing skill: ${skillNameOrPath}`);
633
+ const isGit = isGitUrl(skillNameOrPath);
634
+ if (isGit) {
635
+ logger.info("Installing from Git URL");
636
+ logger.dim(skillNameOrPath);
637
+ } else {
638
+ logger.info(`Installing skill: ${skillNameOrPath}`);
639
+ }
531
640
  ensureSharedDir();
532
641
  let skillPath;
533
642
  let skillName;
534
- if (isGitUrl(skillNameOrPath)) {
643
+ if (process.env.DEBUG_ESKILL) {
644
+ logger.dim(`[DEBUG] isGitUrl=${isGit}, parseGitUrl=${parseGitUrl(skillNameOrPath) ? "ok" : "null"}`);
645
+ }
646
+ if (isGit) {
535
647
  const gitInfo = parseGitUrl(skillNameOrPath);
536
648
  if (!gitInfo) {
537
649
  logger.error(`Invalid git URL: ${skillNameOrPath}`);
@@ -543,21 +655,17 @@ async function install(skillNameOrPath, options = {}) {
543
655
  const cloneDir = import_node_path5.default.join(tempDir, "repo");
544
656
  try {
545
657
  const timeout = options.timeout || 12e4;
546
- const spinner = logger.start(`Cloning ${gitInfo.gitUrl}...`);
547
- logger.infoWithoutStop(`Repository: ${gitInfo.gitUrl}`);
548
- if (gitInfo.branch) {
549
- logger.infoWithoutStop(`Branch: ${gitInfo.branch}`);
550
- }
551
- if (gitInfo.path) {
552
- logger.infoWithoutStop(`Path: ${gitInfo.path}`);
553
- }
554
- logger.infoWithoutStop(`Timeout: ${timeout / 1e3}s`);
555
- import_node_fs4.default.mkdirSync(tempDir, { recursive: true });
658
+ const gitDetails = [`${gitInfo.gitUrl}`];
659
+ if (gitInfo.branch) gitDetails.push(`branch: ${gitInfo.branch}`);
660
+ if (gitInfo.path) gitDetails.push(`path: ${gitInfo.path}`);
661
+ logger.dim(gitDetails.join(" \xB7 "));
662
+ const spinner = logger.start(`Cloning...`);
663
+ import_node_fs6.default.mkdirSync(tempDir, { recursive: true });
556
664
  const branchFlag = gitInfo.branch ? `-b ${gitInfo.branch}` : "";
557
665
  const cloneCommand = branchFlag ? `git clone ${branchFlag} ${gitInfo.gitUrl} ${cloneDir} --depth 1 --quiet` : `git clone ${gitInfo.gitUrl} ${cloneDir} --depth 1 --quiet`;
558
666
  try {
559
667
  await execWithTimeout(cloneCommand, timeout);
560
- spinner.succeed(`Repository cloned successfully`);
668
+ spinner.succeed(`Cloned successfully`);
561
669
  } catch (error) {
562
670
  spinner.fail("Clone failed");
563
671
  if (error.message.includes("timeout")) {
@@ -574,7 +682,7 @@ async function install(skillNameOrPath, options = {}) {
574
682
  }
575
683
  if (gitInfo.path) {
576
684
  skillPath = import_node_path5.default.join(cloneDir, gitInfo.path);
577
- if (!import_node_fs4.default.existsSync(skillPath)) {
685
+ if (!import_node_fs6.default.existsSync(skillPath)) {
578
686
  logger.error(`Path not found in repository: ${gitInfo.path}`);
579
687
  logger.info(`Repository cloned to: ${cloneDir}`);
580
688
  process.exit(1);
@@ -583,7 +691,7 @@ async function install(skillNameOrPath, options = {}) {
583
691
  skillPath = cloneDir;
584
692
  }
585
693
  const skillMdPath = import_node_path5.default.join(skillPath, "SKILL.md");
586
- if (!import_node_fs4.default.existsSync(skillMdPath)) {
694
+ if (!import_node_fs6.default.existsSync(skillMdPath)) {
587
695
  logger.warn(`Warning: SKILL.md not found in ${skillPath}`);
588
696
  logger.info("The directory may not be a valid skill package");
589
697
  }
@@ -605,16 +713,16 @@ Tried to clone: ${gitInfo.gitUrl}`);
605
713
  }
606
714
  process.exit(1);
607
715
  }
608
- } else if (options.link || import_node_fs4.default.existsSync(skillNameOrPath)) {
716
+ } else if (options.link || import_node_fs6.default.existsSync(skillNameOrPath)) {
609
717
  skillPath = import_node_path5.default.resolve(skillNameOrPath);
610
- if (!import_node_fs4.default.existsSync(skillPath)) {
718
+ if (!import_node_fs6.default.existsSync(skillPath)) {
611
719
  logger.error(`Path not found: ${skillPath}`);
612
720
  process.exit(1);
613
721
  }
614
722
  const pkgPath = import_node_path5.default.join(skillPath, "package.json");
615
- if (import_node_fs4.default.existsSync(pkgPath)) {
723
+ if (import_node_fs6.default.existsSync(pkgPath)) {
616
724
  try {
617
- const pkg = JSON.parse(import_node_fs4.default.readFileSync(pkgPath, "utf-8"));
725
+ const pkg = JSON.parse(import_node_fs6.default.readFileSync(pkgPath, "utf-8"));
618
726
  skillName = extractSkillName(pkg.name);
619
727
  } catch {
620
728
  skillName = extractSkillName(import_node_path5.default.basename(skillPath));
@@ -631,12 +739,12 @@ Tried to clone: ${gitInfo.gitUrl}`);
631
739
  const spinner = logger.start(`Installing ${skillNameOrPath}...`);
632
740
  logger.infoWithoutStop(`Registry: ${registry}`);
633
741
  logger.infoWithoutStop(`Timeout: ${timeout / 1e3}s`);
634
- import_node_fs4.default.mkdirSync(tempDir, { recursive: true });
742
+ import_node_fs6.default.mkdirSync(tempDir, { recursive: true });
635
743
  logger.updateSpinner(`Downloading ${skillNameOrPath} from ${registry}...`);
636
- const homeDir = process.env.HOME || process.env.USERPROFILE || import_node_os2.default.homedir();
744
+ const homeDir = process.env.HOME || process.env.USERPROFILE || import_node_os3.default.homedir();
637
745
  const npmCacheDir = import_node_path5.default.join(homeDir, ".npm");
638
746
  const npmConfigPrefix = import_node_path5.default.join(homeDir, ".npm-global");
639
- import_node_fs4.default.mkdirSync(npmCacheDir, { recursive: true });
747
+ import_node_fs6.default.mkdirSync(npmCacheDir, { recursive: true });
640
748
  const installCommand = `npm install ${skillNameOrPath} --prefix ${tempDir} --registry=${registry} --no-save --silent --no-bin-links --prefer-offline`;
641
749
  const env = {
642
750
  ...process.env,
@@ -661,7 +769,9 @@ Tried to clone: ${gitInfo.gitUrl}`);
661
769
  logger.info("");
662
770
  logger.info("Suggestions:");
663
771
  logger.info(` - Try again: eskill add ${skillNameOrPath}`);
664
- logger.info(` - Use a different registry: eskill add ${skillNameOrPath} --registry=https://registry.npmjs.org/`);
772
+ logger.info(
773
+ ` - Use a different registry: eskill add ${skillNameOrPath} --registry=https://registry.npmjs.org/`
774
+ );
665
775
  logger.info(` - Increase timeout: eskill add ${skillNameOrPath} --timeout=300000`);
666
776
  } else if (errorMessage.includes("EACCES") || errorMessage.includes("permission denied") || errorMessage.includes("Permission denied")) {
667
777
  logger.error("Permission denied error detected");
@@ -700,7 +810,9 @@ Tried to clone: ${gitInfo.gitUrl}`);
700
810
  logger.info("Please check:");
701
811
  logger.info(" - Your internet connection");
702
812
  logger.info(` - Registry accessibility: ${registry}`);
703
- logger.info(` - Try a different registry: eskill add ${skillNameOrPath} --registry=https://registry.npmjs.org/`);
813
+ logger.info(
814
+ ` - Try a different registry: eskill add ${skillNameOrPath} --registry=https://registry.npmjs.org/`
815
+ );
704
816
  } else {
705
817
  logger.error(`Failed to download: ${errorMessage}`);
706
818
  logger.info("");
@@ -713,7 +825,7 @@ Tried to clone: ${gitInfo.gitUrl}`);
713
825
  process.exit(1);
714
826
  }
715
827
  skillPath = import_node_path5.default.join(tempDir, "node_modules", skillNameOrPath);
716
- if (!import_node_fs4.default.existsSync(skillPath)) {
828
+ if (!import_node_fs6.default.existsSync(skillPath)) {
717
829
  logger.error(`Failed to download package: ${skillNameOrPath}`);
718
830
  process.exit(1);
719
831
  }
@@ -723,18 +835,19 @@ Tried to clone: ${gitInfo.gitUrl}`);
723
835
  }
724
836
  }
725
837
  const targetPath = getSharedSkillPath(skillName);
726
- if (import_node_fs4.default.existsSync(targetPath)) {
838
+ if (import_node_fs6.default.existsSync(targetPath)) {
727
839
  if (options.force) {
728
840
  logger.warn("Removing existing installation...");
729
- import_node_fs4.default.rmSync(targetPath, { recursive: true, force: true });
841
+ import_node_fs6.default.rmSync(targetPath, { recursive: true, force: true });
730
842
  } else {
731
- logger.error(`Skill already exists: ${targetPath}`);
732
- logger.info("Use --force to overwrite");
843
+ logger.error(`Skill already exists`);
844
+ logger.dim(`Location: ${shortenPath(targetPath)}`);
845
+ logger.dim(`Tip: Add --force to overwrite`);
733
846
  process.exit(1);
734
847
  }
735
848
  }
736
849
  if (options.link) {
737
- import_node_fs4.default.symlinkSync(skillPath, targetPath, "dir");
850
+ import_node_fs6.default.symlinkSync(skillPath, targetPath, "dir");
738
851
  logger.success(`Linked to shared directory (dev mode)`);
739
852
  } else {
740
853
  copyDir(skillPath, targetPath);
@@ -748,21 +861,25 @@ Tried to clone: ${gitInfo.gitUrl}`);
748
861
  logger.info("Skill installed to shared directory, but not linked to any agent");
749
862
  logger.info("");
750
863
  logger.info("Supported agents:");
751
- logger.info(" - Claude Code (~/.claude/skills)");
752
- logger.info(" - Cursor (~/.cursor/skills)");
753
- logger.info(" - Windsurf (~/.windsurf/skills)");
864
+ logger.info(" AMP, Antigravity, Claude Code, ClawdBot, Cline, Codex, Cursor, Droid,");
865
+ logger.info(" Gemini, GitHub Copilot, Goose, Kilo, Kiro CLI, OpenCode, Roo, Trae, Windsurf");
866
+ logger.info("");
867
+ logger.info('Run "eskill agents" to see all agent directories');
754
868
  return;
755
869
  }
756
870
  let targetAgents = installedAgents;
757
871
  if (options.agent && options.agent !== "all") {
758
- const agent = installedAgents.find((a) => a.name === options.agent);
872
+ const agent = AGENTS.find((a) => a.name === options.agent && a.enabled);
759
873
  if (!agent) {
760
- logger.error(`Agent not installed: ${options.agent}`);
874
+ logger.error(`Unknown agent: ${options.agent}`);
761
875
  logger.info(`
762
- Installed agents: ${installedAgents.map((a) => a.name).join(", ")}`);
876
+ Supported agents: ${AGENTS.filter((a) => a.enabled).map((a) => a.name).join(", ")}`);
763
877
  process.exit(1);
764
878
  }
765
879
  targetAgents = [agent];
880
+ if (!installedAgents.find((a) => a.name === options.agent)) {
881
+ logger.info(`Note: ${agent.displayName} directory will be created if not exists`);
882
+ }
766
883
  }
767
884
  logger.info("\nCreating symlinks...");
768
885
  let successCount = 0;
@@ -780,8 +897,8 @@ Linked to ${successCount}/${targetAgents.length} agents`);
780
897
  }
781
898
  }
782
899
  function copyDir(src, dest) {
783
- import_node_fs4.default.mkdirSync(dest, { recursive: true });
784
- const entries = import_node_fs4.default.readdirSync(src, { withFileTypes: true });
900
+ import_node_fs6.default.mkdirSync(dest, { recursive: true });
901
+ const entries = import_node_fs6.default.readdirSync(src, { withFileTypes: true });
785
902
  for (const entry of entries) {
786
903
  const srcPath = import_node_path5.default.join(src, entry.name);
787
904
  const destPath = import_node_path5.default.join(dest, entry.name);
@@ -791,44 +908,44 @@ function copyDir(src, dest) {
791
908
  if (entry.isDirectory()) {
792
909
  copyDir(srcPath, destPath);
793
910
  } else {
794
- import_node_fs4.default.copyFileSync(srcPath, destPath);
911
+ import_node_fs6.default.copyFileSync(srcPath, destPath);
795
912
  }
796
913
  }
797
914
  }
798
915
 
799
916
  // src/commands/list.ts
800
- var import_node_fs5 = __toESM(require("fs"), 1);
917
+ var import_node_fs7 = __toESM(require("fs"), 1);
801
918
  var import_node_path6 = __toESM(require("path"), 1);
802
- var import_chalk2 = __toESM(require("chalk"), 1);
919
+ var import_chalk3 = __toESM(require("chalk"), 1);
803
920
  function list() {
804
- if (!import_node_fs5.default.existsSync(SHARED_SKILLS_DIR)) {
921
+ if (!import_node_fs7.default.existsSync(SHARED_SKILLS_DIR)) {
805
922
  logger.info("No skills installed");
806
923
  logger.info(`
807
- To install a skill, run: ${import_chalk2.default.cyan("eskill install <skill-name>")}`);
924
+ To install a skill, run: ${import_chalk3.default.cyan("eskill install <skill-name>")}`);
808
925
  return;
809
926
  }
810
- const skills = import_node_fs5.default.readdirSync(SHARED_SKILLS_DIR);
927
+ const skills = import_node_fs7.default.readdirSync(SHARED_SKILLS_DIR);
811
928
  if (skills.length === 0) {
812
929
  logger.info("No skills installed");
813
930
  logger.info(`
814
- To install a skill, run: ${import_chalk2.default.cyan("eskill install <skill-name>")}`);
931
+ To install a skill, run: ${import_chalk3.default.cyan("eskill install <skill-name>")}`);
815
932
  return;
816
933
  }
817
- console.log(import_chalk2.default.bold(`
934
+ console.log(import_chalk3.default.bold(`
818
935
  Installed skills in ${SHARED_SKILLS_DIR}:
819
936
  `));
820
937
  for (const skill of skills) {
821
938
  const skillPath = import_node_path6.default.join(SHARED_SKILLS_DIR, skill);
822
939
  try {
823
- const stats = import_node_fs5.default.lstatSync(skillPath);
940
+ const stats = import_node_fs7.default.lstatSync(skillPath);
824
941
  if (!stats.isDirectory() && !stats.isSymbolicLink()) {
825
942
  continue;
826
943
  }
827
944
  let version2 = "unknown";
828
945
  const pkgPath = import_node_path6.default.join(skillPath, "package.json");
829
- if (import_node_fs5.default.existsSync(pkgPath)) {
946
+ if (import_node_fs7.default.existsSync(pkgPath)) {
830
947
  try {
831
- const pkgContent = import_node_fs5.default.readFileSync(pkgPath, "utf-8");
948
+ const pkgContent = import_node_fs7.default.readFileSync(pkgPath, "utf-8");
832
949
  const pkg = JSON.parse(pkgContent);
833
950
  if (pkg.version && typeof pkg.version === "string") {
834
951
  version2 = pkg.version;
@@ -838,9 +955,9 @@ Installed skills in ${SHARED_SKILLS_DIR}:
838
955
  }
839
956
  if (version2 === "unknown") {
840
957
  const skillMdPath = import_node_path6.default.join(skillPath, "SKILL.md");
841
- if (import_node_fs5.default.existsSync(skillMdPath)) {
958
+ if (import_node_fs7.default.existsSync(skillMdPath)) {
842
959
  try {
843
- const skillMdContent = import_node_fs5.default.readFileSync(skillMdPath, "utf-8");
960
+ const skillMdContent = import_node_fs7.default.readFileSync(skillMdPath, "utf-8");
844
961
  const frontmatterMatch = skillMdContent.match(/^---\s*\n([\s\S]*?)\n---/);
845
962
  if (frontmatterMatch) {
846
963
  const frontmatter = frontmatterMatch[1];
@@ -858,8 +975,8 @@ Installed skills in ${SHARED_SKILLS_DIR}:
858
975
  const targetPath = readSymlink(skillPath);
859
976
  if (targetPath) {
860
977
  const targetPkgPath = import_node_path6.default.join(targetPath, "package.json");
861
- if (import_node_fs5.default.existsSync(targetPkgPath)) {
862
- const pkg = JSON.parse(import_node_fs5.default.readFileSync(targetPkgPath, "utf-8"));
978
+ if (import_node_fs7.default.existsSync(targetPkgPath)) {
979
+ const pkg = JSON.parse(import_node_fs7.default.readFileSync(targetPkgPath, "utf-8"));
863
980
  if (pkg.version && typeof pkg.version === "string") {
864
981
  version2 = pkg.version;
865
982
  }
@@ -869,16 +986,16 @@ Installed skills in ${SHARED_SKILLS_DIR}:
869
986
  }
870
987
  }
871
988
  const isDev = isSymlink(skillPath);
872
- const devTag = isDev ? import_chalk2.default.yellow(" (dev)") : "";
873
- const versionDisplay = version2 !== "unknown" ? import_chalk2.default.gray(`(v${version2})`) : "";
874
- console.log(import_chalk2.default.green("\u{1F4E6}") + ` ${import_chalk2.default.bold(skill)}${versionDisplay ? " " + versionDisplay : ""}${devTag}`);
989
+ const devTag = isDev ? import_chalk3.default.yellow(" (dev)") : "";
990
+ const versionDisplay = version2 !== "unknown" ? import_chalk3.default.gray(`(v${version2})`) : "";
991
+ console.log(import_chalk3.default.green("\u{1F4E6}") + ` ${import_chalk3.default.bold(skill)}${versionDisplay ? " " + versionDisplay : ""}${devTag}`);
875
992
  const cwd = process.cwd();
876
993
  const linkedAgents = [];
877
994
  for (const agent of AGENTS) {
878
995
  const skillsDirs = getAgentSkillsDirs(agent, cwd);
879
996
  const hasSymlink = skillsDirs.some((dir) => {
880
997
  const agentSkillPath = import_node_path6.default.join(dir, skill);
881
- if (import_node_fs5.default.existsSync(agentSkillPath) && isSymlink(agentSkillPath)) {
998
+ if (import_node_fs7.default.existsSync(agentSkillPath) && isSymlink(agentSkillPath)) {
882
999
  const target = readSymlink(agentSkillPath);
883
1000
  return target === skillPath;
884
1001
  }
@@ -889,29 +1006,28 @@ Installed skills in ${SHARED_SKILLS_DIR}:
889
1006
  }
890
1007
  }
891
1008
  if (linkedAgents.length > 0) {
892
- console.log(import_chalk2.default.gray(` \u2192 Linked to: ${linkedAgents.join(", ")}`));
1009
+ console.log(import_chalk3.default.gray(` \u2192 Linked to: ${linkedAgents.join(", ")}`));
893
1010
  } else {
894
- console.log(import_chalk2.default.yellow(` \u2192 Not linked to any agent`));
1011
+ console.log(import_chalk3.default.yellow(` \u2192 Not linked to any agent`));
895
1012
  }
896
1013
  if (isDev) {
897
1014
  const target = readSymlink(skillPath);
898
1015
  if (target) {
899
- console.log(import_chalk2.default.gray(` \u2192 Source: ${target}`));
1016
+ console.log(import_chalk3.default.gray(` \u2192 Source: ${target}`));
900
1017
  }
901
1018
  }
902
1019
  console.log("");
903
1020
  } catch (error) {
904
- continue;
905
1021
  }
906
1022
  }
907
1023
  }
908
1024
 
909
1025
  // src/commands/remove.ts
910
- var import_node_fs6 = __toESM(require("fs"), 1);
1026
+ var import_node_fs8 = __toESM(require("fs"), 1);
911
1027
  async function remove(skillName, options = {}) {
912
1028
  const extractedName = extractSkillName(skillName);
913
1029
  const sharedPath = getSharedSkillPath(extractedName);
914
- const skillExists = import_node_fs6.default.existsSync(sharedPath);
1030
+ const skillExists = import_node_fs8.default.existsSync(sharedPath);
915
1031
  if (!skillExists) {
916
1032
  logger.error(`Skill not found: ${extractedName}`);
917
1033
  logger.info(`Location: ${sharedPath}`);
@@ -921,11 +1037,11 @@ async function remove(skillName, options = {}) {
921
1037
  const installedAgents = detectInstalledAgents(cwd);
922
1038
  let targetAgents = installedAgents;
923
1039
  if (options.agent && options.agent !== "all") {
924
- const agent = installedAgents.find((a) => a.name === options.agent);
1040
+ const agent = AGENTS.find((a) => a.name === options.agent && a.enabled);
925
1041
  if (!agent) {
926
- logger.error(`Agent not installed: ${options.agent}`);
1042
+ logger.error(`Unknown agent: ${options.agent}`);
927
1043
  logger.info(`
928
- Installed agents: ${installedAgents.map((a) => a.name).join(", ")}`);
1044
+ Supported agents: ${AGENTS.filter((a) => a.enabled).map((a) => a.name).join(", ")}`);
929
1045
  process.exit(1);
930
1046
  }
931
1047
  targetAgents = [agent];
@@ -947,12 +1063,12 @@ Installed agents: ${installedAgents.map((a) => a.name).join(", ")}`);
947
1063
  }
948
1064
  logger.info("Removing skill from shared directory...");
949
1065
  try {
950
- const stats = import_node_fs6.default.lstatSync(sharedPath);
1066
+ const stats = import_node_fs8.default.lstatSync(sharedPath);
951
1067
  if (stats.isSymbolicLink()) {
952
- import_node_fs6.default.unlinkSync(sharedPath);
1068
+ import_node_fs8.default.unlinkSync(sharedPath);
953
1069
  logger.success("Removed symlink from shared directory");
954
1070
  } else {
955
- import_node_fs6.default.rmSync(sharedPath, { recursive: true, force: true });
1071
+ import_node_fs8.default.rmSync(sharedPath, { recursive: true, force: true });
956
1072
  logger.success("Removed skill from shared directory");
957
1073
  }
958
1074
  } catch (error) {
@@ -963,7 +1079,7 @@ Installed agents: ${installedAgents.map((a) => a.name).join(", ")}`);
963
1079
  for (const agent of AGENTS) {
964
1080
  const agentSkillPaths = getAgentSkillPaths(agent.name, extractedName, cwd);
965
1081
  const hasSymlink = agentSkillPaths.some((path7) => {
966
- return import_node_fs6.default.existsSync(path7) && isSymlink(path7);
1082
+ return import_node_fs8.default.existsSync(path7) && isSymlink(path7);
967
1083
  });
968
1084
  if (hasSymlink) {
969
1085
  remainingSymlinks.push(agent.displayName);
@@ -981,44 +1097,6 @@ Installed agents: ${installedAgents.map((a) => a.name).join(", ")}`);
981
1097
  }
982
1098
  }
983
1099
 
984
- // src/commands/agents.ts
985
- var import_chalk3 = __toESM(require("chalk"), 1);
986
- var import_node_fs7 = __toESM(require("fs"), 1);
987
- var import_node_os3 = __toESM(require("os"), 1);
988
- function agents() {
989
- const cwd = process.cwd();
990
- console.log(import_chalk3.default.bold("\n\u{1F4CB} Supported AI Agents:\n"));
991
- for (const agent of AGENTS) {
992
- const skillsDirs = getAgentSkillsDirs(agent, cwd);
993
- const dirsInfo = skillsDirs.length > 1 ? ` (${skillsDirs.length} directories)` : "";
994
- console.log(import_chalk3.default.bold(agent.displayName));
995
- console.log(import_chalk3.default.gray(` Name: ${agent.name}`));
996
- if (skillsDirs.length === 0) {
997
- console.log(import_chalk3.default.yellow(" \u26A0\uFE0F No directories configured"));
998
- } else {
999
- console.log(import_chalk3.default.gray(` Directories${dirsInfo}:`));
1000
- for (const dir of skillsDirs) {
1001
- const exists = import_node_fs7.default.existsSync(dir);
1002
- const status = exists ? import_chalk3.default.green("\u2713") : import_chalk3.default.gray("\u25CB");
1003
- const pathColor = exists ? import_chalk3.default.white : import_chalk3.default.gray;
1004
- console.log(` ${status} ${pathColor(dir)}`);
1005
- }
1006
- }
1007
- console.log("");
1008
- }
1009
- console.log(import_chalk3.default.bold("\u{1F4E6} Shared Skills Directory:"));
1010
- const sharedExists = import_node_fs7.default.existsSync(SHARED_SKILLS_DIR);
1011
- const sharedStatus = sharedExists ? import_chalk3.default.green("\u2713") : import_chalk3.default.gray("\u25CB");
1012
- const sharedPathColor = sharedExists ? import_chalk3.default.white : import_chalk3.default.gray;
1013
- console.log(` ${sharedStatus} ${sharedPathColor(SHARED_SKILLS_DIR)}`);
1014
- console.log("");
1015
- const home = import_node_os3.default.homedir();
1016
- if (cwd !== home) {
1017
- console.log(import_chalk3.default.gray(`Current working directory: ${cwd}`));
1018
- console.log(import_chalk3.default.gray("(Project-level directories are shown above)\n"));
1019
- }
1020
- }
1021
-
1022
1100
  // src/index.ts
1023
1101
  var __filename2 = (0, import_url.fileURLToPath)(importMetaUrl);
1024
1102
  var __dirname = (0, import_path.dirname)(__filename2);
@@ -1027,7 +1105,11 @@ var packageJson = JSON.parse((0, import_fs.readFileSync)(packageJsonPath, "utf-8
1027
1105
  var version = packageJson.version;
1028
1106
  var program = new import_commander.Command();
1029
1107
  program.name("eskill").description("Unified CLI tool for managing AI agent skills").version(version);
1030
- program.command("install <skill>").alias("add").description("Install a skill from NPM, Git URL, or local directory").option("-a, --agent <name>", "Install for specific agent (claude, cursor, windsurf, or all)").option("-l, --link", "Dev mode: symlink from local directory").option("-f, --force", "Force reinstall if already exists").option("-r, --registry <url>", "NPM registry URL (overrides .npmrc and global config)").option("-t, --timeout <ms>", "Timeout in milliseconds (default: 180000 for npm, 120000 for git)", (value) => parseInt(value, 10)).action(async (skill, options) => {
1108
+ program.command("install <skill>").alias("add").description("Install a skill from NPM, Git URL, or local directory").option("-a, --agent <name>", "Install for specific agent (claude, cursor, windsurf, or all)").option("-l, --link", "Dev mode: symlink from local directory").option("-f, --force", "Force reinstall if already exists").option("-r, --registry <url>", "NPM registry URL (overrides .npmrc and global config)").option(
1109
+ "-t, --timeout <ms>",
1110
+ "Timeout in milliseconds (default: 180000 for npm, 120000 for git)",
1111
+ (value) => Number.parseInt(value, 10)
1112
+ ).action(async (skill, options) => {
1031
1113
  try {
1032
1114
  await install(skill, options);
1033
1115
  } catch (error) {