Compare commits

..
Author SHA1 Message Date
morluto e9c31c4981 Merge main into perf/tests-cli-session-default
Keep this branch's parity test (fresh process versus the session, with
the absent-stdin case). Route the DMG recovery test's CLI calls to fresh
processes, since it checks each command releases its own attachment, and
move a new Rizin caller from sharedCliRun to cli.run.
2026-11-13 22:49:43 -05:00
morluto 5e169583f6 Merge remote-tracking branch 'origin/main' into perf/tests-cli-session-default
# Conflicts:
#	tests/boundary/cli/reconstructionObligationLedgerCli.test.ts
2026-11-13 18:00:07 -05:00
morluto 497fd2acd9 test(cli): give each shared-session command an empty stdin
The shared CLI process reads session frames from its own stdin. A
command that reads stdin without supplied input, such as
`compare-wasm-interfaces - --json`, read that pipe and hung, where a
fresh process receives EOF. The worker now presents an ended, empty
stdin to each command and restores its own afterwards.

The parity test compared the routed path with itself after cli.run
began choosing the session. It now compares a fresh process with the
session directly, including the `mcp add` refusal and a command
reading absent stdin.
2026-11-13 15:24:05 -05:00
morluto 73b207ac64 style(tests): format the managed member summary call site 2026-11-13 15:08:43 -05:00
morluto 5b7f5d2298 perf(tests): run plain CLI commands on the file's shared process
`cli.run` in `cliTest` files started a fresh compiled CLI for every
command, about 0.45s and 260 MB each before any work. The file-scoped
session already existed, but callers had to opt in through
`runFileCli` or `sharedCliRun`, so 1,300 call sites still spawned.

Make the fixture choose: `cli.run` uses the shared process when it
reports the command exactly as a fresh process would, and starts one
otherwise (stdin, explicit deadlines, MCP and MCP doctor routing,
NODE_OPTIONS, or enabled logging). `freshProcess: true` keeps
explicit process-level checks. The session worker now presents the
launcher's entrypoint, so registration identity matches a fresh
process.

`runFileCli` and `sharedCliRun` are superseded and removed; their
call sites use `cli.run`, and paired fresh/shared checks use
`freshProcess`.
2026-11-13 14:44:08 -05:00
morluto 940d7156f6 test(cli): bundle the one-shot entry in the runtime bundle fixture 2026-11-13 14:44:06 -05:00
morluto 06d2413c41 refactor(cli): run one-shot commands through one shared owner
scripts/rea.mjs and the test CLI session worker each implemented the
one-shot command sequence: argument normalization, output admission,
configuration errors, version documents, the Amp scope refusal, and
result delivery. The worker copy had drifted: it never rendered
formatted version reports or the Amp refusal.

Move the sequence into src/cliOneShot.ts. Both callers supply a host
for their streams, exit and resource ownership. The launcher keeps
closed-pipe status, worker shutdown and process exit; the session
worker captures output per command.

The cliOutput bundle entry is superseded and removed. The dispatcher
test now replaces only the command runtime, so output admission runs
production code. A new parity test compares the file session with a
fresh process.
2026-11-13 14:13:07 -05:00
212 changed files with 1101 additions and 1021 deletions

No files matched your search

