rea-agents 6.1.0 → 6.2.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 (453) hide show
  1. package/README.md +7 -5
  2. package/bridge/ghidra/ReaGhidraBridge.java +32 -4
  3. package/bridge/hopper_bridge.py +6 -1
  4. package/dist/android/JadxConfiguration.js +87 -7
  5. package/dist/android/JadxMcpTransport.js +14 -2
  6. package/dist/android/JadxProvider.js +57 -35
  7. package/dist/application/BinaryTargetResolver.js +5 -3
  8. package/dist/application/BrowserEvidence.js +3 -8
  9. package/dist/application/BrowserScenarioEvidence.js +2 -18
  10. package/dist/application/CapabilityInventory.js +43 -9
  11. package/dist/application/ClientConfigurationDocument.js +69 -25
  12. package/dist/application/DirectAnalysis.js +29 -14
  13. package/dist/application/DirectAnalysisCleanup.js +72 -0
  14. package/dist/application/DirectAnalysisStatus.js +4 -5
  15. package/dist/application/Doctor.js +15 -19
  16. package/dist/application/DoctorDiagnostics.js +1 -2
  17. package/dist/application/EnhancedTools.js +51 -6
  18. package/dist/application/EvidenceBundleFiles.js +8 -3
  19. package/dist/application/InvestigationProviders.js +9 -1
  20. package/dist/application/JsonFiles.js +42 -9
  21. package/dist/application/LinuxHopper.js +9 -6
  22. package/dist/application/MacHopper.js +15 -18
  23. package/dist/application/RealHopperAssertions.js +0 -11
  24. package/dist/application/ReconstructionObligationCandidates.js +1 -1
  25. package/dist/application/ReferenceSourceImportEntries.js +1 -1
  26. package/dist/application/Setup.js +8 -16
  27. package/dist/application/SetupHost.js +16 -27
  28. package/dist/application/SetupPlan.js +6 -6
  29. package/dist/application/Uninstall.js +81 -29
  30. package/dist/application/UpdateMaintenance.js +7 -5
  31. package/dist/application/UpdateRuntime.js +12 -12
  32. package/dist/application/WebScriptExportService.js +30 -4
  33. package/dist/application/WorkflowEvidence.js +25 -2
  34. package/dist/application/XrefsAddressResolution.js +45 -0
  35. package/dist/application/analysisView/AnalysisViewService.js +76 -0
  36. package/dist/application/binary/AnalysisClientCleanup.js +30 -5
  37. package/dist/application/binary/AnalysisProviderEvaluation.js +1 -2
  38. package/dist/application/binary/AnalysisProviderRegistry.js +2 -6
  39. package/dist/application/binary/AnalysisSnapshotCache.js +10 -8
  40. package/dist/application/binary/BinarySession.js +70 -29
  41. package/dist/application/binary/BinarySessionComposition.js +1 -3
  42. package/dist/application/binary/BinarySessionExecution.js +3 -5
  43. package/dist/application/binary/BinarySessionOpen.js +1 -1
  44. package/dist/application/binary/BinarySessionRecords.js +1 -1
  45. package/dist/application/binary/BinarySessionStatus.js +1 -6
  46. package/dist/application/binary/CompositeProvider.js +4 -18
  47. package/dist/application/binary/LazyAnalysisProvider.js +5 -5
  48. package/dist/application/binary/SessionProviderRouter.js +27 -135
  49. package/dist/application/homebrew.js +48 -0
  50. package/dist/application/javascript/ElectronActiveEvidence.js +9 -13
  51. package/dist/application/javascript/JavaScriptApplicationEvidence.js +2 -6
  52. package/dist/application/javascript/JavaScriptApplicationService.js +6 -1
  53. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +5 -3
  54. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +11 -9
  55. package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +11 -3
  56. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +9 -0
  57. package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +8 -5
  58. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +12 -3
  59. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +0 -1
  60. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +43 -16
  61. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +46 -6
  62. package/dist/application/javascript/JavaScriptModuleRelationships.js +1 -1
  63. package/dist/application/javascript/JavaScriptRuntimeObservationService.js +3 -3
  64. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +2 -3
  65. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -2
  66. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +2 -3
  67. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +1 -5
  68. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +75 -46
  69. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +2 -3
  70. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +42 -19
  71. package/dist/application/managed/ManagedMemberComparisonService.js +2 -1
  72. package/dist/application/managed/ManagedNativeVerificationService.js +2 -1
  73. package/dist/application/process/ProcessCli.js +11 -11
  74. package/dist/application/process/ProcessEvidence.js +0 -1
  75. package/dist/artifacts/ArtifactProvider.js +39 -14
  76. package/dist/artifacts/ArtifactReader.js +31 -0
  77. package/dist/artifacts/DirectoryArtifactReader.js +2 -1
  78. package/dist/artifacts/MachOSliceArtifactReader.js +9 -2
  79. package/dist/artifacts/NativeDmgArtifactReader.js +65 -20
  80. package/dist/artifacts/SafeOutputTree.js +16 -2
  81. package/dist/artifacts/ZipArtifactReader.js +11 -4
  82. package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +4 -2
  83. package/dist/artifacts/apple/DylibResolutionReader.js +17 -7
  84. package/dist/artifacts/apple/KeyedArchiveReader.js +21 -3
  85. package/dist/artifacts/extraction/ArtifactExtraction.js +78 -21
  86. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +67 -61
  87. package/dist/artifacts/inventory/ArtifactInventory.js +0 -1
  88. package/dist/artifacts/inventory/reader.js +3 -3
  89. package/dist/artifacts/inventory/scanCanonical.js +48 -24
  90. package/dist/artifacts/inventory/scanReader.js +5 -9
  91. package/dist/browser/BrowserScenarioPartialObservation.js +106 -0
  92. package/dist/browser/CdpBrowserProvider.js +2 -3
  93. package/dist/browser/CdpCaptureEventHandlers.js +2 -4
  94. package/dist/browser/CdpCaptureEvents.js +0 -1
  95. package/dist/browser/CdpCaptureValues.js +20 -0
  96. package/dist/browser/CdpElectronProvider.js +0 -2
  97. package/dist/browser/CdpElectronScriptEvents.js +2 -8
  98. package/dist/browser/CdpElectronScripts.js +2 -3
  99. package/dist/browser/CdpPageCaptureScripts.js +2 -3
  100. package/dist/browser/CdpSafeMetadata.js +10 -10
  101. package/dist/browser/PlaywrightBrowserScenarioProvider.js +59 -44
  102. package/dist/browser/PlaywrightElectronActiveActions.js +2 -56
  103. package/dist/browser/PlaywrightElectronActiveProvider.js +10 -6
  104. package/dist/browser/PlaywrightScenarioArtifacts.js +1 -1
  105. package/dist/browser/PlaywrightScenarioBrowser.js +139 -39
  106. package/dist/browser/PlaywrightScenarioEvents.js +1 -1
  107. package/dist/browser/PlaywrightScenarioSession.js +39 -22
  108. package/dist/browser/assets/ScriptCaptureAdapters.js +1 -1
  109. package/dist/browser/history/CaptureFailures.js +6 -2
  110. package/dist/browser/history/MitmproxyCaptureAdapter.js +4 -2
  111. package/dist/catalogIdentity.js +0 -1
  112. package/dist/cli/analysisViewCommands.js +36 -0
  113. package/dist/cli/artifactCommands.js +11 -12
  114. package/dist/cli/coreAnalysisCommands.js +3 -3
  115. package/dist/cli/coreBinaryCommands.js +32 -27
  116. package/dist/cli/coreNativeCommands.js +9 -10
  117. package/dist/cli/electronCommands.js +4 -4
  118. package/dist/cli/interactiveSetup.js +6 -6
  119. package/dist/cli/managedCommands.js +7 -8
  120. package/dist/cli/nativeCallCommands.js +1 -2
  121. package/dist/cli/omittableDefaults.js +50 -0
  122. package/dist/cli/processCommands.js +3 -2
  123. package/dist/cli/setupCommands.js +16 -15
  124. package/dist/cli/utilityCommands.js +9 -9
  125. package/dist/cli.js +16 -8
  126. package/dist/cliBrowserScenarioCommands.js +2 -2
  127. package/dist/cliCommandNames.js +1 -0
  128. package/dist/cliJsonInput.js +15 -1
  129. package/dist/cliOutput.js +0 -38
  130. package/dist/composition/auxiliaryAnalysisProviders.js +27 -23
  131. package/dist/composition/binary.js +9 -9
  132. package/dist/composition/browserScenario.js +2 -1
  133. package/dist/composition/directAnalysis.js +20 -13
  134. package/dist/composition/electronScenario.js +1 -1
  135. package/dist/composition/optionalObservationProviders.js +12 -7
  136. package/dist/config/environment.js +6 -0
  137. package/dist/config/ghidraStartupTimeout.js +4 -9
  138. package/dist/config/homeDirectory.js +12 -0
  139. package/dist/config/mcpResponseBudget.js +9 -1
  140. package/dist/config/parseConfig.js +7 -3
  141. package/dist/config/parsers.js +19 -22
  142. package/dist/contracts/analysisViewToolContracts.js +56 -0
  143. package/dist/contracts/applicationToolContracts.js +5 -4
  144. package/dist/contracts/artifactComparisonExample.js +2 -2
  145. package/dist/contracts/artifactToolContracts.js +1 -1
  146. package/dist/contracts/browserScenarioToolContracts.js +1 -1
  147. package/dist/contracts/browserToolContracts.js +19 -15
  148. package/dist/contracts/enhancedInputs.js +2 -2
  149. package/dist/contracts/enhancedToolContracts.js +4 -3
  150. package/dist/contracts/evm/evmToolContracts.js +1 -1
  151. package/dist/contracts/functionWorkflowToolContracts.js +1 -1
  152. package/dist/contracts/inputSchemaPresentation.js +90 -0
  153. package/dist/contracts/investigationExamples.js +4 -3
  154. package/dist/contracts/javascript/electronToolContracts.js +1 -1
  155. package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +0 -20
  156. package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +245 -0
  157. package/dist/contracts/javascript/javascriptRuntimeObservationToolContracts.js +1 -1
  158. package/dist/contracts/managed/managedToolContracts.js +5 -10
  159. package/dist/contracts/managed/managedWorkflowToolContracts.js +1 -1
  160. package/dist/contracts/mobileApplicationGraphExamples.js +3 -3
  161. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +1 -1
  162. package/dist/contracts/native/nativeToolContracts.js +2 -2
  163. package/dist/contracts/officialToolContracts.js +2 -1
  164. package/dist/contracts/promptContracts.js +2 -2
  165. package/dist/contracts/providerSelection.js +1 -1
  166. package/dist/contracts/sessionToolContracts.js +14 -2
  167. package/dist/contracts/sessionToolSchemas.js +1 -14
  168. package/dist/contracts/toolContracts.js +2 -0
  169. package/dist/contracts/toolEffects.js +1 -0
  170. package/dist/contracts/toolOutputSchemaGroups.js +136 -92
  171. package/dist/contracts/toolOutputSchemaPrimitives.js +11 -21
  172. package/dist/contracts/toolSchemaMetadata.js +18 -69
  173. package/dist/contracts/webNetworkCaptureToolContracts.js +1 -1
  174. package/dist/contracts/webRuntimeToolContracts.js +1 -1
  175. package/dist/contracts/webScriptToolContracts.js +1 -1
  176. package/dist/doctorRuntime.js +7 -5
  177. package/dist/domain/analysisErrorCore.js +3 -0
  178. package/dist/domain/analysisErrorPresentation.js +18 -3
  179. package/dist/domain/analysisErrorProjection.js +24 -5
  180. package/dist/domain/analysisSnapshot.js +29 -31
  181. package/dist/domain/analysisView/analysisView.js +243 -0
  182. package/dist/domain/analysisView/analysisViewCoverage.js +19 -0
  183. package/dist/domain/analysisView/binaryLayoutView.js +159 -0
  184. package/dist/domain/analysisView/javascriptApplicationView.js +238 -0
  185. package/dist/domain/android/androidApplication.js +1 -1
  186. package/dist/domain/apple/appleApplication.js +1 -1
  187. package/dist/domain/apple/dylibResolution.js +10 -3
  188. package/dist/domain/apple/interfaceBuilderGraph.js +0 -1
  189. package/dist/domain/apple/keyedArchive.js +26 -2
  190. package/dist/domain/artifactComparison.js +15 -6
  191. package/dist/domain/artifactGraph.js +16 -3
  192. package/dist/domain/artifactInventoryEvidence.js +9 -16
  193. package/dist/domain/artifactOperationError.js +3 -3
  194. package/dist/domain/artifactPartialObservation.js +1 -0
  195. package/dist/domain/artifactPathSyntax.js +49 -0
  196. package/dist/domain/binaryTarget.js +39 -13
  197. package/dist/domain/browserCaptureComparison.js +13 -49
  198. package/dist/domain/browserNetworkEvidence.js +10 -4
  199. package/dist/domain/browserObservation.js +0 -1
  200. package/dist/domain/browserObservationSchemas.js +14 -3
  201. package/dist/domain/browserScenario.js +0 -1
  202. package/dist/domain/browserScenarioCapture.js +1 -2
  203. package/dist/domain/browserScenarioDiff.js +0 -2
  204. package/dist/domain/browserScenarioDiffEvidence.js +0 -12
  205. package/dist/domain/browserScenarioDiffValues.js +2 -2
  206. package/dist/domain/browserScenarioValues.js +3 -4
  207. package/dist/domain/callPath.js +8 -9
  208. package/dist/domain/callPathSchemas.js +2 -2
  209. package/dist/domain/changedBehavior.js +3 -3
  210. package/dist/domain/completionLedgerGeneration.js +2 -1
  211. package/dist/domain/configurationErrors.js +12 -0
  212. package/dist/domain/conformancePackage.js +4 -3
  213. package/dist/domain/evidence.js +10 -36
  214. package/dist/domain/evidenceBundle.js +7 -9
  215. package/dist/domain/evidenceCompletionLedger.js +2 -1
  216. package/dist/domain/functionComparison.js +4 -5
  217. package/dist/domain/functionComparisonDimensions.js +120 -87
  218. package/dist/domain/functionComparisonNormalization.js +23 -34
  219. package/dist/domain/functionComparisonResults.js +1 -4
  220. package/dist/domain/functionComparisonSchemas.js +2 -8
  221. package/dist/domain/functionDossierEvidence.js +2 -37
  222. package/dist/domain/javascript/electronActiveObservation.js +26 -69
  223. package/dist/domain/javascript/electronObservation.js +14 -3
  224. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +10 -9
  225. package/dist/domain/javascript/electronStaticAnalysisIpc.js +2 -1
  226. package/dist/domain/javascript/electronStaticAnalysisNative.js +2 -1
  227. package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +2 -0
  228. package/dist/domain/javascript/javascriptApplicationGraph.js +26 -3
  229. package/dist/domain/javascript/javascriptApplicationGraphSchemas.js +9 -2
  230. package/dist/domain/javascript/javascriptApplicationVersionItems.js +5 -2
  231. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +2 -1
  232. package/dist/{application/javascript/JavaScriptReturnShapeProjection.js → domain/javascript/javascriptExportReturnShapeProjection.js} +4 -4
  233. package/dist/domain/javascript/javascriptExportShapeComparison.js +7 -1
  234. package/dist/domain/javascript/javascriptExportShapeComparisonIdentity.js +6 -1
  235. package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +29 -1
  236. package/dist/domain/javascript/javascriptExportShapeSelection.js +5 -5
  237. package/dist/domain/javascript/javascriptExportShapeVariants.js +67 -14
  238. package/dist/domain/javascript/javascriptFeatureSeed.js +20 -0
  239. package/dist/domain/javascript/javascriptFeatureTraversal.js +0 -1
  240. package/dist/domain/javascript/javascriptNativeHandoff.js +1 -1
  241. package/dist/domain/javascript/javascriptRuntimeLoadState.js +0 -1
  242. package/dist/domain/javascript/javascriptRuntimeObservation.js +10 -2
  243. package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +1 -1
  244. package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +3 -2
  245. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +0 -1
  246. package/dist/domain/javascript/javascriptSemanticAnalysis.js +9 -3
  247. package/dist/domain/javascript/javascriptSemanticAsyncEffects.js +2 -1
  248. package/dist/domain/javascript/javascriptSemanticCalls.js +2 -1
  249. package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -1
  250. package/dist/domain/javascript/javascriptSemanticDataEffects.js +1 -1
  251. package/dist/domain/javascript/javascriptSemanticGraph.js +88 -46
  252. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +77 -20
  253. package/dist/domain/javascript/javascriptSemanticMutationValues.js +21 -27
  254. package/dist/domain/javascript/javascriptSemanticObjects.js +83 -42
  255. package/dist/domain/javascript/javascriptSemanticPrimitives.js +1 -12
  256. package/dist/domain/javascript/javascriptSemanticProjection.js +2 -3
  257. package/dist/domain/javascript/javascriptSemanticPromises.js +2 -1
  258. package/dist/domain/javascript/javascriptSemanticResourceLimits.js +1 -1
  259. package/dist/domain/javascript/javascriptSemanticResources.js +1 -1
  260. package/dist/domain/javascript/javascriptSemanticReturns.js +32 -17
  261. package/dist/domain/javascript/javascriptSemanticSlots.js +72 -0
  262. package/dist/domain/javascript/javascriptSemanticValues.js +47 -54
  263. package/dist/domain/javascript/javascriptSourceMapPaths.js +104 -0
  264. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +2 -1
  265. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +0 -1
  266. package/dist/domain/javascript/sourceToBundleComparison.js +12 -3
  267. package/dist/domain/javascript/sourceToBundleSignals.js +47 -19
  268. package/dist/domain/localPath.js +1 -1
  269. package/dist/domain/managed/managedArtifact.js +6 -4
  270. package/dist/domain/managed/managedMemberComparison.js +2 -9
  271. package/dist/domain/managed/managedNativeVerification.js +0 -2
  272. package/dist/domain/managed/managedNativeVerificationMatch.js +9 -3
  273. package/dist/domain/native/binaryLayout.js +2 -3
  274. package/dist/domain/native/nativeApiBoundary.js +1 -1
  275. package/dist/domain/native/nativeCallObservation.js +5 -3
  276. package/dist/domain/native/nativeInstruction.js +7 -0
  277. package/dist/domain/native/recordedCrash.js +2 -3
  278. package/dist/domain/offsetDateTime.js +17 -0
  279. package/dist/domain/process/processCapture.js +13 -12
  280. package/dist/domain/process/processCaptureCoverage.js +67 -0
  281. package/dist/domain/process/processCaptureExample.js +2 -1
  282. package/dist/domain/process/processCaptureParsing.js +1 -34
  283. package/dist/domain/process/processCaptureValidation.js +81 -13
  284. package/dist/domain/process/processComparison.js +41 -22
  285. package/dist/domain/process/processObservation.js +10 -2
  286. package/dist/domain/process/processScenario.js +24 -2
  287. package/dist/domain/process/processTraceComparison.js +0 -2
  288. package/dist/domain/process/processTraceDimensionProjection.js +1 -1
  289. package/dist/domain/process/processTraceEvaluation.js +15 -11
  290. package/dist/domain/process/processTraceSpecification.js +3 -4
  291. package/dist/domain/providerAdapterError.js +2 -0
  292. package/dist/domain/reconstructionCoverage.js +5 -2
  293. package/dist/domain/reconstructionObligationLedgerSchemas.js +2 -1
  294. package/dist/domain/reconstructionReadinessSchemas.js +2 -1
  295. package/dist/domain/reconstructionVerification.js +3 -3
  296. package/dist/domain/reconstructionVerificationSchemas.js +2 -1
  297. package/dist/domain/referenceSourceGraph.js +20 -21
  298. package/dist/domain/staticRuntimeCorrelation.js +2 -2
  299. package/dist/domain/stringPatterns.js +6 -0
  300. package/dist/domain/swiftSymbolClassification.js +61 -0
  301. package/dist/domain/symbolAnalysis.js +66 -18
  302. package/dist/domain/webCaptureDiff.js +0 -1
  303. package/dist/domain/webCaptureDiffSchemas.js +6 -3
  304. package/dist/domain/webEventListeners.js +3 -2
  305. package/dist/domain/webExecution.js +3 -2
  306. package/dist/domain/webRuntime.js +0 -2
  307. package/dist/domain/webScriptExport.js +1 -1
  308. package/dist/dotnet/ManagedArtifactInspector.js +2 -19
  309. package/dist/dotnet/ManagedMemberInspector.js +12 -18
  310. package/dist/dotnet/ManagedMemberInspectorCore.js +47 -44
  311. package/dist/dotnet/ManagedMemberRows.js +75 -62
  312. package/dist/dotnet/ManagedMetadataInventory.js +16 -22
  313. package/dist/dotnet/ManagedMethodBodyReader.js +4 -0
  314. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +109 -94
  315. package/dist/dotnet/ManagedNativeBoundaryInspector.js +12 -21
  316. package/dist/dotnet/ManagedReaderFailure.js +16 -0
  317. package/dist/dotnet/ManagedStaticProvider.js +3 -5
  318. package/dist/evaluation/AgentEvaluationFixtures.js +250 -0
  319. package/dist/evaluation/AgentEvaluationReport.js +28 -0
  320. package/dist/evaluation/CodexAgentEval.js +12 -8
  321. package/dist/evaluation/KnownAnswerEvaluation.js +281 -0
  322. package/dist/evm/EvmoleInterfaceProvider.js +2 -1
  323. package/dist/firmware/FirmwareCommand.js +9 -5
  324. package/dist/firmware/FirmwareProvider.js +4 -4
  325. package/dist/generatedPackageMetadata.js +2 -2
  326. package/dist/ghidra/GhidraAnalysisProfile.js +3 -6
  327. package/dist/ghidra/GhidraClient.js +91 -32
  328. package/dist/ghidra/GhidraClientStartup.js +0 -2
  329. package/dist/ghidra/GhidraDoctor.js +6 -5
  330. package/dist/ghidra/GhidraFunctionValues.js +3 -5
  331. package/dist/ghidra/GhidraInstallation.js +40 -12
  332. package/dist/ghidra/GhidraJavaLaunch.js +6 -2
  333. package/dist/ghidra/GhidraLauncher.js +15 -7
  334. package/dist/ghidra/GhidraProvider.js +6 -2
  335. package/dist/ghidra/GhidraProviderCapabilities.js +6 -0
  336. package/dist/ghidra/GhidraProviderClient.js +13 -3
  337. package/dist/ghidra/GhidraSessionError.js +2 -0
  338. package/dist/ghidra/GhidraSessionRoot.js +39 -0
  339. package/dist/ghidra/extensions/GhidraExtensions.js +17 -10
  340. package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +8 -2
  341. package/dist/hopper/BridgeLauncher.js +34 -45
  342. package/dist/hopper/HopperAnalysisProfile.js +3 -8
  343. package/dist/hopper/HopperCleanup.js +56 -27
  344. package/dist/hopper/HopperClient.js +86 -65
  345. package/dist/hopper/HopperMachOImage.js +3 -2
  346. package/dist/hopper/HopperProvider.js +16 -18
  347. package/dist/hopper/HopperRegexSearch.js +3 -6
  348. package/dist/hopper/HopperTargetLease.js +132 -49
  349. package/dist/hopper/LinuxPrivateDisplayProbe.js +6 -0
  350. package/dist/ida/IdaConfiguration.js +8 -3
  351. package/dist/ida/IdaInput.js +1 -7
  352. package/dist/ida/IdaMcpConnection.js +8 -4
  353. package/dist/ida/IdaOperationRunner.js +3 -3
  354. package/dist/ida/IdaProvider.js +8 -12
  355. package/dist/ida/IdaSessionClient.js +20 -18
  356. package/dist/ida/IdaWorkspace.js +12 -13
  357. package/dist/inspector/V8InspectorCaptureProjection.js +1 -1
  358. package/dist/inspector/V8InspectorProvider.js +38 -28
  359. package/dist/javascript/recovery/WakaruCommand.js +7 -2
  360. package/dist/javascript/recovery/WakaruExecution.js +5 -2
  361. package/dist/main/shutdown.js +11 -3
  362. package/dist/main/startup.js +9 -2
  363. package/dist/main/transport.js +22 -2
  364. package/dist/main.js +11 -18
  365. package/dist/native/AppleMachoSelection.js +16 -6
  366. package/dist/native/CommandRunner.js +9 -7
  367. package/dist/native/LldbCallTracer.js +8 -2
  368. package/dist/native/NativeMacOSProvider.js +25 -15
  369. package/dist/native/NativeUiHelperRuntime.js +11 -2
  370. package/dist/native/NativeUiObservation.js +2 -2
  371. package/dist/native/pwntools/PwntoolsDecoder.js +2 -1
  372. package/dist/process/DarwinProcessRunTokenReader.js +16 -2
  373. package/dist/process/ExecFileOutput.js +88 -6
  374. package/dist/process/PrivateRuntimeRoot.js +10 -5
  375. package/dist/process/ProcessOwnership.js +1 -4
  376. package/dist/process/ProcessOwnershipObservation.js +11 -5
  377. package/dist/process/ProviderProcess.js +1 -3
  378. package/dist/process/capture/FilesystemSnapshot.js +50 -13
  379. package/dist/process/capture/ProcessCaptureError.js +13 -0
  380. package/dist/process/capture/ProcessCaptureLifecycle.js +158 -70
  381. package/dist/process/capture/ProcessFilesystemEffects.js +33 -3
  382. package/dist/process/capture/ProcessHarness.js +21 -25
  383. package/dist/process/capture/ProcessNormalization.js +20 -2
  384. package/dist/process/capture/ProcessSampling.js +25 -2
  385. package/dist/process/capture/TerminalRenderer.js +14 -0
  386. package/dist/process/snapshotEnvironment.js +14 -0
  387. package/dist/server/EvidenceMcpServer.js +25 -14
  388. package/dist/server/createServer.js +49 -36
  389. package/dist/server/mcpClientMetadata.js +12 -5
  390. package/dist/server/promptCompletion.js +3 -8
  391. package/dist/server/registerAnalysisViewTool.js +15 -0
  392. package/dist/server/registerAndroidTools.js +2 -3
  393. package/dist/server/registerApplicationTools/compareExportShapes.js +4 -5
  394. package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
  395. package/dist/server/registerApplicationTools/compareVersions.js +4 -5
  396. package/dist/server/registerApplicationTools/coverage.js +1 -2
  397. package/dist/server/registerApplicationTools/helpers.js +1 -2
  398. package/dist/server/registerApplicationTools/obligationLedger.js +4 -5
  399. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -4
  400. package/dist/server/registerApplicationTools/traceFeature.js +4 -5
  401. package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
  402. package/dist/server/registerArtifactComparisonTool.js +4 -5
  403. package/dist/server/registerBinaryDiagnosticsTools.js +2 -3
  404. package/dist/server/registerBrowserScenarioTool.js +3 -4
  405. package/dist/server/registerBrowserTools.js +13 -16
  406. package/dist/server/registerBundleComparisonTool.js +5 -6
  407. package/dist/server/registerCloseLifecycleTool.js +2 -3
  408. package/dist/server/registerElectronTools.js +10 -13
  409. package/dist/server/registerEnhancedTools.js +23 -23
  410. package/dist/server/registerEvidenceTools.js +3 -4
  411. package/dist/server/registerEvmTools.js +2 -3
  412. package/dist/server/registerFirmwareTools.js +2 -3
  413. package/dist/server/registerFunctionComparisonTool.js +7 -8
  414. package/dist/server/registerInvestigationTools.js +14 -15
  415. package/dist/server/registerJavaScriptRecoveryTool.js +2 -3
  416. package/dist/server/registerJavaScriptRuntimeObservationTools.js +6 -6
  417. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +5 -6
  418. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +4 -5
  419. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +6 -7
  420. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +6 -7
  421. package/dist/server/registerOfficialTools.js +4 -19
  422. package/dist/server/registerProcessComparisonTool.js +8 -8
  423. package/dist/server/registerRecordedCrashTools.js +2 -3
  424. package/dist/server/registerSessionRecordTools.js +15 -19
  425. package/dist/server/registerSessionStatusTool.js +3 -4
  426. package/dist/server/registerSessionTools.js +12 -18
  427. package/dist/server/registerWebModuleTool.js +2 -3
  428. package/dist/server/registerWebNetworkCaptureTool.js +2 -3
  429. package/dist/server/registerWebRuntimeTools.js +4 -5
  430. package/dist/server/registerWebScriptTool.js +2 -3
  431. package/dist/server/registerWebSourceLocationTool.js +2 -3
  432. package/dist/server/toolResult.js +66 -94
  433. package/dist/server/toolResultEncoding.js +11 -10
  434. package/dist/windows/WindowsNativeLoader.js +1 -0
  435. package/dist/windows/WindowsOwnedProcess.js +60 -15
  436. package/dist/windows/WindowsPrivateRuntime.js +7 -8
  437. package/native/windows/README.md +3 -1
  438. package/native/windows/build/manifest.json +2 -2
  439. package/native/windows/build/rea-windows-x64.node +0 -0
  440. package/package.json +39 -30
  441. package/scripts/rea.mjs +3 -6
  442. package/skills/reverse-engineer-anything/SKILL.md +9 -8
  443. package/skills/reverse-engineer-anything/references/android-applications.md +6 -3
  444. package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -4
  445. package/skills/reverse-engineer-anything/references/javascript-applications.md +16 -6
  446. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +9 -0
  447. package/dist/config.js +0 -1
  448. package/dist/contracts/browserCaptureToolInputSchema.js +0 -43
  449. package/dist/contracts/process/processCaptureExample.js +0 -2
  450. package/dist/contracts/toolOutputSchemas.js +0 -2
  451. package/dist/main/reload.js +0 -12
  452. package/dist/main/state.js +0 -3
  453. package/dist/server/sessionToolPolicies.js +0 -2
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <div align="center">
2
2
 
