rea-agents 6.3.0 → 6.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (487) hide show
  1. package/README.md +7 -4
  2. package/bridge/ghidra/ReaGhidraApplySeeds.java +151 -0
  3. package/bridge/ghidra/ReaGhidraBridge.java +597 -209
  4. package/bridge/ghidra/ReaGhidraNoReturnFix.java +123 -0
  5. package/dist/adb/AdbConfiguration.js +88 -0
  6. package/dist/adb/AdbDeviceOutput.js +186 -0
  7. package/dist/adb/AdbProvider.js +1190 -0
  8. package/dist/adb/AdbShellOutput.js +309 -0
  9. package/dist/android/AndroidTargetSnapshot.js +104 -22
  10. package/dist/android/JadxConfiguration.js +44 -24
  11. package/dist/android/JadxProvider.js +51 -19
  12. package/dist/apktool/ApktoolConfiguration.js +84 -0
  13. package/dist/apktool/ApktoolDecodeOutput.js +59 -0
  14. package/dist/apktool/ApktoolProvider.js +506 -0
  15. package/dist/application/AnalysisProvider.js +8 -2
  16. package/dist/application/AppBundleExecutable.js +27 -22
  17. package/dist/application/BinaryTargetResolver.js +22 -2
  18. package/dist/application/CapabilityInventory.js +11 -1
  19. package/dist/application/ClientConfigurationDocument.js +70 -0
  20. package/dist/application/ClientConfigurationFiles.js +91 -0
  21. package/dist/application/ClientRegistrationEnvironment.js +35 -0
  22. package/dist/application/ClientRegistrationStatus.js +66 -31
  23. package/dist/application/DirectAnalysis.js +2 -2
  24. package/dist/application/DirectAnalysisCleanup.js +1 -1
  25. package/dist/application/DirectAnalysisStatus.js +1 -1
  26. package/dist/application/Doctor.js +5 -3
  27. package/dist/application/DoctorDiagnostics.js +1 -1
  28. package/dist/application/EvidenceBundleCommands.js +6 -12
  29. package/dist/application/GeminiClientSettings.js +139 -0
  30. package/dist/application/HermesClientHome.js +115 -0
  31. package/dist/application/HopperDownload.js +39 -0
  32. package/dist/application/InvestigationProviders.js +6 -0
  33. package/dist/application/JsonFiles.js +6 -5
  34. package/dist/{cliJsonFile.js → application/JsonInputFile.js} +108 -35
  35. package/dist/application/LinuxHopper.js +4 -12
  36. package/dist/application/MacHopper.js +172 -149
  37. package/dist/application/MipsElfAbiFlags.js +140 -0
  38. package/dist/application/ProviderOperationExecution.js +31 -0
  39. package/dist/application/ReconstructionObligationCandidates.js +9 -3
  40. package/dist/application/ReferenceSourceImport.js +76 -29
  41. package/dist/application/ReferenceSourceImportEntries.js +18 -9
  42. package/dist/application/ReferenceSourceImportPolicy.js +99 -23
  43. package/dist/application/ReferenceSourceImportTypes.js +30 -22
  44. package/dist/application/ReferenceSourceVcsAdapter.js +145 -30
  45. package/dist/application/RegularFileRead.js +93 -7
  46. package/dist/application/Setup.js +54 -6
  47. package/dist/application/SetupClientConfiguration.js +116 -16
  48. package/dist/application/SetupHost.js +102 -24
  49. package/dist/application/SetupPlan.js +5 -8
  50. package/dist/application/SetupSkill.js +58 -39
  51. package/dist/application/SupportedClients.js +290 -65
  52. package/dist/application/Uninstall.js +158 -10
  53. package/dist/application/UpdateMaintenance.js +17 -21
  54. package/dist/application/Utf8JsonInput.js +7 -0
  55. package/dist/application/WebScriptExportService.js +131 -65
  56. package/dist/application/WebSourceLocationService.js +3 -0
  57. package/dist/application/adb/AdbDeviceAnalysisPort.js +1 -0
  58. package/dist/application/adb/AdbDeviceAnalysisService.js +13 -0
  59. package/dist/application/analysisView/AnalysisViewService.js +40 -2
  60. package/dist/application/apktool/ApktoolResourceAnalysisPort.js +1 -0
  61. package/dist/application/apktool/ApktoolResourceAnalysisService.js +13 -0
  62. package/dist/application/binary/AnalysisClientCleanup.js +0 -24
  63. package/dist/application/binary/BinarySession.js +2 -1
  64. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +2 -1
  65. package/dist/application/binaryDiagnostics/PeResourcesPort.js +1 -0
  66. package/dist/application/binaryDiagnostics/PeResourcesService.js +111 -0
  67. package/dist/application/binaryDiagnostics/RecordedCrashService.js +2 -1
  68. package/dist/application/evm/EvmInterfaceService.js +3 -0
  69. package/dist/application/firmware/FirmwareAnalysisService.js +3 -0
  70. package/dist/application/investigation/InspectEvidenceBundle.js +18 -0
  71. package/dist/application/javascript/ElectronBoundaryGraphContext.js +3 -2
  72. package/dist/application/javascript/ElectronBoundaryGraphIpc.js +2 -2
  73. package/dist/application/javascript/ElectronBoundaryGraphNative.js +19 -6
  74. package/dist/application/javascript/ElectronBoundaryGraphWindows.js +3 -3
  75. package/dist/application/javascript/JavaScriptApplicationService.js +22 -11
  76. package/dist/application/javascript/JavaScriptApplicationWorkflowEvidence.js +5 -6
  77. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +171 -30
  78. package/dist/application/javascript/JavaScriptArtifactGraphAccumulator.js +14 -16
  79. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +67 -19
  80. package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +4 -3
  81. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +11 -5
  82. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +19 -16
  83. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +92 -10
  84. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +258 -235
  85. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +115 -26
  86. package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +4 -1
  87. package/dist/application/javascript/JavaScriptModuleRelationships.js +6 -4
  88. package/dist/application/javascript/JavaScriptRecoveryService.js +3 -0
  89. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +9 -3
  90. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +199 -61
  91. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +12 -19
  92. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +4 -1
  93. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +5 -3
  94. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +5 -3
  95. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +19 -8
  96. package/dist/application/jeb/JebAnalysisPort.js +1 -0
  97. package/dist/application/jeb/JebAnalysisService.js +13 -0
  98. package/dist/application/managed/ManagedApplicationGraphService.js +1 -1
  99. package/dist/application/native/NativeUiActionTrace.js +16 -8
  100. package/dist/application/native/NativeValueTrace.js +23 -6
  101. package/dist/application/process/ProcessCli.js +25 -20
  102. package/dist/artifacts/ArtifactPaths.js +129 -8
  103. package/dist/artifacts/ArtifactProvider.js +20 -15
  104. package/dist/artifacts/ArtifactReader.js +23 -0
  105. package/dist/artifacts/ArtifactResourceScope.js +100 -0
  106. package/dist/artifacts/AsarArtifactReader.js +176 -102
  107. package/dist/artifacts/AsarHeader.js +24 -0
  108. package/dist/artifacts/DirectoryArtifactReader.js +168 -65
  109. package/dist/artifacts/MachOSliceArtifactReader.js +116 -39
  110. package/dist/artifacts/NativeDmgArtifactReader.js +29 -22
  111. package/dist/artifacts/SafeOutputTree.js +245 -70
  112. package/dist/artifacts/SafeOutputTreeCleanup.js +45 -0
  113. package/dist/artifacts/SafeOutputTreeCreationFailure.js +20 -0
  114. package/dist/artifacts/SafeOutputTreeIdentity.js +42 -0
  115. package/dist/artifacts/SafeOutputTreeReadback.js +33 -0
  116. package/dist/artifacts/ZipArtifactReader.js +77 -27
  117. package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +58 -18
  118. package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +62 -24
  119. package/dist/artifacts/apple/KeyedArchiveReader.js +32 -13
  120. package/dist/artifacts/extraction/ArtifactExtraction.js +110 -86
  121. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +110 -43
  122. package/dist/artifacts/inventory/ArtifactInventory.js +5 -4
  123. package/dist/artifacts/inventory/classify.js +75 -32
  124. package/dist/artifacts/inventory/hashStableRootArtifact.js +48 -15
  125. package/dist/artifacts/inventory/reader.js +13 -5
  126. package/dist/artifacts/inventory/scanCanonical.js +62 -25
  127. package/dist/artifacts/inventory/scanReader.js +38 -11
  128. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +15 -9
  129. package/dist/artifacts/javascript/JavaScriptSourceAnalysis.js +3 -0
  130. package/dist/browser/BrowserScenarioPartialObservation.js +8 -2
  131. package/dist/browser/BrowserScenarioSecrets.js +52 -37
  132. package/dist/browser/CdpBrowserProvider.js +5 -0
  133. package/dist/browser/CdpCaptureDocuments.js +40 -6
  134. package/dist/browser/CdpCaptureDomSvg.js +210 -0
  135. package/dist/browser/CdpCaptureEventBodyShapes.js +4 -8
  136. package/dist/browser/CdpCaptureEventHandlers.js +26 -9
  137. package/dist/browser/CdpCaptureEvents.js +4 -9
  138. package/dist/browser/CdpConnection.js +22 -5
  139. package/dist/browser/CdpPageCapture.js +1 -1
  140. package/dist/browser/CdpTargetSession.js +30 -34
  141. package/dist/browser/CdpWebMcpDiscovery.js +32 -10
  142. package/dist/browser/ElectronFileScope.js +99 -9
  143. package/dist/browser/PlaywrightBrowserScenarioProvider.js +60 -4
  144. package/dist/browser/PlaywrightElectronActiveProvider.js +11 -6
  145. package/dist/browser/PlaywrightScenarioArtifacts.js +5 -5
  146. package/dist/browser/PlaywrightScenarioBrowser.js +69 -7
  147. package/dist/browser/PlaywrightScenarioSession.js +127 -54
  148. package/dist/browser/PlaywrightScenarioStorage.js +507 -0
  149. package/dist/browser/PngVisualDiff.js +198 -29
  150. package/dist/browser/WebSourceMapFetcher.js +3 -3
  151. package/dist/browser/assets/LocalWebScriptArtifacts.js +3 -1
  152. package/dist/browser/assets/PublishWebScripts.js +75 -20
  153. package/dist/browser/assets/WebArtifactReads.js +23 -1
  154. package/dist/browser/assets/WebSourceLocationArtifacts.js +1 -0
  155. package/dist/browser/execution/CdpExecutionCapture.js +3 -3
  156. package/dist/browser/execution/CdpPreciseCoverage.js +5 -8
  157. package/dist/browser/history/HarCapture.js +14 -0
  158. package/dist/browser/history/HarCaptureProcess.js +2 -10
  159. package/dist/browser/history/MitmproxyCaptureAdapter.js +3 -1
  160. package/dist/browser/modules/WebModuleArtifacts.js +1 -0
  161. package/dist/cli/adbCommands.js +337 -0
  162. package/dist/cli/analysisViewCommands.js +39 -1
  163. package/dist/cli/apktoolCommands.js +53 -0
  164. package/dist/cli/artifactCommands.js +8 -11
  165. package/dist/cli/binaryDiagnosticsCommands.js +19 -1
  166. package/dist/cli/browserAdvancedCommands.js +65 -36
  167. package/dist/cli/coreBinaryCommands.js +0 -5
  168. package/dist/cli/coreNativeCommands.js +1 -14
  169. package/dist/cli/electronCommands.js +6 -1
  170. package/dist/cli/evmCommands.js +13 -4
  171. package/dist/cli/firmwareCommands.js +7 -2
  172. package/dist/cli/javascriptApplicationAnalysis.js +17 -1
  173. package/dist/cli/javascriptRecoveryCommands.js +22 -15
  174. package/dist/cli/jebCommands.js +99 -0
  175. package/dist/cli/jsonOutput.js +11 -4
  176. package/dist/cli/referenceSourceImportStatus.js +7 -0
  177. package/dist/cli/setupCommands.js +15 -3
  178. package/dist/cli/utilityCommands.js +66 -18
  179. package/dist/cli/webScriptCommands.js +20 -1
  180. package/dist/cli/webSourceLocationCommands.js +21 -9
  181. package/dist/cli.js +6 -0
  182. package/dist/cliBrowserScenarioCommands.js +2 -1
  183. package/dist/cliCommandNames.js +32 -0
  184. package/dist/cliJsonInput.js +2 -2
  185. package/dist/cliObservationOptions.js +3 -0
  186. package/dist/composition/adb.js +3 -0
  187. package/dist/composition/apktool.js +3 -0
  188. package/dist/composition/binaryDiagnostics.js +4 -0
  189. package/dist/composition/directAnalysis.js +12 -4
  190. package/dist/composition/javascriptAnalysisWorkerProcess.js +48 -0
  191. package/dist/composition/jeb.js +6 -0
  192. package/dist/config/environment.js +10 -0
  193. package/dist/config/ghidraLanguageOverride.js +9 -0
  194. package/dist/config/mcpInputSchemaProfile.js +27 -0
  195. package/dist/config/parseConfig.js +28 -1
  196. package/dist/contracts/adb/adbToolContracts.js +353 -0
  197. package/dist/contracts/advertisedInputExamples.js +48 -0
  198. package/dist/contracts/analysisDetail.js +10 -0
  199. package/dist/contracts/analysisViewToolContracts.js +17 -2
  200. package/dist/contracts/apktool/apktoolToolContracts.js +33 -0
  201. package/dist/contracts/artifactToolContracts.js +8 -5
  202. package/dist/contracts/browserToolContracts.js +1 -1
  203. package/dist/contracts/compactInputSchema.js +256 -0
  204. package/dist/contracts/functionWorkflowToolContracts.js +1 -1
  205. package/dist/contracts/inputSchemaPresentation.js +10 -10
  206. package/dist/contracts/javascript/electronToolContracts.js +15 -3
  207. package/dist/contracts/javascript/javascriptRecoveryToolContracts.js +1 -1
  208. package/dist/contracts/jeb/jebToolContracts.js +64 -0
  209. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +25 -3
  210. package/dist/contracts/officialToolContracts.js +5 -5
  211. package/dist/contracts/sessionToolContracts.js +2 -2
  212. package/dist/contracts/sessionToolSchemas.js +6 -2
  213. package/dist/contracts/toolContractExamples.js +6 -0
  214. package/dist/contracts/toolContractTypes.js +3 -0
  215. package/dist/contracts/toolContracts.js +6 -0
  216. package/dist/contracts/toolEffects.js +167 -0
  217. package/dist/contracts/toolOutputSchemaGroups.js +5 -3
  218. package/dist/contracts/toolSchemaMetadata.js +82 -7
  219. package/dist/domain/adb/adbDeviceAnalysis.js +583 -0
  220. package/dist/domain/analysisErrorCleanup.js +29 -0
  221. package/dist/domain/analysisErrorPresentation.js +18 -6
  222. package/dist/domain/analysisErrorProjection.js +4 -1
  223. package/dist/domain/analysisSnapshot.js +2 -1
  224. package/dist/domain/analysisView/analysisView.js +52 -2
  225. package/dist/domain/analysisView/binaryLayoutView.js +2 -0
  226. package/dist/domain/analysisView/javascriptApplicationView.js +2 -0
  227. package/dist/domain/analysisView/nativeFunctionView.js +155 -0
  228. package/dist/domain/android/androidApplication.js +25 -20
  229. package/dist/domain/apktool/apktoolResourceAnalysis.js +77 -0
  230. package/dist/domain/apple/appleApplication.js +40 -23
  231. package/dist/domain/apple/appleBundleAnatomy.js +95 -28
  232. package/dist/domain/apple/dyldPaths.js +9 -1
  233. package/dist/domain/apple/dylibResolution.js +2 -2
  234. package/dist/domain/apple/interfaceBuilderGraph.js +22 -19
  235. package/dist/domain/apple/interfaceBuilderKeyedArchive.js +10 -1
  236. package/dist/domain/artifactComparison.js +35 -7
  237. package/dist/domain/artifactGraph.js +5 -3
  238. package/dist/domain/artifactIdentity.js +30 -2
  239. package/dist/domain/artifactInspection.js +3 -43
  240. package/dist/domain/artifactIntegrityPolicy.js +10 -0
  241. package/dist/domain/artifactInventoryEvidence.js +11 -12
  242. package/dist/domain/artifactPathSyntax.js +1 -1
  243. package/dist/domain/binaryTarget.js +16 -0
  244. package/dist/domain/binaryTargetTypes.js +8 -1
  245. package/dist/domain/browserObservationSchemas.js +8 -4
  246. package/dist/domain/canonicalJsonDigestSteps.js +34 -12
  247. package/dist/domain/compactStringIdentity.js +9 -0
  248. package/dist/domain/evidence.js +2 -1
  249. package/dist/domain/evidenceRecordSummary.js +144 -0
  250. package/dist/domain/inputIssueProjection.js +16 -1
  251. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +12 -13
  252. package/dist/domain/javascript/electronStaticAnalysisIpc.js +11 -20
  253. package/dist/domain/javascript/electronStaticAnalysisNative.js +70 -40
  254. package/dist/domain/javascript/electronStaticAnalysisValues.js +16 -0
  255. package/dist/domain/javascript/javascriptAnalysisResourceControls.js +45 -0
  256. package/dist/domain/javascript/javascriptApplicationAnalysis.js +4 -1
  257. package/dist/domain/javascript/javascriptApplicationChangeGraph.js +6 -6
  258. package/dist/domain/javascript/javascriptApplicationGraph.js +79 -18
  259. package/dist/domain/javascript/javascriptApplicationProjectionResources.js +35 -0
  260. package/dist/domain/javascript/javascriptApplicationVersionItems.js +28 -12
  261. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +9 -1
  262. package/dist/domain/javascript/javascriptAstFingerprint.js +58 -31
  263. package/dist/domain/javascript/javascriptAstValues.js +32 -0
  264. package/dist/domain/javascript/javascriptElectronMemberWrites.js +50 -0
  265. package/dist/domain/javascript/javascriptModuleSemanticIr.js +15 -0
  266. package/dist/domain/javascript/javascriptNativeHandoff.js +6 -1
  267. package/dist/domain/javascript/javascriptRpcEndpoints.js +253 -0
  268. package/dist/domain/javascript/javascriptRuntimeLoadState.js +1 -3
  269. package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +7 -2
  270. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +8 -11
  271. package/dist/domain/javascript/javascriptSemanticAnalysis.js +190 -33
  272. package/dist/domain/javascript/javascriptSemanticCallableResults.js +42 -0
  273. package/dist/domain/javascript/javascriptSemanticCalls.js +8 -1
  274. package/dist/domain/javascript/javascriptSemanticDerivedAnalysis.js +15 -4
  275. package/dist/domain/javascript/javascriptSemanticFileProjection.js +1 -0
  276. package/dist/domain/javascript/javascriptSemanticFingerprints.js +42 -41
  277. package/dist/domain/javascript/javascriptSemanticGraph.js +69 -23
  278. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +2 -10
  279. package/dist/domain/javascript/javascriptSemanticIterationSources.js +40 -7
  280. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +341 -87
  281. package/dist/domain/javascript/javascriptSemanticMutationValues.js +78 -35
  282. package/dist/domain/javascript/javascriptSemanticObjectReferences.js +381 -0
  283. package/dist/domain/javascript/javascriptSemanticObjects.js +7 -1
  284. package/dist/domain/javascript/javascriptSemanticProjection.js +52 -14
  285. package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +77 -0
  286. package/dist/domain/javascript/javascriptSemanticQuery.js +27 -29
  287. package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +1 -3
  288. package/dist/domain/javascript/javascriptSemanticReturnedReferences.js +219 -0
  289. package/dist/domain/javascript/javascriptSemanticReturns.js +13 -23
  290. package/dist/domain/javascript/javascriptSemanticState.js +22 -2
  291. package/dist/domain/javascript/javascriptSemanticTraversal.js +19 -1
  292. package/dist/domain/javascript/javascriptSemanticValues.js +47 -19
  293. package/dist/domain/javascript/javascriptSourceAnalysis.js +1 -0
  294. package/dist/domain/javascript/javascriptStaticAnalysis.js +29 -17
  295. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +8 -6
  296. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +49 -5
  297. package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +8 -4
  298. package/dist/domain/javascript/javascriptStaticAnalysisState.js +1 -0
  299. package/dist/domain/jeb/jebAnalysis.js +114 -0
  300. package/dist/domain/jsonShape.js +63 -52
  301. package/dist/domain/jsonValue.js +3 -0
  302. package/dist/domain/managed/managedApplicationGraph.js +37 -0
  303. package/dist/domain/managed/managedApplicationGraphCoverage.js +8 -2
  304. package/dist/domain/managed/managedApplicationGraphNodes.js +32 -22
  305. package/dist/domain/managed/managedArtifact.js +1 -0
  306. package/dist/domain/managed/managedInspectionEvidence.js +13 -0
  307. package/dist/domain/native/nativeAotPe.js +1408 -0
  308. package/dist/domain/native/nativeInstruction.js +21 -0
  309. package/dist/domain/native/nativeMetadataRecovery.js +79 -6
  310. package/dist/domain/native/peResources.js +94 -0
  311. package/dist/domain/nativeConvention.js +33 -0
  312. package/dist/domain/process/processCapture.js +91 -1
  313. package/dist/domain/process/processCaptureExample.js +24 -0
  314. package/dist/domain/process/processCaptureValidation.js +79 -0
  315. package/dist/domain/process/processScenario.js +59 -7
  316. package/dist/domain/propertyListKeys.js +3 -1
  317. package/dist/domain/referenceSourceGraph.js +25 -16
  318. package/dist/domain/referenceSourceImportParsing.js +6 -3
  319. package/dist/domain/referenceSourcePathIdentity.js +22 -0
  320. package/dist/domain/referenceSourceRequireBindings.js +137 -0
  321. package/dist/domain/webBundleAnalyzerInspection.js +14 -2
  322. package/dist/domain/webCaptureDiff.js +102 -4
  323. package/dist/domain/webScriptExportError.js +10 -4
  324. package/dist/domain/webScriptExportPlan.js +7 -13
  325. package/dist/domain/zipPackageFormat.js +4 -1
  326. package/dist/domain/zodCollectionSteps.js +24 -0
  327. package/dist/dotnet/ManagedArtifactInspector.js +55 -43
  328. package/dist/dotnet/ManagedDecodeBudget.js +80 -0
  329. package/dist/dotnet/ManagedMemberInspector.js +13 -6
  330. package/dist/dotnet/ManagedMemberInspectorCore.js +2 -2
  331. package/dist/dotnet/ManagedMemberInstructionDecoder.js +4 -2
  332. package/dist/dotnet/ManagedMemberRows.js +9 -4
  333. package/dist/dotnet/ManagedMetadataHeaps.js +15 -5
  334. package/dist/dotnet/ManagedMetadataInventoryRows.js +20 -11
  335. package/dist/dotnet/ManagedMetadataLayout.js +10 -4
  336. package/dist/dotnet/ManagedMethodBodyReader.js +8 -3
  337. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +3 -2
  338. package/dist/dotnet/ManagedNativeBoundaryInspector.js +49 -34
  339. package/dist/dotnet/ManagedPeReader.js +41 -25
  340. package/dist/dotnet/ManagedReaderFailure.js +2 -1
  341. package/dist/dotnet/ManagedStaticProvider.js +55 -24
  342. package/dist/evaluation/AgentEvaluationReport.js +9 -5
  343. package/dist/evaluation/CodexAgentEval.js +43 -13
  344. package/dist/evm/EvmoleFailures.js +0 -2
  345. package/dist/evm/EvmoleInterfaceProvider.js +67 -2
  346. package/dist/filesystem/OwnedDirectoryHandle.js +29 -0
  347. package/dist/filesystem/OwnedFileHandle.js +36 -0
  348. package/dist/filesystem/RegularFile.js +33 -1
  349. package/dist/filesystem/StableFileHash.js +46 -0
  350. package/dist/filesystem/readFileHandleChunks.js +26 -0
  351. package/dist/firmware/FirmwareCommand.js +25 -3
  352. package/dist/firmware/FirmwareFiles.js +23 -8
  353. package/dist/firmware/FirmwareProvider.js +156 -32
  354. package/dist/firmware/FirmwarePublication.js +24 -3
  355. package/dist/firmware/FirmwareRelease.js +1 -0
  356. package/dist/generatedPackageMetadata.js +2 -2
  357. package/dist/ghidra/GhidraAnalysisProfile.js +55 -4
  358. package/dist/ghidra/GhidraAnalysisSeeds.js +211 -0
  359. package/dist/ghidra/GhidraClient.js +76 -4
  360. package/dist/ghidra/GhidraDiagnostics.js +11 -8
  361. package/dist/ghidra/GhidraFunctionValues.js +26 -2
  362. package/dist/ghidra/GhidraInstallation.js +1 -1
  363. package/dist/ghidra/GhidraInventoryValues.js +23 -1
  364. package/dist/ghidra/GhidraLanguageCatalog.js +99 -0
  365. package/dist/ghidra/GhidraLauncher.js +80 -39
  366. package/dist/ghidra/GhidraLoadImageAttest.js +49 -2
  367. package/dist/ghidra/GhidraMipsProfile.js +79 -0
  368. package/dist/ghidra/GhidraProvider.js +57 -9
  369. package/dist/ghidra/GhidraProviderCapabilities.js +18 -8
  370. package/dist/ghidra/GhidraProviderClient.js +282 -21
  371. package/dist/ghidra/GhidraSessionValues.js +9 -2
  372. package/dist/hopper/HopperAnalysisProfile.js +2 -0
  373. package/dist/hopper/HopperClient.js +15 -6
  374. package/dist/hopper/HopperMachOImage.js +2 -0
  375. package/dist/hopper/HopperProvider.js +13 -2
  376. package/dist/ida/IdaOperationRunner.js +8 -2
  377. package/dist/ida/IdaProvider.js +7 -0
  378. package/dist/ida/IdaSessionClient.js +3 -1
  379. package/dist/ida/IdaWorkspace.js +4 -2
  380. package/dist/javascript/analysis/JavaScriptAnalysisTransfer.js +326 -0
  381. package/dist/javascript/analysis/JavaScriptAnalysisWorker.js +520 -0
  382. package/dist/javascript/analysis/JavaScriptAnalysisWorkerProtocol.js +63 -0
  383. package/dist/javascript/analysis/JavaScriptAnalysisWorkerSchemas.js +521 -0
  384. package/dist/javascript/analysis/JavaScriptAnalysisWorkerServer.js +116 -0
  385. package/dist/javascript/recovery/RecoveryFiles.js +18 -7
  386. package/dist/javascript/recovery/WakaruCommand.js +22 -9
  387. package/dist/javascript/recovery/WakaruExecution.js +11 -7
  388. package/dist/javascript/recovery/WakaruProvider.js +139 -16
  389. package/dist/javascript/recovery/WakaruPublication.js +14 -4
  390. package/dist/javascript/recovery/WakaruRelease.js +10 -3
  391. package/dist/javascript/recovery/WakaruReport.js +12 -7
  392. package/dist/javascript/recovery/WakaruVersion.js +24 -0
  393. package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -3
  394. package/dist/javascript/sourceMaps/SourceMapDecoder.js +63 -7
  395. package/dist/javascript/sourceMaps/SourceMapFormat.js +15 -4
  396. package/dist/jeb/JebMcpConnection.js +179 -0
  397. package/dist/jeb/JebMcpEndpoint.js +40 -0
  398. package/dist/jeb/JebProvider.js +299 -0
  399. package/dist/mcpDoctor.js +15 -6
  400. package/dist/native/AppleDispatchCoverage.js +25 -12
  401. package/dist/native/AppleDispatchMetadata.js +14 -7
  402. package/dist/native/AppleMachoFixups.js +71 -15
  403. package/dist/native/AppleMachoSelection.js +23 -3
  404. package/dist/native/NativeMacOSProvider.js +91 -16
  405. package/dist/native/NativeMachoInspection.js +11 -7
  406. package/dist/native/NativeUiHelperRuntime.js +6 -1
  407. package/dist/native/NativeUiObservation.js +4 -3
  408. package/dist/native/pe/PeResourceLayout.js +120 -0
  409. package/dist/native/pe/PeResourceParser.js +286 -0
  410. package/dist/native/pe/PeResourcesProvider.js +63 -0
  411. package/dist/process/BoundedFileBytes.js +30 -7
  412. package/dist/process/DarwinProcessRunTokenReader.js +8 -3
  413. package/dist/process/OwnedCommand.js +4 -3
  414. package/dist/process/ProcessOwnership.js +104 -112
  415. package/dist/process/ProcessOwnershipObservation.js +96 -39
  416. package/dist/process/ProcessOwnershipProcessTree.js +4 -4
  417. package/dist/process/ProcessRunTokenObservations.js +48 -0
  418. package/dist/process/ProviderDiagnosticRedaction.js +17 -0
  419. package/dist/process/ProviderProcess.js +4 -3
  420. package/dist/process/capture/FilesystemSnapshot.js +28 -4
  421. package/dist/process/capture/ProcessCaptureLifecycle.js +350 -59
  422. package/dist/process/capture/ProcessCaptureProgress.js +62 -0
  423. package/dist/process/capture/ProcessHarness.js +194 -26
  424. package/dist/process/capture/ProcessNormalization.js +3 -1
  425. package/dist/process/capture/ProcessScenarioRuntimeValidation.js +5 -2
  426. package/dist/process/capture/TerminalRenderer.js +24 -7
  427. package/dist/reference/ReferenceSourceReader.js +22 -5
  428. package/dist/reference/ReferenceSourceReaderEntries.js +114 -51
  429. package/dist/reference/ReferenceSourceReaderErrors.js +12 -0
  430. package/dist/reference/ReferenceSourceReaderFile.js +50 -10
  431. package/dist/reference/ReferenceSourceReaderValidate.js +4 -4
  432. package/dist/server/EvidenceMcpServer.js +36 -1
  433. package/dist/server/admittedToolOperation.js +9 -0
  434. package/dist/server/contractToolHandler.js +21 -0
  435. package/dist/server/createServer.js +97 -25
  436. package/dist/server/registerAdbTools.js +36 -0
  437. package/dist/server/registerAnalysisViewTool.js +4 -9
  438. package/dist/server/registerAndroidTools.js +3 -12
  439. package/dist/server/registerApktoolTools.js +14 -0
  440. package/dist/server/registerApplicationTools/compareExportShapes.js +4 -6
  441. package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
  442. package/dist/server/registerApplicationTools/compareVersions.js +3 -2
  443. package/dist/server/registerApplicationTools/coverage.js +3 -2
  444. package/dist/server/registerApplicationTools/obligationLedger.js +3 -2
  445. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -2
  446. package/dist/server/registerApplicationTools/traceFeature.js +3 -2
  447. package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
  448. package/dist/server/registerArtifactComparisonTool.js +5 -2
  449. package/dist/server/registerBinaryDiagnosticsTools.js +16 -4
  450. package/dist/server/registerBrowserScenarioTool.js +10 -7
  451. package/dist/server/registerBrowserTools.js +12 -9
  452. package/dist/server/registerBundleComparisonTool.js +16 -2
  453. package/dist/server/registerCloseLifecycleTool.js +32 -3
  454. package/dist/server/registerElectronTools.js +28 -10
  455. package/dist/server/registerEvmTools.js +4 -9
  456. package/dist/server/registerFirmwareTools.js +3 -11
  457. package/dist/server/registerFunctionComparisonTool.js +5 -2
  458. package/dist/server/registerJavaScriptRecoveryTool.js +4 -9
  459. package/dist/server/registerJavaScriptRuntimeObservationTools.js +9 -6
  460. package/dist/server/registerJebTools.js +16 -0
  461. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -6
  462. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -2
  463. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +3 -2
  464. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +3 -2
  465. package/dist/server/registerPeResourcesTool.js +9 -0
  466. package/dist/server/registerProcessComparisonTool.js +5 -2
  467. package/dist/server/registerRecordedCrashTools.js +4 -9
  468. package/dist/server/registerSessionRecordTools.js +2 -1
  469. package/dist/server/registerSessionTools.js +49 -18
  470. package/dist/server/registerWebModuleTool.js +4 -9
  471. package/dist/server/registerWebNetworkCaptureTool.js +4 -9
  472. package/dist/server/registerWebRuntimeTools.js +6 -5
  473. package/dist/server/registerWebScriptTool.js +6 -3
  474. package/dist/server/registerWebSourceLocationTool.js +4 -9
  475. package/dist/server/toolResult.js +21 -2
  476. package/dist/windows/WindowsPrivateRuntime.js +12 -5
  477. package/install.sh +7 -4
  478. package/licenses/nativeaot-parser-MIT.txt +28 -0
  479. package/native/windows/build/manifest.json +2 -2
  480. package/native/windows/build/rea-windows-x64.node +0 -0
  481. package/package.json +33 -5
  482. package/scripts/rea.mjs +16 -1
  483. package/skills/reverse-engineer-anything/SKILL.md +52 -51
  484. package/skills/reverse-engineer-anything/references/connection-and-recovery.md +127 -0
  485. package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -0
  486. package/skills/reverse-engineer-anything/references/javascript-applications.md +92 -13
  487. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +22 -1
