@eve-horizon/cli 0.2.17 → 0.2.18
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.js +117 -12
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -68055,6 +68055,8 @@ function padRight5(str, width) {
|
|
|
68055
68055
|
var fs2 = __toESM(require("node:fs"));
|
|
68056
68056
|
var path4 = __toESM(require("node:path"));
|
|
68057
68057
|
var import_node_child_process7 = require("node:child_process");
|
|
68058
|
+
var UNIVERSAL_SKILLS_DIR = path4.join(".agents", "skills");
|
|
68059
|
+
var PRIVATE_SKILLS_DIRNAME = "private-skills";
|
|
68058
68060
|
async function handleSkills(subcommand, positionals, flags) {
|
|
68059
68061
|
switch (subcommand) {
|
|
68060
68062
|
case "install":
|
|
@@ -68070,7 +68072,7 @@ async function handleInstall(positionals, flags) {
|
|
|
68070
68072
|
const projectRoot = process.cwd();
|
|
68071
68073
|
const skillsBin = resolveSkillsBinary();
|
|
68072
68074
|
const manifestPath = path4.join(projectRoot, "skills.txt");
|
|
68073
|
-
const skillsDir = path4.join(projectRoot,
|
|
68075
|
+
const skillsDir = path4.join(projectRoot, UNIVERSAL_SKILLS_DIR);
|
|
68074
68076
|
const source = positionals[0];
|
|
68075
68077
|
if (source) {
|
|
68076
68078
|
const parsed = parseSkillSource(source);
|
|
@@ -68102,10 +68104,32 @@ async function handleInstall(positionals, flags) {
|
|
|
68102
68104
|
}
|
|
68103
68105
|
function installSkill(skillsBin, skill, projectRoot) {
|
|
68104
68106
|
console.log(` Installing: ${skill.source} (${skill.type})`);
|
|
68107
|
+
const localDir = resolveLocalDirIfExists(skill, projectRoot);
|
|
68108
|
+
const wantsExcludePrivate = localDir !== null && fs2.existsSync(path4.join(localDir, PRIVATE_SKILLS_DIRNAME)) && !sourcePathExplicitlyTargetsPrivate(skill.source);
|
|
68105
68109
|
try {
|
|
68106
68110
|
const agents = ["claude-code", "codex", "gemini-cli"];
|
|
68111
|
+
if (wantsExcludePrivate && localDir) {
|
|
68112
|
+
const skillDirs = findSkillDirs(localDir, { fullDepth: true, excludePrivate: true });
|
|
68113
|
+
if (skillDirs.length === 0) {
|
|
68114
|
+
console.log(` No skills found under ${skill.source} (after excluding ${PRIVATE_SKILLS_DIRNAME}/)`);
|
|
68115
|
+
return;
|
|
68116
|
+
}
|
|
68117
|
+
console.log(` Installing ${skillDirs.length} public skill(s) (excluding ${PRIVATE_SKILLS_DIRNAME}/)...`);
|
|
68118
|
+
for (const dir of skillDirs) {
|
|
68119
|
+
const rel = path4.relative(projectRoot, dir);
|
|
68120
|
+
const installSource = rel.startsWith(".") ? rel : `./${rel}`;
|
|
68121
|
+
for (const agent of agents) {
|
|
68122
|
+
(0, import_node_child_process7.execSync)(`${skillsBin} add ${JSON.stringify(installSource)} -a ${agent} -s '*' -y --full-depth`, {
|
|
68123
|
+
cwd: projectRoot,
|
|
68124
|
+
stdio: "inherit",
|
|
68125
|
+
timeout: 12e4
|
|
68126
|
+
});
|
|
68127
|
+
}
|
|
68128
|
+
}
|
|
68129
|
+
return;
|
|
68130
|
+
}
|
|
68107
68131
|
for (const agent of agents) {
|
|
68108
|
-
(0, import_node_child_process7.execSync)(`${skillsBin} add ${JSON.stringify(skill.source)} -a ${agent} -s '*' -y`, {
|
|
68132
|
+
(0, import_node_child_process7.execSync)(`${skillsBin} add ${JSON.stringify(skill.source)} -a ${agent} -s '*' -y --full-depth`, {
|
|
68109
68133
|
cwd: projectRoot,
|
|
68110
68134
|
stdio: "inherit",
|
|
68111
68135
|
timeout: 12e4
|
|
@@ -68173,7 +68197,7 @@ function expandGlobPattern(pattern, basePath) {
|
|
|
68173
68197
|
console.warn(`Warning: Glob pattern base directory not found: ${searchRoot}`);
|
|
68174
68198
|
return sources;
|
|
68175
68199
|
}
|
|
68176
|
-
const
|
|
68200
|
+
const findSkillDirs2 = (dir, depth) => {
|
|
68177
68201
|
try {
|
|
68178
68202
|
const entries = fs2.readdirSync(dir, { withFileTypes: true });
|
|
68179
68203
|
for (const entry of entries) {
|
|
@@ -68194,14 +68218,14 @@ function expandGlobPattern(pattern, basePath) {
|
|
|
68194
68218
|
});
|
|
68195
68219
|
}
|
|
68196
68220
|
if (isRecursive || depth === 0) {
|
|
68197
|
-
|
|
68221
|
+
findSkillDirs2(fullPath, depth + 1);
|
|
68198
68222
|
}
|
|
68199
68223
|
}
|
|
68200
68224
|
} catch (err) {
|
|
68201
68225
|
console.warn(`Warning: Error reading directory ${dir}:`, err);
|
|
68202
68226
|
}
|
|
68203
68227
|
};
|
|
68204
|
-
|
|
68228
|
+
findSkillDirs2(searchRoot, 0);
|
|
68205
68229
|
return sources;
|
|
68206
68230
|
}
|
|
68207
68231
|
function parseSkillsManifest(manifestPath) {
|
|
@@ -68276,7 +68300,7 @@ function getInstalledSkills(skillsDir) {
|
|
|
68276
68300
|
return installed;
|
|
68277
68301
|
}
|
|
68278
68302
|
function ensureSkillsSymlink(projectRoot) {
|
|
68279
|
-
const agentSkills = path4.join(projectRoot,
|
|
68303
|
+
const agentSkills = path4.join(projectRoot, UNIVERSAL_SKILLS_DIR);
|
|
68280
68304
|
const claudeDir = path4.join(projectRoot, ".claude");
|
|
68281
68305
|
const claudeSkills = path4.join(claudeDir, "skills");
|
|
68282
68306
|
if (!fs2.existsSync(agentSkills)) {
|
|
@@ -68285,11 +68309,27 @@ function ensureSkillsSymlink(projectRoot) {
|
|
|
68285
68309
|
if (!fs2.existsSync(claudeDir)) {
|
|
68286
68310
|
fs2.mkdirSync(claudeDir, { recursive: true });
|
|
68287
68311
|
}
|
|
68312
|
+
if (fs2.existsSync(claudeSkills) && !fs2.lstatSync(claudeSkills).isSymbolicLink()) {
|
|
68313
|
+
try {
|
|
68314
|
+
const claudeStat = fs2.lstatSync(claudeSkills);
|
|
68315
|
+
if (claudeStat.isDirectory()) {
|
|
68316
|
+
const entries = fs2.readdirSync(agentSkills, { withFileTypes: true });
|
|
68317
|
+
for (const entry of entries) {
|
|
68318
|
+
if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
|
|
68319
|
+
const dst = path4.join(claudeSkills, entry.name);
|
|
68320
|
+
if (fs2.existsSync(dst)) continue;
|
|
68321
|
+
fs2.symlinkSync(path4.join("..", "..", UNIVERSAL_SKILLS_DIR, entry.name), dst);
|
|
68322
|
+
}
|
|
68323
|
+
}
|
|
68324
|
+
} catch {
|
|
68325
|
+
}
|
|
68326
|
+
return;
|
|
68327
|
+
}
|
|
68288
68328
|
if (fs2.existsSync(claudeSkills)) {
|
|
68289
68329
|
const stat = fs2.lstatSync(claudeSkills);
|
|
68290
68330
|
if (stat.isSymbolicLink()) {
|
|
68291
68331
|
const target = fs2.readlinkSync(claudeSkills);
|
|
68292
|
-
if (target ===
|
|
68332
|
+
if (target === `../${UNIVERSAL_SKILLS_DIR}` || target === agentSkills) {
|
|
68293
68333
|
return;
|
|
68294
68334
|
}
|
|
68295
68335
|
fs2.unlinkSync(claudeSkills);
|
|
@@ -68299,12 +68339,61 @@ function ensureSkillsSymlink(projectRoot) {
|
|
|
68299
68339
|
}
|
|
68300
68340
|
}
|
|
68301
68341
|
try {
|
|
68302
|
-
fs2.symlinkSync(
|
|
68303
|
-
console.log(
|
|
68342
|
+
fs2.symlinkSync(`../${UNIVERSAL_SKILLS_DIR}`, claudeSkills);
|
|
68343
|
+
console.log(`Linked .claude/skills -> ${UNIVERSAL_SKILLS_DIR}`);
|
|
68304
68344
|
} catch (err) {
|
|
68305
68345
|
console.warn("Warning: Failed to create symlink:", err);
|
|
68306
68346
|
}
|
|
68307
68347
|
}
|
|
68348
|
+
function resolveLocalDirIfExists(skill, projectRoot) {
|
|
68349
|
+
if (skill.type !== "local") return null;
|
|
68350
|
+
let source = skill.source;
|
|
68351
|
+
if (source.startsWith("~")) {
|
|
68352
|
+
source = source.replace(/^~/, process.env.HOME || "~");
|
|
68353
|
+
}
|
|
68354
|
+
const abs = path4.isAbsolute(source) ? source : path4.resolve(projectRoot, source);
|
|
68355
|
+
try {
|
|
68356
|
+
if (!fs2.existsSync(abs)) return null;
|
|
68357
|
+
if (!fs2.statSync(abs).isDirectory()) return null;
|
|
68358
|
+
return abs;
|
|
68359
|
+
} catch {
|
|
68360
|
+
return null;
|
|
68361
|
+
}
|
|
68362
|
+
}
|
|
68363
|
+
function sourcePathExplicitlyTargetsPrivate(source) {
|
|
68364
|
+
const normalized = source.replace(/\\/g, "/");
|
|
68365
|
+
return normalized === PRIVATE_SKILLS_DIRNAME || normalized.includes(`/${PRIVATE_SKILLS_DIRNAME}/`);
|
|
68366
|
+
}
|
|
68367
|
+
function findSkillDirs(rootDir, opts) {
|
|
68368
|
+
const out = [];
|
|
68369
|
+
const shouldSkipDir = (_parentAbsDir, name) => {
|
|
68370
|
+
if (name.startsWith(".")) return true;
|
|
68371
|
+
if (name === "node_modules" || name === ".git") return true;
|
|
68372
|
+
if (opts.excludePrivate && name === PRIVATE_SKILLS_DIRNAME) return true;
|
|
68373
|
+
if (name === ".agents" || name === ".agent" || name === ".claude") return true;
|
|
68374
|
+
return false;
|
|
68375
|
+
};
|
|
68376
|
+
const walk = (dir) => {
|
|
68377
|
+
let entries;
|
|
68378
|
+
try {
|
|
68379
|
+
entries = fs2.readdirSync(dir, { withFileTypes: true });
|
|
68380
|
+
} catch {
|
|
68381
|
+
return;
|
|
68382
|
+
}
|
|
68383
|
+
const hasSkillMd = entries.some((e) => e.isFile() && e.name === "SKILL.md");
|
|
68384
|
+
if (hasSkillMd) {
|
|
68385
|
+
out.push(dir);
|
|
68386
|
+
if (!opts.fullDepth) return;
|
|
68387
|
+
}
|
|
68388
|
+
for (const entry of entries) {
|
|
68389
|
+
if (!entry.isDirectory()) continue;
|
|
68390
|
+
if (shouldSkipDir(dir, entry.name)) continue;
|
|
68391
|
+
walk(path4.join(dir, entry.name));
|
|
68392
|
+
}
|
|
68393
|
+
};
|
|
68394
|
+
walk(rootDir);
|
|
68395
|
+
return out;
|
|
68396
|
+
}
|
|
68308
68397
|
|
|
68309
68398
|
// src/commands/admin.ts
|
|
68310
68399
|
async function handleAdmin(subcommand, positionals, flags, context2) {
|
|
@@ -69377,7 +69466,7 @@ async function installSkills(projectRoot) {
|
|
|
69377
69466
|
}
|
|
69378
69467
|
}
|
|
69379
69468
|
function ensureSkillsSymlink2(projectRoot) {
|
|
69380
|
-
const agentSkills = path5.join(projectRoot, ".
|
|
69469
|
+
const agentSkills = path5.join(projectRoot, ".agents", "skills");
|
|
69381
69470
|
const claudeDir = path5.join(projectRoot, ".claude");
|
|
69382
69471
|
const claudeSkills = path5.join(claudeDir, "skills");
|
|
69383
69472
|
if (!fs3.existsSync(agentSkills)) {
|
|
@@ -69386,11 +69475,27 @@ function ensureSkillsSymlink2(projectRoot) {
|
|
|
69386
69475
|
if (!fs3.existsSync(claudeDir)) {
|
|
69387
69476
|
fs3.mkdirSync(claudeDir, { recursive: true });
|
|
69388
69477
|
}
|
|
69478
|
+
if (fs3.existsSync(claudeSkills) && !fs3.lstatSync(claudeSkills).isSymbolicLink()) {
|
|
69479
|
+
try {
|
|
69480
|
+
const stat = fs3.lstatSync(claudeSkills);
|
|
69481
|
+
if (stat.isDirectory()) {
|
|
69482
|
+
const entries = fs3.readdirSync(agentSkills, { withFileTypes: true });
|
|
69483
|
+
for (const entry of entries) {
|
|
69484
|
+
if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
|
|
69485
|
+
const dst = path5.join(claudeSkills, entry.name);
|
|
69486
|
+
if (fs3.existsSync(dst)) continue;
|
|
69487
|
+
fs3.symlinkSync(path5.join("..", "..", ".agents", "skills", entry.name), dst);
|
|
69488
|
+
}
|
|
69489
|
+
}
|
|
69490
|
+
} catch {
|
|
69491
|
+
}
|
|
69492
|
+
return;
|
|
69493
|
+
}
|
|
69389
69494
|
if (fs3.existsSync(claudeSkills)) {
|
|
69390
69495
|
const stat = fs3.lstatSync(claudeSkills);
|
|
69391
69496
|
if (stat.isSymbolicLink()) {
|
|
69392
69497
|
const target = fs3.readlinkSync(claudeSkills);
|
|
69393
|
-
if (target === "../.
|
|
69498
|
+
if (target === "../.agents/skills" || target === agentSkills) {
|
|
69394
69499
|
return;
|
|
69395
69500
|
}
|
|
69396
69501
|
fs3.unlinkSync(claudeSkills);
|
|
@@ -69399,7 +69504,7 @@ function ensureSkillsSymlink2(projectRoot) {
|
|
|
69399
69504
|
}
|
|
69400
69505
|
}
|
|
69401
69506
|
try {
|
|
69402
|
-
fs3.symlinkSync("../.
|
|
69507
|
+
fs3.symlinkSync("../.agents/skills", claudeSkills);
|
|
69403
69508
|
} catch {
|
|
69404
69509
|
}
|
|
69405
69510
|
}
|