Files
rea/tests/fixtures/hopperLaunchAdmission.mjs
T
morluto 4acda94b76 fix(hopper): recover provenance-verified Spotlight exits
Verify the native helper's sealed identifier and pinned Apple signing team in BridgeLauncher, then carry that provenance to HopperClient. Only a verified native helper's complete not-found exit confirms no document handoff, allowing runtime and target-lease cleanup and retry; wrappers retain unknown document state.

Share publisher identity with setup through the domain contract. Correct fixture teardown ordering and parameterized MCP coverage. Validation: 54 focused tests passed across boundary, CLI, MCP acceptance, diagnostics and installer coverage (one Linux-only case skipped); check:fast passed. Real codesign verification accepted the installed official Hopper helper; Spotlight failures and bridge recovery used process fixtures.
2026-10-14 06:19:47 +08:00

36 lines
1.5 KiB
JavaScript

import { readFile, writeFile } from "node:fs/promises";
// Model the native helper's external GUI handoff independently of its lifetime.
const [modePath, receiptPath] = process.argv.slice(2, 4);
const mode = await readFile(modePath, "utf8");
const bootstrapIndex = process.argv.indexOf("-Y") + 1;
if (bootstrapIndex === 0) throw new Error("Missing Hopper bootstrap argument");
const bootstrapPath = process.argv[bootstrapIndex];
await writeFile(receiptPath, bootstrapPath);
if (mode === "denied" || mode === "denied-after-handoff") {
process.stderr.write(
"Cannot launch Hopper!\nNot authorized to send Apple events to Hopper Disassembler.\n",
async () => {
if (mode === "denied-after-handoff") {
// A real native helper can create a document before emitting this same
// diagnostic when caller literals alter its AppleScript construction.
await writeFile(`${receiptPath}.document-created`, "unconfirmed");
}
process.exit(2);
},
);
} else if (mode === "not-found") {
// A custom wrapper can forward the native diagnostic after a handoff.
await writeFile(`${receiptPath}.document-created`, "unconfirmed");
process.stderr.write(
"Hopper has not been found.\nPlease make sure that Spotlight is active in order for this tool to find Hopper's executable.\n",
() => process.exit(3),
);
} else if (mode === "handoff") {
process.exit(0);
} else if (mode === "bridge") {
await import("./fakeLauncher.mjs");
} else {
throw new Error(`Unknown Hopper launch admission fixture mode: ${mode}`);
}