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
83 changed files with 564 additions and 542 deletions

No files matched your search

+11 -5
View File
@@ -357,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
+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,
@@ -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" },
});
@@ -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)(
@@ -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,
@@ -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",
@@ -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);
@@ -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 = {
@@ -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);
+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,
+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);
+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 },
@@ -1,7 +1,7 @@
import { describe, expect } from "vitest";
import { nativeDataTypeInputSchema } from "../../../src/domain/native/nativeDataType.js";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
const selectors = [
["function", "procedure", "analyze_function"],
@@ -101,7 +101,7 @@ describe("CLI analysis selector boundaries", () => {
["selector", `--${option}=selector`],
]) {
const label = `${command} ${selection.join(" ")}`;
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
command,
"does-not-exist",
@@ -174,7 +174,7 @@ cliTest(
[["--address", "0x1000"], { code: "target_unavailable" }],
] as const) {
const label = `inspect-native-data-type ${selection.join(" ")}`;
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-native-data-type",
"does-not-exist",
+48 -47
View File
@@ -16,7 +16,7 @@ import { expect } from "vitest";
import { TextReader, Uint8ArrayWriter, ZipWriter } from "@zip.js/zip.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
import {
analysisViewLayoutEvidence,
@@ -119,7 +119,7 @@ cliTest(
);
await writeFile(path, JSON.stringify(createEvidenceBundle([parent])));
const inspect = async (view: JsonValue) => {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-analysis-view",
JSON.stringify({
@@ -177,7 +177,7 @@ cliTest(
]);
const original = JSON.stringify(bundle);
await writeFile(path, original);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-analysis-view",
JSON.stringify(request),
@@ -216,10 +216,10 @@ cliTest(
"--json",
],
};
const rejected =
source.kind === "inline"
? await cli.run(invocation)
: await runFileCli(cli, invocation);
const rejected = await cli.run({
...invocation,
freshProcess: source.kind === "inline",
});
expect(rejected.exitCode).toBe(1);
expect(rejected.json).toMatchObject({ code: expectedCode });
expect(rejected.json).not.toHaveProperty("evidence_id");
@@ -251,9 +251,10 @@ cliTest(
};
// Keep a fresh-process integrity check for the altered bundle while the
// worker must reread the same path for the other invalid inputs.
const rejected = freshProcess
? await cli.run(invocation)
: await runFileCli(cli, invocation);
const rejected = await cli.run({
...invocation,
freshProcess: freshProcess,
});
expect(rejected.exitCode).toBe(1);
expect(rejected.json).toMatchObject({ code: expectedCode });
expect(rejected.json).not.toHaveProperty("evidence_id");
@@ -280,7 +281,7 @@ cliTest(
view: { kind: "native", facet: "callees", offset: 0, limit: 1 },
}),
);
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: ["inspect-analysis-view", request, "--json"],
});
expect(response.exitCode).toBe(0);
@@ -319,7 +320,7 @@ cliTest(
const expected = await inspectAnalysisView(input);
if (!expected.ok) throw expected.error;
await writeFile(request, JSON.stringify(input));
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: ["inspect-analysis-view", request, "--json"],
});
expect(response.exitCode).toBe(0);
@@ -360,7 +361,7 @@ cliTest(
view: { kind: "api-surface", include_query_parameter_names: true },
}),
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-analysis-view", path, "--json"],
});
expect(result.exitCode).toBe(0);
@@ -390,7 +391,7 @@ cliTest(
await writer.add("main.js", new TextReader("console.log('portable');\n"));
await writeFile(archive, await writer.close());
const bundlePath = join(root, "inspection-bundle.json");
const inspected = await runFileCli(cli, {
const inspected = await cli.run({
arguments: [
"inspect-artifact",
archive,
@@ -440,7 +441,7 @@ cliTest(
view: { kind: "page", collection: "sections", offset: 0, limit: 20 },
};
await writeFile(unsupportedRequest, JSON.stringify(unsupportedInput));
const unsupported = await runFileCli(cli, {
const unsupported = await cli.run({
arguments: ["inspect-analysis-view", unsupportedRequest, "--json"],
});
expect(unsupported.exitCode).toBe(1);
@@ -468,7 +469,7 @@ cliTest(
},
}),
);
const projected = await runFileCli(cli, {
const projected = await cli.run({
arguments: ["inspect-analysis-view", request, "--json"],
});
expect(projected.exitCode).toBe(0);
@@ -497,7 +498,7 @@ cliTest(
const writer = new ZipWriter(new Uint8ArrayWriter());
await writer.add("main.js", new TextReader("console.log(1);\n"));
await writeFile(archive, await writer.close());
const inspected = await runFileCli(cli, {
const inspected = await cli.run({
arguments: ["inspect-artifact", archive, "--json"],
});
expect(inspected.exitCode).toBe(0);
@@ -541,10 +542,10 @@ cliTest(
};
// Exercise a valid and a malformed parent in fresh processes as well
// as the shared worker's repeated reads of the rewritten input path.
const reply =
group === "manifest" && variant !== "missing"
? await cli.run(invocation)
: await runFileCli(cli, invocation);
const reply = await cli.run({
...invocation,
freshProcess: group === "manifest" && variant !== "missing",
});
expect(reply.stderr).toBe("");
if (variant === "valid") {
expect(application.ok).toBe(true);
@@ -599,7 +600,7 @@ cliTest(
],
});
await writeFile(path, JSON.stringify(request));
const refused = await runFileCli(cli, {
const refused = await cli.run({
arguments: ["inspect-analysis-view", path, "--json"],
});
expect(refused.exitCode).toBe(1);
@@ -648,7 +649,7 @@ cliTest(
view: { kind: "api-surface" },
}),
);
const refused = await runFileCli(cli, {
const refused = await cli.run({
arguments: ["inspect-analysis-view", path, "--json"],
environment,
});
@@ -679,7 +680,7 @@ cliTest(
view: { kind: "api-surface" },
}),
);
const response = await runFileCli(cli, {
const response = await cli.run({
arguments: ["inspect-analysis-view", path, "--json"],
environment,
});
@@ -716,7 +717,7 @@ cliTest(
detail: "summary" as const,
filters: { evidence_id: parent.evidence_id },
};
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-evidence-bundle",
JSON.stringify({ path, ...options }),
@@ -729,7 +730,7 @@ cliTest(
if (!expected.ok) throw expected.error;
expect(result.json).toEqual(expected.value);
// The same shared owner selects the complete record from the portable file.
const records = await runFileCli(cli, {
const records = await cli.run({
arguments: [
"inspect-evidence-bundle",
JSON.stringify({ path, ...options, detail: "records", limit: 1 }),
@@ -746,7 +747,7 @@ cliTest(
records: [parent],
missing_evidence_links: [],
});
const complete = await runFileCli(cli, {
const complete = await cli.run({
arguments: [
"inspect-evidence-bundle",
JSON.stringify({ path }),
@@ -781,7 +782,7 @@ cliTest(
detail: "links",
traversal: "retained-closure",
} as const;
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-evidence-bundle",
JSON.stringify({ path, ...options }),
@@ -850,7 +851,7 @@ cliTest(
};
{
const json = await runFileCli(cli, {
const json = await cli.run({
arguments: [
"inspect-analysis-view",
input,
@@ -869,7 +870,7 @@ cliTest(
).toHaveLength(rowCount);
}
const markdown = await runFileCli(cli, {
const markdown = await cli.run({
arguments: [
"inspect-analysis-view",
input,
@@ -908,7 +909,7 @@ cliTest(
const input = join(root, "view.json");
await mkdir(root, { recursive: true });
await writeFile(input, JSON.stringify(request));
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-analysis-view", input, "--json"],
environment: {
HOME: root,
@@ -934,7 +935,7 @@ cliTest(
const root = await createTestTempDirectory("rea-empty-layout-view-cli-");
const empty = analysisViewLayoutEvidence(binaryLayoutFixture());
for (const collection of ["sections", "symbols"] as const) {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-analysis-view",
JSON.stringify({
@@ -965,7 +966,7 @@ cliTest(
expect(result.json).not.toHaveProperty("details.issues.0.minimum");
expect(result.json).not.toHaveProperty("details.issues.0.maximum");
}
const populated = await runFileCli(cli, {
const populated = await cli.run({
arguments: [
"inspect-analysis-view",
JSON.stringify({
@@ -1022,7 +1023,7 @@ cliTest(
view: { kind: "native", facet: "pseudocode", offset: 0, limit: 12 },
}),
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-analysis-view", input, "--json"],
environment: { HOME: root, XDG_CONFIG_HOME: root, XDG_CACHE_HOME: root },
});
@@ -1065,7 +1066,7 @@ cliTest(
{ kind: "summary" },
{ kind: "evm", facet: "bytecode_hex", offset: 0, limit: 4 },
]) {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-analysis-view",
JSON.stringify({
@@ -1087,7 +1088,7 @@ cliTest(
cliTest("rejects malformed JSON before projection", async ({ cli }) => {
const root = await createTestTempDirectory("rea-analysis-view-cli-bad-");
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-analysis-view", "{", "--json"],
environment: {
HOME: root,
@@ -1107,7 +1108,7 @@ cliTest("rejects a request that omits source", async ({ cli }) => {
const root = await createTestTempDirectory("rea-analysis-view-cli-missing-");
const input = join(root, "missing-source.json");
await writeFile(input, JSON.stringify({ view: { kind: "summary" } }));
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-analysis-view", input, "--json"],
environment: {
HOME: root,
@@ -1142,7 +1143,7 @@ for (const [view, reason] of [
view,
}),
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-analysis-view", input, "--json"],
environment: {
HOME: root,
@@ -1195,7 +1196,7 @@ cliTest(
XDG_CACHE_HOME: root,
};
await writeFile(capturePath, bytes);
const capture = await runFileCli(cli, {
const capture = await cli.run({
arguments: ["inspect-web-network-capture", capturePath, "har", "--json"],
environment,
});
@@ -1212,7 +1213,7 @@ cliTest(
view: { kind: "api-surface" },
}),
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-analysis-view", input, "--json"],
environment,
});
@@ -1266,7 +1267,7 @@ cliTest(
view,
}),
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-analysis-view", requestPath, "--json"],
});
expect(result.exitCode, result.stdout).toBe(0);
@@ -1312,7 +1313,7 @@ cliTest(
},
}),
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-analysis-view", path, "--json"],
});
expect(result.exitCode, result.stdout).toBe(0);
@@ -1348,7 +1349,7 @@ cliTest(
view: { kind: "environment-manifest" },
}),
);
const refused = await runFileCli(cli, {
const refused = await cli.run({
arguments: ["inspect-analysis-view", path, "--json"],
});
expect(refused.exitCode).toBe(1);
@@ -1383,7 +1384,7 @@ cliTest(
},
}),
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-analysis-view", path, "--json"],
});
expect(result.exitCode, result.stdout).toBe(0);
@@ -1457,7 +1458,7 @@ cliTest.for([
view: { kind: "environment-state" },
});
await writeFile(path, request);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-analysis-view", path, "--json"],
});
expect(result.exitCode, result.stdout).toBe(0);
@@ -1485,7 +1486,7 @@ cliTest(
const root = await createTestTempDirectory("rea-manifest-chain-cli-");
const capturePath = join(root, "capture.har");
await writeFile(capturePath, JSON.stringify(environmentManifestHar()));
const capture = await runFileCli(cli, {
const capture = await cli.run({
arguments: ["inspect-web-network-capture", capturePath, "har", "--json"],
});
expect(capture.exitCode, capture.stdout).toBe(0);
@@ -1498,7 +1499,7 @@ cliTest(
view: { kind: "environment-manifest" },
}),
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-analysis-view", input, "--json"],
});
expect(result.exitCode, result.stdout).toBe(0);
+11 -15
View File
@@ -4,11 +4,7 @@ import { join } from "node:path";
import { describe, expect } from "vitest";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import {
cliTest,
runFileCli,
type CliResult,
} from "../../support/cli/cliFixture.js";
import { cliTest, type CliResult } from "../../support/cli/cliFixture.js";
const SESSION_ID = "27d3e3f1-f1e5-49ae-91ec-95af1f343a5a";
const NON_INTEGER_TEXT = [
@@ -132,7 +128,7 @@ describe("CLI integer arguments", () => {
cliTest.for(NON_INTEGER_OPTION_TEXT)(
"rejects %j as an Android reference overload index",
async (value, { cli }) => {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"trace-android-references",
"/nonexistent/missing.apk",
@@ -149,7 +145,7 @@ describe("CLI integer arguments", () => {
cliTest.for(NON_INTEGER_TEXT)(
"rejects %j as a Cutter expected generation",
async (value, { cli }) => {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["cutter-command", SESSION_ID, value, "pdi", "--json"],
});
@@ -160,7 +156,7 @@ describe("CLI integer arguments", () => {
cliTest.for(NON_INTEGER_TEXT)(
"rejects %j as a web module script index",
async (value, { cli }) => {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"trace-web-module-imports",
"/nonexistent/manifest.json",
@@ -176,7 +172,7 @@ describe("CLI integer arguments", () => {
cliTest.for(NON_INTEGER_OPTION_TEXT)(
"rejects %j in a repeated web capture record selector",
async (value, { cli }) => {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-web-network-capture",
"/nonexistent/capture.qlog",
@@ -206,7 +202,7 @@ describe("byte-entropy window options", () => {
cliTest.for(values)(
`rejects %j as a byte-entropy ${flag} value`,
async (value, { cli }) => {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-byte-entropy",
await entropySample(),
@@ -225,7 +221,7 @@ describe("byte-entropy window options", () => {
async ({ cli }) => {
const path = await entropySample();
const window = async (...flags: string[]): Promise<unknown> => {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["inspect-byte-entropy", path, ...flags, "--json"],
});
expect(result.exitCode, result.stdout).toBe(0);
@@ -271,7 +267,7 @@ describe("pyc and BEAM limit options", () => {
cliTest.for(values)(
`rejects %j as ${command} ${flag}`,
async (value, { cli }) => {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
command,
"/nonexistent/missing-artifact",
@@ -289,7 +285,7 @@ describe("pyc and BEAM limit options", () => {
["inspect-python-pyc", "--max-depth=016"],
["inspect-erlang-beam", "--max-chunks=016"],
] as const)("keeps a decimal %s limit", async ([command, flag], { cli }) => {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [command, "/nonexistent/missing-artifact", flag, "--json"],
});
@@ -322,7 +318,7 @@ describe("artifact decimal options", () => {
cliTest.for(values)(
`rejects %j as ${command} ${flag}`,
async (value, { cli }) => {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
command,
"/nonexistent/missing-artifact",
@@ -337,7 +333,7 @@ describe("artifact decimal options", () => {
}
cliTest("keeps decimal keyed-archive offset and limit", async ({ cli }) => {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"inspect-keyed-archive",
"/nonexistent/missing-archive",
@@ -1,6 +1,6 @@
import { expect } from "vitest";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
const invalidLogLevelMessage =
'REA configuration is invalid: REA_LOG_LEVEL: Invalid option: expected one of "trace"|"debug"|"info"|"warn"|"error"|"fatal"|"silent".\n';
@@ -23,7 +23,7 @@ for (const level of ["loud", "INFO"])
};
for (const doctor of [
await cli.run(doctorInvocation),
await runFileCli(cli, doctorInvocation),
await cli.run(doctorInvocation),
]) {
expect(doctor.exitCode, doctor.stderr).toBe(1);
expect(doctor.stderr).toBe("");
@@ -83,7 +83,7 @@ cliTest(
environment: { REA_LOG_LEVEL: "loud" },
};
const fresh = await cli.run(invocation);
const shared = await runFileCli(cli, invocation);
const shared = await cli.run(invocation);
for (const result of [fresh, shared]) {
expect(result.exitCode, JSON.stringify(arguments_)).toBe(1);
expect(result.stdout, JSON.stringify(arguments_)).toBe("");
@@ -98,7 +98,7 @@ cliTest(
environment: { REA_LOG_LEVEL: "loud", COMPLETE: "bash" },
};
const fresh = await cli.run(completion);
const shared = await runFileCli(cli, completion);
const shared = await cli.run(completion);
for (const result of [fresh, shared]) {
expect(result.exitCode).toBe(1);
expect(result.stdout).toBe("");
+22 -8
View File
@@ -1,10 +1,13 @@
import { expect } from "vitest";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import {
cliProcessEnvironment,
cliTest,
definedCliEnvironment,
} from "../../support/cli/cliFixture.js";
// The file session and the executable run one shared one-shot owner. These
// commands are answered before the command runtime loads, which is where a
// separate session implementation previously diverged.
// The file session and the executable run one shared one-shot owner. Compare
// a fresh process with the session itself: `cli.run` may route either way.
cliTest.for([
{ name: "a formatted version report", arguments: ["--version", "--json"] },
{
@@ -15,16 +18,27 @@ cliTest.for([
name: "a rejected output combination",
arguments: ["capabilities", "--json", "--token-limit", "5"],
},
{
// The session's own stdin carries its frames; a command that reads
// stdin must see the same empty input a fresh process does.
name: "a command reading absent stdin",
arguments: ["compare-wasm-interfaces", "-", "--json"],
},
])(
"the file session reports $name exactly as a fresh process does",
async ({ arguments: arguments_ }, { cli }) => {
async ({ arguments: arguments_ }, { cli, cliCommandSession }) => {
const environment = { REA_LOG_LEVEL: "silent" };
const fresh = await cli.run({ arguments: arguments_, environment });
const shared = await runFileCli(cli, {
const fresh = await cli.run({
arguments: arguments_,
environment,
freshProcess: true,
});
expect(fresh.stdout).not.toBe("");
const shared = await cliCommandSession.run({
arguments: arguments_,
cwd: process.cwd(),
environment: definedCliEnvironment(cliProcessEnvironment(environment)),
});
expect(fresh.stdout + fresh.stderr).not.toBe("");
expect({
exitCode: shared.exitCode,
stdout: shared.stdout,
@@ -193,7 +193,7 @@ cliTest(
before.dom = { total_nodes: 0, nodes: [] };
after.dom = { total_nodes: 0, nodes: [] };
}
const result = await cli.sharedCliRun!({
const result = await cli.run({
arguments: [
"compare-web-captures",
JSON.stringify({ inspection: before }),
+19 -23
View File
@@ -17,11 +17,7 @@ import {
import { dylibResolutionResultSchema } from "../../../src/domain/apple/dylibResolution.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 ENVIRONMENT = { REA_LOG_LEVEL: "silent", REA_ANALYSIS_PROVIDER: "auto" };
@@ -50,7 +46,7 @@ const expectRootInputError = async (
readonly message: string;
},
): Promise<void> => {
const rejected = await runFileCli(cli, {
const rejected = await cli.run({
arguments: ["trace-dylib-resolution", app, "--root", root, "--json"],
environment: ENVIRONMENT,
});
@@ -121,7 +117,7 @@ cliTest.skipIf(process.platform !== "linux")(
]),
machoImage({}),
);
const observed = await runFileCli(cli, {
const observed = await cli.run({
arguments: ["trace-dylib-resolution", app, "--json"],
environment: ENVIRONMENT,
});
@@ -141,7 +137,7 @@ cliTest(
async ({ cli }) => {
const app = await fixtureApp();
await symlink("unexamined", join(app, "Contents", "LinkedResources"));
const observed = await runFileCli(cli, {
const observed = await cli.run({
arguments: ["trace-dylib-resolution", app, "--json"],
environment: ENVIRONMENT,
});
@@ -179,7 +175,7 @@ cliTest(
],
}),
});
const output = await runFileCli(cli, {
const output = await cli.run({
arguments: ["trace-dylib-resolution", app, "--json"],
environment: ENVIRONMENT,
});
@@ -373,7 +369,7 @@ for (const dependency of ["eager", "lazy", "none", "conditional"] as const) {
async ({ cli }) => {
const { app, root, nested, uncertain } =
await loadedSiblingFixture(dependency);
const output = await runFileCli(cli, {
const output = await cli.run({
arguments: ["trace-dylib-resolution", join(app, root), "--json"],
environment: ENVIRONMENT,
});
@@ -466,7 +462,7 @@ for (const dependency of ["eager", "lazy", "none", "conditional"] as const) {
describe("trace-dylib-resolution CLI", () => {
cliTest("traces every executable root of an app bundle", async ({ cli }) => {
const app = await fixtureApp();
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["trace-dylib-resolution", app, "--json"],
environment: ENVIRONMENT,
});
@@ -517,7 +513,7 @@ describe("trace-dylib-resolution CLI", () => {
"narrows roots and architecture, and rejects escaping roots",
async ({ cli }) => {
const app = await fixtureApp();
const narrowed = await runFileCli(cli, {
const narrowed = await cli.run({
arguments: [
"trace-dylib-resolution",
app,
@@ -573,7 +569,7 @@ describe("trace-dylib-resolution CLI", () => {
}),
"unrelated.txt": "not traversed",
});
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"trace-dylib-resolution",
join(directory, "tool"),
@@ -598,7 +594,7 @@ describe("trace-dylib-resolution CLI", () => {
async ({ cli }) => {
const app = await fixtureApp();
await withBrokenHelper(app);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["trace-dylib-resolution", app, "--json"],
environment: ENVIRONMENT,
});
@@ -649,7 +645,7 @@ cliTest(
});
}
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["trace-dylib-resolution", app, "--json"],
environment: ENVIRONMENT,
});
@@ -706,7 +702,7 @@ cliTest(
commands: [buildVersionCommand(1)],
}),
});
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["trace-dylib-resolution", join(directory, "tool"), "--json"],
environment: ENVIRONMENT,
});
@@ -756,7 +752,7 @@ describe.skipIf(process.platform === "win32" || process.getuid?.() === 0)(
});
await chmod(join(directory, "libsecret.dylib"), 0o000);
try {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"trace-dylib-resolution",
join(directory, "tool"),
@@ -804,7 +800,7 @@ cliTest(
],
}),
});
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"trace-dylib-resolution",
app,
@@ -877,7 +873,7 @@ cliTest(
{ cpu: CPU.x86_64, bytes: machoImage({ cpu: CPU.x86_64 }) },
]),
});
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"trace-dylib-resolution",
app,
@@ -931,7 +927,7 @@ cliTest(
commands: [buildVersionCommand(1)],
}),
});
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"trace-dylib-resolution",
app,
@@ -988,7 +984,7 @@ cliTest(
],
}),
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["trace-dylib-resolution", path, "--json"],
environment: ENVIRONMENT,
});
@@ -1036,7 +1032,7 @@ describe("trace-dylib-resolution root enumeration", () => {
"classifies every Mach-O among more files than one batch of magic reads",
async ({ cli }) => {
const app = await crowdedApp();
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["trace-dylib-resolution", app, "--json"],
environment: ENVIRONMENT,
});
@@ -1067,7 +1063,7 @@ describe("trace-dylib-resolution root enumeration", () => {
await writeFile(secret, "x");
await chmod(secret, 0o000);
try {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["trace-dylib-resolution", app, "--json"],
environment: ENVIRONMENT,
});
@@ -7,11 +7,7 @@ import { z } from "zod";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { connectLocalToolsMcp } from "../../fixtures/localToolsMcp.js";
import { writeFixtureFiles } from "../../support/javascriptApplicationFixture.js";
import {
cliTest,
runFileCli,
type TestCli,
} from "../../support/cli/cliFixture.js";
import { cliTest, type TestCli } from "../../support/cli/cliFixture.js";
import { javascriptApplicationAnalysisResultSchema } from "../../../src/domain/javascript/javascriptApplicationAnalysis.js";
import { applicationFeatureTraceResultSchema } from "../../../src/domain/javascript/javascriptFeatureTraceSchemas.js";
import { analyzeJavaScriptDirectory } from "../../support/cli/javascriptApplication.js";
@@ -223,7 +219,7 @@ cliTest(
direction: "outgoing",
}),
);
const traced = await runFileCli(cli, {
const traced = await cli.run({
arguments: ["trace-application-feature", input, "--json"],
});
expect(traced.exitCode).toBe(0);
@@ -425,7 +421,7 @@ cliTest(
"main.cjs": `const { ipcMain, clipboard } = require("electron");
ipcMain.handle("nested:write", (event, value) => clipboard.writeText(value));`,
});
const output = await runFileCli(cli, {
const output = await cli.run({
arguments: ["analyze-javascript-application", root, "--json"],
});
expect(output.exitCode, output.stderr).toBe(0);
@@ -467,7 +463,7 @@ cliTest(
direction: "outgoing",
}),
);
const traced = await runFileCli(cli, {
const traced = await cli.run({
arguments: ["trace-application-feature", traceInput, "--json"],
});
expect(traced.exitCode).toBe(0);
@@ -495,7 +491,7 @@ cliTest(
"main.js": `const { ipcMain } = require("electron");
ipcMain.on("write", (event) => event.sender.copy());`,
});
const output = await runFileCli(cli, {
const output = await cli.run({
arguments: ["analyze-javascript-application", root, "--json"],
});
expect(output.exitCode).toBe(0);
@@ -552,7 +548,7 @@ cliTest(
"main.js": `const { ipcMain } = require("electron");
ipcMain.handle("nested:write", (event, value) => value);`,
});
const output = await runFileCli(cli, {
const output = await cli.run({
arguments: ["analyze-javascript-application", root, "--json"],
});
expect(output.exitCode).toBe(0);
@@ -585,7 +581,7 @@ cliTest(
direction: "outgoing",
}),
);
const traced = await runFileCli(cli, {
const traced = await cli.run({
arguments: ["trace-application-feature", traceInput, "--json"],
});
expect(traced.exitCode).toBe(0);
@@ -855,7 +851,7 @@ cliTest(
e.ipcMain.on("shallow:run", event => event.sender.copy());
e.ipcMain.on("deep:run", event => event.sender.copy());`,
});
const output = await runFileCli(cli, {
const output = await cli.run({
arguments: ["analyze-javascript-application", root, "--json"],
});
expect(output.exitCode).toBe(0);
@@ -909,7 +905,7 @@ cliTest(
"main.cjs": `const e=require("electron");
e.ipcMain.on("shared:run", event => event.sender.copy());`,
});
const output = await runFileCli(cli, {
const output = await cli.run({
arguments: ["analyze-javascript-application", root, "--json"],
});
expect(output.exitCode, output.stderr).toBe(0);
@@ -944,7 +940,7 @@ cliTest(
join(root, "main.cjs"),
'const e=require("electron"); e.ipcMain.on("shared:run", () => {}); e.ipcMain.on("shared:run", () => {});',
);
const competing = await runFileCli(cli, {
const competing = await cli.run({
arguments: ["analyze-javascript-application", root, "--json"],
});
expect(competing.exitCode, competing.stderr).toBe(0);
@@ -975,7 +971,7 @@ cliTest(
"main.cjs": `const { ipcMain } = require("electron");
ipcMain.on("empty:key", event => event.sender.copy());`,
});
const output = await runFileCli(cli, {
const output = await cli.run({
arguments: ["analyze-javascript-application", root, "--json"],
});
expect(output.exitCode).toBe(0);
@@ -22,7 +22,7 @@ import {
updateResidualUnknown,
} from "../../../src/domain/residualUnknown.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
const revisionBundle = () => {
const records = ["open", "investigate"].map((operation) =>
@@ -78,7 +78,7 @@ cliTest(
[["compare", "bundle.json", ""], "right"],
[["evidence-export", "missing.json", ""], "output"],
] as const) {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [...args, "--json"],
cwd: root,
});
@@ -138,7 +138,7 @@ cliTest(
["evidence-export", { source: " bundle.json", output: " exported.json" }],
["compare", { left: " bundle.json", right: " other.json" }],
] as const) {
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [command, "--schema", "--json"],
});
expect(result.exitCode, result.stderr).toBe(0);
@@ -246,7 +246,7 @@ cliTest.for([
: operation === "compare-left"
? ["compare", path, canonical]
: ["compare", canonical, path];
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [...arguments_, "--json"],
environment: { REA_LOG_LEVEL: "silent" },
});
@@ -325,7 +325,7 @@ cliTest(
await writeFile(source, JSON.stringify(bundle));
for (const full of [false, true]) {
const output = join(root, `${label}-${String(full)}.json`);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: [
"evidence-export",
source,
@@ -387,7 +387,7 @@ cliTest(
{ ...bundle, unknowns: bundle.unknowns.slice(1) },
]) {
await writeFile(path, JSON.stringify(invalid));
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["evidence-import", path, "--json"],
});
expect(result.exitCode).toBe(1);
@@ -414,7 +414,7 @@ cliTest(
);
await writeFile(path, JSON.stringify(createEvidenceBundle([record])));
const output = await runFileCli(cli, {
const output = await cli.run({
arguments: [
"inspect-evidence-bundle",
JSON.stringify({ path, detail: "complete" }),
@@ -466,12 +466,12 @@ cliTest(
"--filter-output",
"records.0.normalized_result",
];
const json = await runFileCli(cli, { arguments: [...base, "--json"] });
const json = await cli.run({ arguments: [...base, "--json"] });
expect(json.exitCode, json.stderr).toBe(0);
expect(json.stdout).toContain(JSON.stringify(result.text));
expect(json.stdout).toContain(JSON.stringify(result.type));
expect(json.stdout).toContain(JSON.stringify(result.literal));
const markdown = await runFileCli(cli, {
const markdown = await cli.run({
arguments: [...base, "--format", "md"],
});
expect(markdown.exitCode, markdown.stderr).toBe(0);
@@ -497,7 +497,7 @@ cliTest(
records: [record],
};
await writeFile(path, JSON.stringify(bundle));
const imported = await runFileCli(cli, {
const imported = await cli.run({
arguments: ["evidence-import", path, "--json"],
});
expect(imported.exitCode).toBe(1);
+5 -5
View File
@@ -6,7 +6,7 @@ import { readEvidenceBundle } from "../../../src/application/EvidenceBundleFiles
import { createLinkedIl2cppMetadataFixture } from "../../fixtures/il2cpp/metadata.js";
import { createIl2cppDyldBindFixture } from "../../fixtures/il2cpp/binary.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
cliTest(
"preserves both selected IL2CPP input spellings in inline and bundled Evidence",
@@ -22,7 +22,7 @@ cliTest(
);
const input = "./metadata.dat";
const binary = "./GameAssembly.dylib";
const inline = await runFileCli(cli, {
const inline = await cli.run({
cwd: root,
arguments: [
"inspect-il2cpp-metadata",
@@ -47,7 +47,7 @@ cliTest(
"./evidence.json",
"--json",
];
const summary = await runFileCli(cli, {
const summary = await cli.run({
cwd: root,
arguments: summaryArgs,
});
@@ -56,7 +56,7 @@ cliTest(
parseEvidence((summary.json as { summary: unknown }).summary)
.caller_input_paths,
).toEqual({ binary_path: binary });
const refused = await runFileCli(cli, {
const refused = await cli.run({
cwd: root,
arguments: summaryArgs,
});
@@ -71,7 +71,7 @@ cliTest(
expect(saved.value.records[0]?.caller_input_paths).toEqual({
binary_path: binary,
});
const without = await runFileCli(cli, {
const without = await cli.run({
cwd: root,
arguments: ["inspect-il2cpp-metadata", input, "--json"],
});
@@ -4,7 +4,7 @@ import { expect } from "vitest";
import { z } from "zod";
import { javaScriptSemanticTraceResultSchema } from "../../../src/domain/javascript/javascriptSemanticTraceSchemas.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
cliTest(
"traces reassignment inputs through the public analysis and trace commands",
@@ -51,9 +51,10 @@ cliTest(
const trace = {
arguments: ["trace-javascript-semantics", queryFile, "--json"],
};
const traced = await (name === "declaration"
? cli.run(trace)
: runFileCli(cli, trace));
const traced = await cli.run({
...trace,
freshProcess: name === "declaration",
});
expect(traced.exitCode, `${name} traced: ${traced.stderr}`).toBe(0);
const { normalized_result: result } = z
.object({ normalized_result: javaScriptSemanticTraceResultSchema })
@@ -74,7 +75,7 @@ cliTest(
query: { ...query.query, include_ambiguous_dynamic_edges: true },
}),
);
const expanded = await runFileCli(cli, {
const expanded = await cli.run({
arguments: ["trace-javascript-semantics", queryFile, "--json"],
});
expect(expanded.exitCode, `${name} expanded: ${expanded.stderr}`).toBe(0);
@@ -9,7 +9,7 @@ import {
expectKeyedArchivePrototypeKeys,
keyedArchivePrototypeKeyFixture,
} from "../../fixtures/keyedArchivePrototypeKeys.js";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { keyedArchiveResultSchema } from "../../../src/domain/apple/keyedArchive.js";
import { connectLocalToolsMcp } from "../../fixtures/localToolsMcp.js";
@@ -86,9 +86,10 @@ cliTest(
USERPROFILE: directory,
},
};
const output = await (name !== "plain" && rootArguments.length === 0
? cli.run(invocation)
: runFileCli(cli, invocation));
const output = await cli.run({
...invocation,
freshProcess: name !== "plain" && rootArguments.length === 0,
});
expect(output.exitCode, output.stdout).toBe(0);
const result = keyedArchiveResultSchema.parse(
parseEvidence(output.json).normalized_result,
@@ -134,7 +134,7 @@ cliTest(
const sha256 = createHash("sha256").update(bytes).digest("hex");
await writeFile(path, bytes);
await writeFile(peerPath, bytes);
const inspected = await cli.sharedCliRun!({
const inspected = await cli.run({
arguments: ["inspect-managed-members", path, "--json"],
});
expect(inspected.exitCode, inspected.stderr).toBe(0);
@@ -160,7 +160,7 @@ cliTest(
: {}),
});
}
const compared = await cli.sharedCliRun!({
const compared = await cli.run({
arguments: ["compare-managed-members", path, path, "--json"],
});
expect(compared.exitCode, compared.stderr).toBe(0);
@@ -28,11 +28,7 @@ import {
} from "../../../src/domain/managed/managedArtifact.js";
import { buildManagedPeFixture } from "../../../src/dotnet/ManagedPe.fixture.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 memberFixture = (): Buffer =>
buildManagedPeFixture({
@@ -86,7 +82,7 @@ const verifyCliSelection = async ({
parent,
report,
}: CliMemberViewContext) => {
const selected = await runFileCli(cli, {
const selected = await cli.run({
cwd,
arguments: [
"inspect-analysis-view",
@@ -154,7 +150,7 @@ const verifyCliFullPages = async (
expect(reportedCounts[collection]).toBe(rows.length);
const paged: unknown[] = [];
for (let offset: number | null = 0; offset !== null;) {
const response = await runFileCli(cli, {
const response = await cli.run({
cwd,
arguments: [
"inspect-analysis-view",
@@ -12,7 +12,7 @@ import { modelArtifactSchema } from "../../../src/domain/model/modelArtifact.js"
import { renderCliDocument } from "../../../src/cliOutput.js";
import { safetensorsFixture } from "../../fixtures/model/model.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
afterAll(() => disposeMdItInstance());
@@ -231,7 +231,7 @@ cliTest(
"preserves capability provider identities in rendered Markdown",
async ({ cli }) => {
const json = await cli.run({ arguments: ["capabilities", "--json"] });
const markdown = await runFileCli(cli, {
const markdown = await cli.run({
arguments: ["capabilities", "--format", "md"],
});
expect(json.exitCode, json.stderr).toBe(0);
@@ -277,7 +277,7 @@ cliTest(
"--filter-output",
"records.0.normalized_result",
];
const markdown = await runFileCli(cli, {
const markdown = await cli.run({
arguments: [...base, "--format", "md"],
});
const json = await cli.run({ arguments: [...base, "--json"] });
@@ -343,7 +343,7 @@ cliTest(
);
const base = ["inspect-model-artifact", path, "--detail", "complete"];
const json = await cli.run({ arguments: [...base, "--json"] });
const markdown = await runFileCli(cli, {
const markdown = await cli.run({
arguments: [...base, "--format", "md"],
});
expect(json.exitCode, json.stderr).toBe(0);
@@ -398,7 +398,7 @@ cliTest(
"--filter-output",
"records.0.normalized_result",
];
const markdown = await runFileCli(cli, {
const markdown = await cli.run({
arguments: [...base, "--format", "md"],
});
const json = await cli.run({ arguments: [...base, "--json"] });
@@ -6,7 +6,7 @@ import { join } from "node:path";
import { describe, expect, it } from "vitest";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { javascriptApplicationAnalysisResultSchema } from "../../../src/domain/javascript/javascriptApplicationAnalysis.js";
import { reconstructionObligationLedgerSchema } from "../../../src/domain/reconstructionObligationLedgerSchemas.js";
@@ -384,10 +384,10 @@ describe("reconstruction proof applicability through CLI", () => {
"--json",
],
};
const result =
name === "matching implementation and revision"
? await cli.run(invocation)
: await runFileCli(cli, invocation);
const result = await cli.run({
...invocation,
freshProcess: name === "matching implementation and revision",
});
expect(result.exitCode, result.stderr).toBe(0);
const ledger = reconstructionObligationLedgerSchema.parse(
(result.json as { normalized_result: unknown }).normalized_result,
@@ -7,7 +7,7 @@ import { describe, expect } from "vitest";
import { historicalSourceGraphSchema } from "../../../src/domain/referenceSourceGraph.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
describe.skipIf(process.platform === "win32")(
"compiled historical-source summaries",
@@ -199,10 +199,10 @@ describe("compiled historical-source summary input boundaries", () => {
arguments: ["import-reference-source", root, ...options, "--json"],
cwd: root,
};
const result =
label === "--outline-depth="
? await cli.run(invocation)
: await runFileCli(cli, invocation);
const result = await cli.run({
...invocation,
freshProcess: label === "--outline-depth=",
});
expect(result.exitCode).toBe(1);
expect(result.json).toMatchObject({
code: "VALIDATION_ERROR",
@@ -226,7 +226,7 @@ describe("compiled historical-source summary input boundaries", () => {
const root = await createTestTempDirectory(
"rea-reference-summary-input-",
);
const result = await runFileCli(cli, {
const result = await cli.run({
arguments: ["import-reference-source", root, ...options, "--json"],
cwd: root,
});
@@ -922,15 +922,6 @@ test("closes the real JavaScript CLI worker through its resource cleanup", async
expect(session.processId()).toBeUndefined();
});
const requireSharedCli = (cli: {
sharedCliRun?: (invocation: CliInvocation) => Promise<CliResult>;
}): ((invocation: CliInvocation) => Promise<CliResult>) => {
const run = cli.sharedCliRun;
if (run === undefined)
throw new Error("cliTest did not provide a shared CLI session");
return run;
};
const normalized = (result: CliResult) =>
z
.object({ normalized_result: javascriptApplicationAnalysisResultSchema })
@@ -957,12 +948,12 @@ const writeApplication = async (prefix: string): Promise<string> => {
cliTest(
"matches a fresh CLI process and reuses that process for the same environment",
async ({ cli, cliCommandSession }) => {
const sharedCliRun = requireSharedCli(cli);
const fresh = await cli.run({
freshProcess: true,
arguments: ["--version"],
environment: { REA_LOG_LEVEL: "silent" },
});
const shared = await sharedCliRun({
const shared = await cli.run({
arguments: ["--version"],
environment: { REA_LOG_LEVEL: "silent" },
});
@@ -971,7 +962,7 @@ cliTest(
expect(shared.stderr).toBe(fresh.stderr);
const pid = cliCommandSession.processId();
expect(pid).toEqual(expect.any(Number));
const again = await sharedCliRun({
const again = await cli.run({
arguments: ["--version"],
environment: { REA_LOG_LEVEL: "silent" },
});
@@ -979,10 +970,11 @@ cliTest(
expect(cliCommandSession.processId()).toBe(pid);
const freshInvalid = await cli.run({
freshProcess: true,
arguments: ["--version"],
environment: { REA_LOG_LEVEL: "not-a-level" },
});
const sharedInvalid = await sharedCliRun({
const sharedInvalid = await cli.run({
arguments: ["--version"],
environment: { REA_LOG_LEVEL: "not-a-level" },
});
@@ -992,7 +984,7 @@ cliTest(
expect(sharedInvalid.stderr).toBe(freshInvalid.stderr);
expect(cliCommandSession.processId()).not.toBe(pid);
const restored = await sharedCliRun({
const restored = await cli.run({
arguments: ["--version"],
environment: { REA_LOG_LEVEL: "silent" },
});
@@ -1005,13 +997,13 @@ cliTest(
cliTest(
"reuses one CLI process across JavaScript application directories",
async ({ cli, cliCommandSession }) => {
const sharedCliRun = requireSharedCli(cli);
const firstRoot = await writeApplication("rea-shared-cli-");
const fresh = await cli.run({
freshProcess: true,
arguments: analyzeArguments(firstRoot),
environment: { REA_LOG_LEVEL: "silent" },
});
const shared = await sharedCliRun({
const shared = await cli.run({
arguments: analyzeArguments(firstRoot),
environment: { REA_LOG_LEVEL: "silent" },
});
@@ -1022,10 +1014,11 @@ cliTest(
const secondRoot = await writeApplication("rea-shared-cli-next-");
const freshNext = await cli.run({
freshProcess: true,
arguments: analyzeArguments(secondRoot),
environment: { REA_LOG_LEVEL: "silent" },
});
const sharedNext = await sharedCliRun({
const sharedNext = await cli.run({
arguments: analyzeArguments(secondRoot),
environment: { REA_LOG_LEVEL: "silent" },
});
@@ -36,7 +36,7 @@ const runJson = async (
await writeFile(path, JSON.stringify(input));
// These JSON commands share no provider state; reuse the fixture-owned CLI
// process so the matrix measures validation rather than repeated startup.
const run = cli.sharedCliRun?.bind(cli) ?? cli.run.bind(cli);
const run = cli.run.bind(cli);
return run({
arguments: [
command,
@@ -13,7 +13,7 @@ import {
expectKeyedArchiveNumberMetadata,
keyedArchiveNumberMetadataFixture,
} from "../../fixtures/keyedArchiveNumberMetadata.js";
import { cliTest, runFileCli } from "../../support/cli/cliFixture.js";
import { cliTest } from "../../support/cli/cliFixture.js";
it("preserves 16-byte binary integers and adjacent 64-bit integer metadata", async () => {
const fixture = await keyedArchiveWideIntegerFixture();
@@ -133,7 +133,7 @@ cliTest.for(archiveNumberMetadataCases)(
"built CLI preserves numeric meaning for $name",
async (item, { cli }) => {
const fixture = await keyedArchiveNumberMetadataFixture(item);
const output = await runFileCli(cli, {
const output = await cli.run({
arguments: ["inspect-keyed-archive", fixture.path, "--json"],
environment: { REA_LOG_LEVEL: "silent", REA_ANALYSIS_PROVIDER: "auto" },
});
@@ -7,7 +7,7 @@ import { z } from "zod";
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";
const scenarios = [
{
@@ -126,7 +126,7 @@ cliTest.for(["full", "compact"] as const)(
`${scenario.name}: ${JSON.stringify(validate.errors)}`,
).toBe(scenario.fullSchemaValid || profile === "compact");
const cliResult = await runFileCli(cli, {
const cliResult = await cli.run({
arguments: [
"capture-browser-scenario",
JSON.stringify(input),
@@ -15,7 +15,7 @@ import { buildManagedPeFixture } from "../../../src/dotnet/ManagedPe.fixture.js"
import { fileLocalToolsMcp } 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 fileMcp = fileLocalToolsMcp();
@@ -330,10 +330,10 @@ cliTest(
const invocation = {
arguments: ["verify-managed-native-boundaries", request, "--json"],
};
const cliRun =
index === 0
? await cli.run(invocation)
: await runFileCli(cli, invocation);
const cliRun = await cli.run({
...invocation,
freshProcess: index === 0,
});
expect(cliRun.exitCode, cliRun.stderr).toBe(0);
const cliResult = managedNativeVerificationResultSchema.parse(
parseEvidence(cliRun.json).normalized_result,
+1 -3
View File
@@ -148,9 +148,7 @@ describe("process CLI cleanup errors", () => {
try {
// A retained PTY can keep its CLI process alive. Read the completed
// compiled command result before releasing the child and joining exit.
if (cli.sharedCliRun === undefined)
throw new Error("Expected the compiled CLI command session");
const result = await cli.sharedCliRun({
const result = await cli.run({
arguments: ["capture-process", scenario, "--json"],
environment: {
TMPDIR: root,
+2 -2
View File
@@ -9,7 +9,7 @@ import { toolContract } from "../../src/contracts/toolContracts.js";
import { javascriptApplicationAnalysisResultSchema } from "../../src/domain/javascript/javascriptApplicationAnalysis.js";
import { projectedExportReturnShapesSchema } from "../../src/domain/javascript/javascriptExportShapeComparisonSchemas.js";
import { createTestTempDirectory } from "./temporaryDirectory.js";
import { runFileCli, type TestCli } from "../support/cli/cliFixture.js";
import type { TestCli } from "../support/cli/cliFixture.js";
import { createMcpSchemaValidation } from "./mcpSchemaValidation.js";
const exportedReturnFields = (value: unknown) => {
@@ -46,7 +46,7 @@ const analyzeReturnShapesThroughCli = async (
) => {
const root = await createTestTempDirectory("rea-return-shapes-");
await writeFile(join(root, fileName), source);
const cliResponse = await runFileCli(cli, {
const cliResponse = await cli.run({
arguments: [
"analyze-javascript-application",
root,
+16 -1
View File
@@ -1,4 +1,4 @@
import { Writable } from "node:stream";
import { Readable, Writable } from "node:stream";
import { access } from "node:fs/promises";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
@@ -21,6 +21,10 @@ const { default: packageJson } = await import(
{ with: { type: "json" } }
);
// Present the launcher's entrypoint, as a fresh `rea` process does. The
// runtime derives the current registration command from it at load time.
process.argv[1] = resolve(packageRoot, "scripts/rea.mjs");
const runtimeFiles = [
"dist/cli-runtime/cli.js",
"dist/cli-runtime/cliOneShot.js",
@@ -158,6 +162,15 @@ async function runOneShot(args) {
const originalStderrWrite = process.stderr.write.bind(process.stderr);
process.stdout.write = captureWrite(stdoutChunks);
process.stderr.write = captureWrite(stderrChunks);
// This process's stdin carries session frames. Give each command the empty,
// ended stdin a fresh process receives when the caller supplies no input.
const stdinDescriptor = Object.getOwnPropertyDescriptor(process, "stdin");
const commandStdin = Readable.from([]);
Object.defineProperty(process, "stdin", {
configurable: true,
enumerable: stdinDescriptor?.enumerable ?? true,
get: () => commandStdin,
});
const destination = new Writable({
write(chunk, encoding, callback) {
process.stdout.write(chunk, encoding, callback);
@@ -209,6 +222,8 @@ async function runOneShot(args) {
} finally {
process.stdout.write = originalStdoutWrite;
process.stderr.write = originalStderrWrite;
if (stdinDescriptor !== undefined)
Object.defineProperty(process, "stdin", stdinDescriptor);
}
const exitCode =
explicitExit ??
+48 -31
View File
@@ -1,5 +1,7 @@
import { resolve } from "node:path";
import { tmpdir } from "node:os";
import { productionMcpDoctorArguments } from "../../../src/cliBuiltinArguments.js";
import { parseLogLevel } from "../../../src/config/processStart.js";
import { INLINE_EVIDENCE_MCP_ENVIRONMENT } from "../../../scripts/lib/mcp-verification-environment.mjs";
import {
@@ -23,6 +25,11 @@ export interface CliInvocation {
readonly environment?: NodeJS.ProcessEnv;
readonly input?: string | Uint8Array;
readonly timeoutMs?: number;
/**
* Start a new process even when the file's shared process could serve the
* command. Use it for process-level facts such as startup or exit.
*/
readonly freshProcess?: boolean;
}
/** Normalized result from the compiled REA CLI. */
@@ -39,18 +46,17 @@ export type SharedMcpCall = Awaited<
/** Compiled REA CLI driver owned by one test. */
export interface TestCli {
/**
* Run one command. `cliTest` drivers use the file's shared process when it
* reports the command exactly as a fresh process would, and start a fresh
* process otherwise. Drivers from `createTestCli` always start one.
*/
run(invocation: CliInvocation): Promise<CliResult>;
/**
* File-scoped stdio MCP caller. Present on `cliTest` drivers and absent for
* drivers created with `createTestCli` alone.
*/
sharedMcpCall?(): Promise<SharedMcpCall>;
/**
* File-scoped compiled CLI process for commands with no stdin. Present on
* `cliTest` drivers. A different environment restarts the process. Stdin and
* explicit deadlines stay on `run`, which starts a fresh process.
*/
sharedCliRun?(invocation: CliInvocation): Promise<CliResult>;
}
/** One file-scoped stdio MCP session. */
@@ -256,17 +262,33 @@ export const cliCompileCacheEnvironment = (
});
/**
* Run one command on the file-scoped compiled CLI. Stdin and explicit
* deadlines stay on `TestCli.run`, which starts a fresh process.
* Whether the file's shared process reports this command exactly as a fresh
* `rea` process would. Stdin and deadlines belong to a process; the launcher
* routes MCP and its doctor before the shared one-shot path; Node options
* change the process itself; and enabled logging writes outside the
* per-command output capture.
*/
export const runFileCli = (
cli: TestCli,
invocation: CliInvocation,
): Promise<CliResult> => {
const run = cli.sharedCliRun;
if (run === undefined)
throw new Error("cliTest did not provide a shared CLI session");
return run(invocation);
const sharedProcessCanServe = ({
arguments: arguments_,
environment,
input,
timeoutMs,
freshProcess,
}: CliInvocation): boolean =>
freshProcess !== true &&
input === undefined &&
timeoutMs === undefined &&
arguments_[0] !== "mcp" &&
arguments_[0] !== "--mcp" &&
productionMcpDoctorArguments([...arguments_]) === undefined &&
environment?.NODE_OPTIONS === undefined &&
!enablesLogging(environment?.REA_LOG_LEVEL);
/** A valid level other than silent; an invalid level is a captured refusal. */
const enablesLogging = (level: string | undefined): boolean => {
if (level === undefined) return false;
const parsed = parseLogLevel(level);
return parsed.ok && parsed.value !== "silent";
};
/** Create a compiled CLI driver backed by the supplied process registry. */
@@ -342,22 +364,17 @@ export const cliTest = processTest.extend<{
) => {
const cli = createTestCli(processes, cliCompileCache);
await use({
...cli,
run: (invocation) =>
sharedProcessCanServe(invocation)
? cliCommandSession.run({
arguments: invocation.arguments,
cwd: invocation.cwd ?? process.cwd(),
environment: definedCliEnvironment(
cliProcessEnvironment(invocation.environment, cliCompileCache),
),
})
: cli.run(invocation),
sharedMcpCall: () => mcpSession.call(),
sharedCliRun: (invocation) => {
if (
invocation.input !== undefined ||
invocation.timeoutMs !== undefined
)
return cli.run(invocation);
return cliCommandSession.run({
arguments: invocation.arguments,
cwd: invocation.cwd ?? process.cwd(),
environment: definedCliEnvironment(
cliProcessEnvironment(invocation.environment, cliCompileCache),
),
});
},
});
},
});
+1 -1
View File
@@ -55,7 +55,7 @@ export const analyzeJavaScriptDirectory = async (
) => {
let document: unknown;
if (surface === "CLI") {
const run = cli.sharedCliRun ?? ((invocation) => cli.run(invocation));
const run = cli.run.bind(cli);
const response = await run({
arguments: [
"analyze-javascript-application",