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,223 @@
1
+ import { artifactLocalIdentity, createElectronRoleNode, javascriptAnalysisCoverage, linkElectronRoleToAsset, } from "./JavaScriptArtifactGraphContext.js";
2
+ import { astObservationEvidence } from "./JavaScriptArtifactGraphEvidence.js";
3
+ import { addElectronAstEdge, addElectronInferenceEdge, electronFindingSourceNode, electronRangeKey, } from "./ElectronBoundaryGraphContext.js";
4
+ import { resolveArtifactPathByContext } from "./JavaScriptArtifactPathResolution.js";
5
+ /** Project BrowserWindow, contextBridge, preload, and utility-process facts. */
6
+ export const addElectronWindowBoundaries = (context) => {
7
+ for (const analyzed of context.analysis.files) {
8
+ const { file, javascript } = analyzed;
9
+ if (javascript === null)
10
+ continue;
11
+ const coverage = javascriptAnalysisCoverage(javascript, context.input);
12
+ for (const value of javascript.electron.browser_windows) {
13
+ const source = electronFindingSourceNode(context, file, value.module_key);
14
+ if (source !== undefined)
15
+ addBrowserWindow({ context, file, source, value, coverage });
16
+ }
17
+ for (const value of javascript.electron.context_bridge_apis) {
18
+ const source = electronFindingSourceNode(context, file, value.module_key);
19
+ if (source !== undefined)
20
+ addContextBridge({ context, file, source, value, coverage });
21
+ }
22
+ for (const value of javascript.electron.utility_processes) {
23
+ const source = electronFindingSourceNode(context, file, value.module_key);
24
+ if (source !== undefined)
25
+ addUtilityProcess({ context, file, source, value, coverage });
26
+ }
27
+ }
28
+ };
29
+ const addBrowserWindow = (input) => {
30
+ const { context, file, value, coverage } = input;
31
+ const window = context.accumulator.addNode({
32
+ kind: "browser-window",
33
+ identity: artifactLocalIdentity(file.sha256, "electron-browser-window", electronRangeKey(value.location)),
34
+ observations: [
35
+ {
36
+ label: `BrowserWindow@${electronRangeKey(value.location)}`,
37
+ properties: {
38
+ source_path: file.path,
39
+ options_status: value.options_status,
40
+ web_preferences_status: value.web_preferences_status,
41
+ web_preferences: value.web_preferences,
42
+ omitted_web_preferences: value.omitted_web_preferences,
43
+ preload_path: value.preload_path,
44
+ preload_resolution_context: value.preload_resolution_context,
45
+ absence_means_default: false,
46
+ },
47
+ evidence: astObservationEvidence({
48
+ sha256: file.sha256,
49
+ path: file.path,
50
+ range: value.location,
51
+ operation: "observe-browser-window-construction",
52
+ coverage,
53
+ limitations: [
54
+ "Only explicitly present webPreferences are reported; omitted properties are not interpreted as Electron defaults.",
55
+ ],
56
+ }),
57
+ },
58
+ ],
59
+ });
60
+ addElectronAstEdge(context, {
61
+ source: input.source,
62
+ target: window,
63
+ file,
64
+ range: value.location,
65
+ coverage,
66
+ relation: "contains",
67
+ operation: "locate-browser-window-construction",
68
+ properties: { source_path: file.path },
69
+ });
70
+ addWindowPreload(input, window);
71
+ };
72
+ const addWindowPreload = (input, window) => {
73
+ const declared = input.value.preload_path;
74
+ if (declared === null)
75
+ return;
76
+ const resolution = resolveArtifactPathByContext({
77
+ declaredPath: declared,
78
+ sourcePath: input.file.path,
79
+ context: input.value.preload_resolution_context ?? "module-specifier",
80
+ files: input.context.filesByPath,
81
+ });
82
+ const role = createElectronRoleNode(input.context, {
83
+ kind: "electron-preload",
84
+ anchor: input.file,
85
+ resolution,
86
+ mechanism: "BrowserWindow:webPreferences.preload",
87
+ range: input.value.location,
88
+ coverage: input.coverage,
89
+ });
90
+ addElectronInferenceEdge(input.context, {
91
+ source: window,
92
+ target: role,
93
+ file: input.file,
94
+ range: input.value.location,
95
+ coverage: input.coverage,
96
+ relation: "loads",
97
+ operation: "associate-browser-window-preload",
98
+ properties: {
99
+ declared_path: declared,
100
+ resolution_context: resolution.resolution_context,
101
+ resolved_path: resolution.resolved_path,
102
+ resolution_status: resolution.resolution_status,
103
+ limitations: resolution.limitations,
104
+ },
105
+ });
106
+ linkElectronRoleToAsset(input.context, {
107
+ role,
108
+ anchor: input.file,
109
+ resolution,
110
+ range: input.value.location,
111
+ coverage: input.coverage,
112
+ });
113
+ };
114
+ const addContextBridge = (input) => {
115
+ const { context, file, value, coverage } = input;
116
+ const bridge = context.accumulator.addNode({
117
+ kind: "context-bridge-api",
118
+ identity: artifactLocalIdentity(file.sha256, "electron-context-bridge", `${value.world}:${value.api_key ?? value.api_key_expression ?? "[missing]"}:${electronRangeKey(value.location)}`),
119
+ observations: [
120
+ {
121
+ label: value.api_key,
122
+ properties: {
123
+ world: value.world,
124
+ world_id: value.world_id,
125
+ api_key: value.api_key,
126
+ api_key_expression: value.api_key_expression,
127
+ api_status: value.api_status,
128
+ members: value.members,
129
+ unknown_members: value.unknown_members,
130
+ omitted_members: value.omitted_members,
131
+ },
132
+ evidence: astObservationEvidence({
133
+ sha256: file.sha256,
134
+ path: file.path,
135
+ range: value.location,
136
+ operation: "observe-context-bridge-api",
137
+ coverage,
138
+ }),
139
+ },
140
+ ],
141
+ });
142
+ addElectronInferenceEdge(context, {
143
+ source: input.source,
144
+ target: bridge,
145
+ file,
146
+ range: value.location,
147
+ coverage,
148
+ relation: "exposes",
149
+ operation: "map-context-bridge-exposure",
150
+ properties: {
151
+ world: value.world,
152
+ api_key: value.api_key,
153
+ resolution: value.api_key === null ? "dynamic" : "literal",
154
+ },
155
+ });
156
+ };
157
+ const addUtilityProcess = (input) => {
158
+ const { context, file, value, coverage } = input;
159
+ const utility = context.accumulator.addNode({
160
+ kind: "electron-utility",
161
+ identity: artifactLocalIdentity(file.sha256, "electron-utility-process", `${value.module_path ?? value.module_expression ?? "[missing]"}:${electronRangeKey(value.location)}`),
162
+ observations: [
163
+ {
164
+ label: value.service_name ?? value.module_path,
165
+ properties: {
166
+ module_path: value.module_path,
167
+ module_resolution_context: value.module_resolution_context,
168
+ module_expression: value.module_expression,
169
+ service_name: value.service_name,
170
+ },
171
+ evidence: astObservationEvidence({
172
+ sha256: file.sha256,
173
+ path: file.path,
174
+ range: value.location,
175
+ operation: "observe-utility-process-fork",
176
+ coverage,
177
+ }),
178
+ },
179
+ ],
180
+ });
181
+ addElectronInferenceEdge(context, {
182
+ source: input.source,
183
+ target: utility,
184
+ file,
185
+ range: value.location,
186
+ coverage,
187
+ relation: "loads",
188
+ operation: "map-utility-process-launch",
189
+ properties: {
190
+ declared_path: value.module_path,
191
+ expression: value.module_expression,
192
+ },
193
+ });
194
+ if (value.module_path === null)
195
+ return;
196
+ const resolution = resolveArtifactPathByContext({
197
+ declaredPath: value.module_path,
198
+ sourcePath: file.path,
199
+ context: value.module_resolution_context ?? "module-specifier",
200
+ files: context.filesByPath,
201
+ });
202
+ const resolved = resolution.resolved_path;
203
+ const target = resolved === null
204
+ ? undefined
205
+ : (context.assetNodes.get(resolved) ?? context.fileNodes.get(resolved));
206
+ if (target === undefined)
207
+ return;
208
+ addElectronInferenceEdge(context, {
209
+ source: utility,
210
+ target,
211
+ file,
212
+ range: value.location,
213
+ coverage,
214
+ relation: "maps_to",
215
+ operation: "resolve-utility-process-entrypoint",
216
+ properties: {
217
+ declared_path: value.module_path,
218
+ resolution_context: resolution.resolution_context,
219
+ resolved_path: resolved,
220
+ resolution_status: resolution.resolution_status,
221
+ },
222
+ });
223
+ };
@@ -0,0 +1,22 @@
1
+ import { AnalysisOutputError } from "../domain/errors.js";
2
+ import { parseAddressedPage } from "../domain/hopperValues.js";
3
+ import { err, ok } from "../domain/result.js";
4
+ /** Read all addressed entries while enforcing advancing provider pagination. */
5
+ export const readAllAddressed = async (input) => {
6
+ const entries = [];
7
+ let offset = 0;
8
+ while (true) {
9
+ const result = await input.call(input.tool, { offset, limit: 500 }, input.signal);
10
+ if (!result.ok)
11
+ return result;
12
+ const page = parseAddressedPage(result.value);
13
+ if (!page.ok)
14
+ return page;
15
+ entries.push(...page.value.items);
16
+ if (!page.value.hasMore || page.value.nextOffset === null)
17
+ return ok(entries);
18
+ if (page.value.nextOffset <= offset)
19
+ return err(new AnalysisOutputError(input.tool, "provider returned a non-advancing pagination offset"));
20
+ offset = page.value.nextOffset;
21
+ }
22
+ };
@@ -0,0 +1,4 @@
1
+ import { AnalysisInputError } from "../domain/errors.js";
2
+ import { err } from "../domain/result.js";
3
+ import { enhancedInputSchemas, } from "../contracts/enhancedInputs.js";
4
+ export const invalidEnhancedInput = (name, cause) => Promise.resolve(err(new AnalysisInputError(name, { cause })));
@@ -1,81 +1,108 @@
1
1
  import { enhancedInputSchemas } from "../contracts/enhancedInputs.js";
