rea-agents 6.1.0 → 6.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (453) hide show
  1. package/README.md +7 -5
  2. package/bridge/ghidra/ReaGhidraBridge.java +32 -4
  3. package/bridge/hopper_bridge.py +6 -1
  4. package/dist/android/JadxConfiguration.js +87 -7
  5. package/dist/android/JadxMcpTransport.js +14 -2
  6. package/dist/android/JadxProvider.js +57 -35
  7. package/dist/application/BinaryTargetResolver.js +5 -3
  8. package/dist/application/BrowserEvidence.js +3 -8
  9. package/dist/application/BrowserScenarioEvidence.js +2 -18
  10. package/dist/application/CapabilityInventory.js +43 -9
  11. package/dist/application/ClientConfigurationDocument.js +69 -25
  12. package/dist/application/DirectAnalysis.js +29 -14
  13. package/dist/application/DirectAnalysisCleanup.js +72 -0
  14. package/dist/application/DirectAnalysisStatus.js +4 -5
  15. package/dist/application/Doctor.js +15 -19
  16. package/dist/application/DoctorDiagnostics.js +1 -2
  17. package/dist/application/EnhancedTools.js +51 -6
  18. package/dist/application/EvidenceBundleFiles.js +8 -3
  19. package/dist/application/InvestigationProviders.js +9 -1
  20. package/dist/application/JsonFiles.js +42 -9
  21. package/dist/application/LinuxHopper.js +9 -6
  22. package/dist/application/MacHopper.js +15 -18
  23. package/dist/application/RealHopperAssertions.js +0 -11
  24. package/dist/application/ReconstructionObligationCandidates.js +1 -1
  25. package/dist/application/ReferenceSourceImportEntries.js +1 -1
  26. package/dist/application/Setup.js +8 -16
  27. package/dist/application/SetupHost.js +16 -27
  28. package/dist/application/SetupPlan.js +6 -6
  29. package/dist/application/Uninstall.js +81 -29
  30. package/dist/application/UpdateMaintenance.js +7 -5
  31. package/dist/application/UpdateRuntime.js +12 -12
  32. package/dist/application/WebScriptExportService.js +30 -4
  33. package/dist/application/WorkflowEvidence.js +25 -2
  34. package/dist/application/XrefsAddressResolution.js +45 -0
  35. package/dist/application/analysisView/AnalysisViewService.js +76 -0
  36. package/dist/application/binary/AnalysisClientCleanup.js +30 -5
  37. package/dist/application/binary/AnalysisProviderEvaluation.js +1 -2
  38. package/dist/application/binary/AnalysisProviderRegistry.js +2 -6
  39. package/dist/application/binary/AnalysisSnapshotCache.js +10 -8
  40. package/dist/application/binary/BinarySession.js +70 -29
  41. package/dist/application/binary/BinarySessionComposition.js +1 -3
  42. package/dist/application/binary/BinarySessionExecution.js +3 -5
  43. package/dist/application/binary/BinarySessionOpen.js +1 -1
  44. package/dist/application/binary/BinarySessionRecords.js +1 -1
  45. package/dist/application/binary/BinarySessionStatus.js +1 -6
  46. package/dist/application/binary/CompositeProvider.js +4 -18
  47. package/dist/application/binary/LazyAnalysisProvider.js +5 -5
  48. package/dist/application/binary/SessionProviderRouter.js +27 -135
  49. package/dist/application/homebrew.js +48 -0
  50. package/dist/application/javascript/ElectronActiveEvidence.js +9 -13
  51. package/dist/application/javascript/JavaScriptApplicationEvidence.js +2 -6
  52. package/dist/application/javascript/JavaScriptApplicationService.js +6 -1
  53. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +5 -3
  54. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +11 -9
  55. package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +11 -3
  56. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +9 -0
  57. package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +8 -5
  58. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +12 -3
  59. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +0 -1
  60. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +43 -16
  61. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +46 -6
  62. package/dist/application/javascript/JavaScriptModuleRelationships.js +1 -1
  63. package/dist/application/javascript/JavaScriptRuntimeObservationService.js +3 -3
  64. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +2 -3
  65. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -2
  66. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +2 -3
  67. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +1 -5
  68. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +75 -46
  69. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +2 -3
  70. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +42 -19
  71. package/dist/application/managed/ManagedMemberComparisonService.js +2 -1
  72. package/dist/application/managed/ManagedNativeVerificationService.js +2 -1
  73. package/dist/application/process/ProcessCli.js +11 -11
  74. package/dist/application/process/ProcessEvidence.js +0 -1
  75. package/dist/artifacts/ArtifactProvider.js +39 -14
  76. package/dist/artifacts/ArtifactReader.js +31 -0
  77. package/dist/artifacts/DirectoryArtifactReader.js +2 -1
  78. package/dist/artifacts/MachOSliceArtifactReader.js +9 -2
  79. package/dist/artifacts/NativeDmgArtifactReader.js +65 -20
  80. package/dist/artifacts/SafeOutputTree.js +16 -2
  81. package/dist/artifacts/ZipArtifactReader.js +11 -4
  82. package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +4 -2
  83. package/dist/artifacts/apple/DylibResolutionReader.js +17 -7
  84. package/dist/artifacts/apple/KeyedArchiveReader.js +21 -3
  85. package/dist/artifacts/extraction/ArtifactExtraction.js +78 -21
  86. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +67 -61
  87. package/dist/artifacts/inventory/ArtifactInventory.js +0 -1
  88. package/dist/artifacts/inventory/reader.js +3 -3
  89. package/dist/artifacts/inventory/scanCanonical.js +48 -24
  90. package/dist/artifacts/inventory/scanReader.js +5 -9
  91. package/dist/browser/BrowserScenarioPartialObservation.js +106 -0
  92. package/dist/browser/CdpBrowserProvider.js +2 -3
  93. package/dist/browser/CdpCaptureEventHandlers.js +2 -4
  94. package/dist/browser/CdpCaptureEvents.js +0 -1
  95. package/dist/browser/CdpCaptureValues.js +20 -0
  96. package/dist/browser/CdpElectronProvider.js +0 -2
  97. package/dist/browser/CdpElectronScriptEvents.js +2 -8
  98. package/dist/browser/CdpElectronScripts.js +2 -3
  99. package/dist/browser/CdpPageCaptureScripts.js +2 -3
  100. package/dist/browser/CdpSafeMetadata.js +10 -10
  101. package/dist/browser/PlaywrightBrowserScenarioProvider.js +59 -44
  102. package/dist/browser/PlaywrightElectronActiveActions.js +2 -56
  103. package/dist/browser/PlaywrightElectronActiveProvider.js +10 -6
  104. package/dist/browser/PlaywrightScenarioArtifacts.js +1 -1
  105. package/dist/browser/PlaywrightScenarioBrowser.js +139 -39
  106. package/dist/browser/PlaywrightScenarioEvents.js +1 -1
  107. package/dist/browser/PlaywrightScenarioSession.js +39 -22
  108. package/dist/browser/assets/ScriptCaptureAdapters.js +1 -1
  109. package/dist/browser/history/CaptureFailures.js +6 -2
  110. package/dist/browser/history/MitmproxyCaptureAdapter.js +4 -2
  111. package/dist/catalogIdentity.js +0 -1
  112. package/dist/cli/analysisViewCommands.js +36 -0
  113. package/dist/cli/artifactCommands.js +11 -12
  114. package/dist/cli/coreAnalysisCommands.js +3 -3
  115. package/dist/cli/coreBinaryCommands.js +32 -27
  116. package/dist/cli/coreNativeCommands.js +9 -10
  117. package/dist/cli/electronCommands.js +4 -4
  118. package/dist/cli/interactiveSetup.js +6 -6
  119. package/dist/cli/managedCommands.js +7 -8
  120. package/dist/cli/nativeCallCommands.js +1 -2
  121. package/dist/cli/omittableDefaults.js +50 -0
  122. package/dist/cli/processCommands.js +3 -2
  123. package/dist/cli/setupCommands.js +16 -15
  124. package/dist/cli/utilityCommands.js +9 -9
  125. package/dist/cli.js +16 -8
  126. package/dist/cliBrowserScenarioCommands.js +2 -2
  127. package/dist/cliCommandNames.js +1 -0
  128. package/dist/cliJsonInput.js +15 -1
  129. package/dist/cliOutput.js +0 -38
  130. package/dist/composition/auxiliaryAnalysisProviders.js +27 -23
  131. package/dist/composition/binary.js +9 -9
  132. package/dist/composition/browserScenario.js +2 -1
  133. package/dist/composition/directAnalysis.js +20 -13
  134. package/dist/composition/electronScenario.js +1 -1
  135. package/dist/composition/optionalObservationProviders.js +12 -7
  136. package/dist/config/environment.js +6 -0
  137. package/dist/config/ghidraStartupTimeout.js +4 -9
  138. package/dist/config/homeDirectory.js +12 -0
  139. package/dist/config/mcpResponseBudget.js +9 -1
  140. package/dist/config/parseConfig.js +7 -3
  141. package/dist/config/parsers.js +19 -22
  142. package/dist/contracts/analysisViewToolContracts.js +56 -0
  143. package/dist/contracts/applicationToolContracts.js +5 -4
  144. package/dist/contracts/artifactComparisonExample.js +2 -2
  145. package/dist/contracts/artifactToolContracts.js +1 -1
  146. package/dist/contracts/browserScenarioToolContracts.js +1 -1
  147. package/dist/contracts/browserToolContracts.js +19 -15
  148. package/dist/contracts/enhancedInputs.js +2 -2
  149. package/dist/contracts/enhancedToolContracts.js +4 -3
  150. package/dist/contracts/evm/evmToolContracts.js +1 -1
  151. package/dist/contracts/functionWorkflowToolContracts.js +1 -1
  152. package/dist/contracts/inputSchemaPresentation.js +90 -0
  153. package/dist/contracts/investigationExamples.js +4 -3
  154. package/dist/contracts/javascript/electronToolContracts.js +1 -1
  155. package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +0 -20
  156. package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +245 -0
  157. package/dist/contracts/javascript/javascriptRuntimeObservationToolContracts.js +1 -1
  158. package/dist/contracts/managed/managedToolContracts.js +5 -10
  159. package/dist/contracts/managed/managedWorkflowToolContracts.js +1 -1
  160. package/dist/contracts/mobileApplicationGraphExamples.js +3 -3
  161. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +1 -1
  162. package/dist/contracts/native/nativeToolContracts.js +2 -2
  163. package/dist/contracts/officialToolContracts.js +2 -1
  164. package/dist/contracts/promptContracts.js +2 -2
  165. package/dist/contracts/providerSelection.js +1 -1
  166. package/dist/contracts/sessionToolContracts.js +14 -2
  167. package/dist/contracts/sessionToolSchemas.js +1 -14
  168. package/dist/contracts/toolContracts.js +2 -0
  169. package/dist/contracts/toolEffects.js +1 -0
  170. package/dist/contracts/toolOutputSchemaGroups.js +136 -92
  171. package/dist/contracts/toolOutputSchemaPrimitives.js +11 -21
  172. package/dist/contracts/toolSchemaMetadata.js +18 -69
  173. package/dist/contracts/webNetworkCaptureToolContracts.js +1 -1
  174. package/dist/contracts/webRuntimeToolContracts.js +1 -1
  175. package/dist/contracts/webScriptToolContracts.js +1 -1
  176. package/dist/doctorRuntime.js +7 -5
  177. package/dist/domain/analysisErrorCore.js +3 -0
  178. package/dist/domain/analysisErrorPresentation.js +18 -3
  179. package/dist/domain/analysisErrorProjection.js +24 -5
  180. package/dist/domain/analysisSnapshot.js +29 -31
  181. package/dist/domain/analysisView/analysisView.js +243 -0
  182. package/dist/domain/analysisView/analysisViewCoverage.js +19 -0
  183. package/dist/domain/analysisView/binaryLayoutView.js +159 -0
  184. package/dist/domain/analysisView/javascriptApplicationView.js +238 -0
  185. package/dist/domain/android/androidApplication.js +1 -1
  186. package/dist/domain/apple/appleApplication.js +1 -1
  187. package/dist/domain/apple/dylibResolution.js +10 -3
  188. package/dist/domain/apple/interfaceBuilderGraph.js +0 -1
  189. package/dist/domain/apple/keyedArchive.js +26 -2
  190. package/dist/domain/artifactComparison.js +15 -6
  191. package/dist/domain/artifactGraph.js +16 -3
  192. package/dist/domain/artifactInventoryEvidence.js +9 -16
  193. package/dist/domain/artifactOperationError.js +3 -3
  194. package/dist/domain/artifactPartialObservation.js +1 -0
  195. package/dist/domain/artifactPathSyntax.js +49 -0
  196. package/dist/domain/binaryTarget.js +39 -13
  197. package/dist/domain/browserCaptureComparison.js +13 -49
  198. package/dist/domain/browserNetworkEvidence.js +10 -4
  199. package/dist/domain/browserObservation.js +0 -1
  200. package/dist/domain/browserObservationSchemas.js +14 -3
  201. package/dist/domain/browserScenario.js +0 -1
  202. package/dist/domain/browserScenarioCapture.js +1 -2
  203. package/dist/domain/browserScenarioDiff.js +0 -2
  204. package/dist/domain/browserScenarioDiffEvidence.js +0 -12
  205. package/dist/domain/browserScenarioDiffValues.js +2 -2
  206. package/dist/domain/browserScenarioValues.js +3 -4
  207. package/dist/domain/callPath.js +8 -9
  208. package/dist/domain/callPathSchemas.js +2 -2
  209. package/dist/domain/changedBehavior.js +3 -3
  210. package/dist/domain/completionLedgerGeneration.js +2 -1
  211. package/dist/domain/configurationErrors.js +12 -0
  212. package/dist/domain/conformancePackage.js +4 -3
  213. package/dist/domain/evidence.js +10 -36
  214. package/dist/domain/evidenceBundle.js +7 -9
  215. package/dist/domain/evidenceCompletionLedger.js +2 -1
  216. package/dist/domain/functionComparison.js +4 -5
  217. package/dist/domain/functionComparisonDimensions.js +120 -87
  218. package/dist/domain/functionComparisonNormalization.js +23 -34
  219. package/dist/domain/functionComparisonResults.js +1 -4
  220. package/dist/domain/functionComparisonSchemas.js +2 -8
  221. package/dist/domain/functionDossierEvidence.js +2 -37
  222. package/dist/domain/javascript/electronActiveObservation.js +26 -69
  223. package/dist/domain/javascript/electronObservation.js +14 -3
  224. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +10 -9
  225. package/dist/domain/javascript/electronStaticAnalysisIpc.js +2 -1
  226. package/dist/domain/javascript/electronStaticAnalysisNative.js +2 -1
  227. package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +2 -0
  228. package/dist/domain/javascript/javascriptApplicationGraph.js +26 -3
  229. package/dist/domain/javascript/javascriptApplicationGraphSchemas.js +9 -2
  230. package/dist/domain/javascript/javascriptApplicationVersionItems.js +5 -2
  231. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +2 -1
  232. package/dist/{application/javascript/JavaScriptReturnShapeProjection.js → domain/javascript/javascriptExportReturnShapeProjection.js} +4 -4
  233. package/dist/domain/javascript/javascriptExportShapeComparison.js +7 -1
  234. package/dist/domain/javascript/javascriptExportShapeComparisonIdentity.js +6 -1
  235. package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +29 -1
  236. package/dist/domain/javascript/javascriptExportShapeSelection.js +5 -5
  237. package/dist/domain/javascript/javascriptExportShapeVariants.js +67 -14
  238. package/dist/domain/javascript/javascriptFeatureSeed.js +20 -0
  239. package/dist/domain/javascript/javascriptFeatureTraversal.js +0 -1
  240. package/dist/domain/javascript/javascriptNativeHandoff.js +1 -1
  241. package/dist/domain/javascript/javascriptRuntimeLoadState.js +0 -1
  242. package/dist/domain/javascript/javascriptRuntimeObservation.js +10 -2
  243. package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +1 -1
  244. package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +3 -2
  245. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +0 -1
  246. package/dist/domain/javascript/javascriptSemanticAnalysis.js +9 -3
  247. package/dist/domain/javascript/javascriptSemanticAsyncEffects.js +2 -1
  248. package/dist/domain/javascript/javascriptSemanticCalls.js +2 -1
  249. package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -1
  250. package/dist/domain/javascript/javascriptSemanticDataEffects.js +1 -1
  251. package/dist/domain/javascript/javascriptSemanticGraph.js +88 -46
  252. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +77 -20
  253. package/dist/domain/javascript/javascriptSemanticMutationValues.js +21 -27
  254. package/dist/domain/javascript/javascriptSemanticObjects.js +83 -42
  255. package/dist/domain/javascript/javascriptSemanticPrimitives.js +1 -12
  256. package/dist/domain/javascript/javascriptSemanticProjection.js +2 -3
  257. package/dist/domain/javascript/javascriptSemanticPromises.js +2 -1
  258. package/dist/domain/javascript/javascriptSemanticResourceLimits.js +1 -1
  259. package/dist/domain/javascript/javascriptSemanticResources.js +1 -1
  260. package/dist/domain/javascript/javascriptSemanticReturns.js +32 -17
  261. package/dist/domain/javascript/javascriptSemanticSlots.js +72 -0
  262. package/dist/domain/javascript/javascriptSemanticValues.js +47 -54
  263. package/dist/domain/javascript/javascriptSourceMapPaths.js +104 -0
  264. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +2 -1
  265. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +0 -1
  266. package/dist/domain/javascript/sourceToBundleComparison.js +12 -3
  267. package/dist/domain/javascript/sourceToBundleSignals.js +47 -19
  268. package/dist/domain/localPath.js +1 -1
  269. package/dist/domain/managed/managedArtifact.js +6 -4
  270. package/dist/domain/managed/managedMemberComparison.js +2 -9
  271. package/dist/domain/managed/managedNativeVerification.js +0 -2
  272. package/dist/domain/managed/managedNativeVerificationMatch.js +9 -3
  273. package/dist/domain/native/binaryLayout.js +2 -3
  274. package/dist/domain/native/nativeApiBoundary.js +1 -1
  275. package/dist/domain/native/nativeCallObservation.js +5 -3
  276. package/dist/domain/native/nativeInstruction.js +7 -0
  277. package/dist/domain/native/recordedCrash.js +2 -3
  278. package/dist/domain/offsetDateTime.js +17 -0
  279. package/dist/domain/process/processCapture.js +13 -12
  280. package/dist/domain/process/processCaptureCoverage.js +67 -0
  281. package/dist/domain/process/processCaptureExample.js +2 -1
  282. package/dist/domain/process/processCaptureParsing.js +1 -34
  283. package/dist/domain/process/processCaptureValidation.js +81 -13
  284. package/dist/domain/process/processComparison.js +41 -22
  285. package/dist/domain/process/processObservation.js +10 -2
  286. package/dist/domain/process/processScenario.js +24 -2
  287. package/dist/domain/process/processTraceComparison.js +0 -2
  288. package/dist/domain/process/processTraceDimensionProjection.js +1 -1
  289. package/dist/domain/process/processTraceEvaluation.js +15 -11
  290. package/dist/domain/process/processTraceSpecification.js +3 -4
  291. package/dist/domain/providerAdapterError.js +2 -0
  292. package/dist/domain/reconstructionCoverage.js +5 -2
  293. package/dist/domain/reconstructionObligationLedgerSchemas.js +2 -1
  294. package/dist/domain/reconstructionReadinessSchemas.js +2 -1
  295. package/dist/domain/reconstructionVerification.js +3 -3
  296. package/dist/domain/reconstructionVerificationSchemas.js +2 -1
  297. package/dist/domain/referenceSourceGraph.js +20 -21
  298. package/dist/domain/staticRuntimeCorrelation.js +2 -2
  299. package/dist/domain/stringPatterns.js +6 -0
  300. package/dist/domain/swiftSymbolClassification.js +61 -0
  301. package/dist/domain/symbolAnalysis.js +66 -18
  302. package/dist/domain/webCaptureDiff.js +0 -1
  303. package/dist/domain/webCaptureDiffSchemas.js +6 -3
  304. package/dist/domain/webEventListeners.js +3 -2
  305. package/dist/domain/webExecution.js +3 -2
  306. package/dist/domain/webRuntime.js +0 -2
  307. package/dist/domain/webScriptExport.js +1 -1
  308. package/dist/dotnet/ManagedArtifactInspector.js +2 -19
  309. package/dist/dotnet/ManagedMemberInspector.js +12 -18
  310. package/dist/dotnet/ManagedMemberInspectorCore.js +47 -44
  311. package/dist/dotnet/ManagedMemberRows.js +75 -62
  312. package/dist/dotnet/ManagedMetadataInventory.js +16 -22
  313. package/dist/dotnet/ManagedMethodBodyReader.js +4 -0
  314. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +109 -94
  315. package/dist/dotnet/ManagedNativeBoundaryInspector.js +12 -21
  316. package/dist/dotnet/ManagedReaderFailure.js +16 -0
  317. package/dist/dotnet/ManagedStaticProvider.js +3 -5
  318. package/dist/evaluation/AgentEvaluationFixtures.js +250 -0
  319. package/dist/evaluation/AgentEvaluationReport.js +28 -0
  320. package/dist/evaluation/CodexAgentEval.js +12 -8
  321. package/dist/evaluation/KnownAnswerEvaluation.js +281 -0
  322. package/dist/evm/EvmoleInterfaceProvider.js +2 -1
  323. package/dist/firmware/FirmwareCommand.js +9 -5
  324. package/dist/firmware/FirmwareProvider.js +4 -4
  325. package/dist/generatedPackageMetadata.js +2 -2
  326. package/dist/ghidra/GhidraAnalysisProfile.js +3 -6
  327. package/dist/ghidra/GhidraClient.js +91 -32
  328. package/dist/ghidra/GhidraClientStartup.js +0 -2
  329. package/dist/ghidra/GhidraDoctor.js +6 -5
  330. package/dist/ghidra/GhidraFunctionValues.js +3 -5
  331. package/dist/ghidra/GhidraInstallation.js +40 -12
  332. package/dist/ghidra/GhidraJavaLaunch.js +6 -2
  333. package/dist/ghidra/GhidraLauncher.js +15 -7
  334. package/dist/ghidra/GhidraProvider.js +6 -2
  335. package/dist/ghidra/GhidraProviderCapabilities.js +6 -0
  336. package/dist/ghidra/GhidraProviderClient.js +13 -3
  337. package/dist/ghidra/GhidraSessionError.js +2 -0
  338. package/dist/ghidra/GhidraSessionRoot.js +39 -0
  339. package/dist/ghidra/extensions/GhidraExtensions.js +17 -10
  340. package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +8 -2
  341. package/dist/hopper/BridgeLauncher.js +34 -45
  342. package/dist/hopper/HopperAnalysisProfile.js +3 -8
  343. package/dist/hopper/HopperCleanup.js +56 -27
  344. package/dist/hopper/HopperClient.js +86 -65
  345. package/dist/hopper/HopperMachOImage.js +3 -2
  346. package/dist/hopper/HopperProvider.js +16 -18
  347. package/dist/hopper/HopperRegexSearch.js +3 -6
  348. package/dist/hopper/HopperTargetLease.js +132 -49
  349. package/dist/hopper/LinuxPrivateDisplayProbe.js +6 -0
  350. package/dist/ida/IdaConfiguration.js +8 -3
  351. package/dist/ida/IdaInput.js +1 -7
  352. package/dist/ida/IdaMcpConnection.js +8 -4
  353. package/dist/ida/IdaOperationRunner.js +3 -3
  354. package/dist/ida/IdaProvider.js +8 -12
  355. package/dist/ida/IdaSessionClient.js +20 -18
  356. package/dist/ida/IdaWorkspace.js +12 -13
  357. package/dist/inspector/V8InspectorCaptureProjection.js +1 -1
  358. package/dist/inspector/V8InspectorProvider.js +38 -28
  359. package/dist/javascript/recovery/WakaruCommand.js +7 -2
  360. package/dist/javascript/recovery/WakaruExecution.js +5 -2
  361. package/dist/main/shutdown.js +11 -3
  362. package/dist/main/startup.js +9 -2
  363. package/dist/main/transport.js +22 -2
  364. package/dist/main.js +11 -18
  365. package/dist/native/AppleMachoSelection.js +16 -6
  366. package/dist/native/CommandRunner.js +9 -7
  367. package/dist/native/LldbCallTracer.js +8 -2
  368. package/dist/native/NativeMacOSProvider.js +25 -15
  369. package/dist/native/NativeUiHelperRuntime.js +11 -2
  370. package/dist/native/NativeUiObservation.js +2 -2
  371. package/dist/native/pwntools/PwntoolsDecoder.js +2 -1
  372. package/dist/process/DarwinProcessRunTokenReader.js +16 -2
  373. package/dist/process/ExecFileOutput.js +88 -6
  374. package/dist/process/PrivateRuntimeRoot.js +10 -5
  375. package/dist/process/ProcessOwnership.js +1 -4
  376. package/dist/process/ProcessOwnershipObservation.js +11 -5
  377. package/dist/process/ProviderProcess.js +1 -3
  378. package/dist/process/capture/FilesystemSnapshot.js +50 -13
  379. package/dist/process/capture/ProcessCaptureError.js +13 -0
  380. package/dist/process/capture/ProcessCaptureLifecycle.js +158 -70
  381. package/dist/process/capture/ProcessFilesystemEffects.js +33 -3
  382. package/dist/process/capture/ProcessHarness.js +21 -25
  383. package/dist/process/capture/ProcessNormalization.js +20 -2
  384. package/dist/process/capture/ProcessSampling.js +25 -2
  385. package/dist/process/capture/TerminalRenderer.js +14 -0
  386. package/dist/process/snapshotEnvironment.js +14 -0
  387. package/dist/server/EvidenceMcpServer.js +25 -14
  388. package/dist/server/createServer.js +49 -36
  389. package/dist/server/mcpClientMetadata.js +12 -5
  390. package/dist/server/promptCompletion.js +3 -8
  391. package/dist/server/registerAnalysisViewTool.js +15 -0
  392. package/dist/server/registerAndroidTools.js +2 -3
  393. package/dist/server/registerApplicationTools/compareExportShapes.js +4 -5
  394. package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
  395. package/dist/server/registerApplicationTools/compareVersions.js +4 -5
  396. package/dist/server/registerApplicationTools/coverage.js +1 -2
  397. package/dist/server/registerApplicationTools/helpers.js +1 -2
  398. package/dist/server/registerApplicationTools/obligationLedger.js +4 -5
  399. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -4
  400. package/dist/server/registerApplicationTools/traceFeature.js +4 -5
  401. package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
  402. package/dist/server/registerArtifactComparisonTool.js +4 -5
  403. package/dist/server/registerBinaryDiagnosticsTools.js +2 -3
  404. package/dist/server/registerBrowserScenarioTool.js +3 -4
  405. package/dist/server/registerBrowserTools.js +13 -16
  406. package/dist/server/registerBundleComparisonTool.js +5 -6
  407. package/dist/server/registerCloseLifecycleTool.js +2 -3
  408. package/dist/server/registerElectronTools.js +10 -13
  409. package/dist/server/registerEnhancedTools.js +23 -23
  410. package/dist/server/registerEvidenceTools.js +3 -4
  411. package/dist/server/registerEvmTools.js +2 -3
  412. package/dist/server/registerFirmwareTools.js +2 -3
  413. package/dist/server/registerFunctionComparisonTool.js +7 -8
  414. package/dist/server/registerInvestigationTools.js +14 -15
  415. package/dist/server/registerJavaScriptRecoveryTool.js +2 -3
  416. package/dist/server/registerJavaScriptRuntimeObservationTools.js +6 -6
  417. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +5 -6
  418. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +4 -5
  419. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +6 -7
  420. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +6 -7
  421. package/dist/server/registerOfficialTools.js +4 -19
  422. package/dist/server/registerProcessComparisonTool.js +8 -8
  423. package/dist/server/registerRecordedCrashTools.js +2 -3
  424. package/dist/server/registerSessionRecordTools.js +15 -19
  425. package/dist/server/registerSessionStatusTool.js +3 -4
  426. package/dist/server/registerSessionTools.js +12 -18
  427. package/dist/server/registerWebModuleTool.js +2 -3
  428. package/dist/server/registerWebNetworkCaptureTool.js +2 -3
  429. package/dist/server/registerWebRuntimeTools.js +4 -5
  430. package/dist/server/registerWebScriptTool.js +2 -3
  431. package/dist/server/registerWebSourceLocationTool.js +2 -3
  432. package/dist/server/toolResult.js +66 -94
  433. package/dist/server/toolResultEncoding.js +11 -10
  434. package/dist/windows/WindowsNativeLoader.js +1 -0
  435. package/dist/windows/WindowsOwnedProcess.js +60 -15
  436. package/dist/windows/WindowsPrivateRuntime.js +7 -8
  437. package/native/windows/README.md +3 -1
  438. package/native/windows/build/manifest.json +2 -2
  439. package/native/windows/build/rea-windows-x64.node +0 -0
  440. package/package.json +39 -30
  441. package/scripts/rea.mjs +3 -6
  442. package/skills/reverse-engineer-anything/SKILL.md +9 -8
  443. package/skills/reverse-engineer-anything/references/android-applications.md +6 -3
  444. package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -4
  445. package/skills/reverse-engineer-anything/references/javascript-applications.md +16 -6
  446. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +9 -0
  447. package/dist/config.js +0 -1
  448. package/dist/contracts/browserCaptureToolInputSchema.js +0 -43
  449. package/dist/contracts/process/processCaptureExample.js +0 -2
  450. package/dist/contracts/toolOutputSchemas.js +0 -2
  451. package/dist/main/reload.js +0 -12
  452. package/dist/main/state.js +0 -3
  453. package/dist/server/sessionToolPolicies.js +0 -2
