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
@@ -1,5 +1,5 @@
1
1
  import { reconcileCapturedWebScript, stableWebScriptKey, } from "../domain/webInventory.js";
2
- import { requiredRecord, sourceExcluded, sourceResult, cdpStringValue, } from "./CdpCaptureValues.js";
2
+ import { requiredScriptSource, sourceExcluded, sourceResult, } from "./CdpCaptureValues.js";
3
3
  export const captureScripts = async (options) => {
4
4
  const { context, events, rawResources, resources, frameIds } = options;
5
5
  const state = {
@@ -42,8 +42,7 @@ const buildScriptDraft = async (script, state) => {
42
42
  };
43
43
  const captureScriptSource = async (script, state) => {
44
44
  const { context } = state;
45
- const result = requiredRecord(await context.connection.send("Debugger.getScriptSource", { scriptId: script.scriptId }, context.sessionId, context.signal));
46
- const content = cdpStringValue(result.scriptSource) ?? "";
45
+ const content = requiredScriptSource(await context.connection.send("Debugger.getScriptSource", { scriptId: script.scriptId }, context.sessionId, context.signal), context.operation);
47
46
  return sourceResult(content);
48
47
  };
49
48
  const keyAndBuildInventory = (drafts, scriptCount) => {
@@ -56,7 +56,7 @@ const parseCsp = (value, baseUrl, allowedOrigins) => {
56
56
  for (const rawDirective of (value ?? "").split(";")) {
57
57
  const [rawName, ...tokens] = rawDirective.trim().split(/\s+/u);
58
58
  const name = (rawName ?? "").toLowerCase();
59
- if (!/^[a-z][a-z0-9-]*$/u.test(name))
59
+ if (!/^[a-z][a-z0-9\x2d]*$/u.test(name))
60
60
  continue;
61
61
  const sources = [];
62
62
  for (const token of tokens) {
@@ -79,9 +79,9 @@ const parseCsp = (value, baseUrl, allowedOrigins) => {
79
79
  };
80
80
  const cspSource = (token, baseUrl, allowedOrigins) => {
81
81
  const lower = token.toLowerCase();
82
- if (/^'[a-z0-9-]+'$/u.test(lower))
82
+ if (/^'[a-z0-9\x2d]+'$/u.test(lower))
83
83
  return { kind: "keyword", value: lower };
84
- if (/^[a-z][a-z0-9+.-]*:$/u.test(lower))
84
+ if (/^[a-z][a-z0-9+.\x2d]*:$/u.test(lower))
85
85
  return { kind: "scheme", value: lower };
86
86
  const hostOrigin = cspHostSourceOrigin(token, baseUrl);
87
87
  if (hostOrigin === undefined)
@@ -98,14 +98,14 @@ const cspSource = (token, baseUrl, allowedOrigins) => {
98
98
  * `undefined` when the token is not a host-source at all.
99
99
  */
100
100
  const cspHostSourceOrigin = (token, baseUrl) => {
101
- const match = /^(?:([a-z][a-z0-9+.-]*):\/\/)?([^/?#]+)(?:\/[^?#]*)?$/iu.exec(token);
101
+ const match = /^(?:([a-z][a-z0-9+.\x2d]*):\/\/)?([^\x2f?#]+)(?:\/[^?#]*)?$/iu.exec(token);
102
102
  const authority = match?.[2];
103
103
  if (authority === undefined || authority.length === 0)
104
104
  return undefined;
105
105
  const scheme = (match?.[1] ?? schemeOf(baseUrl))?.toLowerCase();
106
- if (scheme === undefined || !/^[a-z][a-z0-9+.-]*$/u.test(scheme))
106
+ if (scheme === undefined || !/^[a-z][a-z0-9+.\x2d]*$/u.test(scheme))
107
107
  return undefined;
108
- if (!/^(?:\*|(?:\*\.)?[a-z0-9-]+(?:\.[a-z0-9-]+)*\.?)(?::(?:\*|\d+))?$/iu.test(authority))
108
+ if (!/^(?:\*|(?:\*\.)?[a-z0-9\x2d]+(?:\.[a-z0-9\x2d]+)*\.?)(?::(?:\*|\d+))?$/iu.test(authority))
109
109
  return undefined;
110
110
  if (authority.includes("*"))
111
111
  return null;
@@ -194,7 +194,7 @@ const linkParameters = (value) => {
194
194
  const name = (separator < 0 ? raw : raw.slice(0, separator))
195
195
  .trim()
196
196
  .toLowerCase();
197
- if (!/^[a-z][a-z0-9-]*$/u.test(name))
197
+ if (!/^[a-z][a-z0-9\x2d]*$/u.test(name))
198
198
  continue;
199
199
  const parameter = separator < 0 ? "" : raw.slice(separator + 1).trim();
200
200
  parameters.set(name, unquote(parameter));
@@ -221,7 +221,7 @@ const permissionFeatures = (value) => [
221
221
  ...new Set((value ?? "")
222
222
  .split(",")
223
223
  .map((entry) => entry.split("=", 1)[0]?.trim().toLowerCase() ?? "")
224
- .filter((feature) => /^[a-z][a-z0-9-]*$/u.test(feature))),
224
+ .filter((feature) => /^[a-z][a-z0-9\x2d]*$/u.test(feature))),
225
225
  ].sort();
226
226
  const wellKnownHint = (url) => {
227
227
  try {
@@ -259,7 +259,7 @@ const referrerPolicy = (value) => {
259
259
  const token = raw.trim().toLowerCase();
260
260
  if (token === "")
261
261
  continue;
262
- if (!/^[a-z-]+$/u.test(token))
262
+ if (!/^[a-z\x2d]+$/u.test(token))
263
263
  return null;
264
264
  if (referrerPolicies.has(token))
265
265
  policy = token;
@@ -268,7 +268,7 @@ const referrerPolicy = (value) => {
268
268
  };
269
269
  const policyToken = (value) => {
270
270
  const token = (value ?? "").trim().toLowerCase();
271
- return /^[a-z][a-z0-9_.-]*$/u.test(token) ? token : null;
271
+ return /^[a-z][a-z0-9_.\x2d]*$/u.test(token) ? token : null;
272
272
  };
273
273
  const nonnegativeInteger = (value) => {
274
274
  const number = numberValue(value === undefined ? undefined : Number(value));
@@ -1,17 +1,11 @@
1
- import { browserScenarioCaptureSchema, classifyBrowserScenarioCompleteness, browserScenarioStepSchema, browserStepArtifactsSchema, } from "../domain/browserScenarioCapture.js";
1
+ import { browserScenarioCaptureSchema, } from "../domain/browserScenarioCapture.js";
2
+ import { classifyBrowserScenarioCompleteness, browserScenarioStepSchema, browserStepArtifactsSchema, } from "../domain/browserScenarioCaptureValues.js";
2
3
  import { AnalysisError } from "../domain/analysisErrorBase.js";
3
4
  import { BrowserObservationError } from "../domain/browserObservationError.js";
4
5
  import { ProviderAdapterError } from "../domain/providerAdapterError.js";
5
6
  import { err, ok } from "../domain/result.js";
7
+ import { browserScenarioCleanupObservation, browserScenarioOperationFailure, browserScenarioCaptureData, } from "./BrowserScenarioPartialObservation.js";
6
8
  const OPERATION = "capture_browser_scenario";
7
- let defaultFactory;
8
- const lazyPlaywrightFactory = {
9
- async open(scenario, options) {
10
- defaultFactory ??= import("./PlaywrightScenarioSession.js").then(({ PlaywrightScenarioSessionFactory }) => new PlaywrightScenarioSessionFactory());
11
- return (await defaultFactory).open(scenario, options);
12
- },
13
- };
14
- export { PLAYWRIGHT_BROWSER_SCENARIO_PROVIDER_IDENTITY } from "./providerIdentities.js";
15
9
  import { PLAYWRIGHT_BROWSER_SCENARIO_PROVIDER_IDENTITY } from "./providerIdentities.js";
16
10
  const SNAPSHOT_KINDS = [
17
11
  "screenshot",
@@ -147,7 +141,7 @@ const runScenario = async (factory, scenario, options) => {
147
141
  const startedAt = Date.now();
148
142
  const session = await factory.open(scenario, options.signal === undefined ? {} : { signal: options.signal });
149
143
  const steps = [];
150
- let cleanup;
144
+ let operationOutcome = { ok: true };
151
145
  try {
152
146
  steps.push(await initialStep({
153
147
  session,
@@ -169,49 +163,70 @@ const runScenario = async (factory, scenario, options) => {
169
163
  failed ||= step.status !== "completed";
170
164
  }
171
165
  }
172
- finally {
173
- cleanup = await session.close();
166
+ catch (cause) {
167
+ operationOutcome = { ok: false, cause };
168
+ }
169
+ let cleanupOutcome;
170
+ try {
171
+ cleanupOutcome = { ok: true, cleanup: await session.close() };
172
+ }
173
+ catch (cause) {
174
+ cleanupOutcome = { ok: false, cause };
174
175
  }
175
- const events = session.events();
176
+ if (!cleanupOutcome.ok) {
177
+ const cleanup = browserScenarioCleanupObservation(cleanupOutcome.cause);
178
+ const partialObservation = {
179
+ kind: "browser-scenario-observation",
180
+ capture: browserScenarioCaptureData({
181
+ session,
182
+ scenario,
183
+ startedAt,
184
+ steps,
185
+ cleanup: "incomplete",
186
+ limitations: [
187
+ "Scenario observations are partial because browser cleanup could not be confirmed.",
188
+ ],
189
+ }),
190
+ };
191
+ if (!operationOutcome.ok)
192
+ throw browserScenarioOperationFailure(operationOutcome.cause, partialObservation, { cause: cleanupOutcome.cause });
193
+ throw new BrowserObservationError(OPERATION, "cleanup_failed", {
194
+ cause: cleanupOutcome.cause,
195
+ cleanup,
196
+ partialObservation,
197
+ detail: `Browser scenario cleanup could not be confirmed: ${cleanup.reason}. Collected steps and events are retained in partial_observation. Review the reported resources before retrying.`,
198
+ });
199
+ }
200
+ if (!operationOutcome.ok)
201
+ throw browserScenarioOperationFailure(operationOutcome.cause, {
202
+ kind: "browser-scenario-observation",
203
+ capture: browserScenarioCaptureData({
204
+ session,
205
+ scenario,
206
+ startedAt,
207
+ steps,
208
+ cleanup: cleanupOutcome.cleanup,
209
+ limitations: [
210
+ "Scenario capture ended after an operation failed; uncollected steps are not represented.",
211
+ ],
212
+ }),
213
+ });
176
214
  const completeness = globalCompleteness(scenario, session, steps);
177
215
  return browserScenarioCaptureSchema.parse({
178
- browser: {
179
- mode: session.mode,
180
- process_ownership: session.processOwnership,
181
- cleanup,
182
- product: session.product,
183
- version: session.version,
184
- },
185
- scenario: {
186
- start_origin: new URL(scenario.start_url.url).origin,
187
- action_count: scenario.actions.length,
188
- secret_references: scenario.secrets.map(({ secret_id: id }) => id).sort(),
189
- network_content: scenario.capture.network,
190
- },
191
- duration_ms: Date.now() - startedAt,
192
- steps,
193
- events,
216
+ ...browserScenarioCaptureData({
217
+ session,
218
+ scenario,
219
+ startedAt,
220
+ steps,
221
+ cleanup: cleanupOutcome.cleanup,
222
+ }),
194
223
  completeness,
195
- limitations: [
196
- "Event sequence records provider receipt order; simultaneous browser causality is not inferred.",
197
- "Network content is retained only when selected; response bytes are browser-decoded, not compressed wire bytes.",
198
- "Request bytes are limited to what Playwright exposes; not_exposed does not establish body absence or multipart file coverage.",
199
- "Network content reads settle within 5 seconds each and never wait for unfinished responses or refetch them.",
200
- "Playwright scenario events do not expose request initiator stacks; receipt order does not prove causality.",
201
- "Storage values are hashed only after declared-secret redaction.",
202
- ...(session.eventLimitations?.() ?? []),
203
- ...(session.mode === "connect"
204
- ? [
205
- "CDP attachment cannot recover pre-attach events or guarantee launch-time context options.",
206
- ]
207
- : []),
208
- ],
209
224
  });
210
225
  };
211
226
  /** Controlled Playwright/CDP scenario driver with exact process ownership. */
212
227
  export class PlaywrightBrowserScenarioProvider {
213
228
  factory;
214
- constructor(factory = lazyPlaywrightFactory) {
229
+ constructor(factory) {
215
230
  this.factory = factory;
216
231
  }
217
232
  identity() {
@@ -1,63 +1,9 @@
1
1
  import { z } from "zod";
2
2
  import { BrowserObservationError } from "../domain/browserObservationError.js";
3
+ import { electronActiveTimelineEventSchema, } from "../domain/javascript/electronActiveObservation.js";
3
4
  const OPERATION = "capture_electron_scenario";
4
- const hookEventSchema = z.strictObject({
5
- sequence: z.number().int().min(1),
6
- correlation_id: z.string().nullable(),
7
- kind: z.enum([
8
- "main-handler-invocation",
9
- "main-event-invocation",
10
- "utility-process-fork",
11
- "utility-process-message",
12
- "ipc-main-to-renderer",
13
- "ipc-utility-to-main",
14
- "ipc-renderer-send",
15
- "ipc-renderer-invoke",
16
- "ipc-renderer-post-message",
17
- "app-lifecycle",
18
- "window-lifecycle",
19
- "web-contents-lifecycle",
20
- "navigation",
21
- "shell-attempt",
22
- "process-lifecycle",
23
- "permission",
24
- "popup-attempt",
25
- "download",
26
- "protocol",
27
- "preload",
28
- "native-addon",
29
- "updater",
30
- "error",
31
- ]),
32
- event: z.string().nullable(),
33
- phase: z.enum(["attempted", "completed", "blocked", "failed", "observed"]),
34
- channel: z.string().nullable(),
35
- direction: z
36
- .enum([
37
- "renderer-to-main",
38
- "main-to-renderer",
39
- "main-to-utility",
40
- "utility-to-main",
41
- ])
42
- .nullable(),
43
- sender: z.string().nullable(),
44
- receiver: z.string().nullable(),
45
- frame: z.string().nullable(),
46
- target: z.string().nullable(),
47
- argument_shapes: z.array(z.string()),
48
- result_shape: z.string().nullable(),
49
- process_type: z.string().nullable(),
50
- source: z.string(),
51
- capture_method: z.enum(["api-wrapper", "event-emitter", "process-hook"]),
52
- artifact_path: z.string().nullable(),
53
- artifact_sha256: z
54
- .string()
55
- .regex(/^[a-f0-9]{64}$/u)
56
- .nullable(),
57
- error: z.boolean(),
58
- });
59
5
  const hookSnapshotSchema = z.strictObject({
60
- events: z.array(hookEventSchema),
6
+ events: z.array(electronActiveTimelineEventSchema),
61
7
  retention_budget_bytes: z.number().int().min(0),
62
8
  estimated_retained_bytes: z.number().int().min(0),
63
9
  event_serialized_byte_upper_bound: z.number().int().min(0),
@@ -14,12 +14,16 @@ import { runElectronActions, readApplicationState, runWithExecutionLimits, } fro
14
14
  import { projectElectronActiveCapture } from "./PlaywrightElectronActiveProjection.js";
15
15
  const OPERATION = "capture_electron_scenario";
16
16
  const STARTUP_TIMEOUT_MS = 60_000;
17
- /** Public identity for provider-owned Electron runtime experiments. */
18
- export { PLAYWRIGHT_ELECTRON_ACTIVE_PROVIDER_IDENTITY } from "./providerIdentities.js";
19
17
  import { PLAYWRIGHT_ELECTRON_ACTIVE_PROVIDER_IDENTITY } from "./providerIdentities.js";
20
18
  const hookPath = fileURLToPath(new URL("../../scripts/electron-active-hook.cjs", import.meta.url));
21
19
  /** Launch an owned Electron application through the official Playwright API. */
22
20
  export class PlaywrightElectronActiveProvider {
21
+ environment;
22
+ launch;
23
+ constructor(environment, launch = (options) => electron.launch(options)) {
24
+ this.environment = environment;
25
+ this.launch = launch;
26
+ }
23
27
  identity() {
24
28
  return PLAYWRIGHT_ELECTRON_ACTIVE_PROVIDER_IDENTITY;
25
29
  }
@@ -42,10 +46,10 @@ export class PlaywrightElectronActiveProvider {
42
46
  const captureBaseline = await systemProcessOwnershipHost.captureBaseline?.(options.signal);
43
47
  if (options.signal?.aborted)
44
48
  throw new BrowserObservationError(OPERATION, "cancelled");
45
- application = await electron.launch({
49
+ application = await this.launch({
46
50
  executablePath: paths.executable,
47
51
  cwd: paths.root,
48
- env: safeElectronEnvironment(runId),
52
+ env: safeElectronEnvironment(this.environment, runId),
49
53
  args: ["-r", hookPath, paths.application, ...input.args],
50
54
  timeout: Math.max(1, startupDeadline - Date.now()),
51
55
  });
@@ -258,7 +262,7 @@ const canonicalPaths = async (input) => {
258
262
  : await realpath(input.application_root);
259
263
  return { executable, application, root };
260
264
  };
261
- const safeElectronEnvironment = (runId) => Object.fromEntries([
265
+ const safeElectronEnvironment = (environment, runId) => Object.fromEntries([
262
266
  ...[
263
267
  "HOME",
264
268
  "LANG",
@@ -269,7 +273,7 @@ const safeElectronEnvironment = (runId) => Object.fromEntries([
269
273
  "DISPLAY",
270
274
  "WAYLAND_DISPLAY",
271
275
  ]
272
- .map((name) => [name, process.env[name]])
276
+ .map((name) => [name, environment[name]])
273
277
  .filter((entry) => entry[1] !== undefined),
274
278
  ["REA_PROCESS_RUN_ID", runId],
275
279
  ]);
@@ -1,6 +1,6 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { z } from "zod";
3
- import { browserStepArtifactsSchema, } from "../domain/browserScenarioCapture.js";
3
+ import { browserStepArtifactsSchema, } from "../domain/browserScenarioCaptureValues.js";
4
4
  const historyValueSchema = z.strictObject({
5
5
  length: z.number().int().min(0),
6
6
  navigation_entries: z.array(z.strictObject({
@@ -2,9 +2,90 @@ import { chmod, mkdtemp, rm } from "node:fs/promises";
2
2
  import { tmpdir } from "node:os";
3
3
  import { join, resolve } from "node:path";
4
4
  import { chromium, } from "playwright-core";
5
+ import { AnalysisError } from "../domain/analysisErrorBase.js";
5
6
  import { BrowserObservationError } from "../domain/browserObservationError.js";
6
7
  import { withPlaywrightExecutionBoundary } from "./PlaywrightExecutionBoundary.js";
7
8
  const OPERATION = "capture_browser_scenario";
9
+ /** Owns one browser connection and optional private profile through cleanup retries. */
10
+ export class PlaywrightScenarioBrowserCleanupOwner {
11
+ resources;
12
+ #browserClosed = false;
13
+ #profileRemoved;
14
+ #closePromise;
15
+ #eventFinalizationPromise;
16
+ /** Keep the narrow provider actions needed to release one opened browser. */
17
+ constructor(resources) {
18
+ this.resources = resources;
19
+ this.#profileRemoved = resources.removeProfile === undefined;
20
+ }
21
+ close(finishEvents, signal) {
22
+ const cleanup = this.#closePromise ?? this.#closeResources(finishEvents);
23
+ if (this.#closePromise === undefined) {
24
+ this.#closePromise = cleanup;
25
+ void cleanup.catch(() => {
26
+ if (this.#closePromise === cleanup)
27
+ this.#closePromise = undefined;
28
+ });
29
+ }
30
+ return this.#awaitCleanup(cleanup, signal);
31
+ }
32
+ async #awaitCleanup(cleanup, signal) {
33
+ try {
34
+ await withPlaywrightExecutionBoundary(() => cleanup, 1_000, signal);
35
+ }
36
+ catch (cause) {
37
+ throw new BrowserObservationError(OPERATION, "cleanup_failed", {
38
+ cause,
39
+ cleanup: {
40
+ reason: cause instanceof Error ? cause.message : String(cause),
41
+ resources: [
42
+ "browser_transport",
43
+ ...(this.resources.removeProfile === undefined
44
+ ? []
45
+ : ["browser_profile"]),
46
+ ],
47
+ },
48
+ });
49
+ }
50
+ }
51
+ async #closeResources(finishEvents) {
52
+ const failures = [];
53
+ const eventFinalization = (this.#eventFinalizationPromise ??=
54
+ Promise.resolve().then(async () => {
55
+ await finishEvents?.();
56
+ }));
57
+ try {
58
+ await eventFinalization;
59
+ }
60
+ catch (cause) {
61
+ failures.push(cause);
62
+ }
63
+ if (!this.#browserClosed) {
64
+ try {
65
+ await this.resources.closeBrowser();
66
+ this.#browserClosed = true;
67
+ }
68
+ catch (cause) {
69
+ failures.push(cause);
70
+ }
71
+ }
72
+ if (this.#browserClosed &&
73
+ !this.#profileRemoved &&
74
+ this.resources.removeProfile !== undefined) {
75
+ try {
76
+ await this.resources.removeProfile();
77
+ this.#profileRemoved = true;
78
+ }
79
+ catch (cause) {
80
+ failures.push(cause);
81
+ }
82
+ }
83
+ if (failures.length === 1)
84
+ throw failures[0];
85
+ if (failures.length > 1)
86
+ throw new AggregateError(failures, "Browser session cleanup failed");
87
+ }
88
+ }
8
89
  const allowedBrowserEnvironment = (environment) => {
9
90
  const allowed = [
10
91
  "DBUS_SESSION_BUS_ADDRESS",
@@ -69,23 +150,57 @@ const configureAttachedEnvironment = async (context, page, scenario) => {
69
150
  await session.detach();
70
151
  }
71
152
  };
72
- export const openPlaywrightScenarioBrowser = async (scenario, environment) => {
153
+ /** Preserve an operation failure while reporting any incomplete cleanup. */
154
+ export const failBrowserScenarioOperation = async (cleanup, primaryFailure, fallbackCleanupResources = ["browser_transport"]) => {
155
+ try {
156
+ await cleanup();
157
+ }
158
+ catch (cleanupFailure) {
159
+ const cleanupDetails = cleanupFailure instanceof AnalysisError &&
160
+ cleanupFailure.cleanup !== undefined
161
+ ? cleanupFailure.cleanup
162
+ : {
163
+ reason: cleanupFailure instanceof Error
164
+ ? cleanupFailure.message
165
+ : String(cleanupFailure),
166
+ resources: cleanupFailure instanceof AnalysisError
167
+ ? cleanupFailure.cleanupResources
168
+ : fallbackCleanupResources,
169
+ };
170
+ throw new BrowserObservationError(OPERATION, "cleanup_failed", {
171
+ cause: new AggregateError([primaryFailure, cleanupFailure], "Browser scenario operation and cleanup both failed", { cause: primaryFailure }),
172
+ cleanup: cleanupDetails,
173
+ });
174
+ }
175
+ throw primaryFailure;
176
+ };
177
+ /** Launch or attach using the caller-selected environment and browser engine. */
178
+ export const openPlaywrightScenarioBrowser = async (scenario, environment, launcher = chromium) => {
73
179
  if (scenario.browser.mode === "connect") {
74
- const browser = await chromium.connectOverCDP(scenario.browser.cdp_endpoint, { timeout: 0 });
180
+ const browser = await launcher.connectOverCDP(scenario.browser.cdp_endpoint, { timeout: 0 });
181
+ const cleanup = new PlaywrightScenarioBrowserCleanupOwner({
182
+ closeBrowser: () => browser.close(),
183
+ removeProfile: undefined,
184
+ });
75
185
  try {
76
186
  const target = await findConnectedPage(browser, scenario.browser.target_id);
77
187
  await configureAttachedEnvironment(target.context, target.page, scenario);
78
- return { ...target, browser, profilePath: undefined };
188
+ return {
189
+ ...target,
190
+ browser,
191
+ profilePath: undefined,
192
+ cleanup,
193
+ };
79
194
  }
80
195
  catch (cause) {
81
- await browser.close();
82
- throw cause;
196
+ return failBrowserScenarioOperation(() => cleanup.close(), cause);
83
197
  }
84
198
  }
85
199
  const profilePath = await mkdtemp(join(tmpdir(), "rea-browser-scenario-"));
86
- await chmod(profilePath, 0o700);
200
+ let context;
87
201
  try {
88
- const context = await chromium.launchPersistentContext(profilePath, {
202
+ await chmod(profilePath, 0o700);
203
+ context = await launcher.launchPersistentContext(profilePath, {
89
204
  executablePath: resolve(scenario.browser.executable_path),
90
205
  headless: scenario.browser.headless,
91
206
  acceptDownloads: false,
@@ -105,43 +220,28 @@ export const openPlaywrightScenarioBrowser = async (scenario, environment) => {
105
220
  handleSIGTERM: false,
106
221
  timeout: 0,
107
222
  });
108
- const browser = context.browser();
109
- if (browser === null) {
110
- await context.close();
111
- throw new BrowserObservationError(OPERATION, "protocol_error");
112
- }
113
- const page = context.pages()[0] ?? (await context.newPage());
114
- return { context, page, browser, profilePath };
115
223
  }
116
224
  catch (cause) {
117
- await rm(profilePath, { recursive: true, force: true, maxRetries: 3 });
118
- throw cause;
225
+ return failBrowserScenarioOperation(() => rm(profilePath, { recursive: true, force: true, maxRetries: 3 }), cause, ["browser_profile"]);
119
226
  }
120
- };
121
- export const closePlaywrightScenarioBrowser = async ({ context, browser, profilePath }, signal) => {
122
- const cleanup = (async () => {
123
- try {
124
- // In connect mode Playwright's Browser.close disconnects its CDP client;
125
- // it does not close the externally owned browser process.
126
- if (profilePath === undefined)
127
- await browser.close();
128
- else
129
- await context.close();
130
- }
131
- finally {
132
- if (profilePath !== undefined)
133
- await rm(profilePath, { recursive: true, force: true, maxRetries: 3 });
134
- }
135
- })();
136
- // best-effort cleanup: the bounded execution boundary below observes the
137
- // same cleanup promise; this early attachment only prevents unhandled rejection.
138
- void cleanup.catch(() => undefined);
139
- // The shared execution boundary rejects cancellation/timeouts instead of
140
- // returning a successful capture whose browser or profile may still exist.
227
+ const cleanup = new PlaywrightScenarioBrowserCleanupOwner({
228
+ closeBrowser: () => context.close(),
229
+ removeProfile: () => rm(profilePath, { recursive: true, force: true, maxRetries: 3 }),
230
+ });
141
231
  try {
142
- await withPlaywrightExecutionBoundary(() => cleanup, 1_000, signal);
232
+ const browser = context.browser();
233
+ if (browser === null)
234
+ throw new BrowserObservationError(OPERATION, "protocol_error");
235
+ const page = context.pages()[0] ?? (await context.newPage());
236
+ return {
237
+ context,
238
+ page,
239
+ browser,
240
+ profilePath,
241
+ cleanup,
242
+ };
143
243
  }
144
244
  catch (cause) {
145
- throw new BrowserObservationError(OPERATION, "cleanup_failed", { cause });
245
+ return failBrowserScenarioOperation(() => cleanup.close(), cause);
146
246
  }
147
247
  };
@@ -1,4 +1,4 @@
1
- import { browserScenarioEventSchema, } from "../domain/browserScenarioCapture.js";
1
+ import { browserScenarioEventSchema, } from "../domain/browserScenarioCaptureValues.js";
2
2
  import { PlaywrightScenarioNetwork } from "./network/PlaywrightScenarioNetwork.js";
3
3
  /** Arrival-ordered Playwright event capture with current-step attribution. */
4
4
  export class PlaywrightScenarioEvents {