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
@@ -223,24 +223,29 @@ const assertStableAuthorizedFrame = async (context, initialUrl, origins) => {
223
223
  };
224
224
  const ingestWebMcpEvent = (options) => {
225
225
  const { event, input, frames, tools, completeness, transientFrames, resolvedTransientFrames, } = options;
226
+ if (event.method !== "WebMCP.toolsAdded" &&
227
+ event.method !== "WebMCP.toolsRemoved")
228
+ return;
226
229
  const params = recordValue(event.params);
227
- if (params === undefined)
230
+ if (params === undefined) {
231
+ completeness.exclude("webmcp_tools", "invalid_protocol_value");
228
232
  return;
233
+ }
229
234
  if (event.method === "WebMCP.toolsRemoved") {
230
- for (const removed of recordsValue(params.tools)) {
235
+ for (const removed of webMcpEventTools(params.tools, completeness)) {
231
236
  const name = cdpStringValue(removed.name);
232
237
  const frameId = cdpStringValue(removed.frameId);
233
- if (name === undefined || frameId === undefined)
238
+ if (name === undefined || frameId === undefined) {
239
+ completeness.exclude("webmcp_tools", "invalid_protocol_value");
234
240
  continue;
241
+ }
235
242
  for (const [key, tool] of tools)
236
243
  if (tool.name === name && tool.frame_id === frameId)
237
244
  tools.delete(key);
238
245
  }
239
246
  return;
240
247
  }
241
- if (event.method !== "WebMCP.toolsAdded")
242
- return;
243
- for (const declared of recordsValue(params.tools)) {
248
+ for (const declared of webMcpEventTools(params.tools, completeness)) {
244
249
  const frameId = cdpStringValue(declared.frameId);
245
250
  if (frameId !== undefined && transientFrames.has(frameId)) {
246
251
  if (!resolvedTransientFrames.has(frameId))
@@ -254,14 +259,31 @@ const ingestWebMcpEvent = (options) => {
254
259
  tools.set(normalized.tool_key, normalized);
255
260
  }
256
261
  };
262
+ const webMcpEventTools = (value, completeness) => {
263
+ if (!Array.isArray(value)) {
264
+ completeness.exclude("webmcp_tools", "invalid_protocol_value");
265
+ return [];
266
+ }
267
+ const records = [];
268
+ for (const item of value) {
269
+ const record = recordValue(item);
270
+ if (record === undefined) {
271
+ completeness.exclude("webmcp_tools", "invalid_protocol_value");
272
+ continue;
273
+ }
274
+ records.push(record);
275
+ }
276
+ return records;
277
+ };
257
278
  const normalizeTool = (value, input, frames, completeness) => {
258
279
  const frameId = cdpStringValue(value.frameId);
259
280
  const name = cdpStringValue(value.name);
260
281
  const frame = frameId === undefined ? undefined : frames.get(frameId);
261
- if (frameId === undefined ||
262
- name === undefined ||
263
- frame?.origin === null ||
264
- frame === undefined) {
282
+ if (frameId === undefined || name === undefined) {
283
+ completeness.exclude("webmcp_tools", "invalid_protocol_value");
284
+ return undefined;
285
+ }
286
+ if (frame?.origin === null || frame === undefined) {
265
287
  completeness.exclude("webmcp_tools", "out_of_target_scope");
266
288
  return undefined;
267
289
  }
@@ -1,6 +1,7 @@
1
- import { realpath, stat } from "node:fs/promises";
2
- import { isAbsolute } from "node:path";
1
+ import { open, realpath, stat } from "node:fs/promises";
2
+ import { isAbsolute, join, sep } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
+ import { admitAsarHeader, MAX_ASAR_HEADER_BYTES, } from "../artifacts/AsarHeader.js";
4
5
  /** Resolve one local file URL while rejecting remote hosts and encoded separators. */
5
6
  export const authorizedElectronFile = async (value) => {
6
7
  if (/%(?:2f|5c)/iu.test(value))
@@ -30,16 +31,105 @@ export const authorizedElectronFile = async (value) => {
30
31
  }
31
32
  if (!isAbsolute(path) || path.includes("\0"))
32
33
  return undefined;
33
- let canonical;
34
34
  try {
35
- if (!(await stat(path)).isFile())
36
- return undefined;
37
- canonical = await realpath(path);
35
+ if ((await stat(path)).isFile())
36
+ return await realpath(path);
38
37
  }
39
38
  catch (cause) {
40
- // Missing or unreadable files cannot authorize a local file.
39
+ // Electron serves packaged pages from inside app.asar, which the host
40
+ // filesystem cannot stat; resolve those through the archive header below.
41
41
  void cause;
42
- return undefined;
43
42
  }
44
- return canonical;
43
+ return await authorizedAsarMember(path);
44
+ };
45
+ /**
46
+ * Resolve `<archive>.asar/<member>` the way Electron's file protocol does: the
47
+ * first `.asar` path component that is a regular file is the archive, and the
48
+ * remainder must name a regular file in its header (packed or unpacked).
49
+ */
50
+ const authorizedAsarMember = async (path) => {
51
+ const segments = path.split(sep);
52
+ for (let index = 1; index < segments.length - 1; index += 1) {
53
+ if (!(segments[index] ?? "").toLowerCase().endsWith(".asar"))
54
+ continue;
55
+ const archive = segments.slice(0, index + 1).join(sep);
56
+ const member = segments.slice(index + 1);
57
+ if (member.some((part) => part === "" || part === "." || part === ".."))
58
+ return undefined;
59
+ try {
60
+ const metadata = await stat(archive);
61
+ if (!metadata.isFile())
62
+ continue;
63
+ const canonical = await realpath(archive);
64
+ const files = await asarFiles(canonical, metadata);
65
+ return isAsarRegularFile(files, member)
66
+ ? join(canonical, ...member)
67
+ : undefined;
68
+ }
69
+ catch (cause) {
70
+ // An unreadable or malformed archive cannot authorize its members.
71
+ void cause;
72
+ return undefined;
73
+ }
74
+ }
75
+ return undefined;
76
+ };
77
+ // This is a retained-memory budget for JSON headers, shared across all archives.
78
+ const MAX_CACHED_HEADERS = 8;
79
+ const headerCache = new Map();
80
+ const archiveIdentity = (metadata) => `${String(metadata.dev)}:${String(metadata.ino)}:${String(metadata.size)}:${String(metadata.mtimeMs)}`;
81
+ /** Read the two Chromium pickle headers on one handle before allocating JSON. */
82
+ const asarFiles = async (archive, metadata) => {
83
+ const identity = archiveIdentity(metadata);
84
+ const cached = headerCache.get(archive);
85
+ if (cached?.identity === identity)
86
+ return cached.files;
87
+ const handle = await open(archive, "r");
88
+ let files;
89
+ let jsonBytes;
90
+ try {
91
+ const opened = await handle.stat();
92
+ if (!opened.isFile() || archiveIdentity(opened) !== identity)
93
+ throw new Error("ASAR identity changed before header read");
94
+ const admitted = await admitAsarHeader(handle);
95
+ jsonBytes = admitted.jsonBytes;
96
+ const json = Buffer.alloc(jsonBytes);
97
+ let offset = 0;
98
+ while (offset < json.length) {
99
+ const part = await handle.read(json, offset, json.length - offset, 16 + offset);
100
+ if (part.bytesRead === 0)
101
+ throw new Error("Truncated ASAR JSON header");
102
+ offset += part.bytesRead;
103
+ }
104
+ if (archiveIdentity(await handle.stat()) !== identity)
105
+ throw new Error("ASAR identity changed during header read");
106
+ const parsed = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(json));
107
+ if (!isRecord(parsed) || !isRecord(parsed.files))
108
+ throw new Error("ASAR header has no file tree");
109
+ files = parsed.files;
110
+ }
111
+ finally {
112
+ await handle.close();
113
+ }
114
+ headerCache.delete(archive);
115
+ headerCache.set(archive, { identity, files, bytes: jsonBytes });
116
+ const retainedBytes = () => [...headerCache.values()].reduce((sum, entry) => sum + entry.bytes, 0);
117
+ while (headerCache.size > MAX_CACHED_HEADERS ||
118
+ retainedBytes() > MAX_ASAR_HEADER_BYTES)
119
+ headerCache.delete(headerCache.keys().next().value ?? archive);
120
+ return files;
121
+ };
122
+ const isAsarRegularFile = (files, member) => {
123
+ let node = { files };
124
+ for (const part of member) {
125
+ const children = isRecord(node) ? node.files : undefined;
126
+ if (!isRecord(children) || !Object.hasOwn(children, part))
127
+ return false;
128
+ node = children[part];
129
+ }
130
+ return (isRecord(node) &&
131
+ typeof node.size === "number" &&
132
+ !("files" in node) &&
133
+ !("link" in node));
45
134
  };
135
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -135,11 +135,14 @@ const globalCompleteness = (scenario, session, steps) => {
135
135
  missing.push("events");
136
136
  return classifyBrowserScenarioCompleteness(missing, truncated);
137
137
  };
138
- const runScenario = async (openSession, scenario, options) => {
138
+ const runScenario = async (openSession, scenario, options, retainCleanup) => {
139
139
  if (options.signal?.aborted === true)
140
140
  throw new BrowserObservationError(OPERATION, "cancelled");
141
141
  const startedAt = Date.now();
142
- const session = await openSession(scenario, options.signal === undefined ? {} : { signal: options.signal });
142
+ const session = await openSession(scenario, {
143
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
144
+ retainCleanup,
145
+ });
143
146
  const steps = [];
144
147
  let operationOutcome = { ok: true };
145
148
  try {
@@ -172,6 +175,7 @@ const runScenario = async (openSession, scenario, options) => {
172
175
  }
173
176
  catch (cause) {
174
177
  cleanupOutcome = { ok: false, cause };
178
+ retainCleanup(() => session.close());
175
179
  }
176
180
  if (!cleanupOutcome.ok) {
177
181
  const cleanup = browserScenarioCleanupObservation(cleanupOutcome.cause);
@@ -226,15 +230,33 @@ const runScenario = async (openSession, scenario, options) => {
226
230
  /** Controlled Playwright/CDP scenario driver with exact process ownership. */
227
231
  export class PlaywrightBrowserScenarioProvider {
228
232
  openSession;
233
+ #tail = Promise.resolve();
234
+ #closing = false;
235
+ #closePromise;
236
+ #pendingCleanup = new Set();
229
237
  constructor(openSession) {
230
238
  this.openSession = openSession;
231
239
  }
232
240
  identity() {
233
241
  return PLAYWRIGHT_BROWSER_SCENARIO_PROVIDER_IDENTITY;
234
242
  }
235
- async captureScenario(scenario, options = {}) {
243
+ captureScenario(scenario, options = {}) {
244
+ if (this.#closing)
245
+ return Promise.resolve(err(this.#closedError()));
246
+ const operation = this.#tail.then(() => this.#closing
247
+ ? err(this.#closedError())
248
+ : this.#captureScenario(scenario, options));
249
+ this.#tail = operation.then(() => undefined, () => undefined);
250
+ return operation;
251
+ }
252
+ async #captureScenario(scenario, options) {
253
+ const pending = await this.#retryCleanup();
254
+ if (pending !== undefined)
255
+ return err(pending);
236
256
  try {
237
- return ok(await runScenario(this.openSession, scenario, options));
257
+ return ok(await runScenario(this.openSession, scenario, options, (close) => {
258
+ this.#pendingCleanup.add(close);
259
+ }));
238
260
  }
239
261
  catch (cause) {
240
262
  if (cause instanceof AnalysisError)
@@ -242,4 +264,38 @@ export class PlaywrightBrowserScenarioProvider {
242
264
  return err(new ProviderAdapterError(PLAYWRIGHT_BROWSER_SCENARIO_PROVIDER_IDENTITY.id, OPERATION, { cause }));
243
265
  }
244
266
  }
267
+ async close() {
268
+ this.#closing = true;
269
+ this.#closePromise ??= this.#tail
270
+ .then(async () => {
271
+ const failure = await this.#retryCleanup();
272
+ if (failure !== undefined)
273
+ throw failure;
274
+ })
275
+ .catch((cause) => {
276
+ this.#closePromise = undefined;
277
+ throw cause;
278
+ });
279
+ return this.#closePromise;
280
+ }
281
+ #closedError() {
282
+ return new BrowserObservationError(OPERATION, "cleanup_failed", {
283
+ detail: "Browser scenario provider is closing.",
284
+ cleanup: { reason: "Provider is closing", resources: [] },
285
+ });
286
+ }
287
+ async #retryCleanup() {
288
+ for (const pending of this.#pendingCleanup) {
289
+ try {
290
+ await pending();
291
+ this.#pendingCleanup.delete(pending);
292
+ }
293
+ catch (cause) {
294
+ return cause instanceof AnalysisError
295
+ ? cause
296
+ : new ProviderAdapterError(PLAYWRIGHT_BROWSER_SCENARIO_PROVIDER_IDENTITY.id, OPERATION, { cause });
297
+ }
298
+ }
299
+ return undefined;
300
+ }
245
301
  }
@@ -181,18 +181,23 @@ export class PlaywrightElectronActiveProvider {
181
181
  return outcome;
182
182
  }
183
183
  }
184
- const cleanupElectronProcesses = async (ownership, lineage) => {
185
- if (process.platform === "win32") {
186
- const root = await cleanupWindowsProcessTree(ownership.leaderPid);
187
- if (!root.cleaned)
188
- return root;
184
+ /** Clean up an Electron launch. Windows signals a process only after lineage is verified. */
185
+ export const cleanupElectronProcesses = async (ownership, lineage, host = {
186
+ platform: process.platform,
187
+ terminateTree: cleanupWindowsProcessTree,
188
+ }) => {
189
+ if (host.platform === "win32") {
190
+ // An empty Windows process table is not ownership proof for this PID.
189
191
  if (lineage?.status !== "verified")
190
192
  return {
191
193
  cleaned: false,
192
194
  reason: "owned Electron lineage was unavailable; helper cleanup was not proven",
193
195
  };
196
+ const root = await host.terminateTree(ownership.leaderPid);
197
+ if (!root.cleaned)
198
+ return root;
194
199
  for (const descendant of lineage.lineage.descendants) {
195
- const result = await cleanupWindowsProcessTree(descendant.pid);
200
+ const result = await host.terminateTree(descendant.pid);
196
201
  if (!result.cleaned)
197
202
  return result;
198
203
  }
@@ -120,20 +120,20 @@ const captureStorage = async (input) => {
120
120
  }))()`));
121
121
  const value = {
122
122
  cookies: cookies.map((cookie) => ({
123
- name: cookie.name,
124
- domain: cookie.domain,
125
- path: cookie.path,
123
+ name: secrets.redact(cookie.name),
124
+ domain: secrets.redact(cookie.domain),
125
+ path: secrets.redact(cookie.path),
126
126
  secure: cookie.secure,
127
127
  http_only: cookie.httpOnly,
128
128
  same_site: cookie.sameSite,
129
129
  ...secrets.fingerprint(cookie.value),
130
130
  })),
131
131
  local_storage: pageStorage.local_storage.map(([name, value]) => ({
132
- name,
132
+ name: secrets.redact(name),
133
133
  ...secrets.fingerprint(value),
134
134
  })),
135
135
  session_storage: pageStorage.session_storage.map(([name, value]) => ({
136
- name,
136
+ name: secrets.redact(name),
137
137
  ...secrets.fingerprint(value),
138
138
  })),
139
139
  };
@@ -3,6 +3,7 @@ import { tmpdir } from "node:os";
3
3
  import { join, resolve } from "node:path";
4
4
  import { chromium, } from "playwright-core";
5
5
  import { AnalysisError } from "../domain/analysisErrorBase.js";
6
+ import { isLiteralLoopbackHostname } from "../domain/browserObservation.js";
6
7
  import { BrowserObservationError } from "../domain/browserObservationError.js";
7
8
  import { withPlaywrightExecutionBoundary } from "./PlaywrightExecutionBoundary.js";
8
9
  const OPERATION = "capture_browser_scenario";
@@ -22,6 +23,9 @@ export class PlaywrightScenarioBrowserCleanupOwner {
22
23
  this.resources = resources;
23
24
  this.#profileRemoved = resources.removeProfile === undefined;
24
25
  }
26
+ get browserClosed() {
27
+ return this.#browserClosed;
28
+ }
25
29
  close(finishEvents, signal) {
26
30
  const cleanup = this.#closePromise ?? this.#closeResources(finishEvents);
27
31
  if (this.#closePromise === undefined) {
@@ -63,6 +67,9 @@ export class PlaywrightScenarioBrowserCleanupOwner {
63
67
  await eventFinalization;
64
68
  }
65
69
  catch (cause) {
70
+ // A failed finalization stays failed: the memoized attempt rejects on
71
+ // every retry so cleanup can never report success for unfinalized
72
+ // events.
66
73
  failures.push(cause);
67
74
  }
68
75
  if (!this.#browserClosed) {
@@ -119,10 +126,19 @@ const createAttachedScenarioRelease = (key, admission) => {
119
126
  releaseAttachedScenario(key, admission);
120
127
  };
121
128
  };
129
+ /** One browser admission. The key is the discovery URL this endpoint already parses. */
130
+ export const attachedScenarioLeaseKey = (endpoint, targetId) => {
131
+ const discovery = new URL("/json/version", endpoint);
132
+ // One CDP browser serves every loopback stack on one port, so spellings that
133
+ // reach it through 127.0.0.1 or ::1 must share a single admission.
134
+ if (isLiteralLoopbackHostname(discovery.hostname))
135
+ discovery.hostname = "127.0.0.1";
136
+ return JSON.stringify([discovery.href, targetId]);
137
+ };
122
138
  const acquireAttachedScenario = (scenario, signal) => {
123
139
  if (signal?.aborted === true)
124
140
  return Promise.reject(new BrowserObservationError(OPERATION, "cancelled"));
125
- const key = JSON.stringify([scenario.cdp_endpoint, scenario.target_id]);
141
+ const key = attachedScenarioLeaseKey(scenario.cdp_endpoint, scenario.target_id);
126
142
  const admission = attachedScenarioAdmissions.get(key) ??
127
143
  {
128
144
  active: false,
@@ -180,9 +196,23 @@ const allowedBrowserEnvironment = (environment) => {
180
196
  "XAUTHORITY",
181
197
  "XDG_RUNTIME_DIR",
182
198
  ];
183
- return Object.fromEntries(allowed
199
+ const selected = Object.fromEntries(allowed
184
200
  .map((name) => [name, environment[name]])
185
201
  .filter((entry) => entry[1] !== undefined));
202
+ if (process.platform !== "android")
203
+ return selected;
204
+ // Android rejects execve() for binaries below Termux's application data
205
+ // directory. Termux supplies an exec interceptor that rewrites those calls
206
+ // through the system linker and removes itself for the launched program.
207
+ // Playwright must retain it for its Chromium child process.
208
+ const prefix = environment.PREFIX;
209
+ if (prefix === undefined)
210
+ return selected;
211
+ return {
212
+ ...selected,
213
+ LD_PRELOAD: `${prefix}/lib/libtermux-exec.so`,
214
+ TERMUX_EXEC__PROC_SELF_EXE: process.execPath,
215
+ };
186
216
  };
187
217
  const findConnectedPage = async (browser, targetId, signal) => {
188
218
  for (const context of browser.contexts())
@@ -254,7 +284,7 @@ export const failBrowserScenarioOperation = async (cleanup, primaryFailure, fall
254
284
  }
255
285
  throw primaryFailure;
256
286
  };
257
- const openAttachedScenarioBrowser = async (browserRequest, environment, launcher, signal) => {
287
+ const openAttachedScenarioBrowser = async (browserRequest, environment, launcher, signal, retainCleanup) => {
258
288
  const lease = await acquireAttachedScenario(browserRequest, signal);
259
289
  let cleanupOwner;
260
290
  try {
@@ -291,14 +321,22 @@ const openAttachedScenarioBrowser = async (browserRequest, environment, launcher
291
321
  throw cause;
292
322
  }
293
323
  const cleanup = cleanupOwner;
294
- return failBrowserScenarioOperation(() => cleanup.close(), cause);
324
+ const close = () => cleanup.close();
325
+ try {
326
+ return await failBrowserScenarioOperation(close, cause);
327
+ }
328
+ catch (failure) {
329
+ if (failure !== cause)
330
+ retainCleanup?.(close);
331
+ throw failure;
332
+ }
295
333
  }
296
334
  };
297
335
  /** Launch or attach using the caller-selected environment and browser engine. */
298
336
  export const openPlaywrightScenarioBrowser = async (scenario, environment, options = {}) => {
299
337
  const launcher = options.launcher ?? chromium;
300
338
  if (scenario.browser.mode === "connect")
301
- return openAttachedScenarioBrowser(scenario.browser, scenario.environment, launcher, options.signal);
339
+ return openAttachedScenarioBrowser(scenario.browser, scenario.environment, launcher, options.signal, options.retainCleanup);
302
340
  const profilePath = await mkdtemp(join(tmpdir(), "rea-browser-scenario-"));
303
341
  let context;
304
342
  try {
@@ -322,10 +360,26 @@ export const openPlaywrightScenarioBrowser = async (scenario, environment, optio
322
360
  handleSIGINT: false,
323
361
  handleSIGTERM: false,
324
362
  timeout: 0,
363
+ // Termux's Chromium cannot create its renderer process through Android's
364
+ // executable boundary. Single-process mode keeps the browser and page in
365
+ // the Termux-launched process so scenario navigation remains available.
366
+ args: process.platform === "android"
367
+ ? ["--no-sandbox", "--single-process"]
368
+ : [],
325
369
  });
326
370
  }
327
371
  catch (cause) {
328
- return failBrowserScenarioOperation(() => rm(profilePath, { recursive: true, force: true, maxRetries: 3 }), cause, ["browser_profile"]);
372
+ const cleanup = () => rm(profilePath, { recursive: true, force: true, maxRetries: 3 });
373
+ try {
374
+ return await failBrowserScenarioOperation(cleanup, cause, [
375
+ "browser_profile",
376
+ ]);
377
+ }
378
+ catch (failure) {
379
+ if (failure !== cause)
380
+ options.retainCleanup?.(cleanup);
381
+ throw failure;
382
+ }
329
383
  }
330
384
  const cleanup = new PlaywrightScenarioBrowserCleanupOwner({
331
385
  closeBrowser: () => context.close(),
@@ -345,6 +399,14 @@ export const openPlaywrightScenarioBrowser = async (scenario, environment, optio
345
399
  };
346
400
  }
347
401
  catch (cause) {
348
- return failBrowserScenarioOperation(() => cleanup.close(), cause);
402
+ const close = () => cleanup.close();
403
+ try {
404
+ return await failBrowserScenarioOperation(close, cause);
405
+ }
406
+ catch (failure) {
407
+ if (failure !== cause)
408
+ options.retainCleanup?.(close);
409
+ throw failure;
410
+ }
349
411
  }
350
412
  };