rea-agents 3.2.1 → 4.0.1

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
@@ -4,6 +4,7 @@ import { CdpCaptureCompleteness } from "./CdpCaptureCompleteness.js";
4
4
  import { authorizedMainFrame } from "./CdpAuthorizedMainFrame.js";
5
5
  import { allowedSanitizedUrl, isHttpUrl, numberValue, recordValue, stringValue, } from "./CdpCaptureValues.js";
6
6
  import { mainFrameUrl } from "./CdpCaptureDocuments.js";
7
+ import { isMainFrameNavigation } from "./CdpCaptureEventHelpers.js";
7
8
  /** Observe external user actions without rejecting approved same-origin navigation. */
8
9
  export const observeCdpSession = async (context) => {
9
10
  const allowedOrigins = new Set(context.input.allowed_origins);
@@ -33,7 +34,7 @@ export const observeCdpSession = async (context) => {
33
34
  phase: "browser_observation",
34
35
  completed: 1,
35
36
  total: 2,
36
- message: "Browser observation armed; perform the approved user action now",
37
+ message: "Browser observation armed; perform the requested user action now",
37
38
  });
38
39
  let endReason = await waitForWindow(context.input.observation_ms, capture, context.signal);
39
40
  if (endReason === "window_elapsed")
@@ -96,13 +97,13 @@ class TimelineCapture {
96
97
  return;
97
98
  switch (event.method) {
98
99
  case "Page.frameRequestedNavigation":
99
- this.#navigationRequested(params);
100
+ this.#navigationRequested(event, params);
100
101
  break;
101
102
  case "Page.frameNavigated":
102
- this.#navigationCommitted(params);
103
+ this.#navigationCommitted(event, params);
103
104
  break;
104
105
  case "Page.navigatedWithinDocument":
105
- this.#sameDocument(params);
106
+ this.#sameDocument(event, params);
106
107
  break;
107
108
  case "Network.requestWillBeSent":
108
109
  this.#redirect(params);
@@ -150,8 +151,8 @@ class TimelineCapture {
150
151
  const destination = scopedUrl(rawUrl, this.allowedOrigins);
151
152
  this.finalUrl = destination.scope === "approved" ? destination.url : null;
152
153
  }
153
- #navigationRequested(params) {
154
- if (stringValue(params.frameId) !== this.mainFrameId)
154
+ #navigationRequested(event, params) {
155
+ if (!isMainFrameNavigation(event, this.mainFrameId))
155
156
  return;
156
157
  const reason = safeDetail(params.reason);
157
158
  this.#pendingReload = reason === "reload";
@@ -163,9 +164,9 @@ class TimelineCapture {
163
164
  detail: reason,
164
165
  });
165
166
  }
166
- #navigationCommitted(params) {
167
+ #navigationCommitted(event, params) {
167
168
  const frame = recordValue(params.frame);
168
- if (stringValue(frame?.id) !== this.mainFrameId)
169
+ if (!isMainFrameNavigation(event, this.mainFrameId))
169
170
  return;
170
171
  const rawUrl = stringValue(frame?.url);
171
172
  const destination = scopedUrl(rawUrl, this.allowedOrigins);
@@ -185,8 +186,8 @@ class TimelineCapture {
185
186
  this.end("target_left_scope");
186
187
  }
187
188
  }
188
- #sameDocument(params) {
189
- if (stringValue(params.frameId) !== this.mainFrameId)
189
+ #sameDocument(event, params) {
190
+ if (!isMainFrameNavigation(event, this.mainFrameId))
190
191
  return;
191
192
  const rawUrl = stringValue(params.url);
192
193
  const destination = scopedUrl(rawUrl, this.allowedOrigins);
@@ -206,6 +207,9 @@ class TimelineCapture {
206
207
  }
207
208
  }
208
209
  #redirect(params) {
210
+ const resourceType = stringValue(params.type);
211
+ if (resourceType !== undefined && resourceType !== "Document")
212
+ return;
209
213
  if (stringValue(params.frameId) !== this.mainFrameId ||
210
214
  recordValue(params.redirectResponse) === undefined)
