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.
Files changed (333) hide show
  1. package/README.md +112 -59
  2. package/bridge/ghidra/ReaGhidraBridge.java +96 -11
  3. package/dist/application/ArtifactExtraction.js +1 -1
  4. package/dist/application/ArtifactInventory/classify.js +42 -0
  5. package/dist/application/ArtifactInventory/hash.js +43 -0
  6. package/dist/application/ArtifactInventory/reader.js +41 -0
  7. package/dist/application/ArtifactInventory/scanCanonical.js +155 -0
  8. package/dist/application/ArtifactInventory/scanReader.js +124 -0
  9. package/dist/application/ArtifactInventory/types.js +10 -0
  10. package/dist/application/ArtifactInventory.js +9 -351
  11. package/dist/application/AuthorizedArtifactInventory.js +2 -2
  12. package/dist/application/BinarySession.js +47 -270
  13. package/dist/application/BinarySessionExecution.js +28 -0
  14. package/dist/application/BinarySessionOpen.js +39 -0
  15. package/dist/application/BinarySessionRecords.js +149 -0
  16. package/dist/application/BinarySessionStatus.js +75 -0
  17. package/dist/application/CapabilityInventory.js +42 -2
  18. package/dist/application/ClientRegistrationStatus.js +1 -1
  19. package/dist/application/CrossVersionInventory.js +8 -2
  20. package/dist/application/CrossVersionInvestigation.js +11 -29
  21. package/dist/application/CrossVersionInvestigationCollections.js +23 -0
  22. package/dist/application/DirectAnalysis.js +47 -44
  23. package/dist/application/Doctor.js +165 -197
  24. package/dist/application/DoctorDiagnostics.js +180 -0
  25. package/dist/application/ElectronBoundaryAnalysis.js +112 -0
  26. package/dist/application/ElectronBoundaryGraph.js +9 -0
  27. package/dist/application/ElectronBoundaryGraphContext.js +62 -0
  28. package/dist/application/ElectronBoundaryGraphIpc.js +242 -0
  29. package/dist/application/ElectronBoundaryGraphNative.js +86 -0
  30. package/dist/application/ElectronBoundaryGraphWindows.js +223 -0
  31. package/dist/application/EnhancedToolPagination.js +22 -0
  32. package/dist/application/EnhancedToolTypes.js +4 -0
  33. package/dist/application/EnhancedTools.js +58 -50
  34. package/dist/application/InstrumentedJavaScriptReplayHost.js +36 -0
  35. package/dist/application/InvestigationProviders.js +30 -0
  36. package/dist/application/InvestigationWorkspaceStore.js +24 -10
  37. package/dist/application/JavaScriptApplicationEvidence.js +26 -0
  38. package/dist/application/JavaScriptApplicationEvidenceGraph.js +89 -0
  39. package/dist/application/JavaScriptApplicationService.js +74 -0
  40. package/dist/application/JavaScriptApplicationWorkflowEvidence.js +29 -0
  41. package/dist/application/JavaScriptApplicationWorkflowService.js +90 -0
  42. package/dist/application/JavaScriptArtifactAnalysis.js +52 -7
  43. package/dist/application/JavaScriptArtifactFiles.js +6 -2
  44. package/dist/application/JavaScriptArtifactGraphBuilder.js +82 -17
  45. package/dist/application/JavaScriptArtifactGraphBundlers.js +225 -0
  46. package/dist/application/JavaScriptArtifactGraphContext.js +37 -36
  47. package/dist/application/JavaScriptArtifactGraphDocuments.js +27 -4
  48. package/dist/application/JavaScriptArtifactGraphEvidence.js +24 -14
  49. package/dist/application/JavaScriptArtifactGraphFindings.js +54 -8
  50. package/dist/application/JavaScriptArtifactGraphStructure.js +29 -101
  51. package/dist/application/JavaScriptArtifactPathResolution.js +269 -0
  52. package/dist/application/JavaScriptArtifactReconstruction.js +4 -1
  53. package/dist/application/JavaScriptArtifactReconstructionInput.js +2 -83
  54. package/dist/application/JavaScriptJsonModules.js +39 -0
  55. package/dist/application/JavaScriptModuleRelationships.js +262 -0
  56. package/dist/application/JavaScriptReplayPermission.js +16 -0
  57. package/dist/application/JavaScriptReplayPlanning.js +201 -0
  58. package/dist/application/JavaScriptReplayService.js +292 -0
  59. package/dist/application/JavaScriptRuntimeReconciliationEvidence.js +25 -0
  60. package/dist/application/JavaScriptRuntimeReconciliationService.js +27 -0
  61. package/dist/application/LinuxHopper.js +10 -0
  62. package/dist/application/MacHopper.js +22 -11
  63. package/dist/application/ManagedApplicationGraphService.js +55 -0
  64. package/dist/application/ManagedMemberComparisonService.js +122 -0
  65. package/dist/application/ManagedNativeVerificationService.js +39 -0
  66. package/dist/application/ManagedReconstructionService.js +58 -0
  67. package/dist/application/ManagedRuntimeCorrelationService.js +103 -0
  68. package/dist/application/NodeRuntimeCharacterizationService.js +196 -0
  69. package/dist/application/PermissionAuthority.js +106 -63
  70. package/dist/application/ProcessCaptureCapability.js +1 -1
  71. package/dist/application/ProcessCapturePermission.js +13 -0
  72. package/dist/application/ProcessCli.js +2 -12
  73. package/dist/application/ProcessHarness.js +1 -1
  74. package/dist/application/ProcessSampling.js +15 -11
  75. package/dist/application/ProjectPermissionStore.js +49 -9
  76. package/dist/application/RealHopperAssertions.js +76 -0
  77. package/dist/application/ReconstructionCoverageService.js +69 -0
  78. package/dist/application/ReconstructionCoverageWorkspaceStore.js +31 -0
  79. package/dist/application/RuntimeExecutableDiagnostics.js +172 -0
  80. package/dist/application/Setup.js +147 -259
  81. package/dist/application/SetupClientConfiguration.js +220 -0
  82. package/dist/application/SetupClients.js +24 -2
  83. package/dist/application/SetupPlan.js +123 -12
  84. package/dist/application/SetupSkill.js +26 -12
  85. package/dist/application/SupportedClients.js +1 -0
  86. package/dist/application/Uninstall.js +6 -3
  87. package/dist/application/WindowsCapabilities.js +86 -0
  88. package/dist/application/runtime.js +2 -0
  89. package/dist/artifacts/AsarArtifactReader.js +11 -0
  90. package/dist/browser/BrowserProcessStartup.js +88 -0
  91. package/dist/browser/CdpCaptureDocuments.js +12 -8
  92. package/dist/browser/CdpCaptureEventBodyShapes.js +75 -0
  93. package/dist/browser/CdpCaptureEventHandlers.js +336 -0
  94. package/dist/browser/CdpCaptureEventHelpers.js +71 -0
  95. package/dist/browser/CdpCaptureEventState.js +1 -0
  96. package/dist/browser/CdpCaptureEventTypes.js +1 -0
  97. package/dist/browser/CdpCaptureEvents.js +46 -464
  98. package/dist/browser/CdpElectronInspection.js +106 -162
  99. package/dist/browser/CdpElectronProvider.js +5 -1
  100. package/dist/browser/CdpElectronScriptEvents.js +69 -0
  101. package/dist/browser/CdpElectronScripts.js +94 -0
  102. package/dist/browser/CdpElectronWorkers.js +56 -0
  103. package/dist/browser/CdpObservationSession.js +51 -8
  104. package/dist/browser/CdpPageCapture.js +12 -129
  105. package/dist/browser/CdpPageCaptureScripts.js +97 -0
  106. package/dist/browser/CdpPageCaptureWorkers.js +46 -0
  107. package/dist/browser/CdpWebMcpDiscovery.js +38 -14
  108. package/dist/browser/PngVisualDiff.js +9 -2
  109. package/dist/catalogIdentity.js +8 -1
  110. package/dist/cli/artifactCommands.js +82 -0
  111. package/dist/cli/coreAnalysisCommands.js +232 -0
  112. package/dist/cli/managedCommands.js +397 -0
  113. package/dist/cli/managedProjectGraphCommand.js +24 -0
  114. package/dist/cli/options.js +9 -0
  115. package/dist/cli/setupCommands.js +108 -0
  116. package/dist/cli/types.js +1 -0
  117. package/dist/cli/utilityCommands.js +122 -0
  118. package/dist/cli.js +13 -383
  119. package/dist/cliApplicationCommands.js +176 -0
  120. package/dist/cliBrowserAdvancedCommands.js +73 -16
  121. package/dist/cliBrowserCommands.js +39 -115
  122. package/dist/cliCommandNames.js +17 -0
  123. package/dist/cliElectronCommands.js +100 -27
  124. package/dist/cliEvidenceCommands.js +13 -2
  125. package/dist/cliInvestigationCommands.js +53 -10
  126. package/dist/cliJsonInput.js +54 -0
  127. package/dist/cliObservationOptions.js +137 -0
  128. package/dist/cliPolicyCommands.js +80 -46
  129. package/dist/cliSetup.js +289 -0
  130. package/dist/config/environment.js +107 -0
  131. package/dist/config/parseConfig.js +228 -0
  132. package/dist/config/parsers.js +68 -0
  133. package/dist/config/permissions.js +30 -0
  134. package/dist/config/types.js +1 -0
  135. package/dist/config.js +1 -292
  136. package/dist/contracts/applicationToolContracts.js +225 -0
  137. package/dist/contracts/artifactToolContracts.js +5 -9
  138. package/dist/contracts/browserToolContracts.js +14 -62
  139. package/dist/contracts/electronToolContracts.js +45 -19
  140. package/dist/contracts/errorSchemas.js +1 -0
  141. package/dist/contracts/investigationExamples.js +0 -6
  142. package/dist/contracts/javascriptApplicationWorkflowExamples.js +46 -0
  143. package/dist/contracts/javascriptRuntimeReconciliationExample.js +208 -0
  144. package/dist/contracts/managedToolContracts.js +153 -0
  145. package/dist/contracts/managedWorkflowExamples.js +346 -0
  146. package/dist/contracts/managedWorkflowToolContracts.js +203 -0
  147. package/dist/contracts/nativeToolContracts.js +2 -6
  148. package/dist/contracts/promptContracts.js +18 -2
  149. package/dist/contracts/providerSelection.js +2 -0
  150. package/dist/contracts/toolContractExamples.js +10 -25
  151. package/dist/contracts/toolContracts.js +49 -47
  152. package/dist/contracts/toolEffects.js +174 -0
  153. package/dist/contracts/toolOutputSchemaGroups.js +232 -0
  154. package/dist/contracts/toolOutputSchemaPrimitives.js +327 -0
  155. package/dist/contracts/toolOutputSchemas.js +2 -535
  156. package/dist/doctorRuntime.js +42 -1
  157. package/dist/domain/analysisErrorPresentation.js +234 -0
  158. package/dist/domain/analysisErrorProjection.js +284 -0
  159. package/dist/domain/artifactComparison.js +37 -19
  160. package/dist/domain/binaryTarget.js +87 -37
  161. package/dist/domain/browserObservation.js +1 -282
  162. package/dist/domain/browserObservationSchemas.js +286 -0
  163. package/dist/domain/bundleComparison.js +4 -4
  164. package/dist/domain/electronObservation.js +13 -0
  165. package/dist/domain/electronStaticAnalysis.js +9 -0
  166. package/dist/domain/electronStaticAnalysisBrowser.js +206 -0
  167. package/dist/domain/electronStaticAnalysisIpc.js +171 -0
  168. package/dist/domain/electronStaticAnalysisNative.js +164 -0
  169. package/dist/domain/electronStaticAnalysisTypes.js +1 -0
  170. package/dist/domain/electronStaticAnalysisValues.js +103 -0
  171. package/dist/domain/errors.js +32 -448
  172. package/dist/domain/functionComparison.js +4 -165
  173. package/dist/domain/functionComparisonDimensions.js +164 -0
  174. package/dist/domain/functionComparisonSchemas.js +3 -8
  175. package/dist/domain/inputIssueProjection.js +52 -0
  176. package/dist/domain/javascriptApplicationAnalysis.js +155 -0
  177. package/dist/domain/javascriptApplicationChangeGraph.js +231 -0
  178. package/dist/domain/javascriptApplicationEvidenceSchemas.js +18 -0
  179. package/dist/domain/javascriptApplicationGraph.js +2 -1
  180. package/dist/domain/javascriptApplicationGraphSchemas.js +7 -0
  181. package/dist/domain/javascriptApplicationVersionComparison.js +116 -0
  182. package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +139 -0
  183. package/dist/domain/javascriptApplicationVersionItems.js +233 -0
  184. package/dist/domain/javascriptApplicationVersionKeys.js +170 -0
  185. package/dist/domain/javascriptExportInstrumentation.js +97 -0
  186. package/dist/domain/javascriptFeatureSeed.js +140 -0
  187. package/dist/domain/javascriptFeatureTrace.js +232 -0
  188. package/dist/domain/javascriptFeatureTraceSchemas.js +136 -0
  189. package/dist/domain/javascriptFeatureTraversal.js +100 -0
  190. package/dist/domain/javascriptNativeHandoff.js +85 -0
  191. package/dist/domain/javascriptReplay.js +361 -0
  192. package/dist/domain/javascriptRuntimeLoadState.js +106 -0
  193. package/dist/domain/javascriptRuntimeReconciliation.js +42 -0
  194. package/dist/domain/javascriptRuntimeReconciliationGraph.js +169 -0
  195. package/dist/domain/javascriptRuntimeReconciliationMatching.js +247 -0
  196. package/dist/domain/javascriptRuntimeReconciliationParsing.js +160 -0
  197. package/dist/domain/javascriptRuntimeReconciliationResult.js +119 -0
  198. package/dist/domain/javascriptRuntimeReconciliationRuntime.js +316 -0
  199. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +245 -0
  200. package/dist/domain/javascriptRuntimeStaticCandidates.js +193 -0
  201. package/dist/domain/javascriptSemanticAnalysis.js +386 -0
  202. package/dist/domain/javascriptSemanticIr.js +30 -0
  203. package/dist/domain/javascriptSemanticProjection.js +366 -0
  204. package/dist/domain/javascriptSemanticState.js +40 -0
  205. package/dist/domain/javascriptSemanticTraversal.js +22 -0
  206. package/dist/domain/javascriptSemanticValues.js +352 -0
  207. package/dist/domain/javascriptStaticAnalysis.js +26 -254
  208. package/dist/domain/javascriptStaticAnalysisBundler.js +209 -0
  209. package/dist/domain/javascriptStaticAnalysisCalls.js +180 -0
  210. package/dist/domain/javascriptStaticAnalysisFindings.js +39 -0
  211. package/dist/domain/javascriptStaticAnalysisHelpers.js +81 -2
  212. package/dist/domain/javascriptStaticAnalysisState.js +6 -0
  213. package/dist/domain/knownPageCoverage.js +21 -0
  214. package/dist/domain/managedApplicationGraph.js +206 -0
  215. package/dist/domain/managedApplicationGraphCoverage.js +170 -0
  216. package/dist/domain/managedApplicationGraphNodeCoverage.js +6 -0
  217. package/dist/domain/managedApplicationGraphNodes.js +336 -0
  218. package/dist/domain/managedArtifact.js +452 -0
  219. package/dist/domain/managedMemberComparison.js +211 -0
  220. package/dist/domain/managedMemberComparisonCoverage.js +72 -0
  221. package/dist/domain/managedMemberComparisonMatch.js +356 -0
  222. package/dist/domain/managedNativeVerification.js +46 -0
  223. package/dist/domain/managedNativeVerificationMatch.js +272 -0
  224. package/dist/domain/managedNativeVerificationSchemas.js +141 -0
  225. package/dist/domain/managedReconstruction.js +196 -0
  226. package/dist/domain/managedRuntimeCorrelation.js +184 -0
  227. package/dist/domain/nodeRuntimeCharacterization.js +66 -0
  228. package/dist/domain/permissionPolicy.js +2 -0
  229. package/dist/domain/reconstructionCoverage.js +387 -0
  230. package/dist/domain/reconstructionCoverageEvaluation.js +212 -0
  231. package/dist/domain/reconstructionVerificationSchemas.js +9 -3
  232. package/dist/domain/runtimeCharacterization.js +85 -0
  233. package/dist/domain/webBundleAnalyzer.js +3 -409
  234. package/dist/domain/webBundleAnalyzerAst.js +77 -0
  235. package/dist/domain/webBundleAnalyzerInspection.js +307 -0
  236. package/dist/domain/webBundleAnalyzerResult.js +120 -0
  237. package/dist/dotnet/ManagedArtifactInspector.js +339 -0
  238. package/dist/dotnet/ManagedMemberInspector.js +153 -0
  239. package/dist/dotnet/ManagedMemberInspectorCore.js +297 -0
  240. package/dist/dotnet/ManagedMemberInstructionDecoder.js +427 -0
  241. package/dist/dotnet/ManagedMemberRows.js +120 -0
  242. package/dist/dotnet/ManagedMetadataHeaps.js +131 -0
  243. package/dist/dotnet/ManagedMetadataInventory.js +104 -0
  244. package/dist/dotnet/ManagedMetadataInventoryRows.js +292 -0
  245. package/dist/dotnet/ManagedMetadataLayout.js +259 -0
  246. package/dist/dotnet/ManagedMetadataRowSizes.js +54 -0
  247. package/dist/dotnet/ManagedMethodBodyReader.js +143 -0
  248. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +311 -0
  249. package/dist/dotnet/ManagedNativeBoundaryInspector.js +143 -0
  250. package/dist/dotnet/ManagedPeReader.js +188 -0
  251. package/dist/dotnet/ManagedReaderFailure.js +10 -0
  252. package/dist/dotnet/ManagedStaticProvider.js +203 -0
  253. package/dist/generatedPackageMetadata.js +2 -2
  254. package/dist/ghidra/GhidraClient.js +76 -91
  255. package/dist/ghidra/GhidraClientStartup.js +29 -0
  256. package/dist/ghidra/GhidraClientWire.js +34 -0
  257. package/dist/ghidra/GhidraDefaults.js +1 -1
  258. package/dist/ghidra/GhidraDiagnostics.js +6 -1
  259. package/dist/ghidra/GhidraInstallation.js +20 -15
  260. package/dist/ghidra/GhidraLauncher.js +93 -29
  261. package/dist/ghidra/GhidraProvider.js +67 -161
  262. package/dist/ghidra/GhidraProviderCapabilities.js +173 -0
  263. package/dist/ghidra/GhidraSessionValues.js +2 -0
  264. package/dist/ghidra/GhidraSocketConnection.js +44 -7
  265. package/dist/ghidra/GhidraTargetSnapshot.js +30 -0
  266. package/dist/ghidra/GhidraTransport.js +71 -0
  267. package/dist/identity.js +3 -2
  268. package/dist/main/messages.js +5 -0
  269. package/dist/main/reload.js +49 -0
  270. package/dist/main/shutdown.js +25 -0
  271. package/dist/main/startup.js +14 -0
  272. package/dist/main/state.js +26 -0
  273. package/dist/main/transport.js +61 -0
  274. package/dist/main/types.js +1 -0
  275. package/dist/main.js +35 -132
  276. package/dist/process/PrivateRuntimeRoot.js +3 -2
  277. package/dist/process/ProcessOwnership.js +35 -0
  278. package/dist/process/ProviderProcess.js +2 -0
  279. package/dist/replay/JavaScriptReplayWorker.js +300 -0
  280. package/dist/replay/LinuxJavaScriptReplayRunner.js +217 -0
  281. package/dist/replay/LinuxJavaScriptReplaySandbox.js +140 -0
  282. package/dist/replay/LinuxRuntimeClosure.js +46 -0
  283. package/dist/replay/LinuxSeccompPolicy.js +40 -0
  284. package/dist/replay/ReplayOutcome.js +95 -0
  285. package/dist/replay/ReplayProcessLifecycle.js +71 -0
  286. package/dist/replay/ReplayWorkerProtocol.js +55 -0
  287. package/dist/replay/SystemJavaScriptReplayHost.js +182 -0
  288. package/dist/server/ProcessCaptureElicitation.js +157 -0
  289. package/dist/server/createServer.js +158 -41
  290. package/dist/server/registerApplicationTools/characterization.js +57 -0
  291. package/dist/server/registerApplicationTools/compareVersions.js +34 -0
  292. package/dist/server/registerApplicationTools/controlledReplay.js +38 -0
  293. package/dist/server/registerApplicationTools/coverage.js +84 -0
  294. package/dist/server/registerApplicationTools/helpers.js +42 -0
  295. package/dist/server/registerApplicationTools/traceFeature.js +26 -0
  296. package/dist/server/registerApplicationTools/types.js +1 -0
  297. package/dist/server/registerApplicationTools.js +13 -0
  298. package/dist/server/registerArtifactComparisonTool.js +16 -9
  299. package/dist/server/registerBrowserTools.js +61 -60
  300. package/dist/server/registerBundleComparisonTool.js +17 -20
  301. package/dist/server/registerElectronTools.js +39 -12
  302. package/dist/server/registerEnhancedTools.js +52 -15
  303. package/dist/server/registerEvidenceResources.js +54 -0
  304. package/dist/server/registerEvidenceTools.js +5 -1
  305. package/dist/server/registerFunctionComparisonTool.js +14 -7
  306. package/dist/server/registerInvestigationTools/helpers.js +74 -0
  307. package/dist/server/registerInvestigationTools/types.js +1 -0
  308. package/dist/server/registerInvestigationTools.js +103 -132
  309. package/dist/server/registerManagedTools.js +6 -0
  310. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +65 -0
  311. package/dist/server/registerManagedWorkflowTools/contract.js +8 -0
  312. package/dist/server/registerManagedWorkflowTools/evidence.js +43 -0
  313. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +39 -0
  314. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +39 -0
  315. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +52 -0
  316. package/dist/server/registerManagedWorkflowTools/types.js +1 -0
  317. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +75 -0
  318. package/dist/server/registerManagedWorkflowTools.js +13 -0
  319. package/dist/server/registerOfficialTools.js +81 -67
  320. package/dist/server/registerProcessComparisonTool.js +25 -47
  321. package/dist/server/registerSessionRecordTools.js +137 -0
  322. package/dist/server/registerSessionStatusTool.js +9 -8
  323. package/dist/server/registerSessionTools.js +77 -216
  324. package/dist/server/sessionAvailabilityPolicy.js +10 -0
  325. package/dist/server/sessionEvidence.js +14 -19
  326. package/dist/server/toolInputValidation.js +77 -0
  327. package/dist/server/toolRegistrationOptions.js +177 -2
  328. package/dist/server/toolResult.js +30 -17
  329. package/package.json +21 -14
  330. package/scripts/rea.mjs +1 -1
  331. package/skills/{rea-analysis → reverse-engineer-anything}/SKILL.md +75 -6
  332. package/scripts/prepare-node-pty.mjs +0 -35
  333. 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
- if (file.kind === "package-json")
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
- state.files.push({ file, javascript: analysis });
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 += findingCount(analysis);
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 "source-map":
220
+ case "json":
219
221
  return 3;
220
- case "native-addon":
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), null, true);
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 graphLimitations = (context, coverage) => [
64
- ...context.analysis.limitations,
65
- "Webpack/Rspack factories were recovered from AST literals; REA did not invoke push handlers or bundle bootstrap code.",
66
- "Static imports, entrypoints, workers, endpoints, and storage relationships do not prove runtime execution.",
67
- ...(context.accumulator.omittedObservations() === 0
68
- ? []
69
- : [
70
- "Repeated content identities exceeded the per-node observation bound; containment edges still preserve inventoried paths.",
71
- ]),
72
- ...(coverage === "complete"
73
- ? []
74
- : [
75
- "Graph coverage is incomplete; unavailable facts remain explicit and must not be read as absence.",
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",