3
- **English** · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
3
+ **English** · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
4
4
 
5
5
  # REA: Reverse Engineer Anything
6
6
 
@@ -157,7 +157,7 @@ Additional tools and host support depend on the target:
157
157
  | Websites | Page structure, scripts, network observations and requested screenshots | A Chrome-family browser; [browser analysis](https://rea.tools/guides/browser/) |
158
158
  | Saved network captures | Requests, responses, exposed payloads and source locations | HAR; mitmdump on Linux for native mitmproxy captures; [capture guide](docs/web-network-captures.md) |
159
159
  | .NET assemblies | Metadata, CIL instructions, declared native dependencies and build comparisons | Static inspection; [managed-code guide](docs/managed-code-analysis.md) |
160
- | Android APKs | Manifest declarations, classes, decompiled methods and references | Headless JADX and a full JDK on Linux/macOS; [Android guide](docs/android-analysis.md) |
160
+ | Android APKs | Manifest declarations, classes, decompiled methods and references | Headless JADX and a full JDK on Linux/macOS/Windows x64; [Android guide](docs/android-analysis.md) |
161
161
  | Firmware | Regions, extraction results and native-analysis handoffs | Binwalk / Unblob on Linux; [firmware guide](docs/firmware-analysis.md) |
162
162
  | Packages and resources | File inventories, digests, plists, Apple bundle anatomy and extracted resources | [Artifact and JavaScript guide](docs/javascript-artifact-reconstruction.md), [Apple applications](docs/apple-application-analysis.md) |
163
163
  | Process behavior | Terminal output, interactions, exit and filesystem observations, and run comparisons | Linux/macOS with a native PTY; [process capture](docs/process-capture.md) |
@@ -298,7 +298,7 @@ For exact options, prerequisites and result contracts:
298
298
  - [Readiness and troubleshooting](docs/installation.md#check-readiness-for-your-task): diagnose one agent or analysis engine.
299
299
  - [CLI and Evidence](docs/cli.md): commands, provider selection, snapshots, import/export and exit statuses.
300
300
  - [MCP contracts](docs/mcp-contracts.md) and [agent prompts](docs/mcp-prompts.md): tool results, sessions and guided investigations.
301
- - [Tool catalog](docs/mcp-contracts.md#generated-catalog): build-generated inventory of tools, providers and CLI commands.
301
+ - [Tool catalog](docs/mcp-contracts.md#generated-catalog): generated inventory of tools, providers and CLI commands.
302
302
  - [Roadmap](docs/roadmap.md): planned work and capability trackers.
303
303
 
304
304
  Report vulnerabilities through [SECURITY.md](SECURITY.md).
@@ -319,9 +319,9 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and checks,
319
319
 
320
320
  ## Star history
321
321
 
322
- 🎉 **20,000 GitHub stars — thank you!**
322
+ 🎉 **30,000 GitHub stars — thank you!**
323
323
 
324
- Thanks to everyone using REA, reporting bugs, testing builds, and contributing fixes.
324
+ Thanks to everyone using REA, reporting bugs, requesting features, testing builds, and contributing fixes.
325
325
 
326
326
  <a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date">
327
327
  <picture>
@@ -335,6 +335,8 @@ Thanks to everyone using REA, reporting bugs, testing builds, and contributing f
335
335
 
336
336
  REA provides tools for lawful reverse-engineering research, analysis, and reconstruction. You are responsible for obtaining any required authorization and complying with applicable laws. The project does not endorse illegal or unauthorized use.
337
337
 
338
+ REA is an open-source software project. We have not issued or endorsed any cryptocurrency or token. Tokens using the REA name are not affiliated with the project.
339
+
338
340
  ## License
339
341
 
340
342
  [MIT](LICENSE)
@@ -866,6 +866,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
866
866
  JsonArray operands = new JsonArray();
867
867
  JsonArray references = new JsonArray();
868
868
  JsonArray destinations = new JsonArray();
869
+ JsonArray flowEvidence = new JsonArray();
869
870
  JsonObject flow = new JsonObject();
870
871
  flow.addProperty("kind", "unavailable");
871
872
  flow.addProperty("conditional", false);
@@ -881,7 +882,20 @@ public final class ReaGhidraBridge extends HeadlessScript {
881
882
  result.addProperty("mnemonic", instruction.getMnemonicString());
882
883
  result.addProperty("raw_disassembly", instruction.toString());
883
884
  RefType type = instruction.getFlowType();
884
- flow.addProperty("kind", type.isCall() ? "call" : type.isJump() ? "jump" : type.isTerminal() ? "terminal" : "fallthrough");
885
+ JsonObject listingFlow = new JsonObject();
886
+ listingFlow.addProperty("source", "ghidra-listing-flow-type");
887
+ listingFlow.addProperty("value", type.getName());
888
+ flowEvidence.add(listingFlow);
889
+ boolean decodedReturn = false;
890
+ for (PcodeOp operation : instruction.getPcode()) {
891
+ if (operation.getOpcode() != PcodeOp.RETURN) continue;
892
+ decodedReturn = true;
893
+ JsonObject returnEvidence = new JsonObject();
894
+ returnEvidence.addProperty("source", "ghidra-instruction-pcode");
895
+ returnEvidence.addProperty("value", operation.getMnemonic());
896
+ flowEvidence.add(returnEvidence);
897
+ }
898
+ flow.addProperty("kind", type.isCall() ? "call" : type.isJump() ? "jump" : decodedReturn ? "return" : type.isTerminal() ? "terminal" : "fallthrough");
885
899
  flow.addProperty("conditional", type.isConditional());
886
900
  flow.addProperty("computed", type.isComputed());
887
901
  if (!type.isComputed()) for (Address target : instruction.getFlows()) destinations.add(canonicalAddress(target));
@@ -917,10 +931,13 @@ public final class ReaGhidraBridge extends HeadlessScript {
917
931
  }
918
932
  }
919
933
  flow.add("direct_destinations", destinations);
934
+ flow.add("classification_evidence", flowEvidence);
920
935
  result.add("operands", operands);
921
936
  result.add("flow", flow);
922
937
  result.add("references", references);
923
- result.add("limitations", GSON.toJsonTree(List.of("Operand components are Ghidra Listing decoder tokens; effective memory base/index/displacement roles and per-instruction context mode are unavailable. The mode field is the program language variant.", "Terminal flow is not classified as a return without provider evidence.")));
938
+ List<String> limitations = new ArrayList<>(List.of("Operand components are Ghidra Listing decoder tokens; effective memory base/index/displacement roles and per-instruction context mode are unavailable. The mode field is the program language variant."));
939
+ if (flow.get("kind").getAsString().equals("terminal")) limitations.add("No RETURN operation was observed in the provider's instruction p-code; terminal classification remains generic.");
940
+ result.add("limitations", GSON.toJsonTree(limitations));
924
941
  return result;
925
942
  }
926
943
 
@@ -1629,9 +1646,20 @@ public final class ReaGhidraBridge extends HeadlessScript {
1629
1646
  Function function = entry.function;
1630
1647
  Symbol symbol = function.getSymbol();
1631
1648
  String qualified = symbol == null ? function.getName() : symbol.getName(true);
1632
- if (function.getName().equals(value) || qualified.equals(value)) {
1633
- matches.add(function);
1649
+ boolean matchesName = function.getName().equals(value) || qualified.equals(value);
1650
+ if (!matchesName) {
1651
+ // Imported labels (for example Mach-O _main) can share a
1652
+ // function entry without becoming its primary symbol. Only
1653
+ // exact entries qualify; an interior label is not a selector.
1654
+ for (Symbol entrySymbol : currentProgram.getSymbolTable().getSymbols(function.getEntryPoint())) {
1655
+ monitor.checkCancelled();
1656
+ if (entrySymbol.getName().equals(value) || entrySymbol.getName(true).equals(value)) {
1657
+ matchesName = true;
1658
+ break;
1659
+ }
1660
+ }
1634
1661
  }
1662
+ if (matchesName) matches.add(function);
1635
1663
  }
1636
1664
  if (matches.size() > 1)
1637
1665
  throw new RequestFailure("ambiguous", "Ghidra procedure name is ambiguous: " + value +
@@ -553,7 +553,12 @@ def _search_results(document, kind, params):
553
553
  if not matches(item[1]):
554
554
  continue
555
555
  selected.append(item)
556
- return [{"address": address, **_string_inventory(document)[address]} for address, _ in selected] if kind == "string" else [
556
+ if not selected:
557
+ return []
558
+ if kind == "string":
559
+ records = _string_inventory(document)
560
+ return [{"address": address, **records[address]} for address, _ in selected]
561
+ return [
557
562
  {
558
563
  "address": address,
559
564
  "value": value,
@@ -1,11 +1,16 @@
1
1
  import { constants } from "node:fs";
2
2
  import { access, realpath, stat } from "node:fs/promises";
3
- import { isAbsolute, join } from "node:path";
3
+ import { delimiter, isAbsolute, join, resolve } from "node:path";
4
+ import { systemWindowsNativeAuthority } from "../windows/WindowsNativeLoader.js";
4
5
  import { AnalysisCapabilityUnavailableError } from "../domain/analysisErrorCore.js";
6
+ import { ZipArtifactReader } from "../artifacts/ZipArtifactReader.js";
5
7
  import { execFileOutput, execFileOutputFailure, } from "../process/ExecFileOutput.js";
6
8
  import { JADX_JAR_CONFIGURATION_REMEDIATION } from "./JadxRelease.js";
7
9
  const JAVA_MODULE_LISTING_TIMEOUT_MS = 10_000;
8
10
  const JAVA_MODULE_LISTING_MAX_OUTPUT_BYTES = 1024 * 1024;
11
+ // Bound ZIP metadata allocation during discovery. The audited 0.7.1 JAR's
12
+ // central directory occupies 2,294,350 bytes; class bodies are not read here.
13
+ const JAR_METADATA_READ_MAX_BYTES = 8 * 1024 * 1024;
9
14
  class JadxConfigurationFailure extends Error {
10
15
  code;
11
16
  diagnostics;
@@ -74,16 +79,65 @@ export const resolveJadxConfiguration = async (environment, operation, signal) =
74
79
  const readJadxConfiguration = async (environment, signal) => {
75
80
  requireSupportedHost();
76
81
  const jar = await resolveJar(environment);
77
- const java = resolveJava(environment);
82
+ const java = await resolveJava(environment, signal);
78
83
  await requireJavaHomeExecutable(environment.JAVA_HOME, java);
79
84
  const jvmArguments = resolveJvmArguments(environment);
80
85
  await inspectJavaRuntime(java, environment, signal);
86
+ await requireEngineArchive(jar, signal);
81
87
  return { jar, java, jvmArguments };
82
88
  };
89
+ const requireEngineArchive = async (jar, signal) => {
90
+ // These classes are consumed directly by ReaJadxBridge.java. This checks the
91
+ // classpath inventory without loading engine code or starting a JADX session.
92
+ const missing = new Set([
93
+ "com/atxx/jhmcp/JadxSession.class",
94
+ "com/atxx/jhmcp/SessionHolder.class",
95
+ "jadx/api/JadxDecompiler.class",
96
+ "com/google/gson/Gson.class",
97
+ "io/modelcontextprotocol/kotlin/sdk/server/Server.class",
98
+ ]);
99
+ const reader = new ZipArtifactReader(jar, "zip", JAR_METADATA_READ_MAX_BYTES);
100
+ try {
101
+ for await (const entry of reader.entries(signal)) {
102
+ if (entry.kind === "file" && !entry.encrypted)
103
+ missing.delete(entry.path);
104
+ if (missing.size === 0)
105
+ return;
106
+ }
107
+ }
108
+ catch (cause) {
109
+ if (signal?.aborted === true)
110
+ throw cause;
111
+ const reason = cause instanceof Error ? cause.message : String(cause);
112
+ throw configurationFailure("version_unresolved", `Cannot inspect REA_JADX_MCP_JAR ${jar} as a Java archive: ${reason}. ${JADX_JAR_CONFIGURATION_REMEDIATION}`, {
113
+ jar_path: jar,
114
+ phase: "jar-inspection",
115
+ archive_error: reason,
116
+ maximum_metadata_read_bytes: JAR_METADATA_READ_MAX_BYTES,
117
+ }, cause);
118
+ }
119
+ finally {
120
+ await reader.close();
121
+ }
122
+ throw configurationFailure("unsupported_version", `REA_JADX_MCP_JAR ${jar} does not contain the required metadata bridge classes: ${[...missing].join(", ")}. ${JADX_JAR_CONFIGURATION_REMEDIATION}`, { jar_path: jar, phase: "jar-inspection", missing_classes: [...missing] });
123
+ };
83
124
  const requireSupportedHost = () => {
84
125
  if (process.platform === "linux" || process.platform === "darwin")
85
126
  return;
86
- throw configurationFailure("unsupported_host", `Android JADX subprocess ownership is unsupported on ${process.platform}; use Linux or macOS. The metadata bridge has real-provider verification on macOS arm64.`, { platform: process.platform });
127
+ if (process.platform === "win32" && process.arch === "x64") {
128
+ const loaded = systemWindowsNativeAuthority();
129
+ if (loaded.available && loaded.authority.inspection.protocolStdin === true)
130
+ return;
131
+ throw configurationFailure("runtime_missing", loaded.available
132
+ ? "The bundled Windows native artifact lacks owned protocol stdin; use a matching current Windows x64 REA package."
133
+ : loaded.reason, {
134
+ platform: process.platform,
135
+ architecture: process.arch,
136
+ phase: "process-ownership",
137
+ owned_protocol_stdin: false,
138
+ });
139
+ }
140
+ throw configurationFailure("unsupported_host", `Android JADX subprocess ownership is unsupported on ${process.platform}/${process.arch}; use Linux, macOS, or Windows x64 with its bundled native controls.`, { platform: process.platform });
87
141
  };
88
142
  const resolveJar = async (environment) => {
89
143
  const jar = environment.REA_JADX_MCP_JAR;
@@ -101,11 +155,37 @@ const resolveJar = async (environment) => {
101
155
  throw configurationFailure("executable_missing", `Cannot read REA_JADX_MCP_JAR ${jar}: ${cause instanceof Error ? cause.message : String(cause)}`, { jar_path: jar }, cause);
102
156
  }
103
157
  };
104
- const resolveJava = (environment) => {
105
- if (environment.JAVA_HOME === undefined)
106
- return "java";
158
+ const resolveJava = async (environment, signal) => {
159
+ const executable = process.platform === "win32" ? "java.exe" : "java";
160
+ if (environment.JAVA_HOME === undefined) {
161
+ if (process.platform !== "win32")
162
+ return executable;
163
+ const path = Object.entries(environment).find(([key]) => key.toLowerCase() === "path")?.[1] ?? "";
164
+ for (const directory of [process.cwd(), ...path.split(delimiter)]) {
165
+ signal?.throwIfAborted();
166
+ // Windows PATH commonly quotes individual entries containing spaces.
167
+ const selected = directory.startsWith('"') && directory.endsWith('"')
168
+ ? directory.slice(1, -1)
169
+ : directory;
170
+ const candidate = resolve(selected, executable);
171
+ try {
172
+ await access(candidate, constants.R_OK | constants.X_OK);
173
+ if ((await stat(candidate)).isFile())
174
+ return await realpath(candidate);
175
+ }
176
+ catch (cause) {
177
+ if (typeof cause === "object" &&
178
+ cause !== null &&
179
+ "code" in cause &&
180
+ (cause.code === "ENOENT" || cause.code === "ENOTDIR"))
181
+ continue;
182
+ throw configurationFailure("runtime_missing", `Cannot inspect selected Java executable ${candidate}: ${errorText(cause)}`, { java_executable: candidate }, cause);
183
+ }
184
+ }
185
+ throw configurationFailure("runtime_missing", "Cannot find java.exe on the selected Windows PATH. Select a full JDK with JAVA_HOME or PATH, then verify it with java --list-modules. REA does not install Java.", { java_executable: executable });
186
+ }
107
187
  if (isAbsolute(environment.JAVA_HOME))
108
- return join(environment.JAVA_HOME, "bin", "java");
188
+ return join(environment.JAVA_HOME, "bin", executable);
109
189
  throw configurationFailure("open_options_invalid", "JAVA_HOME must select an existing JDK by absolute path; omit it to use java on PATH.", { java_home: environment.JAVA_HOME });
110
190
  };
111
191
  const requireJavaHomeExecutable = async (javaHome, java) => {
@@ -1,5 +1,6 @@
1
1
  import { deserializeMessage, serializeMessage, } from "@modelcontextprotocol/client";
2
2
  import { randomUUID } from "node:crypto";
3
+ import { finished } from "node:stream/promises";
3
4
  import { ProviderProcessSupervisor, spawnOwnedProviderProcess, } from "../process/ProviderProcess.js";
4
5
  import { cleanupOwnedProcessGroup } from "../process/ProcessOwnership.js";
5
6
  import { ProviderCleanupError } from "../domain/providerCleanupError.js";
@@ -71,7 +72,10 @@ export class JadxMcpTransport {
71
72
  }
72
73
  /** Verifies owned process exit before declaring the transport closed. */
73
74
  close() {
74
- this.#closePromise ??= this.#stop();
75
+ this.#closePromise ??= this.#stop().catch((cause) => {
76
+ this.#closePromise = undefined;
77
+ throw cause;
78
+ });
75
79
  return this.#closePromise;
76
80
  }
77
81
  /** Captured provider stderr without persisting inherited environment values. */
@@ -102,8 +106,16 @@ export class JadxMcpTransport {
102
106
  process?.stderr?.off("data", this.#countStderr);
103
107
  process?.off("error", this.#error);
104
108
  process?.off("exit", this.#exit);
105
- process?.stdin?.off("error", this.#error);
109
+ const input = process?.stdin;
110
+ // A job termination can complete an in-flight pipe write asynchronously.
111
+ // Observe its errors until the owned Writable has finished closing.
112
+ const inputClosed = input === undefined || input === null
113
+ ? undefined
114
+ : finished(input, { readable: false, cleanup: true }).catch(() => undefined);
106
115
  const stopped = await this.#supervisor?.stop();
116
+ input?.destroy();
117
+ await inputClosed;
118
+ input?.off("error", this.#error);
107
119
  this.onclose?.();
108
120
  if (stopped?.status === "incomplete")
109
121
  throw new ProviderCleanupError("jadx", [this.runId], {
@@ -6,6 +6,7 @@ import { AnalysisError } from "../domain/analysisErrorBase.js";
6
6
  import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisOutputError, AnalysisInputError, AnalysisTimeoutError, } from "../domain/analysisErrorCore.js";
7
7
  import { ProviderAdapterError } from "../domain/providerAdapterError.js";
8
8
  import { ProviderCleanupError } from "../domain/providerCleanupError.js";
9
+ import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
9
10
  import { err, ok } from "../domain/result.js";
10
11
  import { PrivateRuntimeRoot } from "../process/PrivateRuntimeRoot.js";
11
12
  import { snapshotAndroidEngine, hashAndroidFile, snapshotAndroidTarget, } from "./AndroidTargetSnapshot.js";
@@ -59,14 +60,14 @@ const executionError = (context) => {
59
60
  },
60
61
  });
61
62
  };
62
- const cleanup = async (session, root, previous) => {
63
+ const cleanup = async (resources) => {
64
+ const { session, root, previousError } = resources;
63
65
  const diagnostics = {
64
- previous_error: previous.ok
65
- ? null
66
- : { tag: previous.error._tag, message: previous.error.message },
66
+ previous_error: previousError === undefined ? null : projectAnalysisError(previousError),
67
67
  };
68
68
  try {
69
69
  await session?.close();
70
+ resources.session = undefined;
70
71
  }
71
72
  catch (cause) {
72
73
  // Retain an uncertain workspace until the caller can resolve process ownership.
@@ -79,30 +80,31 @@ const cleanup = async (session, root, previous) => {
79
80
  provider_cleanup: cause instanceof ProviderCleanupError
80
81
  ? (cause.diagnostics ?? null)
81
82
  : null,
82
- }, { cause }));
83
+ }, { cause: previousError ?? cause }));
83
84
  }
84
85
  try {
85
86
  await root?.close();
87
+ resources.root = undefined;
86
88
  }
87
89
  catch (cause) {
88
90
  return err(new ProviderCleanupError("jadx", [root?.path ?? "unknown"], {
89
91
  ...diagnostics,
90
92
  reason: cause instanceof Error ? cause.message : String(cause),
91
- }, { cause }));
93
+ }, { cause: previousError ?? cause }));
92
94
  }
93
- return previous;
95
+ return ok(undefined);
94
96
  };
95
97
  /** One serialized, immutable APK session per REA instance, retired on idle or shutdown. */
96
98
  export class JadxProvider {
97
99
  environment;
98
100
  launcher;
99
101
  #tail = Promise.resolve();
100
- #cleanupFailure;
102
+ #pendingCleanup;
101
103
  #retained;
102
104
  #idle;
103
105
  #shutdown = new AbortController();
104
106
  #closePromise;
105
- constructor(environment = process.env, launcher) {
107
+ constructor(environment, launcher) {
106
108
  this.environment = environment;
107
109
  this.launcher = launcher;
108
110
  }
@@ -132,12 +134,13 @@ export class JadxProvider {
132
134
  try {
133
135
  if (signal.aborted)
134
136
  return err(new AnalysisCancelledError(request.operation));
135
- if (this.#cleanupFailure !== undefined)
136
- return err(this.#cleanupFailure);
137
137
  clearTimeout(this.#idle);
138
+ if (this.#pendingCleanup !== undefined) {
139
+ const retired = await this.#retire();
140
+ if (!retired.ok)
141
+ return retired;
142
+ }
138
143
  const outcome = await this.#execute(target, request, { signal });
139
- if (!outcome.ok && outcome.error.cleanupIncomplete)
140
- this.#cleanupFailure = outcome.error;
141
144
  if (outcome.ok)
142
145
  this.#scheduleIdle();
143
146
  return outcome;
@@ -150,24 +153,39 @@ export class JadxProvider {
150
153
  close() {
151
154
  this.#shutdown.abort();
152
155
  clearTimeout(this.#idle);
153
- this.#closePromise ??= this.#tail.then(() => this.#retire());
156
+ this.#closePromise ??= this.#tail
157
+ .then(async () => {
158
+ const retired = await this.#retire();
159
+ if (!retired.ok)
160
+ throw retired.error;
161
+ })
162
+ .catch((cause) => {
163
+ this.#closePromise = undefined;
164
+ throw cause;
165
+ });
154
166
  return this.#closePromise;
155
167
  }
156
168
  async #retire() {
157
- if (this.#cleanupFailure !== undefined)
158
- throw this.#cleanupFailure;
159
- const retained = this.#retained;
160
- this.#retained = undefined;
161
- const result = await cleanup(retained?.session, retained?.root, ok(undefined));
162
- if (!result.ok) {
163
- this.#cleanupFailure = result.error;
164
- throw result.error;
169
+ if (this.#pendingCleanup === undefined && this.#retained !== undefined) {
170
+ this.#pendingCleanup = {
171
+ session: this.#retained.session,
172
+ root: this.#retained.root,
173
+ previousError: undefined,
174
+ };
175
+ this.#retained = undefined;
165
176
  }
177
+ if (this.#pendingCleanup === undefined)
178
+ return ok(undefined);
179
+ const result = await cleanup(this.#pendingCleanup);
180
+ if (result.ok)
181
+ this.#pendingCleanup = undefined;
182
+ return result;
166
183
  }
167
184
  #scheduleIdle() {
168
185
  this.#idle = setTimeout(() => {
169
- const retirement = this.#tail.then(() => this.#retire());
170
- this.#tail = retirement.catch(() => undefined);
186
+ this.#tail = this.#tail.then(async () => {
187
+ await this.#retire();
188
+ });
171
189
  }, 60_000);
172
190
  this.#idle.unref();
173
191
  }
@@ -178,7 +196,6 @@ export class JadxProvider {
178
196
  : AbortSignal.any([options.signal, timeout]);
179
197
  let root;
180
198
  let session;
181
- let outcome;
182
199
  try {
183
200
  if (target.format !== "apk")
184
201
  throw new AnalysisCapabilityUnavailableError("jadx", request.operation, `Target ${target.path} is ${target.format}; provide one standalone APK.`);
@@ -210,8 +227,11 @@ export class JadxProvider {
210
227
  this.environment.JAVA_HOME,
211
228
  ],
212
229
  });
213
- if (this.#retained !== undefined && this.#retained.key !== key)
214
- await this.#retire();
230
+ if (this.#retained !== undefined && this.#retained.key !== key) {
231
+ const retired = await this.#retire();
232
+ if (!retired.ok)
233
+ return retired;
234
+ }
215
235
  let retained = this.#retained;
216
236
  if (retained === undefined) {
217
237
  root = await PrivateRuntimeRoot.create({ prefix: "rea-android-" });
@@ -247,7 +267,7 @@ export class JadxProvider {
247
267
  root = retained.root;
248
268
  session = retained.session;
249
269
  const { snapshot } = retained;
250
- outcome = ok(await session.execute({
270
+ const outcome = ok(await session.execute({
251
271
  request,
252
272
  target,
253
273
  snapshot,
@@ -260,18 +280,20 @@ export class JadxProvider {
260
280
  return outcome;
261
281
  }
262
282
  catch (cause) {
263
- outcome = err(executionError({
283
+ const previousError = executionError({
264
284
  cause,
265
285
  request,
266
286
  timeout,
267
287
  signal: options?.signal,
268
288
  session,
269
- }));
289
+ });
290
+ // Admission can fail before selecting an existing session for execution.
291
+ root ??= this.#retained?.root;
292
+ session ??= this.#retained?.session;
293
+ this.#retained = undefined;
294
+ this.#pendingCleanup = { session, root, previousError };
295
+ const retired = await this.#retire();
296
+ return retired.ok ? err(previousError) : retired;
270
297
  }
271
- // An existing session also needs retirement when admission fails before selection.
272
- root ??= this.#retained?.root;
273
- session ??= this.#retained?.session;
274
- this.#retained = undefined;
275
- return cleanup(session, root, outcome);
276
298
  }
277
299
  }
@@ -169,6 +169,9 @@ const readExecutableMetadata = async (handle, hostArchitecture) => {
169
169
  const prefix = Buffer.alloc(4096);
170
170
  const prefixRead = await handle.read(prefix, 0, prefix.length, 0);
171
171
  const bytes = prefix.subarray(0, prefixRead.bytesRead);
172
+ // Header commitments such as Mach-O load commands and FAT slices are
173
+ // checked against the whole file, not the probed prefix.
174
+ const fileSize = (await handle.stat()).size;
172
175
  if (bytes.length >= 2 && bytes[0] === 0x4d && bytes[1] === 0x5a) {
173
176
  const offset = mzWindowsHeaderOffset(bytes);
174
177
  if (offset !== null) {
@@ -182,7 +185,6 @@ const readExecutableMetadata = async (handle, hostArchitecture) => {
182
185
  ? bytes.readUInt16LE(24) + bytes.readUInt16LE(6) * 4
183
186
  : 0;
184
187
  const headerBytes = bytes.length >= 28 ? bytes.readUInt16LE(8) * 16 : 0;
185
- const fileSize = (await handle.stat()).size;
186
188
  if (tableEnd > bytes.length &&
187
189
  tableEnd <= headerBytes &&
188
190
  tableEnd <= fileSize) {
@@ -201,11 +203,11 @@ const readExecutableMetadata = async (handle, hostArchitecture) => {
201
203
  if (count <= 128 && required > bytes.length) {
202
204
  const header = Buffer.alloc(required);
203
205
  const headerRead = await handle.read(header, 0, header.length, 0);
204
- return parseExecutableHeader(header.subarray(0, headerRead.bytesRead), hostArchitecture);
206
+ return parseExecutableHeader(header.subarray(0, headerRead.bytesRead), hostArchitecture, fileSize);
205
207
  }
206
208
  }
207
209
  }
208
- return parseExecutableHeader(bytes, hostArchitecture);
210
+ return parseExecutableHeader(bytes, hostArchitecture, fileSize);
209
211
  };
210
212
  const readPeMetadata = async (handle, offset) => {
211
213
  const fileHeader = Buffer.alloc(24);
@@ -27,21 +27,16 @@ export const createBrowserEvidence = (operation, input, result, provider) => cre
27
27
  });
28
28
  const browserParameters = (input, result) => {
29
29
  if (!("cdp_endpoint" in input)) {
30
- if ("before_scenario" in input &&
31
- input.before_scenario !== undefined &&
32
- input.after_scenario !== undefined)
30
+ if ("before_scenario" in input)
33
31
  return {
34
32
  comparison_kind: "browser_scenario",
35
33
  before_browser: input.before_scenario.browser,
36
34
  after_browser: input.after_scenario.browser,
37
35
  before_start_origin: input.before_scenario.scenario.start_origin,
38
36
  after_start_origin: input.after_scenario.scenario.start_origin,
39
- normalization_sha256: commitBrowserScenarioNormalization(input.normalization ?? { rules: [] }).sha256,
37
+ normalization_sha256: commitBrowserScenarioNormalization(input.normalization).sha256,
40
38
  };
41
- if (input.before !== undefined &&
42
- input.after !== undefined &&
43
- "inspection" in input.before &&
44
- "inspection" in input.after)
39
+ if ("inspection" in input.before && "inspection" in input.after)
45
40
  return {
46
41
  before_target_id: input.before.inspection.target.target_id,
47
42
  before_capture_ended_at: input.before.inspection.capture_window.ended_at,
@@ -1,25 +1,9 @@
1
1
  import { canonicalDigest } from "../domain/comparisonSemantics.js";
2
- import { sanitizeBrowserUrl } from "../domain/browserObservation.js";
3
2
  import { createEvidence, } from "../domain/evidence.js";
4
- import { jsonValueSchema } from "../domain/jsonValue.js";
3
+ import { jsonObjectSchema, jsonValueSchema } from "../domain/jsonValue.js";
5
4
  const browserScenarioParameters = (scenario) => ({
5
+ ...jsonObjectSchema.parse(scenario),
6
6
  scenario_sha256: canonicalDigest(scenario, "Browser scenario"),
7
- browser_mode: scenario.browser.mode,
8
- ...(scenario.browser.mode === "launch"
9
- ? { browser_headless: scenario.browser.headless }
10
- : {}),
11
- start_url: sanitizeBrowserUrl(scenario.start_url.url),
12
- environment: scenario.environment,
13
- actions: scenario.actions.map(({ step_id, action }) => ({
14
- step_id,
15
- action,
16
- })),
17
- action_timeouts_ms: scenario.actions.map((item) => "timeout_ms" in item ? (item.timeout_ms ?? null) : null),
18
- secret_declarations: scenario.secrets.map(({ secret_id, environment_variable }) => ({
19
- secret_id,
20
- environment_variable,
21
- })),
22
- capture: scenario.capture,
23
7
  });
24
8
  /** Create Evidence without retaining resolved scenario secret values. */
25
9
  export const createBrowserScenarioEvidence = (scenario, capture, provider) => createEvidence(undefined, provider, {