rea-agents 6.0.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 (611) hide show
  1. package/README.md +26 -18
  2. package/bridge/android/ReaJadxBridge.java +14 -5
  3. package/bridge/ghidra/ReaGhidraBridge.java +205 -51
  4. package/bridge/hopper_bridge.py +314 -127
  5. package/bridge/mitmproxy/capture.py +0 -2
  6. package/bridge/native/rea_lldb_tracer.py +630 -94
  7. package/bridge/process/ProcessRunTokenReader.swift +39 -5
  8. package/bridge/pwntools/recorded_crash_impl.py +4 -0
  9. package/dist/android/JadxConfiguration.js +274 -31
  10. package/dist/android/JadxMcpTransport.js +18 -2
  11. package/dist/android/JadxProtocol.js +6 -0
  12. package/dist/android/JadxProvider.js +76 -37
  13. package/dist/android/JadxSession.js +23 -4
  14. package/dist/application/AnalysisContextQueries.js +8 -35
  15. package/dist/application/AnalysisDocument.js +32 -0
  16. package/dist/application/AppBundleExecutable.js +67 -21
  17. package/dist/application/BinaryTargetResolver.js +5 -3
  18. package/dist/application/BrowserEvidence.js +3 -8
  19. package/dist/application/BrowserScenarioEvidence.js +2 -18
  20. package/dist/application/CallPathTracing.js +19 -3
  21. package/dist/application/CapabilityInventory.js +48 -11
  22. package/dist/application/ClientConfigurationDocument.js +917 -8
  23. package/dist/application/ClientRegistrationIdentity.js +26 -5
  24. package/dist/application/ClientRegistrationStatus.js +29 -14
  25. package/dist/application/DirectAnalysis.js +56 -51
  26. package/dist/application/DirectAnalysisCleanup.js +72 -0
  27. package/dist/application/DirectAnalysisStatus.js +4 -5
  28. package/dist/application/Doctor.js +19 -21
  29. package/dist/application/DoctorDiagnostics.js +1 -2
  30. package/dist/application/DoctorScope.js +25 -13
  31. package/dist/application/EnhancedLiteralTracing.js +22 -25
  32. package/dist/application/EnhancedTools.js +64 -17
  33. package/dist/application/EvidenceBundleFiles.js +30 -13
  34. package/dist/application/FunctionAnalysisEvidence.js +2 -3
  35. package/dist/application/InventoryProjectionEvidence.js +4 -3
  36. package/dist/application/InvestigationProviders.js +11 -2
  37. package/dist/application/JsonFiles.js +83 -28
  38. package/dist/application/LinuxHopper.js +9 -6
  39. package/dist/application/MacHopper.js +15 -18
  40. package/dist/application/ProcedureAddressResolution.js +11 -0
  41. package/dist/application/RealHopperAssertions.js +0 -11
  42. package/dist/application/ReconstructionCoverageService.js +7 -4
  43. package/dist/application/ReconstructionObligationCandidates.js +1 -1
  44. package/dist/application/ReconstructionObligationLedgerService.js +4 -3
  45. package/dist/application/ReferenceSourceImportEntries.js +1 -1
  46. package/dist/application/Setup.js +21 -17
  47. package/dist/application/SetupClientConfiguration.js +10 -15
  48. package/dist/application/SetupHost.js +21 -29
  49. package/dist/application/SetupPlan.js +11 -9
  50. package/dist/application/SupportedClients.js +34 -1
  51. package/dist/application/Uninstall.js +82 -29
  52. package/dist/application/Update.js +18 -3
  53. package/dist/application/UpdateMaintenance.js +7 -5
  54. package/dist/application/UpdateRuntime.js +57 -36
  55. package/dist/application/WebModuleTraceService.js +4 -2
  56. package/dist/application/WebNetworkCaptureService.js +4 -2
  57. package/dist/application/WebRuntimeService.js +5 -3
  58. package/dist/application/WebScriptExportService.js +32 -6
  59. package/dist/application/WebSourceLocationService.js +4 -2
  60. package/dist/application/WorkflowEvidence.js +105 -0
  61. package/dist/application/XrefsAddressResolution.js +45 -0
  62. package/dist/application/analysisView/AnalysisViewService.js +76 -0
  63. package/dist/application/binary/AnalysisClientCleanup.js +30 -5
  64. package/dist/application/binary/AnalysisProviderEvaluation.js +22 -7
  65. package/dist/application/binary/AnalysisProviderRegistry.js +4 -6
  66. package/dist/application/binary/AnalysisSnapshotCache.js +13 -14
  67. package/dist/application/binary/BinarySession.js +161 -93
  68. package/dist/application/binary/BinarySessionComposition.js +1 -3
  69. package/dist/application/binary/BinarySessionExecution.js +3 -5
  70. package/dist/application/binary/BinarySessionOpen.js +4 -4
  71. package/dist/application/binary/BinarySessionRecords.js +26 -4
  72. package/dist/application/binary/BinarySessionStatus.js +18 -7
  73. package/dist/application/binary/CompositeProvider.js +16 -17
  74. package/dist/application/binary/LazyAnalysisProvider.js +8 -5
  75. package/dist/application/binary/SessionProviderRouter.js +27 -135
  76. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +4 -2
  77. package/dist/application/binaryDiagnostics/RecordedCrashService.js +4 -2
  78. package/dist/application/evm/EvmInterfaceService.js +4 -2
  79. package/dist/application/homebrew.js +48 -0
  80. package/dist/application/investigation/EvidenceLedger.js +21 -7
  81. package/dist/application/investigation/InvestigationRecords.js +8 -0
  82. package/dist/application/javascript/ElectronActiveEvidence.js +9 -13
  83. package/dist/application/javascript/JavaScriptAnalysisControl.js +34 -0
  84. package/dist/application/javascript/JavaScriptApplicationEvidence.js +21 -4
  85. package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +19 -2
  86. package/dist/application/javascript/JavaScriptApplicationService.js +27 -15
  87. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +5 -5
  88. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +10 -7
  89. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +44 -10
  90. package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +11 -3
  91. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +9 -0
  92. package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +8 -5
  93. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +12 -3
  94. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +0 -1
  95. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +49 -19
  96. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +56 -8
  97. package/dist/application/javascript/JavaScriptModuleRelationships.js +38 -9
  98. package/dist/application/javascript/JavaScriptRecoveryService.js +4 -2
  99. package/dist/application/javascript/JavaScriptRuntimeObservationService.js +6 -4
  100. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +3 -3
  101. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +2 -3
  102. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +63 -61
  103. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -2
  104. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +2 -3
  105. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +1 -5
  106. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +75 -46
  107. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +2 -3
  108. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +64 -19
  109. package/dist/application/managed/ManagedApplicationGraphService.js +4 -3
  110. package/dist/application/managed/ManagedMemberComparisonService.js +9 -5
  111. package/dist/application/managed/ManagedNativeVerificationService.js +6 -4
  112. package/dist/application/managed/ManagedReconstructionService.js +4 -3
  113. package/dist/application/process/ProcessCli.js +25 -17
  114. package/dist/application/process/ProcessEvidence.js +4 -4
  115. package/dist/application/workflowInputError.js +18 -0
  116. package/dist/artifacts/ArtifactProvider.js +48 -13
  117. package/dist/artifacts/ArtifactReader.js +31 -0
  118. package/dist/artifacts/DirectoryArtifactReader.js +2 -1
  119. package/dist/artifacts/MachOSliceArtifactReader.js +106 -15
  120. package/dist/artifacts/NativeDmgArtifactReader.js +73 -21
  121. package/dist/artifacts/SafeOutputTree.js +16 -2
  122. package/dist/artifacts/ZipArtifactReader.js +11 -4
  123. package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +26 -5
  124. package/dist/artifacts/apple/DylibResolutionReader.js +17 -7
  125. package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +176 -56
  126. package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +195 -0
  127. package/dist/artifacts/apple/KeyedArchiveReader.js +55 -23
  128. package/dist/artifacts/apple/MachoLoadCommandReader.js +92 -31
  129. package/dist/artifacts/apple/NibArchive.js +81 -14
  130. package/dist/artifacts/apple/NibViewHierarchy.js +10 -3
  131. package/dist/artifacts/apple/PlistNumberLiterals.js +164 -0
  132. package/dist/artifacts/extraction/ArtifactExtraction.js +78 -21
  133. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +79 -68
  134. package/dist/artifacts/inventory/ArtifactInventory.js +0 -1
  135. package/dist/artifacts/inventory/reader.js +3 -3
  136. package/dist/artifacts/inventory/scanCanonical.js +59 -38
  137. package/dist/artifacts/inventory/scanReader.js +5 -9
  138. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +6 -2
  139. package/dist/browser/BrowserScenarioPartialObservation.js +106 -0
  140. package/dist/browser/CdpBrowserProvider.js +2 -3
  141. package/dist/browser/CdpCaptureCompleteness.js +2 -0
  142. package/dist/browser/CdpCaptureEventHandlers.js +78 -15
  143. package/dist/browser/CdpCaptureEventTypes.js +5 -1
  144. package/dist/browser/CdpCaptureEvents.js +25 -1
  145. package/dist/browser/CdpCaptureValues.js +20 -0
  146. package/dist/browser/CdpConnection.js +30 -11
  147. package/dist/browser/CdpElectronProvider.js +0 -2
  148. package/dist/browser/CdpElectronScriptEvents.js +2 -8
  149. package/dist/browser/CdpElectronScripts.js +2 -3
  150. package/dist/browser/CdpOptionalCommand.js +2 -3
  151. package/dist/browser/CdpPageCapture.js +23 -1
  152. package/dist/browser/CdpPageCaptureScripts.js +2 -3
  153. package/dist/browser/CdpSafeMetadata.js +10 -10
  154. package/dist/browser/PlaywrightBrowserScenarioProvider.js +59 -44
  155. package/dist/browser/PlaywrightElectronActiveActions.js +34 -79
  156. package/dist/browser/PlaywrightElectronActiveProjection.js +141 -0
  157. package/dist/browser/PlaywrightElectronActiveProvider.js +133 -130
  158. package/dist/browser/PlaywrightScenarioArtifacts.js +1 -1
  159. package/dist/browser/PlaywrightScenarioBrowser.js +139 -39
  160. package/dist/browser/PlaywrightScenarioEvents.js +1 -1
  161. package/dist/browser/PlaywrightScenarioSession.js +39 -22
  162. package/dist/browser/WebSourceMapFetcher.js +426 -72
  163. package/dist/browser/assets/LocalWebScriptArtifacts.js +2 -2
  164. package/dist/browser/assets/ScriptCaptureAdapters.js +1 -1
  165. package/dist/browser/history/CaptureFailures.js +41 -1
  166. package/dist/browser/history/CaptureRelease.js +5 -0
  167. package/dist/browser/history/HarCaptureAdapter.js +3 -3
  168. package/dist/browser/history/HarJson.js +3 -2
  169. package/dist/browser/history/HistoricalCaptureDecoder.js +4 -2
  170. package/dist/browser/history/MitmproxyCaptureAdapter.js +4 -2
  171. package/dist/catalogIdentity.js +0 -1
  172. package/dist/cli/analysisSelector.js +23 -0
  173. package/dist/cli/analysisViewCommands.js +36 -0
  174. package/dist/cli/applicationCommands.js +2 -3
  175. package/dist/cli/artifactCommands.js +11 -12
  176. package/dist/cli/coreAnalysisCommands.js +3 -3
  177. package/dist/cli/coreBinaryCommands.js +100 -37
  178. package/dist/cli/coreNativeCommands.js +9 -10
  179. package/dist/cli/electronCommands.js +10 -9
  180. package/dist/cli/interactiveSetup.js +6 -6
  181. package/dist/cli/javascriptApplicationAnalysis.js +7 -3
  182. package/dist/cli/jsonOutput.js +4 -99
  183. package/dist/cli/managedCommands.js +7 -8
  184. package/dist/cli/nativeCallCommands.js +3 -5
  185. package/dist/cli/omittableDefaults.js +50 -0
  186. package/dist/cli/processCommands.js +3 -2
  187. package/dist/cli/setupCommands.js +16 -15
  188. package/dist/cli/utilityCommands.js +9 -9
  189. package/dist/cli/webRuntimeCommands.js +8 -8
  190. package/dist/cli.js +18 -9
  191. package/dist/cliBrowserScenarioCommands.js +2 -2
  192. package/dist/cliCommandNames.js +1 -1
  193. package/dist/cliJsonInput.js +24 -5
  194. package/dist/cliOutput.js +0 -38
  195. package/dist/composition/auxiliaryAnalysisProviders.js +27 -23
  196. package/dist/composition/binary.js +9 -9
  197. package/dist/composition/browserScenario.js +2 -1
  198. package/dist/composition/directAnalysis.js +20 -13
  199. package/dist/composition/electronScenario.js +1 -1
  200. package/dist/composition/optionalObservationProviders.js +12 -7
  201. package/dist/config/environment.js +10 -0
  202. package/dist/config/ghidraStartupTimeout.js +12 -0
  203. package/dist/config/homeDirectory.js +12 -0
  204. package/dist/config/mcpResponseBudget.js +30 -0
  205. package/dist/config/parseConfig.js +8 -3
  206. package/dist/config/parsers.js +19 -22
  207. package/dist/contracts/analysisViewToolContracts.js +56 -0
  208. package/dist/contracts/applicationToolContracts.js +5 -4
  209. package/dist/contracts/artifactComparisonExample.js +2 -2
  210. package/dist/contracts/artifactToolContracts.js +1 -1
  211. package/dist/contracts/browserScenarioToolContracts.js +1 -1
  212. package/dist/contracts/browserToolContracts.js +19 -15
  213. package/dist/contracts/enhancedInputs.js +7 -5
  214. package/dist/contracts/enhancedToolContracts.js +7 -6
  215. package/dist/contracts/evm/evmToolContracts.js +1 -1
  216. package/dist/contracts/functionWorkflowToolContracts.js +1 -1
  217. package/dist/contracts/hopperMemoryContracts.js +2 -5
  218. package/dist/contracts/inputSchemaPresentation.js +90 -0
  219. package/dist/contracts/investigationExamples.js +4 -3
  220. package/dist/contracts/javascript/electronToolContracts.js +2 -2
  221. package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +0 -20
  222. package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +245 -0
  223. package/dist/contracts/javascript/javascriptRuntimeObservationToolContracts.js +1 -1
  224. package/dist/contracts/managed/managedToolContracts.js +7 -14
  225. package/dist/contracts/managed/managedWorkflowToolContracts.js +1 -1
  226. package/dist/contracts/mobileApplicationGraphExamples.js +3 -3
  227. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +1 -1
  228. package/dist/contracts/native/nativeToolContracts.js +5 -3
  229. package/dist/contracts/officialToolContracts.js +16 -16
  230. package/dist/contracts/promptContracts.js +5 -5
  231. package/dist/contracts/providerSelection.js +1 -1
  232. package/dist/contracts/sessionLifecycleInputs.js +3 -7
  233. package/dist/contracts/sessionStatusContract.js +2 -4
  234. package/dist/contracts/sessionToolContracts.js +18 -8
  235. package/dist/contracts/sessionToolSchemas.js +3 -19
  236. package/dist/contracts/toolContractExamples.js +0 -1
  237. package/dist/contracts/toolContractHelpers.js +4 -1
  238. package/dist/contracts/toolContracts.js +2 -0
  239. package/dist/contracts/toolEffects.js +1 -1
  240. package/dist/contracts/toolOutputSchemaGroups.js +160 -115
  241. package/dist/contracts/toolOutputSchemaPrimitives.js +28 -20
  242. package/dist/contracts/toolSchemaMetadata.js +41 -33
  243. package/dist/contracts/webNetworkCaptureToolContracts.js +2 -2
  244. package/dist/contracts/webRuntimeToolContracts.js +1 -1
  245. package/dist/contracts/webScriptToolContracts.js +1 -1
  246. package/dist/doctorRuntime.js +7 -5
  247. package/dist/domain/analysisErrorBase.js +8 -3
  248. package/dist/domain/analysisErrorCore.js +6 -1
  249. package/dist/domain/analysisErrorPresentation.js +90 -20
  250. package/dist/domain/analysisErrorProjection.js +130 -32
  251. package/dist/domain/analysisSnapshot.js +29 -31
  252. package/dist/domain/analysisView/analysisView.js +243 -0
  253. package/dist/domain/analysisView/analysisViewCoverage.js +19 -0
  254. package/dist/domain/analysisView/binaryLayoutView.js +159 -0
  255. package/dist/domain/analysisView/javascriptApplicationView.js +238 -0
  256. package/dist/domain/android/androidAnalysis.js +2 -4
  257. package/dist/domain/android/androidApplication.js +18 -10
  258. package/dist/domain/apple/appleApplication.js +42 -15
  259. package/dist/domain/apple/dyldEnvironment.js +73 -0
  260. package/dist/domain/apple/dylibResolution.js +130 -12
  261. package/dist/domain/apple/dylibResolutionFindings.js +9 -7
  262. package/dist/domain/apple/interfaceBuilderGraph.js +25 -14
  263. package/dist/domain/apple/interfaceBuilderKeyedArchive.js +13 -3
  264. package/dist/domain/apple/keyedArchive.js +35 -3
  265. package/dist/domain/apple/machoContainer.js +54 -0
  266. package/dist/domain/apple/plistNumbers.js +76 -0
  267. package/dist/domain/artifactComparison.js +15 -6
  268. package/dist/domain/artifactGraph.js +16 -3
  269. package/dist/domain/artifactIdentity.js +29 -0
  270. package/dist/domain/artifactInventoryEvidence.js +28 -40
  271. package/dist/domain/artifactOperationError.js +3 -3
  272. package/dist/domain/artifactPartialObservation.js +1 -0
  273. package/dist/domain/artifactPathSyntax.js +49 -0
  274. package/dist/domain/binaryTarget.js +39 -13
  275. package/dist/domain/bridgeCandidateProjection.js +71 -0
  276. package/dist/domain/browserCaptureComparison.js +13 -49
  277. package/dist/domain/browserCompleteness.js +1 -0
  278. package/dist/domain/browserNetworkEvidence.js +10 -4
  279. package/dist/domain/browserObservation.js +0 -1
  280. package/dist/domain/browserObservationError.js +24 -5
  281. package/dist/domain/browserObservationSchemas.js +14 -3
  282. package/dist/domain/browserScenario.js +0 -1
  283. package/dist/domain/browserScenarioCapture.js +1 -2
  284. package/dist/domain/browserScenarioDiff.js +0 -2
  285. package/dist/domain/browserScenarioDiffEvidence.js +0 -12
  286. package/dist/domain/browserScenarioDiffValues.js +2 -2
  287. package/dist/domain/browserScenarioValues.js +5 -10
  288. package/dist/domain/bundleComparison.js +3 -2
  289. package/dist/domain/callPath.js +8 -9
  290. package/dist/domain/callPathSchemas.js +2 -2
  291. package/dist/domain/canonicalJsonDigestSteps.js +133 -0
  292. package/dist/domain/canonicalOrdering.js +9 -5
  293. package/dist/domain/changedBehavior.js +9 -9
  294. package/dist/domain/comparisonSourceEvidence.js +40 -0
  295. package/dist/domain/completionLedgerGeneration.js +2 -1
  296. package/dist/domain/configurationErrors.js +13 -1
  297. package/dist/domain/conformancePackage.js +4 -3
  298. package/dist/domain/evidence.js +65 -36
  299. package/dist/domain/evidenceBundle.js +47 -8
  300. package/dist/domain/evidenceCompletionLedger.js +2 -1
  301. package/dist/domain/evidenceErrors.js +12 -1
  302. package/dist/domain/explicitSensitiveFailure.js +17 -1
  303. package/dist/domain/firmware/firmwareAnalysis.js +6 -7
  304. package/dist/domain/functionComparison.js +4 -5
  305. package/dist/domain/functionComparisonDimensions.js +120 -87
  306. package/dist/domain/functionComparisonNormalization.js +23 -34
  307. package/dist/domain/functionComparisonResults.js +1 -4
  308. package/dist/domain/functionComparisonSchemas.js +2 -8
  309. package/dist/domain/functionDossierEvidence.js +2 -37
  310. package/dist/domain/hopperErrors.js +23 -2
  311. package/dist/domain/hopperValues.js +51 -8
  312. package/dist/domain/immutableJson.js +114 -0
  313. package/dist/domain/inputIssueProjection.js +3 -0
  314. package/dist/domain/javascript/electronActiveObservation.js +47 -64
  315. package/dist/domain/javascript/electronObservation.js +14 -3
  316. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +10 -9
  317. package/dist/domain/javascript/electronStaticAnalysisIpc.js +2 -1
  318. package/dist/domain/javascript/electronStaticAnalysisNative.js +2 -1
  319. package/dist/domain/javascript/electronStaticAnalysisValues.js +6 -12
  320. package/dist/domain/javascript/javascriptApplicationAnalysis.js +71 -23
  321. package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +2 -0
  322. package/dist/domain/javascript/javascriptApplicationGraph.js +39 -3
  323. package/dist/domain/javascript/javascriptApplicationGraphSchemas.js +9 -2
  324. package/dist/domain/javascript/javascriptApplicationVersionItems.js +5 -2
  325. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +2 -1
  326. package/dist/domain/javascript/javascriptAstValues.js +20 -0
  327. package/dist/{application/javascript/JavaScriptReturnShapeProjection.js → domain/javascript/javascriptExportReturnShapeProjection.js} +4 -4
  328. package/dist/domain/javascript/javascriptExportShapeComparison.js +7 -1
  329. package/dist/domain/javascript/javascriptExportShapeComparisonIdentity.js +6 -1
  330. package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +29 -1
  331. package/dist/domain/javascript/javascriptExportShapeSelection.js +5 -5
  332. package/dist/domain/javascript/javascriptExportShapeVariants.js +67 -14
  333. package/dist/domain/javascript/javascriptFeatureSeed.js +20 -0
  334. package/dist/domain/javascript/javascriptFeatureTraversal.js +0 -1
  335. package/dist/domain/javascript/javascriptNativeHandoff.js +1 -1
  336. package/dist/domain/javascript/javascriptRecovery.js +3 -8
  337. package/dist/domain/javascript/javascriptRuntimeLoadState.js +0 -1
  338. package/dist/domain/javascript/javascriptRuntimeObservation.js +10 -2
  339. package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +1 -1
  340. package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +3 -2
  341. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +0 -1
  342. package/dist/domain/javascript/javascriptSemanticAnalysis.js +106 -5
  343. package/dist/domain/javascript/javascriptSemanticAsyncEffects.js +2 -1
  344. package/dist/domain/javascript/javascriptSemanticCalls.js +2 -1
  345. package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -1
  346. package/dist/domain/javascript/javascriptSemanticCoverage.js +6 -5
  347. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +9 -17
  348. package/dist/domain/javascript/javascriptSemanticDataEffects.js +23 -6
  349. package/dist/domain/javascript/javascriptSemanticGraph.js +98 -43
  350. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +1 -0
  351. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +77 -20
  352. package/dist/domain/javascript/javascriptSemanticMutationValues.js +21 -27
  353. package/dist/domain/javascript/javascriptSemanticObjects.js +83 -42
  354. package/dist/domain/javascript/javascriptSemanticPrimitives.js +18 -21
  355. package/dist/domain/javascript/javascriptSemanticProjection.js +2 -3
  356. package/dist/domain/javascript/javascriptSemanticPromises.js +2 -1
  357. package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -4
  358. package/dist/domain/javascript/javascriptSemanticResourceLimits.js +77 -0
  359. package/dist/domain/javascript/javascriptSemanticResources.js +1 -1
  360. package/dist/domain/javascript/javascriptSemanticReturns.js +32 -17
  361. package/dist/domain/javascript/javascriptSemanticSlots.js +72 -0
  362. package/dist/domain/javascript/javascriptSemanticValues.js +126 -61
  363. package/dist/domain/javascript/javascriptSourceMapPaths.js +104 -0
  364. package/dist/domain/javascript/javascriptSourceParser.js +6 -2
  365. package/dist/domain/javascript/javascriptStaticAnalysis.js +22 -17
  366. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -3
  367. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +16 -5
  368. package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +66 -7
  369. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +28 -17
  370. package/dist/domain/javascript/javascriptStaticAnalysisState.js +3 -2
  371. package/dist/domain/javascript/sourceToBundleComparison.js +12 -3
  372. package/dist/domain/javascript/sourceToBundleSignals.js +47 -19
  373. package/dist/domain/jsonSerialization.js +109 -0
  374. package/dist/domain/jsonValue.js +90 -6
  375. package/dist/domain/localPath.js +6 -0
  376. package/dist/domain/managed/managedApplicationGraph.js +10 -10
  377. package/dist/domain/managed/managedArtifact.js +6 -4
  378. package/dist/domain/managed/managedInspectionEvidence.js +16 -0
  379. package/dist/domain/managed/managedMemberComparison.js +2 -9
  380. package/dist/domain/managed/managedMemberComparisonMatch.js +5 -9
  381. package/dist/domain/managed/managedNativeVerification.js +3 -11
  382. package/dist/domain/managed/managedNativeVerificationMatch.js +9 -3
  383. package/dist/domain/native/binaryLayout.js +2 -3
  384. package/dist/domain/native/fileOffsetPartialObservation.js +1 -0
  385. package/dist/domain/native/nativeApiBoundary.js +1 -1
  386. package/dist/domain/native/nativeCallObservation.js +37 -13
  387. package/dist/domain/native/nativeCallPartialObservation.js +33 -0
  388. package/dist/domain/native/nativeInstruction.js +7 -0
  389. package/dist/domain/native/recordedCrash.js +2 -3
  390. package/dist/domain/offsetDateTime.js +17 -0
  391. package/dist/domain/process/processCapture.js +21 -16
  392. package/dist/domain/process/processCaptureCoverage.js +67 -0
  393. package/dist/domain/process/processCaptureExample.js +2 -1
  394. package/dist/domain/process/processCaptureParsing.js +1 -34
  395. package/dist/domain/process/processCaptureValidation.js +81 -13
  396. package/dist/domain/process/processComparison.js +79 -26
  397. package/dist/domain/process/processObservation.js +10 -2
  398. package/dist/domain/process/processScenario.js +35 -12
  399. package/dist/domain/process/processTraceComparison.js +0 -2
  400. package/dist/domain/process/processTraceDimensionProjection.js +1 -1
  401. package/dist/domain/process/processTraceEvaluation.js +15 -11
  402. package/dist/domain/process/processTraceSpecification.js +3 -4
  403. package/dist/domain/propertyListKeys.js +1 -1
  404. package/dist/domain/propertyListXmlText.js +19 -0
  405. package/dist/domain/providerAdapterError.js +3 -1
  406. package/dist/domain/providerOperationHealth.js +54 -0
  407. package/dist/domain/reconstructionCoverage.js +5 -2
  408. package/dist/domain/reconstructionObligationLedgerSchemas.js +2 -1
  409. package/dist/domain/reconstructionReadinessSchemas.js +2 -1
  410. package/dist/domain/reconstructionVerification.js +9 -46
  411. package/dist/domain/reconstructionVerificationSchemas.js +4 -3
  412. package/dist/domain/referenceSourceGraph.js +20 -21
  413. package/dist/domain/staticRuntimeCorrelation.js +8 -45
  414. package/dist/domain/stringPatterns.js +6 -0
  415. package/dist/domain/swiftSymbolClassification.js +61 -0
  416. package/dist/domain/symbolAnalysis.js +66 -18
  417. package/dist/domain/webBundleAnalysis.js +20 -8
  418. package/dist/domain/webBundleAnalyzerInspection.js +13 -8
  419. package/dist/domain/webBundleAnalyzerResult.js +41 -2
  420. package/dist/domain/webCaptureDiff.js +0 -1
  421. package/dist/domain/webCaptureDiffSchemas.js +6 -3
  422. package/dist/domain/webEventListeners.js +3 -2
  423. package/dist/domain/webExecution.js +3 -2
  424. package/dist/domain/webRuntime.js +19 -7
  425. package/dist/domain/webScriptExport.js +1 -1
  426. package/dist/domain/webSourceLocation.js +1 -0
  427. package/dist/dotnet/ManagedArtifactInspector.js +2 -19
  428. package/dist/dotnet/ManagedMemberInspector.js +12 -18
  429. package/dist/dotnet/ManagedMemberInspectorCore.js +47 -44
  430. package/dist/dotnet/ManagedMemberRows.js +75 -62
  431. package/dist/dotnet/ManagedMetadataInventory.js +16 -22
  432. package/dist/dotnet/ManagedMethodBodyReader.js +4 -0
  433. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +109 -94
  434. package/dist/dotnet/ManagedNativeBoundaryInspector.js +12 -21
  435. package/dist/dotnet/ManagedReaderFailure.js +16 -0
  436. package/dist/dotnet/ManagedStaticProvider.js +3 -5
  437. package/dist/evaluation/AgentEvaluationFixtures.js +250 -0
  438. package/dist/evaluation/AgentEvaluationReport.js +28 -0
  439. package/dist/evaluation/CodexAgentEval.js +12 -8
  440. package/dist/evaluation/KnownAnswerEvaluation.js +281 -0
  441. package/dist/evm/EvmoleInterfaceProvider.js +2 -1
  442. package/dist/firmware/FirmwareCommand.js +9 -5
  443. package/dist/firmware/FirmwareFiles.js +1 -1
  444. package/dist/firmware/FirmwareProvider.js +4 -4
  445. package/dist/generatedPackageMetadata.js +2 -2
  446. package/dist/ghidra/GhidraAnalysisProfile.js +7 -5
  447. package/dist/ghidra/GhidraClient.js +126 -34
  448. package/dist/ghidra/GhidraClientStartup.js +0 -2
  449. package/dist/ghidra/GhidraDiagnostics.js +7 -7
  450. package/dist/ghidra/GhidraDoctor.js +6 -5
  451. package/dist/ghidra/GhidraFunctionValues.js +13 -12
  452. package/dist/ghidra/GhidraInstallation.js +58 -33
  453. package/dist/ghidra/GhidraInventoryValues.js +14 -4
  454. package/dist/ghidra/GhidraJavaLaunch.js +66 -0
  455. package/dist/ghidra/GhidraLauncher.js +47 -22
  456. package/dist/ghidra/GhidraProvider.js +6 -2
  457. package/dist/ghidra/GhidraProviderCapabilities.js +20 -2
  458. package/dist/ghidra/GhidraProviderClient.js +36 -15
  459. package/dist/ghidra/GhidraSessionError.js +13 -7
  460. package/dist/ghidra/GhidraSessionRoot.js +39 -0
  461. package/dist/ghidra/GhidraTargetSnapshot.js +47 -12
  462. package/dist/ghidra/GhidraTransport.js +20 -0
  463. package/dist/ghidra/extensions/GhidraExtensions.js +17 -10
  464. package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +8 -2
  465. package/dist/hopper/BridgeLauncher.js +65 -56
  466. package/dist/hopper/HopperAnalysisProfile.js +65 -12
  467. package/dist/hopper/HopperCleanup.js +63 -22
  468. package/dist/hopper/HopperClient.js +288 -59
  469. package/dist/hopper/HopperFileOffset.js +237 -0
  470. package/dist/hopper/HopperMachOImage.js +197 -0
  471. package/dist/hopper/HopperOperationStage.js +6 -0
  472. package/dist/hopper/HopperProvider.js +71 -19
  473. package/dist/hopper/HopperProviderCapabilities.js +19 -1
  474. package/dist/hopper/HopperRegexSearch.js +134 -0
  475. package/dist/hopper/HopperRegexWorker.js +27 -0
  476. package/dist/hopper/HopperRequestQueue.js +68 -19
  477. package/dist/hopper/HopperTargetLease.js +133 -49
  478. package/dist/hopper/LinuxPrivateDisplayProbe.js +6 -0
  479. package/dist/ida/IdaConfiguration.js +8 -3
  480. package/dist/ida/IdaInput.js +1 -7
  481. package/dist/ida/IdaMcpConnection.js +8 -4
  482. package/dist/ida/IdaOperationRunner.js +3 -3
  483. package/dist/ida/IdaProvider.js +8 -12
  484. package/dist/ida/IdaSessionClient.js +20 -18
  485. package/dist/ida/IdaWorkspace.js +12 -13
  486. package/dist/inspector/JavaScriptRuntimeScope.js +9 -1
  487. package/dist/inspector/V8InspectorCaptureProjection.js +9 -4
  488. package/dist/inspector/V8InspectorProvider.js +82 -36
  489. package/dist/javascript/recovery/WakaruCommand.js +7 -2
  490. package/dist/javascript/recovery/WakaruExecution.js +5 -2
  491. package/dist/javascript/sourceMaps/DecodedSourceMap.js +47 -0
  492. package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -0
  493. package/dist/javascript/sourceMaps/SourceMapFormat.js +79 -31
  494. package/dist/javascript/sourceMaps/TraceSourceMap.js +14 -28
  495. package/dist/main/shutdown.js +11 -3
  496. package/dist/main/startup.js +9 -2
  497. package/dist/main/transport.js +22 -2
  498. package/dist/main.js +11 -18
  499. package/dist/mcpDoctor.js +62 -2
  500. package/dist/native/AppleDispatchCoverage.js +47 -6
  501. package/dist/native/AppleDispatchDecodeFacts.js +6 -0
  502. package/dist/native/AppleDispatchMetadata.js +6 -3
  503. package/dist/native/AppleMachoFixups.js +48 -24
  504. package/dist/native/AppleMachoSelection.js +48 -22
  505. package/dist/native/AppleObjcCategories.js +6 -2
  506. package/dist/native/AppleObjcDispatchFacets.js +5 -2
  507. package/dist/native/AppleObjcProperties.js +2 -1
  508. package/dist/native/AppleSwiftDispatchFacets.js +27 -21
  509. package/dist/native/AppleSwiftVtables.js +21 -15
  510. package/dist/native/CommandRunner.js +87 -88
  511. package/dist/native/LldbCallTracer.js +372 -103
  512. package/dist/native/LldbRetainedObservations.js +178 -0
  513. package/dist/native/NativeCallObservation.js +62 -3
  514. package/dist/native/NativeMacOSProvider.js +122 -31
  515. package/dist/native/NativeUiHelperRuntime.js +11 -2
  516. package/dist/native/NativeUiObservation.js +2 -2
  517. package/dist/native/SignatureTargetBinding.js +155 -0
  518. package/dist/native/parsers/lipo.js +71 -1
  519. package/dist/native/pwndbg/PwndbgCoreContext.js +25 -5
  520. package/dist/native/pwntools/PwntoolsDecoder.js +2 -1
  521. package/dist/native/pwntools/RecordedCrashStructureBindings.js +2 -0
  522. package/dist/process/DarwinProcessRunTokenReader.js +23 -10
  523. package/dist/process/ExecFileOutput.js +108 -6
  524. package/dist/process/OwnedCommand.js +7 -2
  525. package/dist/process/PrivateRuntimeRoot.js +10 -5
  526. package/dist/process/ProcessOwnership.js +204 -57
  527. package/dist/process/ProcessOwnershipObservation.js +60 -9
  528. package/dist/process/ProviderProcess.js +39 -10
  529. package/dist/process/capture/FilesystemSnapshot.js +50 -13
  530. package/dist/process/capture/ProcessCaptureError.js +15 -2
  531. package/dist/process/capture/ProcessCaptureLifecycle.js +235 -81
  532. package/dist/process/capture/ProcessFilesystemEffects.js +33 -3
  533. package/dist/process/capture/ProcessHarness.js +21 -25
  534. package/dist/process/capture/ProcessNormalization.js +20 -2
  535. package/dist/process/capture/ProcessSampling.js +25 -2
  536. package/dist/process/capture/TerminalRenderer.js +14 -0
  537. package/dist/process/snapshotEnvironment.js +14 -0
  538. package/dist/server/EvidenceMcpServer.js +157 -0
  539. package/dist/server/createServer.js +61 -41
  540. package/dist/server/mcpClientMetadata.js +12 -5
  541. package/dist/server/promptCompletion.js +3 -8
  542. package/dist/server/registerAnalysisViewTool.js +15 -0
  543. package/dist/server/registerAndroidTools.js +2 -5
  544. package/dist/server/registerApplicationTools/compareExportShapes.js +4 -5
  545. package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
  546. package/dist/server/registerApplicationTools/compareVersions.js +4 -5
  547. package/dist/server/registerApplicationTools/coverage.js +1 -2
  548. package/dist/server/registerApplicationTools/helpers.js +1 -4
  549. package/dist/server/registerApplicationTools/obligationLedger.js +4 -5
  550. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -4
  551. package/dist/server/registerApplicationTools/traceFeature.js +4 -5
  552. package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
  553. package/dist/server/registerArtifactComparisonTool.js +13 -10
  554. package/dist/server/registerBinaryDiagnosticsTools.js +2 -5
  555. package/dist/server/registerBrowserScenarioTool.js +3 -6
  556. package/dist/server/registerBrowserTools.js +13 -18
  557. package/dist/server/registerBundleComparisonTool.js +5 -7
  558. package/dist/server/registerCloseLifecycleTool.js +9 -20
  559. package/dist/server/registerElectronTools.js +10 -15
  560. package/dist/server/registerEnhancedTools.js +36 -77
  561. package/dist/server/registerEvidenceTools.js +3 -6
  562. package/dist/server/registerEvmTools.js +2 -5
  563. package/dist/server/registerFirmwareTools.js +2 -5
  564. package/dist/server/registerFunctionComparisonTool.js +15 -12
  565. package/dist/server/registerInvestigationTools.js +16 -17
  566. package/dist/server/registerJavaScriptRecoveryTool.js +2 -5
  567. package/dist/server/registerJavaScriptRuntimeObservationTools.js +6 -8
  568. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +5 -8
  569. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +4 -7
  570. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +6 -9
  571. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +6 -9
  572. package/dist/server/registerOfficialTools.js +4 -21
  573. package/dist/server/registerProcessComparisonTool.js +74 -48
  574. package/dist/server/registerRecordedCrashTools.js +2 -5
  575. package/dist/server/registerSessionRecordTools.js +19 -24
  576. package/dist/server/registerSessionStatusTool.js +19 -6
  577. package/dist/server/registerSessionTools.js +20 -18
  578. package/dist/server/registerWebModuleTool.js +2 -5
  579. package/dist/server/registerWebNetworkCaptureTool.js +2 -5
  580. package/dist/server/registerWebRuntimeTools.js +4 -9
  581. package/dist/server/registerWebScriptTool.js +2 -5
  582. package/dist/server/registerWebSourceLocationTool.js +2 -5
  583. package/dist/server/runDerivedOperation.js +15 -3
  584. package/dist/server/sessionAvailabilityPolicy.js +0 -1
  585. package/dist/server/toolRegistrationOptions.js +2 -2
  586. package/dist/server/toolResult.js +75 -51
  587. package/dist/server/toolResultEncoding.js +34 -0
  588. package/dist/windows/WindowsNativeLoader.js +1 -0
  589. package/dist/windows/WindowsOwnedProcess.js +60 -15
  590. package/dist/windows/WindowsPrivateRuntime.js +7 -8
  591. package/install.sh +1 -1
  592. package/native/windows/README.md +3 -1
  593. package/native/windows/build/manifest.json +2 -2
  594. package/native/windows/build/rea-windows-x64.node +0 -0
  595. package/package.json +44 -30
  596. package/scripts/electron-active-hook-boundaries.cjs +18 -20
  597. package/scripts/electron-active-hook.cjs +241 -37
  598. package/scripts/rea.mjs +3 -6
  599. package/skills/reverse-engineer-anything/SKILL.md +12 -3
  600. package/skills/reverse-engineer-anything/references/android-applications.md +6 -3
  601. package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -4
  602. package/skills/reverse-engineer-anything/references/javascript-applications.md +20 -3
  603. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +9 -0
  604. package/dist/config.js +0 -1
  605. package/dist/contracts/browserCaptureToolInputSchema.js +0 -43
  606. package/dist/contracts/process/processCaptureExample.js +0 -2
  607. package/dist/contracts/toolOutputSchemas.js +0 -2
  608. package/dist/ghidra/GhidraDefaults.js +0 -2
  609. package/dist/main/reload.js +0 -12
  610. package/dist/main/state.js +0 -3
  611. package/dist/server/sessionToolPolicies.js +0 -2