2
- import { AnalysisInputError, AnalysisCancelledError, AnalysisOutputError, projectAnalysisError, } from "../domain/errors.js";
3
- import { addressDistance, parseDocuments, parseFunctionDossier, parseAddressedPage, parseListCount, parseRelatedAddresses, parseSegments, } from "../domain/hopperValues.js";
2
+ import { AnalysisCancelledError, AnalysisOutputError, projectAnalysisError, } from "../domain/errors.js";
3
+ import { addressDistance, parseAddressedPage, parseDocuments, parseFunctionDossier, parseListCount, parseRelatedAddresses, parseSegments, } from "../domain/hopperValues.js";
4
4
  import { err, ok } from "../domain/result.js";
5
5
  import { categorizeSwiftTypes, discoverObjcClasses, discoverObjcProtocols, discoverSwiftClasses, } from "../domain/symbolAnalysis.js";
6
+ import { invalidEnhancedInput, } from "./EnhancedToolTypes.js";
7
+ import { readAllAddressed } from "./EnhancedToolPagination.js";
6
8
  /**
7
9
  * Composes direct provider operations into bounded reverse-engineering tools.
8
- * Inputs are parsed again at this application boundary even though MCP normally
9
- * validates them, allowing direct callers to use the same service safely.
10
+ * Direct callers use `execute`; adapters that own validation use
11
+ * `executeValidated` so an MCP input is parsed exactly once.
10
12
  */
