rea-agents 6.1.0 → 6.3.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 (573) hide show
  1. package/README.md +24 -24
  2. package/bridge/ghidra/ReaGhidraBridge.java +32 -4
  3. package/bridge/hopper_bridge.py +8 -1
  4. package/dist/android/JadxConfiguration.js +87 -7
  5. package/dist/android/JadxMcpTransport.js +14 -2
  6. package/dist/android/JadxProvider.js +64 -36
  7. package/dist/android/JadxSession.js +51 -9
  8. package/dist/application/BinaryTargetResolver.js +68 -20
  9. package/dist/application/BrowserEvidence.js +3 -8
  10. package/dist/application/BrowserScenarioEvidence.js +4 -20
  11. package/dist/application/CapabilityInventory.js +43 -9
  12. package/dist/application/ClientConfigurationDocument.js +97 -25
  13. package/dist/application/ClientRegistrationStatus.js +19 -6
  14. package/dist/application/DirectAnalysis.js +41 -20
  15. package/dist/application/DirectAnalysisCleanup.js +71 -0
  16. package/dist/application/DirectAnalysisStatus.js +3 -7
  17. package/dist/application/Doctor.js +40 -53
  18. package/dist/application/DoctorDiagnostics.js +2 -3
  19. package/dist/application/EnhancedTools.js +51 -6
  20. package/dist/application/EvidenceBundleFiles.js +8 -3
  21. package/dist/application/InvestigationProviders.js +13 -5
  22. package/dist/application/JsonFiles.js +56 -23
  23. package/dist/application/LinuxHopper.js +11 -7
  24. package/dist/application/MacHopper.js +15 -18
  25. package/dist/application/RealHopperAssertions.js +0 -11
  26. package/dist/application/ReconstructionObligationCandidates.js +10 -3
  27. package/dist/application/ReconstructionObligationLedgerProjection.js +3 -1
  28. package/dist/application/ReferenceSourceImportEntries.js +1 -1
  29. package/dist/application/RegularFileRead.js +17 -0
  30. package/dist/application/Setup.js +26 -23
  31. package/dist/application/SetupClientConfiguration.js +18 -7
  32. package/dist/application/SetupHost.js +20 -29
  33. package/dist/application/SetupPlan.js +24 -20
  34. package/dist/application/SetupSkill.js +57 -8
  35. package/dist/application/SupportedClients.js +43 -0
  36. package/dist/application/Uninstall.js +98 -30
  37. package/dist/application/UpdateMaintenance.js +13 -7
  38. package/dist/application/UpdateRuntime.js +12 -12
  39. package/dist/application/Utf8JsonInput.js +64 -0
  40. package/dist/application/WebScriptExportService.js +38 -5
  41. package/dist/application/WorkflowEvidence.js +25 -2
  42. package/dist/application/XrefsAddressResolution.js +45 -0
  43. package/dist/application/analysisView/AnalysisViewService.js +76 -0
  44. package/dist/application/android/AndroidAnalysisService.js +1 -1
  45. package/dist/application/binary/AnalysisClientCleanup.js +30 -5
  46. package/dist/application/binary/AnalysisProviderEvaluation.js +1 -2
  47. package/dist/application/binary/AnalysisProviderRegistry.js +2 -6
  48. package/dist/application/binary/AnalysisSnapshotCache.js +13 -10
  49. package/dist/application/binary/BinarySession.js +86 -29
  50. package/dist/application/binary/BinarySessionComposition.js +1 -3
  51. package/dist/application/binary/BinarySessionExecution.js +3 -5
  52. package/dist/application/binary/BinarySessionOpen.js +10 -2
  53. package/dist/application/binary/BinarySessionRecords.js +1 -1
  54. package/dist/application/binary/BinarySessionStatus.js +1 -6
  55. package/dist/application/binary/CompositeProvider.js +4 -18
  56. package/dist/application/binary/LazyAnalysisProvider.js +5 -5
  57. package/dist/application/binary/SessionProviderRouter.js +27 -135
  58. package/dist/application/homebrew.js +48 -0
  59. package/dist/application/javascript/ElectronActiveEvidence.js +10 -14
  60. package/dist/application/javascript/ElectronBoundaryAnalysis.js +2 -2
  61. package/dist/application/javascript/ElectronBoundaryGraphNative.js +5 -1
  62. package/dist/application/javascript/JavaScriptApplicationEvidence.js +3 -6
  63. package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +107 -46
  64. package/dist/application/javascript/JavaScriptApplicationService.js +7 -1
  65. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +59 -45
  66. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +5 -9
  67. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +19 -27
  68. package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +11 -3
  69. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +9 -0
  70. package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +8 -5
  71. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +46 -29
  72. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +0 -1
  73. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +86 -27
  74. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +52 -9
  75. package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +1 -0
  76. package/dist/application/javascript/JavaScriptJsonModules.js +2 -2
  77. package/dist/application/javascript/JavaScriptModuleRelationships.js +6 -18
  78. package/dist/application/javascript/JavaScriptRuntimeObservationService.js +3 -3
  79. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +11 -27
  80. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +4 -5
  81. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +8 -6
  82. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +2 -3
  83. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +7 -5
  84. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +3 -4
  85. package/dist/application/javascript/JavaScriptSemanticGraphEvidence.js +1 -1
  86. package/dist/application/javascript/JavaScriptSemanticGraphFingerprintProjection.js +2 -2
  87. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +3 -7
  88. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +76 -47
  89. package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +4 -4
  90. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +3 -4
  91. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +51 -25
  92. package/dist/application/javascript/JavaScriptSemanticTraceService.js +15 -10
  93. package/dist/application/managed/ManagedMemberComparisonService.js +2 -1
  94. package/dist/application/managed/ManagedNativeVerificationService.js +2 -1
  95. package/dist/application/native/NativeCallRoutes.js +2 -4
  96. package/dist/application/process/ProcessCli.js +11 -11
  97. package/dist/application/process/ProcessEvidence.js +0 -1
  98. package/dist/artifacts/ArtifactProvider.js +53 -30
  99. package/dist/artifacts/ArtifactProviderMetadata.js +1 -4
  100. package/dist/artifacts/ArtifactReader.js +31 -0
  101. package/dist/artifacts/AsarArtifactReader.js +81 -17
  102. package/dist/artifacts/DirectoryArtifactReader.js +2 -1
  103. package/dist/artifacts/MachOSliceArtifactReader.js +9 -2
  104. package/dist/artifacts/NativeDmgArtifactReader.js +207 -77
  105. package/dist/artifacts/NativeDmgOwnership.js +109 -0
  106. package/dist/artifacts/SafeOutputTree.js +16 -2
  107. package/dist/artifacts/ZipArtifactReader.js +11 -4
  108. package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +4 -2
  109. package/dist/artifacts/apple/DylibResolutionReader.js +17 -7
  110. package/dist/artifacts/apple/KeyedArchiveReader.js +68 -42
  111. package/dist/artifacts/apple/MachoLoadCommandReader.js +36 -6
  112. package/dist/artifacts/extraction/ArtifactExtraction.js +104 -29
  113. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +71 -66
  114. package/dist/artifacts/inventory/ArtifactInventory.js +0 -1
  115. package/dist/artifacts/inventory/classify.js +33 -14
  116. package/dist/artifacts/inventory/hashStableRootArtifact.js +37 -0
  117. package/dist/artifacts/inventory/reader.js +3 -3
  118. package/dist/artifacts/inventory/scanCanonical.js +64 -34
  119. package/dist/artifacts/inventory/scanReader.js +12 -20
  120. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +65 -27
  121. package/dist/browser/BrowserScenarioPartialObservation.js +106 -0
  122. package/dist/browser/CdpBrowserProvider.js +6 -6
  123. package/dist/browser/CdpCaptureEventHandlers.js +2 -4
  124. package/dist/browser/CdpCaptureEvents.js +0 -1
  125. package/dist/browser/CdpCaptureStorageFingerprints.js +3 -3
  126. package/dist/browser/CdpCaptureValues.js +20 -0
  127. package/dist/browser/CdpElectronInspection.js +2 -2
  128. package/dist/browser/CdpElectronProvider.js +4 -5
  129. package/dist/browser/CdpElectronScriptEvents.js +2 -8
  130. package/dist/browser/CdpElectronScripts.js +4 -5
  131. package/dist/browser/CdpPageCaptureScripts.js +2 -3
  132. package/dist/browser/CdpSafeMetadata.js +10 -10
  133. package/dist/browser/CdpWebMcpDiscovery.js +16 -13
  134. package/dist/browser/PlaywrightBrowserScenarioProvider.js +64 -49
  135. package/dist/browser/PlaywrightElectronActiveActions.js +2 -56
  136. package/dist/browser/PlaywrightElectronActiveProvider.js +10 -6
  137. package/dist/browser/PlaywrightScenarioArtifacts.js +1 -1
  138. package/dist/browser/PlaywrightScenarioBrowser.js +269 -66
  139. package/dist/browser/PlaywrightScenarioEvents.js +1 -1
  140. package/dist/browser/PlaywrightScenarioSession.js +41 -32
  141. package/dist/browser/WebSourceMapFetcher.js +32 -6
  142. package/dist/browser/assets/ScenarioScriptCapture.js +8 -12
  143. package/dist/browser/assets/ScriptCaptureAdapters.js +1 -1
  144. package/dist/browser/history/CaptureFailures.js +6 -2
  145. package/dist/browser/history/MitmproxyCaptureAdapter.js +4 -2
  146. package/dist/catalogIdentity.js +0 -1
  147. package/dist/cli/analysisViewCommands.js +36 -0
  148. package/dist/cli/artifactCommands.js +11 -12
  149. package/dist/cli/coreAnalysisCommands.js +3 -3
  150. package/dist/cli/coreBinaryCommands.js +37 -28
  151. package/dist/cli/coreNativeCommands.js +9 -10
  152. package/dist/cli/electronCommands.js +12 -13
  153. package/dist/cli/interactiveSetup.js +6 -6
  154. package/dist/cli/javascriptApplicationAnalysis.js +2 -12
  155. package/dist/cli/jsonOutput.js +3 -2
  156. package/dist/cli/managedCommands.js +7 -8
  157. package/dist/cli/nativeCallCommands.js +1 -2
  158. package/dist/cli/omittableDefaults.js +50 -0
  159. package/dist/cli/processCommands.js +3 -2
  160. package/dist/cli/setupCommands.js +16 -15
  161. package/dist/cli/streamedJsonOutput.js +83 -4
  162. package/dist/cli/utilityCommands.js +10 -12
  163. package/dist/cli.js +19 -8
  164. package/dist/cliBrowserScenarioCommands.js +2 -2
  165. package/dist/cliCommandNames.js +1 -0
  166. package/dist/cliJsonFile.js +179 -0
  167. package/dist/cliJsonInput.js +60 -33
  168. package/dist/cliObservationOptions.js +4 -0
  169. package/dist/cliOutput.js +0 -38
  170. package/dist/composition/auxiliaryAnalysisProviders.js +30 -25
  171. package/dist/composition/binary.js +9 -9
  172. package/dist/composition/browserScenario.js +2 -1
  173. package/dist/composition/directAnalysis.js +20 -14
  174. package/dist/composition/electronScenario.js +1 -1
  175. package/dist/composition/optionalObservationProviders.js +12 -7
  176. package/dist/config/environment.js +6 -0
  177. package/dist/config/ghidraStartupTimeout.js +4 -9
  178. package/dist/config/homeDirectory.js +12 -0
  179. package/dist/config/mcpResponseBudget.js +9 -1
  180. package/dist/config/parseConfig.js +7 -3
  181. package/dist/config/parsers.js +19 -22
  182. package/dist/contracts/analysisViewToolContracts.js +56 -0
  183. package/dist/contracts/applicationToolContracts.js +5 -4
  184. package/dist/contracts/artifactComparisonExample.js +7 -7
  185. package/dist/contracts/artifactToolContracts.js +1 -1
  186. package/dist/contracts/browserScenarioToolContracts.js +1 -1
  187. package/dist/contracts/browserToolContracts.js +19 -15
  188. package/dist/contracts/enhancedInputs.js +2 -2
  189. package/dist/contracts/enhancedToolContracts.js +4 -3
  190. package/dist/contracts/errorSchemas.js +3 -1
  191. package/dist/contracts/evm/evmToolContracts.js +1 -1
  192. package/dist/contracts/functionComparisonExample.js +8 -0
  193. package/dist/contracts/functionWorkflowToolContracts.js +1 -1
  194. package/dist/contracts/inputSchemaPresentation.js +181 -0
  195. package/dist/contracts/investigationExamples.js +4 -3
  196. package/dist/contracts/javascript/electronToolContracts.js +3 -2
  197. package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +3 -22
  198. package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +248 -0
  199. package/dist/contracts/javascript/javascriptRuntimeObservationToolContracts.js +1 -1
  200. package/dist/contracts/javascript/javascriptRuntimeReconciliationExample.js +8 -7
  201. package/dist/contracts/managed/managedToolContracts.js +8 -12
  202. package/dist/contracts/managed/managedWorkflowToolContracts.js +1 -1
  203. package/dist/contracts/mobileApplicationGraphExamples.js +8 -8
  204. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +1 -1
  205. package/dist/contracts/native/nativeToolContracts.js +2 -2
  206. package/dist/contracts/officialToolContracts.js +2 -1
  207. package/dist/contracts/promptContracts.js +2 -2
  208. package/dist/contracts/providerSelection.js +1 -1
  209. package/dist/contracts/sessionLifecycleInputs.js +4 -3
  210. package/dist/contracts/sessionStatusContract.js +3 -2
  211. package/dist/contracts/sessionToolContracts.js +17 -4
  212. package/dist/contracts/sessionToolSchemas.js +4 -16
  213. package/dist/contracts/toolContracts.js +2 -0
  214. package/dist/contracts/toolEffects.js +1 -0
  215. package/dist/contracts/toolOutputSchemaGroups.js +138 -94
  216. package/dist/contracts/toolOutputSchemaPrimitives.js +13 -26
  217. package/dist/contracts/toolSchemaMetadata.js +18 -69
  218. package/dist/contracts/webNetworkCaptureToolContracts.js +1 -1
  219. package/dist/contracts/webRuntimeToolContracts.js +1 -1
  220. package/dist/contracts/webScriptToolContracts.js +1 -1
  221. package/dist/doctorRuntime.js +7 -5
  222. package/dist/domain/analysisErrorBase.js +5 -0
  223. package/dist/domain/analysisErrorCore.js +3 -0
  224. package/dist/domain/analysisErrorPresentation.js +22 -5
  225. package/dist/domain/analysisErrorProjection.js +24 -5
  226. package/dist/domain/analysisSnapshot.js +31 -31
  227. package/dist/domain/analysisView/analysisView.js +241 -0
  228. package/dist/domain/analysisView/analysisViewCoverage.js +19 -0
  229. package/dist/domain/analysisView/binaryLayoutView.js +159 -0
  230. package/dist/domain/analysisView/javascriptApplicationView.js +238 -0
  231. package/dist/domain/android/androidApplication.js +1 -1
  232. package/dist/domain/android/androidPartialObservation.js +36 -0
  233. package/dist/domain/apple/appleApplication.js +1 -1
  234. package/dist/domain/apple/dylibResolution.js +10 -3
  235. package/dist/domain/apple/interfaceBuilderGraph.js +0 -1
  236. package/dist/domain/apple/keyedArchive.js +26 -2
  237. package/dist/domain/artifactComparison.js +15 -6
  238. package/dist/domain/artifactGraph.js +17 -4
  239. package/dist/domain/artifactIdentity.js +8 -8
  240. package/dist/domain/artifactInspection.js +8 -8
  241. package/dist/domain/artifactInventoryEvidence.js +9 -16
  242. package/dist/domain/artifactOperationError.js +3 -3
  243. package/dist/domain/artifactPartialObservation.js +1 -0
  244. package/dist/domain/artifactPathSyntax.js +49 -0
  245. package/dist/domain/binaryTarget.js +39 -13
  246. package/dist/domain/browserCaptureComparison.js +13 -49
  247. package/dist/domain/browserCompleteness.js +3 -2
  248. package/dist/domain/browserNetworkEvidence.js +10 -4
  249. package/dist/domain/browserObservation.js +0 -1
  250. package/dist/domain/browserObservationSchemas.js +14 -3
  251. package/dist/domain/browserScenario.js +0 -1
  252. package/dist/domain/browserScenarioCapture.js +1 -2
  253. package/dist/domain/browserScenarioCaptureValues.js +2 -2
  254. package/dist/domain/browserScenarioDiff.js +0 -2
  255. package/dist/domain/browserScenarioDiffEvidence.js +0 -12
  256. package/dist/domain/browserScenarioDiffValues.js +2 -2
  257. package/dist/domain/browserScenarioNormalization.js +3 -3
  258. package/dist/domain/browserScenarioValues.js +6 -6
  259. package/dist/domain/callPath.js +15 -18
  260. package/dist/domain/callPathSchemas.js +2 -2
  261. package/dist/domain/canonicalDigest.js +7 -1
  262. package/dist/domain/canonicalOrdering.js +1 -13
  263. package/dist/domain/changedBehavior.js +5 -6
  264. package/dist/domain/comparisonSemantics.js +0 -5
  265. package/dist/domain/completionLedgerGeneration.js +2 -1
  266. package/dist/domain/configurationErrors.js +12 -0
  267. package/dist/domain/conformancePackage.js +4 -3
  268. package/dist/domain/digests.js +0 -3
  269. package/dist/domain/evidence.js +19 -40
  270. package/dist/domain/evidenceBundle.js +58 -42
  271. package/dist/domain/evidenceCompletionLedger.js +2 -1
  272. package/dist/domain/firmware/firmwareAnalysis.js +4 -3
  273. package/dist/domain/functionComparison.js +6 -6
  274. package/dist/domain/functionComparisonDimensions.js +120 -87
  275. package/dist/domain/functionComparisonNormalization.js +26 -36
  276. package/dist/domain/functionComparisonResults.js +3 -6
  277. package/dist/domain/functionComparisonSchemas.js +2 -8
  278. package/dist/domain/functionDossierEvidence.js +4 -38
  279. package/dist/domain/hopperValues.js +11 -15
  280. package/dist/domain/javascript/electronActiveObservation.js +29 -71
  281. package/dist/domain/javascript/electronObservation.js +14 -3
  282. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +12 -11
  283. package/dist/domain/javascript/electronStaticAnalysisIpc.js +11 -2
  284. package/dist/domain/javascript/electronStaticAnalysisNative.js +7 -4
  285. package/dist/domain/javascript/electronStaticAnalysisValues.js +8 -4
  286. package/dist/domain/javascript/javascriptApplicationAnalysis.js +3 -1
  287. package/dist/domain/javascript/javascriptApplicationChangeGraph.js +12 -8
  288. package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +6 -0
  289. package/dist/domain/javascript/javascriptApplicationGraph.js +41 -16
  290. package/dist/domain/javascript/javascriptApplicationGraphSchemas.js +9 -2
  291. package/dist/domain/javascript/javascriptApplicationVersionComparison.js +4 -4
  292. package/dist/domain/javascript/javascriptApplicationVersionComparisonSchemas.js +37 -22
  293. package/dist/domain/javascript/javascriptApplicationVersionItems.js +50 -36
  294. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +9 -8
  295. package/dist/domain/javascript/javascriptAstFingerprint.js +2 -2
  296. package/dist/domain/javascript/javascriptAstValues.js +22 -0
  297. package/dist/{application/javascript/JavaScriptReturnShapeProjection.js → domain/javascript/javascriptExportReturnShapeProjection.js} +4 -4
  298. package/dist/domain/javascript/javascriptExportShapeComparison.js +10 -3
  299. package/dist/domain/javascript/javascriptExportShapeComparisonIdentity.js +6 -1
  300. package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +58 -22
  301. package/dist/domain/javascript/javascriptExportShapeSelection.js +7 -7
  302. package/dist/domain/javascript/javascriptExportShapeVariants.js +70 -16
  303. package/dist/domain/javascript/javascriptFeatureSeed.js +25 -3
  304. package/dist/domain/javascript/javascriptFeatureTrace.js +7 -6
  305. package/dist/domain/javascript/javascriptFeatureTraceSchemas.js +17 -9
  306. package/dist/domain/javascript/javascriptFeatureTraversal.js +4 -5
  307. package/dist/domain/javascript/javascriptNativeHandoff.js +7 -7
  308. package/dist/domain/javascript/javascriptRuntimeLoadState.js +0 -1
  309. package/dist/domain/javascript/javascriptRuntimeObservation.js +18 -7
  310. package/dist/domain/javascript/javascriptRuntimeReconciliation.js +12 -6
  311. package/dist/domain/javascript/javascriptRuntimeReconciliationActive.js +9 -8
  312. package/dist/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js +212 -0
  313. package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +5 -4
  314. package/dist/domain/javascript/javascriptRuntimeReconciliationInputValidation.js +28 -0
  315. package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +6 -6
  316. package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +12 -222
  317. package/dist/domain/javascript/javascriptRuntimeReconciliationResult.js +2 -2
  318. package/dist/domain/javascript/javascriptRuntimeReconciliationRuntime.js +15 -4
  319. package/dist/domain/javascript/javascriptRuntimeReconciliationSchemas.js +2 -2
  320. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +7 -7
  321. package/dist/domain/javascript/javascriptSemanticAnalysis.js +209 -11
  322. package/dist/domain/javascript/javascriptSemanticAsyncEffects.js +2 -1
  323. package/dist/domain/javascript/javascriptSemanticCallResolution.js +9 -7
  324. package/dist/domain/javascript/javascriptSemanticCalls.js +2 -1
  325. package/dist/domain/javascript/javascriptSemanticChildProcesses.js +4 -3
  326. package/dist/domain/javascript/javascriptSemanticCoverage.js +20 -0
  327. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +7 -9
  328. package/dist/domain/javascript/javascriptSemanticDataEffects.js +4 -11
  329. package/dist/domain/javascript/javascriptSemanticFingerprints.js +2 -2
  330. package/dist/domain/javascript/javascriptSemanticGraph.js +220 -71
  331. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +19 -1
  332. package/dist/domain/javascript/javascriptSemanticIr.js +0 -4
  333. package/dist/domain/javascript/javascriptSemanticIterationSources.js +106 -0
  334. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +515 -74
  335. package/dist/domain/javascript/javascriptSemanticMutationInitializers.js +190 -0
  336. package/dist/domain/javascript/javascriptSemanticMutationValues.js +44 -36
  337. package/dist/domain/javascript/javascriptSemanticObjects.js +79 -42
  338. package/dist/domain/javascript/javascriptSemanticPrimitives.js +8 -14
  339. package/dist/domain/javascript/javascriptSemanticProjection.js +21 -16
  340. package/dist/domain/javascript/javascriptSemanticPromises.js +16 -21
  341. package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +23 -0
  342. package/dist/domain/javascript/javascriptSemanticProvenance.js +3 -3
  343. package/dist/domain/javascript/javascriptSemanticQuery.js +8 -2
  344. package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +3 -2
  345. package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -9
  346. package/dist/domain/javascript/javascriptSemanticRequireOrigin.js +16 -10
  347. package/dist/domain/javascript/javascriptSemanticResourceLimits.js +1 -1
  348. package/dist/domain/javascript/javascriptSemanticResources.js +1 -1
  349. package/dist/domain/javascript/javascriptSemanticReturns.js +55 -44
  350. package/dist/domain/javascript/javascriptSemanticSlots.js +72 -0
  351. package/dist/domain/javascript/javascriptSemanticTraversal.js +6 -1
  352. package/dist/domain/javascript/javascriptSemanticValues.js +180 -76
  353. package/dist/domain/javascript/javascriptSourceMapPaths.js +114 -0
  354. package/dist/domain/javascript/javascriptSourceParser.js +34 -9
  355. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -6
  356. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +2 -1
  357. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +26 -16
  358. package/dist/domain/javascript/sourceToBundleComparison.js +19 -8
  359. package/dist/domain/javascript/sourceToBundleSignals.js +53 -25
  360. package/dist/domain/jsonSerialization.js +109 -55
  361. package/dist/domain/jsonShape.js +46 -19
  362. package/dist/domain/localPath.js +10 -4
  363. package/dist/domain/managed/managedApplicationGraph.js +10 -6
  364. package/dist/domain/managed/managedApplicationGraphNodes.js +82 -57
  365. package/dist/domain/managed/managedArtifact.js +6 -4
  366. package/dist/domain/managed/managedMemberComparison.js +2 -9
  367. package/dist/domain/managed/managedMemberComparisonMatch.js +6 -7
  368. package/dist/domain/managed/managedNativeVerification.js +0 -2
  369. package/dist/domain/managed/managedNativeVerificationMatch.js +9 -3
  370. package/dist/domain/native/binaryLayout.js +2 -3
  371. package/dist/domain/native/nativeApiBoundary.js +1 -1
  372. package/dist/domain/native/nativeCallObservation.js +3 -3
  373. package/dist/domain/native/nativeInstruction.js +7 -0
  374. package/dist/domain/native/nativeValueFlow.js +5 -11
  375. package/dist/domain/native/objcSwiftMetadata.js +15 -17
  376. package/dist/domain/native/recordedCrash.js +2 -3
  377. package/dist/domain/offsetDateTime.js +17 -0
  378. package/dist/domain/process/processCapture.js +22 -20
  379. package/dist/domain/process/processCaptureCoverage.js +70 -0
  380. package/dist/domain/process/processCaptureExample.js +45 -1
  381. package/dist/domain/process/processCaptureParsing.js +1 -34
  382. package/dist/domain/process/processCaptureValidation.js +82 -13
  383. package/dist/domain/process/processComparison.js +39 -43
  384. package/dist/domain/process/processObservation.js +10 -2
  385. package/dist/domain/process/processScenario.js +24 -2
  386. package/dist/domain/process/processTraceComparison.js +0 -2
  387. package/dist/domain/process/processTraceDimensionProjection.js +1 -1
  388. package/dist/domain/process/processTraceEvaluation.js +19 -15
  389. package/dist/domain/process/processTraceSpecification.js +4 -7
  390. package/dist/domain/providerAdapterError.js +2 -0
  391. package/dist/domain/providerCleanupError.js +6 -2
  392. package/dist/domain/reconstructionCoverage.js +7 -3
  393. package/dist/domain/reconstructionObligationLedgerSchemas.js +2 -1
  394. package/dist/domain/reconstructionReadinessSchemas.js +2 -1
  395. package/dist/domain/reconstructionUnknowns.js +4 -3
  396. package/dist/domain/reconstructionVerification.js +6 -5
  397. package/dist/domain/reconstructionVerificationSchemas.js +2 -1
  398. package/dist/domain/referenceSourceGraph.js +27 -28
  399. package/dist/domain/referenceSourceImportParsing.js +34 -45
  400. package/dist/domain/residualUnknown.js +3 -2
  401. package/dist/domain/staticRuntimeCorrelation.js +4 -3
  402. package/dist/domain/stringPatterns.js +6 -0
  403. package/dist/domain/swiftSymbolClassification.js +66 -0
  404. package/dist/domain/symbolAnalysis.js +83 -20
  405. package/dist/domain/unicodeCodePointOrder.js +6 -0
  406. package/dist/domain/webBundleAnalyzerInspection.js +9 -1
  407. package/dist/domain/webCaptureDiff.js +71 -30
  408. package/dist/domain/webCaptureDiffSchemas.js +8 -11
  409. package/dist/domain/webEventListeners.js +3 -2
  410. package/dist/domain/webExecution.js +3 -2
  411. package/dist/domain/webInventory.js +3 -2
  412. package/dist/domain/webMcpDiscovery.js +4 -3
  413. package/dist/domain/webRuntime.js +0 -2
  414. package/dist/domain/webScriptExport.js +2 -2
  415. package/dist/dotnet/ManagedArtifactInspector.js +2 -19
  416. package/dist/dotnet/ManagedMemberInspector.js +12 -18
  417. package/dist/dotnet/ManagedMemberInspectorCore.js +47 -44
  418. package/dist/dotnet/ManagedMemberInstructionDecoder.js +1 -2
  419. package/dist/dotnet/ManagedMemberRows.js +75 -62
  420. package/dist/dotnet/ManagedMetadataInventory.js +16 -22
  421. package/dist/dotnet/ManagedMethodBodyReader.js +4 -0
  422. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +109 -94
  423. package/dist/dotnet/ManagedNativeBoundaryInspector.js +12 -21
  424. package/dist/dotnet/ManagedReaderFailure.js +16 -0
  425. package/dist/dotnet/ManagedStaticProvider.js +13 -12
  426. package/dist/dotnet/ManagedStaticProviderMetadata.js +1 -4
  427. package/dist/evaluation/AgentEvaluationFixtures.js +250 -0
  428. package/dist/evaluation/AgentEvaluationReport.js +28 -0
  429. package/dist/evaluation/CodexAgentEval.js +12 -8
  430. package/dist/evaluation/KnownAnswerEvaluation.js +281 -0
  431. package/dist/evm/EvmoleInterfaceProvider.js +2 -1
  432. package/dist/filesystem/RegularFile.js +41 -0
  433. package/dist/firmware/FirmwareCommand.js +9 -5
  434. package/dist/firmware/FirmwareProvider.js +4 -4
  435. package/dist/generatedPackageMetadata.js +2 -2
  436. package/dist/ghidra/GhidraAnalysisProfile.js +3 -6
  437. package/dist/ghidra/GhidraClient.js +105 -36
  438. package/dist/ghidra/GhidraClientStartup.js +0 -2
  439. package/dist/ghidra/GhidraDoctor.js +6 -5
  440. package/dist/ghidra/GhidraFunctionValues.js +3 -5
  441. package/dist/ghidra/GhidraInstallation.js +151 -22
  442. package/dist/ghidra/GhidraJavaLaunch.js +6 -2
  443. package/dist/ghidra/GhidraLauncher.js +58 -26
  444. package/dist/ghidra/GhidraProvider.js +6 -2
  445. package/dist/ghidra/GhidraProviderCapabilities.js +6 -0
  446. package/dist/ghidra/GhidraProviderClient.js +13 -3
  447. package/dist/ghidra/GhidraSessionError.js +2 -0
  448. package/dist/ghidra/GhidraSessionRoot.js +39 -0
  449. package/dist/ghidra/extensions/GhidraExtensions.js +17 -10
  450. package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +8 -2
  451. package/dist/hopper/BridgeLauncher.js +34 -45
  452. package/dist/hopper/HopperAnalysisProfile.js +3 -8
  453. package/dist/hopper/HopperCleanup.js +56 -27
  454. package/dist/hopper/HopperClient.js +86 -65
  455. package/dist/hopper/HopperMachOImage.js +3 -2
  456. package/dist/hopper/HopperProvider.js +16 -18
  457. package/dist/hopper/HopperRegexSearch.js +3 -6
  458. package/dist/hopper/HopperTargetLease.js +132 -49
  459. package/dist/hopper/LinuxPrivateDisplayProbe.js +6 -0
  460. package/dist/ida/IdaConfiguration.js +8 -3
  461. package/dist/ida/IdaInput.js +1 -7
  462. package/dist/ida/IdaMcpConnection.js +8 -4
  463. package/dist/ida/IdaOperationRunner.js +5 -3
  464. package/dist/ida/IdaProvider.js +8 -12
  465. package/dist/ida/IdaSessionClient.js +24 -20
  466. package/dist/ida/IdaWorkspace.js +12 -13
  467. package/dist/inspector/JavaScriptRuntimeScope.js +9 -5
  468. package/dist/inspector/V8InspectorCaptureProjection.js +47 -14
  469. package/dist/inspector/V8InspectorProvider.js +97 -35
  470. package/dist/javascript/recovery/WakaruCommand.js +7 -2
  471. package/dist/javascript/recovery/WakaruExecution.js +5 -2
  472. package/dist/main/shutdown.js +81 -29
  473. package/dist/main/startup.js +9 -2
  474. package/dist/main/transport.js +23 -3
  475. package/dist/main.js +11 -18
  476. package/dist/native/AppleMachoSelection.js +16 -6
  477. package/dist/native/AppleObjcDispatchFacets.js +3 -3
  478. package/dist/native/AppleObjcProperties.js +17 -7
  479. package/dist/native/CommandRunner.js +9 -7
  480. package/dist/native/LldbCallTracer.js +249 -77
  481. package/dist/native/NativeMacOSProvider.js +32 -17
  482. package/dist/native/NativeMacOSProviderMetadata.js +1 -2
  483. package/dist/native/NativeUiHelperRuntime.js +11 -2
  484. package/dist/native/NativeUiObservation.js +2 -2
  485. package/dist/native/pwntools/PwntoolsDecoder.js +2 -1
  486. package/dist/process/DarwinProcessRunTokenReader.js +16 -2
  487. package/dist/process/ExecFileOutput.js +88 -6
  488. package/dist/process/PrivateRuntimeRoot.js +10 -5
  489. package/dist/process/ProcessOwnership.js +1 -4
  490. package/dist/process/ProcessOwnershipObservation.js +18 -16
  491. package/dist/process/ProviderProcess.js +1 -3
  492. package/dist/process/capture/FilesystemSnapshot.js +131 -24
  493. package/dist/process/capture/ProcessCaptureError.js +13 -0
  494. package/dist/process/capture/ProcessCaptureLifecycle.js +148 -74
  495. package/dist/process/capture/ProcessFilesystemEffects.js +51 -6
  496. package/dist/process/capture/ProcessHarness.js +16 -33
  497. package/dist/process/capture/ProcessNormalization.js +20 -2
  498. package/dist/process/capture/ProcessSampling.js +25 -2
  499. package/dist/process/capture/TerminalRenderer.js +14 -0
  500. package/dist/process/snapshotEnvironment.js +14 -0
  501. package/dist/server/EvidenceMcpServer.js +25 -14
  502. package/dist/server/analysisAdmission.js +8 -0
  503. package/dist/server/createServer.js +71 -59
  504. package/dist/server/mcpClientMetadata.js +12 -5
  505. package/dist/server/promptCompletion.js +3 -8
  506. package/dist/server/registerAnalysisViewTool.js +15 -0
  507. package/dist/server/registerAndroidTools.js +2 -3
  508. package/dist/server/registerApplicationTools/compareExportShapes.js +6 -6
  509. package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
  510. package/dist/server/registerApplicationTools/compareVersions.js +4 -5
  511. package/dist/server/registerApplicationTools/coverage.js +1 -2
  512. package/dist/server/registerApplicationTools/helpers.js +4 -4
  513. package/dist/server/registerApplicationTools/obligationLedger.js +4 -5
  514. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -4
  515. package/dist/server/registerApplicationTools/traceFeature.js +4 -5
  516. package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
  517. package/dist/server/registerArtifactComparisonTool.js +4 -5
  518. package/dist/server/registerArtifactTools.js +2 -2
  519. package/dist/server/registerBinaryDiagnosticsTools.js +2 -3
  520. package/dist/server/registerBrowserScenarioTool.js +3 -4
  521. package/dist/server/registerBrowserTools.js +13 -16
  522. package/dist/server/registerBundleComparisonTool.js +5 -6
  523. package/dist/server/registerCloseLifecycleTool.js +8 -7
  524. package/dist/server/registerElectronTools.js +10 -13
  525. package/dist/server/registerEnhancedTools.js +82 -77
  526. package/dist/server/registerEvidenceTools.js +54 -47
  527. package/dist/server/registerEvmTools.js +2 -3
  528. package/dist/server/registerFirmwareTools.js +2 -3
  529. package/dist/server/registerFunctionComparisonTool.js +7 -8
  530. package/dist/server/registerInvestigationTools.js +14 -15
  531. package/dist/server/registerJavaScriptRecoveryTool.js +2 -3
  532. package/dist/server/registerJavaScriptRuntimeObservationTools.js +6 -6
  533. package/dist/server/registerManagedTools.js +7 -4
  534. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +5 -6
  535. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +4 -5
  536. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +6 -7
  537. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +6 -7
  538. package/dist/server/registerOfficialTools.js +32 -41
  539. package/dist/server/registerProcessComparisonTool.js +8 -8
  540. package/dist/server/registerRecordedCrashTools.js +2 -3
  541. package/dist/server/registerSessionRecordTools.js +15 -19
  542. package/dist/server/registerSessionStatusTool.js +3 -4
  543. package/dist/server/registerSessionTools.js +19 -19
  544. package/dist/server/registerWebModuleTool.js +2 -3
  545. package/dist/server/registerWebNetworkCaptureTool.js +2 -3
  546. package/dist/server/registerWebRuntimeTools.js +4 -5
  547. package/dist/server/registerWebScriptTool.js +2 -3
  548. package/dist/server/registerWebSourceLocationTool.js +2 -3
  549. package/dist/server/toolResult.js +66 -94
  550. package/dist/server/toolResultEncoding.js +11 -10
  551. package/dist/windows/WindowsNativeLoader.js +1 -0
  552. package/dist/windows/WindowsOwnedProcess.js +60 -15
  553. package/dist/windows/WindowsPrivateRuntime.js +7 -8
  554. package/native/windows/README.md +3 -1
  555. package/native/windows/build/manifest.json +2 -2
  556. package/native/windows/build/rea-windows-x64.node +0 -0
  557. package/package.json +42 -30
  558. package/scripts/rea.mjs +3 -6
  559. package/skills/reverse-engineer-anything/SKILL.md +14 -13
  560. package/skills/reverse-engineer-anything/references/android-applications.md +6 -3
  561. package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -4
  562. package/skills/reverse-engineer-anything/references/javascript-applications.md +16 -6
  563. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +18 -0
  564. package/dist/artifacts/inventory/policy.js +0 -2
  565. package/dist/config.js +0 -1
  566. package/dist/contracts/browserCaptureToolInputSchema.js +0 -43
  567. package/dist/contracts/process/processCaptureExample.js +0 -2
  568. package/dist/contracts/toolOutputSchemas.js +0 -2
  569. package/dist/domain/managed/managedApplicationGraphNodeCoverage.js +0 -6
  570. package/dist/main/reload.js +0 -12
  571. package/dist/main/state.js +0 -3
  572. package/dist/server/registerNativeTools.js +0 -6
  573. package/dist/server/sessionToolPolicies.js +0 -2
