mirror of
https://github.com/morluto/rea
synced 2026-10-26 14:25:49 -04:00
ae09e3fe70
* fix(native): recover macOS command deadlines Promote native_command_timeout_ms (default 60000), native_ui_deadline_ms (default 180000), and pwntools_timeout_ms (default 30000) as validated per-call settings. Keep cpuSeconds, byte allowances, LLDB grace, and plist probes fixed, and say those caps have no runtime override. Co-authored-by: morluto <morluto@users.noreply.github.com> * fix(native): report the deadline that actually expired Pass the selected native command timeout through xcrun resolution, thread the pwntools deadline into pwndbg failures, and state the selected UI deadline apart from the fixed wait-step cap. SIGXFSZ and EFBIG recovery names the file-size allowance. Co-authored-by: morluto <morluto@users.noreply.github.com> * fix(native): honor the selected deadline on helper stages The UI helper compile and capture subprocesses used fixed 60s and 30s exec timeouts, so a longer native_ui_deadline_ms still failed as a generic provider error. Preparation timeouts reported the 60000 ms default instead of the selected native_command_timeout_ms. Memory resource-constraint recovery names memory again, and the Darwin plist CLI expectation matches the byte-counted input allowance. Co-authored-by: morluto <morluto@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: morluto <morluto@users.noreply.github.com>
107 lines
3.7 KiB
TypeScript
107 lines
3.7 KiB
TypeScript
import {
|
|
AnalysisCancelledError,
|
|
AnalysisTimeoutError,
|
|
} from "../domain/analysisErrorCore.js";
|
|
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
|
|
import { expect, it } from "vitest";
|
|
import { NativeUiInterruptionControl } from "./NativeUiInterruptionControl.js";
|
|
|
|
it("names the selected native UI deadline and the fixed sibling caps", () => {
|
|
const deadline = AbortSignal.abort();
|
|
const control = new NativeUiInterruptionControl(undefined, deadline, 2_500);
|
|
const error = control.error("observe_native_ui");
|
|
expect(error).toBeInstanceOf(AnalysisTimeoutError);
|
|
if (!(error instanceof AnalysisTimeoutError)) return;
|
|
const projected = projectAnalysisError(error);
|
|
expect(projected.message).toContain("2500 ms");
|
|
expect(projected.message).toContain("native_ui_deadline_ms");
|
|
expect(projected.remediation.action).toContain("--native-ui-deadline-ms");
|
|
expect(projected.remediation.action).toContain("no runtime override");
|
|
expect(projected.remediation.action).toContain("67108864");
|
|
control.dispose();
|
|
});
|
|
|
|
it("gives a pre-aborted caller priority over a pre-aborted deadline", () => {
|
|
const reason = { phase: "shared" };
|
|
const caller = new AbortController();
|
|
const deadline = new AbortController();
|
|
caller.abort(reason);
|
|
deadline.abort(reason);
|
|
const control = new NativeUiInterruptionControl(
|
|
caller.signal,
|
|
deadline.signal,
|
|
);
|
|
expect(control.error("observe_native_ui")).toBeInstanceOf(
|
|
AnalysisCancelledError,
|
|
);
|
|
expect(control.error("observe_native_ui")?.cause).toBe(reason);
|
|
control.dispose();
|
|
});
|
|
|
|
it("keeps the first observed source when caller and deadline share a reason", () => {
|
|
const reason = { phase: "shared" };
|
|
const caller = new AbortController();
|
|
const deadline = new AbortController();
|
|
const control = new NativeUiInterruptionControl(
|
|
caller.signal,
|
|
deadline.signal,
|
|
);
|
|
deadline.abort(reason);
|
|
caller.abort(reason);
|
|
expect(control.error("observe_native_ui")).toBeInstanceOf(
|
|
AnalysisTimeoutError,
|
|
);
|
|
expect(control.error("observe_native_ui")?.cause).toBe(reason);
|
|
control.dispose();
|
|
});
|
|
|
|
it("records a helper subprocess timeout as the selected UI deadline", () => {
|
|
const deadline = new AbortController();
|
|
const control = new NativeUiInterruptionControl(
|
|
undefined,
|
|
deadline.signal,
|
|
2_500,
|
|
);
|
|
const error = control.deadlineFailure("observe_native_ui");
|
|
expect(error).toBeInstanceOf(AnalysisTimeoutError);
|
|
if (!(error instanceof AnalysisTimeoutError)) return;
|
|
const projected = projectAnalysisError(error);
|
|
expect(projected.message).toContain("2500 ms");
|
|
expect(projected.message).toContain("native_ui_deadline_ms");
|
|
expect(projected.message).not.toContain("30000 ms");
|
|
expect(projected.message).not.toContain("60000 ms");
|
|
control.dispose();
|
|
});
|
|
|
|
it("keeps caller cancellation ahead of a later helper subprocess timeout", () => {
|
|
const reason = { phase: "caller" };
|
|
const caller = new AbortController();
|
|
caller.abort(reason);
|
|
const control = new NativeUiInterruptionControl(
|
|
caller.signal,
|
|
new AbortController().signal,
|
|
2_500,
|
|
);
|
|
const error = control.deadlineFailure("observe_native_ui");
|
|
expect(error).toBeInstanceOf(AnalysisCancelledError);
|
|
expect(error.cause).toBe(reason);
|
|
control.dispose();
|
|
});
|
|
|
|
it("records a caller interruption before a later deadline", () => {
|
|
const reason = { phase: "shared" };
|
|
const caller = new AbortController();
|
|
const deadline = new AbortController();
|
|
const control = new NativeUiInterruptionControl(
|
|
caller.signal,
|
|
deadline.signal,
|
|
);
|
|
caller.abort(reason);
|
|
deadline.abort(reason);
|
|
expect(control.error("observe_native_ui")).toBeInstanceOf(
|
|
AnalysisCancelledError,
|
|
);
|
|
expect(control.error("observe_native_ui")?.cause).toBe(reason);
|
|
control.dispose();
|
|
});
|