From 7c420859509cdba5d91727a1c9702daaadd78279 Mon Sep 17 00:00:00 2001 From: Aditya Datta Date: Sat, 25 Jul 2026 12:11:21 +0530 Subject: [PATCH] refactor: share package version lookup --- packages/cli/src/ayo.ts | 15 ++++----------- packages/core/src/node/index.ts | 1 + packages/core/src/node/version.ts | 18 ++++++++++++++++++ packages/mcp/src/index.ts | 12 ++---------- 4 files changed, 25 insertions(+), 21 deletions(-) create mode 100644 packages/core/src/node/version.ts diff --git a/packages/cli/src/ayo.ts b/packages/cli/src/ayo.ts index 805a439..fda2770 100644 --- a/packages/cli/src/ayo.ts +++ b/packages/cli/src/ayo.ts @@ -8,6 +8,7 @@ import { readFileSync, writeFileSync, existsSync, rmSync } from "node:fs"; import { join } from "node:path"; import { Command, Help } from "commander"; import pc from "picocolors"; +import { pkgVersion } from "@ayo-dev/core/node"; import { AYO_DIR, DAEMON_META_PATH, @@ -42,16 +43,8 @@ import { soundList, soundMute, soundPreview, soundSet, soundStatus, soundUnmute, // Read the real version from package.json (dist/ayo.js → ../package.json, which // npm always includes in the tarball). Fall back so `--version` can never throw. -function pkgVersion(): string { - try { - return JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version ?? "0.0.0"; - } catch { - return "0.0.0"; - } -} - const program = new Command(); -program.name("ayo").description("Ping your teammates from inside Codex and Claude.").version(pkgVersion()); +program.name("ayo").description("Ping your teammates from inside Codex and Claude.").version(pkgVersion(import.meta.url)); program.showSuggestionAfterError(true); // Help lists everyday commands before plumbing — beloved CLIs teach the primary @@ -1119,9 +1112,9 @@ program } catch { /* older daemon wrote no meta */ } - const skew = dv && dv !== pkgVersion(); + const skew = dv && dv !== pkgVersion(import.meta.url); console.log(pc.green(`✓ daemon running (ayod${dv ? ` v${dv}` : ""})`)); - if (skew) console.log(pc.yellow(`⚠ daemon is v${dv} but the CLI is v${pkgVersion()} — restart it: \`ayo daemon stop && ayo daemon start\``)); + if (skew) console.log(pc.yellow(`⚠ daemon is v${dv} but the CLI is v${pkgVersion(import.meta.url)} — restart it: \`ayo daemon stop && ayo daemon start\``)); else if (!dv) console.log(pc.dim(" (daemon predates version reporting — restart it once so doctor can check for skew)")); } else { console.log(pc.yellow("⚠ daemon not running — `ayo daemon install` (or `ayo daemon start`)")); diff --git a/packages/core/src/node/index.ts b/packages/core/src/node/index.ts index 76d3214..3af7f02 100644 --- a/packages/core/src/node/index.ts +++ b/packages/core/src/node/index.ts @@ -9,3 +9,4 @@ export * from "./files.js"; export * from "./http.js"; export * from "./git-context.js"; +export * from "./version.js"; diff --git a/packages/core/src/node/version.ts b/packages/core/src/node/version.ts new file mode 100644 index 0000000..32b5fa8 --- /dev/null +++ b/packages/core/src/node/version.ts @@ -0,0 +1,18 @@ +import { readFileSync } from "node:fs"; + +/** + * Read the package version beside a compiled package entry point. + * + * Callers pass their own `import.meta.url` so this works for every package in + * the monorepo while keeping the package manifest out of the module graph. + */ +export function pkgVersion(importMetaUrl: string): string { + try { + const manifest = JSON.parse( + readFileSync(new URL("../package.json", importMetaUrl), "utf8"), + ) as { version?: unknown }; + return typeof manifest.version === "string" ? manifest.version : "0.0.0"; + } catch { + return "0.0.0"; + } +} diff --git a/packages/mcp/src/index.ts b/packages/mcp/src/index.ts index 2f250bd..d12798b 100644 --- a/packages/mcp/src/index.ts +++ b/packages/mcp/src/index.ts @@ -6,24 +6,16 @@ * send + pull. Identity is shared with the CLI via ~/.ayo (see relay.ts). */ -import { readFileSync } from "node:fs"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; import type { AyoContext, SendAyoResponse } from "@ayo-dev/core"; +import { pkgVersion } from "@ayo-dev/core/node"; import { loadAuth, relay } from "./relay.js"; import { captureContext } from "./context.js"; // Real version from package.json (dist/index.js → ../package.json, always packed). -function pkgVersion(): string { - try { - return JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version ?? "0.0.0"; - } catch { - return "0.0.0"; - } -} - -const server = new McpServer({ name: "ayo", version: pkgVersion() }); +const server = new McpServer({ name: "ayo", version: pkgVersion(import.meta.url) }); const recipients = z.array(z.string().min(1)).min(1).describe('Handles to ping. Use ["*"] for the whole team.');