@@ -0,0 +1,134 @@
1
+ import { Worker } from "node:worker_threads";
2
+ import { z } from "zod";
3
+ import { AnalysisCancelledError, AnalysisOutputError, AnalysisResourceConstraintError, } from "../domain/analysisErrorCore.js";
4
+ import { analysisStringSchema } from "../domain/hopperValues.js";
5
+ import { HopperRemoteError } from "../domain/hopperErrors.js";
6
+ import { err, ok } from "../domain/result.js";
7
+ import { analysisSearchInput } from "../contracts/analysisSearchContract.js";
8
+ const MATCHING_DEADLINE_MS = 5_000;
9
+ const inputSchema = z.strictObject({
10
+ ...analysisSearchInput,
11
+ mode: z.literal("regex"),
12
+ });
13
+ const replySchema = z.discriminatedUnion("status", [
14
+ z.strictObject({
15
+ status: z.literal("matched"),
16
+ indices: z.array(z.number().int().nonnegative()),
17
+ }),
18
+ z.strictObject({ status: z.literal("invalid_pattern"), reason: z.string() }),
19
+ ]);
20
+ /** Match collected native facts off Hopper's API thread, with cancellable lifetime. */
21
+ export class HopperRegexSearch {
22
+ client;
23
+ #active = new Map();
24
+ constructor(client) {
25
+ this.client = client;
26
+ }
27
+ execute(operation, parameters, options) {
28
+ const controller = new AbortController();
29
+ const signal = options?.signal === undefined
30
+ ? controller.signal
31
+ : AbortSignal.any([controller.signal, options.signal]);
32
+ const pending = this.#execute(operation, parameters, {
33
+ ...options,
34
+ signal,
35
+ });
36
+ this.#active.set(controller, pending);
37
+ void pending.then(() => this.#active.delete(controller), () => this.#active.delete(controller));
38
+ return pending;
39
+ }
40
+ /** Abort matching workers before their provider session closes. */
41
+ async close() {
42
+ for (const controller of this.#active.keys())
43
+ controller.abort();
44
+ await Promise.all(this.#active.values());
45
+ }
46
+ async #execute(operation, parameters, options) {
47
+ const input = inputSchema.safeParse(parameters);
48
+ if (!input.success)
49
+ return err(new HopperRemoteError(-32000, `Invalid search arguments: ${input.error.message}`, { diagnosticType: "invalid_request", operation }));
50
+ const inventoryOptions = {
51
+ ...options,
52
+ ...(options.progress === undefined
53
+ ? {}
54
+ : {
55
+ progress: {
56
+ report: (update) => options.progress?.report({
57
+ ...update,
58
+ completed: update.total === null || update.total === 0
59
+ ? 0
60
+ : Math.min(0.5, update.completed / update.total / 2),
61
+ total: 1,
62
+ }) ?? Promise.resolve(),
63
+ },
64
+ }),
65
+ };
66
+ const inventory = await this.client.callTool(operation === "search_strings" ? "list_strings" : "list_procedures", input.data.document === undefined
67
+ ? {}
68
+ : { document: input.data.document }, inventoryOptions);
69
+ if (!inventory.ok)
70
+ return inventory;
71
+ const parsed = z.array(analysisStringSchema).safeParse(inventory.value);
72
+ if (!parsed.success)
73
+ return err(new AnalysisOutputError(operation, "Hopper search inventory is malformed"));
74
+ if (options.signal?.aborted)
75
+ return err(new AnalysisCancelledError(operation));
76
+ await options.progress
77
+ ?.report({
78
+ phase: "hopper_regex",
79
+ completed: 0.5,
80
+ total: 1,
81
+ message: "Matching inventory in cancellable regex worker",
82
+ })
83
+ .catch(() => undefined);
84
+ if (options.signal?.aborted)
85
+ return err(new AnalysisCancelledError(operation));
86
+ let worker;
87
+ try {
88
+ worker = new Worker(new URL("./HopperRegexWorker.js", import.meta.url), {
89
+ workerData: {
90
+ pattern: input.data.pattern,
91
+ caseSensitive: input.data.case_sensitive,
92
+ values: parsed.data.map((item) => item.value),
93
+ },
94
+ });
95
+ }
96
+ catch (cause) {
97
+ return err(new AnalysisOutputError(operation, `Cannot start regex worker: ${cause instanceof Error ? cause.message : String(cause)}`, { cause }));
98
+ }
99
+ try {
100
+ return await new Promise((resolve) => {
101
+ const finish = (result) => {
102
+ clearTimeout(timer);
103
+ options.signal?.removeEventListener("abort", onAbort);
104
+ resolve(result);
105
+ };
106
+ const onAbort = () => finish(err(new AnalysisCancelledError(operation)));
107
+ const timer = setTimeout(() => finish(err(new AnalysisResourceConstraintError(operation, "cpu", "Regex matching exceeded its supervised deadline; the Hopper API thread remains available.", { matching_deadline_ms: MATCHING_DEADLINE_MS }, {
108
+ remediationAction: "Simplify the ECMAScript Unicode regex or use literal mode, then retry in the same session.",
109
+ }))), MATCHING_DEADLINE_MS);
110
+ options.signal?.addEventListener("abort", onAbort, { once: true });
111
+ if (options.signal?.aborted)
112
+ onAbort();
113
+ worker.once("message", (message) => {
114
+ const reply = replySchema.safeParse(message);
115
+ if (!reply.success)
116
+ return finish(err(new AnalysisOutputError(operation, "Regex worker reply is malformed")));
117
+ if (reply.data.status === "invalid_pattern")
118
+ return finish(err(new HopperRemoteError(-32000, `Invalid regex pattern: ${reply.data.reason}`, { diagnosticType: "invalid_request", operation })));
119
+ const indices = reply.data.indices;
120
+ if (indices.some((index, position) => index >= parsed.data.length ||
121
+ (position > 0 && index <= (indices[position - 1] ?? -1))))
122
+ return finish(err(new AnalysisOutputError(operation, "Regex worker returned invalid inventory indices")));
123
+ const selected = new Set(indices);
124
+ finish(ok(parsed.data.filter((_, index) => selected.has(index))));
125
+ });
126
+ worker.once("error", (cause) => finish(err(new AnalysisOutputError(operation, `Regex worker failed: ${cause.message}`, { cause }))));
127
+ worker.once("exit", (code) => finish(err(new AnalysisOutputError(operation, `Regex worker exited without a result (${code})`))));
128
+ });
129
+ }
130
+ finally {
131
+ await worker.terminate();
132
+ }
133
+ }
134
+ }
@@ -0,0 +1,27 @@
1
+ import { parentPort, workerData } from "node:worker_threads";
2
+ import { z } from "zod";
3
+ const input = z
4
+ .strictObject({
5
+ pattern: z.string().min(1),
6
+ caseSensitive: z.boolean(),
7
+ values: z.array(z.string()),
8
+ })
9
+ .parse(workerData);
10
+ let expression;
11
+ try {
12
+ expression = new RegExp(input.pattern, input.caseSensitive ? "u" : "iu");
13
+ }
14
+ catch (cause) {
15
+ parentPort?.postMessage({
16
+ status: "invalid_pattern",
17
+ reason: cause instanceof Error ? cause.message : String(cause),
18
+ });
19
+ }
20
+ if (expression !== undefined) {
21
+ const indices = [];
22
+ for (const [index, value] of input.values.entries()) {
23
+ if (expression.test(value))
24
+ indices.push(index);
25
+ }
26
+ parentPort?.postMessage({ status: "matched", indices });
27
+ }
@@ -1,5 +1,8 @@
1
- import { HopperCancelledError, HopperProcessError, HopperProtocolError, HopperRemoteError, } from "../domain/hopperErrors.js";
1
+ import { hopperOperationStage } from "./HopperOperationStage.js";
2
+ import { HopperCancelledError, HopperProcessError, HopperProtocolError, HopperRemoteError, HopperTimeoutError, } from "../domain/hopperErrors.js";
2
3
  import { err } from "../domain/result.js";