11
13
  export class EnhancedTools {
12
14
  analysis;
13
15
  constructor(analysis) {
14
16
  this.analysis = analysis;
15
17
  }
16
- /** Parse inputs again at the direct-call boundary, then dispatch exhaustively. */
18
+ /** Parse an untrusted direct-call input once, then dispatch exhaustively. */
17
19
  execute(name, input, signal) {
18
20
  switch (name) {
19
21
  case "swift_classes": {
20
22
  const parsed = enhancedInputSchemas.swift_classes.safeParse(input);
21
23
  return parsed.success
22
- ? this.#swiftClasses(parsed.data.pattern, signal)
23
- : invalidInput(name, parsed.error);
24
+ ? this.executeValidated({ name, input: parsed.data }, signal)
25
+ : invalidEnhancedInput(name, parsed.error);
24
26
  }
25
27
  case "get_objc_classes": {
26
28
  const parsed = enhancedInputSchemas.get_objc_classes.safeParse(input);
27
29
  return parsed.success
28
- ? this.#objcClasses(parsed.data.pattern, signal)
29
- : invalidInput(name, parsed.error);
30
+ ? this.executeValidated({ name, input: parsed.data }, signal)
31
+ : invalidEnhancedInput(name, parsed.error);
30
32
  }
31
33
  case "get_objc_protocols":
32
- return this.#objcProtocols(signal);
34
+ return this.executeValidated({ name, input: {} }, signal);
33
35
  case "batch_decompile": {
34
36
  const parsed = enhancedInputSchemas.batch_decompile.safeParse(input);
35
37
  return parsed.success
36
- ? this.#batchDecompile(parsed.data.addresses, signal)
37
- : invalidInput(name, parsed.error);
38
+ ? this.executeValidated({ name, input: parsed.data }, signal)
39
+ : invalidEnhancedInput(name, parsed.error);
38
40
  }
39
41
  case "get_call_graph": {
40
42
  const parsed = enhancedInputSchemas.get_call_graph.safeParse(input);
41
43
  return parsed.success
42
- ? this.#callGraph(parsed.data, signal)
43
- : invalidInput(name, parsed.error);
44
+ ? this.executeValidated({ name, input: parsed.data }, signal)
45
+ : invalidEnhancedInput(name, parsed.error);
44
46
  }
45
47
  case "analyze_swift_types":
46
- return this.#analyzeSwiftTypes(signal);
48
+ return this.executeValidated({ name, input: {} }, signal);
47
49
  case "find_xrefs_to_name": {
48
50
  const parsed = enhancedInputSchemas.find_xrefs_to_name.safeParse(input);
49
51
  return parsed.success
50
- ? this.#findXrefs(parsed.data.name, signal)
51
- : invalidInput(name, parsed.error);
52
+ ? this.executeValidated({ name, input: parsed.data }, signal)
53
+ : invalidEnhancedInput(name, parsed.error);
52
54
  }
53
55
  case "binary_overview": {
54
56
  const parsed = enhancedInputSchemas.binary_overview.safeParse(input);
55
57
  return parsed.success
56
- ? this.#binaryOverview(parsed.data, signal)
57
- : invalidInput(name, parsed.error);
58
+ ? this.executeValidated({ name, input: parsed.data }, signal)
59
+ : invalidEnhancedInput(name, parsed.error);
58
60
  }
59
61
  case "analyze_function": {
60
62
  const parsed = enhancedInputSchemas.analyze_function.safeParse(input);
61
63
  return parsed.success
62
- ? this.#analyzeFunction(parsed.data, signal)
63
- : invalidInput(name, parsed.error);
64
+ ? this.executeValidated({ name, input: parsed.data }, signal)
65
+ : invalidEnhancedInput(name, parsed.error);
64
66
  }
65
67
  case "trace_feature": {
66
68
  const parsed = enhancedInputSchemas.trace_feature.safeParse(input);
67
69
  return parsed.success
68
- ? this.#traceFeature(parsed.data, signal)
69
- : invalidInput(name, parsed.error);
70
+ ? this.executeValidated({ name, input: parsed.data }, signal)
71
+ : invalidEnhancedInput(name, parsed.error);
70
72
  }
71
73
  }
72
74
  }
75
+ /** Dispatch input already parsed by a trusted adapter boundary. */
76
+ executeValidated(call, signal) {
77
+ switch (call.name) {
78
+ case "swift_classes":
79
+ return this.#swiftClasses(call.input.pattern, signal);
80
+ case "get_objc_classes":
81
+ return this.#objcClasses(call.input.pattern, signal);
82
+ case "get_objc_protocols":
83
+ return this.#objcProtocols(signal);
84
+ case "batch_decompile":
85
+ return this.#batchDecompile(call.input.addresses, signal);
86
+ case "get_call_graph":
87
+ return this.#callGraph(call.input, signal);
88
+ case "analyze_swift_types":
89
+ return this.#analyzeSwiftTypes(signal);
90
+ case "find_xrefs_to_name":
91
+ return this.#findXrefs(call.input.name, signal);
92
+ case "binary_overview":
93
+ return this.#binaryOverview(call.input, signal);
94
+ case "analyze_function":
95
+ return this.#analyzeFunction(call.input, signal);
96
+ case "trace_feature":
97
+ return this.#traceFeature(call.input, signal);
98
+ }
99
+ }
73
100
  async #analyzeFunction(input, signal) {
74
101
  const result = await this.#call("analyze_function", input, signal);
75
102
  return result.ok ? parseFunctionDossier(result.value) : result;
76
103
  }
