diff --git a/packages/cli/src/commands/agent.ts b/packages/cli/src/commands/agent.ts index 4c68855..542416d 100644 --- a/packages/cli/src/commands/agent.ts +++ b/packages/cli/src/commands/agent.ts @@ -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`, ); } }