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
@@ -1,11 +1,11 @@
1
+ import { analysisErrorWithCleanupFailure } from "../application/binary/AnalysisClientCleanup.js";
1
2
  import { fileURLToPath } from "node:url";
2
3
  import { createAnalysisExecution, } from "../application/AnalysisProvider.js";
3
- import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisInputError, AnalysisTimeoutError, } from "../domain/analysisErrorCore.js";
4
+ import { AnalysisCancelledError, AnalysisArtifactChangedError, AnalysisAccessDeniedError, AnalysisCapabilityUnavailableError, AnalysisInputError, AnalysisResourceConstraintError, AnalysisTimeoutError, } from "../domain/analysisErrorCore.js";
4
5
  import {} from "../domain/analysisErrorBase.js";
5
6
  import { ProviderAdapterError } from "../domain/providerAdapterError.js";
6
7
  import { err, ok } from "../domain/result.js";
7
8
  import { GhidraClient } from "./GhidraClient.js";
8
- import { GHIDRA_STARTUP_TIMEOUT_MS } from "./GhidraDefaults.js";
9
9
  import { isGhidraFunctionOperation, parseGhidraFunctionInput, parseGhidraFunctionResult, } from "./GhidraFunctionValues.js";
10
10
  import { isGhidraInventoryOperation, parseGhidraInventoryInput, parseGhidraInventoryResult, } from "./GhidraInventoryValues.js";
11
11
  import { ghidraInstallationDiagnostics, } from "./GhidraInstallation.js";
@@ -55,12 +55,12 @@ export const createGhidraProviderClient = (input) => {
55
55
  ]
56
56
  : [];
