rea-agents 3.2.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (434) hide show
  1. package/README.md +183 -332
  2. package/bridge/ghidra/ReaGhidraBridge.java +561 -74
  3. package/bridge/hopper_bridge.py +70 -27
  4. package/bridge/native/ReaNativeUI.swift +157 -0
  5. package/dist/application/AnalysisContextQueries.js +19 -5
  6. package/dist/application/AnalysisSnapshotCache.js +30 -11
  7. package/dist/application/AppleAssetCatalogAnalysis.js +171 -0
  8. package/dist/application/ArtifactExtractionDestination.js +0 -12
  9. package/dist/application/ArtifactGraphConstruction.js +44 -11
  10. package/dist/application/ArtifactInventory/classify.js +7 -15
  11. package/dist/application/ArtifactInventory/hash.js +4 -2
  12. package/dist/application/ArtifactInventory/policy.js +2 -17
  13. package/dist/application/ArtifactInventory/reader.js +3 -3
  14. package/dist/application/ArtifactInventory/scanCanonical.js +2 -2
  15. package/dist/application/ArtifactInventory/scanReader.js +12 -4
  16. package/dist/application/ArtifactInventory/types.js +0 -3
  17. package/dist/application/BinarySession.js +28 -43
  18. package/dist/application/BinarySessionExecution.js +37 -1
  19. package/dist/application/BinaryTargetResolver.js +50 -4
  20. package/dist/application/BrowserEvidence.js +36 -7
  21. package/dist/application/BrowserObservationService.js +17 -44
  22. package/dist/application/BrowserScenarioCaptureService.js +2 -35
  23. package/dist/application/BrowserScenarioEvidence.js +13 -9
  24. package/dist/application/CapabilityClientRequirements.js +2 -11
  25. package/dist/application/CapabilityInventory.js +21 -35
  26. package/dist/application/ClientConfigurationDocument.js +84 -7
  27. package/dist/application/ClientRegistrationIdentity.js +32 -0
  28. package/dist/application/ClientRegistrationStatus.js +59 -6
  29. package/dist/application/DirectAnalysis.js +37 -58
  30. package/dist/application/DirectAnalysisStatus.js +4 -4
  31. package/dist/application/Doctor.js +89 -80
  32. package/dist/application/DoctorDiagnostics.js +2 -26
  33. package/dist/application/DoctorScope.js +8 -14
  34. package/dist/application/ElectronActiveEvidence.js +10 -27
  35. package/dist/application/ElectronActiveObservationService.js +9 -36
  36. package/dist/application/ElectronBoundaryAnalysis.js +2 -0
  37. package/dist/application/ElectronBoundaryGraphNative.js +1 -1
  38. package/dist/application/ElectronEvidence.js +8 -3
  39. package/dist/application/ElectronObservationService.js +9 -25
  40. package/dist/application/EnhancedLiteralTracing.js +4 -8
  41. package/dist/application/EnhancedTools.js +15 -35
  42. package/dist/application/FilesystemSnapshot.js +7 -8
  43. package/dist/application/JavaScriptApplicationEvidenceGraph.js +2 -1
  44. package/dist/application/JavaScriptApplicationWorkflowService.js +31 -7
  45. package/dist/application/JavaScriptArtifactAnalysis.js +6 -4
  46. package/dist/application/JavaScriptArtifactFiles.js +5 -0
  47. package/dist/application/JavaScriptArtifactPathResolution.js +179 -47
  48. package/dist/application/JavaScriptRuntimeObservationEvidence.js +6 -3
  49. package/dist/application/JavaScriptRuntimeObservationService.js +9 -25
  50. package/dist/application/JavaScriptRuntimeReconciliationService.js +45 -4
  51. package/dist/application/JavaScriptSemanticGraphAsyncProjection.js +11 -0
  52. package/dist/application/JavaScriptSemanticGraphChildProcessProjection.js +11 -0
  53. package/dist/application/JavaScriptSemanticGraphDataProjection.js +11 -0
  54. package/dist/application/JavaScriptSemanticGraphFlowProjection.js +14 -5
  55. package/dist/application/JsonFiles.js +1 -1
  56. package/dist/application/LazyAnalysisProvider.js +27 -6
  57. package/dist/application/ManagedMemberComparisonService.js +19 -6
  58. package/dist/application/NativeApiInspection.js +2 -0
  59. package/dist/application/NativeCallRoutes.js +72 -0
  60. package/dist/application/NativeDispatchMetadataInspection.js +33 -0
  61. package/dist/application/NativeUiActionTrace.js +73 -49
  62. package/dist/application/NativeValueTrace.js +320 -0
  63. package/dist/application/ProcessCaptureCapability.js +32 -5
  64. package/dist/application/ProcessCaptureEnvironment.js +9 -26
  65. package/dist/application/ProcessCaptureError.js +1 -5
  66. package/dist/application/ProcessCaptureJournal.js +3 -40
  67. package/dist/application/ProcessCaptureLifecycle.js +102 -111
  68. package/dist/application/ProcessCli.js +18 -25
  69. package/dist/application/ProcessEvidence.js +5 -7
  70. package/dist/application/ProcessFilesystemEffects.js +36 -0
  71. package/dist/application/ProcessHarness.js +41 -120
  72. package/dist/application/ProcessNormalization.js +2 -17
  73. package/dist/application/ProcessScenarioRuntimeValidation.js +76 -0
  74. package/dist/application/ReferenceSourceImport.js +3 -4
  75. package/dist/application/Setup.js +236 -84
  76. package/dist/application/SetupClientConfiguration.js +14 -9
  77. package/dist/application/SetupPlan.js +138 -86
  78. package/dist/application/SetupSkill.js +0 -1
  79. package/dist/application/SupportedClients.js +102 -21
  80. package/dist/application/Uninstall.js +31 -20
  81. package/dist/application/Update.js +93 -0
  82. package/dist/application/UpdateMaintenance.js +108 -0
  83. package/dist/application/UpdateRuntime.js +126 -0
  84. package/dist/application/runtime.js +13 -2
  85. package/dist/artifacts/ArtifactPaths.js +6 -8
  86. package/dist/artifacts/ArtifactProvider.js +94 -41
  87. package/dist/artifacts/AsarArtifactReader.js +19 -4
  88. package/dist/artifacts/KeyedArchiveReader.js +110 -0
  89. package/dist/artifacts/MachOSliceArtifactReader.js +53 -5
  90. package/dist/artifacts/ZipArtifactReader.js +18 -1
  91. package/dist/browser/BrowserScenarioSecrets.js +28 -1
  92. package/dist/browser/CdpBrowserProvider.js +36 -15
  93. package/dist/browser/CdpCaptureDocuments.js +22 -8
  94. package/dist/browser/CdpCaptureEventHandlers.js +14 -5
  95. package/dist/browser/CdpCaptureEventHelpers.js +13 -0
  96. package/dist/browser/CdpCaptureEvents.js +10 -1
  97. package/dist/browser/CdpElectronInspection.js +5 -10
  98. package/dist/browser/CdpElectronProvider.js +1 -5
  99. package/dist/browser/CdpElectronScripts.js +1 -1
  100. package/dist/browser/CdpEndpoint.js +3 -2
  101. package/dist/browser/CdpObservationSession.js +14 -10
  102. package/dist/browser/CdpPageCapture.js +1 -1
  103. package/dist/browser/CdpPageCaptureScripts.js +1 -1
  104. package/dist/browser/CdpSafeMetadata.js +5 -4
  105. package/dist/browser/CdpScreenshot.js +16 -5
  106. package/dist/browser/CdpTargetSession.js +25 -4
  107. package/dist/browser/CdpWebMcpDiscovery.js +93 -20
  108. package/dist/browser/JavaScriptRuntimeScope.js +28 -2
  109. package/dist/browser/PlaywrightBrowserScenarioProvider.js +9 -8
  110. package/dist/browser/PlaywrightElectronActiveActions.js +3 -10
  111. package/dist/browser/PlaywrightElectronActiveProvider.js +5 -5
  112. package/dist/browser/PlaywrightScenarioActions.js +1 -1
  113. package/dist/browser/PlaywrightScenarioArtifacts.js +13 -25
  114. package/dist/browser/PlaywrightScenarioBrowser.js +28 -25
  115. package/dist/browser/PlaywrightScenarioEvents.js +82 -93
  116. package/dist/browser/PlaywrightScenarioSession.js +27 -123
  117. package/dist/browser/PngVisualDiff.js +22 -3
  118. package/dist/browser/V8InspectorCaptureProjection.js +7 -1
  119. package/dist/browser/V8InspectorProvider.js +60 -7
  120. package/dist/browser/WebSourceMapFetcher.js +99 -53
  121. package/dist/cli/artifactCommands.js +56 -12
  122. package/dist/cli/coreAnalysisCommands.js +110 -0
  123. package/dist/cli/managedCommands.js +1 -31
  124. package/dist/cli/setupCommands.js +16 -14
  125. package/dist/cli/utilityCommands.js +61 -4
  126. package/dist/cli.js +5 -7
  127. package/dist/cliApplicationCommands.js +0 -83
  128. package/dist/cliBrowserAdvancedCommands.js +7 -11
  129. package/dist/cliBrowserCommands.js +15 -23
  130. package/dist/cliBrowserContext.js +3 -24
  131. package/dist/cliBrowserScenarioCommands.js +2 -10
  132. package/dist/cliCommandNames.js +82 -7
  133. package/dist/cliElectronCommands.js +10 -36
  134. package/dist/cliJavaScriptRuntimeCommands.js +6 -30
  135. package/dist/cliJsonInput.js +4 -2
  136. package/dist/cliLogging.js +16 -7
  137. package/dist/cliObservationOptions.js +1 -1
  138. package/dist/cliOutput.js +2 -4
  139. package/dist/cliProcessCommands.js +6 -33
  140. package/dist/cliSetup.js +90 -160
  141. package/dist/config/environment.js +2 -78
  142. package/dist/config/parseConfig.js +18 -109
  143. package/dist/config/parsers.js +0 -23
  144. package/dist/contracts/applicationToolContracts.js +1 -118
  145. package/dist/contracts/artifactToolContracts.js +11 -19
  146. package/dist/contracts/browserScenarioToolContracts.js +1 -5
  147. package/dist/contracts/browserToolContracts.js +9 -16
  148. package/dist/contracts/electronToolContracts.js +5 -6
  149. package/dist/contracts/enhancedInputs.js +3 -2
  150. package/dist/contracts/errorSchemas.js +16 -40
  151. package/dist/contracts/functionWorkflowToolContracts.js +2 -2
  152. package/dist/contracts/javascriptApplicationWorkflowExamples.js +2 -2
  153. package/dist/contracts/javascriptRuntimeObservationToolContracts.js +4 -4
  154. package/dist/contracts/javascriptRuntimeReconciliationExample.js +1 -1
  155. package/dist/contracts/managedToolContracts.js +7 -4
  156. package/dist/contracts/managedWorkflowExamples.js +0 -22
  157. package/dist/contracts/managedWorkflowToolContracts.js +16 -31
  158. package/dist/contracts/nativeToolContracts.js +9 -0
  159. package/dist/contracts/promptContracts.js +6 -6
  160. package/dist/contracts/sessionToolSchemas.js +3 -3
  161. package/dist/contracts/toolContractExamples.js +4 -3
  162. package/dist/contracts/toolContracts.js +18 -7
  163. package/dist/contracts/toolEffects.js +34 -21
  164. package/dist/contracts/toolOutputSchemaGroups.js +18 -5
  165. package/dist/contracts/toolOutputSchemaPrimitives.js +9 -6
  166. package/dist/contracts/toolSchemaMetadata.js +5 -8
  167. package/dist/doctorRuntime.js +0 -41
  168. package/dist/domain/analysisErrorPresentation.js +4 -28
  169. package/dist/domain/analysisErrorProjection.js +33 -50
  170. package/dist/domain/analysisProfile.js +1 -1
  171. package/dist/domain/analysisSnapshot.js +77 -3
  172. package/dist/domain/androidApplication.js +5 -4
  173. package/dist/domain/appleApplication.js +5 -4
  174. package/dist/domain/appleAssetCatalog.js +127 -0
  175. package/dist/domain/artifactComparison.js +7 -11
  176. package/dist/domain/artifactGraph.js +8 -6
  177. package/dist/domain/artifactInspection.js +13 -12
  178. package/dist/domain/binaryTarget.js +23 -9
  179. package/dist/domain/browserObservation.js +43 -24
  180. package/dist/domain/browserObservationSchemas.js +2 -1
  181. package/dist/domain/browserScenario.js +7 -107
  182. package/dist/domain/browserScenarioCapture.js +0 -1
  183. package/dist/domain/browserScenarioCaptureValues.js +5 -4
  184. package/dist/domain/browserScenarioDiff.js +1 -3
  185. package/dist/domain/browserScenarioValues.js +16 -107
  186. package/dist/domain/bundleComparison.js +18 -17
  187. package/dist/domain/callPathSchemas.js +17 -7
  188. package/dist/domain/changedBehavior.js +2 -3
  189. package/dist/domain/comparisonSemantics.js +19 -0
  190. package/dist/domain/completionLedgerGeneration.js +3 -2
  191. package/dist/domain/conformancePackage.js +2 -1
  192. package/dist/domain/conformanceTrustGate.js +3 -5
  193. package/dist/domain/customProtocolCapture.js +2 -2
  194. package/dist/domain/digests.js +30 -0
  195. package/dist/domain/dosMz.js +83 -0
  196. package/dist/domain/electronActiveObservation.js +7 -5
  197. package/dist/domain/electronObservation.js +3 -2
  198. package/dist/domain/electronStaticAnalysisNative.js +15 -6
  199. package/dist/domain/emptyArraySchema.js +3 -0
  200. package/dist/domain/errors.js +10 -28
  201. package/dist/domain/evidence.js +5 -3
  202. package/dist/domain/evidenceCompletionLedger.js +3 -2
  203. package/dist/domain/functionComparisonNormalization.js +24 -18
  204. package/dist/domain/functionComparisonResults.js +3 -7
  205. package/dist/domain/functionComparisonSchemas.js +3 -2
  206. package/dist/domain/hopperValues.js +108 -8
  207. package/dist/domain/javascriptApplicationAnalysis.js +4 -7
  208. package/dist/domain/javascriptApplicationEvidenceSchemas.js +4 -3
  209. package/dist/domain/javascriptApplicationGraphSchemas.js +8 -7
  210. package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +9 -7
  211. package/dist/domain/javascriptApplicationVersionItems.js +12 -18
  212. package/dist/domain/javascriptAstValues.js +4 -0
  213. package/dist/domain/javascriptExportShapeComparison.js +1 -6
  214. package/dist/domain/javascriptExportShapeComparisonSchemas.js +6 -10
  215. package/dist/domain/javascriptExportShapeVariants.js +15 -2
  216. package/dist/domain/javascriptFeatureTraceSchemas.js +8 -7
  217. package/dist/domain/javascriptRuntimeObservation.js +14 -2
  218. package/dist/domain/javascriptRuntimeReconciliationMatching.js +8 -0
  219. package/dist/domain/javascriptRuntimeReconciliationParsing.js +4 -2
  220. package/dist/domain/javascriptRuntimeReconciliationResult.js +6 -4
  221. package/dist/domain/javascriptRuntimeReconciliationRuntime.js +15 -4
  222. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +19 -18
  223. package/dist/domain/javascriptRuntimeStaticCandidates.js +18 -6
  224. package/dist/domain/javascriptSemanticAnalysis.js +57 -19
  225. package/dist/domain/javascriptSemanticAsyncEffects.js +39 -40
  226. package/dist/domain/javascriptSemanticCalls.js +46 -27
  227. package/dist/domain/javascriptSemanticChildProcesses.js +43 -50
  228. package/dist/domain/javascriptSemanticDataEffectHelpers.js +91 -18
  229. package/dist/domain/javascriptSemanticDataEffects.js +22 -10
  230. package/dist/domain/javascriptSemanticGraphSchemas.js +8 -6
  231. package/dist/domain/javascriptSemanticObjects.js +13 -3
  232. package/dist/domain/javascriptSemanticProjection.js +144 -38
  233. package/dist/domain/javascriptSemanticPromises.js +14 -27
  234. package/dist/domain/javascriptSemanticQuerySchemas.js +6 -9
  235. package/dist/domain/javascriptSemanticResources.js +2 -5
  236. package/dist/domain/javascriptSemanticState.js +4 -0
  237. package/dist/domain/javascriptSemanticTraceSchemas.js +2 -1
  238. package/dist/domain/javascriptSemanticTraversal.js +13 -5
  239. package/dist/domain/javascriptSemanticValues.js +10 -9
  240. package/dist/domain/javascriptSourceParser.js +5 -1
  241. package/dist/domain/javascriptStaticAnalysisCalls.js +8 -5
  242. package/dist/domain/javascriptStaticAnalysisHelpers.js +16 -7
  243. package/dist/domain/keyedArchive.js +181 -0
  244. package/dist/domain/managedApplicationGraph.js +4 -3
  245. package/dist/domain/managedArtifact.js +2 -1
  246. package/dist/domain/managedMemberComparison.js +18 -13
  247. package/dist/domain/managedMemberComparisonCoverage.js +2 -1
  248. package/dist/domain/managedMemberComparisonItems.js +27 -7
  249. package/dist/domain/managedMemberComparisonMatch.js +22 -6
  250. package/dist/domain/managedNativeVerificationMatch.js +2 -2
  251. package/dist/domain/managedNativeVerificationSchemas.js +7 -5
  252. package/dist/domain/managedReconstruction.js +6 -5
  253. package/dist/domain/nativeApiBoundary.js +7 -0
  254. package/dist/domain/nativeDataType.js +51 -0
  255. package/dist/domain/nativeInspection.js +0 -1
  256. package/dist/domain/nativeInstruction.js +82 -0
  257. package/dist/domain/nativeInvestigationGraph.js +9 -5
  258. package/dist/domain/nativeUiObservation.js +123 -0
  259. package/dist/domain/nativeValueFlow.js +17 -0
  260. package/dist/domain/nativeValueTrace.js +64 -0
  261. package/dist/domain/objcSwiftMetadata.js +39 -0
  262. package/dist/domain/peInspection.js +1 -0
  263. package/dist/domain/processCapture.js +5 -55
  264. package/dist/domain/processCaptureExample.js +0 -9
  265. package/dist/domain/processCaptureValidation.js +13 -144
  266. package/dist/domain/processComparison.js +3 -25
  267. package/dist/domain/processObservation.js +0 -29
  268. package/dist/domain/processScenario.js +28 -228
  269. package/dist/domain/processTraceDimensionProjection.js +0 -15
  270. package/dist/domain/processTraceEvaluation.js +0 -6
  271. package/dist/domain/protocolCapture.js +8 -36
  272. package/dist/domain/reconstructionCoverage.js +3 -2
  273. package/dist/domain/reconstructionObligationLedgerSchemas.js +4 -12
  274. package/dist/domain/reconstructionReadinessSchemas.js +4 -3
  275. package/dist/domain/reconstructionVerification.js +2 -1
  276. package/dist/domain/reconstructionVerificationSchemas.js +6 -13
  277. package/dist/domain/referenceSourceClassification.js +0 -110
  278. package/dist/domain/referenceSourceGraph.js +15 -5
  279. package/dist/domain/residualUnknown.js +3 -2
  280. package/dist/domain/runtimeIdentification.js +6 -5
  281. package/dist/domain/sourceMapContents.js +5 -0
  282. package/dist/domain/sourceToBundleComparison.js +3 -10
  283. package/dist/domain/sourceToBundleComparisonSchemas.js +7 -6
  284. package/dist/domain/sourceToBundleSignals.js +9 -3
  285. package/dist/domain/staticRuntimeCorrelation.js +5 -11
  286. package/dist/domain/webBundleAnalysis.js +17 -9
  287. package/dist/domain/webBundleAnalyzer.js +1 -1
  288. package/dist/domain/webCaptureDiff.js +5 -11
  289. package/dist/domain/webCaptureDiffSchemas.js +2 -1
  290. package/dist/domain/webMcpDiscovery.js +2 -1
  291. package/dist/dotnet/ManagedMemberInspectorCore.js +15 -7
  292. package/dist/dotnet/ManagedMemberInstructionDecoder.js +57 -40
  293. package/dist/dotnet/ManagedMemberRows.js +2 -0
  294. package/dist/dotnet/ManagedMethodBodyReader.js +15 -8
  295. package/dist/dotnet/ManagedPeReader.js +2 -0
  296. package/dist/generatedMcpToolCatalog.js +1 -1
  297. package/dist/generatedPackageMetadata.js +2 -2
  298. package/dist/ghidra/GhidraAnalysisProfile.js +15 -5
  299. package/dist/ghidra/GhidraClient.js +38 -8
  300. package/dist/ghidra/GhidraFunctionValues.js +56 -20
  301. package/dist/ghidra/GhidraInstallation.js +7 -4
  302. package/dist/ghidra/GhidraInventoryValues.js +44 -9
  303. package/dist/ghidra/GhidraLauncher.js +18 -3
  304. package/dist/ghidra/GhidraProvider.js +23 -2
  305. package/dist/ghidra/GhidraRequestQueue.js +45 -4
  306. package/dist/ghidra/GhidraSessionValues.js +5 -0
  307. package/dist/hopper/HopperAnalysisProfile.js +2 -0
  308. package/dist/hopper/HopperProvider.js +29 -6
  309. package/dist/hopper/HopperTargetLease.js +18 -4
  310. package/dist/logger.js +0 -13
  311. package/dist/main/messages.js +0 -1
  312. package/dist/main/reload.js +3 -32
  313. package/dist/main/shutdown.js +1 -2
  314. package/dist/main/transport.js +0 -17
  315. package/dist/main.js +0 -10
  316. package/dist/native/AppleDispatchMetadata.js +582 -0
  317. package/dist/native/AppleObjcProtocols.js +88 -0
  318. package/dist/native/AppleSwiftVtables.js +86 -0
  319. package/dist/native/CommandRunner.js +1 -1
  320. package/dist/native/NativeHostCapabilities.js +23 -0
  321. package/dist/native/NativeMacOSProvider.js +61 -9
  322. package/dist/native/NativeMachoInspection.js +39 -6
  323. package/dist/native/NativeUiHelperRuntime.js +42 -0
  324. package/dist/native/NativeUiObservation.js +174 -0
  325. package/dist/native/parsers/codesign.js +4 -1
  326. package/dist/native/parsers/dyldInfo.js +51 -25
  327. package/dist/native/parsers/lipo.js +13 -4
  328. package/dist/native/parsers/otool.js +84 -39
  329. package/dist/native/parsers/plist.js +2 -1
  330. package/dist/process/ExecFileOutput.js +5 -1
  331. package/dist/process/ProcessOwnership.js +69 -33
  332. package/dist/process/ProcessOwnershipObservation.js +31 -12
  333. package/dist/process/ProviderProcess.js +4 -2
  334. package/dist/reference/ReferenceSourceReaderEntries.js +48 -31
  335. package/dist/reference/ReferenceSourceReaderErrors.js +24 -0
  336. package/dist/reference/ReferenceSourceReaderFile.js +11 -5
  337. package/dist/reference/ReferenceSourceReaderValidate.js +22 -8
  338. package/dist/server/createServer.js +7 -62
  339. package/dist/server/registerApplicationTools/helpers.js +2 -9
  340. package/dist/server/registerApplicationTools.js +0 -4
  341. package/dist/server/registerArtifactComparisonTool.js +1 -1
  342. package/dist/server/registerBrowserScenarioTool.js +4 -2
  343. package/dist/server/registerBrowserTools.js +7 -7
  344. package/dist/server/registerBundleComparisonTool.js +1 -1
  345. package/dist/server/registerCloseLifecycleTool.js +1 -1
  346. package/dist/server/registerElectronTools.js +10 -4
  347. package/dist/server/registerEnhancedTools.js +20 -12
  348. package/dist/server/registerEvidenceTools.js +4 -28
  349. package/dist/server/registerFunctionComparisonTool.js +1 -1
  350. package/dist/server/registerInvestigationTools.js +6 -6
  351. package/dist/server/registerJavaScriptRuntimeObservationTools.js +2 -2
  352. package/dist/server/registerManagedTools.js +28 -14
  353. package/dist/server/registerManagedWorkflowTools.js +0 -2
  354. package/dist/server/registerProcessComparisonTool.js +1 -3
  355. package/dist/server/registerSessionRecordTools.js +9 -9
  356. package/dist/server/registerSessionStatusTool.js +1 -1
  357. package/dist/server/registerSessionTools.js +28 -57
  358. package/dist/server/sessionAvailabilityPolicy.js +2 -3
  359. package/dist/server/sessionToolPolicies.js +0 -4
  360. package/dist/server/toolResult.js +8 -10
  361. package/package.json +32 -22
  362. package/skills/reverse-engineer-anything/SKILL.md +15 -11
  363. package/skills/reverse-engineer-anything/references/evidence-workflows.md +3 -2
  364. package/skills/reverse-engineer-anything/references/javascript-applications.md +3 -2
  365. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +8 -6
  366. package/skills/reverse-engineer-anything/references/runtime-observation.md +15 -11
  367. package/dist/application/CommandShimReplay.js +0 -152
  368. package/dist/application/ConfiguredRoots.js +0 -19
  369. package/dist/application/InstrumentedJavaScriptReplayHost.js +0 -36
  370. package/dist/application/JavaScriptReplayPermission.js +0 -16
  371. package/dist/application/JavaScriptReplayPlanning.js +0 -207
  372. package/dist/application/JavaScriptReplayService.js +0 -274
  373. package/dist/application/LoopbackReplay.js +0 -389
  374. package/dist/application/LoopbackReplayRecorder.js +0 -129
  375. package/dist/application/ManagedRuntimeCorrelationService.js +0 -104
  376. package/dist/application/NodeRuntimeCharacterizationService.js +0 -191
  377. package/dist/application/PermissionAuthority.js +0 -268
  378. package/dist/application/PermissionConfiguration.js +0 -26
  379. package/dist/application/PermissionFailure.js +0 -5
  380. package/dist/application/ProcessCaptureAuthority.js +0 -24
  381. package/dist/application/ProcessCapturePermission.js +0 -13
  382. package/dist/application/ProcessCheckpoints.js +0 -178
  383. package/dist/application/ProcessReactiveCoordinator.js +0 -223
  384. package/dist/application/ProcessReactiveEffects.js +0 -153
  385. package/dist/application/ProcessReactiveHarness.js +0 -106
  386. package/dist/application/ProcessReactiveObservations.js +0 -105
  387. package/dist/application/ProjectPermissionStore.js +0 -199
  388. package/dist/application/RuntimeExecutableDiagnostics.js +0 -198
  389. package/dist/application/Upgrade.js +0 -134
  390. package/dist/browser/SensitiveTextCapture.js +0 -8
  391. package/dist/cliPolicyCommands.js +0 -185
  392. package/dist/config/browserScenario.js +0 -77
  393. package/dist/config/electronAutomation.js +0 -35
  394. package/dist/config/javascriptReplay.js +0 -41
  395. package/dist/config/managedRuntime.js +0 -25
  396. package/dist/config/passiveObservation.js +0 -87
  397. package/dist/config/permissions.js +0 -23
  398. package/dist/config/processCapture.js +0 -47
  399. package/dist/contracts/replayMachineExample.js +0 -37
  400. package/dist/domain/javascriptExportInstrumentation.js +0 -95
  401. package/dist/domain/javascriptReplay.js +0 -360
  402. package/dist/domain/managedRuntimeCorrelation.js +0 -181
  403. package/dist/domain/nodeRuntimeCharacterization.js +0 -63
  404. package/dist/domain/permissionPolicy.js +0 -176
  405. package/dist/domain/processCaptureReactiveSchema.js +0 -68
  406. package/dist/domain/processCaptureReactiveValidation.js +0 -180
  407. package/dist/domain/processReactiveCheckpointDataflow.js +0 -32
  408. package/dist/domain/processReactiveMatching.js +0 -196
  409. package/dist/domain/processReactiveRuntime.js +0 -116
  410. package/dist/domain/processReactiveScenario.js +0 -296
  411. package/dist/domain/processReactiveScenarioPreflight.js +0 -95
  412. package/dist/domain/processReactiveTransition.js +0 -187
  413. package/dist/domain/replayMachine.js +0 -320
  414. package/dist/domain/replayMachineRun.js +0 -168
  415. package/dist/domain/replayMachineRuntime.js +0 -296
  416. package/dist/domain/replayMachineValues.js +0 -84
  417. package/dist/domain/runtimeCharacterization.js +0 -84
  418. package/dist/replay/JavaScriptReplayWorker.js +0 -382
  419. package/dist/replay/JavaScriptReplayWorkerTypes.js +0 -1
  420. package/dist/replay/LinuxJavaScriptReplayRunner.js +0 -216
  421. package/dist/replay/LinuxJavaScriptReplaySandbox.js +0 -121
  422. package/dist/replay/LinuxRuntimeClosure.js +0 -44
  423. package/dist/replay/LinuxSeccompPolicy.js +0 -40
  424. package/dist/replay/ReplayOutcome.js +0 -104
  425. package/dist/replay/ReplayProcessLifecycle.js +0 -96
  426. package/dist/replay/ReplaySeccompFile.js +0 -29
  427. package/dist/replay/ReplayWorkerProtocol.js +0 -58
  428. package/dist/replay/SystemJavaScriptReplayHost.js +0 -153
  429. package/dist/server/ProcessCaptureElicitation.js +0 -153
  430. package/dist/server/registerApplicationTools/characterization.js +0 -46
  431. package/dist/server/registerApplicationTools/controlledReplay.js +0 -31
  432. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +0 -29
  433. package/dist/server/registerReplayMachineTool.js +0 -14
  434. package/skills/reverse-engineer-anything/references/controlled-replay.md +0 -12