+12 -9
View File
@@ -307,10 +307,7 @@ assertion. `vitest.config.ts` applies the deadlines in
and 120 seconds for built projects, with hooks sharing their project's
deadline. Coverage doubles every deadline, and so does hosted CI, where
CPU-bound cases share every core with other workers and their subprocesses.
Do not pass a per-test timeout to fit a slow host. A child run through a
test process registry (`processTest`, `cli.run`, or `createTestProcessRegistry`)
gets the running test's remaining deadline less a reporting reserve, so a hung
child fails with its captured output. Pass `timeoutMs` only when the child's deadline is itself under test. Tag a bounded workload that needs longer with
Do not pass a per-test timeout to fit a slow host. Tag a bounded workload that needs longer with
`{ tags: ["long-running"] }`, or a whole file with
`// @module-tag long-running`. Assert elapsed time explicitly when speed is the
behavior under test. Derive an explicit deadline only when a test must outlive
@@ -360,11 +357,17 @@ The process restarts when the environment changes, after 32 commands, or when
the worker reports a resident set of at least 1 GiB. A fatal worker failure
or a broken session frame retires that process and waits for it to exit before
the next command starts.
`cli.run` still starts a fresh process, including stdin and explicit deadlines.
`runFileCli` uses the file session for commands that have neither. Go binary,
IL2CPP metadata, and dylib-resolution commands use that session. File teardown
stops the shared CLI process, including startup still in flight, and does not
open another after close.
In a `cliTest` file, `cli.run` uses that shared process when it reports the
command exactly as a fresh `rea` process would. Both run the same one-shot
owner (`src/cliOneShot.ts`), and the shared process presents the launcher's
entrypoint. A command starts a fresh process instead when it supplies stdin or
an explicit deadline, enters MCP or the MCP doctor (which the launcher routes
first), sets `NODE_OPTIONS`, or enables logging, which writes outside the
per-command capture. Pass `freshProcess: true` for process-level facts such as
startup, signals, or exit, and keep one fresh check beside reused cases where
dispatch itself is under test. `createTestCli` drivers always start a fresh
process. File teardown stops the shared CLI process, including startup still in
flight, and does not open another after close.
`exportedFunctionBindingsCli.test.ts` uses the shared compiled CLI session for
its file and compares its JSON command results with the MCP session. It selects
20-second startup and command deadlines; other callers retain their existing
@@ -296,6 +296,7 @@ it(
process.execPath,
["--import", "tsx", "--input-type=module", "--eval", CATALOG_PROGRAM],
{
timeoutMs: 50_000,
env: {
PATH: process.env.PATH,
SystemRoot: process.env.SystemRoot,
@@ -102,6 +102,7 @@ it("repairs equal-launcher Copilot JSONC syntax while strict JSON and standard J
process.execPath,
["--import", "tsx", entrypoint],
{
timeoutMs: 20_000,
env: {
PATH: process.env.PATH,
SystemRoot: process.env.SystemRoot,
@@ -13,40 +13,29 @@ import { prepareProcessScenarioPlan } from "./ProcessScenarioPreparation.js";
afterEach(() => vi.restoreAllMocks());
/**
* Windows refuses capture before root admission runs. The cancellation cases
* replace admission, so they plan for a platform that reaches it on any host.
*/
const capturePlatform = "linux";
it("rejects observation roots that capture admission rejects", async () => {
const root = await createTestTempDirectory("rea-process-plan-");
const file = join(root, "selected");
await writeFile(file, "not a directory");
const scenario = processScenarioSchema.parse({
executable: process.execPath,
working_directory: root,
filesystem_observation_paths: [join(file, "child")],
});
// A path below a regular file is ENOTDIR on POSIX. Windows reports ENOENT,
// which admission accepts as a root the scenario may create.
it.skipIf(process.platform === "win32")(
"rejects observation roots that capture admission rejects",
async () => {
const root = await createTestTempDirectory("rea-process-plan-");
const file = join(root, "selected");
await writeFile(file, "not a directory");
const scenario = processScenarioSchema.parse({
executable: process.execPath,
working_directory: root,
filesystem_observation_paths: [join(file, "child")],
});
const prepared = await prepareProcessScenarioPlan(
scenario,
{},
process.platform,
);
const prepared = await prepareProcessScenarioPlan(
scenario,
{},
process.platform,
);
expect(prepared.ok).toBe(false);
if (prepared.ok) return;
expect(prepared.error).toMatchObject({
_tag: "ProcessCaptureError",
userMessage: "filesystem observation admission failed",
});
},
);
expect(prepared.ok).toBe(false);
if (prepared.ok) return;
expect(prepared.error).toMatchObject({
_tag: "ProcessCaptureError",
userMessage: "filesystem observation admission failed",
});
});
it("reports cancellation normalized inside admission as planning cancellation", async () => {
const scenario = processScenarioSchema.parse({
@@ -70,7 +59,7 @@ it("reports cancellation normalized inside admission as planning cancellation",
const prepared = await prepareProcessScenarioPlan(
scenario,
{},
capturePlatform,
process.platform,
controller.signal,
);
@@ -111,7 +100,7 @@ it("reports cancellation after the last awaited admission step", async () => {
const planning = prepareProcessScenarioPlan(
scenario,
{},
capturePlatform,
process.platform,
controller.signal,
);
+1 -6
View File
@@ -44,12 +44,7 @@ it("returns the original validated metadata snapshot with its actual descriptor"
});
return handle;
});
// The test just wrote this file. Settling its fresh Windows ChangeTime would
// replace the first observation, so admit it as written on every host.
const descriptor = await openRegularFile(path, {
symlinks: "reject",
changeTime: "as-written",
});
const descriptor = await openRegularFile(path, { symlinks: "reject" });
try {
expect(descriptor.handle).toBe(opened);
expect(descriptor.initial).toBe(validated);
+13 -9
View File
@@ -21,15 +21,19 @@ it("retains escape-heavy strings within a heap near their decoded size", async (
if (!Array.isArray(parsed) || parsed.length !== 463 || parsed.some((value) => value !== body)) process.exit(3);
`;
const child = await processes.run(process.execPath, [
"--max-old-space-size=48",
"--max-semi-space-size=8",
"--import",
"tsx",
"--input-type=module",
"--eval",
program,
]);
const child = await processes.run(
process.execPath,
[
"--max-old-space-size=48",
"--max-semi-space-size=8",
"--import",
"tsx",
"--input-type=module",
"--eval",
program,
],
{ timeoutMs: 30_000 },
);
expect(child.exitCode, child.stderr).toBe(0);
});
+2 -5
View File
@@ -19,10 +19,7 @@ import {
ghidraDolSectionFile,
} from "./GhidraDolProfile.js";
import { GhidraProvider } from "./GhidraProvider.js";
import {
ghidraProfileInstallationHost as host,
simulatedInstallDirectory,
} from "./GhidraInstallation.fixture.js";
import { ghidraProfileInstallationHost as host } from "./GhidraInstallation.fixture.js";
// Abbreviated from Ghidra 12.1.4 ppc.ldefs and x86.ldefs: the stock PowerPC
// default, the optional Broadway variant, and one little-endian language to refuse.
@@ -50,7 +47,7 @@ const configFor = (environment: NodeJS.ProcessEnv) => {
};
const installedConfig = async (environment: NodeJS.ProcessEnv) => {
const installDir = await simulatedInstallDirectory("rea-ghidra-dol-");
const installDir = await createTestTempDirectory("rea-ghidra-dol-");
const languages = join(
installDir,
"Ghidra/Processors/PowerPC/data/languages",
-44
View File
@@ -1,9 +1,3 @@
import { mkdir, mkdtemp, realpath } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join, parse, relative } from "node:path";
import { onTestFinished } from "vitest";
import { normalizeTestTemporaryPrefix } from "../../scripts/lib/test-temporary-ownership.mjs";
import { removeTestWorkspace } from "../../tests/support/workspace/workspaceFixture.js";
import { ok as javaProbeOk, err } from "../domain/result.js";
import type {
GhidraJavaObservation,
@@ -29,44 +23,6 @@ export const ghidraProfileInstallationHost: GhidraInstallationHost = {
}),
};
/**
* A temporary installation directory the simulated Linux host accepts as
* absolute. On Windows it is made under the working directory and spelled as a
* POSIX path on that drive; other hosts get an ordinary test directory. The
* caller owns and disposes the native directory.
*/
export const createSimulatedInstallDirectory = async (
prefix: string,
): Promise<{
readonly path: string;
readonly dispose: () => Promise<void>;
}> => {
const root =
process.platform === "win32"
? join(process.cwd(), "build")
: await realpath(tmpdir());
await mkdir(root, { recursive: true });
const owned = await realpath(
await mkdtemp(join(root, normalizeTestTemporaryPrefix(prefix))),
);
return {
path:
process.platform === "win32"
? `/${relative(parse(owned).root, owned).replaceAll("\\", "/")}`
: owned,
dispose: () => removeTestWorkspace(owned),
};
};
/** Own the simulated directory for a single test. */
export const simulatedInstallDirectory = async (
prefix: string,
): Promise<string> => {
const directory = await createSimulatedInstallDirectory(prefix);
onTestFinished(directory.dispose);
return directory.path;
};
/** A confirmed absent Java command for installation admission fixtures. */
export const missingJavaProbe = err<GhidraJavaProbeFailure>({
_tag: "GhidraJavaProbeFailure",
+24 -13
View File
@@ -1,5 +1,13 @@
import { chmod, mkdir, readdir, rm, writeFile } from "node:fs/promises";
import { join } from "node:path";
import {
chmod,
mkdir,
mkdtemp,
readdir,
rm,
writeFile,
} from "node:fs/promises";
import { tmpdir } from "node:os";
import { join, parse, relative } from "node:path";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { createTestTempDirectory } from "../../tests/fixtures/temporaryDirectory.js";
import { parseConfig } from "../config/parseConfig.js";
@@ -10,10 +18,7 @@ import {
ghidraProfileLanguageOverride,
sameGhidraLanguageOverride,
} from "./GhidraAnalysisProfile.js";
import {
createSimulatedInstallDirectory,
ghidraProfileInstallationHost as host,
} from "./GhidraInstallation.fixture.js";
import { ghidraProfileInstallationHost as host } from "./GhidraInstallation.fixture.js";
import {
admitGhidraLanguageOverride,
parseGhidraLanguageDefinitions,
@@ -101,19 +106,25 @@ const legacyMips: BinaryTarget = {
};
let installDir = "";
let disposeInstallDir: (() => Promise<void>) | undefined;
let ownedInstallDir = "";
beforeAll(async () => {
const directory = await createSimulatedInstallDirectory(
"rea-ghidra-languages-",
);
installDir = directory.path;
disposeInstallDir = directory.dispose;
const root =
process.platform === "win32" ? join(process.cwd(), "build") : tmpdir();
await mkdir(root, { recursive: true });
ownedInstallDir = await mkdtemp(join(root, "rea-ghidra-languages-"));
// The simulated Linux host needs a POSIX absolute path. Keep the owned
// native path for cleanup and derive the simulated path on the same drive.
installDir =
process.platform === "win32"
? `/${relative(parse(ownedInstallDir).root, ownedInstallDir).replaceAll("\\", "/")}`
: ownedInstallDir;
const languages = join(installDir, "Ghidra/Processors/x86/data/languages");
await mkdir(languages, { recursive: true });
await writeFile(join(languages, "x86.ldefs"), X86_LDEFS);
});
afterAll(async () => {
await disposeInstallDir?.();
if (ownedInstallDir !== "")
await rm(ownedInstallDir, { recursive: true, force: true });
});
const provider = (environment: Record<string, string>) => {
+3 -5
View File
@@ -1,6 +1,7 @@
import { describe, expect, it } from "vitest";
import { mkdir, writeFile } from "node:fs/promises";
import { join } from "node:path";
import { createTestTempDirectory } from "../../tests/fixtures/temporaryDirectory.js";
import { ok } from "../domain/result.js";
import { parseConfig } from "../config/parseConfig.js";
import type {
@@ -16,10 +17,7 @@ import {
ghidraMipsProfileMismatchReason,
ghidraMipsProfileParameters,
} from "./GhidraMipsProfile.js";
import {
ghidraProfileInstallationHost as host,
simulatedInstallDirectory,
} from "./GhidraInstallation.fixture.js";
import { ghidraProfileInstallationHost as host } from "./GhidraInstallation.fixture.js";
import { GHIDRA_SESSION_CAPABILITIES } from "./GhidraSessionValues.js";
import type { GhidraMipsSoftFloatReport } from "./GhidraMipsProfile.js";
import {
@@ -47,7 +45,7 @@ const MIPS_LANGUAGE_DEFINITIONS = `<?xml version="1.0" encoding="UTF-8"?>
`;
const installedMipsConfig = async () => {
const installDir = await simulatedInstallDirectory("rea-ghidra-mips-");
const installDir = await createTestTempDirectory("rea-ghidra-mips-");
const languages = join(installDir, "Ghidra/Processors/MIPS/data/languages");
await mkdir(languages, { recursive: true });
await writeFile(join(languages, "mips.ldefs"), MIPS_LANGUAGE_DEFINITIONS);
+18 -8
View File
@@ -1,6 +1,7 @@
import { mkdir, writeFile } from "node:fs/promises";
import { join } from "node:path";
import { describe, expect, it } from "vitest";
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join, parse, relative } from "node:path";
import { describe, expect, it, onTestFinished } from "vitest";
import { parseConfig } from "../config/parseConfig.js";
import type {
BinaryTarget,
@@ -15,10 +16,7 @@ import {
ghidraProfileLanguageOverride,
} from "./GhidraAnalysisProfile.js";
import { GhidraProvider } from "./GhidraProvider.js";
import {
ghidraProfileInstallationHost as host,
simulatedInstallDirectory,
} from "./GhidraInstallation.fixture.js";
import { ghidraProfileInstallationHost as host } from "./GhidraInstallation.fixture.js";
// Abbreviated from Ghidra 12.1.4 Processors/PowerPC/data/languages/ppc.ldefs.
const PPC_LDEFS = `<?xml version="1.0" encoding="UTF-8"?>
@@ -78,7 +76,19 @@ describe("bounded Ghidra PowerPC admission", () => {
});
it("lets a configured language replace the lane default", async () => {
const installDir = await simulatedInstallDirectory("rea-ghidra-ppc-");
const root =
process.platform === "win32" ? join(process.cwd(), "build") : tmpdir();
await mkdir(root, { recursive: true });
const ownedInstallDir = await mkdtemp(join(root, "rea-ghidra-ppc-"));
onTestFinished(async () => {
await rm(ownedInstallDir, { recursive: true, force: true });
});
// The simulated Linux host needs a POSIX absolute path. Keep the owned
// native path for cleanup and derive the simulated path on the same drive.
const installDir =
process.platform === "win32"
? `/${relative(parse(ownedInstallDir).root, ownedInstallDir).replaceAll("\\", "/")}`
: ownedInstallDir;
const languages = join(
installDir,
"Ghidra/Processors/PowerPC/data/languages",
+13 -13
View File
@@ -1,5 +1,6 @@
import { mkdir, readFile, writeFile } from "node:fs/promises";
import { join } from "node:path";
import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join, parse, relative } from "node:path";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { parseConfig } from "../config/parseConfig.js";
import type {
@@ -30,10 +31,7 @@ import {
GHIDRA_SESSION_CAPABILITIES,
type GhidraSessionInfo,
} from "./GhidraSessionValues.js";
import {
createSimulatedInstallDirectory,
ghidraProfileInstallationHost as host,
} from "./GhidraInstallation.fixture.js";
import { ghidraProfileInstallationHost as host } from "./GhidraInstallation.fixture.js";
import {
ghidraPinnedLanguage,
ghidraProfileLanguageOverride,
@@ -109,19 +107,21 @@ const ilp32 = (
});
let installDir = "";
let disposeInstallDir: (() => Promise<void>) | undefined;
beforeAll(async () => {
const directory = await createSimulatedInstallDirectory(
"rea-ghidra-riscv-languages-",
);
installDir = directory.path;
disposeInstallDir = directory.dispose;
const root =
process.platform === "win32" ? join(process.cwd(), "build") : tmpdir();
await mkdir(root, { recursive: true });
installDir = await mkdtemp(join(root, "rea-ghidra-riscv-languages-"));
// The simulated Linux host needs a POSIX absolute path. A current-drive root
// path also reaches this real fixture on Windows without changing admission.
if (process.platform === "win32")
installDir = `/${relative(parse(installDir).root, installDir).replaceAll("\\", "/")}`;
const languages = join(installDir, "Ghidra/Processors/RISCV/data/languages");
await mkdir(languages, { recursive: true });
await writeFile(join(languages, "riscv.ldefs"), RISCV_LDEFS);
});
afterAll(async () => {
await disposeInstallDir?.();
await rm(installDir, { recursive: true, force: true });
});
const ghidra = (environment: Record<string, string> = {}) =>
+2 -3
View File
@@ -10,6 +10,5 @@ export const MCP_SHUTDOWN_FAILED =
"REA could not close cleanly. End the REA process before starting it again.";
export const SERVER_START_FAILED =
"Do not repeat this startup. Tell the user REA could not start and ask them to restart the MCP client, then run `rea doctor`.";
/** The listener error owns recovery for its parsed failure; never its native cause text. */
export const mcpHttpListenFailed = (remediation: string): string =>
`REA could not listen for MCP HTTP connections. ${remediation}`;
export const MCP_HTTP_LISTEN_FAILED =
"REA could not listen for MCP HTTP connections on the selected host and port. Choose another --port or stop the process using it.";
+5 -2
View File
@@ -12,7 +12,7 @@ import type { OptionalProviderLoadResult } from "../application/OptionalObservat
import { OwnedMcpServers } from "./OwnedMcpServers.js";
import {
MCP_CONNECTION_START_FAILED,
mcpHttpListenFailed,
MCP_HTTP_LISTEN_FAILED,
} from "./messages.js";
import { reportMcpTransportError } from "./reportMcpTransportError.js";
@@ -181,7 +181,10 @@ export const startMcpTransport = async (
if (!cancelled) {
const startFailure =
cause instanceof StreamableHttpListenError
? mcpHttpListenFailed(cause.remediationAction)
? cause.classification.ok &&
cause.classification.value.kind === "host_allowlist"
? cause.remediationAction
: MCP_HTTP_LISTEN_FAILED
: MCP_CONNECTION_START_FAILED;
serverLogger.error(
{
+1 -1
View File
@@ -12,7 +12,7 @@ import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
import { cliTest, type TestCli } from "../support/cli/cliFixture.js";
const inspectBoth = async (cli: TestCli, path: string) => {
const output = await cli.sharedCliRun!({
const output = await cli.run({
arguments: [
"inspect-apk-signature",
path,
+1
View File
@@ -29,6 +29,7 @@ cliTest(
"--json",
],
environment: { NODE_OPTIONS: "--max-old-space-size=256" },
timeoutMs: 30000,
});
expect(result.exitCode, result.stderr).toBe(0);
const evidence = toolContract("inspect_apple_ips").outputSchema.parse(
@@ -6,7 +6,7 @@ import { expect } from "vitest";
import { toolContract } from "../../../src/contracts/toolContracts.js";
import { connectLocalToolsMcp } from "../../fixtures/localToolsMcp.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
const SERIAL = "listing-numbers-device";
const UNSAFE = "9007199254740993";
@@ -224,9 +224,10 @@ process.stdout.write(require('node:fs').readFileSync(path));
arguments: [operation.replaceAll("_", "-"), SERIAL, "--json"],
environment,
};
const output = await (variant === "safe"
? cli.run(invocation)
: runFileCli(cli, invocation));
const output = await cli.run({
...invocation,
freshProcess: variant === "safe",
});
expect(output.exitCode, output.stderr).toBe(0);
const evidence = contract.outputSchema.parse(output.json);
expect(evidence.parameters).toMatchObject({ serial: SERIAL });
@@ -9,7 +9,7 @@ import { adbDisplayPartialObservationSchema } from "../../../src/domain/adb/adbD
import { connectLocalToolsMcp } from "../../fixtures/localToolsMcp.js";
import { parseMcpToolError } from "../../fixtures/mcpToolError.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
const SERIAL = "numeric-declarations-device";
const PACKAGE = "com.example.numeric";
@@ -224,9 +224,10 @@ cliTest.skipIf(process.platform === "win32")(
arguments: ["inspect-adb-display", SERIAL, "--json"],
environment: fixture.environment,
};
const output = await (scenario === displayScenarios[0]
? cli.run(invocation)
: runFileCli(cli, invocation));
const output = await cli.run({
...invocation,
freshProcess: scenario === displayScenarios[0],
});
expect(output.exitCode, `${scenario.name}: ${output.stderr}`).toBe(0);
const evidence = contract.outputSchema.parse(output.json);
expect(evidence.parameters).toEqual({ serial: SERIAL });
@@ -281,9 +282,10 @@ cliTest.skipIf(process.platform === "win32")(
arguments: ["inspect-adb-display", SERIAL, "--json"],
environment: fixture.environment,
};
const output = await (value === null
? cli.run(invocation)
: runFileCli(cli, invocation));
const output = await cli.run({
...invocation,
freshProcess: value === null,
});
expect(output.exitCode, output.stderr).toBe(1);
const projected = analysisErrorProjectionSchema.parse(output.json);
expect(projected.code).toBe("unreadable_output");
@@ -454,9 +456,10 @@ cliTest.skipIf(process.platform === "win32")(
arguments: ["inspect-adb-package", SERIAL, PACKAGE, "--json"],
environment: fixture.environment,
};
const output = await (scenario === packageScenarios[0]
? cli.run(invocation)
: runFileCli(cli, invocation));
const output = await cli.run({
...invocation,
freshProcess: scenario === packageScenarios[0],
});
expect(output.exitCode, `${scenario.name}: ${output.stderr}`).toBe(0);
const evidence = contract.outputSchema.parse(output.json);
expect(evidence.parameters).toEqual({ serial: SERIAL, package: PACKAGE });
@@ -8,7 +8,7 @@ import { toolContract } from "../../../src/contracts/toolContracts.js";
import { parseEvidence } from "../../../src/domain/evidence.js";
import { connectLocalToolsMcp } from "../../fixtures/localToolsMcp.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
const PACKAGE_LINE = "package:/data/app/example/base.apk=com.example.app";
@@ -139,9 +139,10 @@ process.exit(91);
arguments: [command, "emulator-5554", ...tail, "--json"],
environment,
};
const output = await (count === 0
? cli.run(invocation)
: runFileCli(cli, invocation));
const output = await cli.run({
...invocation,
freshProcess: count === 0,
});
expect(output.exitCode, output.stderr).toBe(0);
const evidence = parseEvidence(output.json);
expect(
@@ -131,7 +131,7 @@ const checkCliPublication = async (
},
) => {
const { root, path, parent, summary, selected } = context;
const run = cli.sharedCliRun?.bind(cli) ?? cli.run.bind(cli);
const run = cli.run.bind(cli);
const complete = await run({
arguments: ["inspect-api-contract", path, "--json"],
});
@@ -395,7 +395,7 @@ cliTest(
coverage: { total: 3 },
source_coverage: { status: "partial" },
});
const run = cli.sharedCliRun?.bind(cli) ?? cli.run.bind(cli);
const run = cli.run.bind(cli);
const cliResult = await run({
arguments: ["inspect-api-contract", path, "--json"],
});
@@ -442,7 +442,7 @@ cliTest(
details: { partial_observation: snapshot },
});
expect(JSON.stringify(response)).not.toContain("u:p@h");
const run = cli.sharedCliRun?.bind(cli) ?? cli.run.bind(cli);
const run = cli.run.bind(cli);
const result = await run({
arguments: ["inspect-api-contract", path, "--json"],
});
@@ -7,7 +7,7 @@ import { parseEvidence } from "../../../src/domain/evidence.js";
import { javascriptApplicationAnalysisResultSchema } from "../../../src/domain/javascript/javascriptApplicationAnalysis.js";
import { applicationVersionComparisonResultSchema } from "../../../src/domain/javascript/javascriptApplicationVersionComparisonSchemas.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
cliTest(
"keeps unavailable source-selection scopes unknown in version comparisons",
@@ -72,7 +72,7 @@ cliTest(
) => {
const inputPath = join(root, `${name}.json`);
await writeFile(inputPath, JSON.stringify({ left, right }));
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: ["compare-application-versions", inputPath, "--json"],
environment: { REA_LOG_LEVEL: "silent" },
});
@@ -492,7 +492,7 @@ cliTest(
const compare = async (left: unknown, right: unknown) => {
const inputPath = join(root, `comparison-${Math.random()}.json`);
await writeFile(inputPath, JSON.stringify({ left, right }));
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: ["compare-application-versions", inputPath, "--json"],
environment: { REA_LOG_LEVEL: "silent" },
});
@@ -16,6 +16,7 @@ cliTest.for(["", " \t "])(
"--json",
],
environment: { REA_LOG_LEVEL: "silent" },
timeoutMs: 15000,
});
expect(response.exitCode).toBe(1);
expect(response.json).toMatchObject({
@@ -107,7 +107,7 @@ cliTest(
const root = await createTestTempDirectory("rea-beam-views-");
const path = join(root, "app.beam");
await writeFile(path, erlangBeamFixture("views"));
const run = cli.sharedCliRun?.bind(cli) ?? cli.run.bind(cli);
const run = cli.run.bind(cli);
const complete = await run({
arguments: ["inspect-erlang-beam", path, "--json"],
});
@@ -312,7 +312,7 @@ cliTest(
async ({ cli }) => {
const root = await createTestTempDirectory("rea-beam-invalid-view-");
const output = join(root, "unused.json");
const run = cli.sharedCliRun?.bind(cli) ?? cli.run.bind(cli);
const run = cli.run.bind(cli);
const view = JSON.stringify({ kind: "beam", collection: "exports" });
for (const [flags, key] of [
[["--detail", "summary"], "evidence_output"],
@@ -137,7 +137,7 @@ cliTest(
},
}),
);
const run = cli.sharedCliRun?.bind(cli) ?? cli.run.bind(cli);
const run = cli.run.bind(cli);
const result = await run({
arguments: ["compare-artifacts", requestPath, "--json"],
});
@@ -35,7 +35,7 @@ const checkCliPublication = async (
},
) => {
const { root, parent, selected } = context;
const run = cli.sharedCliRun?.bind(cli) ?? cli.run.bind(cli);
const run = cli.run.bind(cli);
const args = [
"inspect-api-contract",
"./SDL 雪.graphql",
@@ -271,7 +271,7 @@ cliTest(
},
}),
);
const run = cli.sharedCliRun?.bind(cli) ?? cli.run.bind(cli);
const run = cli.run.bind(cli);
const offline = await run({
arguments: ["inspect-analysis-view", queryPath, "--json"],
});
@@ -339,7 +339,7 @@ cliTest(
source_coverage: { status: "partial", operations: "unavailable" },
},
});
const run = cli.sharedCliRun?.bind(cli) ?? cli.run.bind(cli);
const run = cli.run.bind(cli);
const cliResult = await run({
arguments: [
"inspect-api-contract",
@@ -392,7 +392,7 @@ cliTest(
items: [{ code: "schema-parse-refused", source: { role: "schema" } }],
});
await writeFile(path, text);
const run = cli.sharedCliRun?.bind(cli) ?? cli.run.bind(cli);
const run = cli.run.bind(cli);
const result = await run({
arguments: [
"inspect-api-contract",
@@ -9,11 +9,7 @@ import { interfaceBuilderAnalysisSchema } from "../../../src/domain/apple/interf
import { thinMach } from "../../../src/domain/binaryTarget.fixture.js";
import { parseEvidence } from "../../../src/domain/evidence.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import {
cliTest,
runFileCli,
type TestCli,
} from "../../support/cli/cliFixture.js";
import { cliTest, type TestCli } from "../../support/cli/cliFixture.js";
const unknownMixedInteger = {
$plist_type: "unknown",
@@ -39,7 +35,7 @@ const inspectArchive = (cli: TestCli, app: string, fresh: boolean) => {
arguments: ["decode-interface-builder", app, "--json"],
environment: { REA_LOG_LEVEL: "silent", REA_ANALYSIS_PROVIDER: "auto" },
};
return fresh ? cli.run(invocation) : runFileCli(cli, invocation);
return cli.run({ ...invocation, freshProcess: fresh });
};
cliTest.for(scenarios)(
@@ -30,6 +30,7 @@ cliTest(
bundlePath,
"--json",
],
timeoutMs: 60_000,
});
expect(response.exitCode).toBe(0);
const bundle = evidenceBundleSchema.parse(
@@ -9,12 +9,16 @@ processTest(
"returns a nonzero exit for a streamed JSON analysis failure",
async ({ processes }) => {
const root = await createTestTempDirectory("rea-cli-js-missing-");
const result = await processes.run(process.execPath, [
"scripts/rea.mjs",
"analyze-javascript-application",
join(root, "missing"),
"--json",
]);
const result = await processes.run(
process.execPath,
[
"scripts/rea.mjs",
"analyze-javascript-application",
join(root, "missing"),
"--json",
],
{ timeoutMs: 20_000 },
);
expect(result.exitCode).toBe(1);
expect(JSON.parse(result.stdout)).toMatchObject({
code: "invalid_request",
@@ -84,6 +84,7 @@ cliTest.skipIf(process.versions.bun !== undefined).for([
environment: {
NODE_OPTIONS: `--max-old-space-size=${String(heapMb)} --max-semi-space-size=8`,
},
timeoutMs: 60_000,
});
expect(response.exitCode).toBe(0);
const result = javascriptApplicationAnalysisResultSchema.parse(
@@ -200,6 +201,7 @@ cliTest.skipIf(process.versions.bun !== undefined)(
environment: {
NODE_OPTIONS: "--max-old-space-size=640 --max-semi-space-size=8",
},
timeoutMs: 75_000,
});
expect(response.stderr).not.toMatch(/FATAL ERROR:.*heap/iu);
expect(
@@ -32,10 +32,11 @@ cliTest.for(["CLI", "stdio MCP"] as const)(
["a", "b"],
[],
]) {
const control = await processes.run(process.execPath, [
join(root, "child.cjs"),
...values,
]);
const control = await processes.run(
process.execPath,
[join(root, "child.cjs"), ...values],
{ timeoutMs: 5_000 },
);
expect(control.exitCode, control.stderr).toBe(0);
counts.push(Number(control.stdout));
}
@@ -27,7 +27,7 @@ cliTest.for(["CLI", "stdio MCP"] as const)(
const control = await processes.run(
process.execPath,
[join(root, "entry.mjs"), "abc", " mode "],
{ env: { REA_ENDPOINT: "endpoint" } },
{ env: { REA_ENDPOINT: "endpoint" }, timeoutMs: 15_000 },
);
expect(control.exitCode, control.stderr).toBe(0);
expect(JSON.parse(control.stdout)).toEqual([
@@ -46,6 +46,7 @@ cliTest(
"directory",
"--json",
],
timeoutMs: 60_000,
});
expect(cliResponse.exitCode).toBe(0);
const cliEvidence = toolContract(
@@ -35,6 +35,7 @@ cliTest(
"directory",
"--json",
],
timeoutMs: 60_000,
});
expect(cliResponse.exitCode).toBe(0);
const cliEvidence = toolContract(
@@ -159,6 +160,7 @@ cliTest(
"directory",
"--json",
],
timeoutMs: 60_000,
});
expect(analyzed.exitCode, analyzed.stderr).toBe(0);
const application = toolContract(
@@ -191,6 +193,7 @@ cliTest(
);
const traced = await cli.run({
arguments: ["trace-javascript-semantics", request, "--json"],
timeoutMs: 60_000,
});
expect(traced.exitCode, traced.stdout).toBe(0);
const trace = javaScriptSemanticTraceResultSchema.parse(
@@ -6,7 +6,7 @@ import { expect } from "vitest";
import { analysisViewResultSchema } from "../../../src/domain/analysisView/analysisView.js";
import { parseEvidence } from "../../../src/domain/evidence.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
cliTest(
"pages only module units for a CommonJS file that exports symbols",
@@ -23,7 +23,7 @@ cliTest(
"exports.beta = function beta() { return 2; };",
].join("\n"),
);
const analyzed = await runFileCli(cli, {
const analyzed = await cli.run({
arguments: ["analyze-javascript-application", root, "--format", "json"],
});
expect(analyzed.exitCode, analyzed.stdout + analyzed.stderr).toBe(0);
@@ -54,7 +54,7 @@ cliTest(
traceInput,
JSON.stringify({ application: evidence, seed }),
);
const traced = await runFileCli(cli, {
const traced = await cli.run({
arguments: ["trace-application-feature", traceInput, "--json"],
});
expect(traced.exitCode, traced.stdout + traced.stderr).toBe(0);
@@ -86,7 +86,7 @@ cliTest(
view,
}),
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-analysis-view", queryPath, "--json"],
});
expect(result.exitCode, result.stdout + result.stderr).toBe(0);
@@ -13,7 +13,6 @@ import { findApplicationFeatureSeeds } from "../../../src/domain/javascript/java
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import {
cliTest,
runFileCli,
type SharedMcpCall,
type TestCli,
} from "../../support/cli/cliFixture.js";
@@ -170,7 +169,7 @@ const traceThroughCli = async (
const invocation = {
arguments: ["trace-application-feature", input, "--json"],
};
const response = await runFileCli(cli, invocation);
const response = await cli.run(invocation);
expect(response.exitCode, `${scenario.name} via CLI`).toBe(0);
const evidence = toolContract("trace_application_feature").outputSchema.parse(
response.json,
@@ -19,6 +19,7 @@ cliTest(
const cliResult = await driver.run({
arguments: ["analyze-javascript-application", root, "--json"],
environment: process.env,
timeoutMs: 15_000,
});
expect(cliResult.exitCode, cliResult.stderr).toBe(0);
const result = javascriptApplicationAnalysisResultSchema.parse(
@@ -591,7 +591,7 @@ cliTest(
const result = await analyzeJavaScriptDirectory(
"CLI",
{ run: (invocation) => cli.run({ ...invocation }) },
{ run: (invocation) => cli.run({ ...invocation, timeoutMs: 20_000 }) },
root,
);
expect(result.statistics.parse_failures).toBe(0);
@@ -8,7 +8,7 @@ import { afterAll, expect } from "vitest";
import { parse as parseYaml } from "yaml";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
afterAll(() => disposeMdItInstance());
@@ -45,9 +45,10 @@ cliTest.for([
const invocation = {
arguments: ["inspect-keyed-archive", path, ...args],
};
return label === "high" || label === "pair"
? cli.run(invocation)
: runFileCli(cli, invocation);
return cli.run({
...invocation,
freshProcess: label === "high" || label === "pair",
});
};
for (const format of ["json", "yaml"] as const) {
const output = await run(["--format", format]);
@@ -120,9 +121,7 @@ cliTest(
const invocation = {
arguments: ["inspect-keyed-archive", path, ...args],
};
return label === "nul"
? cli.run(invocation)
: runFileCli(cli, invocation);
return cli.run({ ...invocation, freshProcess: label === "nul" });
};
const json = await run(["--json"]);
expect(json.exitCode, json.stderr).toBe(0);
@@ -8,7 +8,7 @@ import { expect } from "vitest";
import { keyedArchiveResultSchema } from "../../../src/domain/apple/keyedArchive.js";
import { parseEvidence } from "../../../src/domain/evidence.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
cliTest.for([
{ name: "plain real", element: "<real>1.25</real>", expected: 1.25 },
@@ -74,7 +74,7 @@ cliTest.for([
await writeFile(path, bytes);
const call = await cli.sharedMcpCall?.();
if (call === undefined) throw new Error("Missing file-scoped MCP session");
const output = await runFileCli(cli, {
const output = await cli.run({
arguments: [
"inspect-keyed-archive",
path,
@@ -155,7 +155,7 @@ cliTest(
}).replace("<string>__VALUE__</string>", element),
);
await writeFile(path, bytes);
const output = await runFileCli(cli, {
const output = await cli.run({
arguments: ["inspect-keyed-archive", path, "--json"],
environment: { REA_LOG_LEVEL: "silent" },
});
@@ -19,7 +19,7 @@ import { parseEvidence } from "../../../src/domain/evidence.js";
import { harmonyApplicationProjectionResultSchema } from "../../../src/domain/harmony/harmonyApplication.js";
import { connectLocalToolsMcp } from "../../fixtures/localToolsMcp.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest, type CliInvocation } from "../../support/cli/cliFixture.js";
const harmony = {
family: "HarmonyOS",
@@ -146,10 +146,8 @@ cliTest.for(fixtures)(
const { call } = await connectLocalToolsMcp(environment);
for (const mode of ["directories", "files", "nested"] as const) {
// Keep one fresh dispatcher check per family; reuse later commands.
const run =
mode === "directories"
? cli.run.bind(cli)
: runFileCli.bind(undefined, cli);
const run = (invocation: CliInvocation) =>
cli.run({ ...invocation, freshProcess: mode === "directories" });
const writer = new ZipWriter(new Uint8ArrayWriter());
for (const path of fixture.paths) {
if (mode !== "files")
@@ -324,9 +322,8 @@ cliTest.for([
const environment = { HOME: root, USERPROFILE: root };
const { call } = await connectLocalToolsMcp(environment);
for (const encrypted of [false, true]) {
const run = encrypted
? runFileCli.bind(undefined, cli)
: cli.run.bind(cli);
const run = (invocation: CliInvocation) =>
cli.run({ ...invocation, freshProcess: !encrypted });
const writer = new ZipWriter(new Uint8ArrayWriter());
for (const member of fixture.paths)
await writer.add(
@@ -40,7 +40,7 @@ cliTest.for(["pe", "elf"] as const)(
versionDefinitions: ["fixture", "V1"],
});
await writeFile(path, bytes);
const run = cli.sharedCliRun?.bind(cli) ?? cli.run.bind(cli);
const run = cli.run.bind(cli);
const complete = await run({
arguments: ["inspect-native-exports", path, "--json"],
});
@@ -9,11 +9,7 @@ import { peResourceFixture } from "../../../src/native/pe/PeResources.fixture.js
import { connectLocalToolsMcp } from "../../fixtures/localToolsMcp.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { parseMcpToolError } from "../../fixtures/mcpToolError.js";
import {
cliTest,
runFileCli,
type TestCli,
} from "../../support/cli/cliFixture.js";
import { cliTest, type TestCli } from "../../support/cli/cliFixture.js";
type PeResourceCall = (
arguments_: Record<string, unknown>,
@@ -26,7 +22,7 @@ const expectPeInputFailureAcrossAdapters = async (input: {
readonly reason: "invalid_format" | "invalid_value";
}) => {
const { cli, call, path, reason } = input;
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-pe-resources", path, "--json"],
});
expect(result.exitCode).toBe(1);
@@ -117,7 +113,7 @@ const expectPeWordAlignedRecordsAcrossAdapters = async (input: {
);
const path = join(root, `word-aligned-${plus}-${index}.exe`);
await writeFile(path, fixture.bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-pe-resources", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -208,7 +204,7 @@ const expectPeMappingOwnershipAcrossAdapters = async (
});
continue;
}
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-pe-resources", path, "--json"],
});
expect(result.exitCode, name).toBe(0);
@@ -266,9 +262,7 @@ const expectPeInventoriesAcrossAdapters = async (
};
// Keep an independent public-wrapper process for both PE32 and PE32+.
// The empty-payload variants reuse only compiled-command startup.
const result = await (empty
? runFileCli(cli, invocation)
: cli.run(invocation));
const result = await (empty ? cli.run(invocation) : cli.run(invocation));
expect(result.exitCode).toBe(0);
const evidence = contract.outputSchema.parse(result.json);
const report = peResourcesSchema.parse(evidence.normalized_result);
@@ -348,7 +342,7 @@ const expectPeEmptyBranchesAcrossAdapters = async (
shared ? "shared-empty64.exe" : "empty-branches32.exe",
);
await writeFile(path, fixture.bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-pe-resources", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -73,7 +73,7 @@ cliTest(
(await call("inspect_playwright_trace", { path: fixture.path, view }))
.structuredContent,
).toEqual(selected);
const run = cli.sharedCliRun?.bind(cli) ?? cli.run.bind(cli);
const run = cli.run.bind(cli);
const result = await run({
arguments: ["inspect-playwright-trace", fixture.path, "--json"],
});
@@ -102,7 +102,7 @@ const checkCliPublication = async ({
call: McpCall;
}) => {
const source = { kind: "retained-evidence", evidence_id: parent.evidence_id };
const run = cli.sharedCliRun?.bind(cli) ?? cli.run.bind(cli);
const run = cli.run.bind(cli);
const fullCli = await run({
arguments: ["inspect-playwright-trace", fixture.path, "--json"],
});
@@ -420,7 +420,7 @@ cliTest(
expect(
parseEvidence(full.structuredContent).normalized_result,
).toMatchObject({ items: [{ text: message }] });
const run = cli.sharedCliRun?.bind(cli) ?? cli.run.bind(cli);
const run = cli.run.bind(cli);
const result = await run({
arguments: ["inspect-playwright-trace", fixture.path, "--json"],
});
@@ -74,7 +74,7 @@ cliTest(
const root = await createTestTempDirectory("rea-pyc-views-");
const path = join(root, "module.pyc");
await writeSameNamePyc(path);
const run = cli.sharedCliRun?.bind(cli) ?? cli.run.bind(cli);
const run = cli.run.bind(cli);
const complete = await run({
arguments: ["inspect-python-pyc", path, "--json"],
});
@@ -222,7 +222,7 @@ cliTest(
async ({ cli }) => {
const root = await createTestTempDirectory("rea-pyc-invalid-delivery-");
const output = join(root, "unused.json");
const run = cli.sharedCliRun?.bind(cli) ?? cli.run.bind(cli);
const run = cli.run.bind(cli);
const view = JSON.stringify({
kind: "python-pyc",
collection: "code_objects",
@@ -47,7 +47,7 @@ const prepareInputs = async (cli: TestCli) => {
"f0e7d2c869c811d4272a7b2916c6531c8c6cc7938336a35575e2a6b7b6346714",
);
await writeFile(harPath, harBytes);
const run = cli.sharedCliRun?.bind(cli) ?? cli.run.bind(cli);
const run = cli.run.bind(cli);
const analyzed = await run({
arguments: [
"analyze-javascript-application",
@@ -39,9 +39,11 @@ cliTest.for(["CLI", "stdio MCP"] as const)(
"console.log(JSON.stringify([a, b, c, d, first.length, rest.length, mixed.length]));",
].join("\n"),
});
const control = await processes.run(process.execPath, [
join(root, "entry.mts"),
]);
const control = await processes.run(
process.execPath,
[join(root, "entry.mts")],
{ timeoutMs: 15_000 },
);
expect(control.exitCode, control.stderr).toBe(0);
expect(JSON.parse(control.stdout)).toEqual([
7,
@@ -25,6 +25,7 @@ cliTest(
const cliResult = await driver.run({
arguments: ["inspect-artifact", leftPath, "--json"],
environment: process.env,
timeoutMs: 15_000,
});
expect(cliResult.exitCode, cliResult.stderr).toBe(0);
const cliEvidence = parseEvidence(JSON.parse(cliResult.stdout));
@@ -23,6 +23,7 @@ cliTest(
const result = await driver.run({
arguments: ["inspect-artifact", path, "--detail", "complete", "--json"],
environment: process.env,
timeoutMs: 15_000,
});
expect(result.exitCode, result.stderr).toBe(0);
const inspection = artifactInspectionResultSchema.parse(
@@ -77,6 +77,8 @@ cliTest.skipIf(process.platform !== "darwin")(
expect(before.length).toBeGreaterThan(0);
expect(await attachedImagePaths()).toContain(resolvedImage);
const busy = await cli.run({
// Each command must release its own attachment when its process ends.
freshProcess: true,
arguments: ["inspect-artifact", image, "--json"],
});
expect(busy.exitCode, busy.stdout).toBe(1);
@@ -115,6 +117,7 @@ cliTest.skipIf(process.platform !== "darwin")(
}
expect(await mountedDevices()).toEqual([]);
const control = await cli.run({
freshProcess: true,
arguments: ["inspect-artifact", image, "--json"],
});
expect(control.exitCode, control.stdout).toBe(0);
@@ -39,6 +39,7 @@ cliTest.skipIf(process.platform === "win32")(
"--json",
],
environment: { BROWSER_FIXTURE_SECRET: secret },
timeoutMs: 20_000,
});
expect(response.exitCode, response.stdout + response.stderr).toBe(1);
expect(response.stdout).not.toContain(secret);
@@ -47,6 +47,7 @@ cliTest(
"--total-analysis-timeout-ms",
"1",
],
timeoutMs: 30_000,
});
expect(
interrupted.exitCode,
@@ -73,6 +74,7 @@ cliTest(
const recovered = await cli.run({
arguments: baseArguments,
timeoutMs: 30_000,
});
expect(recovered.exitCode, recovered.stdout + recovered.stderr).toBe(0);
expect(recovered.json).toMatchObject({
@@ -46,6 +46,7 @@ cliTest.for([
const result = await cli.run({
arguments: ["capture-browser-scenario", path, "--json"],
environment: { HOME: home, REA_LOG_LEVEL: "silent" },
timeoutMs: 30_000,
});
expect(result.exitCode).toBe(1);
expect(result.json).toMatchObject(expected);
@@ -2,7 +2,6 @@ import { estimateTokenCount } from "tokenx";
import { expect } from "vitest";
import { workspaceCliTest } from "../support/cli/workspaceCliFixture.js";
import { runFileCli } from "../support/cli/cliFixture.js";
workspaceCliTest(
"applies token controls to SDK manifest and schema documents",
@@ -12,12 +11,15 @@ workspaceCliTest(
const freshTokenCount = arguments_.join(" ") === "--llms --token-count";
const freshTokenLimit =
arguments_.join(" ") === "--llms-full --token-limit 1";
const result = await (!freshTokenCount &&
!freshTokenLimit &&
(arguments_.includes("--token-count") ||
arguments_.includes("--token-limit"))
? runFileCli(cli, invocation)
: cli.run(invocation));
const result = await cli.run({
...invocation,
freshProcess: !(
!freshTokenCount &&
!freshTokenLimit &&
(arguments_.includes("--token-count") ||
arguments_.includes("--token-limit"))
),
});
expect(result.exitCode, result.stderr).toBe(0);
expect(result.stderr).toBe("");
return result.stdout;
+1 -1
View File
@@ -36,7 +36,7 @@ cliTest.for([
bytes[8] = version;
await writeFile(path, bytes);
const hash = createHash("sha256").update(bytes).digest("hex");
const output = await cli.sharedCliRun!({
const output = await cli.run({
arguments: ["inspect-elf-notes", path, "--json"],
});
expect(output.exitCode, output.stderr).toBe(0);
+1 -1
View File
@@ -51,7 +51,7 @@ for (const { bits, ownership, machine } of [
});
await writeFile(path, bytes);
const output = await cli.sharedCliRun!({
const output = await cli.run({
arguments: ["inspect-elf-notes", path, "--json"],
});
expect(output.exitCode, output.stderr).toBe(0);
+1 -1
View File
@@ -65,7 +65,7 @@ for (const target of [
}),
);
const cliOut = await cli.sharedCliRun!({
const cliOut = await cli.run({
arguments: ["inspect-elf-notes", path, "--json"],
});
expect(cliOut.exitCode, cliOut.stderr).toBe(0);
+1 -1
View File
@@ -152,7 +152,7 @@ cliTest(
});
await writeFile(path, bytes);
const output = await cli.sharedCliRun!({
const output = await cli.run({
arguments: ["inspect-elf-notes", path, "--json"],
});
expect(output.exitCode, output.stderr).toBe(0);
+20 -20
View File
@@ -21,7 +21,7 @@ import {
} from "../fixtures/go/image.js";
import { createGoRodataStringFixture } from "../fixtures/go/rodataStringImage.js";
import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../support/cli/cliFixture.js";
import { cliTest } from "../support/cli/cliFixture.js";
import { parseEvidence } from "../../src/domain/evidence.js";
import { connectLocalToolsMcp } from "../fixtures/localToolsMcp.js";
import { expectCliMcpEvidenceParity } from "../fixtures/cliMcpEvidenceParity.js";
@@ -47,7 +47,7 @@ cliTest(
] as const) {
const path = join(root, `${item.name}.macho`);
await writeFile(path, item.bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-go-binary", path, "--json"],
});
const response = await call("inspect_go_binary", { path });
@@ -130,7 +130,7 @@ cliTest(
);
const path = join(root, `${item.name}.elf`);
await writeFile(path, item.fixture.bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-go-binary", path, "--json"],
});
const response = await call("inspect_go_binary", { path });
@@ -199,12 +199,12 @@ cliTest(
const path = join(root, "application.elf");
const output = join(root, "source.json");
await writeFile(path, createGoBinaryFixture().bytes);
const complete = await runFileCli(cli, {
const complete = await cli.run({
arguments: ["inspect-go-binary", path, "--json"],
});
expect(complete.exitCode, complete.stderr).toBe(0);
const full = evidenceResultOf(goBinarySchema).parse(complete.json);
const summary = await runFileCli(cli, {
const summary = await cli.run({
arguments: [
"inspect-go-binary",
path,
@@ -233,7 +233,7 @@ cliTest(
.map((record) => parseEvidence(record))
.find((record) => record.evidence_id === full.evidence_id),
).toEqual(full);
const refused = await runFileCli(cli, {
const refused = await cli.run({
arguments: [
"inspect-go-binary",
join(root, "missing"),
@@ -256,7 +256,7 @@ cliTest(
const root = await createTestTempDirectory("rea-go-overlap-");
const path = join(root, "overlapping.elf");
await writeFile(path, createGoOverlappingElfFixture());
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-go-binary", path, "--json"],
});
expect(result.exitCode).toBe(1);
@@ -289,7 +289,7 @@ cliTest(
const fixture = createGoSplitElfFixture({ sectionless });
const path = join(root, sectionless ? "sectionless.elf" : "original.elf");
await writeFile(path, fixture.bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-go-binary", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -324,7 +324,7 @@ for (const bits of [32, 64] as const) {
] as const) {
const path = join(root, `${label}.exe`);
await writeFile(path, bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-go-binary", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -379,7 +379,7 @@ cliTest(
path,
machoImageWithUnknownCommand(fixture.wide, fixture.size),
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-go-binary", path, "--json"],
});
const response = await call("inspect_go_binary", { path });
@@ -418,7 +418,7 @@ for (const expectedErrno of ["ELOOP", "ENAMETOOLONG"] as const) {
root,
expectedErrno,
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-go-binary", path, "--json"],
});
expect(result.exitCode).toBe(1);
@@ -449,7 +449,7 @@ cliTest(
const path = join(root, "byte-strings.elf");
const fixture = createGoBinaryByteStringFixture();
await writeFile(path, fixture.bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-go-binary", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -467,7 +467,7 @@ for (const fixture of createGoBinaryDiagnosticFixtures()) {
const root = await createTestTempDirectory("rea-go-cli-mz-");
const path = join(root, `${fixture.name}.exe`);
await writeFile(path, fixture.bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-go-binary", path, "--json"],
});
expect(result.exitCode).toBe(1);
@@ -488,7 +488,7 @@ cliTest(
const root = await createTestTempDirectory("rea-go-cli-");
const path = join(root, "text.bin");
await writeFile(path, "This is not an executable container.");
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-go-binary", path, "--json"],
});
expect(result.exitCode).toBe(1);
@@ -508,7 +508,7 @@ for (const format of ["elf", "pe", "macho"] as const) {
const fixture = createGoBinaryFixture({ format, encoding });
const path = join(root, "application.bin");
await writeFile(path, fixture.bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-go-binary", "application.bin", "--json"],
cwd: root,
});
@@ -582,7 +582,7 @@ cliTest("preserves MIPS identity in Go CLI Evidence", async ({ cli }) => {
fixture.bytes.writeUInt16LE(8, 18); // ELF EM_MIPS.
const path = join(root, "application.elf");
await writeFile(path, fixture.bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-go-binary", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -601,7 +601,7 @@ cliTest(
const root = await createTestTempDirectory("rea-go-cli-");
const path = join(root, "metadata-free.elf");
await writeFile(path, createGoBinaryFixture({ omitBuildInfo: true }).bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-go-binary", path, "--json"],
});
expect(result.exitCode).toBe(0);
@@ -625,7 +625,7 @@ cliTest(
const root = await createTestTempDirectory("rea-go-gopath-cli-");
const path = join(root, "application.elf");
await writeFile(path, createGoBinaryFixture({ moduleText }).bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-go-binary", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -662,7 +662,7 @@ cliTest(
});
await writeFile(path, fixture.bytes);
const standaloneCap = await runFileCli(cli, {
const standaloneCap = await cli.run({
arguments: [
"inspect-go-binary",
path,
@@ -680,7 +680,7 @@ cliTest(
},
});
const cliResult = await runFileCli(cli, {
const cliResult = await cli.run({
arguments: [
"inspect-go-binary",
path,
@@ -5,7 +5,7 @@ import { evidenceResultOf } from "../../src/contracts/toolOutputSchemaPrimitives
import { goBinarySchema } from "../../src/domain/go/goBinary.js";
import { createGoBinaryFixture, GO_MODULE_TEXT } from "../fixtures/go/image.js";
import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../support/cli/cliFixture.js";
import { cliTest } from "../support/cli/cliFixture.js";
cliTest(
"inspects ELF64 Go metadata with four-byte amd64p32 pointers through CLI",
@@ -20,7 +20,7 @@ cliTest(
});
const path = join(root, "nacl-amd64p32.nexe");
await writeFile(path, fixture.bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-go-binary", path, "--json"],
});
@@ -12,7 +12,7 @@ import { connectLocalToolsMcp } from "../fixtures/localToolsMcp.js";
import { expectCliMcpEvidenceParity } from "../fixtures/cliMcpEvidenceParity.js";
import { parseMcpToolError } from "../fixtures/mcpToolError.js";
import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../support/cli/cliFixture.js";
import { cliTest } from "../support/cli/cliFixture.js";
cliTest(
"retains header-backed PE and cross-load ELF pointer metadata through CLI and MCP",
@@ -34,7 +34,7 @@ cliTest(
for (const { name, fixture } of cases) {
const path = join(root, name);
await writeFile(path, fixture.bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-go-binary", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -64,7 +64,7 @@ cliTest(
damaged.bytes.writeBigUInt64LE(0x11001n, 200); // A one-byte virtual gap.
const path = join(root, "elf-cross-load-gap");
await writeFile(path, damaged.bytes);
const rejected = await runFileCli(cli, {
const rejected = await cli.run({
arguments: ["inspect-go-binary", path, "--json"],
});
expect(rejected.exitCode).toBe(1);
+22 -22
View File
@@ -13,7 +13,7 @@ import { parseEvidence, createEvidence } from "../../src/domain/evidence.js";
import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
import { connectLocalToolsMcp } from "../fixtures/localToolsMcp.js";
import { parseMcpToolError } from "../fixtures/mcpToolError.js";
import { cliTest, runFileCli } from "../support/cli/cliFixture.js";
import { cliTest } from "../support/cli/cliFixture.js";
import {
cudaFixture,
peGpuFixture,
@@ -38,7 +38,7 @@ cliTest(
] as const) {
const path = join(root, name);
await writeFile(path, bytes);
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: [
"inspect-gpu-code-objects",
path,
@@ -76,7 +76,7 @@ cliTest(
const bytes = cubinFixture({ name: "k".repeat(65_536) });
const path = join(root, "long-symbol.cubin");
await writeFile(path, bytes);
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: [
"inspect-gpu-code-objects",
path,
@@ -124,7 +124,7 @@ cliTest(
const bytes = Buffer.concat([header, compressed]),
path = join(root, `v${version}`);
await writeFile(path, bytes);
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: [
"inspect-gpu-code-objects",
path,
@@ -183,7 +183,7 @@ cliTest(
const bytes = hipFixture(payload, bundleId),
path = join(root, name);
await writeFile(path, bytes);
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: [
"inspect-gpu-code-objects",
path,
@@ -233,7 +233,7 @@ cliTest(
}
const path = join(root, "raw-bitcode");
await writeFile(path, bitcode);
const raw = await runFileCli(cli, {
const raw = await cli.run({
arguments: [
"inspect-gpu-code-objects",
path,
@@ -271,7 +271,7 @@ cliTest(
]),
path = join(root, name);
await writeFile(path, bytes);
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: [
"inspect-gpu-code-objects",
path,
@@ -355,7 +355,7 @@ cliTest(
]),
path = join(root, name);
await writeFile(path, bytes);
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: [
"inspect-gpu-code-objects",
path,
@@ -396,7 +396,7 @@ cliTest(
]),
path = join(root, "large-parameter.cubin");
await writeFile(path, bytes);
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: [
"inspect-gpu-code-objects",
path,
@@ -433,7 +433,7 @@ cliTest(
const bytes = hipFixture(payload, "hip-amdgcn-amd-amdhsa--gfx906+xnack"),
path = join(root, "feature.bundle");
await writeFile(path, bytes);
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: [
"inspect-gpu-code-objects",
path,
@@ -478,7 +478,7 @@ cliTest(
root = await createTestTempDirectory("rea-ptx-callprototype-"),
path = join(root, "prototype.ptx");
await writeFile(path, source);
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: [
"inspect-gpu-code-objects",
path,
@@ -528,7 +528,7 @@ cliTest(
const bytes = cubinFixture({ extendedSectionIndex: true });
const path = join(root, "extended.cubin");
await writeFile(path, bytes);
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: [
"inspect-gpu-code-objects",
path,
@@ -576,7 +576,7 @@ cliTest(
malformedBytes.writeBigUInt64LE(4n, sectionTable + indexTable! * 64 + 32);
const malformedPath = join(root, "short-shndx.cubin");
await writeFile(malformedPath, malformedBytes);
const malformed = await runFileCli(cli, {
const malformed = await cli.run({
arguments: [
"inspect-gpu-code-objects",
malformedPath,
@@ -607,7 +607,7 @@ cliTest(
const text = `.version 7.0\n.target sm_80\n.address_size 64\n.visible .entry kernel() {\n.reg .b32 ${register};\nmov.u32 ${register}, 0;\nret;\n}\n`;
const path = join(root, `${register.slice(1)}.ptx`);
await writeFile(path, text);
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: [
"inspect-gpu-code-objects",
path,
@@ -644,7 +644,7 @@ cliTest(
const text = `.version 8.8\n.target sm_80\n.address_size 64\n.entry %kernel(.param .u32 input) {\nret;\n}\n`;
const path = join(root, "identifiers.ptx");
await writeFile(path, text);
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: [
"inspect-gpu-code-objects",
path,
@@ -707,7 +707,7 @@ cliTest(
const text = `${preamble}${declaration}\n`,
path = join(root, `${name}.ptx`);
await writeFile(path, text);
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: [
"inspect-gpu-code-objects",
path,
@@ -757,7 +757,7 @@ cliTest(
const text = `.version 8.8\n.target compute_80\n.address_size 64\n.entry kernel() {\nret;\n}\n`;
const path = join(root, "target.ptx");
await writeFile(path, text);
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: [
"inspect-gpu-code-objects",
path,
@@ -787,7 +787,7 @@ cliTest(
const text = `.version 1.3\n.target sm_80\n.address_size 64\n.entry kernel {\n.param .u32 input;\nret;\n}\n`;
const path = join(root, "legacy.ptx");
await writeFile(path, text);
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: [
"inspect-gpu-code-objects",
path,
@@ -826,7 +826,7 @@ cliTest(
malformedPath,
`.version 1.3\n.target sm_80\n.entry kernel {\n.param .u32 input\n`,
);
const malformed = await runFileCli(cli, {
const malformed = await cli.run({
arguments: [
"inspect-gpu-code-objects",
malformedPath,
@@ -853,7 +853,7 @@ cliTest(
"attributes malformed selector JSON to its actual CLI option",
async ({ cli }) => {
for (const name of ["object_ids", "targets", "view"]) {
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: [
"inspect-gpu-code-objects",
"/not-opened-for-invalid-selectors",
@@ -893,7 +893,7 @@ cliTest(
},
});
// PowerShell's Get-FileHash prints the digest in upper case.
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: [
"inspect-gpu-code-objects",
"/not-opened-for-invalid-selectors",
@@ -1339,7 +1339,7 @@ cliTest(
] as const) {
const path = join(root, name);
await writeFile(path, bytes);
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: [
"inspect-gpu-code-objects",
path,
+28 -28
View File
@@ -44,7 +44,7 @@ import {
import { connectLocalToolsMcp } from "../fixtures/localToolsMcp.js";
import { parseMcpToolError } from "../fixtures/mcpToolError.js";
import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../support/cli/cliFixture.js";
import { cliTest } from "../support/cli/cliFixture.js";
const parseCliMetadata = (value: unknown) =>
il2cppMetadataSchema.parse(
@@ -75,7 +75,7 @@ cliTest(
}
strings.copy(bytes, 500);
await writeFile(path, bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-il2cpp-metadata", path, "--json"],
});
expect(result.exitCode).toBe(1);
@@ -122,7 +122,7 @@ cliTest(
createLinkedIl2cppMetadataFixture({ version: 39 }).bytes,
);
await writeFile(binaryPath, createIl2cppBinaryFixture());
const produced = await runFileCli(cli, {
const produced = await cli.run({
arguments: [
"inspect-il2cpp-metadata",
path,
@@ -161,7 +161,7 @@ cliTest(
};
const query = join(root, `image-${image}.json`);
await writeFile(query, JSON.stringify(request));
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-analysis-view", query, "--json"],
});
const mcp = await call("inspect_analysis_view", request);
@@ -222,7 +222,7 @@ cliTest(
};
const query = join(root, `${scenario}.json`);
await writeFile(query, JSON.stringify(request));
const cliResult = await runFileCli(cli, {
const cliResult = await cli.run({
arguments: ["inspect-analysis-view", query, "--json"],
});
const mcp = await call("inspect_analysis_view", request);
@@ -249,7 +249,7 @@ cliTest(
});
const path = join(root, `valid-${count}.dat`);
await writeFile(path, bytes);
const output = await runFileCli(cli, {
const output = await cli.run({
arguments: ["inspect-il2cpp-metadata", path, "--json"],
});
expect(output.exitCode, output.stderr).toBe(0);
@@ -282,7 +282,7 @@ cliTest(
);
const path = join(root, `invalid-${declaredCount}-${declaredBytes}.dat`);
await writeFile(path, fixture.bytes);
const output = await runFileCli(cli, {
const output = await cli.run({
arguments: ["inspect-il2cpp-metadata", path, "--json"],
});
expect(output.exitCode).toBe(1);
@@ -321,7 +321,7 @@ cliTest(
propertiesAndEvents: true,
});
await writeFile(path, bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-il2cpp-metadata", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -472,7 +472,7 @@ cliTest(
] as const) {
const path = join(root, name);
await writeFile(path, bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-il2cpp-metadata", path, "--json"],
});
expect(result.exitCode).toBe(1);
@@ -521,7 +521,7 @@ cliTest(
},
},
};
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-il2cpp-metadata", path, "--json"],
});
expect(result.exitCode).toBe(1);
@@ -828,7 +828,7 @@ cliTest(
const root = await createTestTempDirectory("rea-il2cpp-cli-export-");
const path = join(root, "global-metadata.dat");
const bundle = join(root, "evidence.json");
const refused = await runFileCli(cli, {
const refused = await cli.run({
arguments: [
"inspect-il2cpp-metadata",
join(root, "must-not-be-read"),
@@ -852,14 +852,14 @@ cliTest(
bundle,
"--json",
];
const result = await runFileCli(cli, { arguments: args });
const result = await cli.run({ arguments: args });
expect(result.exitCode, result.stderr).toBe(0);
expect(result.json).toMatchObject({
evidence_bundle: { path: bundle, bytes: expect.any(Number) },
summary: { normalized_result: { kind: "summary" } },
});
const before = await readFile(bundle);
const overwrite = await runFileCli(cli, { arguments: args });
const overwrite = await cli.run({ arguments: args });
expect(overwrite.exitCode).toBe(1);
expect(Buffer.compare(await readFile(bundle), before)).toBe(0);
const saved = await readEvidenceBundle(bundle);
@@ -887,7 +887,7 @@ cliTest(
},
}),
);
const selected = await runFileCli(cli, {
const selected = await cli.run({
arguments: ["inspect-analysis-view", query, "--json"],
});
expect(selected.exitCode, selected.stderr).toBe(0);
@@ -913,7 +913,7 @@ cliTest.skipIf(process.platform === "win32")(
const decoy = join(root, "evidence.json");
await writeFile(decoy, "unrelated caller data");
const selected = `${root}/link/../evidence.json`;
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-il2cpp-metadata",
path,
@@ -932,7 +932,7 @@ cliTest.skipIf(process.platform === "win32")(
expect(
JSON.parse(await readFile(join(actual, "evidence.json"), "utf8")),
).toEqual(saved.value);
const read = await runFileCli(cli, {
const read = await cli.run({
arguments: [
"inspect-evidence-bundle",
JSON.stringify({ path: selected, detail: "summary" }),
@@ -966,7 +966,7 @@ cliTest(
rva: `0x${(address - FIXTURE_BINARY_BASE).toString(16)}`,
},
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-il2cpp-metadata",
path,
@@ -1044,7 +1044,7 @@ cliTest(
await writeFile(path, createLinkedIl2cppMetadataFixture().bytes);
await writeFile(binaryPath, createIl2cppDyldBindFixture(0n));
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-il2cpp-metadata",
path,
@@ -1089,7 +1089,7 @@ cliTest(
await writeFile(path, createLinkedIl2cppMetadataFixture().bytes);
const inspect = async (bytes: Buffer) => {
await writeFile(binaryPath, bytes);
const output = await runFileCli(cli, {
const output = await cli.run({
arguments: [
"inspect-il2cpp-metadata",
path,
@@ -1162,7 +1162,7 @@ cliTest(
bytes.fill(0xff, 0x604, 0x608);
const binaryPath = join(root, `registration-${tailBytes}.dylib`);
await writeFile(binaryPath, bytes);
const output = await runFileCli(cli, {
const output = await cli.run({
arguments: [
"inspect-il2cpp-metadata",
path,
@@ -1252,7 +1252,7 @@ cliTest(
const binaryPath = join(root, `${entry.name}.dylib`);
await writeFile(path, entry.metadata.bytes);
await writeFile(binaryPath, entry.binary);
const cliResult = await runFileCli(cli, {
const cliResult = await cli.run({
arguments: [
"inspect-il2cpp-metadata",
path,
@@ -1307,7 +1307,7 @@ cliTest(
{ machine: 62 },
),
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-il2cpp-metadata",
path,
@@ -1338,7 +1338,7 @@ cliTest(
await writeFile(path, createLinkedIl2cppMetadataFixture().bytes);
await writeFile(binaryPath, createElfFixture(createIl2cppBinaryFixture()));
const run = (output: string, extra: readonly string[] = []) =>
runFileCli(cli, {
cli.run({
arguments: [
"inspect-il2cpp-metadata",
path,
@@ -1393,7 +1393,7 @@ cliTest(
});
expect(await readFile(seeds, "utf8")).toBe("kept\n");
const unlinked = await runFileCli(cli, {
const unlinked = await cli.run({
arguments: [
"inspect-il2cpp-metadata",
path,
@@ -1432,7 +1432,7 @@ cliTest(
binaryPath,
createElfFixture(createIl2cppBinaryFixture({ genericMethods: {} })),
);
const linked = await runFileCli(cli, {
const linked = await cli.run({
arguments: [
"inspect-il2cpp-metadata",
path,
@@ -1458,7 +1458,7 @@ cliTest(
].join("\n"),
);
const unlinked = await runFileCli(cli, {
const unlinked = await cli.run({
arguments: [
"inspect-il2cpp-metadata",
path,
@@ -1508,7 +1508,7 @@ cliTest(
const inspect = async (binary: Buffer) => {
await writeFile(binaryPath, binary);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-il2cpp-metadata",
path,
@@ -1551,7 +1551,7 @@ cliTest.skipIf(process.platform === "win32")(
await writeFile(path, createLinkedIl2cppMetadataFixture().bytes);
await writeFile(binaryPath, createElfFixture(createIl2cppBinaryFixture()));
await writeFile(parent, "unchanged");
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-il2cpp-metadata",
path,
@@ -5,7 +5,7 @@ import { createIl2cppMetadataFixture } from "../fixtures/il2cpp/metadata.js";
import { connectLocalToolsMcp } from "../fixtures/localToolsMcp.js";
import { parseMcpToolError } from "../fixtures/mcpToolError.js";
import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../support/cli/cliFixture.js";
import { cliTest } from "../support/cli/cliFixture.js";
cliTest(
"rejects partial IL2CPP table extents through CLI and MCP without a binary",
@@ -24,7 +24,7 @@ cliTest(
});
const path = join(root, `${version}-${name}.dat`);
await writeFile(path, fixture.bytes);
const intact = await runFileCli(cli, {
const intact = await cli.run({
arguments: ["inspect-il2cpp-metadata", path, "--json"],
});
expect(intact.exitCode, intact.stderr).toBe(0);
@@ -35,7 +35,7 @@ cliTest(
fixture.header(name, "size"),
);
await writeFile(path, damaged);
const invalid = await runFileCli(cli, {
const invalid = await cli.run({
arguments: ["inspect-il2cpp-metadata", path, "--json"],
});
const expected = {
@@ -30,6 +30,7 @@ cliTest(
"30000",
"--json",
],
timeoutMs: 55_000,
});
// Analysis retains the interrupted file rather than failing the command.
expect(response.exitCode, `${response.stdout}\n${response.stderr}`).toBe(0);
@@ -29,6 +29,7 @@ cliTest(
}),
"--json",
],
timeoutMs: 60_000,
});
expect(unpublished.exitCode, unpublished.stderr).toBe(1);
expect(unpublished.json).toMatchObject({
@@ -59,6 +60,7 @@ cliTest(
bundle,
"--json",
],
timeoutMs: 60_000,
});
expect(analyzed.exitCode, analyzed.stderr).toBe(0);
const request = (fields?: readonly string[]) =>
@@ -6,7 +6,7 @@ import { expect } from "vitest";
import { parseEvidence } from "../../src/domain/evidence.js";
import { pythonPycFixture } from "../../src/python/PythonPyc.fixture.js";
import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../support/cli/cliFixture.js";
import { cliTest } from "../support/cli/cliFixture.js";
const fileCommands = [
"inspect-sqlite-database",
@@ -51,7 +51,7 @@ cliTest(
},
];
for (const selection of selections) {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [...selection.arguments, "--json"],
cwd,
});
@@ -161,7 +161,7 @@ cliTest(
},
];
for (const selection of selections) {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [...selection.arguments, "--json"],
cwd,
});
@@ -183,7 +183,7 @@ cliTest(
const bytes = pythonPycFixture();
const path = join(cwd, "selected.pyc");
await writeFile(path, bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-python-pyc", "./selected.pyc", "--json"],
cwd,
});
+5 -5
View File
@@ -7,7 +7,7 @@ import { expect } from "vitest";
import { elf, thinMach } from "../../src/domain/binaryTarget.fixture.js";
import { buildManagedPeFixture } from "../../src/dotnet/ManagedPe.fixture.js";
import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../support/cli/cliFixture.js";
import { cliTest } from "../support/cli/cliFixture.js";
cliTest(
"recovers the same managed artifact through decimal CLI budgets and retains caller choices",
@@ -157,7 +157,7 @@ cliTest(
ilBody: Buffer.concat([Buffer.from([(il.length << 2) | 2]), il]),
}),
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-managed-members", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -546,7 +546,7 @@ cliTest(
});
const path = join(root, `virtual-${virtualSectionSize}.dll`);
await writeFile(path, bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-managed-members", path, "--json"],
});
expect(result.exitCode).toBe(0);
@@ -647,7 +647,7 @@ cliTest(
"inspect-managed-members",
"inspect-managed-native-boundaries",
]) {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [command, path, "--json"],
});
expect(result.exitCode).toBe(1);
@@ -682,7 +682,7 @@ cliTest(
"inspect-managed-members",
"inspect-managed-native-boundaries",
]) {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [command, path, "--json"],
});
expect(result.exitCode).not.toBe(0);
@@ -37,7 +37,7 @@ cliTest(
],
] as const) {
const selected = operation === "inspect_managed_members";
const output = await cli.sharedCliRun!({
const output = await cli.run({
arguments: [
command,
path,
@@ -27,7 +27,7 @@ cliTest(
["Inner", "Fixture.Inner"],
["Fixture.Inner"],
]) {
const output = await cli.sharedCliRun!({
const output = await cli.run({
arguments: [
"inspect-managed-members",
path,
@@ -99,7 +99,7 @@ cliTest(
const sha256 = createHash("sha256").update(content).digest("hex");
await writeFile(path, content);
for (const isSelected of [true, false]) {
const output = await cli.sharedCliRun!({
const output = await cli.run({
arguments: [
"inspect-managed-members",
path,
+6 -10
View File
@@ -22,11 +22,7 @@ import {
safetensorsFixture,
} from "../fixtures/model/model.js";
import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
import {
cliTest,
createSharedMcpSession,
runFileCli,
} from "../support/cli/cliFixture.js";
import { cliTest, createSharedMcpSession } from "../support/cli/cliFixture.js";
// Model queries are target-free; share immutable registration and schema setup.
// Portable export keeps its separate post-CLI connection below.
@@ -113,7 +109,7 @@ cliTest(
});
const bytes = Buffer.concat([fixture.bytes, Buffer.alloc(16)]);
await writeFile(path, bytes);
const cliResult = await runFileCli(cli, {
const cliResult = await cli.run({
arguments: [
"inspect-model-artifact",
path,
@@ -365,7 +361,7 @@ cliTest(
tensors,
});
await writeFile(path, fixture.bytes);
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: [
"inspect-model-artifact",
path,
@@ -999,7 +995,7 @@ cliTest(
] as const) {
const path = join(root, name);
await writeFile(path, bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-model-artifact",
path,
@@ -1047,7 +1043,7 @@ cliTest(
Buffer.alloc(0),
).bytes,
);
const mapCli = await runFileCli(cli, {
const mapCli = await cli.run({
arguments: [
"inspect-model-artifact",
mapPath,
@@ -1084,7 +1080,7 @@ cliTest(
safetensorsFixture(`{"__metadata__":${numeric}}`, Buffer.alloc(0))
.bytes,
);
const malformedCli = await runFileCli(cli, {
const malformedCli = await cli.run({
arguments: ["inspect-model-artifact", malformedPath, "--json"],
});
expect(malformedCli.exitCode).toBe(1);
@@ -66,6 +66,7 @@ for (const { jarConfigured, setting } of [
const cliResult = await cli.run({
arguments: ["inspect-android-package", apk, "--json"],
environment,
timeoutMs: 10_000,
});
expect(cliResult.exitCode).toBe(1);
expect(cliResult.json).toMatchObject({ code: "capability_unavailable" });
@@ -90,6 +91,7 @@ cliTest.skipIf(process.platform === "win32")(
const cliResult = await cli.run({
arguments: ["inspect-android-package", apk, "--json"],
environment: { REA_LOG_LEVEL: "silent", ...environment },
timeoutMs: 10_000,
});
expect(cliResult.exitCode).toBe(1);
const client = await connect({ REA_LOG_LEVEL: "silent", ...environment });
@@ -144,6 +146,7 @@ cliTest.skipIf(process.platform !== "linux")(
const cliResult = await cli.run({
arguments: ["inspect-firmware-regions", path, "--json"],
environment,
timeoutMs: 10_000,
});
expect(cliResult.exitCode).toBe(1);
expect(cliResult.json).toMatchObject({ code: "capability_unavailable" });
@@ -169,6 +172,7 @@ cliTest.skipIf(process.platform !== "linux")(
arguments: ["inspect-firmware-regions", "input.bin", "--json"],
cwd: root,
environment: { REA_LOG_LEVEL: "silent" },
timeoutMs: 10_000,
});
// A relative path must pass input validation and reach the provider,
// which reports the missing firmware engine — not a validation error.
@@ -195,6 +199,7 @@ cliTest(
"--json",
],
environment,
timeoutMs: 10000,
});
expect(cliResult.exitCode).toBe(1);
expect(cliResult.json).toMatchObject({ code: "capability_unavailable" });
@@ -234,6 +239,7 @@ cliTest(
"--json",
],
environment,
timeoutMs: 10_000,
});
const response = await client.callTool({
name: "recover_javascript_sources",
@@ -60,6 +60,7 @@ cliTest.skipIf(missingNative)(
const success = await cli.run({
arguments: ["inspect-pcap-capture", single, "--json"],
environment: environmentFor(root),
timeoutMs: 60_000,
});
expect(success.exitCode, success.stderr).toBe(0);
expect(success.stdout.includes(credential)).toBe(false);
@@ -77,6 +78,7 @@ cliTest.skipIf(missingNative)(
const failed = await cli.run({
arguments: ["inspect-pcap-capture", many, "--json"],
environment: environmentFor(root),
timeoutMs: 60_000,
});
expect(failed.exitCode, failed.stderr).toBe(1);
expect(failed.stdout.includes(credential)).toBe(false);
+16 -16
View File
@@ -12,7 +12,7 @@ import {
import { repeatedCertificateSignedData } from "../fixtures/peCertificateAllowance.js";
import { parseMcpToolError } from "../fixtures/mcpToolError.js";
import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../support/cli/cliFixture.js";
import { cliTest } from "../support/cli/cliFixture.js";
cliTest.for([0x00, 0x01, 0x7f, 0xfe, 0xff, null])(
"requires canonical extension critical encoding %s through CLI and MCP",
@@ -41,7 +41,7 @@ cliTest.for([0x00, 0x01, 0x7f, 0xfe, 0xff, null])(
}),
);
await writeFile(path, bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-pe-certificates", path, "--json"],
});
const call = await cli.sharedMcpCall!();
@@ -104,7 +104,7 @@ cliTest.for(["extra-field", "empty-rdn"] as const)(
);
const bytes = peCertificateFixture(false, payload);
await writeFile(path, bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-pe-certificates", path, "--json"],
});
expect.soft(result.exitCode, result.stdout).toBe(1);
@@ -138,7 +138,7 @@ cliTest.for(["pubkey", "signature"])(
expect(at).toBeGreaterThanOrEqual(0);
payload[at + 2] = 1;
await writeFile(path, peCertificateFixture(false, payload));
const invalid = await runFileCli(cli, {
const invalid = await cli.run({
arguments: ["inspect-pe-certificates", path, "--json"],
});
expect(invalid.exitCode).toBe(1);
@@ -159,7 +159,7 @@ cliTest.for(["pubkey", "signature"])(
const last = at + marker.length - 1;
payload[last] = payload[last]! & 0xfe;
await writeFile(path, peCertificateFixture(false, payload));
const valid = await runFileCli(cli, {
const valid = await cli.run({
arguments: ["inspect-pe-certificates", path, "--json"],
});
expect(valid.exitCode, valid.stderr).toBe(0);
@@ -210,7 +210,7 @@ cliTest("reports unsigned attributes through CLI and MCP", async ({ cli }) => {
[1, 3, 6, 1, 4, 1, 311, 3, 3, 1],
]);
await writeFile(path, peCertificateFixture(true, payload));
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-pe-certificates", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -239,7 +239,7 @@ cliTest(
const payload = pkcs7SignedDataIndefiniteEnvelopeFixture();
await writeFile(path, peCertificateFixture(false, payload));
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-pe-certificates", path, "--json"],
});
@@ -297,7 +297,7 @@ cliTest("reports a truncated PE as invalid input", async ({ cli }) => {
const root = await createTestTempDirectory("rea-pe-cert-cli-bad-");
const path = join(root, "broken.exe");
await writeFile(path, Buffer.from("MZ"));
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-pe-certificates", path, "--json"],
});
expect(result.exitCode).toBe(1);
@@ -318,7 +318,7 @@ cliTest(
// Replace an equal-length UTF8String with T.61's acute accent plus 'e'.
Buffer.from([0x14, 0x02, 0xc2, 0x65]).copy(payload, nameAt);
await writeFile(path, peCertificateFixture(false, payload));
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-pe-certificates", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -348,7 +348,7 @@ cliTest(
payload.subarray(4),
]);
await writeFile(path, peCertificateFixture(false, malformed));
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-pe-certificates", path, "--json"],
});
expect(result.exitCode).toBe(1);
@@ -372,7 +372,7 @@ cliTest(
// Equal-size replacement keeps the DER lengths and all unrelated fields intact.
Buffer.from([0x1e, 0x04, 0xd8, 0, 0xdc, 0]).copy(payload, nameAt);
await writeFile(path, peCertificateFixture(false, payload));
const invalid = await runFileCli(cli, {
const invalid = await cli.run({
arguments: ["inspect-pe-certificates", path, "--json"],
});
expect(invalid.exitCode).toBe(1);
@@ -382,7 +382,7 @@ cliTest(
});
Buffer.from([0x1e, 0x04, 0xd7, 0xff, 0xe0, 0]).copy(payload, nameAt);
await writeFile(path, peCertificateFixture(false, payload));
const valid = await runFileCli(cli, {
const valid = await cli.run({
arguments: ["inspect-pe-certificates", path, "--json"],
});
expect(valid.exitCode, valid.stderr).toBe(0);
@@ -407,7 +407,7 @@ cliTest(
// 2025 has no 29 February; the equal-length edit keeps every DER length.
payload.write("250229000000Z", timeAt, "ascii");
await writeFile(path, peCertificateFixture(false, payload));
const invalid = await runFileCli(cli, {
const invalid = await cli.run({
arguments: ["inspect-pe-certificates", path, "--json"],
});
expect(invalid.exitCode).toBe(1);
@@ -417,7 +417,7 @@ cliTest(
});
payload.write("240229000000Z", timeAt, "ascii");
await writeFile(path, peCertificateFixture(false, payload));
const valid = await runFileCli(cli, {
const valid = await cli.run({
arguments: ["inspect-pe-certificates", path, "--json"],
});
expect(valid.exitCode, valid.stderr).toBe(0);
@@ -521,7 +521,7 @@ cliTest.for([
expect(at).toBeGreaterThanOrEqual(0);
payload[at] = tag;
await writeFile(path, peCertificateFixture(false, payload));
const invalid = await runFileCli(cli, {
const invalid = await cli.run({
arguments: ["inspect-pe-certificates", path, "--json"],
});
expect(invalid.exitCode).toBe(1);
@@ -532,7 +532,7 @@ cliTest.for([
// Only restore the string tag: the same bytes are valid UTF8String content.
payload[at] = 0x0c;
await writeFile(path, peCertificateFixture(false, payload));
const valid = await runFileCli(cli, {
const valid = await cli.run({
arguments: ["inspect-pe-certificates", path, "--json"],
});
expect(valid.exitCode, valid.stderr).toBe(0);
+5 -4
View File
@@ -14,7 +14,7 @@ import {
} from "../fixtures/binaryDiagnostics/peImports.js";
import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
import { parseMcpToolError } from "../fixtures/mcpToolError.js";
import { cliTest, runFileCli } from "../support/cli/cliFixture.js";
import { cliTest } from "../support/cli/cliFixture.js";
for (const bits of [32, 64] as const) {
cliTest(
@@ -263,9 +263,10 @@ cliTest(
const invocation = {
arguments: ["inspect-pe-imports", path, "--json"],
};
const result = await (rva === 0xffffffec
? cli.run(invocation)
: runFileCli(cli, invocation));
const result = await cli.run({
...invocation,
freshProcess: rva === 0xffffffec,
});
expect(result.exitCode, result.stderr).toBe(0);
const report = toolContract("inspect_pe_imports").outputSchema.parse(
result.json,
@@ -132,6 +132,7 @@ test.for(["target", "loader"] as const)(
const result = await cli.run({
arguments: ["analyze", target, "--provider", "hopper", "--json"],
environment,
timeoutMs: 15_000,
});
expect(result.exitCode).toBe(1);
expect(result.json).toMatchObject({
@@ -222,6 +223,7 @@ test("recovers a denied Hopper launch through the same stdio MCP session and CLI
const deniedCli = await cli.run({
arguments: ["analyze", target, "--provider", "hopper", "--json"],
environment,
timeoutMs: 15_000,
});
expect(deniedCli.exitCode).toBe(1);
expect(deniedCli.json).toMatchObject({
@@ -160,6 +160,7 @@ cliTest(
const result = await driver.run({
arguments: ["inspect-artifact", path, "--json"],
environment: process.env,
timeoutMs: 15_000,
});
expect(result.exitCode, result.stderr).toBe(0);
const inspection = artifactInspectionResultSchema.parse(
@@ -327,6 +328,7 @@ cliTest(
const result = await driver.run({
arguments: ["extract-artifact", path, "--json"],
environment: process.env,
timeoutMs: 15_000,
});
expect(result.exitCode, result.stderr).toBe(0);
const extraction = artifactExtractionResultSchema.parse(
@@ -390,6 +392,7 @@ cliTest(
const result = await driver.run({
arguments: ["inspect-artifact", path, "--json"],
environment: process.env,
timeoutMs: 15_000,
});
expect(result.exitCode, result.stderr).toBe(0);
const inspection = artifactInspectionResultSchema.parse(
@@ -442,6 +445,7 @@ cliTest(
const result = await driver.run({
arguments: ["inspect-artifact", path, "--json"],
environment: process.env,
timeoutMs: 15_000,
});
expect(result.exitCode, result.stderr).toBe(0);
const inspection = artifactInspectionResultSchema.parse(
@@ -469,6 +473,7 @@ cliTest(
const result = await driver.run({
arguments: ["extract-artifact", path, "--json"],
environment: process.env,
timeoutMs: 15_000,
});
expect(result.exitCode, result.stderr).toBe(0);
const extracted = artifactExtractionResultSchema.parse(
@@ -531,6 +536,7 @@ cliTest(
const inspectResult = await driver.run({
arguments: ["inspect-artifact", path, "--json"],
environment: process.env,
timeoutMs: 15_000,
});
expect(inspectResult.exitCode, inspectResult.stderr).toBe(0);
const inspection = artifactInspectionResultSchema.parse(
@@ -604,6 +610,7 @@ cliTest(
const extractResult = await driver.run({
arguments: ["extract-artifact", path, "--json"],
environment: process.env,
timeoutMs: 15_000,
});
expect(extractResult.exitCode, extractResult.stderr).toBe(0);
const extracted = artifactExtractionResultSchema.parse(
@@ -638,6 +645,7 @@ cliTest(
const result = await driver.run({
arguments: ["inspect-artifact", path, "--json"],
environment: process.env,
timeoutMs: 15_000,
});
expect(result.exitCode, result.stderr).toBe(0);
const inspection = artifactInspectionResultSchema.parse(
@@ -680,6 +688,7 @@ cliTest.for([
const result = await driver.run({
arguments: ["inspect-artifact", path, "--json"],
environment: process.env,
timeoutMs: 15_000,
});
expect(result.exitCode, result.stderr).toBe(0);
const inspection = artifactInspectionResultSchema.parse(
@@ -743,6 +752,7 @@ cliTest.for([
const result = await driver.run({
arguments: ["inspect-artifact", path, "--json"],
environment: process.env,
timeoutMs: 15_000,
});
expect(result.exitCode, result.stderr).toBe(0);
const inspection = artifactInspectionResultSchema.parse(
@@ -790,6 +800,7 @@ cliTest(
const result = await driver.run({
arguments: ["inspect-artifact", path, "--json"],
environment: process.env,
timeoutMs: 15_000,
});
expect(result.exitCode).toBe(1);
expect(result.json).toMatchObject({
+13 -13
View File
@@ -10,7 +10,7 @@ import {
pythonPycHeader,
} from "../../src/python/PythonPyc.fixture.js";
import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../support/cli/cliFixture.js";
import { cliTest } from "../support/cli/cliFixture.js";
const completePycEvidenceSchema = toolContract(
"inspect_python_pyc",
@@ -57,7 +57,7 @@ cliTest(
}),
]),
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-python-pyc", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -77,7 +77,7 @@ cliTest(
}),
]),
);
const ordinaryInt = await runFileCli(cli, {
const ordinaryInt = await cli.run({
arguments: ["inspect-python-pyc", ordinaryIntPath, "--json"],
});
expect(ordinaryInt.exitCode, ordinaryInt.stderr).toBe(0);
@@ -95,7 +95,7 @@ cliTest(
Buffer.alloc(7),
]),
);
const truncated = await runFileCli(cli, {
const truncated = await cli.run({
arguments: ["inspect-python-pyc", truncatedPath, "--json"],
});
expect(truncated.exitCode).toBe(1);
@@ -183,7 +183,7 @@ cliTest(
const path = join(root, `inline-caches-${magic}.pyc`);
await writeFile(path, pyc);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-python-pyc", path, "--json"],
});
expect(
@@ -278,7 +278,7 @@ cliTest(
header[2] = 0x0d;
header[3] = 0x0a;
await writeFile(path, Buffer.concat([header, marshal]));
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-python-pyc", path, "--json"],
});
expect(result.exitCode).toBe(1);
@@ -295,7 +295,7 @@ cliTest(
for (const magic of [3392, 3394]) {
const path = join(root, `${magic}.pyc`);
await writeFile(path, Buffer.concat([pythonPycHeader(magic), marshal]));
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-python-pyc", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -354,7 +354,7 @@ cliTest(
path,
Buffer.concat([pythonPycHeader(magic), marshalCode(layout, fields)]),
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-python-pyc", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -413,7 +413,7 @@ cliTest(
path,
Buffer.concat([pythonPycHeader(magic), marshalCode(layout, fields)]),
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-python-pyc", path, "--json"],
});
expect(result.exitCode).toBe(1);
@@ -503,7 +503,7 @@ cliTest(
}),
]),
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-python-pyc", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -553,7 +553,7 @@ cliTest(
marshalCode(testCase.layout, { consts: [frozenSet, dict] }),
]),
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-python-pyc", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -631,7 +631,7 @@ cliTest(
marshalCode(testCase.layout, { consts: [frozenSet, dict] }),
]),
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-python-pyc", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -662,7 +662,7 @@ cliTest(
}),
]),
);
const rawResult = await runFileCli(cli, {
const rawResult = await cli.run({
arguments: ["inspect-python-pyc", rawPath, "--json"],
});
expect(rawResult.exitCode, rawResult.stderr).toBe(0);
@@ -113,7 +113,7 @@ cliTest.skipIf(process.platform === "win32")(
// Both adapters share the service's classification; the CLI checks one
// refusal and one command diagnostic.
for (const outcome of [outcomes[0]!, outcomes[5]!]) {
const response = await cli.sharedCliRun!({
const response = await cli.run({
arguments: [
"execute-rizin-command",
artifact,
+13 -13
View File
@@ -16,7 +16,7 @@ import {
rustDependencyPayload,
} from "../fixtures/rust/image.js";
import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../support/cli/cliFixture.js";
import { cliTest } from "../support/cli/cliFixture.js";
import { connectLocalToolsMcp } from "../fixtures/localToolsMcp.js";
import { expectCliMcpEvidenceParity } from "../fixtures/cliMcpEvidenceParity.js";
import { parseMcpToolError } from "../fixtures/mcpToolError.js";
@@ -187,7 +187,7 @@ cliTest(
}),
);
if (surface === "cli") {
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: ["inspect-rust-binary", path, "--json"],
});
expect(response.exitCode, response.stderr).toBe(0);
@@ -212,7 +212,7 @@ cliTest(
}
if (surface === "cli") {
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: ["inspect-rust-binary", malformedPath, "--json"],
});
expect(response.exitCode).toBe(1);
@@ -245,7 +245,7 @@ cliTest("returns null metadata when .dep-v0 is absent", async ({ cli }) => {
const root = await createTestTempDirectory("rea-rust-cli-missing-");
const path = join(root, "plain");
await writeFile(path, createRustImage({ format: "elf", omitSection: true }));
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-rust-binary", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -278,7 +278,7 @@ cliTest(
fixture.type,
),
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-rust-binary", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -324,7 +324,7 @@ cliTest(
bytes.writeUInt32LE(0x0200000c, 4);
await writeFile(path, bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-rust-binary", path, "--json"],
});
@@ -356,7 +356,7 @@ cliTest(
],
});
await writeFile(path, createRustImage({ format: "elf", payload }));
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-rust-binary", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -385,7 +385,7 @@ cliTest("rejects malformed dependency JSON", async ({ cli }) => {
includeRustc: false,
}),
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-rust-binary", path, "--json"],
});
expect(result.exitCode).toBe(1);
@@ -410,7 +410,7 @@ cliTest(
}),
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-rust-binary", path, "--json"],
});
expect(result.exitCode).toBe(1);
@@ -442,7 +442,7 @@ cliTest(
bytes.writeUInt32LE(alignedSize, 264 + 16); // .dep-v0 SizeOfRawData
await writeFile(path, bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-rust-binary", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -519,7 +519,7 @@ cliTest(
reported_limits: { maximum_bytes: compressed.length * 64 },
},
};
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-rust-binary", path, "--json"],
});
expect(result.exitCode).toBe(1);
@@ -625,7 +625,7 @@ cliTest(
}
const path = join(root, `mixed.${format}`);
await writeFile(path, bytes);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-rust-binary", path, "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -656,7 +656,7 @@ cliTest(
const response = await call("inspect_rust_binary", { path });
expect(response.isError, JSON.stringify(response)).not.toBe(true);
expectCliMcpEvidenceParity(evidence, response.structuredContent, path);
const go = await runFileCli(cli, {
const go = await cli.run({
arguments: ["inspect-go-binary", path, "--json"],
});
expect(go.exitCode).toBe(1);
+1 -1
View File
@@ -26,7 +26,7 @@ cliTest(
if (name === "writable") bytes.writeBigUInt64LE(3n, 384 + 8);
const path = join(root, `${name}.elf`);
await writeFile(path, bytes);
const output = await cli.sharedCliRun!({
const output = await cli.run({
arguments: ["inspect-rust-binary", path, "--json"],
});
expect(output.exitCode, output.stderr).toBe(0);
@@ -200,6 +200,7 @@ cliTest(
arguments: [...args, "--json"],
cwd: home,
environment,
timeoutMs: 20_000,
});
const plan = await run(["setup", "--client", "dsh", "--dry-run"]);
expect(plan.exitCode).toBe(0);
@@ -50,6 +50,7 @@ for (const version of ["1.1", "1.2"] as const) {
HERMES_HOME: profile,
HOPPER_LAUNCHER_PATH: process.execPath,
},
timeoutMs: 20_000,
});
expect(removed.exitCode).toBe(0);
expect(await readFile(config, "utf8")).toBe(original);
@@ -83,6 +84,7 @@ for (const version of ["1.1", "1.2"] as const) {
GHIDRA_INSTALL_DIR: ghidra,
JAVA_HOME: java,
},
timeoutMs: 20_000,
});
const setup = [
"setup",
@@ -164,6 +166,7 @@ cliTest("Hermes still registers into an explicit table", async ({ cli }) => {
HERMES_HOME: profile,
HOPPER_LAUNCHER_PATH: process.execPath,
},
timeoutMs: 20_000,
});
expect(applied.exitCode).toBe(0);
expect(applied.json).toMatchObject({ status: "ready" });
@@ -206,6 +209,7 @@ for (const version of ["1.1", "1.2"] as const) {
HERMES_HOME: profile,
HOPPER_LAUNCHER_PATH: process.execPath,
},
timeoutMs: 20_000,
});
expect(applied.exitCode).toBe(0);
const configured = parse(await readFile(config, "utf8"), { version });
@@ -233,6 +237,7 @@ cliTest(
HERMES_HOME: profile,
HOPPER_LAUNCHER_PATH: process.execPath,
},
timeoutMs: 20_000,
});
const [command, ...args] = currentClientRegistrationCommand({
entrypointPath: resolve("scripts/rea.mjs"),
@@ -311,6 +316,7 @@ for (const original of [
HERMES_HOME: profile,
HOPPER_LAUNCHER_PATH: process.execPath,
},
timeoutMs: 20_000,
});
expect(rejected.exitCode).not.toBe(0);
expect(rejected.json).toMatchObject({
@@ -23,6 +23,7 @@ const cliLifecycle = (cli: TestCli, home: string, profile: string) => {
arguments: arguments_,
cwd: home,
environment: { HOME: home, USERPROFILE: home, HERMES_HOME: profile },
timeoutMs: 20_000,
});
const setup = [
"setup",
@@ -61,6 +61,7 @@ for (const [version, keyStyle] of [
arguments: arguments_,
cwd: home,
environment: { USERPROFILE: home, HERMES_HOME: profile },
timeoutMs: 20_000,
});
const setup = [
"setup",
@@ -140,6 +141,7 @@ cliTest(
arguments: arguments_,
cwd: home,
environment: { USERPROFILE: home, HERMES_HOME: profile },
timeoutMs: 20_000,
});
const setup = ["setup", "--client", "hermes", "--skill=false", "--json"];
const preview = await run([...setup, "--dry-run"]);
@@ -221,6 +223,7 @@ cliTest(
REA_CLIENT_PROFILE_HOME: home,
HERMES_HOME: " ${REA_CLIENT_PROFILE_HOME}/profile ",
},
timeoutMs: 20_000,
});
const planned = await run([
"setup",
@@ -330,6 +333,7 @@ for (const selection of ["default", "custom", "suffix", "explicit"] as const) {
? root
: undefined,
},
timeoutMs: 20_000,
});
const plan = await run([
"setup",
@@ -464,6 +468,7 @@ for (const selection of [
LOCALAPPDATA: join(home, "AppData", "Local"),
HERMES_HOME: root,
},
timeoutMs: 20_000,
});
if (selection === "missing") {
expect(plan.exitCode).toBe(1);
@@ -568,6 +573,7 @@ for (const layout of ["symlinked-default", "escaping-prefix"] as const) {
LOCALAPPDATA: join(home, "AppData", "Local"),
HERMES_HOME: root,
},
timeoutMs: 20_000,
});
expect(plan.exitCode, plan.stdout).toBe(0);
expect(plan.json).toMatchObject({
@@ -644,6 +650,7 @@ for (const name of ["missing", "deleted", "ghost", "../escape", "root"]) {
arguments: args,
cwd: home,
environment: { USERPROFILE: home, HERMES_HOME: root },
timeoutMs: 20_000,
});
const rejected = await run([
"setup",
@@ -713,6 +720,7 @@ cliTest.skipIf(process.platform === "win32")(
HERMES_HOME: "$REA_HERMES_PROFILE",
REA_HERMES_PROFILE: override,
},
timeoutMs: 20_000,
});
const planned = await run([
"setup",
@@ -775,6 +783,7 @@ cliTest(
arguments: arguments_,
cwd: home,
environment: { USERPROFILE: home, HERMES_HOME: override },
timeoutMs: 20_000,
});
const setup = await run(["setup", "--client", "hermes", "--yes", "--json"]);
expect(setup.exitCode).not.toBe(0);
@@ -161,6 +161,7 @@ cliTest.skipIf(process.platform === "win32").for([
XDG_CONFIG_HOME: join(home, ".config"),
PATH: process.env.PATH ?? "",
},
timeoutMs: 30_000,
});
const setup = await run(registered, [
@@ -295,6 +296,7 @@ cliTest.skipIf(process.platform === "win32")(
XDG_CONFIG_HOME: join(home, ".config"),
PATH: process.env.PATH ?? "",
},
timeoutMs: 30_000,
});
const uninstall = await run(["uninstall", "--json"]);
expect(uninstall.exitCode, uninstall.stderr).toBe(0);
@@ -34,6 +34,7 @@ for (const [variable, profile] of [
PI_CODING_AGENT_DIR: agent,
[variable]: profile,
},
timeoutMs: 20_000,
});
for (const option of ["--dry-run", "--yes"]) {
const rejected = await run(
@@ -100,6 +101,7 @@ cliTest(
OMP_PROFILE: " ",
PI_PROFILE: "Bad Name",
},
timeoutMs: 20_000,
});
expect(result.exitCode).toBe(0);
expect(result.json).toMatchObject({ status: "ready" });
@@ -138,6 +138,7 @@ cliTest(
arguments: arguments_,
cwd: home,
environment,
timeoutMs: 20_000,
});
expect(applied.exitCode).toBe(0);
expect(applied.json).toMatchObject({
@@ -192,6 +193,7 @@ cliTest(
arguments: arguments_,
cwd: home,
environment,
timeoutMs: 20_000,
});
expect(repeated.exitCode).toBe(0);
expect(repeated.json).toMatchObject({
@@ -230,6 +232,7 @@ cliTest(
PI_PROFILE: "legacy",
PI_CONFIG_DIR: ".omp-other",
},
timeoutMs: 20_000,
});
const planned = await run([
@@ -342,6 +345,7 @@ cliTest(
HOPPER_LAUNCHER_PATH: join(home, "unconfigured-hopper"),
PI_CODING_AGENT_DIR: "custom-agent",
},
timeoutMs: 20_000,
});
const run = runIn(created);
const setup = await run(["setup", "--client", "pi", "--yes", "--json"]);
@@ -452,6 +456,7 @@ cliTest(
PI_CODING_AGENT_DIR: "file:///agent%2fdir",
REA_DARWIN_MODULE_CACHE_PATH: moduleCache,
},
timeoutMs: 20_000,
});
const plan = await run([
"setup",
@@ -46,6 +46,7 @@ cliTest(
cli.run({
arguments: arguments_,
cwd: home,
timeoutMs: 20_000,
environment: {
USERPROFILE: home,
PATH: [
+22 -25
View File
@@ -33,7 +33,7 @@ import { createTestTempDirectory } from "../fixtures/temporaryDirectory.js";
import {
cliTest,
createSharedMcpSession,
runFileCli,
type TestCli,
} from "../support/cli/cliFixture.js";
const digest = (bytes: Buffer): string =>
@@ -49,11 +49,8 @@ const parityMcp = createSharedMcpSession(async (registerCleanup, isClosed) => {
afterAll(() => parityMcp.close());
/** Run the offset page through the CLI so the option name is covered as well as the MCP input. */
const pagedCliRows = async (
cli: Parameters<typeof runFileCli>[0],
path: string,
): Promise<unknown> => {
const result = await runFileCli(cli, {
const pagedCliRows = async (cli: TestCli, path: string): Promise<unknown> => {
const result = await cli.run({
arguments: [
"inspect-sqlite-database",
path,
@@ -168,7 +165,7 @@ cliTest.runIf(SQLITE_NATIVE_LIMITS_AVAILABLE)(
`${base}[0,1].value,${base}.1.value`,
`${base}.1.value,${base}[0,1].value`,
]) {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-sqlite-database",
path,
@@ -187,7 +184,7 @@ cliTest.runIf(SQLITE_NATIVE_LIMITS_AVAILABLE)(
},
});
}
const refused = await runFileCli(cli, {
const refused = await cli.run({
arguments: [
"inspect-sqlite-database",
path,
@@ -220,7 +217,7 @@ cliTest.runIf(SQLITE_NATIVE_LIMITS_AVAILABLE)(
} finally {
database.close();
}
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-sqlite-database",
path,
@@ -506,7 +503,7 @@ cliTest.runIf(SQLITE_NATIVE_LIMITS_AVAILABLE)(
},
},
});
const cliResult = await runFileCli(cli, {
const cliResult = await cli.run({
arguments: [
"inspect-sqlite-database",
path,
@@ -672,7 +669,7 @@ cliTest.runIf(SQLITE_NATIVE_LIMITS_AVAILABLE)(
}
const { call } = await connectLocalToolsMcp();
for (const limit of [1001, Number.MAX_SAFE_INTEGER]) {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-sqlite-database",
path,
@@ -896,7 +893,7 @@ cliTest.runIf(SQLITE_NATIVE_LIMITS_AVAILABLE)(
const wal = before[1];
expect(db).toBeDefined();
expect(wal).toBeDefined();
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-sqlite-database",
path,
@@ -962,7 +959,7 @@ cliTest.runIf(SQLITE_NATIVE_LIMITS_AVAILABLE)(
],
},
};
const corrupt = await runFileCli(cli, {
const corrupt = await cli.run({
arguments: ["inspect-sqlite-database", selected, "--json"],
environment: { REA_LOG_LEVEL: "silent" },
});
@@ -998,7 +995,7 @@ cliTest.runIf(SQLITE_NATIVE_LIMITS_AVAILABLE)(
},
},
});
const ambiguous = await runFileCli(cli, {
const ambiguous = await cli.run({
arguments: [
"inspect-sqlite-database",
valid,
@@ -1018,7 +1015,7 @@ cliTest.runIf(SQLITE_NATIVE_LIMITS_AVAILABLE)(
})
).isError,
).toBe(true);
const missing = await runFileCli(cli, {
const missing = await cli.run({
arguments: [
"inspect-sqlite-database",
valid,
@@ -1068,7 +1065,7 @@ cliTest.runIf(SQLITE_NATIVE_LIMITS_AVAILABLE)(
producer.close();
}
const before = await sourceState(path);
const control = await runFileCli(cli, {
const control = await cli.run({
arguments: [
"inspect-sqlite-database",
path,
@@ -1098,7 +1095,7 @@ cliTest.runIf(SQLITE_NATIVE_LIMITS_AVAILABLE)(
const columns = Array.from({ length: selectedColumns }, () => "value");
// The framed fixture executes the compiled public CLI without the host's
// process-argument ceiling rejecting this many repeated flags first.
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-sqlite-database",
path,
@@ -1155,7 +1152,7 @@ cliTest.runIf(SQLITE_NATIVE_LIMITS_AVAILABLE)(
const path = createSqliteApplicationCollationFixture(root);
const before = await sourceState(path);
const { call } = await connectLocalToolsMcp();
const schema = await runFileCli(cli, {
const schema = await cli.run({
arguments: [
"inspect-sqlite-database",
path,
@@ -1194,7 +1191,7 @@ cliTest.runIf(SQLITE_NATIVE_LIMITS_AVAILABLE)(
expect(schemaResponse.isError).not.toBe(true);
expect(schemaResponse.structuredContent).toMatchObject(expectedSchema);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-sqlite-database",
path,
@@ -1269,7 +1266,7 @@ cliTest.runIf(SQLITE_NATIVE_LIMITS_AVAILABLE)(
},
};
for (const columns of [["b", "a"], undefined]) {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-sqlite-database",
path,
@@ -1290,7 +1287,7 @@ cliTest.runIf(SQLITE_NATIVE_LIMITS_AVAILABLE)(
});
expect(parseMcpToolError(response).error).toMatchObject(expectedError);
}
const base = await runFileCli(cli, {
const base = await cli.run({
arguments: [
"inspect-sqlite-database",
path,
@@ -1347,7 +1344,7 @@ cliTest.runIf(SQLITE_NATIVE_LIMITS_AVAILABLE)(
"selected_table",
"database",
] as const) {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-sqlite-database",
path,
@@ -1400,7 +1397,7 @@ cliTest.runIf(SQLITE_NATIVE_LIMITS_AVAILABLE)(
["UTF-16be", "database"],
] as const) {
const { path, names } = createSqliteLongNameFixture(root, encoding);
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: [
"inspect-sqlite-database",
path,
@@ -1492,7 +1489,7 @@ cliTest.runIf(SQLITE_NATIVE_LIMITS_AVAILABLE)(
native.close();
}
const cliResult = await runFileCli(cli, {
const cliResult = await cli.run({
arguments: [
"inspect-sqlite-database",
path,
@@ -1571,7 +1568,7 @@ cliTest.runIf(SQLITE_NATIVE_LIMITS_AVAILABLE)(
producer.close();
}
const original = await readFile(path);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-sqlite-database", path, "--json"],
environment: { REA_LOG_LEVEL: "silent" },
});
@@ -9,7 +9,7 @@ import { historicalHar } from "../../fixtures/historicalHar.js";
import { connectLocalToolsMcp } from "../../fixtures/localToolsMcp.js";
import { parseMcpToolError } from "../../fixtures/mcpToolError.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
cliTest(
"omits HAR extension payloads from capture previews while retaining complete records",
@@ -166,10 +166,10 @@ cliTest(
"--json",
],
};
const output =
label === "null-timings"
? await cli.run(invocation)
: await runFileCli(cli, invocation);
const output = await cli.run({
...invocation,
freshProcess: label === "null-timings",
});
expect(output.exitCode).toBe(1);
const expected = {
code: "invalid_request",
@@ -12,7 +12,7 @@ import {
import { createEvidence, parseEvidence } from "../../../src/domain/evidence.js";
import { artifactInventoryResultSchema } from "../../../src/domain/artifactGraph.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
const graphExamples = [
{
@@ -112,10 +112,10 @@ cliTest.for(graphExamples)(
const invocation = {
arguments: [command, JSON.stringify(input), "--json"],
};
const result =
code === "evidence_integrity_mismatch"
? await cli.run(invocation)
: await runFileCli(cli, invocation);
const result = await cli.run({
...invocation,
freshProcess: code === "evidence_integrity_mismatch",
});
expect(result.exitCode).toBe(1);
expect(result.json).toMatchObject({
code,
@@ -3,7 +3,7 @@ import { join } from "node:path";
import { expect } from "vitest";
import {
cliTest,
runFileCli,
type CliInvocation,
type TestCli,
} from "../../support/cli/cliFixture.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
@@ -173,7 +173,7 @@ const verifyPortableCli = async (
);
const original = await readFile(bundlePath);
await writeFile(inputPath, JSON.stringify({ ...input, detail: "complete" }));
const cliFull = await runFileCli(cli, {
const cliFull = await cli.run({
arguments: [
"match-native-functions",
inputPath,
@@ -187,7 +187,7 @@ const verifyPortableCli = async (
expect(cliFull.exitCode, cliFull.stderr).toBe(0);
expect(parseEvidence(cliFull.json).evidence_id).toBe(evidenceId);
await writeFile(inputPath, JSON.stringify(input));
const cliSummary = await runFileCli(cli, {
const cliSummary = await cli.run({
arguments: [
"match-native-functions",
inputPath,
@@ -222,7 +222,7 @@ const verifyPortableCli = async (
expect(ids.has(unrelated.evidence_id)).toBe(false);
expect(ids.has(evidenceId)).toBe(true);
expect(Buffer.compare(await readFile(bundlePath), original)).toBe(0);
const incomplete = await runFileCli(cli, {
const incomplete = await cli.run({
arguments: [
"match-native-functions",
inputPath,
@@ -508,8 +508,8 @@ cliTest(
"right_observations",
] as const) {
// Keep fresh-process coverage for both source-admission routes on left.
const run =
field === "left" ? cli.run.bind(cli) : runFileCli.bind(undefined, cli);
const run = (invocation: CliInvocation) =>
cli.run({ ...invocation, freshProcess: field === "left" });
const observation = field.endsWith("observations");
const request = {
left,
@@ -581,7 +581,7 @@ cliTest(
detail: "complete",
};
await writeFile(requestPath, JSON.stringify(inlineRequest));
const inline = await runFileCli(cli, {
const inline = await cli.run({
arguments: ["match-native-functions", requestPath, "--json"],
});
await writeFile(
@@ -589,7 +589,7 @@ cliTest(
JSON.stringify(createEvidenceBundle([wrongRole, right])),
);
await writeFile(requestPath, JSON.stringify(portableRequest));
const portable = await runFileCli(cli, {
const portable = await cli.run({
arguments: [
"match-native-functions",
requestPath,
@@ -611,7 +611,7 @@ cliTest(
const corruptRequest = { left: badCoordinate, right, detail: "complete" };
await writeFile(requestPath, JSON.stringify(corruptRequest));
const corruptInline = await runFileCli(cli, {
const corruptInline = await cli.run({
arguments: ["match-native-functions", requestPath, "--json"],
});
const corruptPortableRequest = {
@@ -623,7 +623,7 @@ cliTest(
detail: "complete",
};
await writeFile(requestPath, JSON.stringify(corruptPortableRequest));
const corruptPortable = await runFileCli(cli, {
const corruptPortable = await cli.run({
arguments: [
"match-native-functions",
requestPath,
@@ -641,7 +641,7 @@ cliTest(
const malformedBundlePath = join(root, "malformed-outer-frame.json");
await writeFile(malformedBundlePath, JSON.stringify({ records: [left] }));
const malformedBundle = await runFileCli(cli, {
const malformedBundle = await cli.run({
arguments: [
"match-native-functions",
requestPath,
@@ -17,7 +17,7 @@ import {
withPassiveDroppedEvents,
} from "../../fixtures/passiveNetworkCapture.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
type Capture = {
inspection: CompareWebCapturesInput["before"]["inspection"];
@@ -516,9 +516,10 @@ cliTest.for(cases.filter(({ name }) => cliCaseNames.has(name)))(
arguments: ["compare-web-captures", ...paths, "--json"],
environment: { REA_LOG_LEVEL: "silent" },
};
const response = await (scenario.name === "heterogeneous HTTP omission 0"
? cli.run(invocation)
: runFileCli(cli, invocation));
const response = await cli.run({
...invocation,
freshProcess: scenario.name === "heterogeneous HTTP omission 0",
});
expect(response.exitCode, response.stderr).toBe(0);
expectComparison(response.json, scenario);
},
@@ -10,7 +10,7 @@ import {
withPassiveDroppedEvents,
} from "../../fixtures/passiveNetworkCapture.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
const comparisonCases = () => {
const before = passiveNetworkCapture();
@@ -191,9 +191,10 @@ cliTest.for(cases)(
arguments: ["compare-web-captures", ...paths, "--json"],
environment: { REA_LOG_LEVEL: "silent" },
};
const response = await (name === "added" || name === "removed"
? cli.run(options)
: runFileCli(cli, options));
const response = await cli.run({
...options,
freshProcess: name === "added" || name === "removed",
});
expect(response.exitCode, response.stderr).toBe(0);
expectComparison(response.json, name, change);
expect(
@@ -9,7 +9,7 @@ import {
} from "node:fs/promises";
import { join } from "node:path";
import { expect } from "vitest";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import {
protobufCaptureDescriptor,
@@ -649,9 +649,10 @@ captureTest.for(
"--json",
],
};
const response = await (name === "valid"
? cli.run(options)
: runFileCli(cli, options));
const response = await cli.run({
...options,
freshProcess: name === "valid",
});
expect(response.exitCode, response.stdout + response.stderr).toBe(0);
const evidence = parseEvidence(response.json);
const report = webNetworkCaptureSchema.parse(evidence.normalized_result);
@@ -147,7 +147,7 @@ cliTest(
},
};
if (change === "declarations") {
const output = await cli.sharedCliRun!({
const output = await cli.run({
arguments: [
"inspect-web-network-capture",
capture,
@@ -254,7 +254,7 @@ cliTest(
const bytes = writer.finish();
const descriptor = join(root, `${mode}.pb`);
await writeFile(descriptor, bytes);
const output = await cli.sharedCliRun!({
const output = await cli.run({
arguments: [
"inspect-web-network-capture",
capture,
@@ -132,7 +132,7 @@ cliTest.for([
const descriptor = join(root, `${variant}.pb`);
const bytes = toBinary(FileDescriptorSetSchema, definition);
await writeFile(descriptor, bytes);
const output = await cli.sharedCliRun!({
const output = await cli.run({
arguments: [
"inspect-web-network-capture",
capture,
@@ -222,7 +222,7 @@ cliTest(
const definition = toBinary(FileDescriptorSetSchema, valid);
await writeFile(capture, protobufHar(body, "application/x-protobuf"));
await writeFile(descriptor, definition);
const output = await cli.sharedCliRun!({
const output = await cli.run({
arguments: [
"inspect-web-network-capture",
capture,
@@ -30,7 +30,7 @@ cliTest(
const path = join(root, `${index}.har`);
const original = protobufHar(body, mime);
await writeFile(path, original);
const output = await cli.sharedCliRun!({
const output = await cli.run({
arguments: [
"inspect-web-network-capture",
path,
@@ -109,7 +109,7 @@ cliTest(
await writeFile(path, original);
const call = await cli.sharedMcpCall!();
for (const framing of ["auto", "raw"] as const) {
const output = await cli.sharedCliRun!({
const output = await cli.run({
arguments: [
"inspect-web-network-capture",
path,
@@ -233,7 +233,7 @@ cliTest(
const mime = 'application/protobuf;encoding="binary';
const original = protobufHar(body, mime);
await writeFile(path, original);
const output = await cli.sharedCliRun!({
const output = await cli.run({
arguments: [
"inspect-web-network-capture",
path,
@@ -117,7 +117,7 @@ cliTest(
// Both orders cross the actual CLI adapter; other geometries reuse
// the production MCP session and the same application workflow.
if (scope === "same-file") {
const output = await cli.sharedCliRun!({
const output = await cli.run({
arguments: [
"inspect-web-network-capture",
capture,
@@ -124,7 +124,7 @@ cliTest(
},
];
const call = await cli.sharedMcpCall!();
const run = cli.sharedCliRun!.bind(cli);
const run = cli.run.bind(cli);
for (const test of cases) {
const request = {
source: { kind: "inline", evidence: test.evidence },
Loaded 100 of 212 files, more files were not shown because too many files have changed in this diff. Show more