rea-agents 6.2.0 → 6.4.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 (636) hide show
  1. package/README.md +24 -23
  2. package/bridge/ghidra/ReaGhidraApplySeeds.java +151 -0
  3. package/bridge/ghidra/ReaGhidraBridge.java +597 -209
  4. package/bridge/ghidra/ReaGhidraNoReturnFix.java +123 -0
  5. package/bridge/hopper_bridge.py +2 -0
  6. package/dist/adb/AdbConfiguration.js +88 -0
  7. package/dist/adb/AdbDeviceOutput.js +186 -0
  8. package/dist/adb/AdbProvider.js +1190 -0
  9. package/dist/adb/AdbShellOutput.js +309 -0
  10. package/dist/android/AndroidTargetSnapshot.js +104 -22
  11. package/dist/android/JadxConfiguration.js +44 -24
  12. package/dist/android/JadxProvider.js +59 -21
  13. package/dist/android/JadxSession.js +51 -9
  14. package/dist/apktool/ApktoolConfiguration.js +84 -0
  15. package/dist/apktool/ApktoolDecodeOutput.js +59 -0
  16. package/dist/apktool/ApktoolProvider.js +506 -0
  17. package/dist/application/AnalysisProvider.js +8 -2
  18. package/dist/application/AppBundleExecutable.js +27 -22
  19. package/dist/application/BinaryTargetResolver.js +85 -19
  20. package/dist/application/BrowserScenarioEvidence.js +2 -2
  21. package/dist/application/CapabilityInventory.js +11 -1
  22. package/dist/application/ClientConfigurationDocument.js +98 -0
  23. package/dist/application/ClientConfigurationFiles.js +91 -0
  24. package/dist/application/ClientRegistrationEnvironment.js +35 -0
  25. package/dist/application/ClientRegistrationStatus.js +75 -27
  26. package/dist/application/DirectAnalysis.js +14 -8
  27. package/dist/application/DirectAnalysisCleanup.js +1 -2
  28. package/dist/application/DirectAnalysisStatus.js +3 -6
  29. package/dist/application/Doctor.js +27 -34
  30. package/dist/application/DoctorDiagnostics.js +1 -1
  31. package/dist/application/EvidenceBundleCommands.js +6 -12
  32. package/dist/application/EvidenceBundleFiles.js +1 -1
  33. package/dist/application/GeminiClientSettings.js +139 -0
  34. package/dist/application/HermesClientHome.js +115 -0
  35. package/dist/application/HopperDownload.js +39 -0
  36. package/dist/application/InvestigationProviders.js +10 -4
  37. package/dist/application/JsonFiles.js +16 -15
  38. package/dist/application/JsonInputFile.js +252 -0
  39. package/dist/application/LinuxHopper.js +6 -13
  40. package/dist/application/MacHopper.js +172 -149
  41. package/dist/application/MipsElfAbiFlags.js +140 -0
  42. package/dist/application/ProviderOperationExecution.js +31 -0
  43. package/dist/application/ReconstructionObligationCandidates.js +16 -3
  44. package/dist/application/ReconstructionObligationLedgerProjection.js +3 -1
  45. package/dist/application/ReferenceSourceImport.js +76 -29
  46. package/dist/application/ReferenceSourceImportEntries.js +18 -9
  47. package/dist/application/ReferenceSourceImportPolicy.js +99 -23
  48. package/dist/application/ReferenceSourceImportTypes.js +30 -22
  49. package/dist/application/ReferenceSourceVcsAdapter.js +145 -30
  50. package/dist/application/RegularFileRead.js +103 -0
  51. package/dist/application/Setup.js +69 -10
  52. package/dist/application/SetupClientConfiguration.js +134 -23
  53. package/dist/application/SetupHost.js +102 -22
  54. package/dist/application/SetupPlan.js +18 -17
  55. package/dist/application/SetupSkill.js +81 -13
  56. package/dist/application/SupportedClients.js +305 -37
  57. package/dist/application/Uninstall.js +172 -8
  58. package/dist/application/UpdateMaintenance.js +23 -23
  59. package/dist/application/Utf8JsonInput.js +71 -0
  60. package/dist/application/WebScriptExportService.js +130 -57
  61. package/dist/application/WebSourceLocationService.js +3 -0
  62. package/dist/application/adb/AdbDeviceAnalysisPort.js +1 -0
  63. package/dist/application/adb/AdbDeviceAnalysisService.js +13 -0
  64. package/dist/application/analysisView/AnalysisViewService.js +40 -2
  65. package/dist/application/android/AndroidAnalysisService.js +1 -1
  66. package/dist/application/apktool/ApktoolResourceAnalysisPort.js +1 -0
  67. package/dist/application/apktool/ApktoolResourceAnalysisService.js +13 -0
  68. package/dist/application/binary/AnalysisClientCleanup.js +0 -24
  69. package/dist/application/binary/AnalysisSnapshotCache.js +5 -4
  70. package/dist/application/binary/BinarySession.js +18 -1
  71. package/dist/application/binary/BinarySessionOpen.js +9 -1
  72. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +2 -1
  73. package/dist/application/binaryDiagnostics/PeResourcesPort.js +1 -0
  74. package/dist/application/binaryDiagnostics/PeResourcesService.js +111 -0
  75. package/dist/application/binaryDiagnostics/RecordedCrashService.js +2 -1
  76. package/dist/application/evm/EvmInterfaceService.js +3 -0
  77. package/dist/application/firmware/FirmwareAnalysisService.js +3 -0
  78. package/dist/application/investigation/InspectEvidenceBundle.js +18 -0
  79. package/dist/application/javascript/ElectronActiveEvidence.js +2 -2
  80. package/dist/application/javascript/ElectronBoundaryAnalysis.js +2 -2
  81. package/dist/application/javascript/ElectronBoundaryGraphContext.js +3 -2
  82. package/dist/application/javascript/ElectronBoundaryGraphIpc.js +2 -2
  83. package/dist/application/javascript/ElectronBoundaryGraphNative.js +20 -3
  84. package/dist/application/javascript/ElectronBoundaryGraphWindows.js +3 -3
  85. package/dist/application/javascript/JavaScriptApplicationEvidence.js +1 -0
  86. package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +107 -46
  87. package/dist/application/javascript/JavaScriptApplicationService.js +23 -11
  88. package/dist/application/javascript/JavaScriptApplicationWorkflowEvidence.js +5 -6
  89. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +59 -45
  90. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +171 -36
  91. package/dist/application/javascript/JavaScriptArtifactGraphAccumulator.js +14 -16
  92. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +74 -36
  93. package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +4 -3
  94. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +11 -5
  95. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +53 -42
  96. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +92 -10
  97. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +293 -238
  98. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +120 -28
  99. package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +4 -0
  100. package/dist/application/javascript/JavaScriptJsonModules.js +2 -2
  101. package/dist/application/javascript/JavaScriptModuleRelationships.js +10 -20
  102. package/dist/application/javascript/JavaScriptRecoveryService.js +3 -0
  103. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +11 -27
  104. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +11 -5
  105. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +206 -66
  106. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -1
  107. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +18 -23
  108. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +5 -2
  109. package/dist/application/javascript/JavaScriptSemanticGraphEvidence.js +1 -1
  110. package/dist/application/javascript/JavaScriptSemanticGraphFingerprintProjection.js +2 -2
  111. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +7 -5
  112. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +6 -4
  113. package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +4 -4
  114. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +1 -1
  115. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +29 -15
  116. package/dist/application/javascript/JavaScriptSemanticTraceService.js +15 -10
  117. package/dist/application/jeb/JebAnalysisPort.js +1 -0
  118. package/dist/application/jeb/JebAnalysisService.js +13 -0
  119. package/dist/application/managed/ManagedApplicationGraphService.js +1 -1
  120. package/dist/application/native/NativeCallRoutes.js +2 -4
  121. package/dist/application/native/NativeUiActionTrace.js +16 -8
  122. package/dist/application/native/NativeValueTrace.js +23 -6
  123. package/dist/application/process/ProcessCli.js +25 -20
  124. package/dist/artifacts/ArtifactPaths.js +129 -8
  125. package/dist/artifacts/ArtifactProvider.js +34 -31
  126. package/dist/artifacts/ArtifactProviderMetadata.js +1 -4
  127. package/dist/artifacts/ArtifactReader.js +23 -0
  128. package/dist/artifacts/ArtifactResourceScope.js +100 -0
  129. package/dist/artifacts/AsarArtifactReader.js +218 -80
  130. package/dist/artifacts/AsarHeader.js +24 -0
  131. package/dist/artifacts/DirectoryArtifactReader.js +168 -65
  132. package/dist/artifacts/MachOSliceArtifactReader.js +116 -39
  133. package/dist/artifacts/NativeDmgArtifactReader.js +179 -87
  134. package/dist/artifacts/NativeDmgOwnership.js +109 -0
  135. package/dist/artifacts/SafeOutputTree.js +245 -70
  136. package/dist/artifacts/SafeOutputTreeCleanup.js +45 -0
  137. package/dist/artifacts/SafeOutputTreeCreationFailure.js +20 -0
  138. package/dist/artifacts/SafeOutputTreeIdentity.js +42 -0
  139. package/dist/artifacts/SafeOutputTreeReadback.js +33 -0
  140. package/dist/artifacts/ZipArtifactReader.js +77 -27
  141. package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +58 -18
  142. package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +62 -24
  143. package/dist/artifacts/apple/KeyedArchiveReader.js +76 -49
  144. package/dist/artifacts/apple/MachoLoadCommandReader.js +36 -6
  145. package/dist/artifacts/extraction/ArtifactExtraction.js +134 -92
  146. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +116 -50
  147. package/dist/artifacts/inventory/ArtifactInventory.js +5 -4
  148. package/dist/artifacts/inventory/classify.js +87 -25
  149. package/dist/artifacts/inventory/hashStableRootArtifact.js +70 -0
  150. package/dist/artifacts/inventory/reader.js +13 -5
  151. package/dist/artifacts/inventory/scanCanonical.js +73 -30
  152. package/dist/artifacts/inventory/scanReader.js +43 -20
  153. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +72 -28
  154. package/dist/artifacts/javascript/JavaScriptSourceAnalysis.js +3 -0
  155. package/dist/browser/BrowserScenarioPartialObservation.js +8 -2
  156. package/dist/browser/BrowserScenarioSecrets.js +52 -37
  157. package/dist/browser/CdpBrowserProvider.js +9 -3
  158. package/dist/browser/CdpCaptureDocuments.js +40 -6
  159. package/dist/browser/CdpCaptureDomSvg.js +210 -0
  160. package/dist/browser/CdpCaptureEventBodyShapes.js +4 -8
  161. package/dist/browser/CdpCaptureEventHandlers.js +26 -9
  162. package/dist/browser/CdpCaptureEvents.js +4 -9
  163. package/dist/browser/CdpCaptureStorageFingerprints.js +3 -3
  164. package/dist/browser/CdpConnection.js +22 -5
  165. package/dist/browser/CdpElectronInspection.js +2 -2
  166. package/dist/browser/CdpElectronProvider.js +4 -3
  167. package/dist/browser/CdpElectronScripts.js +2 -2
  168. package/dist/browser/CdpPageCapture.js +1 -1
  169. package/dist/browser/CdpTargetSession.js +30 -34
  170. package/dist/browser/CdpWebMcpDiscovery.js +48 -23
  171. package/dist/browser/ElectronFileScope.js +99 -9
  172. package/dist/browser/PlaywrightBrowserScenarioProvider.js +63 -7
  173. package/dist/browser/PlaywrightElectronActiveProvider.js +11 -6
  174. package/dist/browser/PlaywrightScenarioArtifacts.js +5 -5
  175. package/dist/browser/PlaywrightScenarioBrowser.js +208 -43
  176. package/dist/browser/PlaywrightScenarioSession.js +130 -65
  177. package/dist/browser/PlaywrightScenarioStorage.js +507 -0
  178. package/dist/browser/PngVisualDiff.js +198 -29
  179. package/dist/browser/WebSourceMapFetcher.js +35 -9
  180. package/dist/browser/assets/LocalWebScriptArtifacts.js +3 -1
  181. package/dist/browser/assets/PublishWebScripts.js +75 -20
  182. package/dist/browser/assets/ScenarioScriptCapture.js +8 -12
  183. package/dist/browser/assets/WebArtifactReads.js +23 -1
  184. package/dist/browser/assets/WebSourceLocationArtifacts.js +1 -0
  185. package/dist/browser/execution/CdpExecutionCapture.js +3 -3
  186. package/dist/browser/execution/CdpPreciseCoverage.js +5 -8
  187. package/dist/browser/history/HarCapture.js +14 -0
  188. package/dist/browser/history/HarCaptureProcess.js +2 -10
  189. package/dist/browser/history/MitmproxyCaptureAdapter.js +3 -1
  190. package/dist/browser/modules/WebModuleArtifacts.js +1 -0
  191. package/dist/cli/adbCommands.js +337 -0
  192. package/dist/cli/analysisViewCommands.js +39 -1
  193. package/dist/cli/apktoolCommands.js +53 -0
  194. package/dist/cli/artifactCommands.js +8 -11
  195. package/dist/cli/binaryDiagnosticsCommands.js +19 -1
  196. package/dist/cli/browserAdvancedCommands.js +65 -36
  197. package/dist/cli/coreAnalysisCommands.js +2 -2
  198. package/dist/cli/coreBinaryCommands.js +12 -13
  199. package/dist/cli/coreNativeCommands.js +1 -14
  200. package/dist/cli/electronCommands.js +14 -10
  201. package/dist/cli/evmCommands.js +13 -4
  202. package/dist/cli/firmwareCommands.js +7 -2
  203. package/dist/cli/javascriptApplicationAnalysis.js +19 -13
  204. package/dist/cli/javascriptRecoveryCommands.js +22 -15
  205. package/dist/cli/jebCommands.js +99 -0
  206. package/dist/cli/jsonOutput.js +12 -4
  207. package/dist/cli/referenceSourceImportStatus.js +7 -0
  208. package/dist/cli/setupCommands.js +15 -3
  209. package/dist/cli/streamedJsonOutput.js +83 -4
  210. package/dist/cli/utilityCommands.js +68 -22
  211. package/dist/cli/webScriptCommands.js +20 -1
  212. package/dist/cli/webSourceLocationCommands.js +21 -9
  213. package/dist/cli.js +11 -2
  214. package/dist/cliBrowserScenarioCommands.js +2 -1
  215. package/dist/cliCommandNames.js +32 -0
  216. package/dist/cliJsonInput.js +47 -34
  217. package/dist/cliObservationOptions.js +7 -0
  218. package/dist/composition/adb.js +3 -0
  219. package/dist/composition/apktool.js +3 -0
  220. package/dist/composition/auxiliaryAnalysisProviders.js +5 -4
  221. package/dist/composition/binaryDiagnostics.js +4 -0
  222. package/dist/composition/browserScenario.js +2 -2
  223. package/dist/composition/directAnalysis.js +14 -7
  224. package/dist/composition/javascriptAnalysisWorkerProcess.js +48 -0
  225. package/dist/composition/jeb.js +6 -0
  226. package/dist/config/environment.js +10 -0
  227. package/dist/config/ghidraLanguageOverride.js +9 -0
  228. package/dist/config/mcpInputSchemaProfile.js +27 -0
  229. package/dist/config/parseConfig.js +28 -1
  230. package/dist/contracts/adb/adbToolContracts.js +353 -0
  231. package/dist/contracts/advertisedInputExamples.js +48 -0
  232. package/dist/contracts/analysisDetail.js +10 -0
  233. package/dist/contracts/analysisViewToolContracts.js +17 -2
  234. package/dist/contracts/apktool/apktoolToolContracts.js +33 -0
  235. package/dist/contracts/artifactComparisonExample.js +5 -5
  236. package/dist/contracts/artifactToolContracts.js +8 -5
  237. package/dist/contracts/browserToolContracts.js +1 -1
  238. package/dist/contracts/compactInputSchema.js +256 -0
  239. package/dist/contracts/errorSchemas.js +3 -1
  240. package/dist/contracts/functionComparisonExample.js +8 -0
  241. package/dist/contracts/functionWorkflowToolContracts.js +1 -1
  242. package/dist/contracts/inputSchemaPresentation.js +104 -13
  243. package/dist/contracts/javascript/electronToolContracts.js +16 -3
  244. package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +3 -2
  245. package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +6 -3
  246. package/dist/contracts/javascript/javascriptRecoveryToolContracts.js +1 -1
  247. package/dist/contracts/javascript/javascriptRuntimeReconciliationExample.js +8 -7
  248. package/dist/contracts/jeb/jebToolContracts.js +64 -0
  249. package/dist/contracts/managed/managedToolContracts.js +3 -2
  250. package/dist/contracts/mobileApplicationGraphExamples.js +5 -5
  251. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +25 -3
  252. package/dist/contracts/native/nativeToolContracts.js +1 -1
  253. package/dist/contracts/officialToolContracts.js +5 -5
  254. package/dist/contracts/sessionLifecycleInputs.js +4 -3
  255. package/dist/contracts/sessionStatusContract.js +3 -2
  256. package/dist/contracts/sessionToolContracts.js +5 -4
  257. package/dist/contracts/sessionToolSchemas.js +9 -4
  258. package/dist/contracts/toolContractExamples.js +6 -0
  259. package/dist/contracts/toolContractTypes.js +3 -0
  260. package/dist/contracts/toolContracts.js +6 -0
  261. package/dist/contracts/toolEffects.js +167 -0
  262. package/dist/contracts/toolOutputSchemaGroups.js +7 -5
  263. package/dist/contracts/toolOutputSchemaPrimitives.js +2 -5
  264. package/dist/contracts/toolSchemaMetadata.js +82 -7
  265. package/dist/domain/adb/adbDeviceAnalysis.js +583 -0
  266. package/dist/domain/analysisErrorBase.js +5 -0
  267. package/dist/domain/analysisErrorCleanup.js +29 -0
  268. package/dist/domain/analysisErrorPresentation.js +18 -4
  269. package/dist/domain/analysisErrorProjection.js +4 -1
  270. package/dist/domain/analysisSnapshot.js +5 -2
  271. package/dist/domain/analysisView/analysisView.js +53 -5
  272. package/dist/domain/analysisView/binaryLayoutView.js +2 -0
  273. package/dist/domain/analysisView/javascriptApplicationView.js +2 -0
  274. package/dist/domain/analysisView/nativeFunctionView.js +155 -0
  275. package/dist/domain/android/androidApplication.js +25 -20
  276. package/dist/domain/android/androidPartialObservation.js +36 -0
  277. package/dist/domain/apktool/apktoolResourceAnalysis.js +77 -0
  278. package/dist/domain/apple/appleApplication.js +40 -23
  279. package/dist/domain/apple/appleBundleAnatomy.js +95 -28
  280. package/dist/domain/apple/dyldPaths.js +9 -1
  281. package/dist/domain/apple/dylibResolution.js +3 -3
  282. package/dist/domain/apple/interfaceBuilderGraph.js +22 -19
  283. package/dist/domain/apple/interfaceBuilderKeyedArchive.js +10 -1
  284. package/dist/domain/artifactComparison.js +39 -11
  285. package/dist/domain/artifactGraph.js +6 -4
  286. package/dist/domain/artifactIdentity.js +37 -9
  287. package/dist/domain/artifactInspection.js +10 -50
  288. package/dist/domain/artifactIntegrityPolicy.js +10 -0
  289. package/dist/domain/artifactInventoryEvidence.js +16 -17
  290. package/dist/domain/artifactPathSyntax.js +1 -1
  291. package/dist/domain/binaryTarget.js +16 -0
  292. package/dist/domain/binaryTargetTypes.js +8 -1
  293. package/dist/domain/browserCompleteness.js +3 -2
  294. package/dist/domain/browserObservationSchemas.js +8 -4
  295. package/dist/domain/browserScenarioCaptureValues.js +2 -2
  296. package/dist/domain/browserScenarioNormalization.js +3 -3
  297. package/dist/domain/browserScenarioValues.js +3 -2
  298. package/dist/domain/callPath.js +8 -10
  299. package/dist/domain/canonicalDigest.js +7 -1
  300. package/dist/domain/canonicalJsonDigestSteps.js +34 -12
  301. package/dist/domain/canonicalOrdering.js +1 -13
  302. package/dist/domain/changedBehavior.js +2 -3
  303. package/dist/domain/compactStringIdentity.js +9 -0
  304. package/dist/domain/comparisonSemantics.js +0 -5
  305. package/dist/domain/digests.js +0 -3
  306. package/dist/domain/evidence.js +12 -6
  307. package/dist/domain/evidenceBundle.js +51 -33
  308. package/dist/domain/evidenceRecordSummary.js +144 -0
  309. package/dist/domain/firmware/firmwareAnalysis.js +4 -3
  310. package/dist/domain/functionComparison.js +2 -1
  311. package/dist/domain/functionComparisonNormalization.js +4 -3
  312. package/dist/domain/functionComparisonResults.js +2 -2
  313. package/dist/domain/functionDossierEvidence.js +2 -1
  314. package/dist/domain/hopperValues.js +11 -15
  315. package/dist/domain/inputIssueProjection.js +16 -1
  316. package/dist/domain/javascript/electronActiveObservation.js +4 -3
  317. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +14 -15
  318. package/dist/domain/javascript/electronStaticAnalysisIpc.js +20 -21
  319. package/dist/domain/javascript/electronStaticAnalysisNative.js +73 -41
  320. package/dist/domain/javascript/electronStaticAnalysisValues.js +24 -4
  321. package/dist/domain/javascript/javascriptAnalysisResourceControls.js +45 -0
  322. package/dist/domain/javascript/javascriptApplicationAnalysis.js +6 -1
  323. package/dist/domain/javascript/javascriptApplicationChangeGraph.js +18 -14
  324. package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +4 -0
  325. package/dist/domain/javascript/javascriptApplicationGraph.js +91 -28
  326. package/dist/domain/javascript/javascriptApplicationProjectionResources.js +35 -0
  327. package/dist/domain/javascript/javascriptApplicationVersionComparison.js +4 -4
  328. package/dist/domain/javascript/javascriptApplicationVersionComparisonSchemas.js +37 -22
  329. package/dist/domain/javascript/javascriptApplicationVersionItems.js +72 -45
  330. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +16 -8
  331. package/dist/domain/javascript/javascriptAstFingerprint.js +60 -33
  332. package/dist/domain/javascript/javascriptAstValues.js +54 -0
  333. package/dist/domain/javascript/javascriptElectronMemberWrites.js +50 -0
  334. package/dist/domain/javascript/javascriptExportShapeComparison.js +3 -2
  335. package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +31 -23
  336. package/dist/domain/javascript/javascriptExportShapeSelection.js +2 -2
  337. package/dist/domain/javascript/javascriptExportShapeVariants.js +3 -2
  338. package/dist/domain/javascript/javascriptFeatureSeed.js +5 -3
  339. package/dist/domain/javascript/javascriptFeatureTrace.js +7 -6
  340. package/dist/domain/javascript/javascriptFeatureTraceSchemas.js +17 -9
  341. package/dist/domain/javascript/javascriptFeatureTraversal.js +4 -4
  342. package/dist/domain/javascript/javascriptModuleSemanticIr.js +15 -0
  343. package/dist/domain/javascript/javascriptNativeHandoff.js +12 -7
  344. package/dist/domain/javascript/javascriptRpcEndpoints.js +253 -0
  345. package/dist/domain/javascript/javascriptRuntimeLoadState.js +1 -3
  346. package/dist/domain/javascript/javascriptRuntimeObservation.js +8 -5
  347. package/dist/domain/javascript/javascriptRuntimeReconciliation.js +12 -6
  348. package/dist/domain/javascript/javascriptRuntimeReconciliationActive.js +9 -8
  349. package/dist/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js +212 -0
  350. package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +12 -6
  351. package/dist/domain/javascript/javascriptRuntimeReconciliationInputValidation.js +28 -0
  352. package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +5 -5
  353. package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +12 -223
  354. package/dist/domain/javascript/javascriptRuntimeReconciliationResult.js +2 -2
  355. package/dist/domain/javascript/javascriptRuntimeReconciliationRuntime.js +15 -4
  356. package/dist/domain/javascript/javascriptRuntimeReconciliationSchemas.js +2 -2
  357. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +15 -17
  358. package/dist/domain/javascript/javascriptSemanticAnalysis.js +379 -30
  359. package/dist/domain/javascript/javascriptSemanticCallResolution.js +9 -7
  360. package/dist/domain/javascript/javascriptSemanticCallableResults.js +42 -0
  361. package/dist/domain/javascript/javascriptSemanticCalls.js +8 -1
  362. package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -2
  363. package/dist/domain/javascript/javascriptSemanticCoverage.js +20 -0
  364. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +7 -9
  365. package/dist/domain/javascript/javascriptSemanticDataEffects.js +4 -11
  366. package/dist/domain/javascript/javascriptSemanticDerivedAnalysis.js +15 -4
  367. package/dist/domain/javascript/javascriptSemanticFileProjection.js +1 -0
  368. package/dist/domain/javascript/javascriptSemanticFingerprints.js +43 -42
  369. package/dist/domain/javascript/javascriptSemanticGraph.js +205 -52
  370. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +21 -11
  371. package/dist/domain/javascript/javascriptSemanticIr.js +0 -4
  372. package/dist/domain/javascript/javascriptSemanticIterationSources.js +139 -0
  373. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +774 -136
  374. package/dist/domain/javascript/javascriptSemanticMutationInitializers.js +190 -0
  375. package/dist/domain/javascript/javascriptSemanticMutationValues.js +98 -41
  376. package/dist/domain/javascript/javascriptSemanticObjectReferences.js +381 -0
  377. package/dist/domain/javascript/javascriptSemanticObjects.js +9 -7
  378. package/dist/domain/javascript/javascriptSemanticPrimitives.js +7 -2
  379. package/dist/domain/javascript/javascriptSemanticProjection.js +72 -28
  380. package/dist/domain/javascript/javascriptSemanticPromises.js +15 -21
  381. package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +100 -0
  382. package/dist/domain/javascript/javascriptSemanticProvenance.js +3 -3
  383. package/dist/domain/javascript/javascriptSemanticQuery.js +33 -29
  384. package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +4 -5
  385. package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -9
  386. package/dist/domain/javascript/javascriptSemanticRequireOrigin.js +16 -10
  387. package/dist/domain/javascript/javascriptSemanticReturnedReferences.js +219 -0
  388. package/dist/domain/javascript/javascriptSemanticReturns.js +34 -48
  389. package/dist/domain/javascript/javascriptSemanticState.js +22 -2
  390. package/dist/domain/javascript/javascriptSemanticTraversal.js +25 -2
  391. package/dist/domain/javascript/javascriptSemanticValues.js +169 -30
  392. package/dist/domain/javascript/javascriptSourceAnalysis.js +1 -0
  393. package/dist/domain/javascript/javascriptSourceMapPaths.js +11 -1
  394. package/dist/domain/javascript/javascriptSourceParser.js +34 -9
  395. package/dist/domain/javascript/javascriptStaticAnalysis.js +29 -17
  396. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +13 -12
  397. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +49 -5
  398. package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +8 -4
  399. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +26 -15
  400. package/dist/domain/javascript/javascriptStaticAnalysisState.js +1 -0
  401. package/dist/domain/javascript/sourceToBundleComparison.js +7 -5
  402. package/dist/domain/javascript/sourceToBundleSignals.js +7 -7
  403. package/dist/domain/jeb/jebAnalysis.js +114 -0
  404. package/dist/domain/jsonSerialization.js +109 -55
  405. package/dist/domain/jsonShape.js +69 -31
  406. package/dist/domain/jsonValue.js +3 -0
  407. package/dist/domain/localPath.js +10 -4
  408. package/dist/domain/managed/managedApplicationGraph.js +47 -6
  409. package/dist/domain/managed/managedApplicationGraphCoverage.js +8 -2
  410. package/dist/domain/managed/managedApplicationGraphNodes.js +94 -59
  411. package/dist/domain/managed/managedArtifact.js +1 -0
  412. package/dist/domain/managed/managedInspectionEvidence.js +13 -0
  413. package/dist/domain/managed/managedMemberComparisonMatch.js +6 -7
  414. package/dist/domain/native/nativeAotPe.js +1408 -0
  415. package/dist/domain/native/nativeCallObservation.js +2 -4
  416. package/dist/domain/native/nativeInstruction.js +21 -0
  417. package/dist/domain/native/nativeMetadataRecovery.js +79 -6
  418. package/dist/domain/native/nativeValueFlow.js +5 -11
  419. package/dist/domain/native/objcSwiftMetadata.js +15 -17
  420. package/dist/domain/native/peResources.js +94 -0
  421. package/dist/domain/nativeConvention.js +33 -0
  422. package/dist/domain/process/processCapture.js +102 -11
  423. package/dist/domain/process/processCaptureCoverage.js +8 -5
  424. package/dist/domain/process/processCaptureExample.js +67 -0
  425. package/dist/domain/process/processCaptureValidation.js +83 -3
  426. package/dist/domain/process/processComparison.js +0 -23
  427. package/dist/domain/process/processScenario.js +62 -10
  428. package/dist/domain/process/processTraceEvaluation.js +4 -4
  429. package/dist/domain/process/processTraceSpecification.js +1 -3
  430. package/dist/domain/propertyListKeys.js +3 -1
  431. package/dist/domain/providerCleanupError.js +6 -2
  432. package/dist/domain/reconstructionCoverage.js +2 -1
  433. package/dist/domain/reconstructionUnknowns.js +4 -3
  434. package/dist/domain/reconstructionVerification.js +3 -2
  435. package/dist/domain/referenceSourceGraph.js +32 -23
  436. package/dist/domain/referenceSourceImportParsing.js +40 -48
  437. package/dist/domain/referenceSourcePathIdentity.js +22 -0
  438. package/dist/domain/referenceSourceRequireBindings.js +137 -0
  439. package/dist/domain/residualUnknown.js +3 -2
  440. package/dist/domain/staticRuntimeCorrelation.js +2 -1
  441. package/dist/domain/swiftSymbolClassification.js +6 -1
  442. package/dist/domain/symbolAnalysis.js +17 -2
  443. package/dist/domain/unicodeCodePointOrder.js +6 -0
  444. package/dist/domain/webBundleAnalyzerInspection.js +23 -3
  445. package/dist/domain/webCaptureDiff.js +170 -30
  446. package/dist/domain/webCaptureDiffSchemas.js +2 -8
  447. package/dist/domain/webInventory.js +3 -2
  448. package/dist/domain/webMcpDiscovery.js +4 -3
  449. package/dist/domain/webScriptExport.js +1 -1
  450. package/dist/domain/webScriptExportError.js +10 -4
  451. package/dist/domain/webScriptExportPlan.js +7 -13
  452. package/dist/domain/zipPackageFormat.js +4 -1
  453. package/dist/domain/zodCollectionSteps.js +24 -0
  454. package/dist/dotnet/ManagedArtifactInspector.js +55 -43
  455. package/dist/dotnet/ManagedDecodeBudget.js +80 -0
  456. package/dist/dotnet/ManagedMemberInspector.js +13 -6
  457. package/dist/dotnet/ManagedMemberInspectorCore.js +2 -2
  458. package/dist/dotnet/ManagedMemberInstructionDecoder.js +5 -4
  459. package/dist/dotnet/ManagedMemberRows.js +9 -4
  460. package/dist/dotnet/ManagedMetadataHeaps.js +15 -5
  461. package/dist/dotnet/ManagedMetadataInventoryRows.js +20 -11
  462. package/dist/dotnet/ManagedMetadataLayout.js +10 -4
  463. package/dist/dotnet/ManagedMethodBodyReader.js +8 -3
  464. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +3 -2
  465. package/dist/dotnet/ManagedNativeBoundaryInspector.js +49 -34
  466. package/dist/dotnet/ManagedPeReader.js +41 -25
  467. package/dist/dotnet/ManagedReaderFailure.js +2 -1
  468. package/dist/dotnet/ManagedStaticProvider.js +65 -31
  469. package/dist/dotnet/ManagedStaticProviderMetadata.js +1 -4
  470. package/dist/evaluation/AgentEvaluationReport.js +9 -5
  471. package/dist/evaluation/CodexAgentEval.js +43 -13
  472. package/dist/evm/EvmoleFailures.js +0 -2
  473. package/dist/evm/EvmoleInterfaceProvider.js +67 -2
  474. package/dist/filesystem/OwnedDirectoryHandle.js +29 -0
  475. package/dist/filesystem/OwnedFileHandle.js +36 -0
  476. package/dist/filesystem/RegularFile.js +73 -0
  477. package/dist/filesystem/StableFileHash.js +46 -0
  478. package/dist/filesystem/readFileHandleChunks.js +26 -0
  479. package/dist/firmware/FirmwareCommand.js +25 -3
  480. package/dist/firmware/FirmwareFiles.js +23 -8
  481. package/dist/firmware/FirmwareProvider.js +156 -32
  482. package/dist/firmware/FirmwarePublication.js +24 -3
  483. package/dist/firmware/FirmwareRelease.js +1 -0
  484. package/dist/generatedPackageMetadata.js +2 -2
  485. package/dist/ghidra/GhidraAnalysisProfile.js +55 -4
  486. package/dist/ghidra/GhidraAnalysisSeeds.js +211 -0
  487. package/dist/ghidra/GhidraClient.js +90 -8
  488. package/dist/ghidra/GhidraDiagnostics.js +11 -8
  489. package/dist/ghidra/GhidraFunctionValues.js +26 -2
  490. package/dist/ghidra/GhidraInstallation.js +111 -10
  491. package/dist/ghidra/GhidraInventoryValues.js +23 -1
  492. package/dist/ghidra/GhidraLanguageCatalog.js +99 -0
  493. package/dist/ghidra/GhidraLauncher.js +123 -58
  494. package/dist/ghidra/GhidraLoadImageAttest.js +49 -2
  495. package/dist/ghidra/GhidraMipsProfile.js +79 -0
  496. package/dist/ghidra/GhidraProvider.js +57 -9
  497. package/dist/ghidra/GhidraProviderCapabilities.js +18 -8
  498. package/dist/ghidra/GhidraProviderClient.js +282 -21
  499. package/dist/ghidra/GhidraSessionValues.js +9 -2
  500. package/dist/hopper/HopperAnalysisProfile.js +2 -0
  501. package/dist/hopper/HopperCleanup.js +1 -1
  502. package/dist/hopper/HopperClient.js +15 -6
  503. package/dist/hopper/HopperMachOImage.js +2 -0
  504. package/dist/hopper/HopperProvider.js +13 -2
  505. package/dist/ida/IdaOperationRunner.js +10 -2
  506. package/dist/ida/IdaProvider.js +7 -0
  507. package/dist/ida/IdaSessionClient.js +7 -3
  508. package/dist/ida/IdaWorkspace.js +4 -2
  509. package/dist/inspector/JavaScriptRuntimeScope.js +9 -5
  510. package/dist/inspector/V8InspectorCaptureProjection.js +46 -13
  511. package/dist/inspector/V8InspectorProvider.js +60 -8
  512. package/dist/javascript/analysis/JavaScriptAnalysisTransfer.js +326 -0
  513. package/dist/javascript/analysis/JavaScriptAnalysisWorker.js +520 -0
  514. package/dist/javascript/analysis/JavaScriptAnalysisWorkerProtocol.js +63 -0
  515. package/dist/javascript/analysis/JavaScriptAnalysisWorkerSchemas.js +521 -0
  516. package/dist/javascript/analysis/JavaScriptAnalysisWorkerServer.js +116 -0
  517. package/dist/javascript/recovery/RecoveryFiles.js +18 -7
  518. package/dist/javascript/recovery/WakaruCommand.js +22 -9
  519. package/dist/javascript/recovery/WakaruExecution.js +11 -7
  520. package/dist/javascript/recovery/WakaruProvider.js +139 -16
  521. package/dist/javascript/recovery/WakaruPublication.js +14 -4
  522. package/dist/javascript/recovery/WakaruRelease.js +10 -3
  523. package/dist/javascript/recovery/WakaruReport.js +12 -7
  524. package/dist/javascript/recovery/WakaruVersion.js +24 -0
  525. package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -3
  526. package/dist/javascript/sourceMaps/SourceMapDecoder.js +63 -7
  527. package/dist/javascript/sourceMaps/SourceMapFormat.js +15 -4
  528. package/dist/jeb/JebMcpConnection.js +179 -0
  529. package/dist/jeb/JebMcpEndpoint.js +40 -0
  530. package/dist/jeb/JebProvider.js +299 -0
  531. package/dist/main/shutdown.js +76 -32
  532. package/dist/main/transport.js +1 -1
  533. package/dist/mcpDoctor.js +15 -6
  534. package/dist/native/AppleDispatchCoverage.js +25 -12
  535. package/dist/native/AppleDispatchMetadata.js +14 -7
  536. package/dist/native/AppleMachoFixups.js +71 -15
  537. package/dist/native/AppleMachoSelection.js +23 -3
  538. package/dist/native/AppleObjcDispatchFacets.js +3 -3
  539. package/dist/native/AppleObjcProperties.js +17 -7
  540. package/dist/native/LldbCallTracer.js +241 -75
  541. package/dist/native/NativeMacOSProvider.js +100 -20
  542. package/dist/native/NativeMacOSProviderMetadata.js +1 -2
  543. package/dist/native/NativeMachoInspection.js +11 -7
  544. package/dist/native/NativeUiHelperRuntime.js +6 -1
  545. package/dist/native/NativeUiObservation.js +4 -3
  546. package/dist/native/pe/PeResourceLayout.js +120 -0
  547. package/dist/native/pe/PeResourceParser.js +286 -0
  548. package/dist/native/pe/PeResourcesProvider.js +63 -0
  549. package/dist/process/BoundedFileBytes.js +30 -7
  550. package/dist/process/DarwinProcessRunTokenReader.js +8 -3
  551. package/dist/process/OwnedCommand.js +4 -3
  552. package/dist/process/ProcessOwnership.js +104 -112
  553. package/dist/process/ProcessOwnershipObservation.js +104 -51
  554. package/dist/process/ProcessOwnershipProcessTree.js +4 -4
  555. package/dist/process/ProcessRunTokenObservations.js +48 -0
  556. package/dist/process/ProviderDiagnosticRedaction.js +17 -0
  557. package/dist/process/ProviderProcess.js +4 -3
  558. package/dist/process/capture/FilesystemSnapshot.js +116 -22
  559. package/dist/process/capture/ProcessCaptureLifecycle.js +363 -86
  560. package/dist/process/capture/ProcessCaptureProgress.js +62 -0
  561. package/dist/process/capture/ProcessFilesystemEffects.js +19 -4
  562. package/dist/process/capture/ProcessHarness.js +202 -47
  563. package/dist/process/capture/ProcessNormalization.js +3 -1
  564. package/dist/process/capture/ProcessScenarioRuntimeValidation.js +5 -2
  565. package/dist/process/capture/TerminalRenderer.js +24 -7
  566. package/dist/reference/ReferenceSourceReader.js +22 -5
  567. package/dist/reference/ReferenceSourceReaderEntries.js +114 -51
  568. package/dist/reference/ReferenceSourceReaderErrors.js +12 -0
  569. package/dist/reference/ReferenceSourceReaderFile.js +50 -10
  570. package/dist/reference/ReferenceSourceReaderValidate.js +4 -4
  571. package/dist/server/EvidenceMcpServer.js +36 -1
  572. package/dist/server/admittedToolOperation.js +9 -0
  573. package/dist/server/analysisAdmission.js +8 -0
  574. package/dist/server/contractToolHandler.js +21 -0
  575. package/dist/server/createServer.js +118 -47
  576. package/dist/server/registerAdbTools.js +36 -0
  577. package/dist/server/registerAnalysisViewTool.js +4 -9
  578. package/dist/server/registerAndroidTools.js +3 -12
  579. package/dist/server/registerApktoolTools.js +14 -0
  580. package/dist/server/registerApplicationTools/compareExportShapes.js +6 -7
  581. package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
  582. package/dist/server/registerApplicationTools/compareVersions.js +3 -2
  583. package/dist/server/registerApplicationTools/coverage.js +3 -2
  584. package/dist/server/registerApplicationTools/helpers.js +3 -2
  585. package/dist/server/registerApplicationTools/obligationLedger.js +3 -2
  586. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -2
  587. package/dist/server/registerApplicationTools/traceFeature.js +3 -2
  588. package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
  589. package/dist/server/registerArtifactComparisonTool.js +5 -2
  590. package/dist/server/registerArtifactTools.js +2 -2
  591. package/dist/server/registerBinaryDiagnosticsTools.js +16 -4
  592. package/dist/server/registerBrowserScenarioTool.js +10 -7
  593. package/dist/server/registerBrowserTools.js +12 -9
  594. package/dist/server/registerBundleComparisonTool.js +16 -2
  595. package/dist/server/registerCloseLifecycleTool.js +36 -5
  596. package/dist/server/registerElectronTools.js +28 -10
  597. package/dist/server/registerEnhancedTools.js +78 -73
  598. package/dist/server/registerEvidenceTools.js +54 -46
  599. package/dist/server/registerEvmTools.js +4 -9
  600. package/dist/server/registerFirmwareTools.js +3 -11
  601. package/dist/server/registerFunctionComparisonTool.js +5 -2
  602. package/dist/server/registerJavaScriptRecoveryTool.js +4 -9
  603. package/dist/server/registerJavaScriptRuntimeObservationTools.js +9 -6
  604. package/dist/server/registerJebTools.js +16 -0
  605. package/dist/server/registerManagedTools.js +7 -4
  606. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -6
  607. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -2
  608. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +3 -2
  609. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +3 -2
  610. package/dist/server/registerOfficialTools.js +31 -25
  611. package/dist/server/registerPeResourcesTool.js +9 -0
  612. package/dist/server/registerProcessComparisonTool.js +5 -2
  613. package/dist/server/registerRecordedCrashTools.js +4 -9
  614. package/dist/server/registerSessionRecordTools.js +2 -1
  615. package/dist/server/registerSessionTools.js +58 -21
  616. package/dist/server/registerWebModuleTool.js +4 -9
  617. package/dist/server/registerWebNetworkCaptureTool.js +4 -9
  618. package/dist/server/registerWebRuntimeTools.js +6 -5
  619. package/dist/server/registerWebScriptTool.js +6 -3
  620. package/dist/server/registerWebSourceLocationTool.js +4 -9
  621. package/dist/server/toolResult.js +21 -2
  622. package/dist/windows/WindowsPrivateRuntime.js +12 -5
  623. package/install.sh +7 -4
  624. package/licenses/nativeaot-parser-MIT.txt +28 -0
  625. package/native/windows/build/manifest.json +2 -2
  626. package/native/windows/build/rea-windows-x64.node +0 -0
  627. package/package.json +38 -7
  628. package/scripts/rea.mjs +16 -1
  629. package/skills/reverse-engineer-anything/SKILL.md +52 -51
  630. package/skills/reverse-engineer-anything/references/connection-and-recovery.md +127 -0
  631. package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -0
  632. package/skills/reverse-engineer-anything/references/javascript-applications.md +92 -13
  633. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +31 -1
  634. package/dist/artifacts/inventory/policy.js +0 -2
  635. package/dist/domain/managed/managedApplicationGraphNodeCoverage.js +0 -6
  636. package/dist/server/registerNativeTools.js +0 -6
