diff --git a/packages/cli/__tests__/index.test.ts b/packages/cli/__tests__/index.test.ts new file mode 100644 index 000000000..01f781616 --- /dev/null +++ b/packages/cli/__tests__/index.test.ts @@ -0,0 +1,14 @@ +import { describe, expect, it, vi } from "vitest"; + +const parse = vi.fn(); + +vi.mock("../src/program.js", () => ({ + createProgram: () => ({ parse }), +})); + +describe("cli entrypoint", () => { + it("parses the created program", async () => { + await import("../src/index.js"); + expect(parse).toHaveBeenCalledOnce(); + }); +}); diff --git a/packages/cli/__tests__/options/version.test.ts b/packages/cli/__tests__/options/version.test.ts index 71e2cc140..506c1494e 100644 --- a/packages/cli/__tests__/options/version.test.ts +++ b/packages/cli/__tests__/options/version.test.ts @@ -1,14 +1,9 @@ import { describe, expect, it } from "vitest"; -import { execFileSync } from "node:child_process"; -import { fileURLToPath } from "node:url"; import packageJson from "../../package.json" with { type: "json" }; +import { getCliVersion } from "../../src/options/version.js"; -describe("ao --version", () => { +describe("getCliVersion", () => { it("matches the CLI package version", () => { - const tsxEntry = fileURLToPath(new URL("../../node_modules/.bin/tsx", import.meta.url)); - const cliEntry = fileURLToPath(new URL("../../src/index.ts", import.meta.url)); - const output = execFileSync(tsxEntry, [cliEntry, "--version"], { encoding: "utf8" }).trim(); - - expect(output).toBe(packageJson.version); + expect(getCliVersion()).toBe(packageJson.version); }); }); diff --git a/packages/cli/__tests__/program.test.ts b/packages/cli/__tests__/program.test.ts new file mode 100644 index 000000000..656ac51be --- /dev/null +++ b/packages/cli/__tests__/program.test.ts @@ -0,0 +1,9 @@ +import { describe, expect, it } from "vitest"; +import packageJson from "../package.json" with { type: "json" }; +import { createProgram } from "../src/program.js"; + +describe("createProgram", () => { + it("uses the CLI package version", () => { + expect(createProgram().version()).toBe(packageJson.version); + }); +}); diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index d721b19b8..b7791ffbc 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -1,56 +1,5 @@ #!/usr/bin/env node -import { Command } from "commander"; -import { createRequire } from "node:module"; -import { registerInit } from "./commands/init.js"; -import { registerStatus } from "./commands/status.js"; -import { registerSpawn, registerBatchSpawn } from "./commands/spawn.js"; -import { registerSession } from "./commands/session.js"; -import { registerSend } from "./commands/send.js"; -import { registerReviewCheck } from "./commands/review-check.js"; -import { registerDashboard } from "./commands/dashboard.js"; -import { registerOpen } from "./commands/open.js"; -import { registerStart, registerStop } from "./commands/start.js"; -import { registerLifecycleWorker } from "./commands/lifecycle-worker.js"; -import { registerVerify } from "./commands/verify.js"; -import { registerDoctor } from "./commands/doctor.js"; -import { registerUpdate } from "./commands/update.js"; -import { registerSetup } from "./commands/setup.js"; -import { registerPlugin } from "./commands/plugin.js"; -import { getConfigInstruction } from "./lib/config-instruction.js"; +import { createProgram } from "./program.js"; -const require = createRequire(import.meta.url); -const packageJson = require("../package.json") as { version: string }; -const program = new Command(); - -program - .name("ao") - .description("Agent Orchestrator — manage parallel AI coding agents") - .version(packageJson.version); - -registerInit(program); -registerStart(program); -registerStop(program); -registerStatus(program); -registerSpawn(program); -registerBatchSpawn(program); -registerSession(program); -registerSend(program); -registerReviewCheck(program); -registerDashboard(program); -registerOpen(program); -registerLifecycleWorker(program); -registerVerify(program); -registerDoctor(program); -registerUpdate(program); -registerSetup(program); -registerPlugin(program); - -program - .command("config-help") - .description("Show config schema and guide for creating agent-orchestrator.yaml") - .action(() => { - console.log(getConfigInstruction()); - }); - -program.parse(); +createProgram().parse(); diff --git a/packages/cli/src/options/version.ts b/packages/cli/src/options/version.ts new file mode 100644 index 000000000..c8f49a58e --- /dev/null +++ b/packages/cli/src/options/version.ts @@ -0,0 +1,8 @@ +import { createRequire } from "node:module"; + +const require = createRequire(import.meta.url); + +export function getCliVersion(): string { + const packageJson = require("../../package.json") as { version: string }; + return packageJson.version; +} diff --git a/packages/cli/src/program.ts b/packages/cli/src/program.ts new file mode 100644 index 000000000..883ba0f85 --- /dev/null +++ b/packages/cli/src/program.ts @@ -0,0 +1,54 @@ +import { Command } from "commander"; +import { registerInit } from "./commands/init.js"; +import { registerStatus } from "./commands/status.js"; +import { registerSpawn, registerBatchSpawn } from "./commands/spawn.js"; +import { registerSession } from "./commands/session.js"; +import { registerSend } from "./commands/send.js"; +import { registerReviewCheck } from "./commands/review-check.js"; +import { registerDashboard } from "./commands/dashboard.js"; +import { registerOpen } from "./commands/open.js"; +import { registerStart, registerStop } from "./commands/start.js"; +import { registerLifecycleWorker } from "./commands/lifecycle-worker.js"; +import { registerVerify } from "./commands/verify.js"; +import { registerDoctor } from "./commands/doctor.js"; +import { registerUpdate } from "./commands/update.js"; +import { registerSetup } from "./commands/setup.js"; +import { registerPlugin } from "./commands/plugin.js"; +import { getConfigInstruction } from "./lib/config-instruction.js"; +import { getCliVersion } from "./options/version.js"; + +export function createProgram(): Command { + const program = new Command(); + + program + .name("ao") + .description("Agent Orchestrator — manage parallel AI coding agents") + .version(getCliVersion()); + + registerInit(program); + registerStart(program); + registerStop(program); + registerStatus(program); + registerSpawn(program); + registerBatchSpawn(program); + registerSession(program); + registerSend(program); + registerReviewCheck(program); + registerDashboard(program); + registerOpen(program); + registerLifecycleWorker(program); + registerVerify(program); + registerDoctor(program); + registerUpdate(program); + registerSetup(program); + registerPlugin(program); + + program + .command("config-help") + .description("Show config schema and guide for creating agent-orchestrator.yaml") + .action(() => { + console.log(getConfigInstruction()); + }); + + return program; +}