@@ -1,5 +1,6 @@
1
1
  import { allowedSanitizedUrl, numberValue, recordValue, recordsValue, requiredRecord, cdpStringValue, } from "./CdpCaptureValues.js";
2
2
  import { exclusionReasonForUrl } from "./CdpCaptureEventHelpers.js";
3
+ import { createDocumentSvgAncestry, domSvgLink } from "./CdpCaptureDomSvg.js";
3
4
  /** Normalize every allowed frame, optionally selecting a leading frame. */
4
5
  export const captureFrames = (result, allowedOrigins, maximum, completeness) => {
5
6
  const root = recordValue(recordValue(result)?.frameTree);
@@ -114,21 +115,27 @@ export const captureDom = (result, allowedOrigins, input, completeness) => {
114
115
  ? documentNodes.attributes
115
116
  : [];
116
117
  const baseIndex = nodes.length;
118
+ const ancestry = createDocumentSvgAncestry({
119
+ nodeTypes,
120
+ nodeNames,
121
+ parents,
122
+ strings,
123
+ attributes,
124
+ });
117
125
  total += nodeTypes.length;
118
126
  for (let index = 0; index < nodeTypes.length; index += 1) {
119
127
  const attributeIndexes = numberArray(attributes[index]);
120
128
  const parent = Math.trunc(parents[index] ?? -1);
121
129
  const nodeIndex = nodes.length;
122
130
  const nodeName = indexedString(strings, nodeNames[index]);
131
+ const attributeNames = uniqueAttributeNames(attributeIndexes, strings);
123
132
  nodes.push({
124
133
  index: nodeIndex,
125
134
  parent_index: parent < 0 ? -1 : baseIndex + parent,
126
135
  node_type: Math.max(0, Math.trunc(nodeTypes[index] ?? 0)),
127
136
  node_name: nodeName,
128
137
  node_value_length: indexedString(strings, nodeValues[index]).length,
129
- attribute_names: attributeIndexes
130
- .filter((_value, attributeIndex) => attributeIndex % 2 === 0)
131
- .map((value) => indexedString(strings, value)),
138
+ attribute_names: attributeNames,
132
139
  });
133
140
  const metadata = domMetadata({
134
141
  strings,
@@ -139,6 +146,7 @@ export const captureDom = (result, allowedOrigins, input, completeness) => {
139
146
  nodeIndex,
140
147
  nodeName,
141
148
  allowedOrigins,
149
+ ...domSvgLink(ancestry, index),
142
150
  });
143
151
  for (const url of metadata.urls) {
144
152
  urls.push(url);
@@ -261,23 +269,49 @@ const indexedString = (strings, index) => {
261
269
  const integer = numberValue(index);
262
270
  return integer === undefined ? "" : (strings[Math.trunc(integer)] ?? "");
263
271
  };
272
+ const uniqueAttributeNames = (attributeIndexes, strings) => {
273
+ const names = [];
274
+ const seen = new Set();
275
+ for (let index = 0; index < attributeIndexes.length; index += 2) {
276
+ const name = indexedString(strings, attributeIndexes[index]);
277
+ if (seen.has(name))
278
+ continue;
279
+ seen.add(name);
280
+ names.push(name);
281
+ }
282
+ return names;
283
+ };
264
284
  const numberArray = (value) => Array.isArray(value)
265
285
  ? value.flatMap((item) => {
266
286
  const number = numberValue(item);
267
287
  return number === undefined ? [] : [number];
268
288
  })
269
289
  : [];
290
+ // Chrome reads an SVG XLink href only when href itself is absent, and an
291
+ // empty href still wins. HTML keeps the literal attribute name `xlink:href`.
292
+ // XML uses any prefix bound to the XLink namespace. Both are stored as href.
293
+ const hrefAttributeValue = (pairs, attribute, options) => {
294
+ const declared = pairs.get(attribute);
295
+ if (declared !== undefined)
296
+ return declared;
297
+ if (attribute !== "href" || !options.svgElement)
298
+ return undefined;
299
+ return options.xmlDocument ? options.xlinkHref : pairs.get("xlink:href");
300
+ };
270
301
  const domMetadata = (options) => {
271
302
  const { strings, attributes, baseUrl, documentUrl, nodeIndex, nodeName, allowedOrigins, } = options;
272
303
  const pairs = new Map();
273
304
  for (let index = 0; index + 1 < attributes.length; index += 2) {
274
- const name = indexedString(strings, attributes[index]).toLowerCase();
305
+ // Chrome already folds HTML names; SVG/XML names remain case-sensitive.
306
+ const name = indexedString(strings, attributes[index]);
275
307
  const value = indexedString(strings, attributes[index + 1]);
276
- pairs.set(name, value);
308
+ // HTML keeps the first declaration. A later repeat must not move dom_urls.
309
+ if (!pairs.has(name))
310
+ pairs.set(name, value);
277
311
  }
278
312
  const urls = [];
279
313
  for (const attribute of domUrlAttributes) {
280
- const value = pairs.get(attribute);
314
+ const value = hrefAttributeValue(pairs, attribute, options);
281
315
  if (value === undefined)
282
316
  continue;
283
317
  const tagName = nodeName.toLowerCase();
@@ -0,0 +1,210 @@
1
+ import { numberValue } from "./CdpCaptureValues.js";
2
+ const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
3
+ const XLINK_NAMESPACE = "http://www.w3.org/1999/xlink";
4
+ const UNRESOLVED = {
5
+ svgElement: false,
6
+ xlinkHref: undefined,
7
+ };
8
+ const stringAt = (strings, index) => {
9
+ const integer = numberValue(index);
10
+ return integer === undefined ? "" : (strings[Math.trunc(integer)] ?? "");
11
+ };
12
+ const numberArray = (value) => Array.isArray(value)
13
+ ? value.flatMap((item) => {
14
+ const number = numberValue(item);
15
+ return number === undefined ? [] : [number];
16
+ })
17
+ : [];
18
+ // DOMSnapshot has no namespace URI. HTML documents use uppercase `HTML` and
19
+ // the parser's local names. XML documents preserve prefixed names and xmlns
20
+ // declarations, including those on standalone SVG roots.
21
+ const xmlDocument = (nodes) => {
22
+ const documentIndex = nodes.nodeTypes.findIndex((nodeType) => Math.trunc(nodeType) === 9);
23
+ if (documentIndex < 0)
24
+ return false;
25
+ for (let index = 0; index < nodes.nodeTypes.length; index += 1) {
26
+ if (Math.trunc(nodes.nodeTypes[index] ?? 0) !== 1)
27
+ continue;
28
+ if (Math.trunc(nodes.parents[index] ?? -1) !== documentIndex)
29
+ continue;
30
+ const name = stringAt(nodes.strings, nodes.nodeNames[index]);
31
+ if (name === "HTML")
32
+ return false;
33
+ if (name === "html" || name.includes(":"))
34
+ return true;
35
+ // Explicit namespaces also identify standalone SVG and other XML roots.
36
+ // Namespace-free synthetic snapshots retain the legacy HTML behavior.
37
+ const attributes = numberArray(nodes.attributes[index]);
38
+ return attributes.some((value, offset) => offset % 2 === 0 &&
39
+ xmlnsPrefix(stringAt(nodes.strings, value)) !== undefined);
40
+ }
41
+ return false;
42
+ };
43
+ export const createDocumentSvgAncestry = (nodes) => {
44
+ const xml = xmlDocument(nodes);
45
+ return {
46
+ xml,
47
+ nodes,
48
+ svgContexts: new Map(),
49
+ xmlLinks: xml ? resolveXmlElements(nodes) : new Map(),
50
+ };
51
+ };
52
+ export const domSvgLink = (ancestry, index) => {
53
+ if (!ancestry.xml) {
54
+ return {
55
+ svgElement: elementInSvgContext(index, ancestry.nodes, ancestry.svgContexts),
56
+ xmlDocument: false,
57
+ xlinkHref: undefined,
58
+ };
59
+ }
60
+ const resolved = ancestry.xmlLinks.get(index) ?? UNRESOLVED;
61
+ return {
62
+ svgElement: resolved.svgElement,
63
+ xmlDocument: true,
64
+ xlinkHref: resolved.xlinkHref,
65
+ };
66
+ };
67
+ // Chrome's HTML parser records SVG local names (`svg`, `foreignObject`).
68
+ // Descendants of foreignObject are HTML until a nested `svg`.
69
+ const elementInSvgContext = (index, nodes, contexts) => {
70
+ let current = index;
71
+ const seen = new Set();
72
+ let inSvg = false;
73
+ while (current >= 0 &&
74
+ current < nodes.nodeNames.length &&
75
+ !seen.has(current)) {
76
+ const cached = contexts.get(current);
77
+ if (cached !== undefined) {
78
+ inSvg = cached;
79
+ break;
80
+ }
81
+ seen.add(current);
82
+ if (stringAt(nodes.strings, nodes.nodeNames[current]) === "svg") {
83
+ inSvg = true;
84
+ break;
85
+ }
86
+ const parent = Math.trunc(nodes.parents[current] ?? -1);
87
+ if (parent < 0 || parent === current)
88
+ break;
89
+ if (stringAt(nodes.strings, nodes.nodeNames[parent]) === "foreignObject")
90
+ break;
91
+ current = parent;
92
+ }
93
+ // Cache the entire examined chain, including forward references and cycles,
94
+ // so shared ancestors are examined once per document.
95
+ for (const node of seen)
96
+ contexts.set(node, inSvg);
97
+ return inSvg;
98
+ };
99
+ // Walk parent-before-child with one mutable namespace environment. Restore
100
+ // declarations on exit so siblings retain their own scope. Only declarations
101
+ // on the active path are retained, rather than cumulative maps at every node.
102
+ const resolveXmlElements = (nodes) => {
103
+ const children = new Map();
104
+ const pending = [];
105
+ for (let node = 0; node < nodes.nodeNames.length; node += 1) {
106
+ const parent = Math.trunc(nodes.parents[node] ?? -1);
107
+ if (parent < 0)
108
+ pending.push({ node });
109
+ else if (parent < nodes.nodeNames.length && parent !== node) {
110
+ const siblings = children.get(parent);
111
+ if (siblings === undefined)
112
+ children.set(parent, [node]);
113
+ else
114
+ siblings.push(node);
115
+ }
116
+ }
117
+ const bindings = new Map();
118
+ const resolved = new Map();
119
+ while (pending.length > 0) {
120
+ const step = pending.pop();
121
+ if (step === undefined)
122
+ break;
123
+ if ("restore" in step) {
124
+ for (const { prefix, previous } of step.restore) {
125
+ if (previous === undefined)
126
+ bindings.delete(prefix);
127
+ else
128
+ bindings.set(prefix, previous);
129
+ }
130
+ continue;
131
+ }
132
+ const { node } = step;
133
+ const attributes = numberArray(nodes.attributes[node]);
134
+ const restore = applyDeclarations(bindings, attributes, nodes.strings);
135
+ const svgElement = Math.trunc(nodes.nodeTypes[node] ?? 0) === 1 &&
136
+ elementNamespace(stringAt(nodes.strings, nodes.nodeNames[node]), bindings) === SVG_NAMESPACE;
137
+ resolved.set(node, {
138
+ svgElement,
139
+ xlinkHref: svgElement
140
+ ? xlinkHrefValue(attributes, nodes.strings, bindings)
141
+ : undefined,
142
+ });
143
+ pending.push({ restore });
144
+ for (const child of children.get(node) ?? [])
145
+ pending.push({ node: child });
146
+ }
147
+ // Cycles (including self-parents) and dangling chains cannot reach a root,
148
+ // so remain unresolved instead of deriving URLs from an invalid ancestry.
149
+ return resolved;
150
+ };
151
+ const applyDeclarations = (bindings, attributes, strings) => {
152
+ const restore = [];
153
+ const seen = new Set();
154
+ for (let index = 0; index + 1 < attributes.length; index += 2) {
155
+ const prefix = xmlnsPrefix(stringAt(strings, attributes[index]));
156
+ if (prefix === undefined || seen.has(prefix))
157
+ continue;
158
+ seen.add(prefix);
159
+ restore.push({ prefix, previous: bindings.get(prefix) });
160
+ const value = stringAt(strings, attributes[index + 1]);
161
+ if (value.length === 0)
162
+ bindings.delete(prefix);
163
+ else
164
+ bindings.set(prefix, value);
165
+ }
166
+ return restore;
167
+ };
168
+ const xmlnsPrefix = (name) => {
169
+ if (name === "xmlns")
170
+ return "";
171
+ if (!name.startsWith("xmlns:"))
172
+ return undefined;
173
+ const prefix = name.slice("xmlns:".length);
174
+ if (prefix.length === 0 || prefix === "xmlns" || prefix.includes(":"))
175
+ return undefined;
176
+ return prefix;
177
+ };
178
+ const elementNamespace = (nodeName, bindings) => {
179
+ const colon = nodeName.indexOf(":");
180
+ if (colon < 0)
181
+ return bindings.get("") ?? "";
182
+ const prefix = nodeName.slice(0, colon);
183
+ const local = nodeName.slice(colon + 1);
184
+ if (prefix.length === 0 ||
185
+ local.length === 0 ||
186
+ local.includes(":") ||
187
+ prefix === "xmlns")
188
+ return "";
189
+ return bindings.get(prefix) ?? "";
190
+ };
191
+ // First prefixed href bound to the XLink namespace. Duplicate names keep the
192
+ // earlier value. Plain href is applied by the caller and wins even when empty.
193
+ const xlinkHrefValue = (attributes, strings, bindings) => {
194
+ const seen = new Set();
195
+ for (let index = 0; index + 1 < attributes.length; index += 2) {
196
+ const name = stringAt(strings, attributes[index]);
197
+ if (seen.has(name))
198
+ continue;
199
+ seen.add(name);
200
+ const colon = name.indexOf(":");
201
+ if (colon <= 0)
202
+ continue;
203
+ const prefix = name.slice(0, colon);
204
+ const local = name.slice(colon + 1);
205
+ if (local !== "href" || bindings.get(prefix) !== XLINK_NAMESPACE)
206
+ continue;
207
+ return stringAt(strings, attributes[index + 1]);
208
+ }
209
+ return undefined;
210
+ };
@@ -15,8 +15,7 @@ export const ingestResponseBodyShape = (state, requestId, value) => {
15
15
  invalidResponseBodyShape(state, requestId);
16
16
  return;
17
17
  }
18
- const inferred = inferBodyShape(decoded);
19
- updateResponseBodyShape(state, requestId, inferred.shape);
18
+ updateResponseBodyShape(state, requestId, inferJsonShape(decoded));
20
19
  };
21
20
  export const requestBodyShape = (state, request) => {
22
21
  if (!state.input.include_json_body_shapes)
@@ -24,10 +23,10 @@ export const requestBodyShape = (state, request) => {
24
23
  const body = cdpStringValue(request.postData);
25
24
  if (!isJsonContentType(recordValue(request.headers)) || body === undefined)
26
25
  return { status: "unavailable", request: null, response: null };
27
- const inferred = inferBodyShape(body);
26
+ const shape = inferJsonShape(body);
28
27
  return {
29
- status: inferred.shape === null ? "unavailable" : "included",
30
- request: inferred.shape,
28
+ status: shape === null ? "unavailable" : "included",
29
+ request: shape,
31
30
  response: null,
32
31
  };
33
32
  };
@@ -46,9 +45,6 @@ export const updateResponseBodyShape = (state, requestId, response) => {
46
45
  body_shapes: { status, request, response },
47
46
  });
48
47
  };
49
- const inferBodyShape = (text) => {
50
- return { shape: inferJsonShape(text) };
51
- };
52
48
  const invalidResponseBodyShape = (state, requestId) => {
53
49
  updateResponseBodyShape(state, requestId, null);
54
50
  state.completeness.exclude("json_body_shapes", "invalid_protocol_value");
@@ -1,3 +1,4 @@
1
+ import { sanitizeBrowserUrl } from "../domain/browserObservation.js";
1
2
  import { inferJsonShape } from "../domain/jsonShape.js";
2
3
  import { safeResponseMetadata } from "./CdpSafeMetadata.js";
3
4
  import { allowedSanitizedUrl, isHttpUrl, numberValue, recordValue, recordsValue, scriptMetadataValues, cdpStringValue, } from "./CdpCaptureValues.js";
@@ -13,6 +14,7 @@ export const handleExecutionContextCreated = (state, params) => {
13
14
  frameId === undefined)
14
15
  return;
15
16
  const key = String(identifier);
17
+ // New contexts may reuse an id. Scripts already parsed keep the frame stored on them.
16
18
  state.executionContextFrames.set(key, frameId);
17
19
  };
18
20
  export const handleExecutionContextDestroyed = (state, params) => {
@@ -39,6 +41,7 @@ export const handleScriptParsed = (state, params) => {
39
41
  state.completeness.exclude("scripts", exclusionReasonForUrl(rawUrl));
40
42
  return;
41
43
  }
44
+ const executionContext = executionContextKey(params.executionContextId);
42
45
  const baseScript = {
43
46
  scriptId,
44
47
  rawUrl,
@@ -46,7 +49,10 @@ export const handleScriptParsed = (state, params) => {
46
49
  origin: sanitized.origin,
47
50
  ...scriptMetadataValues(params),
48
51
  language: cdpStringValue(params.scriptLanguage) ?? null,
49
- executionContextKey: executionContextKey(params.executionContextId),
52
+ executionContextKey: executionContext,
53
+ frameId: executionContext === null
54
+ ? null
55
+ : (state.executionContextFrames.get(executionContext) ?? null),
50
56
  };
51
57
  const baseBytes = scriptMetadataStringBytes(baseScript);
52
58
  const sourceMapDeclared = typeof params.sourceMapURL === "string" && params.sourceMapURL.length > 0;
@@ -79,7 +85,8 @@ const scriptMetadataStringBytes = (script) => stringByteLength(script.scriptId)
79
85
  stringByteLength(script.origin) +
80
86
  stringByteLength(script.hash) +
81
87
  stringByteLength(script.language) +
82
- stringByteLength(script.executionContextKey);
88
+ stringByteLength(script.executionContextKey) +
89
+ stringByteLength(script.frameId);
83
90
  const stringByteLength = (value) => value === null ? 0 : Buffer.byteLength(value, "utf8");
84
91
  const sourceMapForScript = (value, scriptUrl, state, remainingBytes) => {
85
92
  const declaredUrl = cdpStringValue(value);
@@ -350,8 +357,10 @@ const captureConsoleText = (state, arguments_) => {
350
357
  };
351
358
  export const handleWebSocketFrame = (state, params, direction) => {
352
359
  const requestId = cdpStringValue(params.requestId);
353
- if (requestId === undefined ||
354
- (!state.network.has(requestId) && !state.allowedWebSockets.has(requestId)))
360
+ if (requestId === undefined)
361
+ return;
362
+ const connection = state.webSocketConnectionsById.get(requestId);
363
+ if (connection === undefined)
355
364
  return;
356
365
  const response = recordValue(params.response);
357
366
  const payload = cdpStringValue(response?.payloadData) ?? "";
@@ -359,11 +368,10 @@ export const handleWebSocketFrame = (state, params, direction) => {
359
368
  const decoded = opcode === 1 ? undefined : decodeBase64(payload);
360
369
  if (opcode !== 1 && decoded === undefined)
361
370
  state.completeness.exclude("websocket_frames", "invalid_protocol_value");
362
- state.websockets.push({
363
- request_id: requestId,
371
+ connection.events.push({
364
372
  direction,
365
373
  opcode,
366
- payload_bytes: opcode === 1 ? Buffer.byteLength(payload) : (decoded?.byteLength ?? 0),
374
+ payload_bytes: opcode === 1 ? Buffer.byteLength(payload) : (decoded?.byteLength ?? null),
367
375
  payload_shape: captureWebSocketShape(state, payload, opcode),
368
376
  });
369
377
  };
@@ -389,9 +397,10 @@ export const handleWebSocketCreated = (state, params) => {
389
397
  state.completeness.exclude("websocket_connections", "invalid_protocol_value");
390
398
  return;
391
399
  }
400
+ const sourceUrl = sanitizeBrowserUrl(rawUrl).url;
392
401
  let parsed;
393
402
  try {
394
- parsed = new URL(rawUrl);
403
+ parsed = new URL(sourceUrl);
395
404
  }
396
405
  catch (cause) {
397
406
  // Unparseable URLs are recorded as unsupported, not as failures.
@@ -411,7 +420,15 @@ export const handleWebSocketCreated = (state, params) => {
411
420
  state.completeness.exclude("websocket_connections", "disallowed_origin");
412
421
  return;
413
422
  }
414
- state.allowedWebSockets.add(requestId);
423
+ if (state.webSocketConnectionsById.has(requestId)) {
424
+ state.completeness.exclude("websocket_connections", "invalid_protocol_value");
425
+ return;
426
+ }
427
+ state.webSocketConnectionsById.set(requestId, {
428
+ request_id: requestId,
429
+ url: sourceUrl,
430
+ events: [],
431
+ });
415
432
  };
416
433
  export const handleFrameNavigated = (state, params) => {
417
434
  const frame = recordValue(params.frame);
@@ -16,9 +16,8 @@ export class CdpCaptureEvents {
16
16
  network = new Map();
17
17
  networkRequestTimestamps = new Map();
18
18
  malformedRedirectRequestIds = new Set();
19
- allowedWebSockets = new Set();
19
+ webSocketConnectionsById = new Map();
20
20
  console = [];
21
- websockets = [];
22
21
  responseMetadata = [];
23
22
  agentHints = [];
24
23
  completeness = new CdpCaptureCompleteness([
@@ -54,9 +53,8 @@ export class CdpCaptureEvents {
54
53
  this.network.clear();
55
54
  this.networkRequestTimestamps.clear();
56
55
  this.malformedRedirectRequestIds.clear();
57
- this.allowedWebSockets.clear();
56
+ this.webSocketConnectionsById.clear();
58
57
  this.console.length = 0;
59
- this.websockets.length = 0;
60
58
  this.responseMetadata.length = 0;
61
59
  this.agentHints.length = 0;
62
60
  this.completeness.reset();
@@ -136,11 +134,8 @@ export class CdpCaptureEvents {
136
134
  }
137
135
  /** Resolve a transient execution context to one already authorized frame. */
138
136
  frameForScript(script, allowedFrameIds) {
139
- if (script.executionContextKey === null)
140
- return null;
141
- const frameId = this.executionContextFrames.get(script.executionContextKey);
142
- return frameId !== undefined && allowedFrameIds.has(frameId)
143
- ? frameId
137
+ return script.frameId !== null && allowedFrameIds.has(script.frameId)
138
+ ? script.frameId
144
139
  : null;
145
140
  }
146
141
  responseBodyRequestIds() {
@@ -5,6 +5,10 @@ import { BrowserObservationError } from "../domain/browserObservationError.js";
5
5
  import { CdpCommandRejection } from "./CdpCommandRejection.js";
6
6
  import {} from "../domain/browserObservationErrors.js";
7
7
  import { safeParseJson } from "../domain/safeJson.js";
8
+ import { WEB_RUNTIME_LIMITS } from "../domain/webRuntime.js";
9
+ // ws currently stores maxPayload as a signed 32-bit integer. Larger values can
10
+ // wrap to a negative number, which disables its limit check.
11
+ const MAX_WEBSOCKET_PAYLOAD_BYTES = 0x7fff_ffff;
8
12
  /** Correlated JSON-RPC transport for one CDP target operation. */
9
13
  export class CdpConnection {
10
14
  socket;
@@ -16,6 +20,7 @@ export class CdpConnection {
16
20
  #protocolFailureListeners = new Set();
17
21
  #nextId = 1;
18
22
  #closed = false;
23
+ #closePromise;
19
24
  #protocolFailed = false;
20
25
  #transportFailure = "disconnected";
21
26
  constructor(socket, operation, maxPayloadBytes) {
@@ -32,13 +37,20 @@ export class CdpConnection {
32
37
  static async connect(url, operation, signal, limits) {
33
38
  if (signal?.aborted === true)
34
39
  throw new AnalysisCancelledError(operation);
40
+ const maxPayloadBytes = limits === undefined
41
+ ? WEB_RUNTIME_LIMITS.protocolBytes
42
+ : limits.maxPayloadBytes;
43
+ if (!Number.isSafeInteger(maxPayloadBytes) ||
44
+ maxPayloadBytes <= 0 ||
45
+ maxPayloadBytes > MAX_WEBSOCKET_PAYLOAD_BYTES)
46
+ throw new RangeError(`CDP maxPayloadBytes must be a positive safe integer no greater than ${String(MAX_WEBSOCKET_PAYLOAD_BYTES)}.`);
35
47
  const socket = new WebSocket(url, {
36
48
  handshakeTimeout: 0,
37
- maxPayload: limits?.maxPayloadBytes ?? 0,
49
+ maxPayload: maxPayloadBytes,
38
50
  perMessageDeflate: false,
39
51
  });
40
52
  await waitForOpen(socket, operation, signal);
41
- return new CdpConnection(socket, operation, limits?.maxPayloadBytes ?? 0);
53
+ return new CdpConnection(socket, operation, maxPayloadBytes);
42
54
  }
43
55
  /** Subscribe to validated CDP event envelopes. */
44
56
  onEvent(listener) {
@@ -109,9 +121,14 @@ export class CdpConnection {
109
121
  });
110
122
  }
111
123
  /** Close only REA's socket; never close the browser or selected page. */
112
- async close() {
113
- if (this.#closed)
114
- return;
124
+ close() {
125
+ this.#closePromise ??= this.#closeTransport().catch((cause) => {
126
+ this.#closePromise = undefined;
127
+ throw cause;
128
+ });
129
+ return this.#closePromise;
130
+ }
131
+ async #closeTransport() {
115
132
  this.#closed = true;
116
133
  this.#failPending("disconnected");
117
134
  if (this.socket.readyState === WebSocket.CLOSED)
@@ -188,7 +188,7 @@ const normalizedInspection = (state, captured) => ({
188
188
  resources: [...captured.resources],
189
189
  network: {
190
190
  requests: [...state.events.network.values()],
191
- websocket_events: [...state.events.websockets],
191
+ websocket_connections: [...state.events.webSocketConnectionsById.values()],
192
192
  coverage_started_at: state.startedAt,
193
193
  prior_activity_available: false,
194
194
  },
@@ -20,43 +20,39 @@ export const openCdpTargetSession = async (discovery, target, operation, signal,
20
20
  /** Disable enabled domains, detach browser sessions, and close REA's socket. */
21
21
  export const closeCdpTargetSession = async (targetSession, enabledDomains, signal) => {
22
22
  const { connection, sessionId } = targetSession;
23
- for (const [index, domain] of enabledDomains.entries()) {
24
- if (signal?.aborted === true) {
25
- await closeCancelledTargetSession(targetSession, enabledDomains.slice(index));
26
- return;
27
- }
28
- try {
29
- await connection.send(`${domain}.disable`, {}, sessionId, signal);
30
- }
31
- catch (cause) {
32
- // best-effort cleanup: domain disable continues to detach/close boundary.
33
- void cause;
34
- }
35
- }
36
- if (signal?.aborted === true) {
37
- await closeCancelledTargetSession(targetSession, []);
38
- return;
39
- }
40
- if (sessionId !== undefined)
41
- try {
42
- await connection.send("Target.detachFromTarget", { sessionId }, undefined, signal);
43
- }
44
- catch (cause) {
45
- // best-effort cleanup: closing REA's socket is the final cleanup boundary.
46
- void cause;
47
- }
48
- await connection.close();
49
- };
50
- const closeCancelledTargetSession = async ({ connection, sessionId }, enabledDomains) => {
51
- const commands = enabledDomains.map((domain) => connection.send(`${domain}.disable`, {}, sessionId));
52
- if (sessionId !== undefined)
53
- commands.push(connection.send("Target.detachFromTarget", { sessionId }));
54
- const settled = Promise.allSettled(commands);
23
+ const cleanup = new AbortController();
24
+ const domainSignal = signal === undefined
25
+ ? cleanup.signal
26
+ : AbortSignal.any([cleanup.signal, signal]);
27
+ const timeout = setTimeout(() => cleanup.abort(), 1_000);
28
+ timeout.unref();
55
29
  try {
56
- await connection.close();
30
+ if (signal?.aborted !== true) {
31
+ for (const domain of enabledDomains) {
32
+ if (domainSignal.aborted)
33
+ break;
34
+ try {
35
+ await connection.send(`${domain}.disable`, {}, sessionId, domainSignal);
36
+ }
37
+ catch {
38
+ // Best-effort domain cleanup; transport close is the definitive boundary.
39
+ }
40
+ }
41
+ }
42
+ // Cancellation skips optional domain shutdown but still releases the
43
+ // attached session using its independent, bounded cleanup signal.
44
+ if (!cleanup.signal.aborted && sessionId !== undefined)
45
+ try {
46
+ await connection.send("Target.detachFromTarget", { sessionId }, undefined, cleanup.signal);
47
+ }
48
+ catch {
49
+ // Best-effort detach; transport close is the definitive boundary.
50
+ }
57
51
  }
58
52
  finally {
59
- await settled;
53
+ clearTimeout(timeout);
54
+ cleanup.abort();
55
+ await connection.close();
60
56
  }
61
57
  };
62
58
  const attachedSessionId = (value, operation) => {