211
215
  return;
@@ -24,7 +24,7 @@ export const capturePage = async (context) => {
24
24
  allowedOrigins,
25
25
  limitations: [
26
26
  "Observation starts when REA attaches; prior network and console activity is unavailable.",
27
- "Raw network headers, bodies, cookies, storage values, console objects, and WebSocket payloads are never retained; separately approved captures retain only redacted text or value-free shapes.",
27
+ "Raw network headers, bodies, cookies, storage values, console objects, and WebSocket payloads are never retained; explicitly requested primitive console text is retained verbatim, while payload captures retain value-free shapes.",
28
28
  "Source maps are reported only as declarative URLs and are not fetched.",
29
29
  "URL-less scripts and console events without an allowed source URL are excluded because their origin cannot be proven.",
30
30
  ],
@@ -20,7 +20,7 @@ const buildScriptDraft = async (script, state) => {
20
20
  let source = state
21
21
  .context.input.include_script_sources
22
22
  ? await captureScriptSource(script, state)
23
- : sourceExcluded("source capture was not approved");
23
+ : sourceExcluded("source capture was not selected");
24
24
  const inventoryScript = {
25
25
  frame_id: state.events.frameForScript(script, state.frameIds),
26
26
  url: script.url,
@@ -148,14 +148,15 @@ const linkParameters = (value) => {
148
148
  const safeDestination = (value, baseUrl, allowedOrigins) => {
149
149
  try {
150
150
  const parsed = new URL(value, baseUrl);
151
+ const sanitized = sanitizeBrowserUrl(parsed.href).url;
151
152
  if (parsed.protocol !== "http:" && parsed.protocol !== "https:")
152
- return { url: null, scope: "unsupported" };
153
+ return { url: sanitized, scope: "unsupported" };
153
154
  if (!allowedOrigins.has(parsed.origin))
154
- return { url: null, scope: "outside_policy" };
155
- return { url: sanitizeBrowserUrl(parsed.href).url, scope: "approved" };
155
+ return { url: sanitized, scope: "outside_policy" };
156
+ return { url: sanitized, scope: "approved" };
156
157
  }
157
158
  catch {
158
- return { url: null, scope: "unsupported" };
159
+ return { url: value, scope: "unsupported" };
159
160
  }
160
161
  };
161
162
  const permissionFeatures = (value) => [
@@ -1,5 +1,6 @@
1
1
  import { createWebScreenshotArtifact } from "../domain/webScreenshot.js";
2
2
  import { BrowserObservationError } from "../domain/errors.js";
3
+ import { isMainFrameNavigation } from "./CdpCaptureEventHelpers.js";
3
4
  import { allowedSanitizedUrl, recordValue, stringValue, } from "./CdpCaptureValues.js";
4
5
  import { mainFrameUrl } from "./CdpCaptureDocuments.js";
5
6
  import { captureFrames } from "./CdpCaptureDocuments.js";
@@ -21,7 +22,13 @@ export const captureCdpScreenshot = async (context) => {
21
22
  const mainFrame = captureFrames(before, origins, 1).items[0];
22
23
  if (authorized === undefined || mainFrame === undefined)
23
24
  throw new BrowserObservationError("inspect_web_page", "target_not_allowed");
24
- const navigation = { changed: false, leftScope: false };
25
+ const initialFrame = recordValue(recordValue(recordValue(before)?.frameTree)?.frame);
26
+ const navigation = {
27
+ changed: false,
28
+ leftScope: false,
29
+ url: beforeUrl,
30
+ loaderId: stringValue(initialFrame?.loaderId),
31
+ };
25
32
  const removeListener = context.connection.onEvent((event) => {
26
33
  if (event.sessionId !== context.sessionId)
27
34
  return;
@@ -67,19 +74,23 @@ export const captureCdpScreenshot = async (context) => {
67
74
  artifact: createWebScreenshotArtifact(bytes),
68
75
  completeness: new CdpCaptureCompleteness().snapshot(),
69
76
  limitations: [
70
- "The screenshot contains the visible viewport and may include sensitive on-screen content; capture requires separate approval.",
77
+ "The screenshot contains the visible viewport, including on-screen content.",
71
78
  "REA does not scroll, evaluate JavaScript, or capture beyond the current viewport.",
72
79
  ],
73
80
  };
74
81
  };
75
82
  const observeScreenshotNavigation = (event, mainFrameId, origins, state) => {
83
+ if (!isMainFrameNavigation(event, mainFrameId))
84
+ return;
76
85
  const params = recordValue(event.params);
77
86
  if (params === undefined)
78
87
  return;
79
88
  const frame = event.method === "Page.frameNavigated" ? recordValue(params.frame) : params;
80
- if ((event.method !== "Page.frameNavigated" &&
81
- event.method !== "Page.navigatedWithinDocument") ||
82
- (stringValue(frame?.id) ?? stringValue(frame?.frameId)) !== mainFrameId)
89
+ if (event.method === "Page.frameNavigated" &&
90
+ state.loaderId !== undefined &&
91
+ state.loaderId !== "" &&
92
+ stringValue(frame?.loaderId) === state.loaderId &&
93
+ stringValue(frame?.url) === state.url)
83
94
  return;
84
95
  state.changed = true;
85
96
  if (allowedSanitizedUrl(frame?.url, origins) === undefined)
@@ -17,24 +17,45 @@ export const openCdpTargetSession = async (discovery, target, operation, signal)
17
17
  }
18
18
  };
19
19
  /** Disable enabled domains, detach browser sessions, and close REA's socket. */
20
- export const closeCdpTargetSession = async (targetSession, enabledDomains) => {
20
+ export const closeCdpTargetSession = async (targetSession, enabledDomains, signal) => {
21
21
  const { connection, sessionId } = targetSession;
22
- for (const domain of enabledDomains)
22
+ for (const [index, domain] of enabledDomains.entries()) {
23
+ if (signal?.aborted === true) {
24
+ await closeCancelledTargetSession(targetSession, enabledDomains.slice(index));
25
+ return;
26
+ }
23
27
  try {
24
- await connection.send(`${domain}.disable`, {}, sessionId);
28
+ await connection.send(`${domain}.disable`, {}, sessionId, signal);
25
29
  }
26
30
  catch {
27
31
  // Cleanup continues to the detach or direct-socket close boundary.
28
32
  }
33
+ }
34
+ if (signal?.aborted === true) {
35
+ await closeCancelledTargetSession(targetSession, []);
36
+ return;
37
+ }
29
38
  if (sessionId !== undefined)
30
39
  try {
31
- await connection.send("Target.detachFromTarget", { sessionId });
40
+ await connection.send("Target.detachFromTarget", { sessionId }, undefined, signal);
32
41
  }
33
42
  catch {
34
43
  // Closing REA's socket is the final non-destructive cleanup boundary.
35
44
  }
36
45
  await connection.close();
37
46
  };
47
+ const closeCancelledTargetSession = async ({ connection, sessionId }, enabledDomains) => {
48
+ const commands = enabledDomains.map((domain) => connection.send(`${domain}.disable`, {}, sessionId));
49
+ if (sessionId !== undefined)
50
+ commands.push(connection.send("Target.detachFromTarget", { sessionId }));
51
+ const settled = Promise.allSettled(commands);
52
+ try {
53
+ await connection.close();
54
+ }
55
+ finally {
56
+ await settled;
57
+ }
58
+ };
38
59
  const attachedSessionId = (value, operation) => {
39
60
  if (typeof value !== "object" ||
40
61
  value === null ||
@@ -3,9 +3,8 @@ import { inferJsonShape } from "../domain/jsonShape.js";
3
3
  import { CdpCaptureCompleteness } from "./CdpCaptureCompleteness.js";
4
4
  import { BrowserObservationError } from "../domain/errors.js";
5
5
  import { allowedSanitizedUrl, delayWithCancellation, numberValue, recordValue, recordsValue, stringValue, } from "./CdpCaptureValues.js";
6
- import { captureFrames, mainFrameUrl } from "./CdpCaptureDocuments.js";
6
+ import { captureFrames, mainFrameUrl, walkFrameTrees, } from "./CdpCaptureDocuments.js";
7
7
  import { optionalCdpCommand } from "./CdpOptionalCommand.js";
8
- import { redactSensitiveText } from "./SensitiveTextCapture.js";
9
8
  /** Discover WebMCP registrations without evaluating or invoking page code. */
10
9
  export const discoverWebMcp = async (context) => {
11
10
  const origins = new Set(context.input.allowed_origins);
@@ -20,16 +19,16 @@ export const discoverWebMcp = async (context) => {
20
19
  if (allowedSanitizedUrl(initialUrl, origins) === undefined)
21
20
  throw new BrowserObservationError("inspect_web_page", "target_not_allowed");
22
21
  const frames = captureFrames(frameTree, origins, undefined, completeness).items;
23
- const frameUrls = new Map(frames.map((frame) => [
24
- frame.frame_id,
25
- {
26
- url: frame.url,
27
- origin: frame.origin,
28
- parentFrameId: frame.parent_frame_id,
29
- },
30
- ]));
22
+ const frameUrls = initialFrameScope(frameTree, frames, completeness);
31
23
  const tools = new Map();
32
- const frameScope = { origins, frames: frameUrls, tools, completeness };
24
+ const frameScope = {
25
+ origins,
26
+ frames: frameUrls,
27
+ tools,
28
+ completeness,
29
+ transientFrames: new Set(),
30
+ resolvedTransientFrames: new Set(),
31
+ };
33
32
  const removeListener = context.connection.onEvent((event) => {
34
33
  if (event.sessionId !== context.sessionId)
35
34
  return;
@@ -41,6 +40,8 @@ export const discoverWebMcp = async (context) => {
41
40
  frames: frameUrls,
42
41
  tools,
43
42
  completeness,
43
+ transientFrames: frameScope.transientFrames,
44
+ resolvedTransientFrames: frameScope.resolvedTransientFrames,
44
45
  });
45
46
  });
46
47
  await context.progress?.report({
@@ -59,6 +60,8 @@ export const discoverWebMcp = async (context) => {
59
60
  // CDP sends the enable response before the required toolsAdded replay.
60
61
  await delayWithCancellation(context.input.observation_ms, "discover_webmcp_tools", context.signal);
61
62
  await assertStableAuthorizedFrame(context, initialUrl, origins);
63
+ if (frameScope.transientFrames.size > 0)
64
+ completeness.attachLimited("webmcp_tools");
62
65
  return buildWebMcpResult({
63
66
  context,
64
67
  frameTree,
@@ -79,6 +82,27 @@ export const discoverWebMcp = async (context) => {
79
82
  });
80
83
  }
81
84
  };
85
+ const initialFrameScope = (frameTree, frames, completeness) => {
86
+ const scoped = new Map(frames.map((frame) => [
87
+ frame.frame_id,
88
+ {
89
+ url: frame.url,
90
+ origin: frame.origin,
91
+ parentFrameId: frame.parent_frame_id,
92
+ },
93
+ ]));
94
+ const root = recordValue(recordValue(frameTree)?.frameTree);
95
+ if (root === undefined)
96
+ return scoped;
97
+ for (const tree of walkFrameTrees(root, () => completeness.exclude("webmcp_tools", "invalid_protocol_value"))) {
98
+ const frame = recordValue(tree.frame);
99
+ const frameId = stringValue(frame?.id);
100
+ const prior = frameId === undefined ? undefined : scoped.get(frameId);
101
+ if (frameId !== undefined && prior !== undefined)
102
+ scoped.set(frameId, { ...prior, loaderId: stringValue(frame?.loaderId) });
103
+ }
104
+ return scoped;
105
+ };
82
106
  const ingestFrameScopeEvent = (event, state) => {
83
107
  const params = recordValue(event.params);
84
108
  if (params === undefined)
@@ -87,9 +111,9 @@ const ingestFrameScopeEvent = (event, state) => {
87
111
  case "Page.frameDetached":
88
112
  return handleFrameDetached(params, state);
89
113
  case "Page.frameNavigated":
90
- return handleFrameUpdate(recordValue(params.frame), state);
114
+ return handleFrameUpdate(recordValue(params.frame), state, true);
91
115
  case "Page.navigatedWithinDocument":
92
- return handleFrameUpdate(params, state);
116
+ return handleFrameUpdate(params, state, false);
93
117
  default:
94
118
  return false;
95
119
  }
@@ -101,30 +125,72 @@ const handleFrameDetached = (params, state) => {
101
125
  return true;
102
126
  }
103
127
  removeFrame(frameId, state.frames, state.tools);
128
+ state.transientFrames.delete(frameId);
129
+ state.resolvedTransientFrames.delete(frameId);
104
130
  return true;
105
131
  };
106
- const handleFrameUpdate = (frame, state) => {
132
+ const handleFrameUpdate = (frame, state, documentCommitted) => {
133
+ if (frame === undefined) {
134
+ state.completeness.exclude("webmcp_tools", "invalid_protocol_value");
135
+ return true;
136
+ }
107
137
  const frameId = stringValue(frame?.id) ?? stringValue(frame?.frameId);
108
138
  if (frameId === undefined) {
109
139
  state.completeness.exclude("webmcp_tools", "invalid_protocol_value");
110
140
  return true;
111
141
  }
142
+ const rawUrl = stringValue(frame?.url);
143
+ // Chromium can briefly commit an inherited, empty document while replacing
144
+ // a subframe. That intermediate URL says nothing about the frame's eventual
145
+ // scope or its registered tools; wait for the next committed URL (or the
146
+ // authoritative frame-tree re-probe at the end of discovery).
147
+ if (isTransientFrameUrl(rawUrl)) {
148
+ if (documentCommitted) {
149
+ removeFrameTools(frameId, state.tools);
150
+ state.transientFrames.add(frameId);
151
+ state.resolvedTransientFrames.delete(frameId);
152
+ }
153
+ return true;
154
+ }
155
+ updateFrameScope(frame, frameId, state, documentCommitted);
156
+ return true;
157
+ };
158
+ const updateFrameScope = (frame, frameId, state, documentCommitted) => {
112
159
  const url = allowedSanitizedUrl(frame?.url, state.origins);
113
160
  if (url === undefined || url.origin === null) {
114
- removeFrame(frameId, state.frames, state.tools);
161
+ removeFrameTools(frameId, state.tools);
162
+ state.frames.delete(frameId);
115
163
  state.completeness.exclude("webmcp_tools", "out_of_target_scope");
116
- return true;
164
+ return;
117
165
  }
166
+ const previous = state.frames.get(frameId);
167
+ const loaderId = stringValue(frame?.loaderId);
168
+ if (hasNewDocument(documentCommitted, previous, url.url, loaderId))
169
+ removeFrameTools(frameId, state.tools);
170
+ if (documentCommitted && state.transientFrames.has(frameId))
171
+ state.resolvedTransientFrames.add(frameId);
118
172
  state.frames.set(frameId, {
119
173
  url: url.url,
120
174
  origin: url.origin,
175
+ ...(loaderId === undefined ? {} : { loaderId }),
121
176
  parentFrameId: (stringValue(frame?.parentId) ??
122
177
  state.frames.get(frameId)?.parentFrameId ??
123
178
  "") ||
124
179
  null,
125
180
  });
126
- return true;
127
181
  };
182
+ const hasNewDocument = (documentCommitted, previous, url, loaderId) => documentCommitted &&
183
+ previous !== undefined &&
184
+ (previous.url !== url ||
185
+ (loaderId !== undefined &&
186
+ previous.loaderId !== undefined &&
187
+ previous.loaderId !== loaderId));
188
+ const removeFrameTools = (frameId, tools) => {
189
+ for (const [key, tool] of tools)
190
+ if (tool.frame_id === frameId)
191
+ tools.delete(key);
192
+ };
193
+ const isTransientFrameUrl = (url) => url === "" || url === "about:blank" || url === "about:srcdoc";
128
194
  const removeFrame = (frameId, frames, tools) => {
129
195
  const pending = [frameId];
130
196
  const removed = new Set();
@@ -151,7 +217,7 @@ const assertStableAuthorizedFrame = async (context, initialUrl, origins) => {
151
217
  throw new BrowserObservationError("inspect_web_page", "target_changed");
152
218
  };
153
219
  const ingestWebMcpEvent = (options) => {
154
- const { event, input, frames, tools, completeness } = options;
220
+ const { event, input, frames, tools, completeness, transientFrames, resolvedTransientFrames, } = options;
155
221
  const params = recordValue(event.params);
156
222
  if (params === undefined)
157
223
  return;
@@ -170,6 +236,13 @@ const ingestWebMcpEvent = (options) => {
170
236
  if (event.method !== "WebMCP.toolsAdded")
171
237
  return;
172
238
  for (const declared of recordsValue(params.tools)) {
239
+ const frameId = stringValue(declared.frameId);
240
+ if (frameId !== undefined && transientFrames.has(frameId)) {
241
+ if (!resolvedTransientFrames.has(frameId))
242
+ continue;
243
+ transientFrames.delete(frameId);
244
+ resolvedTransientFrames.delete(frameId);
245
+ }
173
246
  const normalized = normalizeTool(declared, input, frames, completeness);
174
247
  if (normalized === undefined)
175
248
  continue;
@@ -187,11 +260,11 @@ const normalizeTool = (value, input, frames, completeness) => {
187
260
  completeness.exclude("webmcp_tools", "out_of_target_scope");
188
261
  return undefined;
189
262
  }
190
- const description = redactSensitiveText(stringValue(value.description) ?? "");
263
+ const description = stringValue(value.description) ?? "";
191
264
  const annotations = recordValue(value.annotations);
192
265
  return {
193
266
  tool_key: toolKey(frame.url, name),
194
- name: redactSensitiveText(name),
267
+ name,
195
268
  description,
196
269
  frame_id: frameId,
197
270
  frame_url: frame.url,
@@ -1,3 +1,4 @@
1
+ import { pathToFileURL } from "node:url";
1
2
  import { browserOriginSchema, sanitizeBrowserUrl, } from "../domain/browserObservation.js";
2
3
  import { authorizedElectronFile } from "./ElectronFileScope.js";
3
4
  /** Resolve a protocol location exposed by the explicitly selected Inspector endpoint. */
@@ -34,5 +35,30 @@ export const authorizeRuntimeLocation = async (value) => {
34
35
  },
35
36
  };
36
37
  };
37
- /** Authorize a target whose Node Inspector URL omits its main entry path. */
38
- export const authorizeRuntimeTargetLocation = async (value) => authorizeRuntimeLocation(value);
38
+ /** Interpret Node's lossy discovery metadata separately from scriptParsed URLs. */
39
+ export const authorizeRuntimeTargetLocation = async (value, context) => {
40
+ if (context.type !== "node" ||
41
+ !/^node\.js\/v/iu.test(context.product) ||
42
+ !value.startsWith("file://"))
43
+ return authorizeRuntimeLocation(value);
44
+ const reportedPath = value.slice("file://".length);
45
+ if (!reportedPath.startsWith("/") && !/^[a-z]:[/\\_]/iu.test(reportedPath))
46
+ return authorizeRuntimeLocation(value);
47
+ // Node concatenates the pathname, then replaces quotes and backslashes with
48
+ // underscores. A remaining underscore cannot prove which pathname was used.
49
+ if (process.platform !== "win32" && !/[_"\\]/u.test(reportedPath)) {
50
+ if (reportedPath.startsWith("/")) {
51
+ const decision = await authorizeRuntimeLocation(pathToFileURL(reportedPath).href);
52
+ if (decision.allowed)
53
+ return decision;
54
+ }
55
+ }
56
+ return {
57
+ allowed: true,
58
+ location: {
59
+ kind: "unresolved",
60
+ reported_url: value,
61
+ reason: "unverifiable-file-location",
62
+ },
63
+ };
64
+ };
@@ -1,4 +1,3 @@
1
- import { sanitizeBrowserUrl } from "../domain/browserObservation.js";
2
1
  import { browserScenarioCaptureSchema, classifyBrowserScenarioCompleteness, browserScenarioStepSchema, browserStepArtifactsSchema, } from "../domain/browserScenarioCapture.js";
3
2
  import { AnalysisError, BrowserObservationError, ProviderAdapterError, } from "../domain/errors.js";
4
3
  import { err, ok } from "../domain/result.js";
@@ -53,8 +52,8 @@ const createStep = (input) => browserScenarioStepSchema.parse({
53
52
  action: input.action,
54
53
  status: input.status,
55
54
  elapsed_ms: input.elapsedMs,
56
- before_url: sanitizeBrowserUrl(input.beforeUrl),
57
- after_url: sanitizeBrowserUrl(input.afterUrl),
55
+ before_url: input.beforeUrl,
56
+ after_url: input.afterUrl,
58
57
  error: input.error,
59
58
  event_sequence_start: input.eventStart,
60
59
  event_sequence_end: input.eventEnd,
@@ -70,8 +69,8 @@ const initialStep = async (input) => {
70
69
  action: "goto_start",
71
70
  status: "completed",
72
71
  elapsedMs,
73
- beforeUrl: session.initialUrl,
74
- afterUrl: session.currentUrl(),
72
+ beforeUrl: session.sanitizeUrl(session.initialUrl),
73
+ afterUrl: session.sanitizeUrl(session.currentUrl()),
75
74
  error: null,
76
75
  eventStart: 1,
77
76
  eventEnd: session.lastEventSequence(),
@@ -80,7 +79,7 @@ const initialStep = async (input) => {
80
79
  };
81
80
  const executeStep = async (input) => {
82
81
  const { session, scenario, action, stepIndex, priorFailure, signal } = input;
83
- const beforeUrl = session.currentUrl();
82
+ const beforeUrl = session.sanitizeUrl(session.currentUrl());
84
83
  const eventStart = session.nextEventSequence();
85
84
  const requested = requestedForStep(scenario, stepIndex);
86
85
  if (priorFailure)
@@ -128,7 +127,7 @@ const executeStep = async (input) => {
128
127
  ...outcome,
129
128
  elapsedMs: Date.now() - actionStartedAt,
130
129
  beforeUrl,
131
- afterUrl: session.currentUrl(),
130
+ afterUrl: session.sanitizeUrl(session.currentUrl()),
132
131
  eventStart,
133
132
  eventEnd: session.lastEventSequence(),
134
133
  artifacts,
@@ -139,6 +138,8 @@ const globalCompleteness = (scenario, session, steps) => {
139
138
  const truncated = steps.flatMap(({ completeness }) => completeness.truncated_sections);
140
139
  if (session.mode === "connect")
141
140
  missing.push("events");
141
+ if ((session.eventLimitations?.().length ?? 0) > 0)
142
+ missing.push("events");
142
143
  return classifyBrowserScenarioCompleteness(missing, truncated);
143
144
  };
144
145
  const runScenario = async (factory, scenario, options) => {
@@ -184,7 +185,6 @@ const runScenario = async (factory, scenario, options) => {
184
185
  },
185
186
  scenario: {
186
187
  start_origin: new URL(scenario.start_url.url).origin,
187
- allowed_origins: scenario.allowed_origins,
188
188
  action_count: scenario.actions.length,
189
189
  secret_references: scenario.secrets.map(({ secret_id: id }) => id).sort(),
190
190
  },
@@ -196,6 +196,7 @@ const runScenario = async (factory, scenario, options) => {
196
196
  "Event sequence records provider receipt order; simultaneous browser causality is not inferred.",
197
197
  "Response bodies are not retained.",
198
198
  "Storage values are hashed only after declared-secret redaction.",
199
+ ...(session.eventLimitations?.() ?? []),
199
200
  ...(session.mode === "connect"
200
201
  ? [
201
202
  "CDP attachment cannot recover pre-attach events or guarantee launch-time context options.",
@@ -1,6 +1,5 @@
1
1
  import { z } from "zod";
2
2
  import { BrowserObservationError } from "../domain/errors.js";
3
- import { redactSensitiveText } from "./SensitiveTextCapture.js";
4
3
  const OPERATION = "capture_electron_scenario";
5
4
  const hookEventSchema = z.strictObject({
6
5
  sequence: z.number().int().min(1),
@@ -123,7 +122,7 @@ export const runElectronActions = async (application, input, options) => {
123
122
  target: selectedWindow === undefined ? null : `window:${String(windowIndex)}`,
124
123
  status: options.signal?.aborted ? "cancelled" : "failed",
125
124
  elapsed_ms: Date.now() - actionStartedAt,
126
- error: safeActionErrorMessage(cause, action),
125
+ error: safeActionErrorMessage(cause),
127
126
  });
128
127
  break;
129
128
  }
@@ -298,12 +297,6 @@ export const runWithExecutionLimits = async (operation, signal, deadline) => {
298
297
  signal?.removeEventListener("abort", abortListener);
299
298
  }
300
299
  };
301
- const safeActionErrorMessage = (cause, action) => {
302
- let message = cause instanceof Error ? cause.message : "Electron action failed";
303
- const inputValues = Object.values(action)
304
- .filter((value) => typeof value === "string" && value.length > 0)
305
- .sort((left, right) => right.length - left.length);
306
- for (const value of inputValues)
307
- message = message.split(value).join("<redacted-input>");
308
- return redactSensitiveText(message);
300
+ const safeActionErrorMessage = (cause) => {
301
+ return cause instanceof Error ? cause.message : "Electron action failed";
309
302
  };
@@ -1,10 +1,10 @@
1
1
  import { realpath } from "node:fs/promises";
2
+ import { dirname } from "node:path";
2
3
  import { randomUUID } from "node:crypto";
3
4
  import { fileURLToPath } from "node:url";
4
5
  import { _electron as electron } from "playwright-core";
5
6
  import { electronActiveObservationResultSchema, } from "../domain/electronActiveObservation.js";
6
7
  import { AnalysisError, BrowserObservationError, ProviderAdapterError, } from "../domain/errors.js";
7
- import { isPathContained } from "../domain/permissionPolicy.js";
8
8
  import { err, ok } from "../domain/result.js";
9
9
  import { cleanupOwnedProcessGroup, cleanupWindowsProcessTree, observeOwnedProcessLineage, selectCapturedProcessGroupIds, verifyNoTokenOwnedProcesses, } from "../process/ProcessOwnership.js";
10
10
  import { runElectronActions, readApplicationState, runWithExecutionLimits, } from "./PlaywrightElectronActiveActions.js";
@@ -243,13 +243,13 @@ const createResult = (paths, input, actions, state) => {
243
243
  });
244
244
  };
245
245
  const canonicalPaths = async (input) => {
246
- const [executable, application, root] = await Promise.all([
246
+ const [executable, application] = await Promise.all([
247
247
  realpath(input.executable_path),
248
248
  realpath(input.application_path),
249
- realpath(input.application_root),
250
249
  ]);
251
- if (!isPathContained(root, application))
252
- throw new BrowserObservationError(OPERATION, "target_not_allowed");
250
+ const root = input.application_root === undefined
251
+ ? dirname(application)
252
+ : await realpath(input.application_root);
253
253
  return { executable, application, root };
254
254
  };
255
255
  const safeElectronEnvironment = (runId) => Object.fromEntries([
@@ -5,7 +5,7 @@ const resolveLocator = (page, locator) => {
5
5
  case "role":
6
6
  return page.getByRole(locator.role, {
7
7
  name: locator.name,
8
- exact: locator.exact,
8
+ exact: true,
9
9
  });
10
10
  case "css":
11
11
  return page.locator(locator.selector);