@@ -1,7 +1,10 @@
1
1
  import { createReadStream } from "node:fs";
2
+ import { stat } from "node:fs/promises";
3
+ import { Readable } from "node:stream";
2
4
  import { XcrunCommandRunner, } from "../native/CommandRunner.js";
3
5
  import { parseLipoArchitectures } from "../native/parsers/lipo.js";
4
6
  import { ArtifactReaderFailure, } from "./ArtifactReader.js";
7
+ import { streamChunkToBuffer } from "./StreamBytes.js";
5
8
  /** Read-only universal Mach-O slice reader backed by native lipo metadata. */
6
9
  export class MachOSliceArtifactReader {
7
10
  path;
@@ -24,9 +27,17 @@ export class MachOSliceArtifactReader {
24
27
  exit_code: captured.value.exitCode,
25
28
  effects: ["read"],
26
29
  };
30
+ const fileSize = (await stat(this.path)).size;
27
31
  for (const architecture of parseLipoArchitectures(captured.value.stdout)) {
28
32
  if (architecture.file_offset === null || architecture.size === null)
29
33
  throw new ArtifactReaderFailure("integrity", "lipo omitted a universal slice byte range");
34
+ if (!Number.isSafeInteger(architecture.file_offset) ||
35
+ !Number.isSafeInteger(architecture.size) ||
36
+ architecture.file_offset < 0 ||
37
+ architecture.size <= 0 ||
38
+ !Number.isSafeInteger(architecture.file_offset + architecture.size) ||
39
+ architecture.file_offset + architecture.size > fileSize)
40
+ throw new ArtifactReaderFailure("integrity", `lipo reported an out-of-bounds Mach-O slice: ${architecture.name}`);
30
41
  yield {
31
42
  path: `slices/${architecture.name}`,
32
43
  kind: "slice",
@@ -42,17 +53,48 @@ export class MachOSliceArtifactReader {
42
53
  };
43
54
  }
44
55
  }
45
- open(entry, signal) {
56
+ async open(entry, signal) {
46
57
  if (signal?.aborted === true)
47
58
  return Promise.reject(new ArtifactReaderFailure("cancelled", "Mach-O slice read cancelled"));
48
59
  const [offsetText, sizeText] = entry.adapterKey.split(":");
49
- const offset = Number(offsetText);
50
- const size = Number(sizeText);
60
+ const offset = parseSliceKeyInteger(offsetText);
61
+ const size = parseSliceKeyInteger(sizeText);
51
62
  if (!Number.isSafeInteger(offset) ||
52
63
  !Number.isSafeInteger(size) ||
64
+ offset === null ||
65
+ size === null ||
66
+ offset < 0 ||
53
67
  size <= 0)
54
- return Promise.reject(new ArtifactReaderFailure("integrity", "Invalid Mach-O slice byte range"));
55
- return Promise.resolve(createReadStream(this.path, { start: offset, end: offset + size - 1 }));
68
+ throw new ArtifactReaderFailure("integrity", "Invalid Mach-O slice byte range");
69
+ const fileSize = (await stat(this.path)).size;
70
+ if (!Number.isSafeInteger(offset + size) || offset + size > fileSize)
71
+ throw new ArtifactReaderFailure("integrity", `Mach-O slice range is outside the artifact: ${entry.path}`);
72
+ const source = createReadStream(this.path, {
73
+ start: offset,
74
+ end: offset + size - 1,
75
+ ...(signal === undefined ? {} : { signal }),
76
+ });
77
+ return Readable.from((async function* () {
78
+ let observedBytes = 0;
79
+ try {
80
+ for await (const raw of source) {
81
+ const chunk = streamChunkToBuffer(raw);
82
+ observedBytes += chunk.byteLength;
83
+ if (observedBytes > size)
84
+ throw new ArtifactReaderFailure("integrity", `Mach-O slice exceeded its reported size: ${entry.path}`);
85
+ yield chunk;
86
+ }
87
+ }
88
+ catch (cause) {
89
+ if (cause instanceof ArtifactReaderFailure)
90
+ throw cause;
91
+ if (signal?.aborted === true)
92
+ throw new ArtifactReaderFailure("cancelled", "Mach-O slice read cancelled", { cause });
93
+ throw new ArtifactReaderFailure("integrity", `Could not read Mach-O slice range: ${entry.path}`, { cause });
94
+ }
95
+ if (observedBytes !== size)
96
+ throw new ArtifactReaderFailure("integrity", `Mach-O slice size disagrees with lipo metadata: ${entry.path}`);
97
+ })());
56
98
  }
57
99
  provenance() {
58
100
  return this.#command === undefined ? [] : [structuredClone(this.#command)];
@@ -61,3 +103,9 @@ export class MachOSliceArtifactReader {
61
103
  return Promise.resolve();
62
104
  }
63
105
  }
106
+ const parseSliceKeyInteger = (value) => {
107
+ if (value === undefined || !/^\d+$/u.test(value))
108
+ return null;
109
+ const parsed = Number(value);
110
+ return Number.isSafeInteger(parsed) ? parsed : null;
111
+ };
@@ -80,11 +80,27 @@ export class ZipArtifactReader {
80
80
  }
81
81
  const extractStream = (entry, signal) => {
82
82
  const output = new PassThrough();
83
+ const controller = new AbortController();
84
+ const onAbort = () => {
85
+ controller.abort(signal?.reason);
86
+ // AbortSignal listeners dispatch synchronously, so this destroy wins the race
87
+ // against `getData` rejecting with its own AbortError. That ordering is what
88
+ // keeps the caller-visible failure typed as `cancelled`.
89
+ output.destroy(new ArtifactReaderFailure("cancelled", "ZIP operation cancelled"));
90
+ };
91
+ signal?.addEventListener("abort", onAbort, { once: true });
92
+ // `close` covers both a consumer walking away mid-entry and normal completion
93
+ // after `end()`; aborting then is harmless because `getData` has already
94
+ // resolved, and it releases the producer in the abandoned-consumer case.
95
+ output.once("close", () => {
96
+ signal?.removeEventListener("abort", onAbort);
97
+ controller.abort();
98
+ });
83
99
  const writable = new WritableStream({
84
100
  write: async (chunk) => {
85
101
  abortIfNeeded(signal);
86
102
  if (!output.write(Buffer.from(chunk)))
87
- await once(output, "drain");
103
+ await once(output, "drain", { signal: controller.signal });
88
104
  },
89
105
  close: () => {
90
106
  output.end();
@@ -95,6 +111,7 @@ const extractStream = (entry, signal) => {
95
111
  });
96
112
  void entry
97
113
  .getData(writable, {
114
+ signal: controller.signal,
98
115
  checkSignature: true,
99
116
  checkOverlappingEntry: true,
100
117
  onprogress: () => abortIfNeeded(signal),
@@ -1,4 +1,5 @@
1
1
  import { createHash } from "node:crypto";
2
+ import { sanitizeBrowserUrl, } from "../domain/browserObservation.js";
2
3
  const REDACTION_PREFIX = "[REDACTED:";
3
4
  /** Resolved secret values kept only for one in-memory scenario session. */
4
5
  export class BrowserScenarioSecrets {
@@ -10,7 +11,8 @@ export class BrowserScenarioSecrets {
10
11
  const values = new Map();
11
12
  for (const declaration of scenario.secrets) {
12
13
  const value = environment[declaration.environment_variable];
13
- if (value === undefined)
14
+ if (!Object.hasOwn(environment, declaration.environment_variable) ||
15
+ typeof value !== "string")
14
16
  return undefined;
15
17
  values.set(declaration.secret_id, value);
16
18
  }
@@ -39,6 +41,31 @@ export class BrowserScenarioSecrets {
39
41
  output = output.replaceAll(secret, `${REDACTION_PREFIX}${id}]`);
40
42
  return output;
41
43
  }
44
+ /** Remove only declared secret values from one URL and report that action. */
45
+ sanitizeUrl(value) {
46
+ let output = value;
47
+ const replacements = [...this.values].sort(([leftId, left], [rightId, right]) => right.length - left.length ||
48
+ (leftId < rightId ? -1 : leftId > rightId ? 1 : 0));
49
+ for (const [id, secret] of replacements) {
50
+ if (secret === "")
51
+ continue;
52
+ const marker = `${REDACTION_PREFIX}${id}]`;
53
+ const searchParamsValue = new URLSearchParams([["value", secret]])
54
+ .toString()
55
+ .slice("value=".length);
56
+ for (const candidate of new Set([
57
+ secret,
58
+ encodeURIComponent(secret),
59
+ searchParamsValue,
60
+ ]))
61
+ output = output.replaceAll(candidate, marker);
62
+ }
63
+ const sanitized = sanitizeBrowserUrl(output);
64
+ return {
65
+ ...sanitized,
66
+ redacted: sanitized.redacted || output !== value,
67
+ };
68
+ }
42
69
  fingerprint(value) {
43
70
  for (const secret of this.values.values())
44
71
  if (secret !== "" && value.includes(secret))
@@ -23,7 +23,7 @@ export const CDP_BROWSER_PROVIDER_IDENTITY = Object.freeze({
23
23
  });
24
24
  const IDENTITY = CDP_BROWSER_PROVIDER_IDENTITY;
25
25
  const CLEANUP_DOMAINS = ["Network", "Debugger", "Runtime", "Page"];
26
- /** Passive, origin-scoped browser observation through a user-owned CDP endpoint. */
26
+ /** Passive browser observation through a selected user-owned CDP endpoint. */
27
27
  export class CdpBrowserProvider {
28
28
  identity() {
29
29
  return IDENTITY;
@@ -31,14 +31,17 @@ export class CdpBrowserProvider {
31
31
  async listTargets(input, options = {}) {
32
32
  try {
33
33
  const discovery = await discoverCdpEndpoint(input.cdp_endpoint, "list_browser_targets", options.signal);
34
- const allowedOrigins = new Set(input.allowed_origins);
35
- const selected = selectTargets(discovery, allowedOrigins);
34
+ const selected = selectTargets(discovery, input.allowed_origins.length === 0
35
+ ? undefined
36
+ : new Set(input.allowed_origins));
36
37
  return ok(browserTargetListSchema.parse({
37
38
  browser: discovery.version,
38
39
  targets: selected.allowed,
39
40
  excluded: selected.excluded,
40
41
  limitations: [
41
- "Only page targets whose current URL matches an approved exact origin are listed.",
42
+ input.allowed_origins.length === 0
43
+ ? "All page targets with supported HTTP(S) URLs are listed."
44
+ : "Only page targets whose current URL matches an explicitly requested exact origin are listed.",
42
45
  ...(selected.unconnectable === 0
43
46
  ? []
44
47
  : [
@@ -64,7 +67,12 @@ export class CdpBrowserProvider {
64
67
  try {
65
68
  const captured = await this.#capture(input, options, "analyze_web_bundle");
66
69
  const sourceMaps = input.fetch_source_maps
67
- ? await fetchWebSourceMaps(captured.sourceMapRequests, input, options.signal)
70
+ ? await fetchWebSourceMaps(captured.sourceMapRequests, {
71
+ ...input,
72
+ allowed_origins: input.allowed_origins.length > 0
73
+ ? input.allowed_origins
74
+ : [captured.inspection.target.origin],
75
+ }, options.signal)
68
76
  : undefined;
69
77
  return ok(webBundleAnalysisSchema.parse(analyzeCapturedWebBundle(captured.inspection, sourceMaps)));
70
78
  }
@@ -77,13 +85,14 @@ export class CdpBrowserProvider {
77
85
  try {
78
86
  const discovery = await discoverCdpEndpoint(input.cdp_endpoint, "observe_web_session", options.signal);
79
87
  const target = authorizeTarget(discovery, input);
88
+ const scopedInput = scopeToTargetOrigin(input, target);
80
89
  targetSession = await openCdpTargetSession(discovery, target, "observe_web_session", options.signal);
81
90
  return ok(webObservationSessionSchema.parse(await observeCdpSession({
82
91
  connection: targetSession.connection,
83
92
  sessionId: targetSession.sessionId,
84
93
  discovery,
85
94
  target,
86
- input,
95
+ input: scopedInput,
87
96
  ...(options.signal === undefined ? {} : { signal: options.signal }),
88
97
  ...(options.progress === undefined
89
98
  ? {}
@@ -95,7 +104,7 @@ export class CdpBrowserProvider {
95
104
  }
96
105
  finally {
97
106
  if (targetSession !== undefined)
98
- await closeCdpTargetSession(targetSession, CLEANUP_DOMAINS);
107
+ await closeCdpTargetSession(targetSession, CLEANUP_DOMAINS, options.signal);
99
108
  }
100
109
  }
101
110
  async discoverWebMcpTools(input, options = {}) {
@@ -103,13 +112,14 @@ export class CdpBrowserProvider {
103
112
  try {
104
113
  const discovery = await discoverCdpEndpoint(input.cdp_endpoint, "discover_webmcp_tools", options.signal);
105
114
  const target = authorizeTarget(discovery, input);
115
+ const scopedInput = scopeToTargetOrigin(input, target);
106
116
  targetSession = await openCdpTargetSession(discovery, target, "discover_webmcp_tools", options.signal);
107
117
  return ok(webMcpDiscoverySchema.parse(await discoverWebMcp({
108
118
  connection: targetSession.connection,
109
119
  sessionId: targetSession.sessionId,
110
120
  discovery,
111
121
  target,
112
- input,
122
+ input: scopedInput,
113
123
  ...(options.signal === undefined ? {} : { signal: options.signal }),
114
124
  ...(options.progress === undefined
115
125
  ? {}
@@ -121,7 +131,7 @@ export class CdpBrowserProvider {
121
131
  }
122
132
  finally {
123
133
  if (targetSession !== undefined)
124
- await closeCdpTargetSession(targetSession, CLEANUP_DOMAINS);
134
+ await closeCdpTargetSession(targetSession, CLEANUP_DOMAINS, options.signal);
125
135
  }
126
136
  }
127
137
  async compareCaptures(input) {
@@ -137,13 +147,14 @@ export class CdpBrowserProvider {
137
147
  try {
138
148
  const discovery = await discoverCdpEndpoint(input.cdp_endpoint, "capture_web_screenshot", options.signal);
139
149
  const target = authorizeTarget(discovery, input);
150
+ const scopedInput = scopeToTargetOrigin(input, target);
140
151
  targetSession = await openCdpTargetSession(discovery, target, "capture_web_screenshot", options.signal);
141
152
  return ok(webScreenshotSchema.parse(await captureCdpScreenshot({
142
153
  connection: targetSession.connection,
143
154
  sessionId: targetSession.sessionId,
144
155
  discovery,
145
156
  target,
146
- input,
157
+ input: scopedInput,
147
158
  ...(options.signal === undefined ? {} : { signal: options.signal }),
148
159
  ...(options.progress === undefined
149
160
  ? {}
@@ -155,7 +166,7 @@ export class CdpBrowserProvider {
155
166
  }
156
167
  finally {
157
168
  if (targetSession !== undefined)
158
- await closeCdpTargetSession(targetSession, CLEANUP_DOMAINS);
169
+ await closeCdpTargetSession(targetSession, CLEANUP_DOMAINS, options.signal);
159
170
  }
160
171
  }
161
172
  async compareScreenshots(input) {
@@ -171,6 +182,7 @@ export class CdpBrowserProvider {
171
182
  try {
172
183
  const discovery = await discoverCdpEndpoint(input.cdp_endpoint, operation, options.signal);
173
184
  const target = authorizeTarget(discovery, input);
185
+ const scopedInput = scopeToTargetOrigin(input, target);
174
186
  targetSession = await openCdpTargetSession(discovery, target, operation, options.signal);
175
187
  return await capturePage({
176
188
  connection: targetSession.connection,
@@ -178,7 +190,7 @@ export class CdpBrowserProvider {
178
190
  operation,
179
191
  discovery,
180
192
  target,
181
- input,
193
+ input: scopedInput,
182
194
  ...(options.signal === undefined ? {} : { signal: options.signal }),
183
195
  ...(options.progress === undefined
184
196
  ? {}
@@ -187,7 +199,7 @@ export class CdpBrowserProvider {
187
199
  }
188
200
  finally {
189
201
  if (targetSession !== undefined)
190
- await closeCdpTargetSession(targetSession, CLEANUP_DOMAINS);
202
+ await closeCdpTargetSession(targetSession, CLEANUP_DOMAINS, options.signal);
191
203
  }
192
204
  }
193
205
  }
@@ -207,7 +219,7 @@ const selectTargets = (discovery, allowedOrigins) => {
207
219
  unsupportedUrl += 1;
208
220
  continue;
209
221
  }
210
- if (!allowedOrigins.has(url.origin)) {
222
+ if (allowedOrigins !== undefined && !allowedOrigins.has(url.origin)) {
211
223
  disallowedOrigin += 1;
212
224
  continue;
213
225
  }
@@ -242,10 +254,19 @@ const authorizeTarget = (discovery, input) => {
242
254
  const origin = sanitizeBrowserUrl(target.url).origin;
243
255
  if (target.type !== "page" ||
244
256
  origin === null ||
245
- !input.allowed_origins.includes(origin))
257
+ (input.allowed_origins.length > 0 &&
258
+ !input.allowed_origins.includes(origin)))
246
259
  throw new BrowserObservationError("inspect_web_page", "target_not_allowed");
247
260
  return target;
248
261
  };
262
+ const scopeToTargetOrigin = (input, target) => {
263
+ if (input.allowed_origins.length > 0)
264
+ return input;
265
+ const origin = sanitizeBrowserUrl(target.url).origin;
266
+ if (origin === null)
267
+ throw new BrowserObservationError("inspect_web_page", "target_not_allowed");
268
+ return { ...input, allowed_origins: [origin] };
269
+ };
249
270
  const providerError = (cause, operation) => cause instanceof BrowserObservationError && cause.operation !== operation
250
271
  ? new BrowserObservationError(operation, cause.reason, { cause })
251
272
  : cause instanceof AnalysisError
@@ -2,11 +2,13 @@ import { allowedSanitizedUrl, numberValue, recordValue, recordsValue, requiredRe
2
2
  import { exclusionReasonForUrl } from "./CdpCaptureEventHelpers.js";
3
3
  /** Normalize every allowed frame, optionally selecting a leading frame. */
4
4
  export const captureFrames = (result, allowedOrigins, maximum, completeness) => {
5
- const root = recordValue(requiredRecord(result).frameTree);
6
- if (root === undefined)
5
+ const root = recordValue(recordValue(result)?.frameTree);
6
+ if (root === undefined) {
7
+ completeness?.exclude("frames", "invalid_protocol_value");
7
8
  return { items: [] };
9
+ }
8
10
  const items = [];
9
- for (const tree of walkFrameTrees(root)) {
11
+ for (const tree of walkFrameTrees(root, () => completeness?.exclude("frames", "invalid_protocol_value"))) {
10
12
  const frame = recordValue(tree.frame);
11
13
  const frameId = stringValue(frame?.id);
12
14
  const sanitized = allowedSanitizedUrl(frame?.url, allowedOrigins);
@@ -33,11 +35,13 @@ export const captureFrames = (result, allowedOrigins, maximum, completeness) =>
33
35
  export const mainFrameUrl = (result) => stringValue(recordValue(recordValue(requiredRecord(result).frameTree)?.frame)?.url);
34
36
  /** Normalize every allowed resource. */
35
37
  export const captureResources = (result, allowedOrigins, completeness) => {
36
- const root = recordValue(requiredRecord(result).frameTree);
37
- if (root === undefined)
38
+ const root = recordValue(recordValue(result)?.frameTree);
39
+ if (root === undefined) {
40
+ completeness?.exclude("resources", "invalid_protocol_value");
38
41
  return { items: [] };
42
+ }
39
43
  const items = [];
40
- for (const tree of walkFrameTrees(root)) {
44
+ for (const tree of walkFrameTrees(root, () => completeness?.exclude("resources", "invalid_protocol_value"))) {
41
45
  for (const resource of recordsValue(tree.resources)) {
42
46
  const url = allowedSanitizedUrl(resource.url, allowedOrigins);
43
47
  if (url === undefined || url.origin === null) {
@@ -57,13 +61,23 @@ export const captureResources = (result, allowedOrigins, completeness) => {
57
61
  }
58
62
  return { items };
59
63
  };
60
- const walkFrameTrees = function* (root) {
64
+ export const walkFrameTrees = function* (root, onMalformedChild) {
61
65
  const pending = [root];
62
66
  while (pending.length > 0) {
63
67
  const tree = pending.pop();
64
68
  if (tree === undefined)
65
69
  return;
66
- const children = recordsValue(tree.childFrames);
70
+ const rawChildren = tree.childFrames;
71
+ if (rawChildren !== undefined && !Array.isArray(rawChildren))
72
+ onMalformedChild?.();
73
+ const children = Array.isArray(rawChildren)
74
+ ? rawChildren.flatMap((child) => {
75
+ const parsed = recordValue(child);
76
+ if (parsed === undefined)
77
+ onMalformedChild?.();
78
+ return parsed === undefined ? [] : [parsed];
79
+ })
80
+ : [];
67
81
  for (let index = children.length - 1; index >= 0; index -= 1) {
68
82
  const child = children[index];
69
83
  if (child !== undefined)
@@ -1,9 +1,8 @@
1
1
  import { inferJsonShape } from "../domain/jsonShape.js";
2
2
  import { safeResponseMetadata } from "./CdpSafeMetadata.js";
3
- import { redactSensitiveText } from "./SensitiveTextCapture.js";
4
3
  import { allowedSanitizedUrl, isHttpUrl, numberValue, recordValue, recordsValue, stringValue, } from "./CdpCaptureValues.js";
5
4
  import { requestBodyShape } from "./CdpCaptureEventBodyShapes.js";
6
- import { consolePrimitive, decodeBase64, exclusionReasonForUrl, executionContextKey, firstCallFrame, initiatorLocation, integerOrNull, } from "./CdpCaptureEventHelpers.js";
5
+ import { consolePrimitive, decodeBase64, exclusionReasonForUrl, executionContextKey, firstCallFrame, initiatorLocation, integerOrNull, isMainFrameNavigation, } from "./CdpCaptureEventHelpers.js";
7
6
  export const handleExecutionContextCreated = (state, params) => {
8
7
  const context = recordValue(params.context);
9
8
  const identifier = numberValue(context?.id);
@@ -182,7 +181,7 @@ const captureConsoleText = (state, arguments_) => {
182
181
  const primitive = consolePrimitive(argument);
183
182
  if (primitive === undefined)
184
183
  continue;
185
- const text = redactSensitiveText(primitive.text);
184
+ const text = primitive.text;
186
185
  values.push({
187
186
  argument_index: argumentIndex,
188
187
  type: primitive.type,
@@ -261,10 +260,20 @@ export const handleWebSocketCreated = (state, params) => {
261
260
  };
262
261
  export const handleFrameNavigated = (state, params) => {
263
262
  const frame = recordValue(params.frame);
264
- if (stringValue(frame?.id) !== state.mainFrameId)
263
+ if (state.mainFrameId === undefined)
264
+ return;
265
+ if (!isMainFrameNavigation({ method: "Page.frameNavigated", params }, state.mainFrameId))
265
266
  return;
266
- state.navigationDuringCapture = true;
267
267
  const rawUrl = stringValue(frame?.url);
268
+ const loaderId = stringValue(frame?.loaderId);
269
+ // `frameNavigated` re-fires for a document already reported (same URL and
270
+ // loader). Treating that as a navigation aborted a valid capture with
271
+ // `target_changed`, which is a false claim that the target moved.
272
+ const document = `${String(loaderId ?? "")}\0${String(rawUrl ?? "")}`;
273
+ if (state.committedDocument === document)
274
+ return;
275
+ state.committedDocument = document;
276
+ state.navigationDuringCapture = true;
268
277
  if (isHttpUrl(rawUrl) &&
269
278
  allowedSanitizedUrl(rawUrl, state.allowedOrigins) === undefined)
270
279
  state.originViolation = true;
@@ -1,4 +1,17 @@
1
1
  import { isHttpUrl, numberValue, recordValue, recordsValue, stringValue, } from "./CdpCaptureValues.js";
2
+ /** Identify a top-level navigation event from its untrusted CDP envelope. */
3
+ export const isMainFrameNavigation = (event, mainFrameId) => {
4
+ const params = recordValue(event.params);
5
+ if (params === undefined)
6
+ return false;
7
+ const frameId = event.method === "Page.frameNavigated"
8
+ ? stringValue(recordValue(params.frame)?.id)
9
+ : event.method === "Page.frameRequestedNavigation" ||
10
+ event.method === "Page.navigatedWithinDocument"
11
+ ? stringValue(params.frameId)
12
+ : undefined;
13
+ return frameId === mainFrameId;
14
+ };
2
15
  export const firstCallFrame = (value) => recordsValue(value?.callFrames)[0];
3
16
  export const initiatorLocation = (initiator) => {
4
17
  let stack = recordValue(initiator?.stack);
@@ -24,6 +24,7 @@ export class CdpCaptureEvents {
24
24
  originViolation = false;
25
25
  navigationDuringCapture = false;
26
26
  mainFrameId = undefined;
27
+ committedDocument = undefined;
27
28
  input;
28
29
  allowedOrigins;
29
30
  constructor(input, allowedOrigins) {
@@ -34,6 +35,7 @@ export class CdpCaptureEvents {
34
35
  this.mainFrameId = frameId;
35
36
  this.originViolation = false;
36
37
  this.navigationDuringCapture = false;
38
+ this.committedDocument = undefined;
37
39
  this.scripts.clear();
38
40
  this.executionContextFrames.clear();
39
41
  this.network.clear();
@@ -52,7 +54,14 @@ export class CdpCaptureEvents {
52
54
  }
53
55
  beginFinalCapture(frameId) {
54
56
  this.mainFrameId = frameId;
55
- this.navigationDuringCapture = false;
57
+ // Deliberately does not clear `navigationDuringCapture`. A main-frame
58
+ // navigation observed during the observation window means the page never
59
+ // settled, and clearing the flag here reported the capture as clean while
60
+ // carrying pre-navigation scripts, network and console into the inventory
61
+ // of the new document. The caller now reports `target_changed` instead.
62
+ // `committedDocument` is dropped so the new document's frame events are
63
+ // compared against itself rather than the document we just left.
64
+ this.committedDocument = undefined;
56
65
  }
57
66
  ingest(event) {
58
67
  const params = recordValue(event.params);
@@ -2,6 +2,7 @@ import { BrowserObservationError } from "../domain/errors.js";
2
2
  import { CdpCaptureCompleteness } from "./CdpCaptureCompleteness.js";
3
3
  import { canonicalJsonDigest } from "./CdpCanonicalJsonDigest.js";
4
4
  import { delayWithCancellation, numberValue, recordValue, recordsValue, requiredRecord, stringValue, } from "./CdpCaptureValues.js";
5
+ import { walkFrameTrees } from "./CdpCaptureDocuments.js";
5
6
  import { ingestElectronScriptEvent, } from "./CdpElectronScriptEvents.js";
6
7
  import { captureElectronScripts } from "./CdpElectronScripts.js";
7
8
  import { captureElectronWorkers } from "./CdpElectronWorkers.js";
@@ -15,7 +16,7 @@ export const inspectCdpElectronPage = async (context) => {
15
16
  limitations: [
16
17
  "Local file paths exposed by the selected CDP target are retained in the observation.",
17
18
  "REA does not evaluate renderer JavaScript, invoke Electron APIs, navigate, click, or close the page.",
18
- "Script contents require separate source-capture approval.",
19
+ "Select include_script_sources to retain script contents.",
19
20
  ],
20
21
  mainFrameId: undefined,
21
22
  navigationDuringCapture: false,
@@ -132,13 +133,9 @@ const captureFrames = async (result, completeness) => {
132
133
  const frameTree = recordValue(requiredRecord(result).frameTree);
133
134
  if (frameTree === undefined)
134
135
  throw new BrowserObservationError("inspect_web_page", "protocol_error");
135
- const pending = [{ tree: frameTree, parent: null }];
136
136
  const frames = [];
137
- while (pending.length > 0) {
138
- const current = pending.shift();
139
- if (current === undefined)
140
- break;
141
- const frame = recordValue(current.tree.frame);
137
+ for (const tree of walkFrameTrees(frameTree, () => completeness.exclude("frames", "invalid_protocol_value"))) {
138
+ const frame = recordValue(tree.frame);
142
139
  const frameId = stringValue(frame?.id);
143
140
  const path = await authorizedElectronFile(stringValue(frame?.url) ?? "");
144
141
  if (frameId === undefined || path === undefined) {
@@ -147,11 +144,9 @@ const captureFrames = async (result, completeness) => {
147
144
  }
148
145
  frames.push({
149
146
  frame_id: frameId,
150
- parent_frame_id: current.parent,
147
+ parent_frame_id: stringValue(frame?.parentId) ?? null,
151
148
  file_path: path,
152
149
  });
153
- for (const child of recordsValue(current.tree.childFrames))
154
- pending.push({ tree: child, parent: frameId });
155
150
  }
156
151
  return frames;
157
152
  };
@@ -91,11 +91,7 @@ export class CdpElectronProvider {
91
91
  }
92
92
  finally {
93
93
  if (targetSession !== undefined)
94
- await closeCdpTargetSession(targetSession, [
95
- "Debugger",
96
- "Runtime",
97
- "Page",
98
- ]);
94
+ await closeCdpTargetSession(targetSession, ["Debugger", "Runtime", "Page"], options.signal);
99
95
  }
100
96
  }
101
97
  }
@@ -51,7 +51,7 @@ const captureScriptSource = async (input, script) => {
51
51
  return {
52
52
  source: {
53
53
  included: false,
54
- reason: "source capture was not approved",
54
+ reason: "source capture was not selected",
55
55
  },
56
56
  };
57
57
  const result = requiredRecord(await input.connection.send("Debugger.getScriptSource", { scriptId: script.scriptId }, input.sessionId, input.signal));
@@ -82,8 +82,9 @@ const sanitizeSameOriginTitleUrl = (candidate, target) => {
82
82
  catch {
83
83
  return candidate;
84
84
  }
85
- return parsed.origin === target.origin && parsed.search !== ""
86
- ? sanitizeBrowserUrl(parsed.href).url
85
+ return parsed.origin === target.origin &&
86
+ (parsed.username !== "" || parsed.password !== "")
87
+ ? sanitizeBrowserUrl(candidate).url
87
88
  : candidate;
88
89
  };
89
90
  const escapeRegExp = (value) => value.replaceAll(/[.*+?^${}()|[\]\\]/gu, "\\$&");