57
57
  const client = clientFactory({
58
+ startupTimeoutMs: config.ghidraStartupTimeoutMs,
58
59
  platform: installation.platform,
59
60
  launcher: new GhidraHeadlessLauncher({
61
+ environment: input.environment,
60
62
  analyzeHeadlessPath: prerequisites.value.analyzeHeadlessPath,
61
- ...(config.ghidraJavaHome === undefined
62
- ? {}
63
- : { javaHome: config.ghidraJavaHome }),
63
+ javaHome: prerequisites.value.javaHome,
64
64
  bridgeScriptPath: fileURLToPath(new URL("../../bridge/ghidra/ReaGhidraBridge.java", import.meta.url)),
65
65
  ...(target.format === "dos-mz" ? { dosMz: true } : {}),
66
66
  ...(target.format === "dos-com" ? { dosCom: true } : {}),
@@ -89,8 +89,10 @@ export const createGhidraProviderClient = (input) => {
89
89
  extensionFailure = ghidraExtensionFailure(extensions, info.analysis_extensions ?? [], operation);
90
90
  if (extensionFailure === undefined)
91
91
  return undefined;
92
- await client.close();
93
- return extensionFailure;
92
+ const closed = await client.close();
93
+ return closed.ok
94
+ ? extensionFailure
95
+ : analysisErrorWithCleanupFailure(extensionFailure, closed.error, operation);
94
96
  };
95
97
  const releaseLimitation = unverifiedGhidraBuildLimitation(prerequisites.value.providerVersion);
96
98
  const sessionLimitations = [
@@ -110,7 +112,7 @@ export const createGhidraProviderClient = (input) => {
110
112
  if (operation === "health") {
111
113
  const started = await client.start(options?.signal);
112
114
  if (!started.ok)
113
- return err(projectSessionError(operation, started.error));
115
+ return err(projectSessionError(operation, started.error, config.ghidraStartupTimeoutMs));
114
116
  const failed = await checkExtensions(operation, started.value);
115
117
  if (failed !== undefined)
116
118
  return err(failed);
@@ -127,14 +129,14 @@ export const createGhidraProviderClient = (input) => {
127
129
  if (extensions.length > 0) {
128
130
  const started = await client.start(options?.signal);
129
131
  if (!started.ok)
130
- return err(projectSessionError(operation, started.error));
132
+ return err(projectSessionError(operation, started.error, config.ghidraStartupTimeoutMs));
131
133
  const failed = await checkExtensions(operation, started.value);
132
134
  if (failed !== undefined)
133
135
  return err(failed);
134
136
  }
135
137
  const called = await client.callTool(operation, input.value, options?.signal === undefined ? {} : { signal: options.signal });
136
138
  if (!called.ok)
137
- return err(projectSessionError(operation, called.error));
139
+ return err(projectSessionError(operation, called.error, config.ghidraStartupTimeoutMs));
138
140
  const result = isGhidraFunctionOperation(operation)
139
141
  ? parseGhidraFunctionResult(operation, called.value)
140
142
  : parseGhidraInventoryResult(operation, called.value);
@@ -142,7 +144,7 @@ export const createGhidraProviderClient = (input) => {
142
144
  return result;
143
145
  let normalized = result.value;
144
146
  if (operation === "inspect_native_load_image") {
145
- const attested = await attestGhidraNativeLoadImage(target, operation, result.value, client, (failure) => projectSessionError(operation, failure));
147
+ const attested = await attestGhidraNativeLoadImage(target, operation, result.value, client, (failure) => projectSessionError(operation, failure, config.ghidraStartupTimeoutMs));
146
148
  if (!attested.ok)
147
149
  return attested;
148
150
  normalized = attested.value;
@@ -176,15 +178,26 @@ const ghidraClientPrerequisites = (target, profile, installation) => {
176
178
  return err(new ProviderAdapterError("ghidra", "health"));
177
179
  return ok({
178
180
  analyzeHeadlessPath: installation.analyzeHeadlessPath,
181
+ javaHome: installation.javaHome,
179
182
  providerVersion: installation.providerVersion,
180
183
  profile,
181
184
  });
182
185
  };
183
186
  const unavailableClient = (failure) => ({
184
187
  execute: () => Promise.resolve(err(failure)),
185
- close: () => Promise.resolve(),
188
+ close: () => Promise.resolve(ok(null)),
186
189
  });
187
- const projectSessionError = (operation, failure) => {
190
+ const projectSessionError = (operation, failure, startupTimeoutMs) => {
191
+ const primary = projectPrimarySessionError(operation, failure, startupTimeoutMs);
192
+ return failure.cleanupFailure === undefined
193
+ ? primary
194
+ : analysisErrorWithCleanupFailure(primary, failure.cleanupFailure, operation);
195
+ };
196
+ const projectPrimarySessionError = (operation, failure, startupTimeoutMs) => {
197
+ if (failure.cause instanceof AnalysisAccessDeniedError)
198
+ return new AnalysisAccessDeniedError(operation, failure.cause.path, failure.cause.systemCode, { cause: failure });
199
+ if (failure.cause instanceof AnalysisArtifactChangedError)
200
+ return new AnalysisArtifactChangedError(operation, failure.cause.path, failure.cause.reason, { cause: failure });
188
201
  if (operation === "annotate_native_function" &&
189
202
  failure.kind === "remote" &&
190
203
  failure.remoteCode === "invalid_function_name")
@@ -194,12 +207,20 @@ const projectSessionError = (operation, failure) => {
194
207
  if (failure.kind === "cancelled")
195
208
  return new AnalysisCancelledError(operation);
196
209
  if (failure.kind === "timeout" || failure.kind === "analysis_timeout")
197
- return new AnalysisTimeoutError(operation, failure.timeoutMs ?? GHIDRA_STARTUP_TIMEOUT_MS);
210
+ return new AnalysisTimeoutError(operation, failure.timeoutMs ?? startupTimeoutMs);
198
211
  if (failure.kind === "remote" && failure.remoteCode === "decompile_cancelled")
199
212
  return new AnalysisCancelledError(operation);
213
+ if (failure.kind === "remote" &&
214
+ failure.remoteCode === "regex_stack_exhausted")
215
+ return new AnalysisResourceConstraintError(operation, "memory", failure.message, null, {
216
+ cause: failure,
217
+ remediationAction: "Retry this search in literal mode or simplify the regex. The active analysis session and annotations remain available.",
218
+ });
200
219
  if (failure.kind === "remote" &&
201
220
  ["invalid_request", "not_found", "ambiguous"].includes(failure.remoteCode ?? ""))
202
- return new AnalysisInputError(operation, { cause: failure });
221
+ return new AnalysisInputError(operation, { cause: failure }, [
222
+ { path: [], reason: "invalid_value", message: failure.message },
223
+ ]);
203
224
  if (failure.kind === "remote" && failure.remoteCode === "method_unavailable")
204
225
  return new AnalysisCapabilityUnavailableError("ghidra", operation, failure.message);
205
226
  return new ProviderAdapterError("ghidra", operation, {
@@ -4,6 +4,7 @@ export class GhidraSessionError extends Error {
4
4
  diagnostics;
5
5
  timeoutMs;
6
6
  remoteCode;
7
+ cleanupFailure;
7
8
  constructor(kind, message, diagnostics = {}, options = {}) {
8
9
  super(message, options);
9
10
  this.kind = kind;
@@ -11,16 +12,21 @@ export class GhidraSessionError extends Error {
11
12
  this.diagnostics = structuredClone(diagnostics);
12
13
  this.timeoutMs = options.timeoutMs;
13
14
  this.remoteCode = options.remoteCode;
15
+ this.cleanupFailure = options.cleanupFailure;
14
16
  }
15
17
  }
16
18
  /** Build a session failure while preserving bounded remote failure metadata. */
17
- const createGhidraSessionError = (failure) => new GhidraSessionError(failure.kind, failure.message, failure.remoteCode === undefined
18
- ? failure.diagnostics
19
- : {
20
- ...failure.diagnostics,
21
- remote_code: failure.redact(failure.remoteCode),
22
- remote_message: failure.message,
23
- }, {
19
+ const createGhidraSessionError = (failure) => new GhidraSessionError(failure.kind, failure.message, {
20
+ ...failure.diagnostics,
21
+ failure_kind: failure.kind,
22
+ failure_message: failure.message,
23
+ ...(failure.remoteCode === undefined
24
+ ? {}
25
+ : {
26
+ remote_code: failure.redact(failure.remoteCode),
27
+ remote_message: failure.message,
28
+ }),
29
+ }, {
24
30
  ...(failure.cause === undefined ? {} : { cause: failure.cause }),
25
31
  ...(failure.timeoutMs === undefined
26
32
  ? {}
@@ -0,0 +1,39 @@
1
+ import { dirname, isAbsolute, resolve, sep } from "node:path";
2
+ import { tmpdir } from "node:os";
3
+ /** Session roots may not contain a dot-prefixed path element. */
4
+ const hasDotPrefixElement = (directory) => resolve(directory)
5
+ .split(sep)
6
+ .some((element) => element.startsWith("."));
7
+ /** Nearest ancestor of `directory`, inclusive, that has no dot-prefixed element. */
8
+ const nearestSafeAncestor = (directory) => {
9
+ let current = resolve(directory);
10
+ for (;;) {
11
+ if (!hasDotPrefixElement(current))
12
+ return current;
13
+ const parent = dirname(current);
14
+ if (parent === current)
15
+ return undefined;
16
+ current = parent;
17
+ }
18
+ };
19
+ /**
20
+ * Select a session root usable as the parent of a Ghidra project path.
21
+ *
22
+ * Ghidra validates every project path element with `NamingUtilities.checkName`
23
+ * and aborts the headless analyzer on any element that starts with `.`, so an
24
+ * inherited `TMPDIR` such as `~/.cache/<tool>` fails every Ghidra operation
25
+ * with a generic analysis failure. Prefer the inherited base when it is usable,
26
+ * then a dot-free platform temp directory, then the nearest dot-free ancestor.
27
+ */
28
+ export const ghidraSessionRoot = (options = {}) => {
29
+ const base = resolve(options.base ?? tmpdir());
30
+ if (!hasDotPrefixElement(base))
31
+ return base;
32
+ const platform = options.platform ?? process.platform;
33
+ const fallback = options.fallback ?? (platform === "win32" ? undefined : "/tmp");
34
+ if (fallback !== undefined &&
35
+ isAbsolute(fallback) &&
36
+ !hasDotPrefixElement(fallback))
37
+ return resolve(fallback);
38
+ return nearestSafeAncestor(base) ?? base;
39
+ };
@@ -1,7 +1,10 @@
1
1
  import { createHash } from "node:crypto";
2
- import { constants, createReadStream } from "node:fs";
3
- import { chmod, copyFile, rm } from "node:fs/promises";
2
+ import { constants } from "node:fs";
3
+ import { open, rm } from "node:fs/promises";
4
4
  import { extname, join } from "node:path";
5
+ import { Transform } from "node:stream";
6
+ import { pipeline } from "node:stream/promises";
7
+ import { AnalysisArtifactChangedError, AnalysisAccessDeniedError, } from "../domain/analysisErrorCore.js";
5
8
  import { windowsPrivateRuntime } from "../windows/WindowsPrivateRuntime.js";
6
9
  /** Copy one target and require its bytes to match the parsed target identity. */
7
10
  export const createGhidraTargetSnapshot = async (sourcePath, runtimeRoot, expectedSha256, options = {}) => {
@@ -12,29 +15,61 @@ export const createGhidraTargetSnapshot = async (sourcePath, runtimeRoot, expect
12
15
  if ((options.platform ?? process.platform) === "win32") {
13
16
  const observed = await windowsPrivateRuntime(runtimeRoot).snapshot(sourcePath, `target-${expectedSha256.slice(0, 12)}${suffix}`, options.signal);
14
17
  if (observed.sha256 !== expectedSha256)
15
- throw new Error(`Ghidra target snapshot digest mismatch: expected ${expectedSha256}, observed ${observed.sha256}`);
18
+ throw new AnalysisArtifactChangedError("open_binary", sourcePath, `Ghidra target snapshot digest mismatch: expected ${expectedSha256}, observed ${observed.sha256}`);
16
19
  return {
17
20
  path: snapshotPath,
18
21
  sha256: observed.sha256,
19
22
  admission: { source: observed.source, snapshot: observed.snapshot },
20
23
  };
21
24
  }
25
+ let source;
26
+ let destination;
22
27
  try {
23
- await copyFile(sourcePath, snapshotPath, constants.COPYFILE_EXCL);
24
- await chmod(snapshotPath, 0o600);
28
+ source = await openSnapshotSource(sourcePath);
29
+ if (!(await source.stat()).isFile())
30
+ throw new AnalysisArtifactChangedError("open_binary", sourcePath, "The selected Ghidra source is no longer a regular file");
31
+ destination = await open(snapshotPath, "wx", 0o600);
32
+ await destination.chmod(0o600);
25
33
  const hash = createHash("sha256");
26
- for await (const chunk of createReadStream(snapshotPath))
27
- hash.update(chunk);
34
+ const digest = new Transform({
35
+ transform(chunk, _encoding, done) {
36
+ if (!Buffer.isBuffer(chunk)) {
37
+ done(new TypeError("Ghidra snapshot stream must contain bytes"));
38
+ return;
39
+ }
40
+ hash.update(chunk);
41
+ done(null, chunk);
42
+ },
43
+ });
44
+ await pipeline(source.createReadStream(), digest, destination.createWriteStream(), options.signal === undefined ? {} : { signal: options.signal });
28
45
  const observedSha256 = hash.digest("hex");
29
46
  if (observedSha256 !== expectedSha256)
30
- throw new Error(`Ghidra target snapshot digest mismatch: expected ${expectedSha256}, observed ${observedSha256}`);
47
+ throw new AnalysisArtifactChangedError("open_binary", sourcePath, `Ghidra target snapshot digest mismatch: expected ${expectedSha256}, observed ${observedSha256}`);
31
48
  return { path: snapshotPath, sha256: observedSha256 };
32
49
  }
33
50
  catch (cause) {
34
- await rm(snapshotPath, { force: true }).catch((cause) => {
35
- // best-effort cleanup: snapshot removal must not mask the copy failure.
36
- void cause;
37
- });
51
+ if (destination !== undefined)
52
+ await rm(snapshotPath, { force: true }).catch((cause) => {
53
+ // best-effort cleanup: snapshot removal must not mask the copy failure.
54
+ void cause;
55
+ });
56
+ throw cause;
57
+ }
58
+ finally {
59
+ await Promise.all([source?.close(), destination?.close()]);
60
+ }
61
+ };
62
+ const openSnapshotSource = async (path) => {
63
+ try {
64
+ // A path replaced by a FIFO must not block startup before its type is checked.
65
+ return await open(path, constants.O_RDONLY | constants.O_NONBLOCK);
66
+ }
67
+ catch (cause) {
68
+ const code = cause instanceof Error && "code" in cause ? cause.code : undefined;
69
+ if (code === "EACCES" || code === "EPERM")
70
+ throw new AnalysisAccessDeniedError("open_binary", path, code, { cause });
71
+ if (code === "ENOENT" || code === "ENOTDIR" || code === "ELOOP")
72
+ throw new AnalysisArtifactChangedError("open_binary", path, `The selected Ghidra source could not be opened (${code})`, { cause });
38
73
  throw cause;
39
74
  }
40
75
  };
@@ -1,7 +1,27 @@
1
1
  import { access, open } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { PrivateRuntimeRoot } from "../process/PrivateRuntimeRoot.js";
2
4
  import { readWindowsPrivateRuntimeFile } from "../windows/WindowsPrivateRuntime.js";
3
5
  import { err, ok } from "../domain/result.js";
4
6
  import { GhidraSessionError } from "./GhidraSessionError.js";
7
+ /** Allocate an endpoint that fits the host's Unix sockaddr without moving the project. */
8
+ export const createGhidraEndpoint = async (runtimeRoot, transport, platform) => {
9
+ const path = join(runtimeRoot, transport === "unix-socket" ? "bridge.sock" : "bridge-endpoint.json");
10
+ // sockaddr_un includes a terminating NUL: macOS has 104 bytes, Linux 108.
11
+ const maximumPathBytes = platform === "darwin" ? 103 : 107;
12
+ if (transport !== "unix-socket" ||
13
+ Buffer.byteLength(path, "utf8") <= maximumPathBytes)
14
+ return { endpoint: { transport, path } };
15
+ const socketRoot = await PrivateRuntimeRoot.create({
16
+ parent: "/tmp",
17
+ prefix: "rea-ghidra-socket-",
18
+ platform,
19
+ });
20
+ return {
21
+ endpoint: { transport, path: join(socketRoot.path, "s") },
22
+ socketRoot,
23
+ };
24
+ };
5
25
  /** Observe a ready endpoint, returning null while its bridge is not listening. */
6
26
  export const observeGhidraEndpoint = async (endpoint) => {
7
27
  if (endpoint.transport === "unix-socket") {
@@ -3,7 +3,7 @@ import { constants } from "node:fs";
3
3
  import { open, realpath, writeFile, mkdir } from "node:fs/promises";
4
4
  import { isAbsolute, join } from "node:path";
5
5
  import { z } from "zod";
6
- import { AnalysisCancelledError } from "../../domain/analysisErrorCore.js";
6
+ import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisUnsupportedTargetError, } from "../../domain/analysisErrorCore.js";
7
7
  import { ProviderAdapterError } from "../../domain/providerAdapterError.js";
8
8
  import { jsonObjectSchema } from "../../domain/jsonValue.js";
9
9
  import { err, ok } from "../../domain/result.js";
@@ -11,7 +11,7 @@ import { nativeAotAdapter } from "./nativeaot/NativeAotAdapter.js";
11
11
  const digest = z.string().regex(/^[a-f0-9]{64}$/u);
12
12
  /** Exact executable extension artifact committed before the session starts. */
13
13
  export const ghidraExtensionSchema = z.strictObject({
14
- id: z.string().regex(/^[a-z][a-z0-9-]*$/u),
14
+ id: z.string().regex(/^[a-z][a-z0-9\x2d]*$/u),
15
15
  path: z.string().refine(isAbsolute, "Extension path must be absolute"),
16
16
  configured_path: z
17
17
  .string()
@@ -70,11 +70,9 @@ export const resolveGhidraExtensions = async (config, target, platform, signal)
70
70
  const configured = adapter.configuredPath(config);
71
71
  if (configured === undefined)
72
72
  continue;
73
- const reason = adapter.unsupportedReason(target, platform);
74
- if (reason !== null)
75
- return err(new ProviderAdapterError("ghidra", "resolve_analysis_profile", {
76
- diagnostics: { extension: adapter.id, reason, path: configured },
77
- }));
73
+ const refusal = adapter.unsupportedReason(target, platform);
74
+ if (refusal !== null)
75
+ return err(extensionRefusalError(refusal, target));
78
76
  try {
79
77
  const path = await realpath(configured);
80
78
  const bytes = await readJar(path);
@@ -115,12 +113,21 @@ export const validateGhidraExtensionProfile = (extensions, config, target, platf
115
113
  adapter.entryClass !== extension.entry_class ||
116
114
  adapter.configuredPath(config) !== extension.configured_path)
117
115
  return `Ghidra extension profile lacks matching explicit local configuration: ${extension.id}`;
118
- const reason = adapter.unsupportedReason(target, platform);
119
- if (reason !== null)
120
- return reason;
116
+ const refusal = adapter.unsupportedReason(target, platform);
117
+ if (refusal !== null)
118
+ return refusal.reason;
121
119
  }
122
120
  return null;
123
121
  };
122
+ /**
123
+ * A deliberate host or target refusal is not an execution failure: retrying
124
+ * cannot change it, and its reason already names the remedy.
125
+ */
126
+ const extensionRefusalError = (refusal, target) => refusal.constraint === "host"
127
+ ? new AnalysisCapabilityUnavailableError("ghidra", "resolve_analysis_profile", refusal.reason, { userMessage: refusal.reason })
128
+ : new AnalysisUnsupportedTargetError("resolve_analysis_profile", target.path, refusal.reason,
129
+ // The reason names the workflows that remain available.
130
+ { remediationAction: refusal.reason });
124
131
  /** Snapshot committed extension bytes into the private runtime before Java loads them. */
125
132
  export const snapshotGhidraExtensions = async (extensions, runtimeRoot) => {
126
133
  if (extensions.length === 0)
@@ -5,11 +5,17 @@ export const nativeAotAdapter = {
5
5
  entryClass: "rea.extensions.nativeaot.NativeAotExtension",
6
6
  configuredPath: (config) => config.ghidraNativeAotJar,
7
7
  unsupportedReason: (target, platform) => platform !== "linux"
8
- ? "NativeAOT recovery is verified on Linux only; omit REA_GHIDRA_NATIVEAOT_JAR for ordinary native analysis."
8
+ ? {
9
+ constraint: "host",
10
+ reason: "NativeAOT recovery is verified on Linux only; omit REA_GHIDRA_NATIVEAOT_JAR for ordinary native analysis.",
11
+ }
9
12
  : !["elf", "pe"].includes(target.format) ||
10
13
  target.architecture !== "x86_64" ||
11
14
  target.managed === true
12
- ? "NativeAOT recovery requires an x86-64 ELF or native PE target on Linux; PE/CLI and ReadyToRun assemblies use inspect_managed_artifact; omit REA_GHIDRA_NATIVEAOT_JAR for ordinary native analysis."
15
+ ? {
16
+ constraint: "target",
17
+ reason: "NativeAOT recovery requires an x86-64 ELF or native PE target on Linux; PE/CLI and ReadyToRun assemblies use inspect_managed_artifact; omit REA_GHIDRA_NATIVEAOT_JAR for ordinary native analysis.",
18
+ }
13
19
  : null,
14
20
  validate: validateNativeAotReport,
15
21
  limitations: [
@@ -9,8 +9,8 @@ import { execFileOutput } from "../process/ExecFileOutput.js";
9
9
  import { spawnOwnedProviderProcess, } from "../process/ProviderProcess.js";
10
10
  import { waitForAbortableDelay } from "../process/ProviderDeadline.js";
11
11
  import { selectLinuxPrivateDisplayStrategy, } from "./LinuxPrivateDisplayProbe.js";
12
- import writeFileAtomic from "write-file-atomic";
13
- import { acquireHopperTargetLease } from "./HopperTargetLease.js";
12
+ import { prepareHopperMachOImage, } from "./HopperMachOImage.js";
13
+ import { acquireHopperTargetLease, acquireLinuxHopperApplicationLease, } from "./HopperTargetLease.js";
14
14
  const execFileAsync = promisify(execFile);
15
15
  const HOPPER_BACKGROUND_STARTUP_MS = 5_000;
16
16
  /**
@@ -35,20 +35,28 @@ export class HopperApplicationLauncher {
35
35
  this.dependencies = dependencies;
36
36
  }
37
37
  async launch(session, options = {}) {
38
- const leaseResult = await this.#acquireTargetLease(session.runId);
38
+ const leaseResult = await this.#acquireLaunchLease(session.runId);
39
39
  if (!leaseResult.ok)
40
40
  return leaseResult;
41
41
  const lease = leaseResult.value;
42
42
  let leaseTransferred = false;
43
43
  try {
44
+ let loadedPath = this.options.targetPath;
45
+ if (this.options.preparedImage !== undefined) {
46
+ const prepared = await prepareHopperMachOImage(this.options.targetPath, this.options.preparedImage.sourceSha256, this.options.preparedImage.image, join(session.directory, "image.macho"), options.signal);
47
+ if (!prepared.ok)
48
+ return prepared;
49
+ loadedPath = prepared.value;
50
+ }
44
51
  const ownsProcessLifetime = usesLinuxDemo(this.options);
45
- const bootstrap = await this.#writeBootstrap(session, ownsProcessLifetime);
52
+ const bootstrap = await this.#writeBootstrap(session, ownsProcessLifetime, loadedPath);
46
53
  if (!bootstrap.ok)
47
54
  return bootstrap;
48
55
  const launched = await this.#launchPreparedTarget({
49
56
  session,
50
57
  signal: options.signal,
51
58
  bootstrapPath: bootstrap.value,
59
+ loadedPath,
52
60
  ownsProcessLifetime,
53
61
  lease,
54
62
  });
@@ -69,7 +77,7 @@ export class HopperApplicationLauncher {
69
77
  "-Y",
70
78
  bootstrapPath,
71
79
  action,
72
- this.options.targetPath,
80
+ input.loadedPath,
73
81
  ];
74
82
  try {
75
83
  if (signal?.aborted === true)
@@ -77,7 +85,7 @@ export class HopperApplicationLauncher {
77
85
  const display = await this.#privateDisplay(signal);
78
86
  if (!display.ok)
79
87
  return err(display.error);
80
- const prepared = await prepareHopperApplication(this.options.launcherPath, signal);
88
+ const prepared = await prepareHopperApplication(this.options.launcherPath, this.options.environment, signal);
81
89
  if (!prepared)
82
90
  return err(new HopperCancelledError());
83
91
  const linuxDemo = linuxDemoLaunch(this.options, session, argumentsForTarget, display.strategy);
@@ -92,62 +100,69 @@ export class HopperApplicationLauncher {
92
100
  });
93
101
  if (started === null)
94
102
  return err(new HopperCancelledError());
95
- const cleanup = () => cleanupOwnedProcessGroup(started.ownership).finally(() => lease?.release());
96
- const ownership = {
97
- run_id: session.runId,
98
- pid: started.ownership.leaderPid,
99
- process_group_id: started.ownership.leaderPid,
100
- parent_pid: process.pid,
101
- launcher: linuxDemo?.command ?? this.options.launcherPath,
102
- created_at: new Date().toISOString(),
103
- };
104
- try {
105
- await writeFileAtomic(join(session.directory, "ownership.json"), `${JSON.stringify(ownership)}\n`, { encoding: "utf8", mode: 0o600 });
106
- }
107
- catch (cause) {
108
- await cleanupOwnedProcessGroup(started.ownership);
109
- return err(new HopperStartError({ cause }));
110
- }
111
- return ok({
103
+ const cleanup = () => cleanupOwnedProcessGroup(started.ownership);
104
+ const ownedLauncher = {
105
+ ...(this.options.preparedImage === undefined
106
+ ? {}
107
+ : { preparedImagePath: input.loadedPath }),
112
108
  process: started.process,
113
109
  ownsProcessLifetime: true,
114
110
  ownership: started.ownership,
115
- shutdownMode: ownsProcessLifetime
116
- ? "process-cleanup"
117
- : "bridge-request",
118
111
  cleanup,
119
- });
112
+ launcherCommand: linuxDemo?.command ?? this.options.launcherPath,
113
+ ...(lease === undefined ? {} : { releaseLease: () => lease.release() }),
114
+ };
115
+ return ownsProcessLifetime
116
+ ? ok({
117
+ ...ownedLauncher,
118
+ providerLifetime: "launcher-process",
119
+ shutdownMode: "process-cleanup",
120
+ })
121
+ : ok({
122
+ ...ownedLauncher,
123
+ providerLifetime: "external-application",
124
+ shutdownMode: "bridge-request",
125
+ });
120
126
  }
121
127
  catch (cause) {
122
128
  return err(hopperLaunchFailure(cause, signal));
123
129
  }
124
130
  }
125
- async #acquireTargetLease(runId) {
126
- if ((this.dependencies.platform ?? process.platform) !== "darwin")
131
+ async #acquireLaunchLease(runId) {
132
+ const platform = this.dependencies.platform ?? process.platform;
133
+ const applicationLease = platform === "linux" && usesLinuxDemo(this.options);
134
+ if (!applicationLease && platform !== "darwin")
127
135
  return ok(undefined);
128
136
  try {
129
- const acquisition = await (this.dependencies.acquireTargetLease ?? acquireHopperTargetLease)({
130
- targetPath: this.options.targetPath,
131
- targetKind: this.options.targetKind,
132
- loaderArgs: this.options.loaderArgs,
133
- runId,
134
- });
137
+ const acquisition = applicationLease
138
+ ? await (this.dependencies.acquireApplicationLease ??
139
+ acquireLinuxHopperApplicationLease)({ runId })
140
+ : await (this.dependencies.acquireTargetLease ?? acquireHopperTargetLease)({
141
+ targetPath: this.options.targetPath,
142
+ targetKind: this.options.targetKind,
143
+ loaderArgs: this.options.loaderArgs,
144
+ runId,
145
+ });
135
146
  if (!acquisition.acquired)
136
147
  return err(new HopperStartError({
137
148
  ownerRunId: acquisition.owner.runId,
138
- userMessage: `This Hopper target is already open in REA session ${acquisition.owner.runId}. ` +
139
- "Use that REA session or close it before opening this target again.",
149
+ userMessage: applicationLease
150
+ ? `Linux Hopper is already active in REA session ${acquisition.owner.runId}; it cannot open ${this.options.targetPath} in another session. This build forwards new launches to the existing application. Use the owning REA session to switch targets, or close it before retrying.`
151
+ : `This Hopper target is already open in REA session ${acquisition.owner.runId}. ` +
152
+ "Use that REA session or close it before opening this target again.",
140
153
  }));
141
154
  return ok(acquisition.lease);
142
155
  }
143
156
  catch (cause) {
144
- return err(new HopperStartError({ cause }));
157
+ return err(cause instanceof HopperStartError
158
+ ? cause
159
+ : new HopperStartError({ cause }));
145
160
  }
146
161
  }
147
- async #writeBootstrap(session, ownsProcessLifetime) {
162
+ async #writeBootstrap(session, ownsProcessLifetime, loadedPath) {
148
163
  const bootstrapPath = `${session.directory}/bootstrap.py`;
149
164
  try {
150
- await writeFile(bootstrapPath, bridgeBootstrapSource(session, this.options, ownsProcessLifetime), { encoding: "utf8", mode: 0o600 });
165
+ await writeFile(bootstrapPath, bridgeBootstrapSource(session, this.options, ownsProcessLifetime, loadedPath), { encoding: "utf8", mode: 0o600 });
151
166
  await chmod(bootstrapPath, 0o600);
152
167
  return ok(bootstrapPath);
153
168
  }
@@ -161,6 +176,7 @@ export class HopperApplicationLauncher {
161
176
  const selection = await (this.dependencies.selectPrivateDisplay ??
162
177
  selectLinuxPrivateDisplayStrategy)({
163
178
  helperPath: this.options.demoHelperPath,
179
+ environment: this.options.environment,
164
180
  ...(signal === undefined ? {} : { signal }),
165
181
  });
166
182
  if (signal?.aborted === true)
@@ -173,11 +189,11 @@ export class HopperApplicationLauncher {
173
189
  };
174
190
  }
175
191
  }
176
- const bridgeBootstrapSource = (session, options, ownsProcessLifetime) => [
192
+ const bridgeBootstrapSource = (session, options, ownsProcessLifetime, loadedPath) => [
177
193
  `REA_SOCKET = ${JSON.stringify(session.socketPath)}`,
178
194
  `REA_TOKEN = ${JSON.stringify(session.token)}`,
179
195
  `REA_RUN_ID = ${JSON.stringify(session.runId)}`,
180
- `REA_TARGET_PATH = ${JSON.stringify(options.targetPath)}`,
196
+ `REA_TARGET_PATH = ${JSON.stringify(loadedPath)}`,
181
197
  `REA_OWNS_PROCESS_LIFETIME = ${ownsProcessLifetime ? "True" : "False"}`,
182
198
  `exec(compile(open(${JSON.stringify(options.bridgeScriptPath)}, 'rb').read(), ${JSON.stringify(options.bridgeScriptPath)}, 'exec'))`,
183
199
  "",
@@ -189,6 +205,7 @@ const launchHopperProcess = async (input) => {
189
205
  arguments: arguments_,
190
206
  runId: input.session.runId,
191
207
  expectedCommand: ownershipCommand,
208
+ hostEnvironment: input.options.environment,
192
209
  ...(input.signal === undefined ? {} : { signal: input.signal }),
193
210
  });
194
211
  if (input.linuxDemo !== undefined)
@@ -197,6 +214,7 @@ const launchHopperProcess = async (input) => {
197
214
  arguments: input.linuxDemo.args,
198
215
  runId: input.session.runId,
199
216
  expectedCommand: ownershipCommand,
217
+ hostEnvironment: input.options.environment,
200
218
  ...(input.signal === undefined ? {} : { signal: input.signal }),
201
219
  });
202
220
  return spawn(input.argumentsForTarget);
@@ -242,21 +260,16 @@ const hopperLaunchFailure = (cause, signal) => signal?.aborted === true
242
260
  : new HopperStartError({ cause });
243
261
  /** Select the version-pinned adapter from the caller's explicit launch mode. */
244
262
  export const usesLinuxDemo = (options) => options.launchMode === "verified_linux_demo";
245
- const prepareHopperApplication = async (launcherPath, signal) => {
263
+ const prepareHopperApplication = async (launcherPath, environment, signal) => {
246
264
  const appBundle = hopperApplicationBundle(launcherPath);
247
265
  if (appBundle === undefined)
248
266
  return signal?.aborted !== true;
249
267
  const executablePath = join(appBundle, "Contents/MacOS/Hopper Disassembler");
250
- if (await processIsRunning(executablePath))
268
+ if (await processIsRunning(executablePath, environment))
251
269
  return signal?.aborted !== true;
252
270
  // This reduces activation when Hopper is cold, but the vendor launcher that
253
271
  // follows may still activate its window. See HopperApplicationLauncher.
254
- await execFileAsync("/usr/bin/open", [
255
- "--hide",
256
- "--background",
257
- "-a",
258
- appBundle,
259
- ]);
272
+ await execFileAsync("/usr/bin/open", ["--hide", "--background", "-a", appBundle], { env: environment });
260
273
  return ((await waitForAbortableDelay(HOPPER_BACKGROUND_STARTUP_MS, signal)) ===
261
274
  "elapsed");
262
275
  };
@@ -266,13 +279,9 @@ const hopperApplicationBundle = (launcherPath) => {
266
279
  const candidate = dirname(dirname(dirname(launcherPath)));
267
280
  return extname(candidate) === ".app" ? candidate : undefined;
268
281
  };
269
- const processIsRunning = async (executablePath) => {
282
+ const processIsRunning = async (executablePath, environment) => {
270
283
  try {
271
- const processes = await execFileOutput("/bin/ps", [
272
- "-ax",
273
- "-o",
274
- "command=",
275
- ]);
284
+ const processes = await execFileOutput("/bin/ps", ["-ax", "-o", "command="], { env: environment });
276
285
  return processes.stdout
277
286
  .split("\n")
278
287
  .some((command) => command.trim() === executablePath);