4
+ /** Node timer ceiling; larger deadlines would be clamped instead of honored. */
5
+ const MAX_TIMEOUT_MS = 2_147_483_647;
3
6
  /** FIFO that keeps the wire serialized until Hopper actually replies. */
4
7
  export class HopperRequestQueue {
5
8
  send;
@@ -8,10 +11,18 @@ export class HopperRequestQueue {
8
11
  constructor(send) {
9
12
  this.send = send;
10
13
  }
11
- /** Queue one request until Hopper replies or the caller cancels it. */
14
+ /** Settle the caller on reply, cancellation, or deadline; retain active wire work. */
12
15
  run(id, method, params, options) {
13
16
  if (options.signal?.aborted === true)
14
17
  return Promise.resolve(err(new HopperCancelledError()));
18
+ const timeoutMs = options.timeoutMs;
19
+ if (timeoutMs !== undefined &&
20
+ (!Number.isInteger(timeoutMs) ||
21
+ timeoutMs < 0 ||
22
+ timeoutMs > MAX_TIMEOUT_MS))
23
+ return Promise.resolve(err(new HopperProtocolError(`Hopper timeoutMs must be an integer between 0 and ${String(MAX_TIMEOUT_MS)}`)));
24
+ if (timeoutMs === 0)
25
+ return Promise.resolve(err(new HopperTimeoutError(0, method, id, "not_started", hopperOperationStage(method))));
15
26
  return new Promise((resolve) => {
16
27
  let entry;
17
28
  const onAbort = options.signal === undefined ? undefined : () => this.#cancel(entry);
@@ -25,12 +36,18 @@ export class HopperRequestQueue {
25
36
  onAbort,
26
37
  callerState: "waiting",
27
38
  callerSettled: false,
39
+ transmitted: false,
28
40
  startedAt: undefined,
29
41
  heartbeat: undefined,
42
+ deadline: undefined,
43
+ deadlineAt: timeoutMs === undefined ? undefined : performance.now() + timeoutMs,
44
+ timeoutMs,
30
45
  };
31
46
  this.#queue.push(entry);
32
47
  if (onAbort !== undefined)
33
48
  options.signal?.addEventListener("abort", onAbort, { once: true });
49
+ if (timeoutMs !== undefined)
50
+ entry.deadline = setTimeout(() => this.#cancel(entry, this.#timeoutError(entry, timeoutMs)), timeoutMs);
34
51
  if (this.#active !== undefined || this.#queue.length > 1)
35
52
  this.#report(entry, `${method} queued behind ${String(this.#size() - 1)} Hopper request(s)`);
36
53
  this.#drain();
@@ -41,17 +58,10 @@ export class HopperRequestQueue {
41
58
  const entry = this.#active;
42
59
  if (entry === undefined || entry.id !== id)
43
60
  return false;
61
+ this.#expireIfElapsed(entry);
44
62
  this.#releaseWire(entry);
45
- if (!entry.callerSettled) {
46
- const contextual = !result.ok && result.error instanceof HopperRemoteError
47
- ? err(new HopperRemoteError(result.error.code, result.error.safeMessage, {
48
- diagnosticType: result.error.diagnosticType,
49
- operation: entry.method,
50
- requestId: entry.id,
51
- }))
52
- : result;
53
- this.#settleCaller(entry, contextual, "waiting");
54
- }
63
+ if (!entry.callerSettled)
64
+ this.#settleCaller(entry, result.ok ? result : err(withRequestContext(result.error, entry)), "waiting");
55
65
  this.#active = undefined;
56
66
  this.#drain();
57
67
  return true;
@@ -120,6 +130,10 @@ export class HopperRequestQueue {
120
130
  const entry = this.#queue.shift();
121
131
  if (entry === undefined)
122
132
  return;
133
+ if (this.#expireIfElapsed(entry)) {
134
+ this.#drain();
135
+ return;
136
+ }
123
137
  if (entry.signal?.aborted === true) {
124
138
  this.#settleCaller(entry, err(new HopperCancelledError()), "cancelled");
125
139
  this.#drain();
@@ -128,6 +142,17 @@ export class HopperRequestQueue {
128
142
  this.#active = entry;
129
143
  entry.startedAt = performance.now();
130
144
  this.#report(entry, `${entry.method} started on Hopper's serial bridge`);
145
+ this.#expireIfElapsed(entry);
146
+ // A progress observer may cancel or tear down synchronously before send.
147
+ // No native work exists yet, so it is safe to release this reserved slot.
148
+ if (this.#active !== entry || entry.callerSettled) {
149
+ if (this.#active === entry) {
150
+ this.#active = undefined;
151
+ this.#releaseWire(entry);
152
+ this.#drain();
153
+ }
154
+ return;
155
+ }
131
156
  entry.heartbeat = setInterval(() => {
132
157
  if (entry.callerSettled || entry.startedAt === undefined)
133
158
  return;
@@ -135,30 +160,44 @@ export class HopperRequestQueue {
135
160
  this.#report(entry, `${entry.method} is still running in Hopper (${String(elapsed)} ms elapsed)`);
136
161
  }, 1_000);
137
162
  try {
138
- this.send({ id: entry.id, method: entry.method, params: entry.params }, () => this.accept(entry.id, err(new HopperProcessError(null))));
163
+ entry.transmitted = true;
164
+ this.send({ id: entry.id, method: entry.method, params: entry.params }, () => this.accept(entry.id, err(new HopperProcessError(null, undefined, entry.method, entry.id, "unreachable", hopperOperationStage(entry.method)))));
139
165
  }
140
166
  catch (cause) {
141
167
  this.accept(entry.id, err(new HopperProtocolError("Hopper socket write failed", { cause })));
142
168
  }
143
169
  }
144
- #cancel(entry) {
170
+ #timeoutError(entry, timeoutMs) {
171
+ return new HopperTimeoutError(timeoutMs, entry.method, entry.id, entry.transmitted ? "busy" : "not_started", hopperOperationStage(entry.method));
172
+ }
173
+ #expireIfElapsed(entry) {
174
+ if (entry.deadlineAt !== undefined &&
175
+ entry.timeoutMs !== undefined &&
176
+ performance.now() >= entry.deadlineAt)
177
+ this.#settleCaller(entry, err(this.#timeoutError(entry, entry.timeoutMs)), "cancelled");
178
+ return entry.callerSettled;
179
+ }
180
+ #cancel(entry, error = new HopperCancelledError()) {
145
181
  if (entry.callerSettled)
146
182
  return;
147
183
  if (this.#active === entry) {
148
- this.#settleCaller(entry, err(new HopperCancelledError()), "cancelled");
184
+ this.#settleCaller(entry, err(error), "cancelled");
149
185
  return;
150
186
  }
151
187
  const index = this.#queue.indexOf(entry);
152
188
  if (index < 0)
153
189
  return;
154
190
  this.#queue.splice(index, 1);
155
- this.#settleCaller(entry, err(new HopperCancelledError()), "cancelled");
191
+ this.#settleCaller(entry, err(error), "cancelled");
156
192
  }
157
193
  #settleCaller(entry, result, callerState) {
158
194
  if (entry.callerSettled)
159
195
  return;
160
196
  entry.callerSettled = true;
161
197
  entry.callerState = callerState;
198
+ if (entry.deadline !== undefined)
199
+ clearTimeout(entry.deadline);
200
+ entry.deadline = undefined;
162
201
  if (this.#active === entry && entry.heartbeat !== undefined) {
163
202
  clearInterval(entry.heartbeat);
164
203
  entry.heartbeat = undefined;
@@ -195,6 +234,16 @@ export class HopperRequestQueue {
195
234
  }
196
235
  }
197
236
  }
198
- const withRequestContext = (error, entry) => error instanceof HopperProcessError
199
- ? new HopperProcessError(error.exitCode, error.diagnostic, entry.method, entry.id)
200
- : error;
237
+ const withRequestContext = (error, entry) => {
238
+ if (error instanceof HopperProcessError)
239
+ return new HopperProcessError(error.exitCode, error.diagnostic, error.operation ?? entry.method, error.requestId ?? entry.id, error.providerState, error.operation === undefined && error.stage === "connection"
240
+ ? hopperOperationStage(entry.method)
241
+ : error.stage);
242
+ if (error instanceof HopperRemoteError)
243
+ return new HopperRemoteError(error.code, error.safeMessage, {
244
+ diagnosticType: error.diagnosticType,
245
+ operation: error.operation ?? entry.method,
246
+ requestId: error.requestId ?? entry.id,
247
+ });
248
+ return error;
249
+ };
@@ -1,14 +1,13 @@
1
1
  import { createHash } from "node:crypto";
2
- import { chmod, lstat, mkdir, realpath, rm } from "node:fs/promises";
2
+ import { chmod, lstat, mkdir, realpath, rm, rmdir } from "node:fs/promises";
3
3
  import { createConnection, createServer, } from "node:net";
4
4
  import { join, resolve } from "node:path";
5
5
  import { HopperStartError } from "../domain/hopperErrors.js";
6
6
  import { safeParseJson } from "../domain/safeJson.js";
7
- const leaseDirectory = join("/tmp", `rea-hopper-${process.getuid?.() ?? 0}`);
7
+ /** Shared private parent of Hopper lease sockets; it outlives individual sessions. */
8
+ export const HOPPER_TARGET_LEASE_DIRECTORY = join("/tmp", `rea-hopper-${process.getuid?.() ?? 0}`);
8
9
  /** Keep two REA processes from opening duplicate Hopper documents for one target/profile. */
9
10
  export const acquireHopperTargetLease = async (input) => {
10
- const directory = input.directory ?? leaseDirectory;
11
- await ensureLeaseDirectory(directory);
12
11
  // The canonical path only derives the lease key; it never authorizes access.
13
12
  // Common expected `realpath` failures include a missing target or path
14
13
  // component (ENOENT, ENOTDIR), an unreadable component (EACCES), or a
@@ -17,43 +16,105 @@ export const acquireHopperTargetLease = async (input) => {
17
16
  // still yields a deterministic key, but aliases may take separate leases
18
17
  // whenever `realpath` cannot resolve them.
19
18
  const targetPath = await realpath(input.targetPath).catch(() => resolve(input.targetPath));
19
+ return acquireLease({
20
+ ...input,
21
+ identity: {
22
+ targetPath,
23
+ targetKind: input.targetKind,
24
+ loaderArgs: input.loaderArgs,
25
+ },
26
+ });
27
+ };
28
+ /** Reserve the Linux demo's singleton application before it can forward a target to another owner. */
29
+ export const acquireLinuxHopperApplicationLease = (input) => acquireLease({ ...input, identity: { application: "linux-hopper-demo" } });
30
+ const acquireLease = async (input) => {
31
+ const directory = input.directory ?? HOPPER_TARGET_LEASE_DIRECTORY;
32
+ await ensureLeaseDirectory(directory);
20
33
  const key = createHash("sha256")
21
- .update(JSON.stringify({
22
- targetPath,
23
- targetKind: input.targetKind,
24
- loaderArgs: input.loaderArgs,
25
- }))
34
+ .update(JSON.stringify(input.identity))
26
35
  .digest("hex")
27
36
  .slice(0, 32);
28
37
  const socketPath = join(directory, `${key}.sock`);
29
38
  const owner = { runId: input.runId, processId: process.pid };
30
- for (let attempt = 0; attempt < 2; attempt += 1) {
31
- const server = createServer((socket) => sendOwner(socket, owner));
32
- const bound = await bind(server, socketPath);
33
- if (bound) {
34
- await chmod(socketPath, 0o600);
35
- let released = false;
36
- return {
37
- acquired: true,
38
- lease: {
39
- release: async () => {
40
- if (released)
41
- return;
42
- released = true;
43
- await closeServer(server);
44
- await rm(socketPath, { force: true });
45
- },
46
- },
47
- };
39
+ const acquisition = await tryAcquireLease(socketPath, owner);
40
+ if (typeof acquisition !== "string")
41
+ return acquisition;
42
+ // Serialize stale cleanup through the replacement bind: otherwise two
43
+ // recoverers can unlink the socket that one of them has just acquired.
44
+ const recoveryPath = `${socketPath}.recovery`;
45
+ await reserveRecovery(recoveryPath);
46
+ let recovered;
47
+ try {
48
+ recovered = await tryAcquireLease(socketPath, owner);
49
+ if (recovered === "stale")
50
+ await rm(socketPath, { force: true });
51
+ if (typeof recovered === "string")
52
+ recovered = await tryAcquireLease(socketPath, owner);
53
+ if (typeof recovered !== "string")
54
+ return recovered;
55
+ throw new HopperStartError({
56
+ userMessage: "REA could not reserve Hopper for this request. Close competing REA sessions and retry.",
57
+ });
58
+ }
59
+ finally {
60
+ try {
61
+ await rmdir(recoveryPath);
48
62
  }
63
+ catch (cause) {
64
+ if (typeof recovered !== "string" && recovered?.acquired)
65
+ await recovered.lease.release();
66
+ throw new HopperStartError({
67
+ cause,
68
+ userMessage: `REA could not remove its Hopper recovery directory at ${JSON.stringify(recoveryPath)}. Check this directory's write access before retrying.`,
69
+ });
70
+ }
71
+ }
72
+ };
73
+ const reserveRecovery = async (recoveryPath) => {
74
+ try {
75
+ await mkdir(recoveryPath, { mode: 0o700 });
76
+ }
77
+ catch (cause) {
78
+ const busy = typeof cause === "object" &&
79
+ cause !== null &&
80
+ Reflect.get(cause, "code") === "EEXIST";
81
+ throw new HopperStartError({
82
+ cause,
83
+ userMessage: busy
84
+ ? `REA could not reserve Hopper lease recovery at ${JSON.stringify(recoveryPath)}; the existing socket was left unchanged. Retry after concurrent startup finishes. If recovery was interrupted, stop REA sessions and remove this recovery directory before retrying.`
85
+ : `REA could not create its Hopper recovery directory at ${JSON.stringify(recoveryPath)}; the existing socket was left unchanged. Check the parent directory's write access before retrying.`,
86
+ });
87
+ }
88
+ };
89
+ const tryAcquireLease = async (socketPath, owner) => {
90
+ const server = createServer((socket) => sendOwner(socket, owner));
91
+ if (!(await bind(server, socketPath))) {
49
92
  const existingOwner = await readOwner(socketPath);
50
- if (existingOwner !== undefined)
51
- return { acquired: false, owner: existingOwner };
52
- await rm(socketPath, { force: true });
93
+ return typeof existingOwner === "string"
94
+ ? existingOwner
95
+ : { acquired: false, owner: existingOwner };
53
96
  }
54
- throw new HopperStartError({
55
- userMessage: "REA could not reserve this Hopper target. Close competing REA sessions and retry.",
56
- });
97
+ try {
98
+ await chmod(socketPath, 0o600);
99
+ }
100
+ catch (cause) {
101
+ await closeServer(server);
102
+ throw cause;
103
+ }
104
+ let released = false;
105
+ return {
106
+ acquired: true,
107
+ lease: {
108
+ release: async () => {
109
+ if (released)
110
+ return;
111
+ // Node removes a bound Unix socket on close. A second unlink here
112
+ // could remove a new owner's socket bound after that close.
113
+ await closeServer(server);
114
+ released = true;
115
+ },
116
+ },
117
+ };
57
118
  };
58
119
  const ensureLeaseDirectory = async (directory) => {
59
120
  let directoryStat;
@@ -95,14 +156,26 @@ const bind = (server, socketPath) => new Promise((resolveBind, reject) => {
95
156
  const sendOwner = (socket, owner) => {
96
157
  socket.end(`${JSON.stringify(owner)}\n`);
97
158
  };
98
- const readOwner = (socketPath) => new Promise((resolveOwner) => {
159
+ const readOwner = (socketPath) => new Promise((resolveOwner, rejectOwner) => {
99
160
  const socket = createConnection(socketPath);
100
161
  let response = "";
101
- const timer = setTimeout(() => {
162
+ let settled = false;
163
+ const fail = (reason, cause) => {
164
+ if (settled)
165
+ return;
166
+ settled = true;
167
+ clearTimeout(timer);
102
168
  socket.destroy();
103
- resolveOwner(undefined);
104
- }, 250);
169
+ rejectOwner(new HopperStartError({
170
+ cause,
171
+ userMessage: `REA could not verify the existing Hopper lease (${reason}); it was left unchanged. Retry when the owning REA session is responsive.`,
172
+ }));
173
+ };
174
+ const timer = setTimeout(() => fail("owner response timed out"), 250);
105
175
  const finish = (owner) => {
176
+ if (settled)
177
+ return;
178
+ settled = true;
106
179
  clearTimeout(timer);
107
180
  socket.destroy();
108
181
  resolveOwner(owner);
@@ -114,23 +187,34 @@ const readOwner = (socketPath) => new Promise((resolveOwner) => {
114
187
  return;
115
188
  const parsed = safeParseJson(response.slice(0, newline));
116
189
  if (!parsed.ok) {
117
- finish(undefined);
190
+ fail("malformed owner response");
118
191
  return;
119
192
  }
120
193
  const value = parsed.value;
121
- if (typeof value === "object" &&
122
- value !== null &&
123
- typeof Reflect.get(value, "runId") === "string" &&
124
- typeof Reflect.get(value, "processId") === "number")
125
- finish({
126
- runId: Reflect.get(value, "runId"),
127
- processId: Reflect.get(value, "processId"),
128
- });
194
+ const runId = typeof value === "object" && value !== null
195
+ ? Reflect.get(value, "runId")
196
+ : undefined;
197
+ const processId = typeof value === "object" && value !== null
198
+ ? Reflect.get(value, "processId")
199
+ : undefined;
200
+ if (typeof runId === "string" &&
201
+ runId.length > 0 &&
202
+ typeof processId === "number" &&
203
+ Number.isSafeInteger(processId) &&
204
+ processId > 0)
205
+ finish({ runId, processId });
206
+ else
207
+ fail("invalid owner identity");
208
+ });
209
+ socket.on("error", (cause) => {
210
+ if (cause.code === "ENOENT")
211
+ finish("missing");
212
+ else if (cause.code === "ECONNREFUSED")
213
+ finish("stale");
129
214
  else
130
- finish(undefined);
215
+ fail(cause.code ?? "owner connection failed", cause);
131
216
  });
132
- socket.on("error", () => finish(undefined));
133
- socket.on("end", () => finish(undefined));
217
+ socket.on("end", () => fail("owner closed without a complete response"));
134
218
  });
135
219
  const closeServer = (server) => new Promise((resolveClose, reject) => {
136
220
  if (!server.listening) {
@@ -50,6 +50,9 @@ export const runLinuxPrivateDisplayProbe = async (strategy, options) => {
50
50
  arguments: command.arguments,
51
51
  runId: randomUUID(),
52
52
  expectedCommand: null,
53
+ ...(options.environment === undefined
54
+ ? {}
55
+ : { hostEnvironment: options.environment }),
53
56
  ...(options.signal === undefined ? {} : { signal: options.signal }),
54
57
  });
55
58
  }
@@ -111,6 +114,9 @@ const evaluatedProbe = async (strategy, options, timeoutMs, runner) => {
111
114
  try {
112
115
  processResult = await runner(strategy, {
113
116
  helperPath: options.helperPath,
117
+ ...(options.environment === undefined
118
+ ? {}
119
+ : { environment: options.environment }),
114
120
  timeoutMs,
115
121
  ...(options.signal === undefined ? {} : { signal: options.signal }),
116
122
  });
@@ -40,7 +40,7 @@ const registrationSchema = z.union([
40
40
  export const readIdaConfiguration = (path) => {
41
41
  try {
42
42
  if (statSync(path).size > 65_536)
43
- return err(new ConfigurationError("REA_IDA_MCP_CONFIG exceeds the 64 KiB registration size."));
43
+ return err(idaConfigurationError("REA_IDA_MCP_CONFIG exceeds the 64 KiB registration size."));
44
44
  const input = JSON.parse(readFileSync(path, "utf8"));
45
45
  const envelope = z
46
46
  .object({ mcpServers: z.object({ "ida-pro-mcp": z.unknown() }) })
@@ -48,9 +48,14 @@ export const readIdaConfiguration = (path) => {
48
48
  const parsed = registrationSchema.safeParse(envelope.success ? envelope.data.mcpServers["ida-pro-mcp"] : input);
49
49
  return parsed.success
50
50
  ? ok(parsed.data)
51
- : err(new ConfigurationError("REA_IDA_MCP_CONFIG must contain an IDA MCP command/args or local url registration; see docs/ida-provider.md.", { cause: parsed.error }));
51
+ : err(idaConfigurationError("REA_IDA_MCP_CONFIG must contain an IDA MCP command/args or local url registration; see docs/ida-provider.md.", parsed.error));
52
52
  }
53
53
  catch (cause) {
54
- return err(new ConfigurationError(`Cannot read IDA MCP registration ${path}; provide a readable JSON configuration.`, { cause }));
54
+ return err(idaConfigurationError(`Cannot read IDA MCP registration ${path}; provide a readable JSON configuration.`, cause));
55
55
  }
56
56
  };
57
+ /** A REA_IDA_MCP_CONFIG rejection that names the setting it concerns. */
58
+ export const idaConfigurationError = (constraint, cause) => new ConfigurationError(constraint, {
59
+ ...(cause === undefined ? {} : { cause }),
60
+ settings: [{ setting: "REA_IDA_MCP_CONFIG", constraint }],
61
+ });
@@ -1,4 +1,3 @@
1
- import { z } from "zod";
2
1
  import { TOOL_CONTRACTS } from "../contracts/toolContracts.js";
3
2
  import { AnalysisInputError } from "../domain/analysisErrorCore.js";
4
3
  import { jsonObjectSchema } from "../domain/jsonValue.js";
@@ -8,12 +7,7 @@ import { projectInputIssues } from "../domain/inputIssueProjection.js";
8
7
  /** Apply the named public contract and IDA's explicit-address boundary before startup. */
9
8
  export const parseIdaInput = (operation, parameters) => {
10
9
  const contract = TOOL_CONTRACTS.find(({ name }) => name === operation);
11
- const schema = contract?.inputSchema;
12
- if (schema instanceof z.ZodObject) {
13
- const shape = schema.shape;
14
- parameters = Object.fromEntries(Object.entries(parameters).filter(([key, value]) => value !== null || shape[key]?.safeParse(undefined).success !== true));
15
- }
16
- const parsed = (schema instanceof z.ZodObject ? schema.strict() : schema)?.safeParse(parameters);
10
+ const parsed = contract?.inputSchema.safeParse(parameters);
17
11
  if (parsed?.success !== true)
18
12
  return err(new AnalysisInputError(operation, { cause: parsed?.error }, parsed?.error === undefined
19
13
  ? []
@@ -1,5 +1,6 @@
1
+ import { snapshotEnvironment } from "../process/snapshotEnvironment.js";
1
2
  import { Client, StreamableHTTPClientTransport, } from "@modelcontextprotocol/client";
2
- import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
3
+ import { DEFAULT_INHERITED_ENV_VARS, StdioClientTransport, } from "@modelcontextprotocol/client/stdio";
3
4
  import { z } from "zod";
4
5
  import { jsonValueSchema } from "../domain/jsonValue.js";
5
6
  import { AnalysisProtocolError } from "../domain/analysisErrorCore.js";
@@ -66,7 +67,7 @@ export const redactIdaTransportFailure = (cause, config) => {
66
67
  return new Error(message, { cause });
67
68
  };
68
69
  /** Create a standard SDK connection to an existing upstream registration. */
69
- export const createIdaMcpConnection = (config) => {
70
+ export const createIdaMcpConnection = (config, environment) => {
70
71
  const client = new Client({ name: "rea-ida-provider", version: "1" });
71
72
  const transportFailure = (cause) => {
72
73
  throw redactIdaTransportFailure(cause, config);
@@ -76,9 +77,12 @@ export const createIdaMcpConnection = (config) => {
76
77
  command: config.command,
77
78
  args: config.args,
78
79
  env: {
79
- ...Object.fromEntries(Object.entries(process.env).filter((entry) => entry[1] !== undefined)),
80
+ // The SDK always merges ambient defaults. Its string-only environment
81
+ // API requires empty values to suppress omitted caller-selected keys.
82
+ ...Object.fromEntries(DEFAULT_INHERITED_ENV_VARS.map((key) => [key, ""])),
83
+ ...Object.fromEntries(Object.entries(snapshotEnvironment(environment)).filter((entry) => entry[1] !== undefined)),
80
84
  IDA_MCP_MAX_WORKERS: "1",
81
- ...config.env,
85
+ ...snapshotEnvironment(config.env),
82
86
  },
83
87
  stderr: "pipe",
84
88
  })