rea-agents 3.2.1 → 4.0.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 (434) hide show
  1. package/README.md +183 -332
  2. package/bridge/ghidra/ReaGhidraBridge.java +561 -74
  3. package/bridge/hopper_bridge.py +70 -27
  4. package/bridge/native/ReaNativeUI.swift +157 -0
  5. package/dist/application/AnalysisContextQueries.js +19 -5
  6. package/dist/application/AnalysisSnapshotCache.js +30 -11
  7. package/dist/application/AppleAssetCatalogAnalysis.js +171 -0
  8. package/dist/application/ArtifactExtractionDestination.js +0 -12
  9. package/dist/application/ArtifactGraphConstruction.js +44 -11
  10. package/dist/application/ArtifactInventory/classify.js +7 -15
  11. package/dist/application/ArtifactInventory/hash.js +4 -2
  12. package/dist/application/ArtifactInventory/policy.js +2 -17
  13. package/dist/application/ArtifactInventory/reader.js +3 -3
  14. package/dist/application/ArtifactInventory/scanCanonical.js +2 -2
  15. package/dist/application/ArtifactInventory/scanReader.js +12 -4
  16. package/dist/application/ArtifactInventory/types.js +0 -3
  17. package/dist/application/BinarySession.js +28 -43
  18. package/dist/application/BinarySessionExecution.js +37 -1
  19. package/dist/application/BinaryTargetResolver.js +50 -4
  20. package/dist/application/BrowserEvidence.js +36 -7
  21. package/dist/application/BrowserObservationService.js +17 -44
  22. package/dist/application/BrowserScenarioCaptureService.js +2 -35
  23. package/dist/application/BrowserScenarioEvidence.js +13 -9
  24. package/dist/application/CapabilityClientRequirements.js +2 -11
  25. package/dist/application/CapabilityInventory.js +21 -35
  26. package/dist/application/ClientConfigurationDocument.js +84 -7
  27. package/dist/application/ClientRegistrationIdentity.js +32 -0
  28. package/dist/application/ClientRegistrationStatus.js +59 -6
  29. package/dist/application/DirectAnalysis.js +37 -58
  30. package/dist/application/DirectAnalysisStatus.js +4 -4
  31. package/dist/application/Doctor.js +89 -80
  32. package/dist/application/DoctorDiagnostics.js +2 -26
  33. package/dist/application/DoctorScope.js +8 -14
  34. package/dist/application/ElectronActiveEvidence.js +10 -27
  35. package/dist/application/ElectronActiveObservationService.js +9 -36
  36. package/dist/application/ElectronBoundaryAnalysis.js +2 -0
  37. package/dist/application/ElectronBoundaryGraphNative.js +1 -1
  38. package/dist/application/ElectronEvidence.js +8 -3
  39. package/dist/application/ElectronObservationService.js +9 -25
  40. package/dist/application/EnhancedLiteralTracing.js +4 -8
  41. package/dist/application/EnhancedTools.js +15 -35
  42. package/dist/application/FilesystemSnapshot.js +7 -8
  43. package/dist/application/JavaScriptApplicationEvidenceGraph.js +2 -1
  44. package/dist/application/JavaScriptApplicationWorkflowService.js +31 -7
  45. package/dist/application/JavaScriptArtifactAnalysis.js +6 -4
  46. package/dist/application/JavaScriptArtifactFiles.js +5 -0
  47. package/dist/application/JavaScriptArtifactPathResolution.js +179 -47
  48. package/dist/application/JavaScriptRuntimeObservationEvidence.js +6 -3
  49. package/dist/application/JavaScriptRuntimeObservationService.js +9 -25
  50. package/dist/application/JavaScriptRuntimeReconciliationService.js +45 -4
  51. package/dist/application/JavaScriptSemanticGraphAsyncProjection.js +11 -0
  52. package/dist/application/JavaScriptSemanticGraphChildProcessProjection.js +11 -0
  53. package/dist/application/JavaScriptSemanticGraphDataProjection.js +11 -0
  54. package/dist/application/JavaScriptSemanticGraphFlowProjection.js +14 -5
  55. package/dist/application/JsonFiles.js +1 -1
  56. package/dist/application/LazyAnalysisProvider.js +27 -6
  57. package/dist/application/ManagedMemberComparisonService.js +19 -6
  58. package/dist/application/NativeApiInspection.js +2 -0
  59. package/dist/application/NativeCallRoutes.js +72 -0
  60. package/dist/application/NativeDispatchMetadataInspection.js +33 -0
  61. package/dist/application/NativeUiActionTrace.js +73 -49
  62. package/dist/application/NativeValueTrace.js +320 -0
  63. package/dist/application/ProcessCaptureCapability.js +32 -5
  64. package/dist/application/ProcessCaptureEnvironment.js +9 -26
  65. package/dist/application/ProcessCaptureError.js +1 -5
  66. package/dist/application/ProcessCaptureJournal.js +3 -40
  67. package/dist/application/ProcessCaptureLifecycle.js +102 -111
  68. package/dist/application/ProcessCli.js +18 -25
  69. package/dist/application/ProcessEvidence.js +5 -7
  70. package/dist/application/ProcessFilesystemEffects.js +36 -0
  71. package/dist/application/ProcessHarness.js +41 -120
  72. package/dist/application/ProcessNormalization.js +2 -17
  73. package/dist/application/ProcessScenarioRuntimeValidation.js +76 -0
  74. package/dist/application/ReferenceSourceImport.js +3 -4
  75. package/dist/application/Setup.js +236 -84
  76. package/dist/application/SetupClientConfiguration.js +14 -9
  77. package/dist/application/SetupPlan.js +138 -86
  78. package/dist/application/SetupSkill.js +0 -1
  79. package/dist/application/SupportedClients.js +102 -21
  80. package/dist/application/Uninstall.js +31 -20
  81. package/dist/application/Update.js +93 -0
  82. package/dist/application/UpdateMaintenance.js +108 -0
  83. package/dist/application/UpdateRuntime.js +126 -0
  84. package/dist/application/runtime.js +13 -2
  85. package/dist/artifacts/ArtifactPaths.js +6 -8
  86. package/dist/artifacts/ArtifactProvider.js +94 -41
  87. package/dist/artifacts/AsarArtifactReader.js +19 -4
  88. package/dist/artifacts/KeyedArchiveReader.js +110 -0
  89. package/dist/artifacts/MachOSliceArtifactReader.js +53 -5
  90. package/dist/artifacts/ZipArtifactReader.js +18 -1
  91. package/dist/browser/BrowserScenarioSecrets.js +28 -1
  92. package/dist/browser/CdpBrowserProvider.js +36 -15
  93. package/dist/browser/CdpCaptureDocuments.js +22 -8
  94. package/dist/browser/CdpCaptureEventHandlers.js +14 -5
  95. package/dist/browser/CdpCaptureEventHelpers.js +13 -0
  96. package/dist/browser/CdpCaptureEvents.js +10 -1
  97. package/dist/browser/CdpElectronInspection.js +5 -10
  98. package/dist/browser/CdpElectronProvider.js +1 -5
  99. package/dist/browser/CdpElectronScripts.js +1 -1
  100. package/dist/browser/CdpEndpoint.js +3 -2
  101. package/dist/browser/CdpObservationSession.js +14 -10
  102. package/dist/browser/CdpPageCapture.js +1 -1
  103. package/dist/browser/CdpPageCaptureScripts.js +1 -1
  104. package/dist/browser/CdpSafeMetadata.js +5 -4
  105. package/dist/browser/CdpScreenshot.js +16 -5
  106. package/dist/browser/CdpTargetSession.js +25 -4
  107. package/dist/browser/CdpWebMcpDiscovery.js +93 -20
  108. package/dist/browser/JavaScriptRuntimeScope.js +28 -2
  109. package/dist/browser/PlaywrightBrowserScenarioProvider.js +9 -8
  110. package/dist/browser/PlaywrightElectronActiveActions.js +3 -10
  111. package/dist/browser/PlaywrightElectronActiveProvider.js +5 -5
  112. package/dist/browser/PlaywrightScenarioActions.js +1 -1
  113. package/dist/browser/PlaywrightScenarioArtifacts.js +13 -25
  114. package/dist/browser/PlaywrightScenarioBrowser.js +28 -25
  115. package/dist/browser/PlaywrightScenarioEvents.js +82 -93
  116. package/dist/browser/PlaywrightScenarioSession.js +27 -123
  117. package/dist/browser/PngVisualDiff.js +22 -3
  118. package/dist/browser/V8InspectorCaptureProjection.js +7 -1
  119. package/dist/browser/V8InspectorProvider.js +60 -7
  120. package/dist/browser/WebSourceMapFetcher.js +99 -53
  121. package/dist/cli/artifactCommands.js +56 -12
  122. package/dist/cli/coreAnalysisCommands.js +110 -0
  123. package/dist/cli/managedCommands.js +1 -31
  124. package/dist/cli/setupCommands.js +16 -14
  125. package/dist/cli/utilityCommands.js +61 -4
  126. package/dist/cli.js +5 -7
  127. package/dist/cliApplicationCommands.js +0 -83
  128. package/dist/cliBrowserAdvancedCommands.js +7 -11
  129. package/dist/cliBrowserCommands.js +15 -23
  130. package/dist/cliBrowserContext.js +3 -24
  131. package/dist/cliBrowserScenarioCommands.js +2 -10
  132. package/dist/cliCommandNames.js +82 -7
  133. package/dist/cliElectronCommands.js +10 -36
  134. package/dist/cliJavaScriptRuntimeCommands.js +6 -30
  135. package/dist/cliJsonInput.js +4 -2
  136. package/dist/cliLogging.js +16 -7
  137. package/dist/cliObservationOptions.js +1 -1
  138. package/dist/cliOutput.js +2 -4
  139. package/dist/cliProcessCommands.js +6 -33
  140. package/dist/cliSetup.js +90 -160
  141. package/dist/config/environment.js +2 -78
  142. package/dist/config/parseConfig.js +18 -109
  143. package/dist/config/parsers.js +0 -23
  144. package/dist/contracts/applicationToolContracts.js +1 -118
  145. package/dist/contracts/artifactToolContracts.js +11 -19
  146. package/dist/contracts/browserScenarioToolContracts.js +1 -5
  147. package/dist/contracts/browserToolContracts.js +9 -16
  148. package/dist/contracts/electronToolContracts.js +5 -6
  149. package/dist/contracts/enhancedInputs.js +3 -2
  150. package/dist/contracts/errorSchemas.js +16 -40
  151. package/dist/contracts/functionWorkflowToolContracts.js +2 -2
  152. package/dist/contracts/javascriptApplicationWorkflowExamples.js +2 -2
  153. package/dist/contracts/javascriptRuntimeObservationToolContracts.js +4 -4
  154. package/dist/contracts/javascriptRuntimeReconciliationExample.js +1 -1
  155. package/dist/contracts/managedToolContracts.js +7 -4
  156. package/dist/contracts/managedWorkflowExamples.js +0 -22
  157. package/dist/contracts/managedWorkflowToolContracts.js +16 -31
  158. package/dist/contracts/nativeToolContracts.js +9 -0
  159. package/dist/contracts/promptContracts.js +6 -6
  160. package/dist/contracts/sessionToolSchemas.js +3 -3
  161. package/dist/contracts/toolContractExamples.js +4 -3
  162. package/dist/contracts/toolContracts.js +18 -7
  163. package/dist/contracts/toolEffects.js +34 -21
  164. package/dist/contracts/toolOutputSchemaGroups.js +18 -5
  165. package/dist/contracts/toolOutputSchemaPrimitives.js +9 -6
  166. package/dist/contracts/toolSchemaMetadata.js +5 -8
  167. package/dist/doctorRuntime.js +0 -41
  168. package/dist/domain/analysisErrorPresentation.js +4 -28
  169. package/dist/domain/analysisErrorProjection.js +33 -50
  170. package/dist/domain/analysisProfile.js +1 -1
  171. package/dist/domain/analysisSnapshot.js +77 -3
  172. package/dist/domain/androidApplication.js +5 -4
  173. package/dist/domain/appleApplication.js +5 -4
  174. package/dist/domain/appleAssetCatalog.js +127 -0
  175. package/dist/domain/artifactComparison.js +7 -11
  176. package/dist/domain/artifactGraph.js +8 -6
  177. package/dist/domain/artifactInspection.js +13 -12
  178. package/dist/domain/binaryTarget.js +23 -9
  179. package/dist/domain/browserObservation.js +43 -24
  180. package/dist/domain/browserObservationSchemas.js +2 -1
  181. package/dist/domain/browserScenario.js +7 -107
  182. package/dist/domain/browserScenarioCapture.js +0 -1
  183. package/dist/domain/browserScenarioCaptureValues.js +5 -4
  184. package/dist/domain/browserScenarioDiff.js +1 -3
  185. package/dist/domain/browserScenarioValues.js +16 -107
  186. package/dist/domain/bundleComparison.js +18 -17
  187. package/dist/domain/callPathSchemas.js +17 -7
  188. package/dist/domain/changedBehavior.js +2 -3
  189. package/dist/domain/comparisonSemantics.js +19 -0
  190. package/dist/domain/completionLedgerGeneration.js +3 -2
  191. package/dist/domain/conformancePackage.js +2 -1
  192. package/dist/domain/conformanceTrustGate.js +3 -5
  193. package/dist/domain/customProtocolCapture.js +2 -2
  194. package/dist/domain/digests.js +30 -0
  195. package/dist/domain/dosMz.js +83 -0
  196. package/dist/domain/electronActiveObservation.js +7 -5
  197. package/dist/domain/electronObservation.js +3 -2
  198. package/dist/domain/electronStaticAnalysisNative.js +15 -6
  199. package/dist/domain/emptyArraySchema.js +3 -0
  200. package/dist/domain/errors.js +10 -28
  201. package/dist/domain/evidence.js +5 -3
  202. package/dist/domain/evidenceCompletionLedger.js +3 -2
  203. package/dist/domain/functionComparisonNormalization.js +24 -18
  204. package/dist/domain/functionComparisonResults.js +3 -7
  205. package/dist/domain/functionComparisonSchemas.js +3 -2
  206. package/dist/domain/hopperValues.js +108 -8
  207. package/dist/domain/javascriptApplicationAnalysis.js +4 -7
  208. package/dist/domain/javascriptApplicationEvidenceSchemas.js +4 -3
  209. package/dist/domain/javascriptApplicationGraphSchemas.js +8 -7
  210. package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +9 -7
  211. package/dist/domain/javascriptApplicationVersionItems.js +12 -18
  212. package/dist/domain/javascriptAstValues.js +4 -0
  213. package/dist/domain/javascriptExportShapeComparison.js +1 -6
  214. package/dist/domain/javascriptExportShapeComparisonSchemas.js +6 -10
  215. package/dist/domain/javascriptExportShapeVariants.js +15 -2
  216. package/dist/domain/javascriptFeatureTraceSchemas.js +8 -7
  217. package/dist/domain/javascriptRuntimeObservation.js +14 -2
  218. package/dist/domain/javascriptRuntimeReconciliationMatching.js +8 -0
  219. package/dist/domain/javascriptRuntimeReconciliationParsing.js +4 -2
  220. package/dist/domain/javascriptRuntimeReconciliationResult.js +6 -4
  221. package/dist/domain/javascriptRuntimeReconciliationRuntime.js +15 -4
  222. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +19 -18
  223. package/dist/domain/javascriptRuntimeStaticCandidates.js +18 -6
  224. package/dist/domain/javascriptSemanticAnalysis.js +57 -19
  225. package/dist/domain/javascriptSemanticAsyncEffects.js +39 -40
  226. package/dist/domain/javascriptSemanticCalls.js +46 -27
  227. package/dist/domain/javascriptSemanticChildProcesses.js +43 -50
  228. package/dist/domain/javascriptSemanticDataEffectHelpers.js +91 -18
  229. package/dist/domain/javascriptSemanticDataEffects.js +22 -10
  230. package/dist/domain/javascriptSemanticGraphSchemas.js +8 -6
  231. package/dist/domain/javascriptSemanticObjects.js +13 -3
  232. package/dist/domain/javascriptSemanticProjection.js +144 -38
  233. package/dist/domain/javascriptSemanticPromises.js +14 -27
  234. package/dist/domain/javascriptSemanticQuerySchemas.js +6 -9
  235. package/dist/domain/javascriptSemanticResources.js +2 -5
  236. package/dist/domain/javascriptSemanticState.js +4 -0
  237. package/dist/domain/javascriptSemanticTraceSchemas.js +2 -1
  238. package/dist/domain/javascriptSemanticTraversal.js +13 -5
  239. package/dist/domain/javascriptSemanticValues.js +10 -9
  240. package/dist/domain/javascriptSourceParser.js +5 -1
  241. package/dist/domain/javascriptStaticAnalysisCalls.js +8 -5
  242. package/dist/domain/javascriptStaticAnalysisHelpers.js +16 -7
  243. package/dist/domain/keyedArchive.js +181 -0
  244. package/dist/domain/managedApplicationGraph.js +4 -3
  245. package/dist/domain/managedArtifact.js +2 -1
  246. package/dist/domain/managedMemberComparison.js +18 -13
  247. package/dist/domain/managedMemberComparisonCoverage.js +2 -1
  248. package/dist/domain/managedMemberComparisonItems.js +27 -7
  249. package/dist/domain/managedMemberComparisonMatch.js +22 -6
  250. package/dist/domain/managedNativeVerificationMatch.js +2 -2
  251. package/dist/domain/managedNativeVerificationSchemas.js +7 -5
  252. package/dist/domain/managedReconstruction.js +6 -5
  253. package/dist/domain/nativeApiBoundary.js +7 -0
  254. package/dist/domain/nativeDataType.js +51 -0
  255. package/dist/domain/nativeInspection.js +0 -1
  256. package/dist/domain/nativeInstruction.js +82 -0
  257. package/dist/domain/nativeInvestigationGraph.js +9 -5
  258. package/dist/domain/nativeUiObservation.js +123 -0
  259. package/dist/domain/nativeValueFlow.js +17 -0
  260. package/dist/domain/nativeValueTrace.js +64 -0
  261. package/dist/domain/objcSwiftMetadata.js +39 -0
  262. package/dist/domain/peInspection.js +1 -0
  263. package/dist/domain/processCapture.js +5 -55
  264. package/dist/domain/processCaptureExample.js +0 -9
  265. package/dist/domain/processCaptureValidation.js +13 -144
  266. package/dist/domain/processComparison.js +3 -25
  267. package/dist/domain/processObservation.js +0 -29
  268. package/dist/domain/processScenario.js +28 -228
  269. package/dist/domain/processTraceDimensionProjection.js +0 -15
  270. package/dist/domain/processTraceEvaluation.js +0 -6
  271. package/dist/domain/protocolCapture.js +8 -36
  272. package/dist/domain/reconstructionCoverage.js +3 -2
  273. package/dist/domain/reconstructionObligationLedgerSchemas.js +4 -12
  274. package/dist/domain/reconstructionReadinessSchemas.js +4 -3
  275. package/dist/domain/reconstructionVerification.js +2 -1
  276. package/dist/domain/reconstructionVerificationSchemas.js +6 -13
  277. package/dist/domain/referenceSourceClassification.js +0 -110
  278. package/dist/domain/referenceSourceGraph.js +15 -5
  279. package/dist/domain/residualUnknown.js +3 -2
  280. package/dist/domain/runtimeIdentification.js +6 -5
  281. package/dist/domain/sourceMapContents.js +5 -0
  282. package/dist/domain/sourceToBundleComparison.js +3 -10
  283. package/dist/domain/sourceToBundleComparisonSchemas.js +7 -6
  284. package/dist/domain/sourceToBundleSignals.js +9 -3
  285. package/dist/domain/staticRuntimeCorrelation.js +5 -11
  286. package/dist/domain/webBundleAnalysis.js +17 -9
  287. package/dist/domain/webBundleAnalyzer.js +1 -1
  288. package/dist/domain/webCaptureDiff.js +5 -11
  289. package/dist/domain/webCaptureDiffSchemas.js +2 -1
  290. package/dist/domain/webMcpDiscovery.js +2 -1
  291. package/dist/dotnet/ManagedMemberInspectorCore.js +15 -7
  292. package/dist/dotnet/ManagedMemberInstructionDecoder.js +57 -40
  293. package/dist/dotnet/ManagedMemberRows.js +2 -0
  294. package/dist/dotnet/ManagedMethodBodyReader.js +15 -8
  295. package/dist/dotnet/ManagedPeReader.js +2 -0
  296. package/dist/generatedMcpToolCatalog.js +1 -1
  297. package/dist/generatedPackageMetadata.js +2 -2
  298. package/dist/ghidra/GhidraAnalysisProfile.js +15 -5
  299. package/dist/ghidra/GhidraClient.js +38 -8
  300. package/dist/ghidra/GhidraFunctionValues.js +56 -20
  301. package/dist/ghidra/GhidraInstallation.js +7 -4
  302. package/dist/ghidra/GhidraInventoryValues.js +44 -9
  303. package/dist/ghidra/GhidraLauncher.js +18 -3
  304. package/dist/ghidra/GhidraProvider.js +23 -2
  305. package/dist/ghidra/GhidraRequestQueue.js +45 -4
  306. package/dist/ghidra/GhidraSessionValues.js +5 -0
  307. package/dist/hopper/HopperAnalysisProfile.js +2 -0
  308. package/dist/hopper/HopperProvider.js +29 -6
  309. package/dist/hopper/HopperTargetLease.js +18 -4
  310. package/dist/logger.js +0 -13
  311. package/dist/main/messages.js +0 -1
  312. package/dist/main/reload.js +3 -32
  313. package/dist/main/shutdown.js +1 -2
  314. package/dist/main/transport.js +0 -17
  315. package/dist/main.js +0 -10
  316. package/dist/native/AppleDispatchMetadata.js +582 -0
  317. package/dist/native/AppleObjcProtocols.js +88 -0
  318. package/dist/native/AppleSwiftVtables.js +86 -0
  319. package/dist/native/CommandRunner.js +1 -1
  320. package/dist/native/NativeHostCapabilities.js +23 -0
  321. package/dist/native/NativeMacOSProvider.js +61 -9
  322. package/dist/native/NativeMachoInspection.js +39 -6
  323. package/dist/native/NativeUiHelperRuntime.js +42 -0
  324. package/dist/native/NativeUiObservation.js +174 -0
  325. package/dist/native/parsers/codesign.js +4 -1
  326. package/dist/native/parsers/dyldInfo.js +51 -25
  327. package/dist/native/parsers/lipo.js +13 -4
  328. package/dist/native/parsers/otool.js +84 -39
  329. package/dist/native/parsers/plist.js +2 -1
  330. package/dist/process/ExecFileOutput.js +5 -1
  331. package/dist/process/ProcessOwnership.js +69 -33
  332. package/dist/process/ProcessOwnershipObservation.js +31 -12
  333. package/dist/process/ProviderProcess.js +4 -2
  334. package/dist/reference/ReferenceSourceReaderEntries.js +48 -31
  335. package/dist/reference/ReferenceSourceReaderErrors.js +24 -0
  336. package/dist/reference/ReferenceSourceReaderFile.js +11 -5
  337. package/dist/reference/ReferenceSourceReaderValidate.js +22 -8
  338. package/dist/server/createServer.js +7 -62
  339. package/dist/server/registerApplicationTools/helpers.js +2 -9
  340. package/dist/server/registerApplicationTools.js +0 -4
  341. package/dist/server/registerArtifactComparisonTool.js +1 -1
  342. package/dist/server/registerBrowserScenarioTool.js +4 -2
  343. package/dist/server/registerBrowserTools.js +7 -7
  344. package/dist/server/registerBundleComparisonTool.js +1 -1
  345. package/dist/server/registerCloseLifecycleTool.js +1 -1
  346. package/dist/server/registerElectronTools.js +10 -4
  347. package/dist/server/registerEnhancedTools.js +20 -12
  348. package/dist/server/registerEvidenceTools.js +4 -28
  349. package/dist/server/registerFunctionComparisonTool.js +1 -1
  350. package/dist/server/registerInvestigationTools.js +6 -6
  351. package/dist/server/registerJavaScriptRuntimeObservationTools.js +2 -2
  352. package/dist/server/registerManagedTools.js +28 -14
  353. package/dist/server/registerManagedWorkflowTools.js +0 -2
  354. package/dist/server/registerProcessComparisonTool.js +1 -3
  355. package/dist/server/registerSessionRecordTools.js +9 -9
  356. package/dist/server/registerSessionStatusTool.js +1 -1
  357. package/dist/server/registerSessionTools.js +28 -57
  358. package/dist/server/sessionAvailabilityPolicy.js +2 -3
  359. package/dist/server/sessionToolPolicies.js +0 -4
  360. package/dist/server/toolResult.js +8 -10
  361. package/package.json +32 -22
  362. package/skills/reverse-engineer-anything/SKILL.md +15 -11
  363. package/skills/reverse-engineer-anything/references/evidence-workflows.md +3 -2
  364. package/skills/reverse-engineer-anything/references/javascript-applications.md +3 -2
  365. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +8 -6
  366. package/skills/reverse-engineer-anything/references/runtime-observation.md +15 -11
  367. package/dist/application/CommandShimReplay.js +0 -152
  368. package/dist/application/ConfiguredRoots.js +0 -19
  369. package/dist/application/InstrumentedJavaScriptReplayHost.js +0 -36
  370. package/dist/application/JavaScriptReplayPermission.js +0 -16
  371. package/dist/application/JavaScriptReplayPlanning.js +0 -207
  372. package/dist/application/JavaScriptReplayService.js +0 -274
  373. package/dist/application/LoopbackReplay.js +0 -389
  374. package/dist/application/LoopbackReplayRecorder.js +0 -129
  375. package/dist/application/ManagedRuntimeCorrelationService.js +0 -104
  376. package/dist/application/NodeRuntimeCharacterizationService.js +0 -191
  377. package/dist/application/PermissionAuthority.js +0 -268
  378. package/dist/application/PermissionConfiguration.js +0 -26
  379. package/dist/application/PermissionFailure.js +0 -5
  380. package/dist/application/ProcessCaptureAuthority.js +0 -24
  381. package/dist/application/ProcessCapturePermission.js +0 -13
  382. package/dist/application/ProcessCheckpoints.js +0 -178
  383. package/dist/application/ProcessReactiveCoordinator.js +0 -223
  384. package/dist/application/ProcessReactiveEffects.js +0 -153
  385. package/dist/application/ProcessReactiveHarness.js +0 -106
  386. package/dist/application/ProcessReactiveObservations.js +0 -105
  387. package/dist/application/ProjectPermissionStore.js +0 -199
  388. package/dist/application/RuntimeExecutableDiagnostics.js +0 -198
  389. package/dist/application/Upgrade.js +0 -134
  390. package/dist/browser/SensitiveTextCapture.js +0 -8
  391. package/dist/cliPolicyCommands.js +0 -185
  392. package/dist/config/browserScenario.js +0 -77
  393. package/dist/config/electronAutomation.js +0 -35
  394. package/dist/config/javascriptReplay.js +0 -41
  395. package/dist/config/managedRuntime.js +0 -25
  396. package/dist/config/passiveObservation.js +0 -87
  397. package/dist/config/permissions.js +0 -23
  398. package/dist/config/processCapture.js +0 -47
  399. package/dist/contracts/replayMachineExample.js +0 -37
  400. package/dist/domain/javascriptExportInstrumentation.js +0 -95
  401. package/dist/domain/javascriptReplay.js +0 -360
  402. package/dist/domain/managedRuntimeCorrelation.js +0 -181
  403. package/dist/domain/nodeRuntimeCharacterization.js +0 -63
  404. package/dist/domain/permissionPolicy.js +0 -176
  405. package/dist/domain/processCaptureReactiveSchema.js +0 -68
  406. package/dist/domain/processCaptureReactiveValidation.js +0 -180
  407. package/dist/domain/processReactiveCheckpointDataflow.js +0 -32
  408. package/dist/domain/processReactiveMatching.js +0 -196
  409. package/dist/domain/processReactiveRuntime.js +0 -116
  410. package/dist/domain/processReactiveScenario.js +0 -296
  411. package/dist/domain/processReactiveScenarioPreflight.js +0 -95
  412. package/dist/domain/processReactiveTransition.js +0 -187
  413. package/dist/domain/replayMachine.js +0 -320
  414. package/dist/domain/replayMachineRun.js +0 -168
  415. package/dist/domain/replayMachineRuntime.js +0 -296
  416. package/dist/domain/replayMachineValues.js +0 -84
  417. package/dist/domain/runtimeCharacterization.js +0 -84
  418. package/dist/replay/JavaScriptReplayWorker.js +0 -382
  419. package/dist/replay/JavaScriptReplayWorkerTypes.js +0 -1
  420. package/dist/replay/LinuxJavaScriptReplayRunner.js +0 -216
  421. package/dist/replay/LinuxJavaScriptReplaySandbox.js +0 -121
  422. package/dist/replay/LinuxRuntimeClosure.js +0 -44
  423. package/dist/replay/LinuxSeccompPolicy.js +0 -40
  424. package/dist/replay/ReplayOutcome.js +0 -104
  425. package/dist/replay/ReplayProcessLifecycle.js +0 -96
  426. package/dist/replay/ReplaySeccompFile.js +0 -29
  427. package/dist/replay/ReplayWorkerProtocol.js +0 -58
  428. package/dist/replay/SystemJavaScriptReplayHost.js +0 -153
  429. package/dist/server/ProcessCaptureElicitation.js +0 -153
  430. package/dist/server/registerApplicationTools/characterization.js +0 -46
  431. package/dist/server/registerApplicationTools/controlledReplay.js +0 -31
  432. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +0 -29
  433. package/dist/server/registerReplayMachineTool.js +0 -14
  434. package/skills/reverse-engineer-anything/references/controlled-replay.md +0 -12
