Files
reverse-engineering-anything/tests/boundary/mcp/nativeLoadImageViewsMcp.test.ts
T
gensokyo-dev f69c52a1cf feat(native): page retained load-image observations (#7134)
Add optional native load-image summary delivery and retained selected-row pages through shared CLI/MCP analysis views. Preserve source verification, provenance, unavailable collections, exact row identity and opt-in byte/check payloads.

Preserve direct caller paths during shared CLI summary publication and cover raw/DOL projection contracts through the actual SDK. Real Ghidra ELF CLI/MCP captures, retained and file-backed pages, focused regressions and static checks passed; the PR records existing main schema failures and the JavaScript resource-recovery CI uncertainty.
2026-10-25 21:50:42 +08:00

96 lines
3.0 KiB
TypeScript

import { expect, it } from "vitest";
import { createEvidence, parseEvidence } from "../../../src/domain/evidence.js";
import { analysisViewResultSchema } from "../../../src/domain/analysisView/analysisView.js";
import {
nativeDolLoadImageFixture,
nativeRawLoadImageFixture,
} from "../../fixtures/nativeLoadImage.js";
import { connectLocalToolsMcp } from "../../fixtures/localToolsMcp.js";
it("preserves raw and DOL verification facts and selected DOL sections through the advertised SDK output", async () => {
const { call } = await connectLocalToolsMcp();
for (const report of [
nativeRawLoadImageFixture(),
nativeDolLoadImageFixture(),
]) {
const parent = createEvidence(
{
path: "/selected/fixture",
sha256: report.target_sha256,
format: report.format,
architecture: report.architecture,
},
{ id: "ghidra", name: "Ghidra", version: "12.1.4" },
{
operation: "inspect_native_load_image",
parameters: {},
result: report,
},
);
const source = { kind: "inline", evidence: parent };
const summary = await call("inspect_analysis_view", {
source,
view: { kind: "summary" },
});
expect(summary.isError, JSON.stringify(summary.content)).not.toBe(true);
const result = analysisViewResultSchema.parse(
parseEvidence(summary.structuredContent).normalized_result,
);
const {
observations: _observations,
checks,
limitations: _limitations,
...verification
} = report;
if ("sections" in verification)
Reflect.deleteProperty(verification, "sections");
expect(result).toMatchObject({
summary: {
verification,
counts: {
checks: checks.length,
sections: report.format === "gamecube-dol" ? 2 : null,
},
},
});
if (report.format !== "gamecube-dol") continue;
const page = await call("inspect_analysis_view", {
source,
view: {
kind: "native-load-image",
collection: "sections",
indices: [1, 0, 1],
offset: 1,
limit: 1,
fields: ["kind", "address"],
},
});
expect(page.isError, JSON.stringify(page.content)).not.toBe(true);
const section = analysisViewResultSchema.parse(
parseEvidence(page.structuredContent).normalized_result,
);
if (section.kind !== "native-load-image") throw new Error("Expected page");
expect(section.items.rows).toEqual([
{
source_index: 1,
record: { kind: "data", address: "ram:0x80004000" },
},
]);
expect(section).toMatchObject({
verification_status: "mismatch",
parent_evidence_id: parent.evidence_id,
items: {
collection: "sections",
rows: [
{
source_index: 1,
record: { kind: "data", address: "ram:0x80004000" },
},
],
},
coverage: { total: 2, next_offset: null, exhausted: true },
limitations: expect.arrayContaining(report.limitations),
});
}
}, 30_000);