@@ -3,9 +3,14 @@ import { tmpdir } from "node:os";
3
3
  import { join, resolve } from "node:path";
4
4
  import { chromium, } from "playwright-core";
5
5
  import { AnalysisError } from "../domain/analysisErrorBase.js";
6
+ import { isLiteralLoopbackHostname } from "../domain/browserObservation.js";
6
7
  import { BrowserObservationError } from "../domain/browserObservationError.js";
7
8
  import { withPlaywrightExecutionBoundary } from "./PlaywrightExecutionBoundary.js";
8
9
  const OPERATION = "capture_browser_scenario";
10
+ const throwIfScenarioCancelled = (signal) => {
11
+ if (signal?.aborted === true)
12
+ throw new BrowserObservationError(OPERATION, "cancelled");
13
+ };
9
14
  /** Owns one browser connection and optional private profile through cleanup retries. */
10
15
  export class PlaywrightScenarioBrowserCleanupOwner {
11
16
  resources;
@@ -18,13 +23,17 @@ export class PlaywrightScenarioBrowserCleanupOwner {
18
23
  this.resources = resources;
19
24
  this.#profileRemoved = resources.removeProfile === undefined;
20
25
  }
26
+ get browserClosed() {
27
+ return this.#browserClosed;
28
+ }
21
29
  close(finishEvents, signal) {
22
30
  const cleanup = this.#closePromise ?? this.#closeResources(finishEvents);
23
31
  if (this.#closePromise === undefined) {
24
32
  this.#closePromise = cleanup;
25
- void cleanup.catch(() => {
33
+ void cleanup.then(() => this.resources.onSettled?.(this.#browserClosed), () => {
26
34
  if (this.#closePromise === cleanup)
27
35
  this.#closePromise = undefined;
36
+ this.resources.onSettled?.(this.#browserClosed);
28
37
  });
29
38
  }
30
39
  return this.#awaitCleanup(cleanup, signal);
@@ -58,6 +67,9 @@ export class PlaywrightScenarioBrowserCleanupOwner {
58
67
  await eventFinalization;
59
68
  }
60
69
  catch (cause) {
70
+ // A failed finalization stays failed: the memoized attempt rejects on
71
+ // every retry so cleanup can never report success for unfinalized
72
+ // events.
61
73
  failures.push(cause);
62
74
  }
63
75
  if (!this.#browserClosed) {
@@ -86,6 +98,88 @@ export class PlaywrightScenarioBrowserCleanupOwner {
86
98
  throw new AggregateError(failures, "Browser session cleanup failed");
87
99
  }
88
100
  }
101
+ const attachedScenarioAdmissions = new Map();
102
+ const releaseAttachedScenario = (key, admission) => {
103
+ const waiter = admission.waiters.shift();
104
+ if (waiter === undefined) {
105
+ admission.active = false;
106
+ if (admission.cleanupOwner === undefined &&
107
+ attachedScenarioAdmissions.get(key) === admission)
108
+ attachedScenarioAdmissions.delete(key);
109
+ return;
110
+ }
111
+ if (waiter.onAbort !== undefined)
112
+ waiter.signal?.removeEventListener("abort", waiter.onAbort);
113
+ if (waiter.signal?.aborted === true) {
114
+ waiter.reject(new BrowserObservationError(OPERATION, "cancelled"));
115
+ releaseAttachedScenario(key, admission);
116
+ return;
117
+ }
118
+ waiter.resolve(createAttachedScenarioRelease(key, admission));
119
+ };
120
+ const createAttachedScenarioRelease = (key, admission) => {
121
+ let released = false;
122
+ return () => {
123
+ if (released)
124
+ return;
125
+ released = true;
126
+ releaseAttachedScenario(key, admission);
127
+ };
128
+ };
129
+ /** One browser admission. The key is the discovery URL this endpoint already parses. */
130
+ export const attachedScenarioLeaseKey = (endpoint, targetId) => {
131
+ const discovery = new URL("/json/version", endpoint);
132
+ // One CDP browser serves every loopback stack on one port, so spellings that
133
+ // reach it through 127.0.0.1 or ::1 must share a single admission.
134
+ if (isLiteralLoopbackHostname(discovery.hostname))
135
+ discovery.hostname = "127.0.0.1";
136
+ return JSON.stringify([discovery.href, targetId]);
137
+ };
138
+ const acquireAttachedScenario = (scenario, signal) => {
139
+ if (signal?.aborted === true)
140
+ return Promise.reject(new BrowserObservationError(OPERATION, "cancelled"));
141
+ const key = attachedScenarioLeaseKey(scenario.cdp_endpoint, scenario.target_id);
142
+ const admission = attachedScenarioAdmissions.get(key) ??
143
+ {
144
+ active: false,
145
+ waiters: [],
146
+ cleanupOwner: undefined,
147
+ };
148
+ attachedScenarioAdmissions.set(key, admission);
149
+ return new Promise((resolve, reject) => {
150
+ const grant = (release) => resolve({ admission, release });
151
+ if (!admission.active) {
152
+ admission.active = true;
153
+ grant(createAttachedScenarioRelease(key, admission));
154
+ return;
155
+ }
156
+ const waiter = {
157
+ signal,
158
+ resolve: (release) => grant(release),
159
+ reject,
160
+ onAbort: undefined,
161
+ };
162
+ admission.waiters.push(waiter);
163
+ if (signal !== undefined) {
164
+ const onAbort = () => {
165
+ const index = admission.waiters.indexOf(waiter);
166
+ if (index < 0)
167
+ return;
168
+ admission.waiters.splice(index, 1);
169
+ signal.removeEventListener("abort", onAbort);
170
+ reject(new BrowserObservationError(OPERATION, "cancelled"));
171
+ if (!admission.active && admission.waiters.length === 0)
172
+ releaseAttachedScenario(key, admission);
173
+ };
174
+ waiter.onAbort = onAbort;
175
+ signal.addEventListener("abort", onAbort, { once: true });
176
+ if (signal.aborted) {
177
+ onAbort();
178
+ return;
179
+ }
180
+ }
181
+ });
182
+ };
89
183
  const allowedBrowserEnvironment = (environment) => {
90
184
  const allowed = [
91
185
  "DBUS_SESSION_BUS_ADDRESS",
@@ -102,16 +196,32 @@ const allowedBrowserEnvironment = (environment) => {
102
196
  "XAUTHORITY",
103
197
  "XDG_RUNTIME_DIR",
104
198
  ];
105
- return Object.fromEntries(allowed
199
+ const selected = Object.fromEntries(allowed
106
200
  .map((name) => [name, environment[name]])
107
201
  .filter((entry) => entry[1] !== undefined));
202
+ if (process.platform !== "android")
203
+ return selected;
204
+ // Android rejects execve() for binaries below Termux's application data
205
+ // directory. Termux supplies an exec interceptor that rewrites those calls
206
+ // through the system linker and removes itself for the launched program.
207
+ // Playwright must retain it for its Chromium child process.
208
+ const prefix = environment.PREFIX;
209
+ if (prefix === undefined)
210
+ return selected;
211
+ return {
212
+ ...selected,
213
+ LD_PRELOAD: `${prefix}/lib/libtermux-exec.so`,
214
+ TERMUX_EXEC__PROC_SELF_EXE: process.execPath,
215
+ };
108
216
  };
109
- const findConnectedPage = async (browser, targetId) => {
217
+ const findConnectedPage = async (browser, targetId, signal) => {
110
218
  for (const context of browser.contexts())
111
219
  for (const page of context.pages()) {
112
220
  const session = await context.newCDPSession(page);
113
221
  try {
222
+ throwIfScenarioCancelled(signal);
114
223
  const { targetInfo } = await session.send("Target.getTargetInfo");
224
+ throwIfScenarioCancelled(signal);
115
225
  if (targetInfo.targetId !== targetId)
116
226
  continue;
117
227
  return { context, page };
@@ -122,33 +232,33 @@ const findConnectedPage = async (browser, targetId) => {
122
232
  }
123
233
  throw new BrowserObservationError(OPERATION, "target_not_found");
124
234
  };
125
- const configureAttachedEnvironment = async (context, page, scenario) => {
126
- await page.setViewportSize({
127
- width: scenario.environment.viewport.width,
128
- height: scenario.environment.viewport.height,
129
- });
235
+ const configureAttachedEnvironment = async (context, page, environment, signal) => {
236
+ // setViewportSize also resizes the external browser window. The scenario's
237
+ // CDP metrics override below supplies the viewport and expires on disconnect.
130
238
  await page.emulateMedia({
131
- colorScheme: scenario.environment.color_scheme,
132
- reducedMotion: scenario.environment.reduced_motion,
239
+ colorScheme: environment.color_scheme,
240
+ reducedMotion: environment.reduced_motion,
133
241
  });
242
+ throwIfScenarioCancelled(signal);
134
243
  const session = await context.newCDPSession(page);
135
- try {
136
- await session.send("Emulation.setDeviceMetricsOverride", {
137
- width: scenario.environment.viewport.width,
138
- height: scenario.environment.viewport.height,
139
- deviceScaleFactor: scenario.environment.viewport.device_scale_factor,
140
- mobile: false,
141
- });
142
- await session.send("Emulation.setLocaleOverride", {
143
- locale: scenario.environment.locale,
144
- });
145
- await session.send("Emulation.setTimezoneOverride", {
146
- timezoneId: scenario.environment.timezone,
147
- });
148
- }
149
- finally {
150
- await session.detach();
151
- }
244
+ throwIfScenarioCancelled(signal);
245
+ // Chromium resets these overrides when the CDP session detaches. Keep it on
246
+ // the scenario transport until cleanup disconnects the attached browser.
247
+ await session.send("Emulation.setDeviceMetricsOverride", {
248
+ width: environment.viewport.width,
249
+ height: environment.viewport.height,
250
+ deviceScaleFactor: environment.viewport.device_scale_factor,
251
+ mobile: false,
252
+ dontSetVisibleSize: true,
253
+ });
254
+ throwIfScenarioCancelled(signal);
255
+ await session.send("Emulation.setLocaleOverride", {
256
+ locale: environment.locale,
257
+ });
258
+ throwIfScenarioCancelled(signal);
259
+ await session.send("Emulation.setTimezoneOverride", {
260
+ timezoneId: environment.timezone,
261
+ });
152
262
  };
153
263
  /** Preserve an operation failure while reporting any incomplete cleanup. */
154
264
  export const failBrowserScenarioOperation = async (cleanup, primaryFailure, fallbackCleanupResources = ["browser_transport"]) => {
@@ -174,28 +284,59 @@ export const failBrowserScenarioOperation = async (cleanup, primaryFailure, fall
174
284
  }
175
285
  throw primaryFailure;
176
286
  };
177
- /** Launch or attach using the caller-selected environment and browser engine. */
178
- export const openPlaywrightScenarioBrowser = async (scenario, environment, launcher = chromium) => {
179
- if (scenario.browser.mode === "connect") {
180
- const browser = await launcher.connectOverCDP(scenario.browser.cdp_endpoint, { timeout: 0 });
287
+ const openAttachedScenarioBrowser = async (browserRequest, environment, launcher, signal, retainCleanup) => {
288
+ const lease = await acquireAttachedScenario(browserRequest, signal);
289
+ let cleanupOwner;
290
+ try {
291
+ const priorOwner = lease.admission.cleanupOwner;
292
+ if (priorOwner !== undefined)
293
+ await priorOwner.close();
294
+ throwIfScenarioCancelled(signal);
295
+ const browser = await launcher.connectOverCDP(browserRequest.cdp_endpoint);
181
296
  const cleanup = new PlaywrightScenarioBrowserCleanupOwner({
182
297
  closeBrowser: () => browser.close(),
298
+ onSettled: (browserClosed) => {
299
+ if (browserClosed && lease.admission.cleanupOwner === cleanup)
300
+ lease.admission.cleanupOwner = undefined;
301
+ lease.release();
302
+ },
183
303
  removeProfile: undefined,
184
304
  });
305
+ cleanupOwner = cleanup;
306
+ lease.admission.cleanupOwner = cleanup;
307
+ throwIfScenarioCancelled(signal);
308
+ const target = await withPlaywrightExecutionBoundary(() => findConnectedPage(browser, browserRequest.target_id, signal), undefined, signal);
309
+ throwIfScenarioCancelled(signal);
310
+ await withPlaywrightExecutionBoundary(() => configureAttachedEnvironment(target.context, target.page, environment, signal), undefined, signal);
311
+ return {
312
+ ...target,
313
+ browser,
314
+ profilePath: undefined,
315
+ cleanup,
316
+ };
317
+ }
318
+ catch (cause) {
319
+ if (cleanupOwner === undefined) {
320
+ lease.release();
321
+ throw cause;
322
+ }
323
+ const cleanup = cleanupOwner;
324
+ const close = () => cleanup.close();
185
325
  try {
186
- const target = await findConnectedPage(browser, scenario.browser.target_id);
187
- await configureAttachedEnvironment(target.context, target.page, scenario);
188
- return {
189
- ...target,
190
- browser,
191
- profilePath: undefined,
192
- cleanup,
193
- };
326
+ return await failBrowserScenarioOperation(close, cause);
194
327
  }
195
- catch (cause) {
196
- return failBrowserScenarioOperation(() => cleanup.close(), cause);
328
+ catch (failure) {
329
+ if (failure !== cause)
330
+ retainCleanup?.(close);
331
+ throw failure;
197
332
  }
198
333
  }
334
+ };
335
+ /** Launch or attach using the caller-selected environment and browser engine. */
336
+ export const openPlaywrightScenarioBrowser = async (scenario, environment, options = {}) => {
337
+ const launcher = options.launcher ?? chromium;
338
+ if (scenario.browser.mode === "connect")
339
+ return openAttachedScenarioBrowser(scenario.browser, scenario.environment, launcher, options.signal, options.retainCleanup);
199
340
  const profilePath = await mkdtemp(join(tmpdir(), "rea-browser-scenario-"));
200
341
  let context;
201
342
  try {
@@ -219,10 +360,26 @@ export const openPlaywrightScenarioBrowser = async (scenario, environment, launc
219
360
  handleSIGINT: false,
220
361
  handleSIGTERM: false,
221
362
  timeout: 0,
363
+ // Termux's Chromium cannot create its renderer process through Android's
364
+ // executable boundary. Single-process mode keeps the browser and page in
365
+ // the Termux-launched process so scenario navigation remains available.
366
+ args: process.platform === "android"
367
+ ? ["--no-sandbox", "--single-process"]
368
+ : [],
222
369
  });
223
370
  }
224
371
  catch (cause) {
225
- return failBrowserScenarioOperation(() => rm(profilePath, { recursive: true, force: true, maxRetries: 3 }), cause, ["browser_profile"]);
372
+ const cleanup = () => rm(profilePath, { recursive: true, force: true, maxRetries: 3 });
373
+ try {
374
+ return await failBrowserScenarioOperation(cleanup, cause, [
375
+ "browser_profile",
376
+ ]);
377
+ }
378
+ catch (failure) {
379
+ if (failure !== cause)
380
+ options.retainCleanup?.(cleanup);
381
+ throw failure;
382
+ }
226
383
  }
227
384
  const cleanup = new PlaywrightScenarioBrowserCleanupOwner({
228
385
  closeBrowser: () => context.close(),
@@ -242,6 +399,14 @@ export const openPlaywrightScenarioBrowser = async (scenario, environment, launc
242
399
  };
243
400
  }
244
401
  catch (cause) {
245
- return failBrowserScenarioOperation(() => cleanup.close(), cause);
402
+ const close = () => cleanup.close();
403
+ try {
404
+ return await failBrowserScenarioOperation(close, cause);
405
+ }
406
+ catch (failure) {
407
+ if (failure !== cause)
408
+ options.retainCleanup?.(close);
409
+ throw failure;
410
+ }
246
411
  }
247
412
  };
@@ -5,16 +5,21 @@ import { failBrowserScenarioOperation, openPlaywrightScenarioBrowser, } from "./
5
5
  import { performPlaywrightScenarioAction } from "./PlaywrightScenarioActions.js";
6
6
  import { capturePlaywrightStepArtifacts } from "./PlaywrightScenarioArtifacts.js";
7
7
  import { PlaywrightScenarioEvents } from "./PlaywrightScenarioEvents.js";
8
+ import { PlaywrightScenarioStorage } from "./PlaywrightScenarioStorage.js";
8
9
  import { withPlaywrightExecutionBoundary } from "./PlaywrightExecutionBoundary.js";
9
10
  import { browserScenarioCaptureData, browserScenarioOperationFailure, } from "./BrowserScenarioPartialObservation.js";
10
11
  const OPERATION = "capture_browser_scenario";
11
- const storageSeeds = (blocks, secrets) => {
12
- const seeds = {};
13
- for (const { origin, entries } of blocks)
14
- (seeds[origin] ??= []).push(...entries.map(({ name, value }) => [name, secrets.value(value)]));
15
- return seeds;
12
+ const throwIfScenarioCancelled = (signal) => {
13
+ if (signal?.aborted === true)
14
+ throw new BrowserObservationError(OPERATION, "cancelled");
16
15
  };
17
- const installStorageSeeds = async (context, page, scenario, secrets) => {
16
+ const throwCleanupFailures = (failures) => {
17
+ if (failures.length === 1)
18
+ throw failures[0];
19
+ if (failures.length > 1)
20
+ throw new AggregateError(failures, "Browser scenario cleanup failed");
21
+ };
22
+ const installCookies = async (context, scenario, secrets) => {
18
23
  await context.addCookies(scenario.storage.cookies.map((cookie) => ({
19
24
  name: cookie.name,
20
25
  value: secrets.value(cookie.value),
@@ -23,19 +28,6 @@ const installStorageSeeds = async (context, page, scenario, secrets) => {
23
28
  secure: cookie.secure,
24
29
  sameSite: cookie.same_site,
25
30
  })));
26
- const storage = {
27
- local: storageSeeds(scenario.storage.local_storage, secrets),
28
- session: storageSeeds(scenario.storage.session_storage, secrets),
29
- };
30
- const payload = JSON.stringify(storage).replaceAll("<", "\\u003c");
31
- await page.addInitScript(`(() => {
32
- const seeds = ${payload};
33
- const local = seeds.local[window.location.origin] ?? [];
34
- const session = seeds.session[window.location.origin] ?? [];
35
- for (const [name, value] of local) window.localStorage.setItem(name, value);
36
- for (const [name, value] of session)
37
- window.sessionStorage.setItem(name, value);
38
- })()`);
39
31
  };
40
32
  const blockAttachedServiceWorkers = async (page) => {
41
33
  const controller = await page.evaluate("Boolean(navigator.serviceWorker?.controller)");
@@ -58,7 +50,7 @@ const initializePage = async (context, page, scenario, secrets) => {
58
50
  context.setDefaultNavigationTimeout(0);
59
51
  if (scenario.browser.mode === "connect")
60
52
  await blockAttachedServiceWorkers(page);
61
- await installStorageSeeds(context, page, scenario, secrets);
53
+ await installCookies(context, scenario, secrets);
62
54
  };
63
55
  export class PlaywrightScenarioSession {
64
56
  opened;
@@ -69,6 +61,9 @@ export class PlaywrightScenarioSession {
69
61
  initialUrl;
70
62
  secrets;
71
63
  eventCapture;
64
+ storage;
65
+ signal;
66
+ #storageReleased = false;
72
67
  constructor(opened, options) {
73
68
  this.opened = opened;
74
69
  this.mode = options.mode;
@@ -76,70 +71,55 @@ export class PlaywrightScenarioSession {
76
71
  options.mode === "launch" ? "provider-owned" : "external";
77
72
  this.secrets = options.secrets;
78
73
  this.eventCapture = options.eventCapture;
74
+ this.storage = options.storage;
75
+ this.signal = options.signal;
79
76
  this.version = opened.browser.version();
80
77
  this.initialUrl = opened.page.url();
81
78
  }
82
79
  static async open(scenario, environment, options) {
83
- if (options.signal?.aborted === true)
84
- throw new BrowserObservationError(OPERATION, "cancelled");
80
+ throwIfScenarioCancelled(options.signal);
85
81
  const secrets = BrowserScenarioSecrets.resolve(scenario, environment);
86
82
  if (secrets === undefined)
87
83
  throw new BrowserObservationError(OPERATION, "secret_unavailable");
88
84
  const startedAt = Date.now();
89
- const opening = openPlaywrightScenarioBrowser(scenario, environment);
85
+ const opening = openPlaywrightScenarioBrowser(scenario, environment, {
86
+ signal: options.signal,
87
+ ...(options.retainCleanup === undefined
88
+ ? {}
89
+ : { retainCleanup: options.retainCleanup }),
90
+ });
90
91
  let opened;
91
- let events;
92
92
  try {
93
93
  opened = await withPlaywrightExecutionBoundary(() => opening, undefined, options.signal);
94
94
  }
95
95
  catch (cause) {
96
- void opening
97
- .then((lateOpened) => lateOpened.cleanup.close(undefined, options.signal))
98
- .catch((cause) => {
99
- // best-effort cleanup: late-open cleanup must not mask the boundary failure.
100
- void cause;
96
+ const lateCleanup = () => opening.then((lateOpened) => lateOpened.cleanup.close(undefined, options.signal), () => undefined);
97
+ options.retainCleanup?.(() => withPlaywrightExecutionBoundary(lateCleanup, 1_000));
98
+ void lateCleanup().catch((cleanupCause) => {
99
+ // best-effort cleanup: retainCleanup keeps the retry capability.
100
+ void cleanupCause;
101
101
  });
102
102
  throw cause;
103
103
  }
104
- let session;
105
- try {
106
- await withPlaywrightExecutionBoundary(() => initializePage(opened.context, opened.page, scenario, secrets), undefined, options.signal);
107
- events = new PlaywrightScenarioEvents({
108
- page: opened.page,
109
- context: opened.context,
110
- ownsContext: scenario.browser.mode === "launch",
111
- enabled: new Set(scenario.capture.events),
112
- secrets,
113
- network: scenario.capture.network,
114
- ...(options.signal === undefined ? {} : { signal: options.signal }),
115
- });
116
- session = new PlaywrightScenarioSession(opened, {
117
- mode: scenario.browser.mode,
118
- secrets,
119
- eventCapture: events,
120
- });
121
- }
122
- catch (cause) {
123
- return failBrowserScenarioOperation(() => opened.cleanup.close(events === undefined
124
- ? undefined
125
- : () => events?.finish() ?? Promise.resolve(), options.signal), cause);
126
- }
104
+ const session = await this.initializeSession(opened, scenario, secrets, options);
127
105
  try {
128
106
  await withPlaywrightExecutionBoundary(() => opened.page.goto(secrets.url(scenario.start_url), {
129
107
  waitUntil: "load",
130
108
  timeout: 0,
131
109
  }), undefined, options.signal);
110
+ await withPlaywrightExecutionBoundary(() => session.storage?.settle() ?? Promise.resolve(), undefined, options.signal);
132
111
  return session;
133
112
  }
134
113
  catch (cause) {
135
114
  let cleanup;
136
115
  let cleanupFailure;
137
116
  try {
138
- cleanup = await session.close();
117
+ cleanup = await session.close(true);
139
118
  }
140
119
  catch (failure) {
141
120
  cleanup = "incomplete";
142
121
  cleanupFailure = { cause: failure };
122
+ options.retainCleanup?.(() => session.close());
143
123
  }
144
124
  throw browserScenarioOperationFailure(cause, {
145
125
  kind: "browser-scenario-observation",
@@ -156,6 +136,76 @@ export class PlaywrightScenarioSession {
156
136
  }, cleanupFailure);
157
137
  }
158
138
  }
139
+ static async initializeSession(opened, scenario, secrets, options) {
140
+ let events;
141
+ let storage;
142
+ try {
143
+ await withPlaywrightExecutionBoundary(() => initializePage(opened.context, opened.page, scenario, secrets), undefined, options.signal);
144
+ storage = await PlaywrightScenarioStorage.create(opened, scenario, secrets, {
145
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
146
+ ...(options.retainCleanup === undefined
147
+ ? {}
148
+ : { retainCleanup: options.retainCleanup }),
149
+ });
150
+ await storage?.initialize(opened.page, opened.context);
151
+ throwIfScenarioCancelled(options.signal);
152
+ events = new PlaywrightScenarioEvents({
153
+ page: opened.page,
154
+ context: opened.context,
155
+ ownsContext: scenario.browser.mode === "launch",
156
+ enabled: new Set(scenario.capture.events),
157
+ secrets,
158
+ network: scenario.capture.network,
159
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
160
+ });
161
+ return new PlaywrightScenarioSession(opened, {
162
+ mode: scenario.browser.mode,
163
+ secrets,
164
+ eventCapture: events,
165
+ storage,
166
+ signal: options.signal,
167
+ });
168
+ }
169
+ catch (cause) {
170
+ let storageReleased = false;
171
+ const cleanup = async () => {
172
+ let storageFailure;
173
+ let browserFailure;
174
+ if (!storageReleased) {
175
+ try {
176
+ await storage?.close(options.signal?.aborted === true);
177
+ }
178
+ catch (failure) {
179
+ storageFailure = { cause: failure };
180
+ }
181
+ }
182
+ try {
183
+ await opened.cleanup.close(events === undefined
184
+ ? undefined
185
+ : () => events?.finish() ?? Promise.resolve(), options.signal);
186
+ }
187
+ catch (failure) {
188
+ browserFailure = { cause: failure };
189
+ }
190
+ if (opened.cleanup.browserClosed)
191
+ storageReleased = true;
192
+ throwCleanupFailures([
193
+ ...(storageReleased || storageFailure === undefined
194
+ ? []
195
+ : [storageFailure.cause]),
196
+ ...(browserFailure === undefined ? [] : [browserFailure.cause]),
197
+ ]);
198
+ };
199
+ try {
200
+ return await failBrowserScenarioOperation(cleanup, cause);
201
+ }
202
+ catch (failure) {
203
+ if (failure !== cause)
204
+ options.retainCleanup?.(cleanup);
205
+ throw failure;
206
+ }
207
+ }
208
+ }
159
209
  currentUrl() {
160
210
  return this.opened.page.url();
161
211
  }
@@ -184,8 +234,10 @@ export class PlaywrightScenarioSession {
184
234
  action,
185
235
  secrets: this.secrets,
186
236
  }), "timeout_ms" in action ? action.timeout_ms : undefined, signal);
237
+ await withPlaywrightExecutionBoundary(() => this.storage?.settle() ?? Promise.resolve(), undefined, signal);
187
238
  }
188
239
  async capture(requested, signal) {
240
+ await withPlaywrightExecutionBoundary(() => this.storage?.settle() ?? Promise.resolve(), undefined, signal);
189
241
  return withPlaywrightExecutionBoundary(() => capturePlaywrightStepArtifacts({
190
242
  context: this.opened.context,
191
243
  page: this.opened.page,
@@ -193,8 +245,31 @@ export class PlaywrightScenarioSession {
193
245
  requested,
194
246
  }), undefined, signal);
195
247
  }
196
- async close() {
197
- await this.opened.cleanup.close(() => this.eventCapture.finish());
248
+ async close(stopLoading = this.signal?.aborted === true) {
249
+ let storageFailure;
250
+ let browserFailure;
251
+ if (!this.#storageReleased) {
252
+ try {
253
+ await this.storage?.close(stopLoading);
254
+ }
255
+ catch (failure) {
256
+ storageFailure = { cause: failure };
257
+ }
258
+ }
259
+ try {
260
+ await this.opened.cleanup.close(() => this.eventCapture.finish());
261
+ }
262
+ catch (failure) {
263
+ browserFailure = { cause: failure };
264
+ }
265
+ if (this.opened.cleanup.browserClosed)
266
+ this.#storageReleased = true;
267
+ throwCleanupFailures([
268
+ ...(this.#storageReleased || storageFailure === undefined
269
+ ? []
270
+ : [storageFailure.cause]),
271
+ ...(browserFailure === undefined ? [] : [browserFailure.cause]),
272
+ ]);
198
273
  return this.mode === "launch"
199
274
  ? "terminated-owned-process"
200
275
  : "disconnected-external";
@@ -203,13 +278,3 @@ export class PlaywrightScenarioSession {
203
278
  return this.secrets.redact(error instanceof Error ? error.message : "browser action failed");
204
279
  }
205
280
  }
206
- /** Production Playwright/CDP session factory. */
207
- export class PlaywrightScenarioSessionFactory {
208
- environment;
209
- constructor(environment) {
210
- this.environment = environment;
211
- }
212
- open(scenario, options = {}) {
213
- return PlaywrightScenarioSession.open(scenario, this.environment, options);
214
- }
215
- }