diff --git a/scripts/rea.mjs b/scripts/rea.mjs index 6d7433910..2ad29c8e0 100755 --- a/scripts/rea.mjs +++ b/scripts/rea.mjs @@ -8,7 +8,7 @@ const { default: packageJson } = await import("../package.json", { }); process.env.REA_PACKAGE_VERSION = packageJson.version; const isMcpMode = - args[0] === "--mcp" || (args.length === 1 && args[0] === "mcp"); + args.length === 1 && (args[0] === "--mcp" || args[0] === "mcp"); if (isMcpMode) { const { runEntrypoint } = await import("../dist/main.js"); diff --git a/tests/dispatcher.test.ts b/tests/dispatcher.test.ts new file mode 100644 index 000000000..2d082f989 --- /dev/null +++ b/tests/dispatcher.test.ts @@ -0,0 +1,64 @@ +import { execFile } from "node:child_process"; +import { copyFile, mkdir, mkdtemp, rm, writeFile } from "node:fs/promises"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { promisify } from "node:util"; + +import { afterEach, describe, expect, it } from "vitest"; + +const execFileAsync = promisify(execFile); +let fixtureRoot: string | undefined; + +afterEach(async () => { + if (fixtureRoot !== undefined) { + await rm(fixtureRoot, { recursive: true, force: true }); + fixtureRoot = undefined; + } +}); + +describe("executable dispatcher", () => { + it("reserves production MCP routing for bare mode arguments", async () => { + fixtureRoot = await mkdtemp(join(tmpdir(), "rea-dispatcher-")); + const scripts = join(fixtureRoot, "scripts"); + const dist = join(fixtureRoot, "dist"); + await Promise.all([mkdir(scripts), mkdir(dist)]); + await Promise.all([ + copyFile("scripts/rea.mjs", join(scripts, "rea.mjs")), + writeFile( + join(fixtureRoot, "package.json"), + JSON.stringify({ type: "module", version: "1.0.0" }), + ), + writeFile( + join(dist, "main.js"), + 'export const runEntrypoint = () => process.stdout.write(JSON.stringify({ adapter: "mcp" }));\n', + ), + writeFile( + join(dist, "cli.js"), + 'export const createCli = () => ({ serve: (args) => process.stdout.write(JSON.stringify({ adapter: "cli", args })) });\n', + ), + writeFile( + join(dist, "cliOutput.js"), + "export const sanitizeCliOutput = (output) => output;\n", + ), + ]); + + const invoke = async (args: readonly string[]): Promise => { + const { stdout } = await execFileAsync(process.execPath, [ + join(scripts, "rea.mjs"), + ...args, + ]); + return JSON.parse(stdout) as unknown; + }; + + await expect(invoke(["mcp"])).resolves.toEqual({ adapter: "mcp" }); + await expect(invoke(["--mcp"])).resolves.toEqual({ adapter: "mcp" }); + await expect(invoke(["mcp", "add"])).resolves.toEqual({ + adapter: "cli", + args: ["mcp", "add"], + }); + await expect(invoke(["--mcp", "extra"])).resolves.toEqual({ + adapter: "cli", + args: ["--mcp", "extra"], + }); + }); +});