@@ -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,9 +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
12
  import { prepareHopperMachOImage, } from "./HopperMachOImage.js";
14
- import { acquireHopperTargetLease } from "./HopperTargetLease.js";
13
+ import { acquireHopperTargetLease, acquireLinuxHopperApplicationLease, } from "./HopperTargetLease.js";
15
14
  const execFileAsync = promisify(execFile);
16
15
  const HOPPER_BACKGROUND_STARTUP_MS = 5_000;
17
16
  /**
@@ -36,7 +35,7 @@ export class HopperApplicationLauncher {
36
35
  this.dependencies = dependencies;
37
36
  }
38
37
  async launch(session, options = {}) {
39
- const leaseResult = await this.#acquireTargetLease(session.runId);
38
+ const leaseResult = await this.#acquireLaunchLease(session.runId);
40
39
  if (!leaseResult.ok)
41
40
  return leaseResult;
42
41
  const lease = leaseResult.value;
@@ -86,7 +85,7 @@ export class HopperApplicationLauncher {
86
85
  const display = await this.#privateDisplay(signal);
87
86
  if (!display.ok)
88
87
  return err(display.error);
89
- const prepared = await prepareHopperApplication(this.options.launcherPath, signal);
88
+ const prepared = await prepareHopperApplication(this.options.launcherPath, this.options.environment, signal);
90
89
  if (!prepared)
91
90
  return err(new HopperCancelledError());
92
91
  const linuxDemo = linuxDemoLaunch(this.options, session, argumentsForTarget, display.strategy);
@@ -101,22 +100,7 @@ export class HopperApplicationLauncher {
101
100
  });
102
101
  if (started === null)
103
102
  return err(new HopperCancelledError());
104
- const cleanup = () => cleanupOwnedProcessGroup(started.ownership).finally(() => lease?.release());
105
- const ownership = {
106
- run_id: session.runId,
107
- pid: started.ownership.leaderPid,
108
- process_group_id: started.ownership.leaderPid,
109
- parent_pid: process.pid,
110
- launcher: linuxDemo?.command ?? this.options.launcherPath,
111
- created_at: new Date().toISOString(),
112
- };
113
- try {
114
- await writeFileAtomic(join(session.directory, "ownership.json"), `${JSON.stringify(ownership)}\n`, { encoding: "utf8", mode: 0o600 });
115
- }
116
- catch (cause) {
117
- await cleanupOwnedProcessGroup(started.ownership);
118
- return err(new HopperStartError({ cause }));
119
- }
103
+ const cleanup = () => cleanupOwnedProcessGroup(started.ownership);
120
104
  const ownedLauncher = {
121
105
  ...(this.options.preparedImage === undefined
122
106
  ? {}
@@ -125,6 +109,8 @@ export class HopperApplicationLauncher {
125
109
  ownsProcessLifetime: true,
126
110
  ownership: started.ownership,
127
111
  cleanup,
112
+ launcherCommand: linuxDemo?.command ?? this.options.launcherPath,
113
+ ...(lease === undefined ? {} : { releaseLease: () => lease.release() }),
128
114
  };
129
115
  return ownsProcessLifetime
130
116
  ? ok({
@@ -142,26 +128,35 @@ export class HopperApplicationLauncher {
142
128
  return err(hopperLaunchFailure(cause, signal));
143
129
  }
144
130
  }
145
- async #acquireTargetLease(runId) {
146
- 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")
147
135
  return ok(undefined);
148
136
  try {
149
- const acquisition = await (this.dependencies.acquireTargetLease ?? acquireHopperTargetLease)({
150
- targetPath: this.options.targetPath,
151
- targetKind: this.options.targetKind,
152
- loaderArgs: this.options.loaderArgs,
153
- runId,
154
- });
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
+ });
155
146
  if (!acquisition.acquired)
156
147
  return err(new HopperStartError({
157
148
  ownerRunId: acquisition.owner.runId,
158
- userMessage: `This Hopper target is already open in REA session ${acquisition.owner.runId}. ` +
159
- "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.",
160
153
  }));
161
154
  return ok(acquisition.lease);
162
155
  }
163
156
  catch (cause) {
164
- return err(new HopperStartError({ cause }));
157
+ return err(cause instanceof HopperStartError
158
+ ? cause
159
+ : new HopperStartError({ cause }));
165
160
  }
166
161
  }
167
162
  async #writeBootstrap(session, ownsProcessLifetime, loadedPath) {
@@ -181,6 +176,7 @@ export class HopperApplicationLauncher {
181
176
  const selection = await (this.dependencies.selectPrivateDisplay ??
182
177
  selectLinuxPrivateDisplayStrategy)({
183
178
  helperPath: this.options.demoHelperPath,
179
+ environment: this.options.environment,
184
180
  ...(signal === undefined ? {} : { signal }),
185
181
  });
186
182
  if (signal?.aborted === true)
@@ -209,6 +205,7 @@ const launchHopperProcess = async (input) => {
209
205
  arguments: arguments_,
210
206
  runId: input.session.runId,
211
207
  expectedCommand: ownershipCommand,
208
+ hostEnvironment: input.options.environment,
212
209
  ...(input.signal === undefined ? {} : { signal: input.signal }),
213
210
  });
214
211
  if (input.linuxDemo !== undefined)
@@ -217,6 +214,7 @@ const launchHopperProcess = async (input) => {
217
214
  arguments: input.linuxDemo.args,
218
215
  runId: input.session.runId,
219
216
  expectedCommand: ownershipCommand,
217
+ hostEnvironment: input.options.environment,
220
218
  ...(input.signal === undefined ? {} : { signal: input.signal }),
221
219
  });
222
220
  return spawn(input.argumentsForTarget);
@@ -262,21 +260,16 @@ const hopperLaunchFailure = (cause, signal) => signal?.aborted === true
262
260
  : new HopperStartError({ cause });
263
261
  /** Select the version-pinned adapter from the caller's explicit launch mode. */
