mirror of
https://github.com/morluto/rea
synced 2026-10-27 14:42:18 -04:00
fix: name host and tool requirements in optional adapter refusals
Host and tool-configuration refusals from the pwntools, EVMole, firmware, mitmproxy, Wakaru, LLDB and xcrun adapters carried no userMessage, so CLI and MCP callers saw the generic "This analysis is unavailable for the current target. Choose another analysis or target." as both message and remediation. Choosing another target cannot satisfy a Linux-only profile or an unset REA_*_COMMAND. The actual requirement appeared only in details.reason. Pass each refusal's reason as its userMessage, as the adapters' other configuration refusals (EVMole limits, JADX, pwndbg) already do. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,30 @@
|
||||
import { EventEmitter } from "node:events";
|
||||
import { PassThrough } from "node:stream";
|
||||
import { expect, it } from "vitest";
|
||||
import { runWakaruCommand, type WakaruLauncher } from "./WakaruCommand.js";
|
||||
import { AnalysisCapabilityUnavailableError } from "../../domain/analysisErrorCore.js";
|
||||
import { projectAnalysisError } from "../../domain/analysisErrorProjection.js";
|
||||
import {
|
||||
resolveWakaruCommand,
|
||||
runWakaruCommand,
|
||||
type WakaruLauncher,
|
||||
} from "./WakaruCommand.js";
|
||||
import { RECOVERY_LIMITS } from "./WakaruRelease.js";
|
||||
|
||||
it("names the Wakaru configuration requirement when it is not configured", async () => {
|
||||
const refusal: unknown = await resolveWakaruCommand({}).catch(
|
||||
(cause: unknown) => cause,
|
||||
);
|
||||
|
||||
if (!(refusal instanceof AnalysisCapabilityUnavailableError))
|
||||
throw new Error("Expected a capability refusal");
|
||||
expect(refusal.reason).toContain("REA_WAKARU_COMMAND");
|
||||
expect(projectAnalysisError(refusal)).toMatchObject({
|
||||
code: "capability_unavailable",
|
||||
message: refusal.reason,
|
||||
remediation: { action: refusal.reason },
|
||||
});
|
||||
});
|
||||
|
||||
it("rejects an exhausted shared execution budget before launching the next command", async () => {
|
||||
await expect(
|
||||
runWakaruCommand({
|
||||
|
||||
@@ -25,6 +25,8 @@ import {
|
||||
import { RECOVERY_LIMITS } from "./WakaruRelease.js";
|
||||
|
||||
const OPERATION = "recover_javascript_sources";
|
||||
const WAKARU_REQUIREMENT =
|
||||
"Provide an absolute REA_WAKARU_COMMAND pointing to Wakaru 1.13.0 on Linux x64; no tool is installed by REA";
|
||||
|
||||
/** Inject the owned process launcher while retaining production protocol parsing. */
|
||||
export type WakaruLauncher = (
|
||||
@@ -45,7 +47,8 @@ export const resolveWakaruCommand = async (
|
||||
throw new AnalysisCapabilityUnavailableError(
|
||||
"wakaru",
|
||||
OPERATION,
|
||||
"Provide an absolute REA_WAKARU_COMMAND pointing to Wakaru 1.13.0 on Linux x64; no tool is installed by REA",
|
||||
WAKARU_REQUIREMENT,
|
||||
{ userMessage: WAKARU_REQUIREMENT },
|
||||
);
|
||||
try {
|
||||
const command = await realpath(configured);
|
||||
@@ -61,12 +64,11 @@ export const resolveWakaruCommand = async (
|
||||
await access(limiter, constants.X_OK);
|
||||
return { command, limiter, ...fingerprint };
|
||||
} catch (cause: unknown) {
|
||||
throw new AnalysisCapabilityUnavailableError(
|
||||
"wakaru",
|
||||
OPERATION,
|
||||
`Configured Wakaru or util-linux prlimit is unavailable: ${recoveryFailureMessage(cause)}`,
|
||||
{ cause },
|
||||
);
|
||||
const reason = `Configured Wakaru or util-linux prlimit is unavailable: ${recoveryFailureMessage(cause)}`;
|
||||
throw new AnalysisCapabilityUnavailableError("wakaru", OPERATION, reason, {
|
||||
cause,
|
||||
userMessage: reason,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -69,12 +69,12 @@ const executeWakaruRecovery = async (context: RecoveryWorkspace) => {
|
||||
if (
|
||||
version.exit_code !== 0 ||
|
||||
version.stdout.trim() !== `wakaru ${WAKARU_RELEASE.version}`
|
||||
)
|
||||
throw new AnalysisCapabilityUnavailableError(
|
||||
"wakaru",
|
||||
OPERATION,
|
||||
`This adapter requires Wakaru ${WAKARU_RELEASE.version}; reported version: ${version.stdout.trim()}; exit: ${String(version.exit_code)}; stderr: ${version.stderr}`,
|
||||
);
|
||||
) {
|
||||
const reason = `This adapter requires Wakaru ${WAKARU_RELEASE.version}; reported version: ${version.stdout.trim()}; exit: ${String(version.exit_code)}; stderr: ${version.stderr}`;
|
||||
throw new AnalysisCapabilityUnavailableError("wakaru", OPERATION, reason, {
|
||||
userMessage: reason,
|
||||
});
|
||||
}
|
||||
const run = await runWakaruCommand({
|
||||
...commandContext,
|
||||
staging,
|
||||
|
||||
Reference in New Issue
Block a user