77
104
  async #swiftClasses(pattern, signal) {
78
- const procedures = await this.#allProcedures(signal);
105
+ const procedures = await this.#allAddressed("list_procedures", signal);
79
106
  return procedures.ok
80
107
  ? ok(discoverSwiftClasses(procedures.value, pattern))
81
108
  : procedures;
@@ -164,7 +191,7 @@ export class EnhancedTools {
164
191
  return ok(graph);
165
192
  }
166
193
  async #analyzeSwiftTypes(signal) {
167
- const procedures = await this.#allProcedures(signal);
194
+ const procedures = await this.#allAddressed("list_procedures", signal);
168
195
  return procedures.ok
169
196
  ? ok(categorizeSwiftTypes(procedures.value))
170
197
  : procedures;
@@ -193,7 +220,7 @@ export class EnhancedTools {
193
220
  const [segmentsResult, documentsResult, procedures, stringsResult] = await Promise.all([
194
221
  this.#call("list_segments", {}, signal),
195
222
  this.#call("list_documents", {}, signal),
196
- this.#allProcedures(signal),
223
+ this.#allAddressed("list_procedures", signal),
197
224
  this.#call("list_strings", {}, signal),
198
225
  ]);
199
226
  if (!segmentsResult.ok)
@@ -333,28 +360,12 @@ export class EnhancedTools {
333
360
  residual: [...residual],
334
361
  });
