mirror of
https://github.com/morluto/rea.git
synced 2026-11-11 09:21:16 +00:00
feat(electron): map static process and IPC boundaries
This commit is contained in:
1 parent
3988a866f1
commit
3fa2304bc7
279 files changed
+7481
-775
No files matched your search
@@ -120,6 +120,7 @@ const SOURCE_PATHS = {
|
||||
webMcpDiscovery: "dist/domain/webMcpDiscovery.js",
|
||||
webScreenshot: "dist/domain/webScreenshot.js",
|
||||
javascriptApplicationGraph: "dist/domain/javascriptApplicationGraph.js",
|
||||
javascriptApplicationAnalysis: "dist/domain/javascriptApplicationAnalysis.js",
|
||||
reconstructionVerification:
|
||||
"dist/domain/reconstructionVerificationSchemas.js",
|
||||
residualUnknown: "dist/domain/residualUnknown.js",
|
||||
@@ -190,8 +191,18 @@ const toolFamilyCatalog = (sources) => {
|
||||
return { total: familyTotal, families };
|
||||
};
|
||||
|
||||
const providerCatalog = (sources) =>
|
||||
[
|
||||
const providerCatalog = (sources) => {
|
||||
const applicationContracts =
|
||||
sources.electronContracts.ELECTRON_TOOL_CONTRACTS.filter(
|
||||
({ name }) => name === "analyze_javascript_application",
|
||||
);
|
||||
const observationContracts =
|
||||
sources.electronContracts.ELECTRON_TOOL_CONTRACTS.filter(
|
||||
({ name }) => name !== "analyze_javascript_application",
|
||||
);
|
||||
if (applicationContracts.length !== 1 || observationContracts.length !== 2)
|
||||
throw new Error("Electron provider capability ownership drifted");
|
||||
return [
|
||||
{
|
||||
identity: sources.hopperProvider.HOPPER_PROVIDER_IDENTITY,
|
||||
contracts: sources.hopperProvider.HOPPER_PROVIDER_TOOL_CONTRACTS,
|
||||
@@ -214,7 +225,11 @@ const providerCatalog = (sources) =>
|
||||
},
|
||||
{
|
||||
identity: sources.electronProvider.CDP_ELECTRON_PROVIDER_IDENTITY,
|
||||
contracts: sources.electronContracts.ELECTRON_TOOL_CONTRACTS,
|
||||
contracts: observationContracts,
|
||||
},
|
||||
{
|
||||
identity: sources.artifactProviders.JAVASCRIPT_APPLICATION_PROVIDER,
|
||||
contracts: applicationContracts,
|
||||
},
|
||||
]
|
||||
.map(({ identity, contracts }) => ({
|
||||
@@ -224,6 +239,7 @@ const providerCatalog = (sources) =>
|
||||
capabilities: names(contracts),
|
||||
}))
|
||||
.sort((left, right) => left.id.localeCompare(right.id));
|
||||
};
|
||||
|
||||
const durableSchemaDefinitions = (sources) => [
|
||||
[
|
||||
@@ -300,6 +316,12 @@ const observationSchemaDefinitions = (sources) => [
|
||||
sources.electronObservation.electronTargetListSchema,
|
||||
["schema_version"],
|
||||
],
|
||||
[
|
||||
"javascript_application_analysis",
|
||||
sources.javascriptApplicationAnalysis
|
||||
.javascriptApplicationAnalysisResultSchema,
|
||||
["schema_version"],
|
||||
],
|
||||
[
|
||||
"web_bundle_analysis",
|
||||
sources.webBundleAnalysis.webBundleAnalysisSchema,
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import { dirname, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
// Route production MCP before importing Incur. Incur owns registration helpers
|
||||
// such as `mcp add`, while only dist/main.js may serve the 78-tool stdio server.
|
||||
// such as `mcp add`, while only dist/main.js may serve the 79-tool stdio server.
|
||||
const args = process.argv.slice(2);
|
||||
const { default: packageJson } = await import("../package.json", {
|
||||
with: { type: "json" },
|
||||
|
||||
@@ -143,6 +143,7 @@ try {
|
||||
!help.includes("import-reference-source") ||
|
||||
!help.includes("list-browser-targets") ||
|
||||
!help.includes("inspect-web-page") ||
|
||||
!help.includes("analyze-javascript-application") ||
|
||||
!help.includes("compare") ||
|
||||
!llms.includes("decompile") ||
|
||||
!llms.includes("function") ||
|
||||
@@ -155,6 +156,7 @@ try {
|
||||
!llms.includes("inventory-artifact") ||
|
||||
!llms.includes("list-browser-targets") ||
|
||||
!llms.includes("inspect-web-page") ||
|
||||
!llms.includes("analyze-javascript-application") ||
|
||||
doctor.healthy !== expectedDoctorHealth ||
|
||||
doctorExecution.status !== (expectedDoctorHealth ? 0 : 1) ||
|
||||
doctor.checks?.find(({ name }) => name === "hopper")?.ok !== true
|
||||
@@ -179,6 +181,40 @@ try {
|
||||
artifactInventory.normalized_result?.manifest?.root_format !== "zip"
|
||||
)
|
||||
throw new Error("packaged artifact inventory CLI failed");
|
||||
const applicationRoot = join(workspace, "electron-app");
|
||||
await mkdir(applicationRoot);
|
||||
await writeFile(
|
||||
join(applicationRoot, "package.json"),
|
||||
'{"name":"packaged-electron-fixture","main":"main.js"}\n',
|
||||
);
|
||||
await writeFile(
|
||||
join(applicationRoot, "main.js"),
|
||||
'const { BrowserWindow, ipcMain } = require("electron");\nnew BrowserWindow({ webPreferences: { preload: path.join(__dirname, "preload.js"), contextIsolation: true } });\nipcMain.handle("rea:ping", () => true);\n',
|
||||
);
|
||||
await writeFile(
|
||||
join(applicationRoot, "preload.js"),
|
||||
'const { contextBridge, ipcRenderer } = require("electron");\ncontextBridge.exposeInMainWorld("rea", { ping: () => ipcRenderer.invoke("rea:ping") });\n',
|
||||
);
|
||||
const applicationAnalysis = json(
|
||||
await run(
|
||||
cli,
|
||||
[
|
||||
"analyze-javascript-application",
|
||||
applicationRoot,
|
||||
"--approved",
|
||||
"--json",
|
||||
],
|
||||
environment,
|
||||
),
|
||||
);
|
||||
if (
|
||||
applicationAnalysis.operation !== "analyze_javascript_application" ||
|
||||
applicationAnalysis.provider?.id !== "rea-javascript-application" ||
|
||||
applicationAnalysis.normalized_result?.summary?.browser_windows !== 1 ||
|
||||
applicationAnalysis.normalized_result?.summary?.ipc
|
||||
?.paired_renderer_transmissions !== 1
|
||||
)
|
||||
throw new Error("packaged JavaScript application analysis CLI failed");
|
||||
// prettier-ignore
|
||||
const investigationReplay = await verifyPackagedInvestigation({ cli, workspace, evidenceRoot, artifactArchive, environment });
|
||||
const unknownProviderExecution = await runWithStatus(
|
||||
|
||||
@@ -22,7 +22,7 @@ transport.stderr?.on("data", (chunk) => {
|
||||
try {
|
||||
await client.connect(transport);
|
||||
const tools = await client.listTools();
|
||||
if (tools.tools.length !== 78)
|
||||
if (tools.tools.length !== 79)
|
||||
throw new Error(
|
||||
`Published MCP exposed ${String(tools.tools.length)} tools`,
|
||||
);
|
||||
@@ -40,5 +40,5 @@ try {
|
||||
}
|
||||
|
||||
process.stdout.write(
|
||||
`${JSON.stringify({ package: "rea-agents", version, mcpTools: 78 })}\n`,
|
||||
`${JSON.stringify({ package: "rea-agents", version, mcpTools: 79 })}\n`,
|
||||
);
|
||||
@@ -362,7 +362,7 @@ try {
|
||||
const expectedNames = TOOL_CONTRACTS.map(({ name }) => name).sort();
|
||||
const actualNames = listed.tools.map(({ name }) => name).sort();
|
||||
if (JSON.stringify(actualNames) !== JSON.stringify(expectedNames)) {
|
||||
throw new Error("The real server did not expose the intended 78 tools");
|
||||
throw new Error("The real server did not expose the intended 79 tools");
|
||||
}
|
||||
|
||||
const options = { timeout };
|
||||
|
||||
Reference in new issue
Block a user