refactor(cli): dynamic version for nerve agent — Phase 3 of RFC #289 #297

Merged
xingyue merged 1 commits from feat/agent-inject-phase3 into main 2026-04-30 14:08:03 +00:00
+31 -12
View File
@@ -13,16 +13,35 @@ import { fileURLToPath } from "node:url";
import { defineCommand } from "citty";
const CLI_VERSION = "0.5.0";
function getSkillSourceDir(): string {
function getPackageRootDir(): string {
const thisFile = fileURLToPath(import.meta.url);
let dir = dirname(thisFile);
for (let i = 0; i < 5; i++) {
if (existsSync(join(dir, "skills"))) return join(dir, "skills");
if (existsSync(join(dir, "package.json"))) return dir;
dir = dirname(dir);
}
throw new Error("Cannot locate skills directory. Is the CLI package intact?");
throw new Error("Cannot locate package root. Is the CLI package intact?");
}
function getCliVersion(): string {
const pkgPath = join(getPackageRootDir(), "package.json");
const pkg = JSON.parse(readFileSync(pkgPath, "utf8")) as { version: string };
return pkg.version;
}
let _cachedVersion: string | null = null;
function cliVersion(): string {
if (_cachedVersion === null) _cachedVersion = getCliVersion();
return _cachedVersion;
}
function getSkillSourceDir(): string {
const root = getPackageRootDir();
const skillsDir = join(root, "skills");
if (!existsSync(skillsDir)) {
throw new Error("Cannot locate skills directory. Is the CLI package intact?");
}
return skillsDir;
}
function getHermesSkillDir(profile: string | null): string {
@@ -48,19 +67,19 @@ function injectHermes(profile: string | null): void {
const targetDir = getHermesSkillDir(profile);
const existing = readVersionFile(targetDir);
if (existing === CLI_VERSION) {
if (existing === cliVersion()) {
const loc = profile !== null ? ` (profile: ${profile})` : "";
process.stdout.write(`✅ Hermes nerve skill is already up to date (v${CLI_VERSION})${loc}\n`);
process.stdout.write(`✅ Hermes nerve skill is already up to date (v${cliVersion()})${loc}\n`);
return;
}
mkdirSync(targetDir, { recursive: true });
cpSync(sourceDir, targetDir, { recursive: true });
writeVersionFile(targetDir, CLI_VERSION);
writeVersionFile(targetDir, cliVersion());
const action = existing !== null ? "Updated" : "Installed";
const loc = profile !== null ? ` (profile: ${profile})` : "";
process.stdout.write(`${action} Hermes nerve skill v${CLI_VERSION}${loc}\n`);
process.stdout.write(`${action} Hermes nerve skill v${cliVersion()}${loc}\n`);
process.stdout.write(`${targetDir}/SKILL.md\n`);
}
@@ -76,7 +95,7 @@ function removeHermes(profile: string | null): void {
}
function printStatus(): void {
process.stdout.write(`nerve agent skills (CLI v${CLI_VERSION})\n\n`);
process.stdout.write(`nerve agent skills (CLI v${cliVersion()})\n\n`);
// Default profile
const defaultDir = getHermesSkillDir(null);
@@ -105,11 +124,11 @@ function printStatus(): void {
function printAgentLine(label: string, version: string | null): void {
if (version === null) {
process.stdout.write(` ${label}: ❌ not installed\n`);
} else if (version === CLI_VERSION) {
} else if (version === cliVersion()) {
process.stdout.write(` ${label}: ✅ v${version}\n`);
} else {
process.stdout.write(
` ${label}: ⚠️ v${version} → v${CLI_VERSION} available (run \`nerve agent update\`)\n`,
` ${label}: ⚠️ v${version} → v${cliVersion()} available (run \`nerve agent update\`)\n`,
);
}
}