264
262
  export const usesLinuxDemo = (options) => options.launchMode === "verified_linux_demo";
265
- const prepareHopperApplication = async (launcherPath, signal) => {
263
+ const prepareHopperApplication = async (launcherPath, environment, signal) => {
266
264
  const appBundle = hopperApplicationBundle(launcherPath);
267
265
  if (appBundle === undefined)
268
266
  return signal?.aborted !== true;
269
267
  const executablePath = join(appBundle, "Contents/MacOS/Hopper Disassembler");
270
- if (await processIsRunning(executablePath))
268
+ if (await processIsRunning(executablePath, environment))
271
269
  return signal?.aborted !== true;
272
270
  // This reduces activation when Hopper is cold, but the vendor launcher that
273
271
  // follows may still activate its window. See HopperApplicationLauncher.
274
- await execFileAsync("/usr/bin/open", [
275
- "--hide",
276
- "--background",
277
- "-a",
278
- appBundle,
279
- ]);
272
+ await execFileAsync("/usr/bin/open", ["--hide", "--background", "-a", appBundle], { env: environment });
280
273
  return ((await waitForAbortableDelay(HOPPER_BACKGROUND_STARTUP_MS, signal)) ===
281
274
  "elapsed");
282
275
  };
@@ -286,13 +279,9 @@ const hopperApplicationBundle = (launcherPath) => {
286
279
  const candidate = dirname(dirname(dirname(launcherPath)));
287
280
  return extname(candidate) === ".app" ? candidate : undefined;
288
281
  };
289
- const processIsRunning = async (executablePath) => {
282
+ const processIsRunning = async (executablePath, environment) => {
290
283
  try {
291
- const processes = await execFileOutput("/bin/ps", [
292
- "-ax",
293
- "-o",
294
- "command=",
295
- ]);
284
+ const processes = await execFileOutput("/bin/ps", ["-ax", "-o", "command="], { env: environment });
296
285
  return processes.stdout
297
286
  .split("\n")
298
287
  .some((command) => command.trim() === executablePath);
@@ -10,7 +10,7 @@ import { resolveHopperMachOImage, } from "./HopperMachOImage.js";
10
10
  /** Resolve Hopper open semantics without placing its CLI flags in BinaryTarget. */
11
11
  export const resolveHopperAnalysisProfile = async (target, options) => {
12
12
  if (target.kind !== "executable" && target.kind !== "database")
13
- return ok({ profile: null, compatibility: {} });
13
+ return ok({ profile: null });
14
14
  let machoContainer;
15
15
  if (target.kind === "executable" && target.format === "mach-o") {
16
16
  const header = await readMachoMagic(target.path, options.signal);
@@ -37,12 +37,11 @@ export const resolveHopperAnalysisProfile = async (target, options) => {
37
37
  const loaderArgs = options.loaderArgsOverride.length === 0
38
38
  ? derived.value
39
39
  : [...options.loaderArgsOverride];
40
- const compatibility = { loaderArgs: [...loaderArgs] };
41
40
  const launcherDigest = await sha256File(options.launcherPath, options.signal);
42
41
  if (!launcherDigest.ok)
43
42
  return launcherDigest;
44
43
  if (launcherDigest.value === undefined)
45
- return ok({ profile: null, compatibility });
44
+ return ok({ profile: null });
46
45
  const provider = {
47
46
  id: options.provider.id,
48
47
  name: options.provider.name,
@@ -66,13 +65,9 @@ export const resolveHopperAnalysisProfile = async (target, options) => {
66
65
  source: options.loaderArgsOverride.length === 0
67
66
  ? "derived"
68
67
  : "configured_override",
69
- argument_count: loaderArgs.length,
70
- arguments_sha256: createHash("sha256")
71
- .update(JSON.stringify(loaderArgs))
72
- .digest("hex"),
68
+ arguments: [...loaderArgs],
73
69
  },
74
70
  }),
75
- compatibility,
76
71
  });
77
72
  };
78
73
  /** Derive Hopper's complete non-interactive CLI loader selection. */
@@ -9,33 +9,54 @@ export const cleanupHopperSession = async (input) => {
9
9
  issues: [],
10
10
  resources: new Set(),
11
11
  cleanupResult: undefined,
12
- shutdownConfirmed: false,
12
+ processStopped: input.resources.processSupervisor === undefined,
13
13
  };
14
- await report(input.progress, 0, input.retainDocument && input.launch?.preparedImagePath === undefined
14
+ await report(input.progress, 0, input.retainDocument &&
15
+ input.resources.launch?.preparedImagePath === undefined
15
16
  ? "detaching REA from the Hopper document"
16
17
  : "requesting Hopper document shutdown");
17
18
  await requestShutdown(input, state);
18
19
  await report(input.progress, 0.35, "releasing Hopper bridge transport");
19
- input.releaseTransport(input.socket);
20
+ if (input.resources.shutdownConfirmed ||
21
+ input.resources.launch?.providerLifetime !== "external-application")
22
+ input.releaseTransport(input.socket);
20
23
  await stopProcess(input, state);
21
24
  recordUnconfirmedDocument(input, state);
22
25
  await report(input.progress, 0.75, "removing Hopper private runtime files");
23
- if (input.launch?.preparedImagePath !== undefined &&
24
- !state.shutdownConfirmed) {
25
- const resource = input.runtimeRoot?.path ?? input.launch.preparedImagePath;
26
+ if (input.resources.runtimeRoot !== undefined &&
27
+ (!state.processStopped ||
28
+ (!input.resources.shutdownConfirmed &&
29
+ (input.resources.launch?.preparedImagePath !== undefined ||
30
+ input.resources.launch?.providerLifetime === "external-application")))) {
31
+ const resource = input.resources.runtimeRoot.path;
26
32
  state.resources.add(resource);
27
33
  state.issues.push({
28
34
  resource,
29
- reason: "Prepared image retained because native document closure was not confirmed",
35
+ reason: "Private runtime retained because process or native document closure was not confirmed",
30
36
  });
31
37
  }
32
38
  else {
33
- await closeRuntimeRoot(input.runtimeRoot, state);
39
+ await closeRuntimeRoot(input, state);
40
+ }
41
+ if (state.processStopped && input.resources.shutdownConfirmed) {
42
+ const launch = input.resources.launch;
43
+ try {
44
+ await launch?.releaseLease?.();
45
+ input.resources.launch = undefined;
46
+ }
47
+ catch (cause) {
48
+ state.resources.add("hopper-lease");
49
+ state.issues.push({
50
+ resource: "hopper-lease",
51
+ reason: cause instanceof Error ? cause.message : String(cause),
52
+ });
53
+ }
34
54
  }
35
55
  return cleanupOutcome(input, state);
36
56
  };
37
57
  const requestShutdown = async (input, state) => {
38
- if (input.socket === undefined ||
58
+ if (input.resources.shutdownConfirmed ||
59
+ input.socket === undefined ||
39
60
  input.socket.destroyed ||
40
61
  input.activeRequest !== null) {
41
62
  if (input.activeRequest !== null)
@@ -45,8 +66,9 @@ const requestShutdown = async (input, state) => {
45
66
  }, "Hopper shutdown skipped because a bridge operation remained active");
46
67
  return;
47
68
  }
48
- const method = (input.retainDocument && input.launch?.preparedImagePath === undefined) ||
49
- input.launch?.shutdownMode === "process-cleanup"
69
+ const method = (input.retainDocument &&
70
+ input.resources.launch?.preparedImagePath === undefined) ||
71
+ input.resources.launch?.shutdownMode === "process-cleanup"
50
72
  ? "shutdown"
51
73
  : "shutdown_document";
52
74
  const shutdown = await input
@@ -54,22 +76,19 @@ const requestShutdown = async (input, state) => {
54
76
  .catch((cause) => err(shutdownRequestFailure(method, cause)));
55
77
  if (shutdown.ok &&
56
78
  isHopperCleanupRequired(shutdown.value) &&
57
- input.launch?.shutdownMode === "process-cleanup") {
58
- state.cleanupResult = await input.launch
79
+ input.resources.launch?.shutdownMode === "process-cleanup") {
80
+ state.cleanupResult = await input.resources.launch
59
81
  .cleanup()
60
82
  .catch(providerCleanupFailure);
61
83
  if (!state.cleanupResult.cleaned) {
62
- state.shutdownConfirmed = await fallbackDocumentShutdown(input);
63
- state.cleanupResult = await input.launch
64
- .cleanup()
65
- .catch(providerCleanupFailure);
84
+ input.resources.shutdownConfirmed = await fallbackDocumentShutdown(input);
66
85
  }
67
86
  }
68
87
  else if (shutdown.ok) {
69
- state.shutdownConfirmed = isHopperShutdownAcknowledgement(shutdown.value);
88
+ input.resources.shutdownConfirmed = isHopperShutdownAcknowledgement(shutdown.value);
70
89
  }
71
90
  if (!shutdown.ok ||
72
- (!state.shutdownConfirmed && state.cleanupResult === undefined))
91
+ (!input.resources.shutdownConfirmed && state.cleanupResult === undefined))
73
92
  input.logger.warn({
74
93
  status: shutdown.ok ? "invalid-acknowledgement" : "failed",
75
94
  ...(shutdown.ok ? {} : shutdownFailureDetails(shutdown.error)),
@@ -125,7 +144,7 @@ const describeFailureCause = (cause) => {
125
144
  return { type: typeof cause };
126
145
  };
127
146
  const stopProcess = async (input, state) => {
128
- const supervisor = input.processSupervisor;
147
+ const supervisor = input.resources.processSupervisor;
129
148
  if (supervisor === undefined)
130
149
  return;
131
150
  const stopped = await supervisor.stop(state.cleanupResult === undefined
@@ -141,9 +160,11 @@ const stopProcess = async (input, state) => {
141
160
  }
142
161
  input.logger.info(diagnostic, "Owned Hopper launcher shutdown completed");
143
162
  if (stopped.status !== "incomplete") {
144
- if (input.launch?.shutdownMode === "process-cleanup" &&
163
+ if (input.resources.launch?.shutdownMode === "process-cleanup" &&
145
164
  stopped.status !== "not-owned")
146
- state.shutdownConfirmed = true;
165
+ input.resources.shutdownConfirmed = true;
166
+ state.processStopped = true;
167
+ input.resources.processSupervisor = undefined;
147
168
  return;
148
169
  }
149
170
  const processGroupId = supervisor.launch.ownership?.processGroupId;
@@ -155,8 +176,14 @@ const stopProcess = async (input, state) => {
155
176
  input.logger.warn({ reason: stopped.reason }, "Owned launcher cleanup failed closed");
156
177
  };
157
178
  const recordUnconfirmedDocument = (input, state) => {
158
- if ((input.socket === undefined && input.launch === undefined) ||
159
- state.shutdownConfirmed)
179
+ if (input.socket === undefined &&
180
+ state.processStopped &&
181
+ input.resources.launch?.providerLifetime === "launcher-process") {
182
+ // Startup never connected a document; the verified provider lifetime ended.
183
+ input.resources.shutdownConfirmed = true;
184
+ }
185
+ if ((input.socket === undefined && input.resources.launch === undefined) ||
186
+ input.resources.shutdownConfirmed)
160
187
  return;
161
188
  state.resources.add("hopper-document");
162
189
  state.issues.push({
@@ -166,9 +193,11 @@ const recordUnconfirmedDocument = (input, state) => {
166
193
  : `bridge operation ${input.activeRequest.operation} remained active after caller ${input.activeRequest.callerState}`,
167
194
  });
168
195
  };
169
- const closeRuntimeRoot = async (runtimeRoot, state) => {
196
+ const closeRuntimeRoot = async (input, state) => {
197
+ const runtimeRoot = input.resources.runtimeRoot;
170
198
  try {
171
199
  await runtimeRoot?.close();
200
+ input.resources.runtimeRoot = undefined;
172
201
  }
173
202
  catch (cause) {
174
203
  const resource = runtimeRoot?.path ?? "hopper-runtime-root";
@@ -186,9 +215,9 @@ const cleanupOutcome = (input, state) => {
186
215
  return ok(null);
187
216
  return err(new ProviderCleanupError("hopper", [...state.resources], {
188
217
  issues: cleanupIssueDetails(state.issues),
189
- ...(input.runtimeRoot === undefined
218
+ ...(input.resources.runtimeRoot === undefined
190
219
  ? {}
191
- : { runtime_root: input.runtimeRoot.path }),
220
+ : { runtime_root: input.resources.runtimeRoot.path }),
192
221
  ...(input.activeRequest === null
193
222
  ? {}
194
223
  : { active_request: activityDetails(input.activeRequest) }),