mirror of
https://github.com/morluto/rea
synced 2026-10-28 06:46:47 -04:00
75 lines
2.8 KiB
TypeScript
75 lines
2.8 KiB
TypeScript
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
import { expect, it } from "vitest";
|
|
import { createCli } from "../../../src/cli.js";
|
|
import { parseConfig } from "../../../src/config/parseConfig.js";
|
|
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
|
|
|
it("setup carries explicit Hopper loader selections into Cursor without persisting target or unrelated settings", async () => {
|
|
const home = await createTestTempDirectory("rea-setup-loader-environment-");
|
|
const path = join(home, ".cursor/mcp.json");
|
|
await mkdir(join(home, ".cursor"));
|
|
await writeFile(path, '{"caller":"retain"}\n');
|
|
const environment = {
|
|
HOME: home,
|
|
USERPROFILE: home,
|
|
HOPPER_LAUNCHER_PATH: join(home, "missing-hopper"),
|
|
GHIDRA_INSTALL_DIR: join(home, "missing-ghidra"),
|
|
JAVA_HOME: join(home, "missing-java"),
|
|
HOPPER_LOADER_ARGS_JSON: '["", "--loader", "Mach-O"]',
|
|
HOPPER_TARGET_PATH: join(home, "per-target"),
|
|
HOPPER_TARGET_KIND: "executable",
|
|
CALLER_UNRELATED_SETTING: "do not persist",
|
|
};
|
|
const setup = async () => {
|
|
let stdout = "";
|
|
await createCli(environment).serve(
|
|
["setup", "--client", "cursor", "--skill=false", "--yes", "--json"],
|
|
{
|
|
env: environment,
|
|
stdout: (chunk) => {
|
|
stdout += chunk;
|
|
},
|
|
exit: () => undefined,
|
|
},
|
|
);
|
|
return JSON.parse(stdout) as unknown;
|
|
};
|
|
const loaderFromSavedRegistration = async () => {
|
|
const document = JSON.parse(await readFile(path, "utf8"));
|
|
expect(document.caller).toBe("retain");
|
|
const saved = document.mcpServers.rea.env;
|
|
expect(saved).not.toHaveProperty("CALLER_UNRELATED_SETTING");
|
|
expect(saved).not.toHaveProperty("HOPPER_TARGET_PATH");
|
|
expect(saved).not.toHaveProperty("HOPPER_TARGET_KIND");
|
|
const config = parseConfig(saved);
|
|
if (!config.ok) throw config.error;
|
|
return config.value.hopperLoaderArgs;
|
|
};
|
|
|
|
expect(await setup()).toMatchObject({ status: "ready" });
|
|
expect(await loaderFromSavedRegistration()).toEqual([
|
|
"",
|
|
"--loader",
|
|
"Mach-O",
|
|
]);
|
|
const created = await readFile(path, "utf8");
|
|
expect(JSON.parse(created).mcpServers.rea.env.HOPPER_LOADER_ARGS_JSON).toBe(
|
|
environment.HOPPER_LOADER_ARGS_JSON,
|
|
);
|
|
environment.HOPPER_LOADER_ARGS_JSON = "[]";
|
|
expect(await setup()).toMatchObject({ status: "ready" });
|
|
expect(await loaderFromSavedRegistration()).toEqual([]);
|
|
const updated = await readFile(path, "utf8");
|
|
expect(JSON.parse(updated).mcpServers.rea.env.HOPPER_LOADER_ARGS_JSON).toBe(
|
|
"[]",
|
|
);
|
|
environment.HOPPER_LOADER_ARGS_JSON = "{";
|
|
expect(await setup()).toMatchObject({
|
|
status: "needs_human",
|
|
plannedActions: [],
|
|
appliedActions: [],
|
|
});
|
|
expect(await readFile(path, "utf8")).toBe(updated);
|
|
});
|