335
362
  }
336
- async #allProcedures(signal) {
337
- return this.#allAddressed("list_procedures", signal);
338
- }
339
363
  async #allAddressed(tool, signal) {
340
- const entries = [];
341
- let offset = 0;
342
- while (true) {
343
- const result = await this.#call(tool, { offset, limit: 500 }, signal);
344
- if (!result.ok)
345
- return result;
346
- const page = parseAddressedPage(result.value);
347
- if (!page.ok)
348
- return page;
349
- entries.push(...page.value.items);
350
- if (!page.value.hasMore || page.value.nextOffset === null) {
351
- return ok(entries);
352
- }
353
- if (page.value.nextOffset <= offset) {
354
- return err(new AnalysisOutputError(tool, "provider returned a non-advancing pagination offset"));
355
- }
356
- offset = page.value.nextOffset;
357
- }
364
+ return readAllAddressed({
365
+ call: (name, arguments_, operationSignal) => this.#call(name, arguments_, operationSignal),
366
+ tool,
367
+ ...(signal === undefined ? {} : { signal }),
368
+ });
358
369
  }
359
370
  async #call(name, arguments_, signal) {
360
371
  if (signal?.aborted === true)
@@ -363,6 +374,3 @@ export class EnhancedTools {
363
374
  return execution.ok ? ok(execution.value.result) : execution;
364
375
  }
365
376
  }
366
- const invalidInput = (name, cause) => Promise.resolve(err(new AnalysisInputError(name, {
367
- cause,
368
- })));
@@ -0,0 +1,36 @@
1
+ import { instrumentJavaScriptExport, } from "../domain/javascriptExportInstrumentation.js";
2
+ /** Decorate one exact replay source with deterministic in-memory instrumentation. */
3
+ export class InstrumentedJavaScriptReplayHost {
4
+ delegate;
5
+ input;
6
+ instrumentation = null;
7
+ constructor(delegate, input) {
8
+ this.delegate = delegate;
9
+ this.input = input;
10
+ }
11
+ async readSource(path, maximumBytes) {
12
+ const source = await this.delegate.readSource(path, maximumBytes);
13
+ if (path !== this.input.artifact_path)
14
+ return source;
15
+ const instrumented = instrumentJavaScriptExport(source.bytes, this.input);
16
+ if (instrumented.bytes.byteLength > maximumBytes)
17
+ throw new RangeError("Instrumented JavaScript exceeds the replay module byte limit");
18
+ this.instrumentation = instrumented;
19
+ return { canonicalPath: source.canonicalPath, bytes: instrumented.bytes };
20
+ }
21
+ identifyExecutable(path, versionArguments) {
22
+ return this.delegate.identifyExecutable(path, versionArguments);
23
+ }
24
+ identifyWorker() {
25
+ return this.delegate.identifyWorker();
26
+ }
27
+ identifyRuntimeClosure(nodePath) {
28
+ return this.delegate.identifyRuntimeClosure(nodePath);
29
+ }
30
+ seccompDigest() {
31
+ return this.delegate.seccompDigest();
32
+ }
33
+ probe(policy) {
34
+ return this.delegate.probe(policy);
35
+ }
36
+ }
@@ -15,6 +15,36 @@ export const ARTIFACT_GRAPH_PROVIDER = {
15
15
  name: "REA safe artifact graph provider",
16
16
  version: "1",
17
17
  };
