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
@@ -4,13 +4,11 @@ import { BrowserObservationError } from "../domain/browserObservationError.js";
4
4
  import { ProviderAdapterError } from "../domain/providerAdapterError.js";
5
5
  import {} from "../domain/browserObservationErrors.js";
6
6
  import { err, ok } from "../domain/result.js";
7
- import { numberValue, recordValue, cdpStringValue, delayWithCancellation, } from "../browser/CdpCaptureValues.js";
7
+ import { numberValue, recordValue, cdpStringValue, scriptMetadataValues, delayWithCancellation, } from "../browser/CdpCaptureValues.js";
8
8
  import { CdpConnection } from "../browser/CdpConnection.js";
9
9
  import { authorizeRuntimeTargetLocation, inspectorExclusionKey, } from "./JavaScriptRuntimeScope.js";
10
10
  import { createInspectorExclusionCounts, describeInspectorTargetLimitations, finalizeInspectorCapture, } from "./V8InspectorCaptureProjection.js";
11
11
  import { discoverV8Inspector, } from "./V8InspectorEndpoint.js";
12
- /** Public identity committed by passive V8 Inspector observations. */
13
- export { V8_INSPECTOR_PROVIDER_IDENTITY } from "./providerIdentity.js";
14
12
  import { V8_INSPECTOR_PROVIDER_IDENTITY } from "./providerIdentity.js";
15
13
  /** Maximum decoded CDP message accepted while observing one Inspector target. */
16
14
  export const INSPECTOR_MAX_PAYLOAD_BYTES = 16 * 1024 * 1024;
@@ -68,7 +66,7 @@ export class V8InspectorProvider {
68
66
  assertRuntimeKind(target, input.runtime_kind);
69
67
  connection = await CdpConnection.connect(target.webSocketUrl, "observe_javascript_runtime", options.signal, { maxPayloadBytes: INSPECTOR_MAX_PAYLOAD_BYTES });
70
68
  const state = emptyCaptureState();
71
- const removeListener = connection.onEvent((event) => ingestEvent(event, input, state));
69
+ const removeListener = connection.onEvent((event) => ingestEvent(event, state));
72
70
  try {
73
71
  await connection.send("Runtime.enable", {}, undefined, options.signal);
74
72
  await connection.send("Debugger.enable", {}, undefined, options.signal);
@@ -102,7 +100,11 @@ export class V8InspectorProvider {
102
100
  }
103
101
  }
104
102
  if (cleanupFailed) {
105
- return err(inspectorCleanupError(primaryFailure, cleanupFailure, failed));
103
+ return err(inspectorCleanupError(primaryFailure, cleanupFailure, failed, outcome?.ok === true
104
+ ? outcome.value
105
+ : outcome?.ok === false
106
+ ? outcome.error.partialObservation
107
+ : undefined));
106
108
  }
107
109
  return (outcome ??
108
110
  err(new BrowserObservationError("observe_javascript_runtime", "protocol_error")));
@@ -132,11 +134,21 @@ export const closeInspectorConnection = async (connection, signal) => {
132
134
  signal.removeEventListener("abort", onAbort);
133
135
  }
134
136
  };
