Files
reverse-engineering-anything/src/application/DoctorRegistrationEnvironment.test.ts
T
morlutoandCursor Agent 88cf498036 fix!: preserve results when source publication fails (#8444)
* fix: retain address context cleanup failures

* fix!: preserve address context input errors

BREAKING CHANGE: Strict clients that cached the previous full inspect_address_context output schema must refresh tools/list and accept the typed error field on unavailable facets.

* test: use session contract for address context

* fix!: preserve address context resource recovery

BREAKING CHANGE: Clients validating unavailable context facets against a cached strict full output schema must refresh tools/list to accept resource_constraint errors.

* fix: expose authenticated records refused by the evidence ledger (#8426)

* fix: preserve completed evidence on retention refusal

* fix: preserve context when unretained evidence exceeds delivery limits

* fix(mcp): recover oversized context from session evidence

* fix(evidence): preserve completed atomic write results

* fix: retain completed results when source publication fails

* test: cover bounded recovery with unknown retention

* fix(evidence): preserve recovery identity and finalization facts

* fix(evidence): clarify retention of omitted observations

* test(evidence): compare omission guidance with its owner

* fix(evidence): preserve completed composed workflows

* fix(evidence): clarify unretained recovery export

* test(evidence): cover mixed recovery guidance

* fix(evidence): preserve caller scope in secondary failures

* refactor(evidence): remove superseded cleanup projection

* test(evidence): align recovery checks with owners

* fix: preserve cleanup on partial recovery limits

* test: use owners for diagnostic wording

* fix: admit completed analysis before evidence construction

* fix: preserve selected paths when reusing evidence

* fix(cli): preserve caller path in unretained evidence

* fix(evidence): preserve recovery metadata and admission bounds

* refactor: consolidate evidence closure imports

* style(test): format CLI help default annotations (#9280)

* test(mcp): keep recovery checks focused on contract facts

* fix(evidence): preserve feature trace replay revision

* test: align evidence recovery checks with ownership

* test: align partial recovery and cleanup diagnostics

* fix(evidence): preserve nested partials during cleanup

* fix(evidence): respect outer recovery ownership

* fix(capture): discard rejected nested observations

* test(frida): assert inline evidence recovery

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-11-09 02:41:54 +08:00

197 lines
5.7 KiB
TypeScript

import { writeFile } from "node:fs/promises";
import { join } from "node:path";
import { expect, it } from "vitest";
import { createTestTempDirectory } from "../../tests/fixtures/temporaryDirectory.js";
import { createDoctorHostFixture as host } from "./Doctor.fixture.js";
import {
registrationEnvironmentDetail,
runDoctor,
systemDoctorHost,
type DoctorHost,
} from "./Doctor.js";
const inspection = (
id: string,
registrationEnvironment: Readonly<Record<string, string>>,
available = true,
) => ({
id,
configured: true,
available,
providerVersion: null,
registrationEnvironment,
checks: [],
});
const recordingHost = (overrides: Partial<DoctorHost>) => {
const requested: Readonly<Record<string, string>>[] = [];
return {
requested,
host: host({
clientRegistrations: (_clients, providerSettings) => {
requested.push(providerSettings ?? {});
return Promise.resolve([
{
client: "cursor",
config_path: "/home/user/.cursor/mcp.json",
command: ["/current/rea", "mcp"],
state: "aligned",
remediation: null,
provider_settings: {
unrecorded: ["GHIDRA_INSTALL_DIR"],
differing: [],
unresolved: [],
},
},
]);
},
...overrides,
}),
};
};
const selectedProviders = {
providerInspections: () =>
Promise.resolve([
inspection("ghidra", { GHIDRA_INSTALL_DIR: "/opt/ghidra" }),
inspection("jadx", { REA_JADX_MCP_JAR: "/opt/jadx.jar" }),
inspection("kuna", { REA_KUNA_COMMAND: "/opt/kuna" }, false),
]),
};
const CHECK = "registration_environment:cursor";
it("compares only settings an available provider relied on", async () => {
const { host: selectedHost, requested } = recordingHost(selectedProviders);
await runDoctor(undefined, selectedHost);
expect(requested).toEqual([
{
GHIDRA_INSTALL_DIR: "/opt/ghidra",
REA_JADX_MCP_JAR: "/opt/jadx.jar",
},
]);
});
it.each([
[{ providers: ["ghidra"] }, true],
[{ clients: ["cursor"] }, true],
[{ clients: ["codex"] }, false],
[{ providers: ["jadx"] }, false],
[{ skill: true }, false],
])("follows the selected scope %j", async (scope, selected) => {
const report = await runDoctor(
undefined,
recordingHost(selectedProviders).host,
scope,
);
const inScope = report.scope_checks.some(({ name }) => name === CHECK);
expect(inScope).toBe(selected);
expect(report.informational_checks.some(({ name }) => name === CHECK)).toBe(
!selected,
);
});
it("does not gate health or name unaffected providers", async () => {
const report = await runDoctor(
undefined,
recordingHost(selectedProviders).host,
{ providers: ["ghidra"] },
);
expect(report.healthy).toBe(true);
expect(report.checks).toContainEqual(
expect.objectContaining({
name: CHECK,
ok: true,
classification: "unknown",
details: { effective_environment: "unknown", providers: ["ghidra"] },
}),
);
});
it.each([
["/custom/Hopper", { HOPPER_LAUNCHER_PATH: "/custom/Hopper" }],
// A default location is found again without this terminal's environment.
[undefined, {}],
])(
"includes Hopper only for an explicit available path (%s)",
async (configuredHopperPath, expected) => {
const { host: selectedHost, requested } = recordingHost(
configuredHopperPath === undefined ? {} : { configuredHopperPath },
);
await runDoctor(undefined, selectedHost);
expect(requested).toEqual([expected]);
},
);
it("does not include an explicit Hopper path that fails its checks", async () => {
const { host: selectedHost, requested } = recordingHost({
configuredHopperPath: "/custom/missing",
executable: () => Promise.resolve(false),
});
await runDoctor(undefined, selectedHost);
expect(requested).toEqual([{}]);
});
it("compares a caller selection as setup spells it", async () => {
const home = await createTestTempDirectory("rea-doctor-spelling-");
await writeFile(
join(home, ".claude.json"),
JSON.stringify({
mcpServers: {
rea: {
command: "/current/rea",
args: ["mcp"],
env: {
GHIDRA_INSTALL_DIR: "/opt/ghidra",
JAVA_HOME: "/selected/alias",
},
},
},
}),
);
const system = systemDoctorHost({
environment: { HOME: home, JAVA_HOME: "/selected/alias" },
});
const statuses = await system.clientRegistrations?.(["claude_code"], {
GHIDRA_INSTALL_DIR: "/opt/ghidra",
// The provider's observed home; setup records the caller's spelling.
JAVA_HOME: "/observed/jdk",
});
await system.close?.();
expect(statuses?.[0]?.client).toBe("claude_code");
expect(statuses?.[0]).not.toHaveProperty("provider_settings");
});
it("states each comparison result without a claim it did not establish", async () => {
const report = await runDoctor(
undefined,
host({
clientRegistrations: () =>
Promise.resolve([
{
client: "cursor",
config_path: "/cursor.json",
command: ["/current/rea", "mcp"],
state: "aligned",
remediation: null,
provider_settings: {
unrecorded: [],
differing: ["JAVA_HOME"],
unresolved: ["GHIDRA_INSTALL_DIR"],
},
},
]),
}),
);
const check = report.checks.find(({ name }) => name === CHECK);
expect(check).toMatchObject({
classification: "unknown",
details: { effective_environment: "unknown" },
});
expect(check?.detail).toBe(
registrationEnvironmentDetail("cursor", {
unrecorded: [],
differing: ["JAVA_HOME"],
unresolved: ["GHIDRA_INSTALL_DIR"],
}),
);
});