Merge pull request #210 from morluto/agent/fix-setup-diagnostics

fix: preserve setup diagnostics and clean Knip config
This commit is contained in:
N0zoM1z0 2026-07-14 20:33:15 +09:00 committed by GitHub
commit 2d1e021782
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 58 additions and 17 deletions

View File

@ -1,18 +1,7 @@
{
"$schema": "./node_modules/knip/schema.json",
"entry": [
"src/main.ts",
"src/cli.ts",
"scripts/rea.mjs",
"scripts/scan-todos.mjs"
],
"project": [
"src/**/*.ts",
"tests/**/*.ts",
"scripts/**/*.mjs",
"vitest.config.ts"
],
"ignore": ["dist/**", "docs/**", ".codex/**", ".devin/**"],
"entry": ["src/main.ts", "src/cli.ts"],
"project": ["src/**/*.ts", "tests/**/*.ts", "scripts/**/*.mjs"],
"ignoreDependencies": [],
"rules": {
"files": "error",

View File

@ -6,7 +6,11 @@ export type SetupFailureCode =
| "launcher_missing"
| "runtime_dependency_unavailable"
| "unsupported_hopper_build"
| "setup_cancelled";
| "setup_cancelled"
| "destination_exists"
| "mount_failed"
| "bundle_invalid"
| "copy_failed";
export type SetupHopperInstallResult =
| { readonly status: "installed"; readonly launcherPath: string }
@ -84,6 +88,34 @@ export const setupInstallFailure = (
remediation:
"Setup was cancelled before Hopper was installed. Rerun rea setup when ready.",
};
case "destination_exists":
return {
status: "failed",
code: "destination_exists",
remediation:
"The Hopper installation destination already exists and was not replaced. Reuse the existing installation or move it aside, then rerun rea setup.",
};
case "mount":
return {
status: "failed",
code: "mount_failed",
remediation:
"The verified Hopper disk image could not be mounted. Eject any stale Hopper image, check local disk access, then rerun rea setup.",
};
case "bundle":
return {
status: "failed",
code: "bundle_invalid",
remediation:
"The mounted package did not contain the expected Hopper application bundle. Retry setup; if it repeats, update REA before installing.",
};
case "copy":
return {
status: "failed",
code: "copy_failed",
remediation:
"The verified Hopper application could not be copied to the installation destination. Check destination permissions and free space, then rerun rea setup.",
};
default:
return {
status: "failed",

View File

@ -108,9 +108,12 @@ const parseStringArray = (
return parsed.success
? ok(parsed.data)
: err(
new ConfigurationError(`${name} must encode an array of strings`, {
cause: parsed.error,
}),
new ConfigurationError(
parsed.error.issues.some(({ code }) => code === "too_big")
? `${name} must encode at most 128 strings`
: `${name} must encode an array of strings`,
{ cause: parsed.error },
),
);
} catch (cause: unknown) {
return err(new ConfigurationError(`${name} must be valid JSON`, { cause }));

View File

@ -125,6 +125,19 @@ describe("runtime configuration", () => {
},
);
it("reports the configured string-array size limit", () => {
const result = parseConfig({
REA_INVESTIGATION_INPUT_ROOTS_JSON: JSON.stringify(
Array.from({ length: 129 }, (_, index) => `/input/${String(index)}`),
),
});
expect(result.ok).toBe(false);
if (!result.ok)
expect(result.error.message).toBe(
"REA_INVESTIGATION_INPUT_ROOTS_JSON must encode at most 128 strings",
);
});
it("parses supported log levels and rejects unknown levels", () => {
const configured = parseConfig({ REA_LOG_LEVEL: "debug" });
expect(configured.ok && configured.value.logLevel).toBe("debug");

View File

@ -19,6 +19,10 @@ describe("setup installer failure projection", () => {
["runtime_dependencies", "runtime_dependency_unavailable"],
["unsupported_hopper_build", "unsupported_hopper_build"],
["cancelled", "setup_cancelled"],
["destination_exists", "destination_exists"],
["mount", "mount_failed"],
["bundle", "bundle_invalid"],
["copy", "copy_failed"],
] as const)("maps %s to %s", (reason, code) => {
const result = setupInstallFailure(reason as HopperInstallFailureReason);
expect(result).toMatchObject({ status: "failed", code });