rea-agents 1.7.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +112 -59
- package/bridge/ghidra/ReaGhidraBridge.java +96 -11
- package/dist/application/ArtifactExtraction.js +1 -1
- package/dist/application/ArtifactInventory/classify.js +42 -0
- package/dist/application/ArtifactInventory/hash.js +43 -0
- package/dist/application/ArtifactInventory/reader.js +41 -0
- package/dist/application/ArtifactInventory/scanCanonical.js +155 -0
- package/dist/application/ArtifactInventory/scanReader.js +124 -0
- package/dist/application/ArtifactInventory/types.js +10 -0
- package/dist/application/ArtifactInventory.js +9 -351
- package/dist/application/AuthorizedArtifactInventory.js +2 -2
- package/dist/application/BinarySession.js +47 -270
- package/dist/application/BinarySessionExecution.js +28 -0
- package/dist/application/BinarySessionOpen.js +39 -0
- package/dist/application/BinarySessionRecords.js +149 -0
- package/dist/application/BinarySessionStatus.js +75 -0
- package/dist/application/CapabilityInventory.js +42 -2
- package/dist/application/ClientRegistrationStatus.js +1 -1
- package/dist/application/CrossVersionInventory.js +8 -2
- package/dist/application/CrossVersionInvestigation.js +11 -29
- package/dist/application/CrossVersionInvestigationCollections.js +23 -0
- package/dist/application/DirectAnalysis.js +47 -44
- package/dist/application/Doctor.js +165 -197
- package/dist/application/DoctorDiagnostics.js +180 -0
- package/dist/application/ElectronBoundaryAnalysis.js +112 -0
- package/dist/application/ElectronBoundaryGraph.js +9 -0
- package/dist/application/ElectronBoundaryGraphContext.js +62 -0
- package/dist/application/ElectronBoundaryGraphIpc.js +242 -0
- package/dist/application/ElectronBoundaryGraphNative.js +86 -0
- package/dist/application/ElectronBoundaryGraphWindows.js +223 -0
- package/dist/application/EnhancedToolPagination.js +22 -0
- package/dist/application/EnhancedToolTypes.js +4 -0
- package/dist/application/EnhancedTools.js +58 -50
- package/dist/application/InstrumentedJavaScriptReplayHost.js +36 -0
- package/dist/application/InvestigationProviders.js +30 -0
- package/dist/application/InvestigationWorkspaceStore.js +24 -10
- package/dist/application/JavaScriptApplicationEvidence.js +26 -0
- package/dist/application/JavaScriptApplicationEvidenceGraph.js +89 -0
- package/dist/application/JavaScriptApplicationService.js +74 -0
- package/dist/application/JavaScriptApplicationWorkflowEvidence.js +29 -0
- package/dist/application/JavaScriptApplicationWorkflowService.js +90 -0
- package/dist/application/JavaScriptArtifactAnalysis.js +52 -7
- package/dist/application/JavaScriptArtifactFiles.js +6 -2
- package/dist/application/JavaScriptArtifactGraphBuilder.js +82 -17
- package/dist/application/JavaScriptArtifactGraphBundlers.js +225 -0
- package/dist/application/JavaScriptArtifactGraphContext.js +37 -36
- package/dist/application/JavaScriptArtifactGraphDocuments.js +27 -4
- package/dist/application/JavaScriptArtifactGraphEvidence.js +24 -14
- package/dist/application/JavaScriptArtifactGraphFindings.js +54 -8
- package/dist/application/JavaScriptArtifactGraphStructure.js +29 -101
- package/dist/application/JavaScriptArtifactPathResolution.js +269 -0
- package/dist/application/JavaScriptArtifactReconstruction.js +4 -1
- package/dist/application/JavaScriptArtifactReconstructionInput.js +2 -83
- package/dist/application/JavaScriptJsonModules.js +39 -0
- package/dist/application/JavaScriptModuleRelationships.js +262 -0
- package/dist/application/JavaScriptReplayPermission.js +16 -0
- package/dist/application/JavaScriptReplayPlanning.js +201 -0
- package/dist/application/JavaScriptReplayService.js +292 -0
- package/dist/application/JavaScriptRuntimeReconciliationEvidence.js +25 -0
- package/dist/application/JavaScriptRuntimeReconciliationService.js +27 -0
- package/dist/application/LinuxHopper.js +10 -0
- package/dist/application/MacHopper.js +22 -11
- package/dist/application/ManagedApplicationGraphService.js +55 -0
- package/dist/application/ManagedMemberComparisonService.js +122 -0
- package/dist/application/ManagedNativeVerificationService.js +39 -0
- package/dist/application/ManagedReconstructionService.js +58 -0
- package/dist/application/ManagedRuntimeCorrelationService.js +103 -0
- package/dist/application/NodeRuntimeCharacterizationService.js +196 -0
- package/dist/application/PermissionAuthority.js +106 -63
- package/dist/application/ProcessCaptureCapability.js +1 -1
- package/dist/application/ProcessCapturePermission.js +13 -0
- package/dist/application/ProcessCli.js +2 -12
- package/dist/application/ProcessHarness.js +1 -1
- package/dist/application/ProcessSampling.js +15 -11
- package/dist/application/ProjectPermissionStore.js +49 -9
- package/dist/application/RealHopperAssertions.js +76 -0
- package/dist/application/ReconstructionCoverageService.js +69 -0
- package/dist/application/ReconstructionCoverageWorkspaceStore.js +31 -0
- package/dist/application/RuntimeExecutableDiagnostics.js +172 -0
- package/dist/application/Setup.js +147 -259
- package/dist/application/SetupClientConfiguration.js +220 -0
- package/dist/application/SetupClients.js +24 -2
- package/dist/application/SetupPlan.js +123 -12
- package/dist/application/SetupSkill.js +26 -12
- package/dist/application/SupportedClients.js +1 -0
- package/dist/application/Uninstall.js +6 -3
- package/dist/application/WindowsCapabilities.js +86 -0
- package/dist/application/runtime.js +2 -0
- package/dist/artifacts/AsarArtifactReader.js +11 -0
- package/dist/browser/BrowserProcessStartup.js +88 -0
- package/dist/browser/CdpCaptureDocuments.js +12 -8
- package/dist/browser/CdpCaptureEventBodyShapes.js +75 -0
- package/dist/browser/CdpCaptureEventHandlers.js +336 -0
- package/dist/browser/CdpCaptureEventHelpers.js +71 -0
- package/dist/browser/CdpCaptureEventState.js +1 -0
- package/dist/browser/CdpCaptureEventTypes.js +1 -0
- package/dist/browser/CdpCaptureEvents.js +46 -464
- package/dist/browser/CdpElectronInspection.js +106 -162
- package/dist/browser/CdpElectronProvider.js +5 -1
- package/dist/browser/CdpElectronScriptEvents.js +69 -0
- package/dist/browser/CdpElectronScripts.js +94 -0
- package/dist/browser/CdpElectronWorkers.js +56 -0
- package/dist/browser/CdpObservationSession.js +51 -8
- package/dist/browser/CdpPageCapture.js +12 -129
- package/dist/browser/CdpPageCaptureScripts.js +97 -0
- package/dist/browser/CdpPageCaptureWorkers.js +46 -0
- package/dist/browser/CdpWebMcpDiscovery.js +38 -14
- package/dist/browser/PngVisualDiff.js +9 -2
- package/dist/catalogIdentity.js +8 -1
- package/dist/cli/artifactCommands.js +82 -0
- package/dist/cli/coreAnalysisCommands.js +232 -0
- package/dist/cli/managedCommands.js +397 -0
- package/dist/cli/managedProjectGraphCommand.js +24 -0
- package/dist/cli/options.js +9 -0
- package/dist/cli/setupCommands.js +108 -0
- package/dist/cli/types.js +1 -0
- package/dist/cli/utilityCommands.js +122 -0
- package/dist/cli.js +13 -383
- package/dist/cliApplicationCommands.js +176 -0
- package/dist/cliBrowserAdvancedCommands.js +73 -16
- package/dist/cliBrowserCommands.js +39 -115
- package/dist/cliCommandNames.js +17 -0
- package/dist/cliElectronCommands.js +100 -27
- package/dist/cliEvidenceCommands.js +13 -2
- package/dist/cliInvestigationCommands.js +53 -10
- package/dist/cliJsonInput.js +54 -0
- package/dist/cliObservationOptions.js +137 -0
- package/dist/cliPolicyCommands.js +80 -46
- package/dist/cliSetup.js +289 -0
- package/dist/config/environment.js +107 -0
- package/dist/config/parseConfig.js +228 -0
- package/dist/config/parsers.js +68 -0
- package/dist/config/permissions.js +30 -0
- package/dist/config/types.js +1 -0
- package/dist/config.js +1 -292
- package/dist/contracts/applicationToolContracts.js +225 -0
- package/dist/contracts/artifactToolContracts.js +5 -9
- package/dist/contracts/browserToolContracts.js +14 -62
- package/dist/contracts/electronToolContracts.js +45 -19
- package/dist/contracts/errorSchemas.js +1 -0
- package/dist/contracts/investigationExamples.js +0 -6
- package/dist/contracts/javascriptApplicationWorkflowExamples.js +46 -0
- package/dist/contracts/javascriptRuntimeReconciliationExample.js +208 -0
- package/dist/contracts/managedToolContracts.js +153 -0
- package/dist/contracts/managedWorkflowExamples.js +346 -0
- package/dist/contracts/managedWorkflowToolContracts.js +203 -0
- package/dist/contracts/nativeToolContracts.js +2 -6
- package/dist/contracts/promptContracts.js +18 -2
- package/dist/contracts/providerSelection.js +2 -0
- package/dist/contracts/toolContractExamples.js +10 -25
- package/dist/contracts/toolContracts.js +49 -47
- package/dist/contracts/toolEffects.js +174 -0
- package/dist/contracts/toolOutputSchemaGroups.js +232 -0
- package/dist/contracts/toolOutputSchemaPrimitives.js +327 -0
- package/dist/contracts/toolOutputSchemas.js +2 -535
- package/dist/doctorRuntime.js +42 -1
- package/dist/domain/analysisErrorPresentation.js +234 -0
- package/dist/domain/analysisErrorProjection.js +284 -0
- package/dist/domain/artifactComparison.js +37 -19
- package/dist/domain/binaryTarget.js +87 -37
- package/dist/domain/browserObservation.js +1 -282
- package/dist/domain/browserObservationSchemas.js +286 -0
- package/dist/domain/bundleComparison.js +4 -4
- package/dist/domain/electronObservation.js +13 -0
- package/dist/domain/electronStaticAnalysis.js +9 -0
- package/dist/domain/electronStaticAnalysisBrowser.js +206 -0
- package/dist/domain/electronStaticAnalysisIpc.js +171 -0
- package/dist/domain/electronStaticAnalysisNative.js +164 -0
- package/dist/domain/electronStaticAnalysisTypes.js +1 -0
- package/dist/domain/electronStaticAnalysisValues.js +103 -0
- package/dist/domain/errors.js +32 -448
- package/dist/domain/functionComparison.js +4 -165
- package/dist/domain/functionComparisonDimensions.js +164 -0
- package/dist/domain/functionComparisonSchemas.js +3 -8
- package/dist/domain/inputIssueProjection.js +52 -0
- package/dist/domain/javascriptApplicationAnalysis.js +155 -0
- package/dist/domain/javascriptApplicationChangeGraph.js +231 -0
- package/dist/domain/javascriptApplicationEvidenceSchemas.js +18 -0
- package/dist/domain/javascriptApplicationGraph.js +2 -1
- package/dist/domain/javascriptApplicationGraphSchemas.js +7 -0
- package/dist/domain/javascriptApplicationVersionComparison.js +116 -0
- package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +139 -0
- package/dist/domain/javascriptApplicationVersionItems.js +233 -0
- package/dist/domain/javascriptApplicationVersionKeys.js +170 -0
- package/dist/domain/javascriptExportInstrumentation.js +97 -0
- package/dist/domain/javascriptFeatureSeed.js +140 -0
- package/dist/domain/javascriptFeatureTrace.js +232 -0
- package/dist/domain/javascriptFeatureTraceSchemas.js +136 -0
- package/dist/domain/javascriptFeatureTraversal.js +100 -0
- package/dist/domain/javascriptNativeHandoff.js +85 -0
- package/dist/domain/javascriptReplay.js +361 -0
- package/dist/domain/javascriptRuntimeLoadState.js +106 -0
- package/dist/domain/javascriptRuntimeReconciliation.js +42 -0
- package/dist/domain/javascriptRuntimeReconciliationGraph.js +169 -0
- package/dist/domain/javascriptRuntimeReconciliationMatching.js +247 -0
- package/dist/domain/javascriptRuntimeReconciliationParsing.js +160 -0
- package/dist/domain/javascriptRuntimeReconciliationResult.js +119 -0
- package/dist/domain/javascriptRuntimeReconciliationRuntime.js +316 -0
- package/dist/domain/javascriptRuntimeReconciliationSchemas.js +245 -0
- package/dist/domain/javascriptRuntimeStaticCandidates.js +193 -0
- package/dist/domain/javascriptSemanticAnalysis.js +386 -0
- package/dist/domain/javascriptSemanticIr.js +30 -0
- package/dist/domain/javascriptSemanticProjection.js +366 -0
- package/dist/domain/javascriptSemanticState.js +40 -0
- package/dist/domain/javascriptSemanticTraversal.js +22 -0
- package/dist/domain/javascriptSemanticValues.js +352 -0
- package/dist/domain/javascriptStaticAnalysis.js +26 -254
- package/dist/domain/javascriptStaticAnalysisBundler.js +209 -0
- package/dist/domain/javascriptStaticAnalysisCalls.js +180 -0
- package/dist/domain/javascriptStaticAnalysisFindings.js +39 -0
- package/dist/domain/javascriptStaticAnalysisHelpers.js +81 -2
- package/dist/domain/javascriptStaticAnalysisState.js +6 -0
- package/dist/domain/knownPageCoverage.js +21 -0
- package/dist/domain/managedApplicationGraph.js +206 -0
- package/dist/domain/managedApplicationGraphCoverage.js +170 -0
- package/dist/domain/managedApplicationGraphNodeCoverage.js +6 -0
- package/dist/domain/managedApplicationGraphNodes.js +336 -0
- package/dist/domain/managedArtifact.js +452 -0
- package/dist/domain/managedMemberComparison.js +211 -0
- package/dist/domain/managedMemberComparisonCoverage.js +72 -0
- package/dist/domain/managedMemberComparisonMatch.js +356 -0
- package/dist/domain/managedNativeVerification.js +46 -0
- package/dist/domain/managedNativeVerificationMatch.js +272 -0
- package/dist/domain/managedNativeVerificationSchemas.js +141 -0
- package/dist/domain/managedReconstruction.js +196 -0
- package/dist/domain/managedRuntimeCorrelation.js +184 -0
- package/dist/domain/nodeRuntimeCharacterization.js +66 -0
- package/dist/domain/permissionPolicy.js +2 -0
- package/dist/domain/reconstructionCoverage.js +387 -0
- package/dist/domain/reconstructionCoverageEvaluation.js +212 -0
- package/dist/domain/reconstructionVerificationSchemas.js +9 -3
- package/dist/domain/runtimeCharacterization.js +85 -0
- package/dist/domain/webBundleAnalyzer.js +3 -409
- package/dist/domain/webBundleAnalyzerAst.js +77 -0
- package/dist/domain/webBundleAnalyzerInspection.js +307 -0
- package/dist/domain/webBundleAnalyzerResult.js +120 -0
- package/dist/dotnet/ManagedArtifactInspector.js +339 -0
- package/dist/dotnet/ManagedMemberInspector.js +153 -0
- package/dist/dotnet/ManagedMemberInspectorCore.js +297 -0
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +427 -0
- package/dist/dotnet/ManagedMemberRows.js +120 -0
- package/dist/dotnet/ManagedMetadataHeaps.js +131 -0
- package/dist/dotnet/ManagedMetadataInventory.js +104 -0
- package/dist/dotnet/ManagedMetadataInventoryRows.js +292 -0
- package/dist/dotnet/ManagedMetadataLayout.js +259 -0
- package/dist/dotnet/ManagedMetadataRowSizes.js +54 -0
- package/dist/dotnet/ManagedMethodBodyReader.js +143 -0
- package/dist/dotnet/ManagedNativeBoundaryHelpers.js +311 -0
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +143 -0
- package/dist/dotnet/ManagedPeReader.js +188 -0
- package/dist/dotnet/ManagedReaderFailure.js +10 -0
- package/dist/dotnet/ManagedStaticProvider.js +203 -0
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraClient.js +76 -91
- package/dist/ghidra/GhidraClientStartup.js +29 -0
- package/dist/ghidra/GhidraClientWire.js +34 -0
- package/dist/ghidra/GhidraDefaults.js +1 -1
- package/dist/ghidra/GhidraDiagnostics.js +6 -1
- package/dist/ghidra/GhidraInstallation.js +20 -15
- package/dist/ghidra/GhidraLauncher.js +93 -29
- package/dist/ghidra/GhidraProvider.js +67 -161
- package/dist/ghidra/GhidraProviderCapabilities.js +173 -0
- package/dist/ghidra/GhidraSessionValues.js +2 -0
- package/dist/ghidra/GhidraSocketConnection.js +44 -7
- package/dist/ghidra/GhidraTargetSnapshot.js +30 -0
- package/dist/ghidra/GhidraTransport.js +71 -0
- package/dist/identity.js +3 -2
- package/dist/main/messages.js +5 -0
- package/dist/main/reload.js +49 -0
- package/dist/main/shutdown.js +25 -0
- package/dist/main/startup.js +14 -0
- package/dist/main/state.js +26 -0
- package/dist/main/transport.js +61 -0
- package/dist/main/types.js +1 -0
- package/dist/main.js +35 -132
- package/dist/process/PrivateRuntimeRoot.js +3 -2
- package/dist/process/ProcessOwnership.js +35 -0
- package/dist/process/ProviderProcess.js +2 -0
- package/dist/replay/JavaScriptReplayWorker.js +300 -0
- package/dist/replay/LinuxJavaScriptReplayRunner.js +217 -0
- package/dist/replay/LinuxJavaScriptReplaySandbox.js +140 -0
- package/dist/replay/LinuxRuntimeClosure.js +46 -0
- package/dist/replay/LinuxSeccompPolicy.js +40 -0
- package/dist/replay/ReplayOutcome.js +95 -0
- package/dist/replay/ReplayProcessLifecycle.js +71 -0
- package/dist/replay/ReplayWorkerProtocol.js +55 -0
- package/dist/replay/SystemJavaScriptReplayHost.js +182 -0
- package/dist/server/ProcessCaptureElicitation.js +157 -0
- package/dist/server/createServer.js +158 -41
- package/dist/server/registerApplicationTools/characterization.js +57 -0
- package/dist/server/registerApplicationTools/compareVersions.js +34 -0
- package/dist/server/registerApplicationTools/controlledReplay.js +38 -0
- package/dist/server/registerApplicationTools/coverage.js +84 -0
- package/dist/server/registerApplicationTools/helpers.js +42 -0
- package/dist/server/registerApplicationTools/traceFeature.js +26 -0
- package/dist/server/registerApplicationTools/types.js +1 -0
- package/dist/server/registerApplicationTools.js +13 -0
- package/dist/server/registerArtifactComparisonTool.js +16 -9
- package/dist/server/registerBrowserTools.js +61 -60
- package/dist/server/registerBundleComparisonTool.js +17 -20
- package/dist/server/registerElectronTools.js +39 -12
- package/dist/server/registerEnhancedTools.js +52 -15
- package/dist/server/registerEvidenceResources.js +54 -0
- package/dist/server/registerEvidenceTools.js +5 -1
- package/dist/server/registerFunctionComparisonTool.js +14 -7
- package/dist/server/registerInvestigationTools/helpers.js +74 -0
- package/dist/server/registerInvestigationTools/types.js +1 -0
- package/dist/server/registerInvestigationTools.js +103 -132
- package/dist/server/registerManagedTools.js +6 -0
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +65 -0
- package/dist/server/registerManagedWorkflowTools/contract.js +8 -0
- package/dist/server/registerManagedWorkflowTools/evidence.js +43 -0
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +39 -0
- package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +39 -0
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +52 -0
- package/dist/server/registerManagedWorkflowTools/types.js +1 -0
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +75 -0
- package/dist/server/registerManagedWorkflowTools.js +13 -0
- package/dist/server/registerOfficialTools.js +81 -67
- package/dist/server/registerProcessComparisonTool.js +25 -47
- package/dist/server/registerSessionRecordTools.js +137 -0
- package/dist/server/registerSessionStatusTool.js +9 -8
- package/dist/server/registerSessionTools.js +77 -216
- package/dist/server/sessionAvailabilityPolicy.js +10 -0
- package/dist/server/sessionEvidence.js +14 -19
- package/dist/server/toolInputValidation.js +77 -0
- package/dist/server/toolRegistrationOptions.js +177 -2
- package/dist/server/toolResult.js +30 -17
- package/package.json +21 -14
- package/scripts/rea.mjs +1 -1
- package/skills/{rea-analysis → reverse-engineer-anything}/SKILL.md +75 -6
- package/scripts/prepare-node-pty.mjs +0 -35
- package/scripts/rebuild-native.mjs +0 -22
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { JAVASCRIPT_APPLICATION_PROVIDER, JAVASCRIPT_RUNTIME_RECONCILIATION_PROVIDER, MANAGED_WORKFLOW_PROVIDER, } from "./InvestigationProviders.js";
|
|
2
|
+
import { parseEvidence } from "../domain/evidence.js";
|
|
3
|
+
import { analyzeJavaScriptApplicationInputSchema, javascriptApplicationAnalysisResultSchema, } from "../domain/javascriptApplicationAnalysis.js";
|
|
4
|
+
import { javascriptRuntimeReconciliationResultSchema } from "../domain/javascriptRuntimeReconciliationSchemas.js";
|
|
5
|
+
import { managedApplicationGraphResultSchema } from "../domain/managedApplicationGraph.js";
|
|
6
|
+
/** Parse and authenticate one REA-produced JavaScript Application Graph Evidence. */
|
|
7
|
+
export const parseApplicationGraphEvidence = (input) => {
|
|
8
|
+
const evidence = parseEvidence(input);
|
|
9
|
+
if (evidence.operation === "analyze_javascript_application" &&
|
|
10
|
+
evidence.predicate_type === "rea.javascript-application-analysis/v1" &&
|
|
11
|
+
providerMatches(evidence, JAVASCRIPT_APPLICATION_PROVIDER))
|
|
12
|
+
return staticApplicationSource(evidence);
|
|
13
|
+
if (evidence.operation === "reconcile_javascript_runtime" &&
|
|
14
|
+
evidence.predicate_type === "rea.javascript-runtime-reconciliation/v1" &&
|
|
15
|
+
providerMatches(evidence, JAVASCRIPT_RUNTIME_RECONCILIATION_PROVIDER))
|
|
16
|
+
return staticRuntimeSource(evidence);
|
|
17
|
+
if (evidence.operation === "project_managed_application_graph" &&
|
|
18
|
+
evidence.predicate_type === "rea.managed-application-graph/v1" &&
|
|
19
|
+
providerMatches(evidence, MANAGED_WORKFLOW_PROVIDER))
|
|
20
|
+
return managedApplicationSource(evidence);
|
|
21
|
+
throw new TypeError("Application workflow requires authenticated analyze_javascript_application, reconcile_javascript_runtime, or project_managed_application_graph Evidence");
|
|
22
|
+
};
|
|
23
|
+
const staticApplicationSource = (evidence) => {
|
|
24
|
+
if (evidence.authority !== "shipped-artifact" ||
|
|
25
|
+
evidence.confidence !== "derived")
|
|
26
|
+
throw new TypeError("JavaScript application Evidence authority or confidence is invalid");
|
|
27
|
+
const result = javascriptApplicationAnalysisResultSchema.parse(evidence.normalized_result);
|
|
28
|
+
analyzeJavaScriptApplicationInputSchema.parse({
|
|
29
|
+
input_path: result.input_path,
|
|
30
|
+
...evidence.parameters,
|
|
31
|
+
});
|
|
32
|
+
assertApplicationSubject(evidence, result);
|
|
33
|
+
return {
|
|
34
|
+
evidence,
|
|
35
|
+
graph: result.graph,
|
|
36
|
+
kind: "static-application",
|
|
37
|
+
rootArtifactSha256: result.root_artifact_sha256,
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
const staticRuntimeSource = (evidence) => {
|
|
41
|
+
if (evidence.authority !== "analyst-inference" ||
|
|
42
|
+
evidence.confidence !== "inferred")
|
|
43
|
+
throw new TypeError("JavaScript runtime reconciliation Evidence authority or confidence is invalid");
|
|
44
|
+
const result = javascriptRuntimeReconciliationResultSchema.parse(evidence.normalized_result);
|
|
45
|
+
if (result.evidence_links.some((evidenceId) => !evidence.evidence_links.includes(evidenceId)))
|
|
46
|
+
throw new TypeError("Runtime reconciliation result references Evidence outside its envelope");
|
|
47
|
+
const applicationLayer = result.static_layers.find(({ role }) => role === "application");
|
|
48
|
+
if (applicationLayer === undefined)
|
|
49
|
+
throw new TypeError("Runtime reconciliation application layer is missing");
|
|
50
|
+
return {
|
|
51
|
+
evidence,
|
|
52
|
+
graph: result.graph,
|
|
53
|
+
kind: "static-runtime-reconciliation",
|
|
54
|
+
rootArtifactSha256: applicationLayer.root_artifact_sha256,
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
const managedApplicationSource = (evidence) => {
|
|
58
|
+
if (evidence.authority !== "analyst-inference" ||
|
|
59
|
+
evidence.confidence !== "inferred")
|
|
60
|
+
throw new TypeError("Managed application graph Evidence authority or confidence is invalid");
|
|
61
|
+
const result = managedApplicationGraphResultSchema.parse(evidence.normalized_result);
|
|
62
|
+
if (result.evidence_links.some((evidenceId) => !evidence.evidence_links.includes(evidenceId)))
|
|
63
|
+
throw new TypeError("Managed application graph result references Evidence outside its envelope");
|
|
64
|
+
return {
|
|
65
|
+
evidence,
|
|
66
|
+
graph: result.graph,
|
|
67
|
+
kind: "managed-application",
|
|
68
|
+
rootArtifactSha256: result.root_artifact_sha256,
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
const assertApplicationSubject = (evidence, result) => {
|
|
72
|
+
if (evidence.subject === null ||
|
|
73
|
+
evidence.subject.digest.sha256 !== result.root_artifact_sha256 ||
|
|
74
|
+
evidence.subject.format !== result.format)
|
|
75
|
+
throw new TypeError("JavaScript application Evidence subject does not match its result");
|
|
76
|
+
};
|
|
77
|
+
const providerMatches = (evidence, provider) => evidence.provider.id === provider.id &&
|
|
78
|
+
evidence.provider.name === provider.name &&
|
|
79
|
+
evidence.provider.version === provider.version;
|
|
80
|
+
/** Parse unique, artifact-bound Evidence that may extend a native handoff. */
|
|
81
|
+
export const parseNativeApplicationEvidence = (inputs) => {
|
|
82
|
+
const parsed = inputs.map((input) => parseEvidence(input));
|
|
83
|
+
if (parsed.some(({ subject }) => subject === null))
|
|
84
|
+
throw new TypeError("Native handoff Evidence requires an artifact subject");
|
|
85
|
+
const ids = parsed.map(({ evidence_id: id }) => id);
|
|
86
|
+
if (new Set(ids).size !== ids.length)
|
|
87
|
+
throw new TypeError("Native handoff Evidence must be unique");
|
|
88
|
+
return parsed;
|
|
89
|
+
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ArtifactReaderFailure } from "../artifacts/ArtifactReader.js";
|
|
3
|
+
import { analyzeJavaScriptApplicationInputSchema, javascriptApplicationAnalysisResultSchema, } from "../domain/javascriptApplicationAnalysis.js";
|
|
4
|
+
import { AnalysisCapabilityUnavailableError, AnalysisInputError, AnalysisProtocolError, ArtifactOperationError, PermissionRequiredError, } from "../domain/errors.js";
|
|
5
|
+
import { err, ok } from "../domain/result.js";
|
|
6
|
+
import { createJavaScriptApplicationEvidence } from "./JavaScriptApplicationEvidence.js";
|
|
7
|
+
import { reconstructJavaScriptArtifact } from "./JavaScriptArtifactReconstruction.js";
|
|
8
|
+
const OPERATION = "analyze_javascript_application";
|
|
9
|
+
/** Authorize and statically analyze one local JavaScript/Electron application. */
|
|
10
|
+
export const analyzeJavaScriptApplication = async (authority, rawInput, options = {}) => {
|
|
11
|
+
const parsed = analyzeJavaScriptApplicationInputSchema.safeParse(rawInput);
|
|
12
|
+
if (!parsed.success)
|
|
13
|
+
return err(new AnalysisInputError(OPERATION));
|
|
14
|
+
return analyzeJavaScriptApplicationValidated(authority, parsed.data, options);
|
|
15
|
+
};
|
|
16
|
+
/** Analyze input already parsed by a trusted adapter boundary. */
|
|
17
|
+
export const analyzeJavaScriptApplicationValidated = async (authority, input, options = {}) => {
|
|
18
|
+
if (authority === undefined)
|
|
19
|
+
return err(new AnalysisCapabilityUnavailableError("rea-javascript-application", OPERATION, "JavaScript application permission policy is not configured"));
|
|
20
|
+
const authorized = await authority.authorize({
|
|
21
|
+
capability: "investigation_input",
|
|
22
|
+
roots: [input.input_path],
|
|
23
|
+
executables: [],
|
|
24
|
+
environment_names: [],
|
|
25
|
+
network: "none",
|
|
26
|
+
mount: false,
|
|
27
|
+
operation_identity: `${OPERATION}:${input.input_path}`,
|
|
28
|
+
}, "read");
|
|
29
|
+
if (!authorized.ok)
|
|
30
|
+
return err(authorized.error instanceof PermissionRequiredError
|
|
31
|
+
? authorized.error
|
|
32
|
+
: new ArtifactOperationError(OPERATION, "path", {
|
|
33
|
+
logicalPath: input.input_path,
|
|
34
|
+
declaredSha256: null,
|
|
35
|
+
calculatedSha256: null,
|
|
36
|
+
unpacked: false,
|
|
37
|
+
}));
|
|
38
|
+
await options.progress?.report({
|
|
39
|
+
phase: "analyze_javascript_application",
|
|
40
|
+
completed: 0,
|
|
41
|
+
total: 1,
|
|
42
|
+
message: "Inventorying and parsing approved application artifacts",
|
|
43
|
+
});
|
|
44
|
+
try {
|
|
45
|
+
const reconstructed = await reconstructJavaScriptArtifact({
|
|
46
|
+
input_path: input.input_path,
|
|
47
|
+
format: input.format,
|
|
48
|
+
source_map_read_approved: input.source_map_read_approved,
|
|
49
|
+
limits: input.limits,
|
|
50
|
+
}, options.signal);
|
|
51
|
+
const { electron_summary: summary, ...application } = reconstructed;
|
|
52
|
+
const result = javascriptApplicationAnalysisResultSchema.parse({
|
|
53
|
+
schema_version: 1,
|
|
54
|
+
...application,
|
|
55
|
+
summary,
|
|
56
|
+
limitations: reconstructed.graph.limitations,
|
|
57
|
+
});
|
|
58
|
+
await options.progress?.report({
|
|
59
|
+
phase: "analyze_javascript_application",
|
|
60
|
+
completed: 1,
|
|
61
|
+
total: 1,
|
|
62
|
+
message: "Application graph and Electron boundaries reconstructed",
|
|
63
|
+
terminal: true,
|
|
64
|
+
});
|
|
65
|
+
return ok(createJavaScriptApplicationEvidence(input, result));
|
|
66
|
+
}
|
|
67
|
+
catch (cause) {
|
|
68
|
+
if (cause instanceof ArtifactReaderFailure)
|
|
69
|
+
return err(new ArtifactOperationError(OPERATION, cause.reason, cause.details));
|
|
70
|
+
if (cause instanceof z.ZodError)
|
|
71
|
+
return err(new AnalysisProtocolError("JavaScript application analysis produced an invalid result", { cause }));
|
|
72
|
+
return err(new ArtifactOperationError(OPERATION, "io"));
|
|
73
|
+
}
|
|
74
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { createEvidence, } from "../domain/evidence.js";
|
|
2
|
+
import { jsonValueSchema } from "../domain/jsonValue.js";
|
|
3
|
+
import { JAVASCRIPT_APPLICATION_WORKFLOW_PROVIDER } from "./InvestigationProviders.js";
|
|
4
|
+
/** Create derived Evidence for one bounded application-graph feature trace. */
|
|
5
|
+
export const createApplicationFeatureTraceEvidence = (parameters, result) => createEvidence(undefined, JAVASCRIPT_APPLICATION_WORKFLOW_PROVIDER, {
|
|
6
|
+
predicateType: "rea.application-feature-trace/v1",
|
|
7
|
+
operation: "trace_application_feature",
|
|
8
|
+
parameters,
|
|
9
|
+
result: jsonValueSchema.parse(result),
|
|
10
|
+
rawResult: null,
|
|
11
|
+
confidence: "inferred",
|
|
12
|
+
authority: "analyst-inference",
|
|
13
|
+
environment: null,
|
|
14
|
+
limitations: result.limitations,
|
|
15
|
+
evidenceLinks: result.evidence_links,
|
|
16
|
+
});
|
|
17
|
+
/** Create derived Evidence for one tiered application version comparison. */
|
|
18
|
+
export const createApplicationVersionComparisonEvidence = (parameters, result) => createEvidence(undefined, JAVASCRIPT_APPLICATION_WORKFLOW_PROVIDER, {
|
|
19
|
+
predicateType: "rea.application-version-comparison/v1",
|
|
20
|
+
operation: "compare_application_versions",
|
|
21
|
+
parameters,
|
|
22
|
+
result: jsonValueSchema.parse(result),
|
|
23
|
+
rawResult: null,
|
|
24
|
+
confidence: "inferred",
|
|
25
|
+
authority: "analyst-inference",
|
|
26
|
+
environment: null,
|
|
27
|
+
limitations: result.limitations,
|
|
28
|
+
evidenceLinks: result.evidence_links,
|
|
29
|
+
});
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { AnalysisInputError, AnalysisProtocolError, } from "../domain/errors.js";
|
|
3
|
+
import { projectInputIssues } from "../domain/inputIssueProjection.js";
|
|
4
|
+
import { compareJavaScriptApplicationVersions } from "../domain/javascriptApplicationVersionComparison.js";
|
|
5
|
+
import { compareApplicationVersionsInputSchema } from "../domain/javascriptApplicationVersionComparisonSchemas.js";
|
|
6
|
+
import { traceApplicationFeature } from "../domain/javascriptFeatureTrace.js";
|
|
7
|
+
import { traceApplicationFeatureInputSchema } from "../domain/javascriptFeatureTraceSchemas.js";
|
|
8
|
+
import { err, ok } from "../domain/result.js";
|
|
9
|
+
import { parseApplicationGraphEvidence, parseNativeApplicationEvidence, } from "./JavaScriptApplicationEvidenceGraph.js";
|
|
10
|
+
import { createApplicationFeatureTraceEvidence, createApplicationVersionComparisonEvidence, } from "./JavaScriptApplicationWorkflowEvidence.js";
|
|
11
|
+
/** Authenticate Evidence and derive one bounded cross-layer feature trace. */
|
|
12
|
+
export const traceApplicationFeatureEvidence = (rawInput) => {
|
|
13
|
+
const operation = "trace_application_feature";
|
|
14
|
+
const parsed = traceApplicationFeatureInputSchema.safeParse(rawInput);
|
|
15
|
+
if (!parsed.success)
|
|
16
|
+
return err(new AnalysisInputError(operation, undefined, projectInputIssues(parsed.error.issues, rawInput)));
|
|
17
|
+
return traceApplicationFeatureEvidenceValidated(parsed.data);
|
|
18
|
+
};
|
|
19
|
+
/** Derive one feature trace from input parsed by a trusted adapter. */
|
|
20
|
+
export const traceApplicationFeatureEvidenceValidated = (input) => {
|
|
21
|
+
const operation = "trace_application_feature";
|
|
22
|
+
try {
|
|
23
|
+
const source = parseApplicationGraphEvidence(input.application);
|
|
24
|
+
const nativeEvidence = parseNativeApplicationEvidence(input.native_observations);
|
|
25
|
+
const result = traceApplicationFeature({
|
|
26
|
+
sourceEvidenceId: source.evidence.evidence_id,
|
|
27
|
+
graph: source.graph,
|
|
28
|
+
nativeEvidence,
|
|
29
|
+
seed: input.seed,
|
|
30
|
+
direction: input.direction,
|
|
31
|
+
limits: input.limits,
|
|
32
|
+
});
|
|
33
|
+
return ok(createApplicationFeatureTraceEvidence({
|
|
34
|
+
application_evidence_id: source.evidence.evidence_id,
|
|
35
|
+
native_evidence_ids: nativeEvidence.map(({ evidence_id: id }) => id),
|
|
36
|
+
seed: input.seed,
|
|
37
|
+
direction: input.direction,
|
|
38
|
+
limits: input.limits,
|
|
39
|
+
}, result));
|
|
40
|
+
}
|
|
41
|
+
catch (cause) {
|
|
42
|
+
return workflowFailure(operation, cause);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
/** Authenticate both graphs and derive a tiered cross-version change graph. */
|
|
46
|
+
export const compareApplicationVersionsEvidence = (rawInput) => {
|
|
47
|
+
const operation = "compare_application_versions";
|
|
48
|
+
const parsed = compareApplicationVersionsInputSchema.safeParse(rawInput);
|
|
49
|
+
if (!parsed.success)
|
|
50
|
+
return err(new AnalysisInputError(operation, undefined, projectInputIssues(parsed.error.issues, rawInput)));
|
|
51
|
+
return compareApplicationVersionsEvidenceValidated(parsed.data);
|
|
52
|
+
};
|
|
53
|
+
/** Compare versions from input parsed by a trusted adapter. */
|
|
54
|
+
export const compareApplicationVersionsEvidenceValidated = (input) => {
|
|
55
|
+
const operation = "compare_application_versions";
|
|
56
|
+
try {
|
|
57
|
+
const left = parseApplicationGraphEvidence(input.left);
|
|
58
|
+
const right = parseApplicationGraphEvidence(input.right);
|
|
59
|
+
const leftNative = parseNativeApplicationEvidence(input.left_native_observations);
|
|
60
|
+
const rightNative = parseNativeApplicationEvidence(input.right_native_observations);
|
|
61
|
+
const result = compareJavaScriptApplicationVersions({
|
|
62
|
+
left: {
|
|
63
|
+
evidenceId: left.evidence.evidence_id,
|
|
64
|
+
rootArtifactSha256: left.rootArtifactSha256,
|
|
65
|
+
graph: left.graph,
|
|
66
|
+
},
|
|
67
|
+
right: {
|
|
68
|
+
evidenceId: right.evidence.evidence_id,
|
|
69
|
+
rootArtifactSha256: right.rootArtifactSha256,
|
|
70
|
+
graph: right.graph,
|
|
71
|
+
},
|
|
72
|
+
leftNativeEvidence: leftNative,
|
|
73
|
+
rightNativeEvidence: rightNative,
|
|
74
|
+
limits: input.limits,
|
|
75
|
+
});
|
|
76
|
+
return ok(createApplicationVersionComparisonEvidence({
|
|
77
|
+
left_evidence_id: left.evidence.evidence_id,
|
|
78
|
+
right_evidence_id: right.evidence.evidence_id,
|
|
79
|
+
left_native_evidence_ids: leftNative.map(({ evidence_id: id }) => id),
|
|
80
|
+
right_native_evidence_ids: rightNative.map(({ evidence_id: id }) => id),
|
|
81
|
+
limits: input.limits,
|
|
82
|
+
}, result));
|
|
83
|
+
}
|
|
84
|
+
catch (cause) {
|
|
85
|
+
return workflowFailure(operation, cause);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const workflowFailure = (operation, cause) => err(cause instanceof z.ZodError || cause instanceof TypeError
|
|
89
|
+
? new AnalysisInputError(operation)
|
|
90
|
+
: new AnalysisProtocolError("JavaScript application workflow produced an invalid result", { cause }));
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { analyzeJavaScriptStaticSource } from "../domain/javascriptStaticAnalysis.js";
|
|
3
|
+
import { analyzeJavaScriptSemantics } from "../domain/javascriptSemanticAnalysis.js";
|
|
4
|
+
import { DEFAULT_JAVASCRIPT_SEMANTIC_LIMITS, } from "../domain/javascriptSemanticIr.js";
|
|
5
|
+
import { analyzeJavaScriptJsonModule } from "./JavaScriptJsonModules.js";
|
|
3
6
|
/** Analyze selected text files under one shared AST, finding, module, and time budget. */
|
|
4
7
|
export const analyzeJavaScriptArtifactFiles = (fileSet, input, now) => {
|
|
5
8
|
const state = emptyArtifactAnalysis();
|
|
@@ -23,6 +26,7 @@ const finalizeArtifactAnalysis = (state, input) => {
|
|
|
23
26
|
return {
|
|
24
27
|
files: state.files,
|
|
25
28
|
packages: state.packages,
|
|
29
|
+
json_modules: state.jsonModules,
|
|
26
30
|
html_scripts: state.htmlScripts.slice(0, input.limits.max_findings),
|
|
27
31
|
source_maps: state.sourceMaps,
|
|
28
32
|
visited_ast_nodes: state.visitedNodes,
|
|
@@ -46,14 +50,13 @@ const finalizeArtifactAnalysis = (state, input) => {
|
|
|
46
50
|
};
|
|
47
51
|
const analyzeArtifactFile = (file, context) => {
|
|
48
52
|
const { state, input } = context;
|
|
49
|
-
|
|
50
|
-
state.packages.push(parsePackage(file));
|
|
53
|
+
addStructuredObservations(file, state);
|
|
51
54
|
if (file.kind === "html" && file.text.included)
|
|
52
55
|
state.htmlScripts.push(...parseHtmlScripts(file.path, file.text.value, Math.max(0, input.limits.max_findings - state.findings)));
|
|
53
56
|
if (file.kind === "source-map")
|
|
54
57
|
addSourceMap(file, context);
|
|
55
58
|
if (file.kind !== "javascript" || !file.text.included) {
|
|
56
|
-
state.files.push({ file, javascript: null });
|
|
59
|
+
state.files.push({ file, javascript: null, semantic: null });
|
|
57
60
|
return;
|
|
58
61
|
}
|
|
59
62
|
const remainingNodes = input.limits.max_ast_nodes - state.visitedNodes;
|
|
@@ -63,7 +66,7 @@ const analyzeArtifactFile = (file, context) => {
|
|
|
63
66
|
remainingFindings <= 0 ||
|
|
64
67
|
remainingModules <= 0 ||
|
|
65
68
|
context.now() > context.deadline) {
|
|
66
|
-
state.files.push({ file, javascript: null });
|
|
69
|
+
state.files.push({ file, javascript: null, semantic: null });
|
|
67
70
|
state.truncatedScopes += 1;
|
|
68
71
|
return;
|
|
69
72
|
}
|
|
@@ -74,14 +77,33 @@ const analyzeArtifactFile = (file, context) => {
|
|
|
74
77
|
deadline: context.deadline,
|
|
75
78
|
now: context.now,
|
|
76
79
|
});
|
|
77
|
-
|
|
80
|
+
const staticFindings = findingCount(analysis);
|
|
81
|
+
const semanticFindingBudget = Math.max(0, input.limits.max_findings - state.findings - staticFindings);
|
|
82
|
+
const semanticLimits = {
|
|
83
|
+
...DEFAULT_JAVASCRIPT_SEMANTIC_LIMITS,
|
|
84
|
+
maxScopes: remainingNodes,
|
|
85
|
+
maxBindings: remainingNodes,
|
|
86
|
+
maxCallables: remainingNodes,
|
|
87
|
+
maxReferences: remainingNodes,
|
|
88
|
+
maxModuleLinks: semanticFindingBudget,
|
|
89
|
+
};
|
|
90
|
+
const semantics = analysis.parse_status === "complete" || analysis.parse_status === "partial"
|
|
91
|
+
? analyzeJavaScriptSemantics(file.text.value, semanticLimits)
|
|
92
|
+
: null;
|
|
93
|
+
state.files.push({
|
|
94
|
+
file,
|
|
95
|
+
javascript: analysis,
|
|
96
|
+
semantic: semantics === null ? null : { ir: semantics, limits: semanticLimits },
|
|
97
|
+
});
|
|
78
98
|
state.visitedNodes += analysis.visited_ast_nodes;
|
|
79
|
-
state.findings +=
|
|
99
|
+
state.findings += staticFindings + (semantics?.moduleLinks.length ?? 0);
|
|
80
100
|
state.modules += analysis.bundler_registrations.reduce((count, registration) => count + registration.modules.length, 0);
|
|
81
101
|
if (analysis.parse_status === "failed")
|
|
82
102
|
state.parseFailures += 1;
|
|
83
103
|
if (analysis.parse_status === "truncated")
|
|
84
104
|
state.truncatedScopes += 1;
|
|
105
|
+
if (semantics?.coverage.status === "truncated")
|
|
106
|
+
state.truncatedScopes += 1;
|
|
85
107
|
};
|
|
86
108
|
const addSourceMap = (file, context) => {
|
|
87
109
|
const sourceMap = parseSourceMap(file, {
|
|
@@ -96,6 +118,7 @@ const addSourceMap = (file, context) => {
|
|
|
96
118
|
const emptyArtifactAnalysis = () => ({
|
|
97
119
|
files: [],
|
|
98
120
|
packages: [],
|
|
121
|
+
jsonModules: [],
|
|
99
122
|
htmlScripts: [],
|
|
100
123
|
sourceMaps: [],
|
|
101
124
|
visitedNodes: 0,
|
|
@@ -105,6 +128,16 @@ const emptyArtifactAnalysis = () => ({
|
|
|
105
128
|
truncatedScopes: 0,
|
|
106
129
|
sourceMapSources: 0,
|
|
107
130
|
});
|
|
131
|
+
const addStructuredObservations = (file, state) => {
|
|
132
|
+
if (file.kind === "package-json")
|
|
133
|
+
state.packages.push(parsePackage(file));
|
|
134
|
+
if (file.kind !== "json")
|
|
135
|
+
return;
|
|
136
|
+
const json = analyzeJavaScriptJsonModule(file);
|
|
137
|
+
state.jsonModules.push(json);
|
|
138
|
+
if (json.status === "invalid")
|
|
139
|
+
state.parseFailures += 1;
|
|
140
|
+
};
|
|
108
141
|
const parsePackage = (file) => {
|
|
109
142
|
if (!file.text.included)
|
|
110
143
|
return unavailablePackage(file, "Package metadata text was unavailable.");
|
|
@@ -146,6 +179,7 @@ const unavailablePackage = (file, limitation) => ({
|
|
|
146
179
|
});
|
|
147
180
|
const parseHtmlScripts = (path, text, maximum) => {
|
|
148
181
|
const scripts = [];
|
|
182
|
+
const baseHref = htmlBaseHref(text);
|
|
149
183
|
const pattern = /<script\b[^>]*\bsrc\s*=\s*(["'])([^"']+)\1[^>]*>/giu;
|
|
150
184
|
for (const match of text.matchAll(pattern)) {
|
|
151
185
|
const script = match[2]?.slice(0, 4_096);
|
|
@@ -155,11 +189,16 @@ const parseHtmlScripts = (path, text, maximum) => {
|
|
|
155
189
|
scripts.push({
|
|
156
190
|
html_path: path,
|
|
157
191
|
script_path: script,
|
|
192
|
+
base_href: baseHref,
|
|
158
193
|
location: rangeForOffsets(text, start, start + match[0].length),
|
|
159
194
|
});
|
|
160
195
|
}
|
|
161
196
|
return scripts;
|
|
162
197
|
};
|
|
198
|
+
const htmlBaseHref = (text) => {
|
|
199
|
+
const match = /<base\b[^>]*\bhref\s*=\s*(["'])([^"']+)\1[^>]*>/iu.exec(text);
|
|
200
|
+
return match?.[2]?.slice(0, 4_096) ?? null;
|
|
201
|
+
};
|
|
163
202
|
const parseSourceMap = (file, context) => {
|
|
164
203
|
if (!file.text.included)
|
|
165
204
|
return unavailableSourceMap(file);
|
|
@@ -284,7 +323,13 @@ const findingCount = (analysis) => analysis.references.length +
|
|
|
284
323
|
analysis.storage.length +
|
|
285
324
|
analysis.role_paths.length +
|
|
286
325
|
analysis.source_map_urls.length +
|
|
287
|
-
analysis.bundler_registrations.length
|
|
326
|
+
analysis.bundler_registrations.length +
|
|
327
|
+
analysis.electron.browser_windows.length +
|
|
328
|
+
analysis.electron.context_bridge_apis.length +
|
|
329
|
+
analysis.electron.ipc.length +
|
|
330
|
+
analysis.electron.sender_validations.length +
|
|
331
|
+
analysis.electron.utility_processes.length +
|
|
332
|
+
analysis.electron.native_addon_bindings.length;
|
|
288
333
|
const rangeForOffsets = (text, start, end) => ({
|
|
289
334
|
start: pointForOffset(text, start),
|
|
290
335
|
end: pointForOffset(text, end),
|
|
@@ -197,6 +197,8 @@ const relevantKind = (path) => {
|
|
|
197
197
|
const lower = path.toLowerCase();
|
|
198
198
|
if (lower === "package.json" || lower.endsWith("/package.json"))
|
|
199
199
|
return "package-json";
|
|
200
|
+
if (lower.endsWith(".json"))
|
|
201
|
+
return "json";
|
|
200
202
|
if (/\.(?:cjs|mjs|js|jsx|ts|tsx)$/u.test(lower))
|
|
201
203
|
return "javascript";
|
|
202
204
|
if (/\.html?$/u.test(lower))
|
|
@@ -215,10 +217,12 @@ const filePriority = (kind) => {
|
|
|
215
217
|
return 1;
|
|
216
218
|
case "javascript":
|
|
217
219
|
return 2;
|
|
218
|
-
case "
|
|
220
|
+
case "json":
|
|
219
221
|
return 3;
|
|
220
|
-
case "
|
|
222
|
+
case "source-map":
|
|
221
223
|
return 4;
|
|
224
|
+
case "native-addon":
|
|
225
|
+
return 5;
|
|
222
226
|
}
|
|
223
227
|
};
|
|
224
228
|
const isFilesystemAsar = (entry, path) => entry.kind === "file" &&
|
|
@@ -3,8 +3,11 @@ import { JavaScriptArtifactGraphAccumulator } from "./JavaScriptArtifactGraphAcc
|
|
|
3
3
|
import { javaScriptAnalysisLimits, } from "./JavaScriptArtifactGraphContext.js";
|
|
4
4
|
import { addJavaScriptHtmlRoles, addJavaScriptSourceMapOriginals, } from "./JavaScriptArtifactGraphDocuments.js";
|
|
5
5
|
import { addJavaScriptStaticFindings } from "./JavaScriptArtifactGraphFindings.js";
|
|
6
|
+
import { addJavaScriptModuleRelationships, addJavaScriptSourceModules, } from "./JavaScriptModuleRelationships.js";
|
|
6
7
|
import { completeReconstructionCoverage, partialReconstructionCoverage, } from "./JavaScriptArtifactGraphEvidence.js";
|
|
7
8
|
import { addJavaScriptArtifactContainers, addJavaScriptArtifactFiles, addJavaScriptBundlerNodes, addJavaScriptPackageNodes, createJavaScriptArtifactRootNode, } from "./JavaScriptArtifactGraphStructure.js";
|
|
9
|
+
import { addElectronBoundaries } from "./ElectronBoundaryGraph.js";
|
|
10
|
+
import { classifyElectronIpcPairings, collectElectronIpcRecords, } from "./ElectronBoundaryAnalysis.js";
|
|
8
11
|
/** Project bounded artifact and AST facts into JavaScript Application Graph v1. */
|
|
9
12
|
export const buildJavaScriptArtifactGraph = (snapshot, fileSet, analysis, input) => {
|
|
10
13
|
const accumulator = new JavaScriptArtifactGraphAccumulator();
|
|
@@ -19,14 +22,19 @@ export const buildJavaScriptArtifactGraph = (snapshot, fileSet, analysis, input)
|
|
|
19
22
|
filesByPath: new Map(fileSet.files.map((file) => [file.path, file])),
|
|
20
23
|
fileNodes: new Map(),
|
|
21
24
|
assetNodes: new Map(),
|
|
25
|
+
sourceModuleNodes: new Map(),
|
|
26
|
+
chunkNodes: new Map(),
|
|
22
27
|
moduleNodes: new Map(),
|
|
23
28
|
containerNodes: new Map([[snapshot.manifest.root_sha256, root]]),
|
|
24
29
|
};
|
|
25
30
|
addJavaScriptArtifactContainers(context);
|
|
26
31
|
addJavaScriptArtifactFiles(context);
|
|
27
32
|
const packageRoots = addJavaScriptPackageNodes(context);
|
|
33
|
+
addJavaScriptSourceModules(context);
|
|
28
34
|
addJavaScriptBundlerNodes(context);
|
|
35
|
+
addJavaScriptModuleRelationships(context);
|
|
29
36
|
addJavaScriptStaticFindings(context);
|
|
37
|
+
addElectronBoundaries(context);
|
|
30
38
|
addJavaScriptHtmlRoles(context);
|
|
31
39
|
addJavaScriptSourceMapOriginals(context);
|
|
32
40
|
const coverage = graphCoverage(context);
|
|
@@ -47,34 +55,91 @@ const graphCoverage = (context) => {
|
|
|
47
55
|
context.accumulator.omittedObservations();
|
|
48
56
|
const sourceMapPolicyGap = context.analysis.source_maps.some(({ status }) => status === "not-approved");
|
|
49
57
|
const malformedStructuredData = context.analysis.packages.some(({ status }) => status !== "included") ||
|
|
58
|
+
context.analysis.json_modules.some(({ status }) => status !== "included") ||
|
|
50
59
|
context.analysis.source_maps.some(({ status }) => status === "invalid");
|
|
60
|
+
const partialJavaScript = context.analysis.files.some(({ javascript }) => javascript !== null && javascript.parse_status === "partial");
|
|
51
61
|
const unknownGap = context.analysis.parse_failures > 0 ||
|
|
52
62
|
context.fileSet.invalid_utf8_files > 0 ||
|
|
53
63
|
sourceMapPolicyGap ||
|
|
54
|
-
malformedStructuredData
|
|
64
|
+
malformedStructuredData ||
|
|
65
|
+
partialJavaScript;
|
|
55
66
|
if (context.analysis.truncated_scopes > 0)
|
|
56
|
-
return partialReconstructionCoverage(reconstructionLimits(context.input),
|
|
67
|
+
return partialReconstructionCoverage(reconstructionLimits(context.input), truncationOmittedCount(context), true);
|
|
57
68
|
if (exactLimitOmissions > 0)
|
|
58
69
|
return partialReconstructionCoverage(reconstructionLimits(context.input), exactLimitOmissions, true);
|
|
59
70
|
if (unknownGap)
|
|
60
71
|
return partialReconstructionCoverage(reconstructionLimits(context.input), null, false);
|
|
61
72
|
return completeReconstructionCoverage(reconstructionLimits(context.input));
|
|
62
73
|
};
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
const truncationOmittedCount = (context) => {
|
|
75
|
+
const staticTruncations = context.analysis.files.filter(({ javascript }) => javascript?.parse_status === "truncated");
|
|
76
|
+
if (staticTruncations.length > 0)
|
|
77
|
+
return null;
|
|
78
|
+
const semanticTruncations = context.analysis.files.flatMap(({ semantic }) => semantic?.ir.coverage.status === "truncated" ? [semantic.ir.coverage] : []);
|
|
79
|
+
const sourceMapTruncations = context.analysis.source_maps.filter(({ status }) => status === "truncated");
|
|
80
|
+
if (sourceMapTruncations.length > 0)
|
|
81
|
+
return null;
|
|
82
|
+
if (semanticTruncations.length !== context.analysis.truncated_scopes)
|
|
83
|
+
return null;
|
|
84
|
+
const omissions = semanticTruncations.map(({ omittedCount }) => omittedCount);
|
|
85
|
+
return omissions.some((omitted) => omitted === null)
|
|
86
|
+
? null
|
|
87
|
+
: omissions.reduce((total, omitted) => total + (omitted ?? 0), 0);
|
|
88
|
+
};
|
|
89
|
+
const graphLimitations = (context, coverage) => {
|
|
90
|
+
const ipc = collectElectronIpcRecords(context.analysis);
|
|
91
|
+
const pairings = classifyElectronIpcPairings(ipc);
|
|
92
|
+
const electronFindings = context.analysis.files.reduce((count, { javascript }) => count +
|
|
93
|
+
(javascript === null
|
|
94
|
+
? 0
|
|
95
|
+
: javascript.electron.browser_windows.length +
|
|
96
|
+
javascript.electron.context_bridge_apis.length +
|
|
97
|
+
javascript.electron.ipc.length +
|
|
98
|
+
javascript.electron.sender_validations.length +
|
|
99
|
+
javascript.electron.utility_processes.length +
|
|
100
|
+
javascript.electron.native_addon_bindings.length), 0);
|
|
101
|
+
return [
|
|
102
|
+
...context.analysis.limitations,
|
|
103
|
+
"CommonJS and ESM binding relationships were recovered from inert syntax and resolved only within the inventoried artifact container.",
|
|
104
|
+
"Webpack/Rspack factories were recovered from AST literals; REA did not invoke push handlers or bundle bootstrap code.",
|
|
105
|
+
"Static imports, entrypoints, workers, endpoints, and storage relationships do not prove runtime execution.",
|
|
106
|
+
...(electronFindings === 0
|
|
107
|
+
? []
|
|
108
|
+
: [
|
|
109
|
+
"Electron relationships are derived from inert syntax; runtime registration, reachability, defaults, and enforcement remain unproven.",
|
|
110
|
+
]),
|
|
111
|
+
...(ipc.some(({ finding }) => finding.channel === null)
|
|
112
|
+
? [
|
|
113
|
+
"Dynamic IPC channel expressions remain unresolved and are never paired by textual similarity.",
|
|
114
|
+
]
|
|
115
|
+
: []),
|
|
116
|
+
...(pairings.some(({ status }) => status === "ambiguous")
|
|
117
|
+
? [
|
|
118
|
+
"Some literal IPC channels have multiple compatible main handlers; ambiguous calls are not paired to any handler.",
|
|
119
|
+
]
|
|
120
|
+
: []),
|
|
121
|
+
...(context.analysis.files.some(({ javascript }) => (javascript?.electron.sender_validations.length ?? 0) > 0)
|
|
122
|
+
? [
|
|
123
|
+
"Sender, frame, URL, and origin checks are observations only; REA does not claim that they enforce a complete authorization policy.",
|
|
124
|
+
]
|
|
125
|
+
: []),
|
|
126
|
+
...(context.analysis.files.some(({ javascript }) => (javascript?.electron.native_addon_bindings.length ?? 0) > 0)
|
|
127
|
+
? [
|
|
128
|
+
"Native member names are requested by JavaScript syntax and are not verified binary exports in this workflow.",
|
|
129
|
+
]
|
|
130
|
+
: []),
|
|
131
|
+
...(context.accumulator.omittedObservations() === 0
|
|
132
|
+
? []
|
|
133
|
+
: [
|
|
134
|
+
"Repeated content identities exceeded the per-node observation bound; containment edges still preserve inventoried paths.",
|
|
135
|
+
]),
|
|
136
|
+
...(coverage === "complete"
|
|
137
|
+
? []
|
|
138
|
+
: [
|
|
139
|
+
"Graph coverage is incomplete; unavailable facts remain explicit and must not be read as absence.",
|
|
140
|
+
]),
|
|
141
|
+
];
|
|
142
|
+
};
|
|
78
143
|
const reconstructionLimits = (input) => [
|
|
79
144
|
{
|
|
80
145
|
name: "max-entries",
|