mirror of
https://github.com/morluto/rea.git
synced 2026-10-28 18:35:53 +00:00
Use one command owner for setup, client writers, Gemini policy and CLI defaults. Migrate recognized runner registrations with backups and remove runner prewarm. Retain unknown identities and exercise real offline npm, CLI and MCP workflows. Fixes #7757 BREAKING CHANGE: managed MCP registrations use the selected absolute runtime and REA entry script, including package-runner cache paths. Keep that installation available or restore it before setup; unknown registrations require confirmed manual repair. Setup no longer returns prewarm or emits its progress events. Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage) Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing) Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
111 lines
3.8 KiB
TypeScript
111 lines
3.8 KiB
TypeScript
import { currentClientRegistrationCommand } from "../../../src/application/ClientRegistrationIdentity.js";
|
|
import { mkdir, readFile, readdir, writeFile } from "node:fs/promises";
|
|
import { dirname, join, resolve } from "node:path";
|
|
import { parse as parseToml } from "smol-toml";
|
|
import { expect } from "vitest";
|
|
|
|
import {
|
|
codexToolPolicy,
|
|
codexToolPolicySource,
|
|
} from "../../fixtures/codexToolPolicy.js";
|
|
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
|
import { cliTest } from "../../support/cli/cliFixture.js";
|
|
|
|
cliTest(
|
|
"Codex policy survives setup preview, refresh, doctor, repeat and uninstall",
|
|
async ({ cli }) => {
|
|
const home = await createTestTempDirectory("rea-codex-tool-policy-");
|
|
const config = join(home, ".codex/config.toml");
|
|
const original = codexToolPolicySource(
|
|
"tables",
|
|
currentClientRegistrationCommand({
|
|
entrypointPath: resolve("scripts/rea.mjs"),
|
|
}),
|
|
);
|
|
await mkdir(dirname(config), { recursive: true });
|
|
await writeFile(config, original);
|
|
const run = (arguments_: readonly string[]) =>
|
|
cli.run({
|
|
arguments: arguments_,
|
|
cwd: home,
|
|
environment: {
|
|
HOME: home,
|
|
USERPROFILE: home,
|
|
CODEX_HOME: dirname(config),
|
|
XDG_CONFIG_HOME: join(home, ".config"),
|
|
REA_GHIDRA_STARTUP_TIMEOUT_MS: "17000",
|
|
},
|
|
});
|
|
const doctorArguments = [
|
|
"doctor",
|
|
"--client",
|
|
"codex",
|
|
"--skill=false",
|
|
"--json",
|
|
];
|
|
const assertAligned = (value: unknown) =>
|
|
expect(value).toMatchObject({
|
|
scope_checks: expect.arrayContaining([
|
|
expect.objectContaining({ name: "registration:codex", ok: true }),
|
|
]),
|
|
});
|
|
const setupArguments = [
|
|
"setup",
|
|
"--client",
|
|
"codex",
|
|
"--skill=false",
|
|
"--json",
|
|
];
|
|
const preview = await run([...setupArguments, "--dry-run"]);
|
|
expect(preview.exitCode, preview.stdout).toBe(0);
|
|
expect(preview.json).toMatchObject({ status: "planned" });
|
|
expect(await readFile(config, "utf8")).toBe(original);
|
|
expect(await readdir(dirname(config))).toEqual(["config.toml"]);
|
|
|
|
const applied = await run([...setupArguments, "--yes"]);
|
|
expect(applied.exitCode, applied.stdout).toBe(0);
|
|
expect(applied.json).toMatchObject({
|
|
status: "ready",
|
|
clients: { codex: { status: "configured" } },
|
|
});
|
|
const configured = await readFile(config, "utf8");
|
|
expect(configured).toContain("# retained root comment");
|
|
expect(configured).toContain("# caller approval");
|
|
expect(
|
|
parseToml(configured, { integersAsBigInt: "asNeeded" }),
|
|
).toMatchObject({
|
|
model: "caller-model",
|
|
mcp_servers: {
|
|
other: { command: "other" },
|
|
rea: {
|
|
...codexToolPolicy,
|
|
startup_timeout_sec: 19,
|
|
tool_timeout_sec: 999,
|
|
env: {
|
|
CALLER_SETTING: "kept exactly",
|
|
REA_GHIDRA_STARTUP_TIMEOUT_MS: "17000",
|
|
},
|
|
},
|
|
},
|
|
});
|
|
expect(await readFile(`${config}.rea.backup`, "utf8")).toBe(original);
|
|
assertAligned((await run(doctorArguments)).json);
|
|
const repeated = await run([...setupArguments, "--yes"]);
|
|
expect(repeated.exitCode, repeated.stdout).toBe(0);
|
|
expect(repeated.json).toMatchObject({
|
|
status: "ready",
|
|
appliedActions: [],
|
|
});
|
|
expect(await readFile(config, "utf8")).toBe(configured);
|
|
expect(await readFile(`${config}.rea.backup`, "utf8")).toBe(original);
|
|
|
|
const removed = await run(["uninstall", "--json"]);
|
|
expect(removed.exitCode, removed.stdout).toBe(0);
|
|
expect(parseToml(await readFile(config, "utf8"))).toEqual({
|
|
model: "caller-model",
|
|
mcp_servers: { other: { command: "other" } },
|
|
});
|
|
expect(await readFile(`${config}.rea.backup`, "utf8")).toBe(original);
|
|
},
|
|
);
|