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
@@ -37,6 +37,21 @@ const ENHANCED_REQUIREMENTS = {
37
37
  "resolve_containing_procedure",
38
38
  ],
39
39
  };
40
+ /** Contract kinds whose operations run on the active session target. */
41
+ const ACTIVE_TARGET_KINDS = new Set([
42
+ "official-proxy",
43
+ "enhanced",
44
+ "native-provider",
45
+ "artifact-provider",
46
+ ]);
47
+ /** Native contracts defined only for an active Mach-O executable. */
48
+ const MACHO_TARGET_OPERATIONS = new Set([
49
+ "inspect_macho",
50
+ "list_architectures",
51
+ "observe_native_calls",
52
+ "observe_native_ui",
53
+ "capture_native_ui_scenario",
54
+ ]);
40
55
  const NAVIGATION_CONTEXT_MODES = [
41
56
  {
42
57
  name: "current_selection",
@@ -61,6 +76,7 @@ export const buildCapabilityInventory = (sessionStatus, policy, clientFeatures =
61
76
  kind: contract.kind,
62
77
  targetOpen: status.open,
63
78
  targetKind: status.kind,
79
+ targetFormat: status.format,
64
80
  descriptors,
65
81
  policy,
66
82
  });
@@ -125,6 +141,9 @@ const availabilityFor = (context) => {
125
141
  const workflowAvailability = workflowAvailabilityFor(context);
126
142
  if (workflowAvailability !== null)
127
143
  return workflowAvailability;
144
+ const hostDecision = hostAvailability(context);
145
+ if (hostDecision !== null)
146
+ return hostDecision;
128
147
  const targetDecision = targetAvailability(context);
129
148
  if (targetDecision !== null)
130
149
  return targetDecision;
@@ -226,7 +245,7 @@ const workflowAvailabilityFor = ({ name, kind, policy, }) => {
226
245
  ? "unsupported_host"
227
246
  : "provider_missing",
228
247
  remediation: policy.androidAnalysisAvailability?.reason ??
229
- "Set REA_JADX_MCP_JAR to a caller-supplied jadx-headless-mcp 0.7.1 JAR and provide a full JDK on Linux or macOS.",
248
+ "Set REA_JADX_MCP_JAR to a caller-supplied jadx-headless-mcp 0.7.1 JAR and provide a full JDK on Linux, macOS, or Windows x64 with its matching bundled native controls.",
230
249
  };
231
250
  const browser = browserProviderAvailability(name, kind, policy);
232
251
  if (browser !== null)
@@ -286,8 +305,22 @@ const browserProviderAvailability = (name, kind, policy) => {
286
305
  remediation: "Start REA with its browser observation provider available.",
287
306
  };
288
307
  };
289
- const targetAvailability = ({ kind, targetKind, targetOpen, }) => {
290
- if (!targetOpen && (kind === "official-proxy" || kind === "enhanced"))
308
+ /**
309
+ * Opening another target cannot make an operation run on an unsupported host.
310
+ * Composed operations are decided by their requirements, which another
311
+ * provider may satisfy.
312
+ */
313
+ const hostAvailability = ({ descriptors, kind, name, }) => {
314
+ if (kind === "enhanced")
315
+ return null;
316
+ const descriptor = descriptors.get(name);
317
+ return descriptor?.available === false &&
318
+ descriptor.availability_code === "unsupported_host"
319
+ ? { reason: "unsupported_host", remediation: descriptor.reason }
320
+ : null;
321
+ };
322
+ const targetAvailability = ({ name, kind, targetKind, targetFormat, targetOpen, }) => {
323
+ if (!targetOpen && ACTIVE_TARGET_KINDS.has(kind))
291
324
  return {
292
325
  reason: "target_required",
293
326
  remediation: "Call open_binary with a supported local target.",
@@ -300,6 +333,13 @@ const targetAvailability = ({ kind, targetKind, targetOpen, }) => {
300
333
  reason: "target_unsupported",
301
334
  remediation: "Inventory or extract a native executable, then call open_binary on that executable.",
302
335
  };
336
+ if (targetOpen &&
337
+ MACHO_TARGET_OPERATIONS.has(name) &&
338
+ (targetKind !== "executable" || targetFormat !== "mach-o"))
339
+ return {
340
+ reason: "target_unsupported",
341
+ remediation: "Call open_binary with a Mach-O executable or an app bundle whose main executable is Mach-O.",
342
+ };
303
343
  return null;
304
344
  };
305
345
  const providerAvailability = ({ descriptors, kind, name, }) => {
@@ -316,12 +356,6 @@ const providerAvailability = ({ descriptors, kind, name, }) => {
316
356
  reason: "provider_missing",
317
357
  remediation: "Install or configure a provider that declares this operation.",
318
358
  };
319
- if (!descriptor.available &&
320
- descriptor.availability_code === "unsupported_host")
321
- return {
322
- reason: "unsupported_host",
323
- remediation: descriptor.reason,
324
- };
325
359
  return descriptor.available
326
360
  ? { reason: "available", remediation: null }
327
361
  : {
@@ -302,7 +302,7 @@ const isBlankOrComment = (line) => {
302
302
  };
303
303
  const looksLikeTomlHeader = (line) => line.trimStart().startsWith("[");
304
304
  /** `mcp_servers.<server>` and tables nested under it, compared by key segment. */
305
- const isGrokServerTable = (path, serverKey) => path[0] === "mcp_servers" && path[1] === serverKey;
305
+ const isTomlServerTable = (path, serverKey) => path[0] === "mcp_servers" && path[1] === serverKey;
306
306
  const parseKeyPath = (text, start) => {
307
307
  const segments = [];
308
308
  let index = start;
@@ -486,7 +486,7 @@ const hasSeparatorComma = (trivia) => trivia.split("\n").some((part) => {
486
486
  * Replace or remove `serverKey` inside one `{ ... }` table. A closed inline
487
487
  * table cannot later grow a `[mcp_servers.rea]` header.
488
488
  */
489
- const editGrokInlineTable = (table, serverKey, entry) => {
489
+ const editInlineServerTable = (table, serverKey, entry) => {
490
490
  if (!table.startsWith("{"))
491
491
  return undefined;
492
492
  const end = endOfContainer(table, 0);
@@ -667,10 +667,12 @@ const disabledServerListLines = (edit, lines, lineIndex, endLine) => {
667
667
  }
668
668
  };
669
669
  /**
670
- * Replace REA's Grok server tables and assignments. Comments that introduce a
671
- * following table stay. Text inside strings is not treated as a header.
670
+ * Replace REA's TOML server tables and assignments. Comments that introduce a
671
+ * following table stay. Codex also retains comments around REA's own table.
672
+ * Text inside strings is not treated as a header. Only Grok Build reads the
673
+ * root `disabled_mcp_servers` list that registration also edits.
672
674
  */
673
- const upsertGrokServerSection = (originalText, serverKey, entry) => {
675
+ const upsertTomlServerSection = (originalText, serverKey, entry, format) => {
674
676
  // smol-toml accepts a leading BOM. Leave it in place or the first header is missed.
675
677
  const bom = originalText.startsWith("\uFEFF");
676
678
  const source = bom ? originalText.slice(1) : originalText;
@@ -721,7 +723,7 @@ const upsertGrokServerSection = (originalText, serverKey, entry) => {
721
723
  const header = parseTomlTableHeader(line);
722
724
  if (header !== undefined) {
723
725
  tablePath = header.path;
724
- if (isGrokServerTable(header.path, serverKey)) {
726
+ if (isTomlServerTable(header.path, serverKey)) {
725
727
  discardPending();
726
728
  skipping = true;
727
729
  lineIndex += 1;
@@ -748,17 +750,19 @@ const upsertGrokServerSection = (originalText, serverKey, entry) => {
748
750
  mode = "none";
749
751
  continue;
750
752
  }
751
- const disabledLines = disabledServerListLines(disabledServerListEdit({
752
- text,
753
- lineStart,
754
- valueOffset,
755
- valueEnd,
756
- statementEnd,
757
- tablePath,
758
- segments: assignment.segments,
759
- serverKey,
760
- entry,
761
- }), lines, lineIndex, endLine);
753
+ const disabledLines = format === "grok"
754
+ ? disabledServerListLines(disabledServerListEdit({
755
+ text,
756
+ lineStart,
757
+ valueOffset,
758
+ valueEnd,
759
+ statementEnd,
760
+ tablePath,
761
+ segments: assignment.segments,
762
+ serverKey,
763
+ entry,
764
+ }), lines, lineIndex, endLine)
765
+ : undefined;
762
766
  if (disabledLines !== undefined) {
763
767
  flushPending();
764
768
  kept.push(...disabledLines);
@@ -771,10 +775,10 @@ const upsertGrokServerSection = (originalText, serverKey, entry) => {
771
775
  const closesServerTable = absolute.length === 1 &&
772
776
  absolute[0] === "mcp_servers" &&
773
777
  text[open] === "{";
774
- if (closesServerTable || isGrokServerTable(absolute, serverKey)) {
778
+ if (closesServerTable || isTomlServerTable(absolute, serverKey)) {
775
779
  if (closesServerTable) {
776
780
  flushPending();
777
- const edited = editGrokInlineTable(text.slice(open, valueEnd), serverKey, entry);
781
+ const edited = editInlineServerTable(text.slice(open, valueEnd), serverKey, entry);
778
782
  const prefix = text.slice(lineStart, open);
779
783
  const suffix = text.slice(valueEnd, statementEnd);
780
784
  const replacement = edited === undefined
@@ -796,7 +800,12 @@ const upsertGrokServerSection = (originalText, serverKey, entry) => {
796
800
  continue;
797
801
  }
798
802
  if (isBlankOrComment(line)) {
799
- pending.push(physical);
803
+ if (format === "toml" && line.trimStart().startsWith("#")) {
804
+ flushPending();
805
+ kept.push(physical);
806
+ }
807
+ else
808
+ pending.push(physical);
800
809
  lineIndex += 1;
801
810
  continue;
802
811
  }
@@ -840,7 +849,7 @@ const upsertGrokServerSection = (originalText, serverKey, entry) => {
840
849
  }
841
850
  return bom ? `\uFEFF${body}` : body;
842
851
  };
843
- const grokServerEntry = (document, serverKey) => {
852
+ const tomlServerEntry = (document, serverKey) => {
844
853
  const servers = objectSchema.safeParse(document.mcp_servers);
845
854
  if (!servers.success || !Object.hasOwn(servers.data, serverKey))
846
855
  return undefined;
@@ -851,10 +860,45 @@ export const grokServerListedDisabled = (document, serverKey) => Array.isArray(d
851
860
  document.disabled_mcp_servers.includes(serverKey);
852
861
  /** Keep an existing Grok document intact aside from the REA server tables. */
853
862
  const serializeGrokConfiguration = (document, originalText) => {
854
- const entry = grokServerEntry(document, PRODUCT_IDENTITY.mcpServerKey);
863
+ const entry = tomlServerEntry(document, PRODUCT_IDENTITY.mcpServerKey);
855
864
  if (originalText === undefined)
856
865
  return stringifyToml(document);
857
- return upsertGrokServerSection(originalText, PRODUCT_IDENTITY.mcpServerKey, entry);
866
+ return upsertTomlServerSection(originalText, PRODUCT_IDENTITY.mcpServerKey, entry, "grok");
867
+ };
868
+ /** Removing the last server leaves an empty table, which equals an absent one. */
869
+ const withoutEmptyServerTable = (document) => {
870
+ const servers = objectSchema.safeParse(document.mcp_servers);
871
+ if (!servers.success || Object.keys(servers.data).length > 0)
872
+ return document;
873
+ const { mcp_servers: empty, ...rest } = document;
874
+ void empty;
875
+ return rest;
876
+ };
877
+ /**
878
+ * Keep an existing Codex document intact aside from the REA server tables.
879
+ * An edit that would change any other parsed value falls back to a full
880
+ * rewrite, which keeps every value but not comments or spelling.
881
+ */
882
+ const serializeCodexConfiguration = (document, originalText) => {
883
+ if (originalText === undefined ||
884
+ isEmptyClientConfigurationText(originalText))
885
+ return stringifyToml(document);
886
+ const upserted = upsertTomlServerSection(originalText, PRODUCT_IDENTITY.mcpServerKey, tomlServerEntry(document, PRODUCT_IDENTITY.mcpServerKey), "toml");
887
+ // Removing a final table also drops the file's last line break.
888
+ const edited = originalText.endsWith("\n") && !upserted.endsWith("\n")
889
+ ? `${upserted}${originalText.endsWith("\r\n") ? "\r\n" : "\n"}`
890
+ : upserted;
891
+ return tomlTextHolds(edited, document) ? edited : stringifyToml(document);
892
+ };
893
+ const tomlTextHolds = (text, document) => {
894
+ try {
895
+ return clientConfigurationValuesEqual(withoutEmptyServerTable(objectSchema.parse(parseToml(text))), withoutEmptyServerTable(document));
896
+ }
897
+ catch (cause) {
898
+ // An unparsable edit is rejected in favor of the full rewrite.
899
+ void cause;
900
+ return false;
901
+ }
858
902
  };
859
903
  /** Comments in the trivia between two properties. `undefined` when there are none. */
860
904
  const commentsBetweenProperties = (gap) => {
@@ -952,12 +996,12 @@ const deleteJsonPropertyPreservingComments = (text, path) => {
952
996
  suffix += "\n";
953
997
  return `${text.slice(0, previous.offset + previous.length)}${suffix}${remainder}`;
954
998
  };
955
- /** Serialize a validated client document, retaining JSONC comments. */
999
+ /** Serialize a validated client document, retaining JSONC and TOML comments. */
956
1000
  export const serializeClientConfiguration = (document, format, originalText, editedPaths) => {
957
1001
  if (format === undefined || format === "unsupported")
958
1002
  throw new TypeError("client does not have a supported MCP config format");
959
1003
  if (format === "toml")
960
- return stringifyToml(document);
1004
+ return serializeCodexConfiguration(document, originalText);
961
1005
  if (format === "grok")
962
1006
  return serializeGrokConfiguration(document, originalText);
963
1007
  // An empty original holds no comments or settings to preserve. Writing a
@@ -1,4 +1,3 @@
1
- import { parseConfig } from "../config.js";
2
1
  import { EnhancedTools } from "./EnhancedTools.js";
3
2
  import { executeFunctionAnalysisEvidence } from "./FunctionAnalysisEvidence.js";
4
3
  import { silentLogger } from "../logger.js";
@@ -15,6 +14,9 @@ import { err, ok } from "../domain/result.js";
15
14
  import { REA_WORKFLOW_PROVIDER, workflowAnalysisProfile, } from "./InvestigationProviders.js";
16
15
  import { createWorkflowEvidence, workflowSnapshotRecord, recordWorkflowUnknowns, } from "./WorkflowEvidence.js";
17
16
  import { artifactInspectionResultSchema } from "../domain/artifactInspection.js";
17
+ import { resolveXrefsAddress } from "./XrefsAddressResolution.js";
18
+ import { AnalysisInputError } from "../domain/analysisErrorCore.js";
19
+ import { directAnalysisCleanupFailure, managedAnalysisCleanupFailure, withSessionCleanup, } from "./DirectAnalysisCleanup.js";
18
20
  /**
19
21
  * Open one binary, execute one tool, and always release provider resources.
20
22
  * Unlike MCP mode, every CLI invocation is intentionally isolated and does not
@@ -42,15 +44,12 @@ export const runProviderAnalysis = async (dependencies, ...[path, tool, argument
42
44
  /** Execute managed metadata inspection in an isolated managed-only session. */
43
45
  export const runManagedProviderExecution = async (dependencies, path, tool, signal) => withProcessCancellation(signal, async (operationSignal) => {
44
46
  const session = dependencies.createManagedBinarySession();
45
- try {
47
+ return withSessionCleanup(session, async () => {
46
48
  const opened = await session.open(path, { signal: operationSignal });
47
49
  if (!opened.ok)
48
50
  return opened;
49
51
  return await session.execute(tool, {}, { signal: operationSignal });
50
- }
51
- finally {
52
- await session.close();
53
- }
52
+ }, managedAnalysisCleanupFailure);
54
53
  });
55
54
  const runManagedProviderAnalysis = async (dependencies, path, tool, signal) => {
56
55
  const execution = await runManagedProviderExecution(dependencies, path, tool, signal);
@@ -68,11 +67,11 @@ const runManagedProviderAnalysis = async (dependencies, path, tool, signal) => {
68
67
  };
69
68
  const runAnalysis = async (dependencies, path, tool, arguments_, options) => {
70
69
  const { logger, signal, snapshotPath } = options;
71
- const config = parseConfig(options.environment ?? process.env);
70
+ const config = dependencies.readConfiguration();
72
71
  if (!config.ok)
73
72
  return cliError(config.error);
74
73
  const session = dependencies.createBinarySession(config.value, logger);
75
- try {
74
+ return withSessionCleanup(session, async () => {
76
75
  const prepared = await prepareSnapshot({
77
76
  path,
78
77
  snapshotPath,
@@ -180,10 +179,7 @@ const runAnalysis = async (dependencies, path, tool, arguments_, options) => {
180
179
  return cliError(written.error);
181
180
  }
182
181
  return output;
183
- }
184
- finally {
185
- await session.close();
186
- }
182
+ }, directAnalysisCleanupFailure);
187
183
  };
188
184
  const executeAnalysisTool = async (input) => {
189
185
  const { session, tool, signal, evidenceProfile } = input;
@@ -211,7 +207,22 @@ const executeAnalysisTool = async (input) => {
211
207
  });
212
208
  return { output: evidence, evidence };
213
209
  }
214
- const result = await session.execute(tool, input.arguments, { signal });
210
+ let result = await session.execute(tool, input.arguments, { signal });
211
+ if (tool === "xrefs" &&
212
+ typeof input.arguments.address === "string" &&
213
+ !result.ok &&
214
+ result.error instanceof AnalysisInputError &&
215
+ !result.error.cleanupIncomplete &&
216
+ result.error.issues.length > 0 &&
217
+ result.error.issues.every(({ path, reason }) => path.length === 1 &&
218
+ path[0] === "address" &&
219
+ reason === "invalid_format")) {
220
+ const address = await resolveXrefsAddress(session, input.arguments.address, signal);
221
+ if (!address.ok)
222
+ return { output: cliError(address.error) };
223
+ if (address.value !== input.arguments.address)
224
+ result = await session.execute(tool, { ...input.arguments, address: address.value }, { signal });
225
+ }
215
226
  if (!result.ok)
216
227
  return { output: cliError(result.error) };
217
228
  const evidence = createEvidence(result.value.subject ?? input.openedTarget, result.value.provider, {
@@ -236,12 +247,16 @@ const withProcessCancellation = async (suppliedSignal, operation) => {
236
247
  return operation(suppliedSignal);
237
248
  const controller = new AbortController();
238
249
  const cancel = () => controller.abort();
239
- process.once("SIGINT", cancel);
250
+ // Package runners can forward a terminal interrupt after REA already received
251
+ // it directly. Keep both guards installed until provider cleanup has settled.
252
+ process.on("SIGINT", cancel);
253
+ process.on("SIGTERM", cancel);
240
254
  try {
241
255
  return await operation(controller.signal);
242
256
  }
243
257
  finally {
244
258
  process.off("SIGINT", cancel);
259
+ process.off("SIGTERM", cancel);
245
260
  }
246
261
  };
247
262
  const prepareSnapshot = async (options) => {
@@ -0,0 +1,72 @@
1
+ import { analysisErrorProjectionSchema } from "../contracts/errorSchemas.js";
2
+ import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
3
+ import { jsonValueSchema } from "../domain/jsonValue.js";
4
+ import { ProviderAdapterError } from "../domain/providerAdapterError.js";
5
+ import { err } from "../domain/result.js";
6
+ import { analysisErrorWithCleanupFailure } from "./binary/AnalysisClientCleanup.js";
7
+ /** Await one-shot cleanup and retain either the outcome or both failures. */
8
+ export const withSessionCleanup = async (session, operation, onCleanupFailure) => {
9
+ let value;
10
+ try {
11
+ value = await operation();
12
+ }
13
+ catch (cause) {
14
+ const closed = await session.close();
15
+ if (!closed.ok)
16
+ throw new AggregateError([cause, closed.error], "Analysis and provider cleanup both failed", { cause });
17
+ throw cause;
18
+ }
19
+ const closed = await session.close();
20
+ return closed.ok ? value : onCleanupFailure(value, closed.error);
21
+ };
22
+ /** Keep the primary CLI failure or completed Evidence alongside cleanup failure. */
23
+ export const directAnalysisCleanupFailure = (output, error) => {
24
+ const cleanup = projectAnalysisError(error);
25
+ if (typeof output === "object" && output !== null && !Array.isArray(output)) {
26
+ const { error: label, ...projection } = output;
27
+ const primary = analysisErrorProjectionSchema.safeParse(projection);
28
+ if (typeof label === "string" && primary.success)
29
+ return {
30
+ error: label,
31
+ ...primary.data,
32
+ code: "cleanup_incomplete",
33
+ retryable: false,
34
+ details: {
35
+ ...primary.data.details,
36
+ cleanup: "incomplete",
37
+ resources: error.cleanupResources.slice(),
38
+ execution_failure: primary.data.details !== undefined &&
39
+ "execution_failure" in primary.data.details
40
+ ? (primary.data.details.execution_failure ?? primary.data.code)
41
+ : primary.data.code,
42
+ primary_error: projection,
43
+ cleanup_error: cleanup,
44
+ },
45
+ };
46
+ }
47
+ return {
48
+ error: "Analysis failed",
49
+ ...cleanup,
50
+ code: "cleanup_incomplete",
51
+ retryable: false,
52
+ details: {
53
+ ...cleanup.details,
54
+ cleanup: "incomplete",
55
+ partial_observation: output,
56
+ },
57
+ };
58
+ };
59
+ /** Preserve managed observations or the original typed failure in diagnostics. */
60
+ export const managedAnalysisCleanupFailure = (result, error) => {
61
+ if (!result.ok)
62
+ return err(analysisErrorWithCleanupFailure(result.error, error));
63
+ const cleanup = projectAnalysisError(error);
64
+ return err(new ProviderAdapterError(error instanceof ProviderAdapterError ? error.providerId : "rea", "close_binary", {
65
+ cause: error,
66
+ cleanup: { reason: cleanup.message, resources: error.cleanupResources },
67
+ diagnostics: {
68
+ cleanup_error: cleanup,
69
+ partial_observation: jsonValueSchema.parse(result.value),
70
+ },
71
+ }));
72
+ };
@@ -1,10 +1,9 @@
1
- import { parseConfig } from "../config.js";
2
1
  import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
3
2
  import { jsonObjectSchema } from "../domain/jsonValue.js";
4
3
  import { createServerIdentity } from "../serverIdentity.js";
5
4
  import { silentLogger } from "../logger.js";
6
- const runSessionStatus = async (dependencies, logger = silentLogger, environment = process.env) => {
7
- const config = parseConfig(environment);
5
+ const runSessionStatus = async (dependencies, logger = silentLogger) => {
6
+ const config = dependencies.readConfiguration();
8
7
  if (!config.ok)
9
8
  return { error: projectAnalysisError(config.error) };
10
9
  const session = dependencies.createBinarySession(config.value, logger);
@@ -21,6 +20,6 @@ const runSessionStatus = async (dependencies, logger = silentLogger, environment
21
20
  }
22
21
  };
23
22
  /** List binary-session provider candidates and auxiliary operation availability. */
24
- export const runProviderStatus = (dependencies, logger = silentLogger, environment = process.env) => runSessionStatus(dependencies, logger, environment);
23
+ export const runProviderStatus = (dependencies, logger = silentLogger) => runSessionStatus(dependencies, logger);
25
24
  /** List binary-session operation descriptors; this is not the full MCP catalog. */
26
- export const runCapabilityStatus = (dependencies, logger = silentLogger, environment = process.env) => runSessionStatus(dependencies, logger, environment);
25
+ export const runCapabilityStatus = (dependencies, logger = silentLogger) => runSessionStatus(dependencies, logger);
@@ -1,11 +1,11 @@
1
1
  import { constants } from "node:fs";
2
2
  import { access, readFile, readdir } from "node:fs/promises";
3
- import { homedir } from "node:os";
4
- import { delimiter, join } from "node:path";
3
+ import { homeDirectoryFromEnvironment } from "../config/homeDirectory.js";
4
+ import { join } from "node:path";
5
5
  import { analysisErrorRemediationAction } from "../domain/analysisErrorPresentation.js";
6
6
  import { parseBinaryTarget } from "./BinaryTargetResolver.js";
7
7
  import { execFileOutput } from "../process/ExecFileOutput.js";
8
- import { probeHomebrew } from "./homebrew.js";
8
+ import { installedCaskAppdir, probeHomebrew } from "./homebrew.js";
9
9
  import { linuxHopperBinarySupported, linuxSharedLibrariesAvailable, readLinuxDistribution, } from "./LinuxHopper.js";
10
10
  import { canonicalSkillNeedsInstall } from "./SetupSkill.js";
11
11
  import { CATALOG_IDENTITY } from "../catalogIdentity.js";
@@ -115,23 +115,13 @@ const registrationCheck = (registration) => ({
115
115
  remediation: registration.remediation,
116
116
  });
117
117
  const installationState = (paths) => paths.length === 0 ? "unknown" : paths.length === 1 ? "single" : "multiple";
118
- const homeFromEnvironment = (environment, platform) => {
119
- const selected = platform === "win32"
120
- ? (environment.USERPROFILE ??
121
- (environment.HOMEDRIVE !== undefined &&
122
- environment.HOMEPATH !== undefined
123
- ? `${environment.HOMEDRIVE}${environment.HOMEPATH}`
124
- : environment.HOME))
125
- : (environment.HOME ?? environment.USERPROFILE);
126
- return selected ?? homedir();
127
- };
128
118
  /** Create diagnostics backed by the current process and host commands. */
129
119
  export const systemDoctorHost = (options = {}) => {
130
120
  const platform = options.platform ?? process.platform;
131
121
  const architecture = options.architecture ?? process.arch;
132
122
  const environment = options.environment ?? process.env;
133
123
  const hostExecFileOutput = options.execFileOutput ?? execFileOutput;
134
- const homeDirectory = homeFromEnvironment(environment, platform);
124
+ const homeDirectory = homeDirectoryFromEnvironment(environment, platform);
135
125
  const commandEnvironment = { env: environment };
136
126
  return {
137
127
  platform,
@@ -180,15 +170,21 @@ export const systemDoctorHost = (options = {}) => {
180
170
  supportedLinuxHopper: linuxHopperBinarySupported,
181
171
  async brewHopperPath() {
182
172
  return probeHomebrew(async (command) => {
173
+ let caskroom;
183
174
  try {
184
- const prefix = (await hostExecFileOutput(command, ["--prefix", "--cask", "hopper-disassembler"], commandEnvironment)).stdout.trim();
185
- return `${prefix}/Hopper Disassembler.app/Contents/MacOS/hopper`;
175
+ // Without a cask argument, `--caskroom` does not load Homebrew's
176
+ // cask API, so doctor writes no Homebrew cache files.
177
+ caskroom = (await hostExecFileOutput(command, ["--caskroom"], commandEnvironment)).stdout.trim();
186
178
  }
187
179
  catch (cause) {
188
180
  // best-effort cleanup: optional Homebrew probing; absence means uninstalled.
189
181
  void cause;
190
182
  return undefined;
191
183
  }
184
+ const appdir = await installedCaskAppdir(caskroom, "hopper-disassembler", homeDirectory);
185
+ return appdir === undefined
186
+ ? undefined
187
+ : join(appdir, "Hopper Disassembler.app/Contents/MacOS/hopper");
192
188
  });
193
189
  },
194
190
  manualHopperPaths: () => manualHopperPaths(homeDirectory),
@@ -229,7 +225,7 @@ export const systemDoctorHost = (options = {}) => {
229
225
  }),
230
226
  };
231
227
  };
232
- const readMacosVersion = async (run = execFileOutput, options = { env: process.env }) => {
228
+ const readMacosVersion = async (run, options) => {
233
229
  try {
234
230
  return (await run("sw_vers", ["-productVersion"], options)).stdout.trim();
235
231
  }
@@ -239,7 +235,7 @@ const readMacosVersion = async (run = execFileOutput, options = { env: process.e
239
235
  return undefined;
240
236
  }
241
237
  };
242
- const executableAvailable = async (path, platform = process.platform, run = execFileOutput, options = { env: process.env }) => {
238
+ const executableAvailable = async (path, platform, run, options) => {
243
239
  try {
244
240
  await access(path, constants.X_OK);
245
241
  if (platform !== "linux")
@@ -260,7 +256,7 @@ const uncomposedLinuxDemoRuntimeCheck = () => Promise.resolve({
260
256
  detail: "Linux Hopper private-display diagnostics were not composed",
261
257
  remediation: "Run rea doctor through the production CLI adapter.",
262
258
  });
263
- const manualHopperPaths = async (home = homedir()) => {
259
+ const manualHopperPaths = async (home) => {
264
260
  const paths = [];
265
261
  for (const root of ["/Applications", join(home, "Applications")]) {
266
262
  try {
@@ -1,4 +1,3 @@
1
- import { homedir } from "node:os";
2
1
  import { SUPPORTED_NODE_VERSION_PROSE, supportsNodeVersion, } from "../domain/runtimeVersion.js";
3
2
  import { linuxHopperLauncherPath } from "./LinuxHopper.js";
4
3
  const DEFAULT_HOPPER = "/Applications/Hopper Disassembler.app/Contents/MacOS/hopper";
@@ -75,7 +74,7 @@ const findHopper = async (host) => {
75
74
  ? [
76
75
  DEFAULT_HOPPER,
77
76
  SYSTEM_LINUX_HOPPER,
78
- linuxHopperLauncherPath(host.homeDirectory ?? homedir()),
77
+ linuxHopperLauncherPath(host.homeDirectory),
79
78
  ...(await host.manualHopperPaths()),
80
79
  ]
81
80
  : [host.configuredHopperPath];