@@ -2,9 +2,168 @@ import { chmod, mkdtemp, rm } from "node:fs/promises";
2
2
  import { tmpdir } from "node:os";
3
3
  import { join, resolve } from "node:path";
4
4
  import { chromium, } from "playwright-core";
5
+ import { AnalysisError } from "../domain/analysisErrorBase.js";
5
6
  import { BrowserObservationError } from "../domain/browserObservationError.js";
6
7
  import { withPlaywrightExecutionBoundary } from "./PlaywrightExecutionBoundary.js";
7
8
  const OPERATION = "capture_browser_scenario";
9
+ const throwIfScenarioCancelled = (signal) => {
10
+ if (signal?.aborted === true)
11
+ throw new BrowserObservationError(OPERATION, "cancelled");
12
+ };
13
+ /** Owns one browser connection and optional private profile through cleanup retries. */
14
+ export class PlaywrightScenarioBrowserCleanupOwner {
15
+ resources;
16
+ #browserClosed = false;
17
+ #profileRemoved;
18
+ #closePromise;
19
+ #eventFinalizationPromise;
20
+ /** Keep the narrow provider actions needed to release one opened browser. */
21
+ constructor(resources) {
22
+ this.resources = resources;
23
+ this.#profileRemoved = resources.removeProfile === undefined;
24
+ }
25
+ close(finishEvents, signal) {
26
+ const cleanup = this.#closePromise ?? this.#closeResources(finishEvents);
27
+ if (this.#closePromise === undefined) {
28
+ this.#closePromise = cleanup;
29
+ void cleanup.then(() => this.resources.onSettled?.(this.#browserClosed), () => {
30
+ if (this.#closePromise === cleanup)
31
+ this.#closePromise = undefined;
32
+ this.resources.onSettled?.(this.#browserClosed);
33
+ });
34
+ }
35
+ return this.#awaitCleanup(cleanup, signal);
36
+ }
37
+ async #awaitCleanup(cleanup, signal) {
38
+ try {
39
+ await withPlaywrightExecutionBoundary(() => cleanup, 1_000, signal);
40
+ }
41
+ catch (cause) {
42
+ throw new BrowserObservationError(OPERATION, "cleanup_failed", {
43
+ cause,
44
+ cleanup: {
45
+ reason: cause instanceof Error ? cause.message : String(cause),
46
+ resources: [
47
+ "browser_transport",
48
+ ...(this.resources.removeProfile === undefined
49
+ ? []
50
+ : ["browser_profile"]),
51
+ ],
52
+ },
53
+ });
54
+ }
55
+ }
56
+ async #closeResources(finishEvents) {
57
+ const failures = [];
58
+ const eventFinalization = (this.#eventFinalizationPromise ??=
59
+ Promise.resolve().then(async () => {
60
+ await finishEvents?.();
61
+ }));
62
+ try {
63
+ await eventFinalization;
64
+ }
65
+ catch (cause) {
66
+ failures.push(cause);
67
+ }
68
+ if (!this.#browserClosed) {
69
+ try {
70
+ await this.resources.closeBrowser();
71
+ this.#browserClosed = true;
72
+ }
73
+ catch (cause) {
74
+ failures.push(cause);
75
+ }
76
+ }
77
+ if (this.#browserClosed &&
78
+ !this.#profileRemoved &&
79
+ this.resources.removeProfile !== undefined) {
80
+ try {
81
+ await this.resources.removeProfile();
82
+ this.#profileRemoved = true;
83
+ }
84
+ catch (cause) {
85
+ failures.push(cause);
86
+ }
87
+ }
88
+ if (failures.length === 1)
89
+ throw failures[0];
90
+ if (failures.length > 1)
91
+ throw new AggregateError(failures, "Browser session cleanup failed");
92
+ }
93
+ }
94
+ const attachedScenarioAdmissions = new Map();
95
+ const releaseAttachedScenario = (key, admission) => {
96
+ const waiter = admission.waiters.shift();
97
+ if (waiter === undefined) {
98
+ admission.active = false;
99
+ if (admission.cleanupOwner === undefined &&
100
+ attachedScenarioAdmissions.get(key) === admission)
101
+ attachedScenarioAdmissions.delete(key);
102
+ return;
103
+ }
104
+ if (waiter.onAbort !== undefined)
105
+ waiter.signal?.removeEventListener("abort", waiter.onAbort);
106
+ if (waiter.signal?.aborted === true) {
107
+ waiter.reject(new BrowserObservationError(OPERATION, "cancelled"));
108
+ releaseAttachedScenario(key, admission);
109
+ return;
110
+ }
111
+ waiter.resolve(createAttachedScenarioRelease(key, admission));
112
+ };
113
+ const createAttachedScenarioRelease = (key, admission) => {
114
+ let released = false;
115
+ return () => {
116
+ if (released)
117
+ return;
118
+ released = true;
119
+ releaseAttachedScenario(key, admission);
120
+ };
121
+ };
122
+ const acquireAttachedScenario = (scenario, signal) => {
123
+ if (signal?.aborted === true)
124
+ return Promise.reject(new BrowserObservationError(OPERATION, "cancelled"));
125
+ const key = JSON.stringify([scenario.cdp_endpoint, scenario.target_id]);
126
+ const admission = attachedScenarioAdmissions.get(key) ??
127
+ {
128
+ active: false,
129
+ waiters: [],
130
+ cleanupOwner: undefined,
131
+ };
132
+ attachedScenarioAdmissions.set(key, admission);
133
+ return new Promise((resolve, reject) => {
134
+ const grant = (release) => resolve({ admission, release });
135
+ if (!admission.active) {
136
+ admission.active = true;
137
+ grant(createAttachedScenarioRelease(key, admission));
138
+ return;
139
+ }
140
+ const waiter = {
141
+ signal,
142
+ resolve: (release) => grant(release),
143
+ reject,
144
+ onAbort: undefined,
145
+ };
146
+ admission.waiters.push(waiter);
147
+ if (signal !== undefined) {
148
+ const onAbort = () => {
149
+ const index = admission.waiters.indexOf(waiter);
150
+ if (index < 0)
151
+ return;
152
+ admission.waiters.splice(index, 1);
153
+ signal.removeEventListener("abort", onAbort);
154
+ reject(new BrowserObservationError(OPERATION, "cancelled"));
155
+ if (!admission.active && admission.waiters.length === 0)
156
+ releaseAttachedScenario(key, admission);
157
+ };
158
+ waiter.onAbort = onAbort;
159
+ signal.addEventListener("abort", onAbort, { once: true });
160
+ if (signal.aborted) {
161
+ onAbort();
162
+ return;
163
+ }
164
+ }
165
+ });
166
+ };
8
167
  const allowedBrowserEnvironment = (environment) => {
9
168
  const allowed = [
10
169
  "DBUS_SESSION_BUS_ADDRESS",
@@ -25,12 +184,14 @@ const allowedBrowserEnvironment = (environment) => {
25
184
  .map((name) => [name, environment[name]])
26
185
  .filter((entry) => entry[1] !== undefined));
27
186
  };
28
- const findConnectedPage = async (browser, targetId) => {
187
+ const findConnectedPage = async (browser, targetId, signal) => {
29
188
  for (const context of browser.contexts())
30
189
  for (const page of context.pages()) {
31
190
  const session = await context.newCDPSession(page);
32
191
  try {
192
+ throwIfScenarioCancelled(signal);
33
193
  const { targetInfo } = await session.send("Target.getTargetInfo");
194
+ throwIfScenarioCancelled(signal);
34
195
  if (targetInfo.targetId !== targetId)
35
196
  continue;
36
197
  return { context, page };
@@ -41,51 +202,108 @@ const findConnectedPage = async (browser, targetId) => {
41
202
  }
42
203
  throw new BrowserObservationError(OPERATION, "target_not_found");
43
204
  };
44
- const configureAttachedEnvironment = async (context, page, scenario) => {
45
- await page.setViewportSize({
46
- width: scenario.environment.viewport.width,
47
- height: scenario.environment.viewport.height,
48
- });
205
+ const configureAttachedEnvironment = async (context, page, environment, signal) => {
206
+ // setViewportSize also resizes the external browser window. The scenario's
207
+ // CDP metrics override below supplies the viewport and expires on disconnect.
49
208
  await page.emulateMedia({
50
- colorScheme: scenario.environment.color_scheme,
51
- reducedMotion: scenario.environment.reduced_motion,
209
+ colorScheme: environment.color_scheme,
210
+ reducedMotion: environment.reduced_motion,
52
211
  });
212
+ throwIfScenarioCancelled(signal);
53
213
  const session = await context.newCDPSession(page);
214
+ throwIfScenarioCancelled(signal);
215
+ // Chromium resets these overrides when the CDP session detaches. Keep it on
216
+ // the scenario transport until cleanup disconnects the attached browser.
217
+ await session.send("Emulation.setDeviceMetricsOverride", {
218
+ width: environment.viewport.width,
219
+ height: environment.viewport.height,
220
+ deviceScaleFactor: environment.viewport.device_scale_factor,
221
+ mobile: false,
222
+ dontSetVisibleSize: true,
223
+ });
224
+ throwIfScenarioCancelled(signal);
225
+ await session.send("Emulation.setLocaleOverride", {
226
+ locale: environment.locale,
227
+ });
228
+ throwIfScenarioCancelled(signal);
229
+ await session.send("Emulation.setTimezoneOverride", {
230
+ timezoneId: environment.timezone,
231
+ });
232
+ };
233
+ /** Preserve an operation failure while reporting any incomplete cleanup. */
234
+ export const failBrowserScenarioOperation = async (cleanup, primaryFailure, fallbackCleanupResources = ["browser_transport"]) => {
54
235
  try {
55
- await session.send("Emulation.setDeviceMetricsOverride", {
56
- width: scenario.environment.viewport.width,
57
- height: scenario.environment.viewport.height,
58
- deviceScaleFactor: scenario.environment.viewport.device_scale_factor,
59
- mobile: false,
60
- });
61
- await session.send("Emulation.setLocaleOverride", {
62
- locale: scenario.environment.locale,
63
- });
64
- await session.send("Emulation.setTimezoneOverride", {
65
- timezoneId: scenario.environment.timezone,
66
- });
236
+ await cleanup();
67
237
  }
68
- finally {
69
- await session.detach();
238
+ catch (cleanupFailure) {
239
+ const cleanupDetails = cleanupFailure instanceof AnalysisError &&
240
+ cleanupFailure.cleanup !== undefined
241
+ ? cleanupFailure.cleanup
242
+ : {
243
+ reason: cleanupFailure instanceof Error
244
+ ? cleanupFailure.message
245
+ : String(cleanupFailure),
246
+ resources: cleanupFailure instanceof AnalysisError
247
+ ? cleanupFailure.cleanupResources
248
+ : fallbackCleanupResources,
249
+ };
250
+ throw new BrowserObservationError(OPERATION, "cleanup_failed", {
251
+ cause: new AggregateError([primaryFailure, cleanupFailure], "Browser scenario operation and cleanup both failed", { cause: primaryFailure }),
252
+ cleanup: cleanupDetails,
253
+ });
70
254
  }
255
+ throw primaryFailure;
71
256
  };
72
- export const openPlaywrightScenarioBrowser = async (scenario, environment) => {
73
- if (scenario.browser.mode === "connect") {
74
- const browser = await chromium.connectOverCDP(scenario.browser.cdp_endpoint, { timeout: 0 });
75
- try {
76
- const target = await findConnectedPage(browser, scenario.browser.target_id);
77
- await configureAttachedEnvironment(target.context, target.page, scenario);
78
- return { ...target, browser, profilePath: undefined };
79
- }
80
- catch (cause) {
81
- await browser.close();
257
+ const openAttachedScenarioBrowser = async (browserRequest, environment, launcher, signal) => {
258
+ const lease = await acquireAttachedScenario(browserRequest, signal);
259
+ let cleanupOwner;
260
+ try {
261
+ const priorOwner = lease.admission.cleanupOwner;
262
+ if (priorOwner !== undefined)
263
+ await priorOwner.close();
264
+ throwIfScenarioCancelled(signal);
265
+ const browser = await launcher.connectOverCDP(browserRequest.cdp_endpoint);
266
+ const cleanup = new PlaywrightScenarioBrowserCleanupOwner({
267
+ closeBrowser: () => browser.close(),
268
+ onSettled: (browserClosed) => {
269
+ if (browserClosed && lease.admission.cleanupOwner === cleanup)
270
+ lease.admission.cleanupOwner = undefined;
271
+ lease.release();
272
+ },
273
+ removeProfile: undefined,
274
+ });
275
+ cleanupOwner = cleanup;
276
+ lease.admission.cleanupOwner = cleanup;
277
+ throwIfScenarioCancelled(signal);
278
+ const target = await withPlaywrightExecutionBoundary(() => findConnectedPage(browser, browserRequest.target_id, signal), undefined, signal);
279
+ throwIfScenarioCancelled(signal);
280
+ await withPlaywrightExecutionBoundary(() => configureAttachedEnvironment(target.context, target.page, environment, signal), undefined, signal);
281
+ return {
282
+ ...target,
283
+ browser,
284
+ profilePath: undefined,
285
+ cleanup,
286
+ };
287
+ }
288
+ catch (cause) {
289
+ if (cleanupOwner === undefined) {
290
+ lease.release();
82
291
  throw cause;
83
292
  }
293
+ const cleanup = cleanupOwner;
294
+ return failBrowserScenarioOperation(() => cleanup.close(), cause);
84
295
  }
296
+ };
297
+ /** Launch or attach using the caller-selected environment and browser engine. */
298
+ export const openPlaywrightScenarioBrowser = async (scenario, environment, options = {}) => {
299
+ const launcher = options.launcher ?? chromium;
300
+ if (scenario.browser.mode === "connect")
301
+ return openAttachedScenarioBrowser(scenario.browser, scenario.environment, launcher, options.signal);
85
302
  const profilePath = await mkdtemp(join(tmpdir(), "rea-browser-scenario-"));
86
- await chmod(profilePath, 0o700);
303
+ let context;
87
304
  try {
88
- const context = await chromium.launchPersistentContext(profilePath, {
305
+ await chmod(profilePath, 0o700);
306
+ context = await launcher.launchPersistentContext(profilePath, {
89
307
  executablePath: resolve(scenario.browser.executable_path),
90
308
  headless: scenario.browser.headless,
91
309
  acceptDownloads: false,
@@ -105,43 +323,28 @@ export const openPlaywrightScenarioBrowser = async (scenario, environment) => {
105
323
  handleSIGTERM: false,
106
324
  timeout: 0,
107
325
  });
108
- const browser = context.browser();
109
- if (browser === null) {
110
- await context.close();
111
- throw new BrowserObservationError(OPERATION, "protocol_error");
112
- }
113
- const page = context.pages()[0] ?? (await context.newPage());
114
- return { context, page, browser, profilePath };
115
326
  }
116
327
  catch (cause) {
117
- await rm(profilePath, { recursive: true, force: true, maxRetries: 3 });
118
- throw cause;
328
+ return failBrowserScenarioOperation(() => rm(profilePath, { recursive: true, force: true, maxRetries: 3 }), cause, ["browser_profile"]);
119
329
  }
120
- };
121
- export const closePlaywrightScenarioBrowser = async ({ context, browser, profilePath }, signal) => {
122
- const cleanup = (async () => {
123
- try {
124
- // In connect mode Playwright's Browser.close disconnects its CDP client;
125
- // it does not close the externally owned browser process.
126
- if (profilePath === undefined)
127
- await browser.close();
128
- else
129
- await context.close();
130
- }
131
- finally {
132
- if (profilePath !== undefined)
133
- await rm(profilePath, { recursive: true, force: true, maxRetries: 3 });
134
- }
135
- })();
136
- // best-effort cleanup: the bounded execution boundary below observes the
137
- // same cleanup promise; this early attachment only prevents unhandled rejection.
138
- void cleanup.catch(() => undefined);
139
- // The shared execution boundary rejects cancellation/timeouts instead of
140
- // returning a successful capture whose browser or profile may still exist.
330
+ const cleanup = new PlaywrightScenarioBrowserCleanupOwner({
331
+ closeBrowser: () => context.close(),
332
+ removeProfile: () => rm(profilePath, { recursive: true, force: true, maxRetries: 3 }),
333
+ });
141
334
  try {
142
- await withPlaywrightExecutionBoundary(() => cleanup, 1_000, signal);
335
+ const browser = context.browser();
336
+ if (browser === null)
337
+ throw new BrowserObservationError(OPERATION, "protocol_error");
338
+ const page = context.pages()[0] ?? (await context.newPage());
339
+ return {
340
+ context,
341
+ page,
342
+ browser,
343
+ profilePath,
344
+ cleanup,
345
+ };
143
346
  }
144
347
  catch (cause) {
145
- throw new BrowserObservationError(OPERATION, "cleanup_failed", { cause });
348
+ return failBrowserScenarioOperation(() => cleanup.close(), cause);
146
349
  }
147
350
  };
@@ -1,4 +1,4 @@
1
- import { browserScenarioEventSchema, } from "../domain/browserScenarioCapture.js";
1
+ import { browserScenarioEventSchema, } from "../domain/browserScenarioCaptureValues.js";
2
2
  import { PlaywrightScenarioNetwork } from "./network/PlaywrightScenarioNetwork.js";
3
3
  /** Arrival-ordered Playwright event capture with current-step attribution. */
4
4
  export class PlaywrightScenarioEvents {
@@ -1,11 +1,12 @@
1
1
  import {} from "playwright-core";
2
2
  import { BrowserObservationError } from "../domain/browserObservationError.js";
3
3
  import { BrowserScenarioSecrets } from "./BrowserScenarioSecrets.js";
4
- import { closePlaywrightScenarioBrowser, openPlaywrightScenarioBrowser, } from "./PlaywrightScenarioBrowser.js";
4
+ import { failBrowserScenarioOperation, openPlaywrightScenarioBrowser, } from "./PlaywrightScenarioBrowser.js";
5
5
  import { performPlaywrightScenarioAction } from "./PlaywrightScenarioActions.js";
6
6
  import { capturePlaywrightStepArtifacts } from "./PlaywrightScenarioArtifacts.js";
7
7
  import { PlaywrightScenarioEvents } from "./PlaywrightScenarioEvents.js";
8
8
  import { withPlaywrightExecutionBoundary } from "./PlaywrightExecutionBoundary.js";
9
+ import { browserScenarioCaptureData, browserScenarioOperationFailure, } from "./BrowserScenarioPartialObservation.js";
9
10
  const OPERATION = "capture_browser_scenario";
10
11
  const storageSeeds = (blocks, secrets) => {
11
12
  const seeds = {};
@@ -66,10 +67,8 @@ export class PlaywrightScenarioSession {
66
67
  product = "Chromium";
67
68
  version;
68
69
  initialUrl;
69
- closed = false;
70
70
  secrets;
71
71
  eventCapture;
72
- signal;
73
72
  constructor(opened, options) {
74
73
  this.opened = opened;
75
74
  this.mode = options.mode;
@@ -77,7 +76,6 @@ export class PlaywrightScenarioSession {
77
76
  options.mode === "launch" ? "provider-owned" : "external";
78
77
  this.secrets = options.secrets;
79
78
  this.eventCapture = options.eventCapture;
80
- this.signal = options.signal;
81
79
  this.version = opened.browser.version();
82
80
  this.initialUrl = opened.page.url();
83
81
  }
@@ -87,23 +85,28 @@ export class PlaywrightScenarioSession {
87
85
  const secrets = BrowserScenarioSecrets.resolve(scenario, environment);
88
86
  if (secrets === undefined)
89
87
  throw new BrowserObservationError(OPERATION, "secret_unavailable");
90
- const opening = openPlaywrightScenarioBrowser(scenario, environment);
88
+ const startedAt = Date.now();
89
+ const opening = openPlaywrightScenarioBrowser(scenario, environment, {
90
+ signal: options.signal,
91
+ });
91
92
  let opened;
93
+ let events;
92
94
  try {
93
95
  opened = await withPlaywrightExecutionBoundary(() => opening, undefined, options.signal);
94
96
  }
95
97
  catch (cause) {
96
98
  void opening
97
- .then((lateOpened) => closePlaywrightScenarioBrowser(lateOpened, options.signal))
99
+ .then((lateOpened) => lateOpened.cleanup.close(undefined, options.signal))
98
100
  .catch((cause) => {
99
101
  // best-effort cleanup: late-open cleanup must not mask the boundary failure.
100
102
  void cause;
101
103
  });
102
104
  throw cause;
103
105
  }
106
+ let session;
104
107
  try {
105
108
  await withPlaywrightExecutionBoundary(() => initializePage(opened.context, opened.page, scenario, secrets), undefined, options.signal);
106
- const events = new PlaywrightScenarioEvents({
109
+ events = new PlaywrightScenarioEvents({
107
110
  page: opened.page,
108
111
  context: opened.context,
109
112
  ownsContext: scenario.browser.mode === "launch",
@@ -112,12 +115,18 @@ export class PlaywrightScenarioSession {
112
115
  network: scenario.capture.network,
113
116
  ...(options.signal === undefined ? {} : { signal: options.signal }),
114
117
  });
115
- const session = new PlaywrightScenarioSession(opened, {
118
+ session = new PlaywrightScenarioSession(opened, {
116
119
  mode: scenario.browser.mode,
117
120
  secrets,
118
121
  eventCapture: events,
119
- ...(options.signal === undefined ? {} : { signal: options.signal }),
120
122
  });
123
+ }
124
+ catch (cause) {
125
+ return failBrowserScenarioOperation(() => opened.cleanup.close(events === undefined
126
+ ? undefined
127
+ : () => events?.finish() ?? Promise.resolve(), options.signal), cause);
128
+ }
129
+ try {
121
130
  await withPlaywrightExecutionBoundary(() => opened.page.goto(secrets.url(scenario.start_url), {
122
131
  waitUntil: "load",
123
132
  timeout: 0,
@@ -125,8 +134,28 @@ export class PlaywrightScenarioSession {
125
134
  return session;
126
135
  }
127
136
  catch (cause) {
128
- await closePlaywrightScenarioBrowser(opened, options.signal);
129
- throw cause;
137
+ let cleanup;
138
+ let cleanupFailure;
139
+ try {
140
+ cleanup = await session.close();
141
+ }
142
+ catch (failure) {
143
+ cleanup = "incomplete";
144
+ cleanupFailure = { cause: failure };
145
+ }
146
+ throw browserScenarioOperationFailure(cause, {
147
+ kind: "browser-scenario-observation",
148
+ capture: browserScenarioCaptureData({
149
+ session,
150
+ scenario,
151
+ startedAt,
152
+ steps: [],
153
+ cleanup,
154
+ limitations: [
155
+ "Scenario navigation failed before the initial state was captured.",
156
+ ],
157
+ }),
158
+ }, cleanupFailure);
130
159
  }
131
160
  }
132
161
  currentUrl() {
@@ -167,17 +196,7 @@ export class PlaywrightScenarioSession {
167
196
  }), undefined, signal);
168
197
  }
169
198
  async close() {
170
- if (this.closed)
171
- return this.mode === "launch"
172
- ? "terminated-owned-process"
173
- : "disconnected-external";
174
- this.closed = true;
175
- try {
176
- await this.eventCapture.finish();
177
- }
178
- finally {
179
- await closePlaywrightScenarioBrowser(this.opened, this.signal);
180
- }
199
+ await this.opened.cleanup.close(() => this.eventCapture.finish());
181
200
  return this.mode === "launch"
182
201
  ? "terminated-owned-process"
183
202
  : "disconnected-external";
@@ -186,13 +205,3 @@ export class PlaywrightScenarioSession {
186
205
  return this.secrets.redact(error instanceof Error ? error.message : "browser action failed");
187
206
  }
188
207
  }
189
- /** Production Playwright/CDP session factory. */
190
- export class PlaywrightScenarioSessionFactory {
191
- environment;
192
- constructor(environment = process.env) {
193
- this.environment = environment;
194
- }
195
- open(scenario, options = {}) {
196
- return PlaywrightScenarioSession.open(scenario, this.environment, options);
197
- }
198
- }
@@ -106,6 +106,12 @@ class SourceMapEncodingError extends Error {
106
106
  this.name = "SourceMapEncodingError";
107
107
  }
108
108
  }
109
+ class SourceMapRedirectLocationError extends Error {
110
+ constructor(url, location) {
111
+ super(`Source-map redirect from ${JSON.stringify(url)} supplied an invalid Location URL: ${JSON.stringify(location)}.`);
112
+ this.name = "SourceMapRedirectLocationError";
113
+ }
114
+ }
109
115
  const fetchOne = async (request, input, signal, host, budget) => {
110
116
  if (!approvedUrl(request.fetchUrl, input.allowed_origins))
111
117
  return emptySourceMapItem(request, "policy_filtered", "Declared source-map URL is outside the approved exact origins.");
@@ -131,13 +137,25 @@ const fetchOne = async (request, input, signal, host, budget) => {
131
137
  throw cause;
132
138
  if (cause instanceof SourceMapEncodingError)
133
139
  return emptySourceMapItem(request, "invalid", cause.message);
134
- return emptySourceMapItem(request, "fetch_failed", cause instanceof SourceMapSizeLimitError
140
+ return emptySourceMapItem(request, "fetch_failed", cause instanceof SourceMapRedirectLocationError ||
141
+ cause instanceof SourceMapSizeLimitError ||
142
+ cause instanceof SourceMapDeadlineError
135
143
  ? cause.message
136
- : cause instanceof SourceMapDeadlineError
137
- ? cause.message
138
- : "Source-map fetch or validation failed.");
144
+ : "Source-map fetch or validation failed.");
139
145
  }
140
146
  };
147
+ /**
148
+ * Fetch redirect statuses per WHATWG Fetch (redirect status list:
149
+ * 301, 302, 303, 307, 308). Single owner for redirect decisions.
150
+ * 300/304/305/306 carry `Location` without being redirects — following
151
+ * them would replace the observed failure with an unrelated map.
152
+ * See https://fetch.spec.whatwg.org/#redirect-status
153
+ */
154
+ export const isFetchRedirectStatus = (status) => status === 301 ||
155
+ status === 302 ||
156
+ status === 303 ||
157
+ status === 307 ||
158
+ status === 308;
141
159
  const fetchFollowingApprovedRedirects = async (initialUrl, allowedOrigins, signal, host) => {
142
160
  let current = initialUrl;
143
161
  const visited = new Set();
@@ -163,13 +181,21 @@ const fetchFollowingApprovedRedirects = async (initialUrl, allowedOrigins, signa
163
181
  await response.body?.cancel(signal.reason).catch(() => undefined);
164
182
  throw signal.reason;
165
183
  }
166
- if (response.status < 300 || response.status >= 400)
184
+ // `Location` is a redirect target only for Fetch redirect statuses.
185
+ // Other 3xx responses retain their own HTTP failure (strict identity:
186
+ // never replace the observed failure with an unrelated map).
187
+ if (!isFetchRedirectStatus(response.status))
167
188
  return { response, fetchedUrl: current };
168
189
  const location = response.headers.get("location");
169
190
  if (location === null)
170
191
  return { response, fetchedUrl: current };
171
192
  await response.body?.cancel();
172
- current = new URL(location, current).href;
193
+ try {
194
+ current = new URL(location, current).href;
195
+ }
196
+ catch {
197
+ throw new SourceMapRedirectLocationError(current, location);
198
+ }
173
199
  }
174
200
  };
175
201
  const readBoundedText = async (response, budget, maxBytes, signal) => {
@@ -14,9 +14,9 @@ const indexResponses = (events) => {
14
14
  requests: new Map(),
15
15
  };
16
16
  for (const event of events) {
17
- if (event.kind === "request" && event.transaction_id !== undefined)
17
+ if (event.kind === "request")
18
18
  index.requests.set(event.transaction_id, (index.requests.get(event.transaction_id) ?? 0) + 1);
19
- if (event.kind === "response" && event.transaction_id !== undefined)
19
+ if (event.kind === "response")
20
20
  append(index.responses, event.transaction_id, event);
21
21
  if (event.kind === "network-content" && event.phase === "response")
22
22
  append(index.contents, event.source_event_sequence, event);
@@ -25,33 +25,29 @@ const indexResponses = (events) => {
25
25
  };
26
26
  const projectRequest = (request, index) => {
27
27
  const id = request.transaction_id;
28
- const matches = id === undefined ? [] : (index.responses.get(id) ?? []);
28
+ const matches = index.responses.get(id) ?? [];
29
29
  const response = matches.length === 1 ? matches[0] : undefined;
30
30
  const bodies = response === undefined ? [] : (index.contents.get(response.sequence) ?? []);
31
31
  const body = bodies.length === 1 ? bodies[0]?.body : undefined;
32
- const ambiguous = (id !== undefined && index.requests.get(id) !== 1) ||
33
- matches.length > 1 ||
34
- bodies.length > 1;
32
+ const ambiguous = index.requests.get(id) !== 1 || matches.length > 1 || bodies.length > 1;
35
33
  return {
36
34
  source: {
37
35
  kind: "scenario-response",
38
- transaction_id: id ?? null,
36
+ transaction_id: id,
39
37
  request_sequence: request.sequence,
40
38
  response_sequence: ambiguous ? null : (response?.sequence ?? null),
41
39
  status: ambiguous ? null : (response?.status ?? null),
42
40
  },
43
41
  url: request.url.url,
44
- content: projectBody(body, id, ambiguous),
42
+ content: projectBody(body, ambiguous),
45
43
  };
46
44
  };
47
45
  const unavailable = (reason, message) => ({ state: "unavailable", reason, message });
48
- const projectBody = (body, transactionId, ambiguous) => {
46
+ const projectBody = (body, ambiguous) => {
49
47
  if (ambiguous)
50
48
  return unavailable("ambiguous-transaction", "The capture does not identify one request, response, and content record for this transaction.");
51
49
  if (body === undefined)
52
- return unavailable(transactionId === undefined
53
- ? "transaction-identity-unavailable"
54
- : "response-content-not-retained", "No selected, completed script response bytes were retained for this request.");
50
+ return unavailable("response-content-not-retained", "No selected, completed script response bytes were retained for this request.");
55
51
  if (body.state === "unavailable")
56
52
  return unavailable(body.reason, body.message);
57
53
  if (body.state !== "captured")
@@ -1,4 +1,4 @@
1
- import { webPageInspectionSchema } from "../../domain/browserObservation.js";
1
+ import { webPageInspectionSchema } from "../../domain/browserObservationSchemas.js";
2
2
  import { browserScenarioCaptureSchema } from "../../domain/browserScenarioCapture.js";
3
3
  import { parseEvidence } from "../../domain/evidence.js";
4
4
  import { pageScripts } from "./PageScriptCapture.js";