18
+ /** Provider identity for execution-free managed PE/CLI analysis. */
19
+ export const MANAGED_STATIC_PROVIDER = {
20
+ id: "rea-dotnet-static",
21
+ name: "REA managed static analysis provider",
22
+ version: "1",
23
+ };
24
+ /** Provider identity for deterministic managed-code comparison workflows. */
25
+ export const MANAGED_WORKFLOW_PROVIDER = {
26
+ id: "rea-dotnet-workflows",
27
+ name: "REA managed-code workflows",
28
+ version: "1",
29
+ };
30
+ /** Provider identity for deterministic static JavaScript application analysis. */
31
+ export const JAVASCRIPT_APPLICATION_PROVIDER = {
32
+ id: "rea-javascript-application",
33
+ name: "REA JavaScript application analyzer",
34
+ version: "1",
35
+ };
36
+ /** Provider identity for static/passive-runtime JavaScript reconciliation. */
37
+ export const JAVASCRIPT_RUNTIME_RECONCILIATION_PROVIDER = {
38
+ id: "rea-javascript-runtime-reconciliation",
39
+ name: "REA JavaScript runtime reconciliation",
40
+ version: "1",
41
+ };
42
+ /** Provider identity for graph-native feature tracing and version comparison. */
43
+ export const JAVASCRIPT_APPLICATION_WORKFLOW_PROVIDER = {
44
+ id: "rea-javascript-application-workflows",
45
+ name: "REA JavaScript application workflows",
46
+ version: "1",
47
+ };
18
48
  /** Provider identity for deterministic cross-artifact comparisons. */
