@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/README.md +19 -5
- package/dist/index.cjs +472 -390
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +471 -389
- package/dist/index.js.map +1 -1
- package/package.json +2 -6
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/
|
|
37
|
-
var
|
|
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: "
|
|
122
|
-
displayName: "
|
|
123
|
-
|
|
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: "
|
|
128
|
-
displayName: "
|
|
129
|
-
|
|
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: "
|
|
134
|
-
displayName: "
|
|
135
|
-
skillsDir: import_node_path.default.join(HOME, ".
|
|
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
|
|
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: "
|
|
158
|
-
displayName: "
|
|
159
|
-
skillsDir: import_node_path.default.join(
|
|
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: "
|
|
164
|
-
displayName: "
|
|
165
|
-
|
|
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: "
|
|
186
|
-
displayName: "
|
|
187
|
-
skillsDir: import_node_path.default.join(
|
|
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: "
|
|
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 (!
|
|
233
|
-
|
|
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
|
|
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/
|
|
261
|
-
var
|
|
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 (!
|
|
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 =
|
|
273
|
-
if (!
|
|
526
|
+
const targetDir = import_node_path4.default.dirname(target);
|
|
527
|
+
if (!import_node_fs5.default.existsSync(targetDir)) {
|
|
274
528
|
try {
|
|
275
|
-
|
|
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 (
|
|
535
|
+
if (import_node_fs5.default.existsSync(target)) {
|
|
282
536
|
try {
|
|
283
|
-
const stats =
|
|
537
|
+
const stats = import_node_fs5.default.lstatSync(target);
|
|
284
538
|
if (stats.isSymbolicLink()) {
|
|
285
|
-
|
|
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
|
-
|
|
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 (!
|
|
567
|
+
if (!import_node_fs5.default.existsSync(target)) {
|
|
314
568
|
continue;
|
|
315
569
|
}
|
|
316
570
|
try {
|
|
317
|
-
const stats =
|
|
571
|
+
const stats = import_node_fs5.default.lstatSync(target);
|
|
318
572
|
if (stats.isSymbolicLink()) {
|
|
319
|
-
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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 (
|
|
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
|
|
547
|
-
|
|
548
|
-
if (gitInfo.
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
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(`
|
|
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 (!
|
|
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 (!
|
|
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 ||
|
|
716
|
+
} else if (options.link || import_node_fs6.default.existsSync(skillNameOrPath)) {
|
|
609
717
|
skillPath = import_node_path5.default.resolve(skillNameOrPath);
|
|
610
|
-
if (!
|
|
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 (
|
|
723
|
+
if (import_node_fs6.default.existsSync(pkgPath)) {
|
|
616
724
|
try {
|
|
617
|
-
const pkg = JSON.parse(
|
|
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
|
-
|
|
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 ||
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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 (!
|
|
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 (
|
|
838
|
+
if (import_node_fs6.default.existsSync(targetPath)) {
|
|
727
839
|
if (options.force) {
|
|
728
840
|
logger.warn("Removing existing installation...");
|
|
729
|
-
|
|
841
|
+
import_node_fs6.default.rmSync(targetPath, { recursive: true, force: true });
|
|
730
842
|
} else {
|
|
731
|
-
logger.error(`Skill already exists
|
|
732
|
-
logger.
|
|
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
|
-
|
|
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("
|
|
752
|
-
logger.info("
|
|
753
|
-
logger.info("
|
|
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 =
|
|
872
|
+
const agent = AGENTS.find((a) => a.name === options.agent && a.enabled);
|
|
759
873
|
if (!agent) {
|
|
760
|
-
logger.error(`
|
|
874
|
+
logger.error(`Unknown agent: ${options.agent}`);
|
|
761
875
|
logger.info(`
|
|
762
|
-
|
|
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
|
-
|
|
784
|
-
const entries =
|
|
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
|
-
|
|
911
|
+
import_node_fs6.default.copyFileSync(srcPath, destPath);
|
|
795
912
|
}
|
|
796
913
|
}
|
|
797
914
|
}
|
|
798
915
|
|
|
799
916
|
// src/commands/list.ts
|
|
800
|
-
var
|
|
917
|
+
var import_node_fs7 = __toESM(require("fs"), 1);
|
|
801
918
|
var import_node_path6 = __toESM(require("path"), 1);
|
|
802
|
-
var
|
|
919
|
+
var import_chalk3 = __toESM(require("chalk"), 1);
|
|
803
920
|
function list() {
|
|
804
|
-
if (!
|
|
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: ${
|
|
924
|
+
To install a skill, run: ${import_chalk3.default.cyan("eskill install <skill-name>")}`);
|
|
808
925
|
return;
|
|
809
926
|
}
|
|
810
|
-
const skills =
|
|
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: ${
|
|
931
|
+
To install a skill, run: ${import_chalk3.default.cyan("eskill install <skill-name>")}`);
|
|
815
932
|
return;
|
|
816
933
|
}
|
|
817
|
-
console.log(
|
|
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 =
|
|
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 (
|
|
946
|
+
if (import_node_fs7.default.existsSync(pkgPath)) {
|
|
830
947
|
try {
|
|
831
|
-
const pkgContent =
|
|
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 (
|
|
958
|
+
if (import_node_fs7.default.existsSync(skillMdPath)) {
|
|
842
959
|
try {
|
|
843
|
-
const skillMdContent =
|
|
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 (
|
|
862
|
-
const pkg = JSON.parse(
|
|
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 ?
|
|
873
|
-
const versionDisplay = version2 !== "unknown" ?
|
|
874
|
-
console.log(
|
|
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 (
|
|
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(
|
|
1009
|
+
console.log(import_chalk3.default.gray(` \u2192 Linked to: ${linkedAgents.join(", ")}`));
|
|
893
1010
|
} else {
|
|
894
|
-
console.log(
|
|
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(
|
|
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
|
|
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 =
|
|
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 =
|
|
1040
|
+
const agent = AGENTS.find((a) => a.name === options.agent && a.enabled);
|
|
925
1041
|
if (!agent) {
|
|
926
|
-
logger.error(`
|
|
1042
|
+
logger.error(`Unknown agent: ${options.agent}`);
|
|
927
1043
|
logger.info(`
|
|
928
|
-
|
|
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 =
|
|
1066
|
+
const stats = import_node_fs8.default.lstatSync(sharedPath);
|
|
951
1067
|
if (stats.isSymbolicLink()) {
|
|
952
|
-
|
|
1068
|
+
import_node_fs8.default.unlinkSync(sharedPath);
|
|
953
1069
|
logger.success("Removed symlink from shared directory");
|
|
954
1070
|
} else {
|
|
955
|
-
|
|
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
|
|
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(
|
|
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) {
|