@@ -1,6 +1,5 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { z } from "zod";
3
- import { sanitizeBrowserUrl } from "../domain/browserObservation.js";
4
3
  import { browserStepArtifactsSchema, } from "../domain/browserScenarioCapture.js";
5
4
  const historyValueSchema = z.strictObject({
6
5
  length: z.number().int().min(0),
@@ -79,7 +78,7 @@ const navigationType = (value) => {
79
78
  return "unknown";
80
79
  }
81
80
  };
82
- const captureHistory = async (page) => {
81
+ const captureHistory = async (page, secrets) => {
83
82
  try {
84
83
  const raw = historyValueSchema.parse(await page.evaluate(`(() => ({
85
84
  length: window.history.length,
@@ -92,10 +91,10 @@ const captureHistory = async (page) => {
92
91
  }))()`));
93
92
  const value = {
94
93
  length: raw.length,
95
- current_url: sanitizeBrowserUrl(page.url()),
94
+ current_url: secrets.sanitizeUrl(page.url()),
96
95
  navigation_entries: raw.navigation_entries.map(({ type, name }) => ({
97
96
  type: navigationType(type),
98
- name: sanitizeBrowserUrl(name),
97
+ name: secrets.sanitizeUrl(name),
99
98
  })),
100
99
  };
101
100
  return { state: "captured", value };
@@ -105,9 +104,12 @@ const captureHistory = async (page) => {
105
104
  }
106
105
  };
107
106
  const captureStorage = async (input) => {
108
- const { context, page, scenario, secrets } = input;
107
+ const { context, page, secrets } = input;
109
108
  try {
110
- const cookies = await context.cookies(scenario.allowed_origins);
109
+ const pageUrl = new URL(page.url());
110
+ const cookies = pageUrl.protocol === "http:" || pageUrl.protocol === "https:"
111
+ ? await context.cookies(pageUrl.href)
112
+ : [];
111
113
  const pageStorage = storageValueSchema.parse(await page.evaluate(`(() => ({
112
114
  local_storage: Object.entries(window.localStorage),
113
115
  session_storage: Object.entries(window.sessionStorage)
@@ -137,33 +139,19 @@ const captureStorage = async (input) => {
137
139
  return missing("storage capture failed");
138
140
  }
139
141
  };
140
- const isAllowedPage = (page, allowedOrigins) => {
141
- try {
142
- return allowedOrigins.has(new URL(page.url()).origin);
143
- }
144
- catch {
145
- return false;
146
- }
147
- };
148
142
  /** Capture selected step artifacts without retaining data after scope loss. */
149
143
  export const capturePlaywrightStepArtifacts = async (input) => {
150
- const { context, page, scenario, secrets, requested } = input;
151
- const allowed = isAllowedPage(page, new Set(scenario.allowed_origins));
152
- const denied = () => missing("current page is outside approved origins");
153
- const state = (kind, capture) => !requested.has(kind)
154
- ? Promise.resolve(notRequested())
155
- : allowed || kind === "url"
156
- ? capture()
157
- : Promise.resolve(denied());
144
+ const { context, page, secrets, requested } = input;
145
+ const state = (kind, capture) => (!requested.has(kind) ? Promise.resolve(notRequested()) : capture());
158
146
  return browserStepArtifactsSchema.parse({
159
147
  screenshot: await state("screenshot", () => captureScreenshot(page)),
160
148
  dom: await state("dom", () => captureDom({ page, secrets })),
161
149
  accessibility: await state("accessibility", () => captureAccessibility({ page, secrets })),
162
150
  url: await state("url", async () => ({
163
151
  state: "captured",
164
- value: sanitizeBrowserUrl(page.url()),
152
+ value: secrets.sanitizeUrl(page.url()),
165
153
  })),
166
- history: await state("history", () => captureHistory(page)),
167
- storage: await state("storage", () => captureStorage({ context, page, scenario, secrets })),
154
+ history: await state("history", () => captureHistory(page, secrets)),
155
+ storage: await state("storage", () => captureStorage({ context, page, secrets })),
168
156
  });
169
157
  };
@@ -1,8 +1,9 @@
1
1
  import { chmod, mkdtemp, rm } from "node:fs/promises";
2
2
  import { tmpdir } from "node:os";
3
- import { join } from "node:path";
3
+ import { join, resolve } from "node:path";
4
4
  import { chromium, } from "playwright-core";
5
5
  import { BrowserObservationError } from "../domain/errors.js";
6
+ import { withPlaywrightExecutionBoundary } from "./PlaywrightExecutionBoundary.js";
6
7
  const OPERATION = "capture_browser_scenario";
7
8
  const allowedBrowserEnvironment = (environment) => {
8
9
  const allowed = [
@@ -24,15 +25,7 @@ const allowedBrowserEnvironment = (environment) => {
24
25
  .map((name) => [name, environment[name]])
25
26
  .filter((entry) => entry[1] !== undefined));
26
27
  };
27
- const originAllowed = (value, allowedOrigins) => {
28
- try {
29
- return allowedOrigins.has(new URL(value).origin);
30
- }
31
- catch {
32
- return false;
33
- }
34
- };
35
- const findConnectedPage = async (browser, targetId, allowedOrigins) => {
28
+ const findConnectedPage = async (browser, targetId) => {
36
29
  for (const context of browser.contexts())
37
30
  for (const page of context.pages()) {
38
31
  const session = await context.newCDPSession(page);
@@ -40,9 +33,6 @@ const findConnectedPage = async (browser, targetId, allowedOrigins) => {
40
33
  const { targetInfo } = await session.send("Target.getTargetInfo");
41
34
  if (targetInfo.targetId !== targetId)
42
35
  continue;
43
- if (page.url() !== "about:blank" &&
44
- !originAllowed(page.url(), allowedOrigins))
45
- throw new BrowserObservationError(OPERATION, "target_not_allowed");
46
36
  return { context, page };
47
37
  }
48
38
  finally {
@@ -83,7 +73,7 @@ export const openPlaywrightScenarioBrowser = async (scenario, environment) => {
83
73
  if (scenario.browser.mode === "connect") {
84
74
  const browser = await chromium.connectOverCDP(scenario.browser.cdp_endpoint, { timeout: 0 });
85
75
  try {
86
- const target = await findConnectedPage(browser, scenario.browser.target_id, new Set(scenario.allowed_origins));
76
+ const target = await findConnectedPage(browser, scenario.browser.target_id);
87
77
  await configureAttachedEnvironment(target.context, target.page, scenario);
88
78
  return { ...target, browser, profilePath: undefined };
89
79
  }
@@ -96,8 +86,8 @@ export const openPlaywrightScenarioBrowser = async (scenario, environment) => {
96
86
  await chmod(profilePath, 0o700);
97
87
  try {
98
88
  const context = await chromium.launchPersistentContext(profilePath, {
99
- executablePath: scenario.browser.executable_path,
100
- headless: true,
89
+ executablePath: resolve(scenario.browser.executable_path),
90
+ headless: scenario.browser.headless,
101
91
  acceptDownloads: false,
102
92
  viewport: {
103
93
  width: scenario.environment.viewport.width,
@@ -108,7 +98,7 @@ export const openPlaywrightScenarioBrowser = async (scenario, environment) => {
108
98
  timezoneId: scenario.environment.timezone,
109
99
  colorScheme: scenario.environment.color_scheme,
110
100
  reducedMotion: scenario.environment.reduced_motion,
111
- serviceWorkers: "block",
101
+ serviceWorkers: scenario.environment.service_workers,
112
102
  env: allowedBrowserEnvironment(environment),
113
103
  handleSIGHUP: false,
114
104
  handleSIGINT: false,
@@ -128,15 +118,28 @@ export const openPlaywrightScenarioBrowser = async (scenario, environment) => {
128
118
  throw cause;
129
119
  }
130
120
  };
131
- export const closePlaywrightScenarioBrowser = async ({ context, browser, profilePath, }) => {
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
+ void cleanup.catch(() => undefined);
137
+ // The shared execution boundary rejects cancellation/timeouts instead of
138
+ // returning a successful capture whose browser or profile may still exist.
132
139
  try {
133
- if (profilePath === undefined)
134
- await browser.close();
135
- else
136
- await context.close();
140
+ await withPlaywrightExecutionBoundary(() => cleanup, 1_000, signal);
137
141
  }
138
- finally {
139
- if (profilePath !== undefined)
140
- await rm(profilePath, { recursive: true, force: true, maxRetries: 3 });
142
+ catch (cause) {
143
+ throw new BrowserObservationError(OPERATION, "cleanup_failed", { cause });
141
144
  }
142
145
  };
@@ -1,4 +1,3 @@
1
- import { sanitizeBrowserUrl } from "../domain/browserObservation.js";
2
1
  import { browserScenarioEventSchema, } from "../domain/browserScenarioCapture.js";
3
2
  /** Arrival-ordered Playwright event capture with current-step attribution. */
4
3
  export class PlaywrightScenarioEvents {
@@ -7,11 +6,43 @@ export class PlaywrightScenarioEvents {
7
6
  sequence = 0;
8
7
  enabled;
9
8
  secrets;
10
- allowedOrigins;
9
+ ownsContext;
10
+ pages = new Set();
11
+ incompleteFamilies = new Set();
11
12
  constructor(options) {
12
13
  this.enabled = options.enabled;
13
14
  this.secrets = options.secrets;
14
- this.allowedOrigins = new Set(options.allowedOrigins);
15
+ this.ownsContext = options.ownsContext === true;
16
+ this.pages.add(options.page);
17
+ if (this.ownsContext && this.enabled.size > 0)
18
+ (options.context ?? options.page.context()).on("page", (page) => this.popup(page));
19
+ if (this.enabled.has("network")) {
20
+ const context = options.context ?? options.page.context();
21
+ const inScope = (request) => {
22
+ if (this.ownsContext)
23
+ return true;
24
+ try {
25
+ return this.pages.has(request.frame().page());
26
+ }
27
+ catch {
28
+ // Initial popup navigations can lack a frame. Never guess ownership
29
+ // from a URL in a shared context; connect captures are attach-limited.
30
+ return false;
31
+ }
32
+ };
33
+ context.on("request", (request) => {
34
+ if (inScope(request))
35
+ this.request("request", request);
36
+ });
37
+ context.on("response", (response) => {
38
+ if (inScope(response.request()))
39
+ this.response(response);
40
+ });
41
+ context.on("requestfailed", (request) => {
42
+ if (inScope(request))
43
+ this.request("request-failed", request);
44
+ });
45
+ }
15
46
  this.observePage(options.page);
16
47
  }
17
48
  setStep(index) {
@@ -23,6 +54,16 @@ export class PlaywrightScenarioEvents {
23
54
  lastSequence() {
24
55
  return this.sequence;
25
56
  }
57
+ /** Report selected popup event families with unrecoverable pre-discovery gaps. */
58
+ limitations() {
59
+ const popupGaps = [...this.incompleteFamilies].map((family) => `Popup ${family} events before Page discovery are unavailable; later events are retained.`);
60
+ return this.enabled.has("network") && !this.ownsContext
61
+ ? [
62
+ "Shared-context network capture excludes requests without a known root or descendant Page frame.",
63
+ ...popupGaps,
64
+ ]
65
+ : popupGaps;
66
+ }
26
67
  result() {
27
68
  return {
28
69
  retained: this.items.length,
@@ -41,80 +82,33 @@ export class PlaywrightScenarioEvents {
41
82
  }
42
83
  observePage(page) {
43
84
  if (this.enabled.has("console"))
44
- page.on("console", (message) => {
45
- if (this.pageInScope(page))
46
- this.console(message);
47
- });
85
+ page.on("console", (message) => this.console(message));
48
86
  if (this.enabled.has("page-errors"))
49
87
  page.on("pageerror", (error) => {
50
- if (this.pageInScope(page))
51
- this.push({
52
- kind: "page-error",
53
- message: this.secrets.redact(error.message),
54
- stack: error.stack === undefined
55
- ? null
56
- : this.secrets.redact(error.stack),
57
- });
58
- });
59
- if (this.enabled.has("network")) {
60
- page.on("request", (request) => {
61
- if (this.pageInScope(page))
62
- this.request("request", request);
63
- });
64
- page.on("response", (response) => {
65
- if (this.pageInScope(page))
66
- this.response(response);
67
- });
68
- page.on("requestfailed", (request) => {
69
- if (this.pageInScope(page))
70
- this.request("request-failed", request);
88
+ this.push({
89
+ kind: "page-error",
90
+ message: this.secrets.redact(error.message),
91
+ stack: error.stack === undefined ? null : this.secrets.redact(error.stack),
92
+ });
71
93
  });
72
- }
73
94
  if (this.enabled.has("websockets"))
74
- page.on("websocket", (socket) => {
75
- if (this.pageInScope(page))
76
- this.webSocket(page, socket);
77
- });
95
+ page.on("websocket", (socket) => this.webSocket(socket));
78
96
  if (this.enabled.has("frames")) {
79
- page.on("frameattached", (frame) => {
80
- if (this.pageInScope(page))
81
- this.frame("frame-attached", frame);
82
- });
83
- page.on("framedetached", (frame) => {
84
- if (this.pageInScope(page))
85
- this.frame("frame-detached", frame);
86
- });
87
- page.on("framenavigated", (frame) => {
88
- if (this.pageInScope(page))
89
- this.frame("frame-navigated", frame);
90
- });
97
+ page.on("frameattached", (frame) => this.frame("frame-attached", frame));
98
+ page.on("framedetached", (frame) => this.frame("frame-detached", frame));
99
+ page.on("framenavigated", (frame) => this.frame("frame-navigated", frame));
91
100
  }
92
101
  if (this.enabled.has("workers"))
93
- page.on("worker", (worker) => {
94
- if (this.pageInScope(page))
95
- this.worker(page, worker);
96
- });
97
- if (this.enabled.has("popups"))
98
- page.on("popup", (popup) => {
99
- if (this.pageInScope(page))
100
- this.popup(popup);
101
- });
102
+ page.on("worker", (worker) => this.worker(worker));
103
+ // Any selected family needs descendant discovery in shared contexts.
104
+ // Popup lifecycle records remain gated on their own selector below.
105
+ if (this.enabled.size > 0)
106
+ page.on("popup", (popup) => this.popup(popup));
102
107
  if (this.enabled.has("downloads"))
103
- page.on("download", (download) => {
104
- if (this.pageInScope(page))
105
- this.download(download);
106
- });
107
- }
108
- pageInScope(page) {
109
- try {
110
- return this.allowedOrigins.has(new URL(page.url()).origin);
111
- }
112
- catch {
113
- return false;
114
- }
108
+ page.on("download", (download) => this.download(download));
115
109
  }
116
110
  safeUrl(value) {
117
- return sanitizeBrowserUrl(this.secrets.redact(value));
111
+ return this.secrets.sanitizeUrl(value);
118
112
  }
119
113
  console(message) {
120
114
  const location = message.location();
@@ -164,21 +158,12 @@ export class PlaywrightScenarioEvents {
164
158
  failure: null,
165
159
  });
166
160
  }
167
- webSocket(page, socket) {
161
+ webSocket(socket) {
168
162
  const url = this.safeUrl(socket.url());
169
163
  this.push({ kind: "websocket-opened", url });
170
- socket.on("framesent", ({ payload }) => {
171
- if (this.pageInScope(page))
172
- this.webSocketFrame("websocket-frame-sent", url, payload);
173
- });
174
- socket.on("framereceived", ({ payload }) => {
175
- if (this.pageInScope(page))
176
- this.webSocketFrame("websocket-frame-received", url, payload);
177
- });
178
- socket.on("close", () => {
179
- if (this.pageInScope(page))
180
- this.push({ kind: "websocket-closed", url });
181
- });
164
+ socket.on("framesent", ({ payload }) => this.webSocketFrame("websocket-frame-sent", url, payload));
165
+ socket.on("framereceived", ({ payload }) => this.webSocketFrame("websocket-frame-received", url, payload));
166
+ socket.on("close", () => this.push({ kind: "websocket-closed", url }));
182
167
  }
183
168
  webSocketFrame(kind, url, payload) {
184
169
  const bytes = Buffer.byteLength(payload);
@@ -211,34 +196,38 @@ export class PlaywrightScenarioEvents {
211
196
  name: frame.name() === "" ? null : this.secrets.redact(frame.name()),
212
197
  });
213
198
  }
214
- worker(page, worker) {
199
+ worker(worker) {
215
200
  const details = {
216
201
  url: this.safeUrl(worker.url()),
217
202
  name: null,
218
203
  };
219
204
  this.push({ kind: "worker-created", ...details });
220
- worker.on("close", () => {
221
- if (this.pageInScope(page))
222
- this.push({ kind: "worker-closed", ...details });
223
- });
205
+ worker.on("close", () => this.push({ kind: "worker-closed", ...details }));
224
206
  }
225
207
  popup(page) {
226
- if (!this.pageInScope(page)) {
227
- void page.close().catch(() => undefined);
208
+ if (this.pages.has(page))
228
209
  return;
229
- }
210
+ this.pages.add(page);
211
+ for (const family of [
212
+ "frames",
213
+ "workers",
214
+ "websockets",
215
+ "downloads",
216
+ ])
217
+ if (this.enabled.has(family))
218
+ this.incompleteFamilies.add(family);
230
219
  const opened = {
231
220
  url: page.url() === "" ? null : this.safeUrl(page.url()),
232
221
  name: null,
233
222
  };
234
- this.push({ kind: "popup-opened", ...opened });
235
- page.on("close", () => this.pageInScope(page)
236
- ? this.push({
223
+ if (this.enabled.has("popups")) {
224
+ this.push({ kind: "popup-opened", ...opened });
225
+ page.on("close", () => this.push({
237
226
  kind: "popup-closed",
238
227
  url: page.url() === "" ? null : this.safeUrl(page.url()),
239
228
  name: null,
240
- })
241
- : undefined);
229
+ }));
230
+ }
242
231
  this.observePage(page);
243
232
  }
244
233
  download(download) {
@@ -7,14 +7,6 @@ import { capturePlaywrightStepArtifacts } from "./PlaywrightScenarioArtifacts.js
7
7
  import { PlaywrightScenarioEvents } from "./PlaywrightScenarioEvents.js";
8
8
  import { withPlaywrightExecutionBoundary } from "./PlaywrightExecutionBoundary.js";
9
9
  const OPERATION = "capture_browser_scenario";
10
- const originAllowed = (value, allowedOrigins) => {
11
- try {
12
- return allowedOrigins.has(new URL(value).origin);
13
- }
14
- catch {
15
- return false;
16
- }
17
- };
18
10
  const storageSeeds = (blocks, secrets) => {
19
11
  const seeds = {};
20
12
  for (const { origin, entries } of blocks)
@@ -44,78 +36,6 @@ const installStorageSeeds = async (context, page, scenario, secrets) => {
44
36
  window.sessionStorage.setItem(name, value);
45
37
  })()`);
46
38
  };
47
- const installHttpPolicy = async (input) => {
48
- const { context, scenario, secrets, ownedPages, claimOwnedPage } = input;
49
- const routes = scenario.request_replay.mode === "exact"
50
- ? new Map(scenario.request_replay.routes.map((route) => [
51
- `${route.method} ${secrets.url(route.request)}`,
52
- route,
53
- ]))
54
- : new Map();
55
- await context.route("**/*", async (route, request) => {
56
- let requestPage;
57
- try {
58
- requestPage = request.frame().page();
59
- }
60
- catch {
61
- requestPage = undefined;
62
- }
63
- if (scenario.browser.mode === "connect" &&
64
- requestPage !== undefined &&
65
- !ownedPages.has(requestPage))
66
- await claimOwnedPage(requestPage);
67
- if (scenario.browser.mode === "connect" &&
68
- (requestPage === undefined || !ownedPages.has(requestPage))) {
69
- await route.continue();
70
- return;
71
- }
72
- if (!originAllowed(request.url(), new Set(scenario.allowed_origins))) {
73
- await route.abort("blockedbyclient");
74
- return;
75
- }
76
- const replay = routes.get(`${request.method()} ${request.url()}`);
77
- if (replay !== undefined) {
78
- await fulfillReplayRoute(route, replay.response, secrets);
79
- return;
80
- }
81
- if (scenario.request_replay.mode === "exact" &&
82
- scenario.request_replay.unmatched === "abort") {
83
- await route.abort("blockedbyclient");
84
- return;
85
- }
86
- await route.continue();
87
- });
88
- };
89
- const fulfillReplayRoute = async (route, response, secrets) => {
90
- if (response.kind === "redirect") {
91
- await route.fulfill({
92
- status: response.status,
93
- headers: { location: secrets.url(response.destination) },
94
- });
95
- return;
96
- }
97
- await route.fulfill({
98
- status: response.status,
99
- headers: Object.fromEntries(response.headers.map(({ name, value }) => [name, secrets.value(value)])),
100
- ...(response.body === undefined
101
- ? {}
102
- : { body: secrets.value(response.body) }),
103
- });
104
- };
105
- const installWebSocketPolicy = async (owner, scenario) => {
106
- const allowed = new Set(scenario.allowed_origins);
107
- await owner.routeWebSocket("**/*", async (route) => {
108
- const url = new URL(route.url());
109
- const httpOrigin = `${url.protocol === "wss:" ? "https:" : "http:"}//${url.host}`;
110
- if (!allowed.has(httpOrigin) ||
111
- (scenario.request_replay.mode === "exact" &&
112
- scenario.request_replay.unmatched === "abort")) {
113
- await route.close({ code: 1008, reason: "outside scenario policy" });
114
- return;
115
- }
116
- route.connectToServer();
117
- });
118
- };
119
39
  const blockAttachedServiceWorkers = async (page) => {
120
40
  const controller = await page.evaluate("Boolean(navigator.serviceWorker?.controller)");
121
41
  if (controller)
@@ -135,57 +55,29 @@ const blockAttachedServiceWorkers = async (page) => {
135
55
  const initializePage = async (context, page, scenario, secrets) => {
136
56
  context.setDefaultTimeout(0);
137
57
  context.setDefaultNavigationTimeout(0);
138
- const ownedPages = new Set([page]);
139
58
  if (scenario.browser.mode === "connect")
140
59
  await blockAttachedServiceWorkers(page);
141
- await installWebSocketPolicy(scenario.browser.mode === "launch" ? context : page, scenario);
142
- const claimOwnedPage = async (candidate) => {
143
- if (ownedPages.has(candidate))
144
- return true;
145
- const opener = await candidate.opener();
146
- if (opener === null || !ownedPages.has(opener))
147
- return false;
148
- await installWebSocketPolicy(candidate, scenario);
149
- ownedPages.add(candidate);
150
- return true;
151
- };
152
- await installHttpPolicy({
153
- context,
154
- scenario,
155
- secrets,
156
- ownedPages,
157
- claimOwnedPage,
158
- });
159
- page.on("popup", (popup) => {
160
- if (scenario.browser.mode === "connect")
161
- void claimOwnedPage(popup).catch(async () => {
162
- await popup.close().catch(() => undefined);
163
- });
164
- else
165
- ownedPages.add(popup);
166
- });
167
60
  await installStorageSeeds(context, page, scenario, secrets);
168
- return ownedPages;
169
61
  };
170
62
  export class PlaywrightScenarioSession {
171
63
  opened;
172
- scenario;
173
- secrets;
174
- eventCapture;
175
64
  mode;
176
65
  processOwnership;
177
66
  product = "Chromium";
178
67
  version;
179
68
  initialUrl;
180
69
  closed = false;
181
- constructor(opened, scenario, secrets, eventCapture) {
70
+ secrets;
71
+ eventCapture;
72
+ signal;
73
+ constructor(opened, options) {
182
74
  this.opened = opened;
183
- this.scenario = scenario;
184
- this.secrets = secrets;
185
- this.eventCapture = eventCapture;
186
- this.mode = scenario.browser.mode;
75
+ this.mode = options.mode;
187
76
  this.processOwnership =
188
- scenario.browser.mode === "launch" ? "provider-owned" : "external";
77
+ options.mode === "launch" ? "provider-owned" : "external";
78
+ this.secrets = options.secrets;
79
+ this.eventCapture = options.eventCapture;
80
+ this.signal = options.signal;
189
81
  this.version = opened.browser.version();
190
82
  this.initialUrl = opened.page.url();
191
83
  }
@@ -202,7 +94,7 @@ export class PlaywrightScenarioSession {
202
94
  }
203
95
  catch (cause) {
204
96
  void opening
205
- .then((lateOpened) => closePlaywrightScenarioBrowser(lateOpened))
97
+ .then((lateOpened) => closePlaywrightScenarioBrowser(lateOpened, options.signal))
206
98
  .catch(() => undefined);
207
99
  throw cause;
208
100
  }
@@ -210,11 +102,17 @@ export class PlaywrightScenarioSession {
210
102
  await withPlaywrightExecutionBoundary(() => initializePage(opened.context, opened.page, scenario, secrets), undefined, options.signal);
211
103
  const events = new PlaywrightScenarioEvents({
212
104
  page: opened.page,
105
+ context: opened.context,
106
+ ownsContext: scenario.browser.mode === "launch",
213
107
  enabled: new Set(scenario.capture.events),
214
108
  secrets,
215
- allowedOrigins: scenario.allowed_origins,
216
109
  });
217
- const session = new PlaywrightScenarioSession(opened, scenario, secrets, events);
110
+ const session = new PlaywrightScenarioSession(opened, {
111
+ mode: scenario.browser.mode,
112
+ secrets,
113
+ eventCapture: events,
114
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
115
+ });
218
116
  await withPlaywrightExecutionBoundary(() => opened.page.goto(secrets.url(scenario.start_url), {
219
117
  waitUntil: "load",
220
118
  timeout: 0,
@@ -222,13 +120,16 @@ export class PlaywrightScenarioSession {
222
120
  return session;
223
121
  }
224
122
  catch (cause) {
225
- await closePlaywrightScenarioBrowser(opened);
123
+ await closePlaywrightScenarioBrowser(opened, options.signal);
226
124
  throw cause;
227
125
  }
228
126
  }
229
127
  currentUrl() {
230
128
  return this.opened.page.url();
231
129
  }
130
+ sanitizeUrl(value) {
131
+ return this.secrets.sanitizeUrl(value);
132
+ }
232
133
  setStep(index) {
233
134
  this.eventCapture.setStep(index);
234
135
  }
@@ -241,6 +142,10 @@ export class PlaywrightScenarioSession {
241
142
  events() {
242
143
  return this.eventCapture.result();
243
144
  }
145
+ /** Preserve event coverage gaps for the aggregate capture's completeness. */
146
+ eventLimitations() {
147
+ return this.eventCapture.limitations();
148
+ }
244
149
  async perform(action, signal) {
245
150
  await withPlaywrightExecutionBoundary(() => performPlaywrightScenarioAction({
246
151
  page: this.opened.page,
@@ -252,7 +157,6 @@ export class PlaywrightScenarioSession {
252
157
  return withPlaywrightExecutionBoundary(() => capturePlaywrightStepArtifacts({
253
158
  context: this.opened.context,
254
159
  page: this.opened.page,
255
- scenario: this.scenario,
256
160
  secrets: this.secrets,
257
161
  requested,
258
162
  }), undefined, signal);
@@ -263,7 +167,7 @@ export class PlaywrightScenarioSession {
263
167
  ? "terminated-owned-process"
264
168
  : "disconnected-external";
265
169
  this.closed = true;
266
- await closePlaywrightScenarioBrowser(this.opened);
170
+ await closePlaywrightScenarioBrowser(this.opened, this.signal);
267
171
  return this.mode === "launch"
268
172
  ? "terminated-owned-process"
269
173
  : "disconnected-external";