19
49
  export const ARTIFACT_COMPARISON_PROVIDER = {
20
50
  id: "rea-artifact-comparison",
@@ -5,27 +5,41 @@ import { isJsonWithinLimits } from "../domain/jsonLimits.js";
5
5
  import { InvestigationWorkspaceError } from "../domain/errors.js";
6
6
  import { parseInvestigationWorkspace, serializeInvestigationWorkspace, } from "../domain/investigationWorkspace.js";
7
7
  import { err, ok } from "../domain/result.js";
8
+ const investigationWorkspaceCodec = {
9
+ parse: parseInvestigationWorkspace,
10
+ serialize: serializeInvestigationWorkspace,
11
+ validateNext: validateNextRevision,
12
+ };
8
13
  /** Read a validated workspace, returning null only when it does not exist. */
9
- export const readInvestigationWorkspace = async (path, policy) => {
14
+ export const readInvestigationWorkspace = async (path, policy) => readRevisionedWorkspace(path, policy, investigationWorkspaceCodec);
15
+ /** Read one root-confined, owner-only revisioned workspace document. */
16
+ export const readRevisionedWorkspace = async (path, policy, codec) => {
10
17
  if (policy.roots.length === 0)
11
18
  return err(new InvestigationWorkspaceError("read", "disabled"));
12
19
  try {
13
20
  const destination = await resolveDestination(path, policy.roots);
14
21
  if (destination === null)
15
22
  return err(new InvestigationWorkspaceError("read", "outside-root"));
16
- return await readWorkspaceFile(destination, policy);
23
+ return await readWorkspaceFile(destination, policy, codec);
17
24
  }
18
25
  catch (cause) {
19
26
  return err(new InvestigationWorkspaceError("read", "io", { cause }));
20
27
  }
21
28
  };
22
29
  /** Atomically append one CAS-linked workspace revision under an exclusive lock. */
23
- export const writeInvestigationWorkspace = async (workspace, path, expectedRevision, policy) => {
30
+ export const writeInvestigationWorkspace = async (workspace, path, expectedRevision, policy) => writeRevisionedWorkspace(path, policy, {
31
+ document: workspace,
32
+ expectedRevision,
33
+ codec: investigationWorkspaceCodec,
34
+ });
35
+ /** Atomically append one validated CAS-linked revision under an exclusive lock. */
36
+ export const writeRevisionedWorkspace = async (path, policy, input) => {
37
+ const { document, expectedRevision, codec } = input;
24
38
  if (policy.roots.length === 0)
25
39
  return err(new InvestigationWorkspaceError("update", "disabled"));
26
40
  let encoded;
27
41
  try {
28
- encoded = serializeInvestigationWorkspace(workspace);
42
+ encoded = codec.serialize(document);
29
43
  }
30
44
  catch (cause) {
31
45
  return err(new InvestigationWorkspaceError("update", "integrity", { cause }));
@@ -42,10 +56,10 @@ export const writeInvestigationWorkspace = async (workspace, path, expectedRevis
42
56
  if (!acquired.ok)
43
57
  return acquired;
44
58
  lock = acquired.value;
45
- const current = await readWorkspaceFile(destination, policy);
59
+ const current = await readWorkspaceFile(destination, policy, codec);
46
60
  if (!current.ok)
47
61
  return current;
48
- const checked = validateNextRevision(current.value, workspace, expectedRevision);
62
+ const checked = codec.validateNext(current.value, document, expectedRevision);
49
63
  if (!checked.ok)
50
64
  return checked;
51
65
  await writeFileAtomic(destination, encoded, {
@@ -76,7 +90,7 @@ const resolveDestination = async (path, roots) => {
76
90
  }
77
91
  return null;
78
92
  };
79
- const readWorkspaceFile = async (destination, policy) => {
93
+ const readWorkspaceFile = async (destination, policy, codec) => {
80
94
  const stats = await lstat(destination).catch((cause) => {
81
95
  if (isFileNotFound(cause))
82
96
  return undefined;
@@ -101,7 +115,7 @@ const readWorkspaceFile = async (destination, policy) => {
101
115
  if (!isJsonWithinLimits(decoded, policy))
102
116
  return err(new InvestigationWorkspaceError("read", "too-large"));
103
117
  try {
104
- return ok(parseInvestigationWorkspace(decoded));
118
+ return ok(codec.parse(decoded));
105
119
  }
106
120
  catch (cause) {
107
121
  return err(new InvestigationWorkspaceError("read", "integrity", { cause }));
@@ -168,7 +182,7 @@ const releaseLock = async (lock) => {
168
182
  await lock.handle.close().catch(() => undefined);
169
183
  await unlink(lock.path).catch(() => undefined);
170
184
  };
171
- const validateNextRevision = (current, next, expectedRevision) => {
185
+ function validateNextRevision(current, next, expectedRevision) {
172
186
  if ((current?.revision ?? null) !== expectedRevision)
173
187
  return err(new InvestigationWorkspaceError("update", "revision-conflict"));
174
188
  if (current === null) {
@@ -182,7 +196,7 @@ const validateNextRevision = (current, next, expectedRevision) => {
182
196
  next.previous_revision_digest === current.revision_digest
183
197
  ? ok(null)
184
198
  : err(new InvestigationWorkspaceError("update", "revision-conflict"));
185
- };
199
+ }
186
200
  const isFileNotFound = (cause) => errorCode(cause) === "ENOENT";
187
201
  const isAlreadyExists = (cause) => errorCode(cause) === "EEXIST";
188
202
  const errorCode = (cause) => typeof cause === "object" && cause !== null && "code" in cause
@@ -0,0 +1,26 @@
1
+ import { createEvidence, } from "../domain/evidence.js";
2
+ import { jsonValueSchema } from "../domain/jsonValue.js";
3
+ import { JAVASCRIPT_APPLICATION_PROVIDER } from "./InvestigationProviders.js";
4
+ /** Create Evidence v2 for one deterministic local JavaScript application graph. */
5
+ export const createJavaScriptApplicationEvidence = (input, result) => createEvidence({
6
+ path: result.input_path,
7
+ sha256: result.root_artifact_sha256,
8
+ format: result.format,
9
+ }, JAVASCRIPT_APPLICATION_PROVIDER, {
10
+ predicateType: "rea.javascript-application-analysis/v1",
11
+ operation: "analyze_javascript_application",
12
+ parameters: parameters(input),
13
+ result: jsonValueSchema.parse(result),
14
+ rawResult: null,
15
+ confidence: "derived",
16
+ authority: "shipped-artifact",
17
+ environment: null,
18
+ limitations: result.limitations,
19
+ locations: [{ kind: "artifact-path", path: "artifact-root" }],
20
+ });
21
+ const parameters = (input) => ({
22
+ format: input.format,
23
+ approved: input.approved,
24
+ source_map_read_approved: input.source_map_read_approved,
25
+ limits: input.limits,
26
+ });