135
- export const inspectorCleanupError = (primaryFailure, cleanupFailure, hasPrimaryFailure) => {
137
+ export const inspectorCleanupError = (primaryFailure, cleanupFailure, hasPrimaryFailure, partialObservation) => {
136
138
  const cause = hasPrimaryFailure
137
139
  ? new AggregateError([primaryFailure, cleanupFailure], "Inspector observation and cleanup both failed")
138
140
  : cleanupFailure;
139
- return new BrowserObservationError("observe_javascript_runtime", "cleanup_failed", { cause });
141
+ const cleanupReason = cleanupFailure instanceof Error
142
+ ? cleanupFailure.message
143
+ : String(cleanupFailure);
144
+ return new BrowserObservationError("observe_javascript_runtime", "cleanup_failed", {
145
+ cause,
146
+ cleanup: {
147
+ reason: cleanupReason,
148
+ resources: ["browser_transport"],
149
+ },
150
+ ...(partialObservation === undefined ? {} : { partialObservation }),
151
+ });
140
152
  };
141
153
  const projectTarget = (target) => ({
142
154
  target_id: target.id,
@@ -177,7 +189,7 @@ const emptyCaptureState = () => ({
177
189
  truncated: false,
178
190
  truncationReasons: new Set(),
179
191
  });
180
- const ingestEvent = (event, input, state) => {
192
+ const ingestEvent = (event, state) => {
181
193
  if (event.method !== "Debugger.scriptParsed" &&
182
194
  event.method !== "Debugger.scriptFailedToParse" &&
183
195
  event.method !== "Runtime.executionContextCreated" &&
@@ -186,7 +198,7 @@ const ingestEvent = (event, input, state) => {
186
198
  return;
187
199
  state.eventsObserved += 1;
188
200
  if (event.method === "Debugger.scriptParsed") {
189
- ingestScript(event, input, state);
201
+ ingestScript(event, state);
190
202
  return;
191
203
  }
192
204
  if (event.method === "Debugger.scriptFailedToParse") {
@@ -194,9 +206,9 @@ const ingestEvent = (event, input, state) => {
194
206
  retainEvent(state, 0);
195
207
  return;
196
208
  }
197
- ingestContext(event, input, state);
209
+ ingestContext(event, state);
198
210
  };
199
- const ingestScript = (event, input, state) => {
211
+ const ingestScript = (event, state) => {
200
212
  state.scriptsObserved += 1;
201
213
  const value = recordValue(event.params);
202
214
  const rawUrl = cdpStringValue(value?.url);
@@ -205,19 +217,20 @@ const ingestScript = (event, input, state) => {
205
217
  retainEvent(state, 0);
206
218
  return;
207
219
  }
220
+ const metadata = scriptMetadataValues(value);
208
221
  const draft = {
209
222
  rawUrl,
210
223
  executionContextKey: contextKey(value?.executionContextId),
211
- cdpHash: cdpStringValue(value?.hash) ?? null,
212
- length: nonnegativeInteger(value?.length),
213
- isModule: value?.isModule === true,
224
+ cdpHash: metadata.hash,
225
+ length: metadata.length,
226
+ isModule: metadata.isModule,
214
227
  };
215
228
  const bytes = retainedMetadataBytes(draft);
216
229
  if (!retainEvent(state, bytes))
217
230
  return;
218
231
  state.scripts.push(draft);
219
232
  };
220
- const ingestContext = (event, input, state) => {
233
+ const ingestContext = (event, state) => {
221
234
  if (event.method === "Runtime.executionContextsCleared") {
222
235
  let byteDelta = 0;
223
236
  for (const context of state.contexts.values()) {
@@ -243,17 +256,18 @@ const ingestContext = (event, input, state) => {
243
256
  retainEvent(state, 0);
244
257
  return;
245
258
  }
246
- const origin = event.method === "Runtime.executionContextCreated"
247
- ? (cdpStringValue(runtimeContext?.origin) ?? null)
248
- : null;
259
+ const previous = state.contexts.get(key);
260
+ const created = event.method === "Runtime.executionContextCreated";
249
261
  const draft = {
250
262
  contextKey: key,
251
- state: event.method === "Runtime.executionContextCreated"
252
- ? "created"
253
- : "destroyed",
254
- origin: origin === "" ? null : origin,
263
+ state: created ? "created" : "destroyed",
264
+ name: created
265
+ ? (cdpStringValue(runtimeContext?.name) ?? null)
266
+ : (previous?.name ?? null),
267
+ origin: created
268
+ ? (cdpStringValue(runtimeContext?.origin) ?? null)
269
+ : (previous?.origin ?? null),
255
270
  };
256
- const previous = state.contexts.get(key);
257
271
  const bytes = retainedMetadataBytes(draft) -
258
272
  (previous === undefined ? 0 : retainedMetadataBytes(previous));
259
273
  if (!retainEvent(state, bytes))
@@ -294,14 +308,10 @@ const waitForCapture = async (connection, observationMs, signal) => {
294
308
  const retainedMetadataBytes = (value) => {
295
309
  const strings = "rawUrl" in value
296
310
  ? [value.rawUrl, value.rawUrl, value.executionContextKey, value.cdpHash]
297
- : [value.contextKey, value.origin];
311
+ : [value.contextKey, value.name, value.origin];
298
312
  return (RETAINED_OBJECT_OVERHEAD_BYTES +
299
313
  strings.reduce((total, text) => total + (text?.length ?? 0) * 2, 0));
300
314
  };
301
- const nonnegativeInteger = (value) => {
302
- const parsed = numberValue(value);
303
- return parsed === undefined ? 0 : Math.max(0, Math.trunc(parsed));
304
- };
305
315
  const contextKey = (value) => {
306
316
  const identifier = numberValue(value);
307
317
  return identifier !== undefined && Number.isSafeInteger(identifier)
@@ -10,6 +10,7 @@ import { ProviderProcessSupervisor, spawnOwnedProviderProcess, } from "../../pro
10
10
  import { checkRecoveryDeadline, inventoryRecoveryFiles, fingerprintRecoveryFile, recoveryFailureMessage, } from "./RecoveryFiles.js";
11
11
  import { RECOVERY_LIMITS } from "./WakaruRelease.js";
12
12
  const OPERATION = "recover_javascript_sources";
13
+ const WAKARU_REQUIREMENT = "Provide an absolute REA_WAKARU_COMMAND pointing to Wakaru 1.13.0 on Linux x64; no tool is installed by REA";
13
14
  /** Resolve and fingerprint explicitly configured tools; acquire nothing at startup. */
14
15
  export const resolveWakaruCommand = async (environment) => {
15
16
  const configured = environment.REA_WAKARU_COMMAND;
@@ -17,7 +18,7 @@ export const resolveWakaruCommand = async (environment) => {
17
18
  process.arch !== "x64" ||
18
19
  configured === undefined ||
19
20
  !isAbsolute(configured))
20
- throw new AnalysisCapabilityUnavailableError("wakaru", OPERATION, "Provide an absolute REA_WAKARU_COMMAND pointing to Wakaru 1.13.0 on Linux x64; no tool is installed by REA");
21
+ throw new AnalysisCapabilityUnavailableError("wakaru", OPERATION, WAKARU_REQUIREMENT, { userMessage: WAKARU_REQUIREMENT });
21
22
  try {
22
23
  const command = await realpath(configured);
23
24
  await access(command, constants.R_OK | constants.X_OK);
@@ -29,7 +30,11 @@ export const resolveWakaruCommand = async (environment) => {
29
30
  return { command, limiter, ...fingerprint };
30
31
  }
31
32
  catch (cause) {
32
- throw new AnalysisCapabilityUnavailableError("wakaru", OPERATION, `Configured Wakaru or util-linux prlimit is unavailable: ${recoveryFailureMessage(cause)}`, { cause });
33
+ const reason = `Configured Wakaru or util-linux prlimit is unavailable: ${recoveryFailureMessage(cause)}`;
34
+ throw new AnalysisCapabilityUnavailableError("wakaru", OPERATION, reason, {
35
+ cause,
36
+ userMessage: reason,
37
+ });
33
38
  }
34
39
  };
35
40
  /** Run one bounded command and verify cleanup before consuming its output. */
@@ -30,8 +30,11 @@ const executeWakaruRecovery = async (context) => {
30
30
  arguments: ["--version"],
31
31
  });
32
32
  if (version.exit_code !== 0 ||
33
- version.stdout.trim() !== `wakaru ${WAKARU_RELEASE.version}`)
34
- throw new AnalysisCapabilityUnavailableError("wakaru", OPERATION, `This adapter requires Wakaru ${WAKARU_RELEASE.version}; reported version: ${version.stdout.trim()}; exit: ${String(version.exit_code)}; stderr: ${version.stderr}`);
33
+ version.stdout.trim() !== `wakaru ${WAKARU_RELEASE.version}`) {
34
+ // The message names the mismatch; the reason also keeps the tool's stderr.
35
+ const mismatch = `This adapter requires Wakaru ${WAKARU_RELEASE.version}; reported version: ${version.stdout.trim()}; exit: ${String(version.exit_code)}`;
36
+ throw new AnalysisCapabilityUnavailableError("wakaru", OPERATION, `${mismatch}; stderr: ${version.stderr}`, { userMessage: `${mismatch}.` });
37
+ }
35
38
  const run = await runWakaruCommand({
36
39
  ...commandContext,
37
40
  staging,
@@ -1,16 +1,20 @@
1
+ import { AnalysisError } from "../domain/analysisErrorBase.js";
2
+ import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
1
3
  import { MCP_SHUTDOWN_FAILED } from "./messages.js";
2
4
  export const createShutdown = (input) => {
3
- const { handle, session, unregisterReload, dependencies, serverLogger } = input;
5
+ const { handle, session, dependencies, serverLogger } = input;
4
6
  let shutdownPromise;
5
7
  let unregisterShutdown = () => undefined;
6
8
  const shutdown = async () => {
7
9
  shutdownPromise ??= (async () => {
8
- unregisterReload();
9
10
  unregisterShutdown();
10
11
  const results = await Promise.allSettled([
11
12
  handle.close(),
12
13
  input.closeAndroid?.(),
13
- session.close({ retainProviderDocuments: true }),
14
+ session.close({ retainProviderDocuments: true }).then((closed) => {
15
+ if (!closed.ok)
16
+ throw closed.error;
17
+ }),
14
18
  ]);
15
19
  for (const result of results)
16
20
  if (result.status === "rejected")
@@ -24,12 +28,16 @@ export const createShutdown = (input) => {
24
28
  dependencies.setExitCode(1);
25
29
  serverLogger.error(MCP_SHUTDOWN_FAILED);
26
30
  dependencies.writeStderr(`${MCP_SHUTDOWN_FAILED}\n`);
31
+ if (cause instanceof AnalysisError)
32
+ dependencies.writeStderr(`${projectAnalysisError(cause).message}\n`);
27
33
  });
28
34
  };
29
35
  unregisterShutdown = dependencies.registerShutdown(requestShutdown);
30
36
  return { shutdown, request: requestShutdown };
31
37
  };
32
38
  const describeShutdownFailure = (cause) => {
39
+ if (cause instanceof AnalysisError)
40
+ return { analysis_error: projectAnalysisError(cause) };
33
41
  if (cause instanceof Error) {
34
42
  const code = "code" in cause ? cause.code : undefined;
35
43
  return {
@@ -7,8 +7,15 @@ export const openInitialTarget = async (session, config, serverLogger, writeStde
7
7
  });
8
8
  if (opened.ok)
9
9
  return { ok: true };
10
- await session.close();
11
- serverLogger.error({ errorTag: opened.error._tag }, "Initial target failed to open");
10
+ const closed = await session.close();
11
+ serverLogger.error({
12
+ error: projectAnalysisError(opened.error),
13
+ ...(closed.ok
14
+ ? {}
15
+ : { cleanup_error: projectAnalysisError(closed.error) }),
16
+ }, "Initial target failed to open");
12
17
  writeStderr(`${projectAnalysisError(opened.error).message}\n`);
18
+ if (!closed.ok)
19
+ writeStderr(`${projectAnalysisError(closed.error).message}\n`);
13
20
  return { ok: false, exitCode: 1 };
14
21
  };
@@ -1,5 +1,6 @@
1
1
  import { createAndroidAnalysisProvider } from "../composition/android.js";
2
2
  import { createServer } from "../server/createServer.js";
3
+ import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
3
4
  import { MCP_CONNECTION_LOST, MCP_CONNECTION_START_FAILED, } from "./messages.js";
4
5
  export const startMcpTransport = async (dependencies, session, serverContext) => {
5
6
  const { serverLogger } = serverContext;
@@ -26,10 +27,12 @@ export const startMcpTransport = async (dependencies, session, serverContext) =>
26
27
  try {
27
28
  handle = dependencies.serve(() => {
28
29
  // The SDK can discard a discovery probe and construct a replacement server.
29
- const android = createAndroidAnalysisProvider(dependencies.env);
30
+ const android = createAndroidAnalysisProvider(serverContext.environment);
30
31
  androidProviders.push(android);
31
32
  return (dependencies.createServer ?? createServer)(session, session, {
32
33
  logger: serverContext.logger,
34
+ environment: serverContext.environment,
35
+ delivery: serverContext.delivery,
33
36
  ...optionalProviders,
34
37
  androidAnalysis: android,
35
38
  });
@@ -41,11 +44,28 @@ export const startMcpTransport = async (dependencies, session, serverContext) =>
41
44
  });
42
45
  }
43
46
  catch (cause) {
44
- await Promise.allSettled([session.close(), closeAndroid()]);
47
+ const [binaryCleanup, androidCleanup] = await Promise.allSettled([
48
+ session.close(),
49
+ closeAndroid(),
50
+ ]);
45
51
  serverLogger.error({
46
52
  error: cause instanceof Error ? cause.message : String(cause),
47
53
  }, MCP_CONNECTION_START_FAILED);
48
54
  dependencies.writeStderr(`${MCP_CONNECTION_START_FAILED}\n`);
55
+ if (binaryCleanup.status === "fulfilled" && !binaryCleanup.value.ok) {
56
+ const cleanupError = projectAnalysisError(binaryCleanup.value.error);
57
+ serverLogger.error({ cleanup_error: cleanupError }, "Binary provider cleanup failed after MCP startup");
58
+ dependencies.writeStderr(`${cleanupError.message}\n`);
59
+ }
60
+ for (const cleanup of [binaryCleanup, androidCleanup]) {
61
+ if (cleanup.status === "rejected") {
62
+ const reason = cleanup.reason instanceof Error
63
+ ? cleanup.reason.message
64
+ : String(cleanup.reason);
65
+ serverLogger.error({ cleanup_error: reason }, "Provider cleanup rejected after MCP startup");
66
+ dependencies.writeStderr(`Provider cleanup failed: ${reason}\n`);
67
+ }
68
+ }
49
69
  return { ok: false };
50
70
  }
51
71
  return { ok: true, handle, closeAndroid };
package/dist/main.js CHANGED
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
+ import { snapshotEnvironment } from "./process/snapshotEnvironment.js";
2
3
  import { pathToFileURL } from "node:url";
3
4
  import { realpathSync } from "node:fs";
4
5
  import { serveStdio } from "@modelcontextprotocol/server/stdio";
5
- import { parseConfig } from "./config.js";
6
+ import { parseConfig } from "./config/parseConfig.js";
6
7
  import { createBinarySession } from "./composition/binary.js";
7
8
  import { createLogger } from "./logger.js";
8
9
  import { projectAnalysisError } from "./domain/analysisErrorProjection.js";
9
10
  import { SERVER_START_FAILED } from "./main/messages.js";
10
- import { createRuntimeState } from "./main/state.js";
11
11
  import { openInitialTarget } from "./main/startup.js";
12
12
  import { startMcpTransport } from "./main/transport.js";
13
- import { loadOptionalObservationProviders } from "./composition/optionalObservationProviders.js";
14
- import { registerConfigReload } from "./main/reload.js";
13
+ import { createOptionalObservationFactories, loadOptionalObservationProviders, } from "./composition/optionalObservationProviders.js";
14
+ import { createToolResultDelivery } from "./server/toolResult.js";
15
15
  import { createShutdown } from "./main/shutdown.js";
16
16
  const runtimeDependencies = () => ({
17
17
  env: process.env,
@@ -32,10 +32,6 @@ const runtimeDependencies = () => ({
32
32
  process.stdin.off("close", handler);
33
33
  };
34
34
  },
35
- registerReload: (handler) => {
36
- process.on("SIGHUP", handler);
37
- return () => process.off("SIGHUP", handler);
38
- },
39
35
  });
40
36
  /**
41
37
  * Start the long-lived MCP adapter and install idempotent shutdown handlers.
@@ -43,35 +39,32 @@ const runtimeDependencies = () => ({
43
39
  * signals close bridge resources without assuming ownership of the Hopper app.
44
40
  */
45
41
  export const run = async (dependencies = runtimeDependencies()) => {
46
- const config = parseConfig(dependencies.env);
42
+ const environment = snapshotEnvironment(dependencies.env);
43
+ const config = parseConfig(environment);
47
44
  if (!config.ok) {
48
45
  dependencies.writeStderr(`${projectAnalysisError(config.error).message}\n`);
49
46
  return 1;
50
47
  }
51
48
  const logger = createLogger("mcp", config.value.logLevel);
52
49
  const serverLogger = logger.child({ layer: "server" });
53
- const session = createBinarySession(config.value, logger);
50
+ const session = createBinarySession(config.value, logger, environment);
54
51
  const opened = await openInitialTarget(session, config.value, serverLogger, dependencies.writeStderr);
55
52
  if (!opened.ok)
56
53
  return opened.exitCode;
57
- const runtimeState = createRuntimeState(config.value);
58
54
  const transport = await startMcpTransport(dependencies, session, {
59
55
  logger,
60
56
  serverLogger,
61
- loadOptionalProviders: dependencies.loadOptionalProviders ?? loadOptionalObservationProviders,
57
+ environment,
58
+ delivery: createToolResultDelivery(config.value.mcpMaxResponseBytes),
59
+ loadOptionalProviders: dependencies.loadOptionalProviders ??
60
+ (() => loadOptionalObservationProviders(createOptionalObservationFactories(environment))),
62
61
  });
63
62
  if (!transport.ok)
64
63
  return 1;
65
- const unregisterReload = registerConfigReload({
66
- dependencies,
67
- runtimeState,
68
- serverLogger,
69
- });
70
64
  createShutdown({
71
65
  handle: transport.handle,
72
66
  closeAndroid: transport.closeAndroid,
73
67
  session,
74
- unregisterReload,
75
68
  dependencies,
76
69
  serverLogger,
77
70
  });
@@ -182,9 +182,14 @@ const collectFixupCommand = (bytes, { cursor, kind, size }, state) => {
182
182
  throw new RangeError("Fixup data exceeds the Mach-O slice");
183
183
  return { offset, size: length };
184
184
  };
185
- if (kind === LC_DYLD_CHAINED_FIXUPS && size >= 16)
185
+ if (kind === LC_DYLD_CHAINED_FIXUPS) {
186
+ if (size < 16)
187
+ throw new RangeError("Truncated chained-fixups command");
186
188
  state.chained = range(cursor + 8);
187
- else if ((kind === LC_DYLD_INFO || kind === LC_DYLD_INFO_ONLY) && size >= 48)
189
+ }
190
+ else if (kind === LC_DYLD_INFO || kind === LC_DYLD_INFO_ONLY) {
191
+ if (size < 48)
192
+ throw new RangeError("Truncated dyld-info command");
188
193
  for (const [at, stream] of [
189
194
  [cursor + 16, "bind"],
190
195
  [cursor + 24, "weak"],
@@ -194,11 +199,16 @@ const collectFixupCommand = (bytes, { cursor, kind, size }, state) => {
194
199
  if (bound.size > 0)
195
200
  state.binds.push({ ...bound, stream });
196
201
  }
197
- else if (DYLIB_COMMANDS.includes(kind) && size >= 24) {
202
+ }
203
+ else if (DYLIB_COMMANDS.includes(kind)) {
204
+ if (size < 24)
205
+ throw new RangeError("Truncated dylib command");
198
206
  const nameOffset = bytes.readUInt32LE(cursor + 8);
207
+ if (nameOffset < 24 || nameOffset >= size)
208
+ throw new RangeError("Dylib install name is outside its load command");
199
209
  const end = bytes.indexOf(0, cursor + nameOffset);
200
- state.dylibs.push(nameOffset >= size || end < 0 || end > cursor + size
201
- ? ""
202
- : bytes.toString("utf8", cursor + nameOffset, end));
210
+ if (end < 0 || end >= cursor + size)
211
+ throw new RangeError("Unterminated dylib install name");
212
+ state.dylibs.push(bytes.toString("utf8", cursor + nameOffset, end));
203
213
  }
204
214
  };
@@ -1,3 +1,4 @@
1
+ import { snapshotEnvironment } from "../process/snapshotEnvironment.js";
1
2
  import { createHash, randomUUID } from "node:crypto";
2
3
  import { createReadStream } from "node:fs";
3
4
  import { realpath } from "node:fs/promises";
@@ -28,8 +29,10 @@ export class NativeCommandFailure extends Error {
28
29
  /** Run allowlisted Xcode tools directly without a shell. */
29
30
  export class XcrunCommandRunner {
30
31
  resolveTool;
31
- constructor(resolveTool = (tool, signal) => resolveXcrunTool(tool, signal)) {
32
+ environment;
33
+ constructor(environment, resolveTool = (tool, signal) => resolveXcrunTool(tool, this.environment, signal)) {
32
34
  this.resolveTool = resolveTool;
35
+ this.environment = snapshotEnvironment(environment);
33
36
  }
34
37
  run(tool, arguments_, options) {
35
38
  if (!ALLOWED_TOOLS.has(tool))
@@ -37,7 +40,7 @@ export class XcrunCommandRunner {
37
40
  return this.resolveTool(tool, options.signal).then(async (resolved) => {
38
41
  if (!resolved.ok)
39
42
  return resolved;
40
- const captured = await captureProcess(resolved.value.path, arguments_, tool, options);
43
+ const captured = await captureProcess(resolved.value.path, arguments_, tool, options, this.environment);
41
44
  return captured.ok
42
45
  ? ok({
43
46
  ...captured.value,
@@ -66,8 +69,8 @@ const ALLOWED_TOOLS = new Set([
66
69
  "vtool",
67
70
  ]);
68
71
  /** Locate an Xcode tool through `xcrun --find` and sample its executable digest. */
69
- export const resolveXcrunTool = async (tool, signal) => {
70
- const found = await captureProcess("/usr/bin/xcrun", ["--find", tool], "xcrun", signal === undefined ? {} : { signal });
72
+ export const resolveXcrunTool = async (tool, environment, signal) => {
73
+ const found = await captureProcess("/usr/bin/xcrun", ["--find", tool], "xcrun", signal === undefined ? {} : { signal }, environment);
71
74
  if (!found.ok) {
72
75
  return err(new NativeCommandFailure(tool, found.error.reason === "nonzero-exit" ||
73
76
  found.error.reason === "unavailable"
@@ -99,7 +102,7 @@ const failureCapture = (capture, truncated) => ({
99
102
  signal: capture.signal,
100
103
  truncated,
101
104
  });
102
- const captureProcess = async (executable, arguments_, tool, options) => {
105
+ const captureProcess = async (executable, arguments_, tool, options, environment) => {
103
106
  const runId = `rea-native-command-${randomUUID()}`;
104
107
  try {
105
108
  const snapshot = await runOwnedCommand({
@@ -107,11 +110,10 @@ const captureProcess = async (executable, arguments_, tool, options) => {
107
110
  arguments: [...arguments_],
108
111
  runId,
109
112
  env: {
110
- PATH: "/usr/bin:/bin:/usr/sbin:/sbin",
111
113
  LC_ALL: "C",
112
114
  LANG: "C",
113
115
  },
114
- hostEnvironment: {},
116
+ hostEnvironment: environment,
115
117
  ...(options.signal === undefined ? {} : { signal: options.signal }),
116
118
  }, {
117
119
  timeoutMs: NATIVE_COMMAND_TIMEOUT_MS,
@@ -1,3 +1,4 @@
1
+ import { snapshotEnvironment } from "../process/snapshotEnvironment.js";
1
2
  import { randomUUID } from "node:crypto";
2
3
  import { open, readFile, writeFile } from "node:fs/promises";
3
4
  import { join } from "node:path";
@@ -18,6 +19,7 @@ import { resolveXcrunTool } from "./CommandRunner.js";
18
19
  import { readLldbObservationJournal, readBoundedPrefix, readPartialCapture, projectLldbPartialObservation, } from "./LldbRetainedObservations.js";
19
20
  const OPERATION = "observe_native_calls";
20
21
  const PROVIDER = "native-macos";
22
+ const LLDB_REQUIREMENT = "LLDB from Xcode or the Command Line Tools is not available";
21
23
  /** Captured target output kept per stream; the rest is counted, not stored. */
22
24
  const MAX_OUTPUT_BYTES = 1024 * 1024;
23
25
  /** LLDB startup, symbol loading and teardown beyond the observation window. */
@@ -90,16 +92,18 @@ const ATTACH_REMEDIATION = "Allow debugging for this user (Developer Tools acces
90
92
  export class LldbCallTracer {
91
93
  launch;
92
94
  resolveTool;
93
- constructor(launch = runLldb, resolveTool = resolveXcrunTool) {
95
+ environment;
96
+ constructor(environment, launch = runLldb, resolveTool = (tool, signal) => resolveXcrunTool(tool, this.environment, signal)) {
94
97
  this.launch = launch;
95
98
  this.resolveTool = resolveTool;
99
+ this.environment = snapshotEnvironment(environment);
96
100
  }
97
101
  async trace(request, signal) {
98
102
  const lldb = await this.resolveTool("lldb", signal);
99
103
  if (!lldb.ok)
100
104
  return err(lldb.error.reason === "cancelled"
101
105
  ? new AnalysisCancelledError(OPERATION)
102
- : new AnalysisCapabilityUnavailableError(PROVIDER, OPERATION, "LLDB from Xcode or the Command Line Tools is not available"));
106
+ : new AnalysisCapabilityUnavailableError(PROVIDER, OPERATION, LLDB_REQUIREMENT, { userMessage: LLDB_REQUIREMENT }));
103
107
  const root = await PrivateRuntimeRoot.create({ prefix: "rea-lldb-" });
104
108
  try {
105
109
  return await this.#run(lldb.value, root.path, request, signal);
@@ -158,6 +162,7 @@ export class LldbCallTracer {
158
162
  deadlineMs: input.duration_ms + DEADLINE_GRACE_MS,
159
163
  pidPath: paths.pid,
160
164
  identityAckPath: paths.identityAck,
165
+ environment: this.environment,
161
166
  ...(signal === undefined ? {} : { signal }),
162
167
  });
163
168
  const output = exited.kind === "exited"
@@ -402,6 +407,7 @@ const runLldb = async (executable, arguments_, options) => {
402
407
  runId: randomUUID(),
403
408
  expectedCommand: executable,
404
409
  signal: deadline.signal,
410
+ hostEnvironment: options.environment,
405
411
  });
406
412
  supervisor = new ProviderProcessSupervisor({
407
413
  ...launched,
@@ -1,5 +1,5 @@
1
+ import { snapshotEnvironment } from "../process/snapshotEnvironment.js";
1
2
  import { NATIVE_MACOS_PROVIDER_IDENTITY as IDENTITY, nativeMacOSCapabilities, } from "./NativeMacOSProviderMetadata.js";
2
- export { NATIVE_MACOS_PROVIDER_IDENTITY } from "./NativeMacOSProviderMetadata.js";
3
3
  import { inspectAppleDispatchMetadata } from "./AppleDispatchMetadata.js";
4
4
  import { observeNativeUi } from "./NativeUiObservation.js";
5
5
  import { LldbCallTracer } from "./LldbCallTracer.js";
@@ -9,6 +9,8 @@ import { open, realpath, stat } from "node:fs/promises";
9
9
  import { z } from "zod";
10
10
  import { createAnalysisExecution, } from "../application/AnalysisProvider.js";
11
11
  import { NATIVE_TOOL_CONTRACTS, } from "../contracts/native/nativeToolContracts.js";
12
+ import { toolContract } from "../contracts/toolContracts.js";
13
+ import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
12
14
  import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisInputError, AnalysisOutputError, AnalysisResourceConstraintError, AnalysisTimeoutError, } from "../domain/analysisErrorCore.js";
13
15
  import { BinaryTargetError } from "../domain/configurationErrors.js";
14
16
  import { ProviderAdapterError } from "../domain/providerAdapterError.js";
@@ -29,9 +31,11 @@ export class NativeMacOSProvider {
29
31
  runner;
30
32
  tracer;
31
33
  #capabilities;
32
- constructor(runner = new XcrunCommandRunner(), platform = process.platform, tracer = new LldbCallTracer()) {
34
+ #environment;
35
+ constructor(environment, runner = new XcrunCommandRunner(environment), platform = process.platform, tracer = new LldbCallTracer(environment)) {
33
36
  this.runner = runner;
34
37
  this.tracer = tracer;
38
+ this.#environment = snapshotEnvironment(environment, platform);
35
39
  this.#capabilities = nativeMacOSCapabilities(platform);
36
40
  }
37
41
  identity() {
@@ -41,17 +45,19 @@ export class NativeMacOSProvider {
41
45
  return this.#capabilities;
42
46
  }
43
47
  createClient(target) {
44
- return new NativeMacOSClient(target, this.runner, this.tracer);
48
+ return new NativeMacOSClient(target, this.runner, this.tracer, this.#environment);
45
49
  }
46
50
  }
47
51
  class NativeMacOSClient {
48
52
  target;
49
53
  runner;
50
54
  tracer;
51
- constructor(target, runner, tracer) {
55
+ environment;
56
+ constructor(target, runner, tracer, environment) {
52
57
  this.target = target;
53
58
  this.runner = runner;
54
59
  this.tracer = tracer;
60
+ this.environment = environment;
55
61
  }
56
62
  async execute(operation, parameters, options) {
57
63
  if (options?.signal?.aborted === true)
@@ -59,16 +65,15 @@ class NativeMacOSClient {
59
65
  if (operation === "health")
60
66
  return ok(createAnalysisExecution(null, IDENTITY));
61
67
  if (operation === "inspect_native_dispatch_metadata") {
68
+ const input = toolContract(operation).inputSchema.safeParse(parameters);
69
+ if (!input.success)
70
+ return err(analysisInputErrorFromIssues(operation, input.error.issues, parameters, {
71
+ cause: input.error,
72
+ }));
62
73
  if (this.target.kind !== "executable" || this.target.format !== "mach-o")
63
74
  return err(new AnalysisCapabilityUnavailableError(IDENTITY.id, operation, "Binary Apple metadata requires Mach-O; other providers can report symbol-only metadata"));
64
75
  try {
65
- const maxRecords = z
66
- .number()
67
- .int()
68
- .min(1)
69
- .max(20000)
70
- .parse(parameters.max_records ?? 5000);
71
- const result = await inspectAppleDispatchMetadata(this.target, maxRecords, options?.signal);
76
+ const result = await inspectAppleDispatchMetadata(this.target, input.data.max_records, options?.signal);
72
77
  return ok(createAnalysisExecution(result, result.provider, {
73
78
  locations: [{ kind: "artifact-path", path: this.target.path }],
74
79
  limitations: result.result.coverage.flatMap(({ reason }) => reason === null ? [] : [reason]),
@@ -102,6 +107,7 @@ class NativeMacOSClient {
102
107
  if (operation === "observe_native_ui" ||
103
108
  operation === "capture_native_ui_scenario") {
104
109
  const result = await observeNativeUi(this.target, operation, parameters, {
110
+ environment: this.environment,
105
111
  signal: options?.signal,
106
112
  });
107
113
  return result.ok
@@ -127,7 +133,7 @@ class NativeMacOSClient {
127
133
  }
128
134
  }
129
135
  close() {
130
- return Promise.resolve();
136
+ return Promise.resolve(ok(null));
131
137
  }
132
138
  #dispatch(operation, parameters, signal) {
133
139
  switch (operation) {
@@ -424,8 +430,10 @@ const translateCommandFailure = (operation, failure) => {
424
430
  ...(capturedOutput === undefined ? {} : { capturedOutput }),
425
431
  ...(cleanup === undefined ? {} : { cleanup }),
426
432
  };
427
- if (failure.reason === "unavailable")
428
- return new AnalysisCapabilityUnavailableError(IDENTITY.id, operation, `${failure.tool} is unavailable through xcrun.`, errorOptions);
433
+ if (failure.reason === "unavailable") {
434
+ const reason = `${failure.tool} is unavailable through xcrun.`;
435
+ return new AnalysisCapabilityUnavailableError(IDENTITY.id, operation, reason, { ...errorOptions, userMessage: reason });
436
+ }
429
437
  if (failure.reason === "cancelled")
430
438
  return new AnalysisCancelledError(operation, errorOptions);
431
439
  if (failure.reason === "timeout")
@@ -513,8 +521,10 @@ const parseEntitlements = (output) => {
513
521
  */
514
522
  const unreadablePlist = (path, requested, reason) => {
515
523
  const sentence = reason.endsWith(".") ? reason : `${reason}.`;
524
+ // Name the default that is missing and the selection that still works.
525
+ const missingDefault = `The target has no readable Contents/Info.plist at ${path}: ${sentence} Select another plist in the target with the path input (CLI: --relative-path).`;
516
526
  return requested === undefined
517
- ? new AnalysisCapabilityUnavailableError(IDENTITY.id, "inspect_plist", `The target has no readable Contents/Info.plist at ${path}: ${sentence} Pass path to inspect another plist.`)
527
+ ? new AnalysisCapabilityUnavailableError(IDENTITY.id, "inspect_plist", missingDefault, { userMessage: missingDefault })
518
528
  : new AnalysisInputError("inspect_plist", undefined, [
519
529
  {
520
530
  path: ["path"],