mirror of
https://github.com/morluto/rea.git
synced 2026-10-11 21:39:55 +00:00
perf(cli): defer command-specific analysis implementations
Load application and Electron workflow implementations only when their commands execute. Keep command schemas and catalog registration eager, and extend the startup import boundary to cover the deferred services.
This commit is contained in:
@@ -1,17 +1,6 @@
|
||||
import { reconstructionCoverageEvaluationInputSchema } from "../domain/reconstructionCoverageInput.js";
|
||||
import { Cli, z } from "incur";
|
||||
|
||||
import { projectAndroidApplicationEvidence } from "../application/android/AndroidApplicationService.js";
|
||||
import { projectAppleApplicationEvidence } from "../application/apple/AppleApplicationService.js";
|
||||
import {
|
||||
compareApplicationVersionsEvidenceValidated,
|
||||
compareJavaScriptExportShapesEvidenceValidated,
|
||||
compareSourceToBundleEvidenceValidated,
|
||||
traceApplicationFeatureEvidenceValidated,
|
||||
} from "../application/javascript/JavaScriptApplicationWorkflowService.js";
|
||||
import { traceJavaScriptSemanticsEvidenceValidated } from "../application/javascript/JavaScriptSemanticTraceService.js";
|
||||
import { evaluateReconstructionCoverage } from "../application/ReconstructionCoverageService.js";
|
||||
import { buildReconstructionObligationLedgerEvidenceValidated } from "../application/ReconstructionObligationLedgerService.js";
|
||||
import { CLI_COMMANDS } from "../cliCommandNames.js";
|
||||
import { parseCliJsonInput } from "../cliJsonInput.js";
|
||||
import { logCliCommand } from "../cliLogging.js";
|
||||
@@ -43,7 +32,11 @@ export const registerApplicationCommands = (
|
||||
description:
|
||||
"Trace a typed seed through authenticated application Evidence JSON",
|
||||
inputSchema: traceApplicationFeatureInputSchema,
|
||||
workflow: traceApplicationFeatureEvidenceValidated,
|
||||
workflow: async (input) => {
|
||||
const { traceApplicationFeatureEvidenceValidated } =
|
||||
await import("../application/javascript/JavaScriptApplicationWorkflowService.js");
|
||||
return traceApplicationFeatureEvidenceValidated(input);
|
||||
},
|
||||
});
|
||||
registerJsonCommand({
|
||||
cli,
|
||||
@@ -52,7 +45,11 @@ export const registerApplicationCommands = (
|
||||
description:
|
||||
"Trace bounded static semantic relations through authenticated application Evidence",
|
||||
inputSchema: traceJavaScriptSemanticsInputSchema,
|
||||
workflow: traceJavaScriptSemanticsEvidenceValidated,
|
||||
workflow: async (input) => {
|
||||
const { traceJavaScriptSemanticsEvidenceValidated } =
|
||||
await import("../application/javascript/JavaScriptSemanticTraceService.js");
|
||||
return traceJavaScriptSemanticsEvidenceValidated(input);
|
||||
},
|
||||
});
|
||||
registerJsonCommand({
|
||||
cli,
|
||||
@@ -61,7 +58,11 @@ export const registerApplicationCommands = (
|
||||
description:
|
||||
"Compare two authenticated JavaScript Application Graph versions",
|
||||
inputSchema: compareApplicationVersionsInputSchema,
|
||||
workflow: compareApplicationVersionsEvidenceValidated,
|
||||
workflow: async (input) => {
|
||||
const { compareApplicationVersionsEvidenceValidated } =
|
||||
await import("../application/javascript/JavaScriptApplicationWorkflowService.js");
|
||||
return compareApplicationVersionsEvidenceValidated(input);
|
||||
},
|
||||
});
|
||||
registerJsonCommand({
|
||||
cli,
|
||||
@@ -70,7 +71,11 @@ export const registerApplicationCommands = (
|
||||
description:
|
||||
"Compare committed historical source with authenticated application Evidence",
|
||||
inputSchema: compareSourceToBundleInputSchema,
|
||||
workflow: compareSourceToBundleEvidenceValidated,
|
||||
workflow: async (input) => {
|
||||
const { compareSourceToBundleEvidenceValidated } =
|
||||
await import("../application/javascript/JavaScriptApplicationWorkflowService.js");
|
||||
return compareSourceToBundleEvidenceValidated(input);
|
||||
},
|
||||
});
|
||||
registerJsonCommand({
|
||||
cli,
|
||||
@@ -79,7 +84,11 @@ export const registerApplicationCommands = (
|
||||
description:
|
||||
"Compare exact static JavaScript export return shapes without execution",
|
||||
inputSchema: compareJavaScriptExportShapesInputSchema,
|
||||
workflow: compareJavaScriptExportShapesEvidenceValidated,
|
||||
workflow: async (input) => {
|
||||
const { compareJavaScriptExportShapesEvidenceValidated } =
|
||||
await import("../application/javascript/JavaScriptApplicationWorkflowService.js");
|
||||
return compareJavaScriptExportShapesEvidenceValidated(input);
|
||||
},
|
||||
});
|
||||
registerObligationLedgerCommand(cli, logger);
|
||||
registerCoverageCommand(cli, logger);
|
||||
@@ -90,7 +99,9 @@ export const registerApplicationCommands = (
|
||||
description:
|
||||
"Project authenticated APK inventory Evidence into an Android application graph",
|
||||
inputSchema: androidApplicationProjectionInputSchema,
|
||||
workflow: (input) => {
|
||||
workflow: async (input) => {
|
||||
const { projectAndroidApplicationEvidence } =
|
||||
await import("../application/android/AndroidApplicationService.js");
|
||||
const result = projectAndroidApplicationEvidence(input);
|
||||
return result.ok
|
||||
? { ok: true, value: jsonValueSchema.parse(result.value) }
|
||||
@@ -104,7 +115,9 @@ export const registerApplicationCommands = (
|
||||
description:
|
||||
"Project authenticated IPA or macOS app inventory Evidence into an Apple application graph",
|
||||
inputSchema: appleApplicationProjectionInputSchema,
|
||||
workflow: (input) => {
|
||||
workflow: async (input) => {
|
||||
const { projectAppleApplicationEvidence } =
|
||||
await import("../application/apple/AppleApplicationService.js");
|
||||
const result = projectAppleApplicationEvidence(input);
|
||||
return result.ok
|
||||
? { ok: true, value: jsonValueSchema.parse(result.value) }
|
||||
@@ -124,7 +137,9 @@ const registerObligationLedgerCommand = (
|
||||
description:
|
||||
"Generate a deterministic Evidence-backed reconstruction obligation ledger page",
|
||||
inputSchema: reconstructionObligationLedgerInputSchema,
|
||||
workflow: (input) => {
|
||||
workflow: async (input) => {
|
||||
const { buildReconstructionObligationLedgerEvidenceValidated } =
|
||||
await import("../application/ReconstructionObligationLedgerService.js");
|
||||
const result =
|
||||
buildReconstructionObligationLedgerEvidenceValidated(input);
|
||||
return result.ok
|
||||
@@ -140,7 +155,9 @@ const registerCoverageCommand = (cli: CliInstance, logger: Logger): void =>
|
||||
name: CLI_COMMANDS.evaluateReconstructionCoverage,
|
||||
description: "Evaluate inline fail-closed reconstruction coverage",
|
||||
inputSchema: reconstructionCoverageEvaluationInputSchema,
|
||||
workflow: (input) => {
|
||||
workflow: async (input) => {
|
||||
const { evaluateReconstructionCoverage } =
|
||||
await import("../application/ReconstructionCoverageService.js");
|
||||
const result = evaluateReconstructionCoverage(input);
|
||||
return result.ok
|
||||
? { ok: true, value: jsonValueSchema.parse(result.value) }
|
||||
@@ -156,9 +173,10 @@ interface JsonCommandOptions<Schema extends z.ZodType> {
|
||||
readonly inputSchema: Schema;
|
||||
readonly workflow: (
|
||||
input: z.output<Schema>,
|
||||
) =>
|
||||
) => Promise<
|
||||
| { readonly ok: true; readonly value: JsonValue }
|
||||
| { readonly ok: false; readonly error: AnalysisError };
|
||||
| { readonly ok: false; readonly error: AnalysisError }
|
||||
>;
|
||||
}
|
||||
|
||||
const registerJsonCommand = <Schema extends z.ZodType>({
|
||||
@@ -190,7 +208,7 @@ const registerJsonCommand = <Schema extends z.ZodType>({
|
||||
),
|
||||
),
|
||||
};
|
||||
const result = workflow(parsed.data);
|
||||
const result = await workflow(parsed.data);
|
||||
return result.ok
|
||||
? result.value
|
||||
: {
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
import { Cli, z } from "incur";
|
||||
|
||||
import {
|
||||
inspectElectronPage,
|
||||
listElectronTargets,
|
||||
} from "../application/javascript/ElectronObservationService.js";
|
||||
import { captureElectronScenario } from "../application/javascript/ElectronActiveObservationService.js";
|
||||
import { reconcileJavaScriptRuntimeEvidence } from "../application/javascript/JavaScriptRuntimeReconciliationService.js";
|
||||
import { logCliCommand } from "../cliLogging.js";
|
||||
import {
|
||||
inspectElectronPageInputSchema,
|
||||
@@ -76,6 +70,8 @@ const registerElectronActiveCommand = (
|
||||
parsed.error.issues,
|
||||
input.value,
|
||||
);
|
||||
const { captureElectronScenario } =
|
||||
await import("../application/javascript/ElectronActiveObservationService.js");
|
||||
const { createElectronScenarioProvider } =
|
||||
await import("../composition/electronScenario.js");
|
||||
const result = await captureElectronScenario(
|
||||
@@ -114,6 +110,8 @@ const registerJavaScriptRuntimeReconciliationCommand = (
|
||||
"reconcile_javascript_runtime",
|
||||
);
|
||||
if (!input.ok) return input.error;
|
||||
const { reconcileJavaScriptRuntimeEvidence } =
|
||||
await import("../application/javascript/JavaScriptRuntimeReconciliationService.js");
|
||||
const result = reconcileJavaScriptRuntimeEvidence(input.value);
|
||||
return result.ok ? result.value : cliError(result.error);
|
||||
},
|
||||
@@ -146,6 +144,8 @@ const registerElectronTargetList = (
|
||||
cdp_endpoint: args.endpoint,
|
||||
});
|
||||
if (!parsed.success) return inputError("list_electron_targets");
|
||||
const { listElectronTargets } =
|
||||
await import("../application/javascript/ElectronObservationService.js");
|
||||
const result = await listElectronTargets(context.provider, parsed.data);
|
||||
return result.ok ? result.value : cliError(result.error);
|
||||
}),
|
||||
@@ -173,6 +173,8 @@ const registerElectronPageInspection = (
|
||||
include_script_sources: options.includeScriptSources,
|
||||
});
|
||||
if (!parsed.success) return inputError("inspect_electron_page");
|
||||
const { inspectElectronPage } =
|
||||
await import("../application/javascript/ElectronObservationService.js");
|
||||
const result = await inspectElectronPage(context.provider, parsed.data);
|
||||
return result.ok ? result.value : cliError(result.error);
|
||||
}),
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { analyzeJavaScriptApplication } from "../application/javascript/JavaScriptApplicationService.js";
|
||||
import { JAVASCRIPT_APPLICATION_PROVIDER } from "../application/InvestigationProviders.js";
|
||||
import { createProgressReporter } from "../application/ProgressReporter.js";
|
||||
import { ArtifactReaderFailure } from "../artifacts/ArtifactReader.js";
|
||||
@@ -13,6 +12,8 @@ export const runCliJavaScriptApplicationAnalysis = async (
|
||||
input: unknown,
|
||||
signal?: AbortSignal,
|
||||
): Promise<JsonValue> => {
|
||||
const { analyzeJavaScriptApplication } =
|
||||
await import("../application/javascript/JavaScriptApplicationService.js");
|
||||
const progress = createProgressReporter(
|
||||
async (update) => {
|
||||
process.stderr.write(`${JSON.stringify({ rea_progress: update })}\n`);
|
||||
|
||||
@@ -74,6 +74,46 @@ const DEFERRED_IMPORTS = [
|
||||
name: "binary-composition",
|
||||
path: "/dist/composition/binary.js",
|
||||
},
|
||||
{
|
||||
name: "javascript-application",
|
||||
path: "/dist/application/javascript/JavaScriptApplicationService.js",
|
||||
},
|
||||
{
|
||||
name: "javascript-workflows",
|
||||
path: "/dist/application/javascript/JavaScriptApplicationWorkflowService.js",
|
||||
},
|
||||
{
|
||||
name: "javascript-semantic-trace",
|
||||
path: "/dist/application/javascript/JavaScriptSemanticTraceService.js",
|
||||
},
|
||||
{
|
||||
name: "electron-observation",
|
||||
path: "/dist/application/javascript/ElectronObservationService.js",
|
||||
},
|
||||
{
|
||||
name: "electron-active-observation",
|
||||
path: "/dist/application/javascript/ElectronActiveObservationService.js",
|
||||
},
|
||||
{
|
||||
name: "javascript-runtime-reconciliation",
|
||||
path: "/dist/application/javascript/JavaScriptRuntimeReconciliationService.js",
|
||||
},
|
||||
{
|
||||
name: "android-application",
|
||||
path: "/dist/application/android/AndroidApplicationService.js",
|
||||
},
|
||||
{
|
||||
name: "apple-application",
|
||||
path: "/dist/application/apple/AppleApplicationService.js",
|
||||
},
|
||||
{
|
||||
name: "reconstruction-coverage",
|
||||
path: "/dist/application/ReconstructionCoverageService.js",
|
||||
},
|
||||
{
|
||||
name: "reconstruction-obligation-ledger",
|
||||
path: "/dist/application/ReconstructionObligationLedgerService.js",
|
||||
},
|
||||
] as const;
|
||||
// Report each resolved deferred package on stderr without changing resolution.
|
||||
const RESOLUTION_HOOK = `data:text/javascript,${encodeURIComponent(`
|
||||
@@ -174,7 +214,7 @@ describe("CLI startup imports", () => {
|
||||
source,
|
||||
"--json",
|
||||
]),
|
||||
).resolves.toEqual(new Set());
|
||||
).resolves.toEqual(new Set(["javascript-application"]));
|
||||
});
|
||||
|
||||
it("loads native provider composition when a provider operation is called", async () => {
|
||||
|
||||
Reference in New Issue
Block a user