rea-agents 5.0.0 → 6.1.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 (507) hide show
  1. package/README.md +168 -655
  2. package/bridge/android/ReaJadxBridge.java +14 -5
  3. package/bridge/ghidra/ReaGhidraBridge.java +173 -47
  4. package/bridge/hopper_bridge.py +310 -128
  5. package/bridge/mitmproxy/capture.py +208 -0
  6. package/bridge/native/rea_lldb_tracer.py +839 -0
  7. package/bridge/process/ProcessRunTokenReader.swift +297 -0
  8. package/bridge/process/ProcessRunTokenReaderMain.swift +35 -0
  9. package/bridge/pwndbg/core_context.py +101 -0
  10. package/bridge/pwndbg/launch.py +39 -0
  11. package/bridge/pwndbg/launch_impl.py +34 -0
  12. package/bridge/pwntools/decoder_runtime.py +59 -0
  13. package/bridge/pwntools/layout.py +39 -0
  14. package/bridge/pwntools/layout_impl.py +309 -0
  15. package/bridge/pwntools/recorded_crash.py +39 -0
  16. package/bridge/pwntools/recorded_crash_impl.py +147 -0
  17. package/dist/android/JadxConfiguration.js +196 -33
  18. package/dist/android/JadxMcpTransport.js +4 -0
  19. package/dist/android/JadxProtocol.js +6 -0
  20. package/dist/android/JadxProvider.js +20 -2
  21. package/dist/android/JadxSession.js +23 -4
  22. package/dist/application/AnalysisContextQueries.js +8 -35
  23. package/dist/application/AnalysisDocument.js +32 -0
  24. package/dist/application/AppBundleExecutable.js +67 -21
  25. package/dist/application/CallPathTracing.js +19 -3
  26. package/dist/application/CapabilityInventory.js +27 -3
  27. package/dist/application/ClientConfigurationDocument.js +871 -6
  28. package/dist/application/ClientRegistrationIdentity.js +26 -5
  29. package/dist/application/ClientRegistrationStatus.js +29 -14
  30. package/dist/application/DirectAnalysis.js +97 -33
  31. package/dist/application/Doctor.js +4 -2
  32. package/dist/application/DoctorScope.js +25 -13
  33. package/dist/application/EnhancedLiteralTracing.js +22 -25
  34. package/dist/application/EnhancedTools.js +13 -11
  35. package/dist/application/EvidenceBundleFiles.js +24 -12
  36. package/dist/application/FunctionAnalysisEvidence.js +2 -3
  37. package/dist/application/InventoryProjectionEvidence.js +4 -3
  38. package/dist/application/InvestigationProviders.js +3 -2
  39. package/dist/application/JsonFiles.js +50 -28
  40. package/dist/application/ProcedureAddressResolution.js +11 -0
  41. package/dist/application/ReconstructionCoverageService.js +7 -4
  42. package/dist/application/ReconstructionObligationCandidates.js +5 -1
  43. package/dist/application/ReconstructionObligationLedgerService.js +4 -3
  44. package/dist/application/Setup.js +13 -1
  45. package/dist/application/SetupClientConfiguration.js +10 -15
  46. package/dist/application/SetupHost.js +5 -2
  47. package/dist/application/SetupPlan.js +5 -3
  48. package/dist/application/SupportedClients.js +34 -1
  49. package/dist/application/Uninstall.js +4 -3
  50. package/dist/application/Update.js +18 -3
  51. package/dist/application/UpdateRuntime.js +46 -25
  52. package/dist/application/WebModuleTraceService.js +4 -2
  53. package/dist/application/WebNetworkCapturePort.js +1 -0
  54. package/dist/application/WebNetworkCaptureService.js +134 -0
  55. package/dist/application/WebRuntimeService.js +5 -3
  56. package/dist/application/WebScriptExportService.js +2 -2
  57. package/dist/application/WebSourceLocationService.js +4 -2
  58. package/dist/application/WindowsCapabilities.js +1 -1
  59. package/dist/application/WorkflowEvidence.js +82 -0
  60. package/dist/application/binary/AnalysisProviderEvaluation.js +21 -5
  61. package/dist/application/binary/AnalysisProviderRegistry.js +2 -0
  62. package/dist/application/binary/AnalysisSnapshotCache.js +52 -12
  63. package/dist/application/binary/BinarySession.js +131 -76
  64. package/dist/application/binary/BinarySessionOpen.js +19 -6
  65. package/dist/application/binary/BinarySessionRecords.js +45 -3
  66. package/dist/application/binary/BinarySessionStatus.js +17 -1
  67. package/dist/application/binary/CompositeProvider.js +13 -0
  68. package/dist/application/binary/LazyAnalysisProvider.js +3 -0
  69. package/dist/application/binaryDiagnostics/BinaryLayoutPort.js +1 -0
  70. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +59 -0
  71. package/dist/application/binaryDiagnostics/RecordedCrashPort.js +1 -0
  72. package/dist/application/binaryDiagnostics/RecordedCrashService.js +62 -0
  73. package/dist/application/evm/EvmInterfacePort.js +1 -0
  74. package/dist/application/evm/EvmInterfaceService.js +64 -0
  75. package/dist/application/investigation/EvidenceLedger.js +21 -7
  76. package/dist/application/investigation/InvestigationRecords.js +8 -0
  77. package/dist/application/javascript/JavaScriptAnalysisControl.js +34 -0
  78. package/dist/application/javascript/JavaScriptApplicationEvidence.js +25 -5
  79. package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +19 -2
  80. package/dist/application/javascript/JavaScriptApplicationService.js +34 -14
  81. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +5 -5
  82. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +47 -27
  83. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +39 -7
  84. package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +26 -2
  85. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +80 -27
  86. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +33 -12
  87. package/dist/application/javascript/JavaScriptModuleRelationships.js +37 -8
  88. package/dist/application/javascript/JavaScriptRecoveryService.js +4 -2
  89. package/dist/application/javascript/JavaScriptRuntimeObservationService.js +3 -1
  90. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +3 -3
  91. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +7 -7
  92. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +149 -72
  93. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +14 -15
  94. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +41 -1
  95. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +7 -7
  96. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +5 -9
  97. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +3 -3
  98. package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +118 -12
  99. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +3 -3
  100. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +27 -5
  101. package/dist/application/managed/ManagedApplicationGraphService.js +4 -3
  102. package/dist/application/managed/ManagedMemberComparisonService.js +7 -4
  103. package/dist/application/managed/ManagedNativeVerificationService.js +4 -3
  104. package/dist/application/managed/ManagedReconstructionService.js +4 -3
  105. package/dist/application/{ProcessCli.js → process/ProcessCli.js} +23 -15
  106. package/dist/application/{ProcessEvidence.js → process/ProcessEvidence.js} +8 -7
  107. package/dist/application/workflowInputError.js +18 -0
  108. package/dist/artifacts/ArtifactProvider.js +42 -5
  109. package/dist/artifacts/ArtifactProviderMetadata.js +2 -1
  110. package/dist/artifacts/MachOSliceArtifactReader.js +98 -14
  111. package/dist/artifacts/NativeDmgArtifactReader.js +13 -6
  112. package/dist/artifacts/ZipArtifactReader.js +3 -0
  113. package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +22 -3
  114. package/dist/artifacts/apple/DylibResolutionReader.js +259 -0
  115. package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +176 -56
  116. package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +195 -0
  117. package/dist/artifacts/apple/KeyedArchiveReader.js +36 -22
  118. package/dist/artifacts/apple/MachoLoadCommandReader.js +355 -0
  119. package/dist/artifacts/apple/NibArchive.js +81 -14
  120. package/dist/artifacts/apple/NibViewHierarchy.js +10 -3
  121. package/dist/artifacts/apple/PlistNumberLiterals.js +164 -0
  122. package/dist/{application → artifacts/extraction}/ArtifactExtraction.js +10 -10
  123. package/dist/{application → artifacts/inventory}/ArtifactGraphConstruction.js +16 -11
  124. package/dist/{application → artifacts/inventory}/ArtifactInventory.js +4 -4
  125. package/dist/{application/ArtifactInventory → artifacts/inventory}/classify.js +2 -2
  126. package/dist/{application/ArtifactInventory → artifacts/inventory}/reader.js +5 -5
  127. package/dist/{application/ArtifactInventory → artifacts/inventory}/scanCanonical.js +14 -17
  128. package/dist/{application/ArtifactInventory → artifacts/inventory}/scanReader.js +5 -5
  129. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +6 -2
  130. package/dist/artifacts/readStableArtifact.js +20 -4
  131. package/dist/browser/CdpCaptureCompleteness.js +2 -0
  132. package/dist/browser/CdpCaptureEventHandlers.js +165 -12
  133. package/dist/browser/CdpCaptureEventTypes.js +5 -1
  134. package/dist/browser/CdpCaptureEvents.js +34 -0
  135. package/dist/browser/CdpConnection.js +30 -11
  136. package/dist/browser/CdpOptionalCommand.js +2 -3
  137. package/dist/browser/CdpPageCapture.js +23 -1
  138. package/dist/browser/PlaywrightElectronActiveActions.js +32 -23
  139. package/dist/browser/PlaywrightElectronActiveProjection.js +141 -0
  140. package/dist/browser/PlaywrightElectronActiveProvider.js +130 -122
  141. package/dist/browser/WebSourceMapFetcher.js +426 -72
  142. package/dist/browser/assets/LocalWebScriptArtifacts.js +2 -2
  143. package/dist/browser/history/CaptureFailures.js +137 -0
  144. package/dist/browser/history/CaptureFormatError.js +10 -0
  145. package/dist/browser/history/CaptureRedaction.js +65 -0
  146. package/dist/browser/history/CaptureRelease.js +17 -0
  147. package/dist/browser/history/HarCapture.js +165 -0
  148. package/dist/browser/history/HarCaptureAdapter.js +20 -0
  149. package/dist/browser/history/HarCaptureProcess.js +57 -0
  150. package/dist/browser/history/HarJson.js +92 -0
  151. package/dist/browser/history/HarSchema.js +72 -0
  152. package/dist/browser/history/HistoricalCaptureDecoder.js +188 -0
  153. package/dist/browser/history/HistoricalCaptureFormatAdapter.js +1 -0
  154. package/dist/browser/history/MitmproxyCaptureAdapter.js +42 -0
  155. package/dist/cli/analysisSelector.js +23 -0
  156. package/dist/cli/applicationCommands.js +2 -3
  157. package/dist/cli/artifactCommands.js +26 -1
  158. package/dist/cli/binaryDiagnosticsCommands.js +39 -0
  159. package/dist/cli/coreAnalysisCommands.js +2 -2
  160. package/dist/cli/coreBinaryCommands.js +78 -20
  161. package/dist/cli/electronCommands.js +21 -13
  162. package/dist/cli/evmCommands.js +24 -0
  163. package/dist/cli/firmwareCommands.js +6 -3
  164. package/dist/cli/javascriptApplicationAnalysis.js +20 -3
  165. package/dist/cli/jsonOutput.js +38 -0
  166. package/dist/cli/nativeCallCommands.js +34 -0
  167. package/dist/cli/processCommands.js +1 -1
  168. package/dist/cli/streamedJsonOutput.js +56 -0
  169. package/dist/cli/utilityCommands.js +2 -0
  170. package/dist/cli/webNetworkCaptureCommands.js +40 -0
  171. package/dist/cli/webRuntimeCommands.js +8 -8
  172. package/dist/cli.js +11 -4
  173. package/dist/cliBrowserScenarioCommands.js +2 -2
  174. package/dist/cliCommandNames.js +6 -1
  175. package/dist/cliJsonInput.js +35 -1
  176. package/dist/cliOutput.js +21 -6
  177. package/dist/composition/binaryDiagnostics.js +8 -0
  178. package/dist/composition/evm.js +4 -0
  179. package/dist/composition/webNetworkCaptures.js +6 -0
  180. package/dist/config/environment.js +4 -0
  181. package/dist/config/ghidraStartupTimeout.js +17 -0
  182. package/dist/config/mcpResponseBudget.js +22 -0
  183. package/dist/config/parseConfig.js +2 -1
  184. package/dist/contracts/artifactToolContracts.js +6 -0
  185. package/dist/contracts/browserCaptureToolInputSchema.js +43 -0
  186. package/dist/contracts/browserToolContracts.js +4 -3
  187. package/dist/contracts/enhancedInputs.js +5 -3
  188. package/dist/contracts/enhancedToolContracts.js +3 -3
  189. package/dist/contracts/errorSchemas.js +8 -1
  190. package/dist/contracts/evm/evmToolContracts.js +20 -0
  191. package/dist/contracts/hopperMemoryContracts.js +2 -5
  192. package/dist/contracts/investigationExamples.js +2 -2
  193. package/dist/contracts/javascript/electronToolContracts.js +1 -1
  194. package/dist/contracts/managed/managedToolContracts.js +8 -6
  195. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +42 -0
  196. package/dist/contracts/native/nativeToolContracts.js +21 -3
  197. package/dist/contracts/officialToolContracts.js +26 -24
  198. package/dist/contracts/process/processCaptureExample.js +2 -0
  199. package/dist/contracts/promptContracts.js +3 -3
  200. package/dist/contracts/sessionLifecycleInputs.js +18 -5
  201. package/dist/contracts/sessionStatusContract.js +8 -2
  202. package/dist/contracts/sessionToolContracts.js +8 -3
  203. package/dist/contracts/sessionToolSchemas.js +8 -4
  204. package/dist/contracts/toolContractExamples.js +1 -2
  205. package/dist/contracts/toolContractHelpers.js +4 -1
  206. package/dist/contracts/toolContracts.js +6 -0
  207. package/dist/contracts/toolEffects.js +30 -1
  208. package/dist/contracts/toolOutputSchemaGroups.js +33 -28
  209. package/dist/contracts/toolOutputSchemaPrimitives.js +19 -1
  210. package/dist/contracts/toolSchemaMetadata.js +69 -10
  211. package/dist/contracts/webNetworkCaptureToolContracts.js +24 -0
  212. package/dist/domain/analysisErrorBase.js +22 -2
  213. package/dist/domain/analysisErrorCore.js +61 -5
  214. package/dist/domain/analysisErrorPresentation.js +95 -12
  215. package/dist/domain/analysisErrorProjection.js +148 -19
  216. package/dist/domain/analysisSnapshot.js +166 -2
  217. package/dist/domain/android/androidAnalysis.js +2 -4
  218. package/dist/domain/android/androidApplication.js +17 -9
  219. package/dist/domain/apple/appleApplication.js +41 -14
  220. package/dist/domain/apple/dyldEnvironment.js +73 -0
  221. package/dist/domain/apple/dyldPaths.js +81 -0
  222. package/dist/domain/apple/dylibResolution.js +478 -0
  223. package/dist/domain/apple/dylibResolutionFindings.js +77 -0
  224. package/dist/domain/apple/interfaceBuilderGraph.js +25 -13
  225. package/dist/domain/apple/interfaceBuilderKeyedArchive.js +13 -3
  226. package/dist/domain/apple/keyedArchive.js +9 -1
  227. package/dist/domain/apple/machoContainer.js +54 -0
  228. package/dist/domain/apple/plistNumbers.js +76 -0
  229. package/dist/domain/artifactIdentity.js +29 -0
  230. package/dist/domain/artifactInventoryEvidence.js +19 -24
  231. package/dist/domain/artifactPathSyntax.js +1 -1
  232. package/dist/domain/bridgeCandidateProjection.js +71 -0
  233. package/dist/domain/browserCompleteness.js +1 -0
  234. package/dist/domain/browserObservation.js +1 -1
  235. package/dist/domain/browserObservationError.js +24 -5
  236. package/dist/domain/browserObservationSchemas.js +13 -0
  237. package/dist/domain/browserScenarioValues.js +5 -2
  238. package/dist/domain/bundleComparison.js +3 -2
  239. package/dist/domain/callPathSchemas.js +1 -1
  240. package/dist/domain/canonicalDigest.js +13 -1
  241. package/dist/domain/canonicalJsonDigestSteps.js +133 -0
  242. package/dist/domain/canonicalOrdering.js +9 -5
  243. package/dist/domain/changedBehavior.js +9 -9
  244. package/dist/domain/comparisonSourceEvidence.js +40 -0
  245. package/dist/domain/comparisonStatus.js +2 -30
  246. package/dist/domain/configurationErrors.js +1 -1
  247. package/dist/domain/conformanceTrustGate.js +0 -16
  248. package/dist/domain/evidence.js +78 -11
  249. package/dist/domain/evidenceBundle.js +42 -1
  250. package/dist/domain/evidenceErrors.js +12 -1
  251. package/dist/domain/evm/evmInterface.js +63 -0
  252. package/dist/domain/explicitSensitiveFailure.js +108 -0
  253. package/dist/domain/explicitSensitiveValues.js +10 -0
  254. package/dist/domain/firmware/firmwareAnalysis.js +10 -4
  255. package/dist/domain/hopperErrors.js +23 -2
  256. package/dist/domain/hopperValues.js +51 -8
  257. package/dist/domain/immutableJson.js +114 -0
  258. package/dist/domain/inputIssueProjection.js +3 -0
  259. package/dist/domain/javascript/electronActiveObservation.js +37 -6
  260. package/dist/domain/javascript/electronStaticAnalysisValues.js +6 -12
  261. package/dist/domain/javascript/htmlArtifactReferences.js +40 -0
  262. package/dist/domain/javascript/javascriptApplicationAnalysis.js +71 -23
  263. package/dist/domain/javascript/javascriptApplicationGraph.js +13 -0
  264. package/dist/domain/javascript/javascriptAstValues.js +20 -0
  265. package/dist/domain/javascript/javascriptExportShapeComparison.js +21 -5
  266. package/dist/domain/javascript/javascriptExportShapeVariants.js +0 -10
  267. package/dist/domain/javascript/javascriptRecovery.js +3 -8
  268. package/dist/domain/javascript/javascriptSemanticAnalysis.js +97 -2
  269. package/dist/domain/javascript/javascriptSemanticCoverage.js +6 -5
  270. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +9 -17
  271. package/dist/domain/javascript/javascriptSemanticDataEffects.js +22 -5
  272. package/dist/domain/javascript/javascriptSemanticGraph.js +34 -5
  273. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +1 -0
  274. package/dist/domain/javascript/javascriptSemanticPrimitives.js +25 -17
  275. package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -4
  276. package/dist/domain/javascript/javascriptSemanticResourceLimits.js +77 -0
  277. package/dist/domain/javascript/javascriptSemanticValues.js +83 -11
  278. package/dist/domain/javascript/javascriptSourceParser.js +6 -2
  279. package/dist/domain/javascript/javascriptStaticAnalysis.js +22 -17
  280. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -3
  281. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +14 -4
  282. package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +66 -7
  283. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +28 -16
  284. package/dist/domain/javascript/javascriptStaticAnalysisState.js +3 -2
  285. package/dist/domain/jsonSerialization.js +109 -0
  286. package/dist/domain/jsonValue.js +91 -3
  287. package/dist/domain/localPath.js +8 -0
  288. package/dist/domain/managed/managedApplicationGraph.js +10 -10
  289. package/dist/domain/managed/managedInspectionEvidence.js +16 -0
  290. package/dist/domain/managed/managedMemberComparisonMatch.js +5 -9
  291. package/dist/domain/managed/managedNativeVerification.js +3 -9
  292. package/dist/domain/native/binaryLayout.js +357 -0
  293. package/dist/domain/native/fileOffsetPartialObservation.js +1 -0
  294. package/dist/domain/native/nativeCallObservation.js +186 -0
  295. package/dist/domain/native/nativeCallPartialObservation.js +33 -0
  296. package/dist/domain/native/objcSwiftMetadata.js +0 -39
  297. package/dist/domain/native/recordedCrash.js +266 -0
  298. package/dist/domain/native/recordedCrashNoteCoverage.js +73 -0
  299. package/dist/domain/{processCapture.js → process/processCapture.js} +143 -2
  300. package/dist/domain/{processCaptureExample.js → process/processCaptureExample.js} +5 -0
  301. package/dist/domain/process/processCaptureParsing.js +54 -0
  302. package/dist/domain/{processCaptureValidation.js → process/processCaptureValidation.js} +18 -2
  303. package/dist/domain/{processComparison.js → process/processComparison.js} +39 -5
  304. package/dist/domain/{processObservation.js → process/processObservation.js} +1 -1
  305. package/dist/domain/{processScenario.js → process/processScenario.js} +11 -10
  306. package/dist/domain/{processTraceSpecification.js → process/processTraceSpecification.js} +1 -1
  307. package/dist/domain/propertyListKeys.js +1 -1
  308. package/dist/domain/propertyListXmlText.js +19 -0
  309. package/dist/domain/providerAdapterError.js +1 -1
  310. package/dist/domain/providerOperationHealth.js +54 -0
  311. package/dist/domain/providerSelectionError.js +4 -2
  312. package/dist/domain/reconstructionVerification.js +9 -46
  313. package/dist/domain/reconstructionVerificationSchemas.js +3 -3
  314. package/dist/domain/residualUnknown.js +3 -2
  315. package/dist/domain/staticRuntimeCorrelation.js +9 -46
  316. package/dist/domain/webBundleAnalysis.js +20 -8
  317. package/dist/domain/webBundleAnalyzerInspection.js +13 -8
  318. package/dist/domain/webBundleAnalyzerResult.js +41 -2
  319. package/dist/domain/webCaptureDiff.js +1 -0
  320. package/dist/domain/webNetworkCapture.js +118 -0
  321. package/dist/domain/webNetworkCaptureCoordinates.js +58 -0
  322. package/dist/domain/webRuntime.js +19 -5
  323. package/dist/domain/webSourceLocation.js +1 -0
  324. package/dist/dotnet/ManagedExceptionRegionValidation.js +41 -0
  325. package/dist/dotnet/ManagedMemberInspector.js +4 -2
  326. package/dist/dotnet/ManagedMemberInspectorCore.js +38 -32
  327. package/dist/dotnet/ManagedMemberInstructionDecoder.js +23 -7
  328. package/dist/dotnet/ManagedMemberRows.js +14 -3
  329. package/dist/dotnet/ManagedMetadataHeaps.js +20 -2
  330. package/dist/dotnet/ManagedMetadataInventory.js +38 -28
  331. package/dist/dotnet/ManagedMetadataInventoryRows.js +24 -10
  332. package/dist/dotnet/ManagedMethodBodyReader.js +7 -1
  333. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +15 -3
  334. package/dist/dotnet/ManagedNativeBoundaryInspector.js +3 -1
  335. package/dist/dotnet/ManagedPeReader.js +11 -0
  336. package/dist/evm/EvmBytecodeCarrier.js +21 -0
  337. package/dist/evm/EvmWorkerLimits.js +40 -0
  338. package/dist/evm/EvmoleFailures.js +126 -0
  339. package/dist/evm/EvmoleInterfaceAdapter.js +53 -0
  340. package/dist/evm/EvmoleInterfaceProvider.js +273 -0
  341. package/dist/evm/EvmoleInterfaceWorker.js +87 -0
  342. package/dist/evm/EvmoleRelease.js +16 -0
  343. package/dist/firmware/FirmwareCommand.js +1 -0
  344. package/dist/firmware/FirmwareFiles.js +1 -1
  345. package/dist/generatedPackageMetadata.js +2 -2
  346. package/dist/ghidra/GhidraAnalysisProfile.js +5 -0
  347. package/dist/ghidra/GhidraClient.js +47 -14
  348. package/dist/ghidra/GhidraDiagnostics.js +7 -7
  349. package/dist/ghidra/GhidraFunctionValues.js +10 -7
  350. package/dist/ghidra/GhidraInstallation.js +18 -21
  351. package/dist/ghidra/GhidraInventoryValues.js +14 -4
  352. package/dist/ghidra/GhidraJavaLaunch.js +62 -0
  353. package/dist/ghidra/GhidraLauncher.js +34 -16
  354. package/dist/ghidra/GhidraProvider.js +2 -2
  355. package/dist/ghidra/GhidraProviderCapabilities.js +15 -3
  356. package/dist/ghidra/GhidraProviderClient.js +23 -12
  357. package/dist/ghidra/GhidraSessionError.js +11 -7
  358. package/dist/ghidra/GhidraTargetSnapshot.js +47 -12
  359. package/dist/ghidra/GhidraTransport.js +20 -0
  360. package/dist/hopper/BridgeLauncher.js +33 -11
  361. package/dist/hopper/HopperAnalysisProfile.js +62 -4
  362. package/dist/hopper/HopperCleanup.js +15 -3
  363. package/dist/hopper/HopperClient.js +222 -14
  364. package/dist/hopper/HopperFileOffset.js +237 -0
  365. package/dist/hopper/HopperMachOImage.js +196 -0
  366. package/dist/hopper/HopperOperationStage.js +6 -0
  367. package/dist/hopper/HopperProvider.js +63 -9
  368. package/dist/hopper/HopperProviderCapabilities.js +19 -1
  369. package/dist/hopper/HopperRegexSearch.js +137 -0
  370. package/dist/hopper/HopperRegexWorker.js +27 -0
  371. package/dist/hopper/HopperRequestQueue.js +68 -19
  372. package/dist/hopper/HopperTargetLease.js +3 -2
  373. package/dist/hopper/LinuxPrivateDisplayProbe.js +4 -2
  374. package/dist/inspector/JavaScriptRuntimeScope.js +9 -1
  375. package/dist/inspector/V8InspectorCaptureProjection.js +8 -3
  376. package/dist/inspector/V8InspectorProvider.js +47 -11
  377. package/dist/javascript/recovery/WakaruCommand.js +3 -0
  378. package/dist/javascript/sourceMaps/DecodedSourceMap.js +47 -0
  379. package/dist/javascript/sourceMaps/SourceMapCommand.js +17 -0
  380. package/dist/javascript/sourceMaps/SourceMapFormat.js +79 -31
  381. package/dist/javascript/sourceMaps/TraceSourceMap.js +14 -28
  382. package/dist/mcpDoctor.js +62 -2
  383. package/dist/native/AppleDispatchCoverage.js +47 -6
  384. package/dist/native/AppleDispatchDecodeFacts.js +6 -0
  385. package/dist/native/AppleDispatchMetadata.js +6 -3
  386. package/dist/native/AppleMachoFixups.js +48 -24
  387. package/dist/native/AppleMachoSelection.js +32 -16
  388. package/dist/native/AppleObjcCategories.js +6 -2
  389. package/dist/native/AppleObjcDispatchFacets.js +5 -2
  390. package/dist/native/AppleObjcProperties.js +2 -1
  391. package/dist/native/AppleSwiftDispatchFacets.js +27 -21
  392. package/dist/native/AppleSwiftVtables.js +21 -15
  393. package/dist/native/CommandRunner.js +82 -84
  394. package/dist/native/LldbCallTracer.js +541 -0
  395. package/dist/native/LldbRetainedObservations.js +178 -0
  396. package/dist/native/NativeCallObservation.js +194 -0
  397. package/dist/native/NativeMacOSProvider.js +117 -20
  398. package/dist/native/NativeMacOSProviderMetadata.js +8 -3
  399. package/dist/native/SignatureTargetBinding.js +155 -0
  400. package/dist/native/parsers/lipo.js +71 -1
  401. package/dist/native/pwndbg/PwndbgCoreContext.js +180 -0
  402. package/dist/native/pwntools/PwntoolsDecoder.js +203 -0
  403. package/dist/native/pwntools/PwntoolsFailures.js +180 -0
  404. package/dist/native/pwntools/PwntoolsLayoutProvider.js +36 -0
  405. package/dist/native/pwntools/PwntoolsRecordedCrashProvider.js +75 -0
  406. package/dist/native/pwntools/PwntoolsRelease.js +19 -0
  407. package/dist/native/pwntools/PwntoolsResourceLimits.js +76 -0
  408. package/dist/native/pwntools/RecordedCrashSourceBindings.js +46 -0
  409. package/dist/native/pwntools/RecordedCrashStructureBindings.js +103 -0
  410. package/dist/process/DarwinProcessRunTokenReader.js +293 -0
  411. package/dist/process/ExecFileOutput.js +20 -0
  412. package/dist/process/OwnedCommand.js +118 -0
  413. package/dist/process/ProcessOwnership.js +431 -51
  414. package/dist/process/ProcessOwnershipObservation.js +209 -27
  415. package/dist/process/ProviderProcess.js +68 -10
  416. package/dist/{application → process/capture}/ProcessCaptureCapability.js +15 -0
  417. package/dist/{application → process/capture}/ProcessCaptureError.js +18 -2
  418. package/dist/process/capture/ProcessCaptureLifecycle.js +681 -0
  419. package/dist/{application → process/capture}/ProcessHarness.js +195 -29
  420. package/dist/{application → process/capture}/ProcessSampling.js +2 -2
  421. package/dist/server/EvidenceMcpServer.js +146 -0
  422. package/dist/server/createServer.js +37 -8
  423. package/dist/server/promptCompletion.js +10 -3
  424. package/dist/server/registerAndroidTools.js +2 -4
  425. package/dist/server/registerApplicationTools/helpers.js +2 -4
  426. package/dist/server/registerArtifactComparisonTool.js +11 -7
  427. package/dist/server/registerBinaryDiagnosticsTools.js +15 -0
  428. package/dist/server/registerBrowserScenarioTool.js +2 -4
  429. package/dist/server/registerBrowserTools.js +2 -4
  430. package/dist/server/registerBundleComparisonTool.js +2 -3
  431. package/dist/server/registerCloseLifecycleTool.js +8 -18
  432. package/dist/server/registerElectronTools.js +2 -4
  433. package/dist/server/registerEnhancedTools.js +18 -59
  434. package/dist/server/registerEvidenceTools.js +3 -5
  435. package/dist/server/registerEvmTools.js +15 -0
  436. package/dist/server/registerFirmwareTools.js +2 -4
  437. package/dist/server/registerFunctionComparisonTool.js +10 -6
  438. package/dist/server/registerInvestigationTools.js +7 -7
  439. package/dist/server/registerJavaScriptRecoveryTool.js +2 -4
  440. package/dist/server/registerJavaScriptRuntimeObservationTools.js +2 -4
  441. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +2 -4
  442. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +2 -4
  443. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +2 -4
  444. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +2 -4
  445. package/dist/server/registerOfficialTools.js +2 -4
  446. package/dist/server/registerProcessComparisonTool.js +72 -46
  447. package/dist/server/registerRecordedCrashTools.js +15 -0
  448. package/dist/server/registerSessionRecordTools.js +5 -6
  449. package/dist/server/registerSessionStatusTool.js +17 -3
  450. package/dist/server/registerSessionTools.js +13 -5
  451. package/dist/server/registerWebModuleTool.js +2 -4
  452. package/dist/server/registerWebNetworkCaptureTool.js +26 -0
  453. package/dist/server/registerWebRuntimeTools.js +3 -7
  454. package/dist/server/registerWebScriptTool.js +2 -4
  455. package/dist/server/registerWebSourceLocationTool.js +2 -4
  456. package/dist/server/runDerivedOperation.js +15 -3
  457. package/dist/server/sessionAvailabilityPolicy.js +3 -1
  458. package/dist/server/sessionToolPolicies.js +1 -1
  459. package/dist/server/toolRegistrationOptions.js +2 -2
  460. package/dist/server/toolResult.js +63 -11
  461. package/dist/server/toolResultEncoding.js +33 -0
  462. package/install.sh +1 -1
  463. package/native/windows/build/manifest.json +2 -2
  464. package/native/windows/build/rea-windows-x64.node +0 -0
  465. package/package.json +42 -9
  466. package/scripts/electron-active-hook-boundaries.cjs +18 -20
  467. package/scripts/electron-active-hook.cjs +241 -37
  468. package/scripts/rea.mjs +11 -3
  469. package/skills/reverse-engineer-anything/SKILL.md +32 -4
  470. package/skills/reverse-engineer-anything/references/javascript-applications.md +8 -1
  471. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +29 -0
  472. package/third_party/README.md +60 -0
  473. package/third_party/evmole/LICENSE +21 -0
  474. package/third_party/evmole/README.md +22 -0
  475. package/third_party/pwndbg/LICENSE.md +21 -0
  476. package/third_party/pwndbg/README.md +23 -0
  477. package/third_party/pwntools/README.md +40 -0
  478. package/dist/application/AuthorizedArtifactInventory.js +0 -7
  479. package/dist/application/ProcessCaptureLifecycle.js +0 -299
  480. package/dist/application/StoreFileLock.js +0 -124
  481. package/dist/contracts/processCaptureExample.js +0 -2
  482. package/dist/domain/bytecodeProvider.js +0 -178
  483. package/dist/domain/customProtocolCapture.js +0 -137
  484. package/dist/domain/eventProcessTree.js +0 -225
  485. package/dist/domain/mobileApplicationInvestigation.js +0 -159
  486. package/dist/domain/packageAnalysis.js +0 -123
  487. package/dist/domain/peInspection.js +0 -197
  488. package/dist/domain/processCaptureParsing.js +0 -21
  489. package/dist/domain/protocolCapture.js +0 -217
  490. package/dist/domain/runtimeIdentification.js +0 -212
  491. package/dist/generatedMcpToolCatalog.js +0 -37
  492. package/dist/ghidra/GhidraDefaults.js +0 -2
  493. /package/dist/application/{ArtifactExtractionDestination.js → artifacts/ArtifactExtractionDestination.js} +0 -0
  494. /package/dist/{application/ArtifactInventory → artifacts/inventory}/policy.js +0 -0
  495. /package/dist/{application/ArtifactInventory → artifacts/inventory}/types.js +0 -0
  496. /package/dist/domain/{processEvidenceProvider.js → process/processEvidenceProvider.js} +0 -0
  497. /package/dist/domain/{processTraceComparison.js → process/processTraceComparison.js} +0 -0
  498. /package/dist/domain/{processTraceDimensionProjection.js → process/processTraceDimensionProjection.js} +0 -0
  499. /package/dist/domain/{processTraceEvaluation.js → process/processTraceEvaluation.js} +0 -0
  500. /package/dist/{application → process/capture}/FilesystemSnapshot.js +0 -0
  501. /package/dist/{application → process/capture}/ProcessCaptureEnvironment.js +0 -0
  502. /package/dist/{application → process/capture}/ProcessCaptureJournal.js +0 -0
  503. /package/dist/{application → process/capture}/ProcessFilesystemEffects.js +0 -0
  504. /package/dist/{application → process/capture}/ProcessNormalization.js +0 -0
  505. /package/dist/{application → process/capture}/ProcessScenarioRuntimeValidation.js +0 -0
  506. /package/dist/{application → process/capture}/ProcessTimer.js +0 -0
  507. /package/dist/{application → process/capture}/TerminalRenderer.js +0 -0
@@ -0,0 +1,137 @@
1
+ import { Worker } from "node:worker_threads";
2
+ import { z } from "zod";
3
+ import { AnalysisCancelledError, AnalysisOutputError, AnalysisResourceConstraintError, } from "../domain/analysisErrorCore.js";
4
+ import { analysisStringSchema } from "../domain/hopperValues.js";
5
+ import { HopperRemoteError } from "../domain/hopperErrors.js";
6
+ import { err, ok } from "../domain/result.js";
7
+ import { analysisSearchInput } from "../contracts/analysisSearchContract.js";
8
+ const MATCHING_DEADLINE_MS = 5_000;
9
+ const inputSchema = z.strictObject({
10
+ ...analysisSearchInput,
11
+ mode: z.literal("regex"),
12
+ document: z.string().nullish(),
13
+ case_sensitive: z
14
+ .boolean()
15
+ .nullish()
16
+ .transform((value) => value ?? false),
17
+ });
18
+ const replySchema = z.discriminatedUnion("status", [
19
+ z.strictObject({
20
+ status: z.literal("matched"),
21
+ indices: z.array(z.number().int().nonnegative()),
22
+ }),
23
+ z.strictObject({ status: z.literal("invalid_pattern"), reason: z.string() }),
24
+ ]);
25
+ /** Match collected native facts off Hopper's API thread, with cancellable lifetime. */
26
+ export class HopperRegexSearch {
27
+ client;
28
+ #active = new Map();
29
+ constructor(client) {
30
+ this.client = client;
31
+ }
32
+ execute(operation, parameters, options) {
33
+ const controller = new AbortController();
34
+ const signal = options?.signal === undefined
35
+ ? controller.signal
36
+ : AbortSignal.any([controller.signal, options.signal]);
37
+ const pending = this.#execute(operation, parameters, {
38
+ ...options,
39
+ signal,
40
+ });
41
+ this.#active.set(controller, pending);
42
+ void pending.then(() => this.#active.delete(controller), () => this.#active.delete(controller));
43
+ return pending;
44
+ }
45
+ /** Abort matching workers before their provider session closes. */
46
+ async close() {
47
+ for (const controller of this.#active.keys())
48
+ controller.abort();
49
+ await Promise.all(this.#active.values());
50
+ }
51
+ async #execute(operation, parameters, options) {
52
+ const input = inputSchema.safeParse(parameters);
53
+ if (!input.success)
54
+ return err(new HopperRemoteError(-32000, `Invalid search arguments: ${input.error.message}`, { diagnosticType: "invalid_request", operation }));
55
+ const inventoryOptions = {
56
+ ...options,
57
+ ...(options.progress === undefined
58
+ ? {}
59
+ : {
60
+ progress: {
61
+ report: (update) => options.progress?.report({
62
+ ...update,
63
+ completed: update.total === null || update.total === 0
64
+ ? 0
65
+ : Math.min(0.5, update.completed / update.total / 2),
66
+ total: 1,
67
+ }) ?? Promise.resolve(),
68
+ },
69
+ }),
70
+ };
71
+ const inventory = await this.client.callTool(operation === "search_strings" ? "list_strings" : "list_procedures", input.data.document == null ? {} : { document: input.data.document }, inventoryOptions);
72
+ if (!inventory.ok)
73
+ return inventory;
74
+ const parsed = z.array(analysisStringSchema).safeParse(inventory.value);
75
+ if (!parsed.success)
76
+ return err(new AnalysisOutputError(operation, "Hopper search inventory is malformed"));
77
+ if (options.signal?.aborted)
78
+ return err(new AnalysisCancelledError(operation));
79
+ await options.progress
80
+ ?.report({
81
+ phase: "hopper_regex",
82
+ completed: 0.5,
83
+ total: 1,
84
+ message: "Matching inventory in cancellable regex worker",
85
+ })
86
+ .catch(() => undefined);
87
+ if (options.signal?.aborted)
88
+ return err(new AnalysisCancelledError(operation));
89
+ let worker;
90
+ try {
91
+ worker = new Worker(new URL("./HopperRegexWorker.js", import.meta.url), {
92
+ workerData: {
93
+ pattern: input.data.pattern,
94
+ caseSensitive: input.data.case_sensitive,
95
+ values: parsed.data.map((item) => item.value),
96
+ },
97
+ });
98
+ }
99
+ catch (cause) {
100
+ return err(new AnalysisOutputError(operation, `Cannot start regex worker: ${cause instanceof Error ? cause.message : String(cause)}`, { cause }));
101
+ }
102
+ try {
103
+ return await new Promise((resolve) => {
104
+ const finish = (result) => {
105
+ clearTimeout(timer);
106
+ options.signal?.removeEventListener("abort", onAbort);
107
+ resolve(result);
108
+ };
109
+ const onAbort = () => finish(err(new AnalysisCancelledError(operation)));
110
+ const timer = setTimeout(() => finish(err(new AnalysisResourceConstraintError(operation, "cpu", "Regex matching exceeded its supervised deadline; the Hopper API thread remains available.", { matching_deadline_ms: MATCHING_DEADLINE_MS }, {
111
+ remediationAction: "Simplify the ECMAScript Unicode regex or use literal mode, then retry in the same session.",
112
+ }))), MATCHING_DEADLINE_MS);
113
+ options.signal?.addEventListener("abort", onAbort, { once: true });
114
+ if (options.signal?.aborted)
115
+ onAbort();
116
+ worker.once("message", (message) => {
117
+ const reply = replySchema.safeParse(message);
118
+ if (!reply.success)
119
+ return finish(err(new AnalysisOutputError(operation, "Regex worker reply is malformed")));
120
+ if (reply.data.status === "invalid_pattern")
121
+ return finish(err(new HopperRemoteError(-32000, `Invalid regex pattern: ${reply.data.reason}`, { diagnosticType: "invalid_request", operation })));
122
+ const indices = reply.data.indices;
123
+ if (indices.some((index, position) => index >= parsed.data.length ||
124
+ (position > 0 && index <= (indices[position - 1] ?? -1))))
125
+ return finish(err(new AnalysisOutputError(operation, "Regex worker returned invalid inventory indices")));
126
+ const selected = new Set(indices);
127
+ finish(ok(parsed.data.filter((_, index) => selected.has(index))));
128
+ });
129
+ worker.once("error", (cause) => finish(err(new AnalysisOutputError(operation, `Regex worker failed: ${cause.message}`, { cause }))));
130
+ worker.once("exit", (code) => finish(err(new AnalysisOutputError(operation, `Regex worker exited without a result (${code})`))));
131
+ });
132
+ }
133
+ finally {
134
+ await worker.terminate();
135
+ }
136
+ }
137
+ }
@@ -0,0 +1,27 @@
1
+ import { parentPort, workerData } from "node:worker_threads";
2
+ import { z } from "zod";
3
+ const input = z
4
+ .strictObject({
5
+ pattern: z.string().min(1),
6
+ caseSensitive: z.boolean(),
7
+ values: z.array(z.string()),
8
+ })
9
+ .parse(workerData);
10
+ let expression;
11
+ try {
12
+ expression = new RegExp(input.pattern, input.caseSensitive ? "u" : "iu");
13
+ }
14
+ catch (cause) {
15
+ parentPort?.postMessage({
16
+ status: "invalid_pattern",
17
+ reason: cause instanceof Error ? cause.message : String(cause),
18
+ });
19
+ }
20
+ if (expression !== undefined) {
21
+ const indices = [];
22
+ for (const [index, value] of input.values.entries()) {
23
+ if (expression.test(value))
24
+ indices.push(index);
25
+ }
26
+ parentPort?.postMessage({ status: "matched", indices });
27
+ }
@@ -1,5 +1,8 @@
1
- import { HopperCancelledError, HopperProcessError, HopperProtocolError, HopperRemoteError, } from "../domain/hopperErrors.js";
1
+ import { hopperOperationStage } from "./HopperOperationStage.js";
2
+ import { HopperCancelledError, HopperProcessError, HopperProtocolError, HopperRemoteError, HopperTimeoutError, } from "../domain/hopperErrors.js";
2
3
  import { err } from "../domain/result.js";
4
+ /** Node timer ceiling; larger deadlines would be clamped instead of honored. */
5
+ const MAX_TIMEOUT_MS = 2_147_483_647;
3
6
  /** FIFO that keeps the wire serialized until Hopper actually replies. */
4
7
  export class HopperRequestQueue {
5
8
  send;
@@ -8,10 +11,18 @@ export class HopperRequestQueue {
8
11
  constructor(send) {
9
12
  this.send = send;
10
13
  }
11
- /** Queue one request until Hopper replies or the caller cancels it. */
14
+ /** Settle the caller on reply, cancellation, or deadline; retain active wire work. */
12
15
  run(id, method, params, options) {
13
16
  if (options.signal?.aborted === true)
14
17
  return Promise.resolve(err(new HopperCancelledError()));
18
+ const timeoutMs = options.timeoutMs;
19
+ if (timeoutMs !== undefined &&
20
+ (!Number.isInteger(timeoutMs) ||
21
+ timeoutMs < 0 ||
22
+ timeoutMs > MAX_TIMEOUT_MS))
23
+ return Promise.resolve(err(new HopperProtocolError(`Hopper timeoutMs must be an integer between 0 and ${String(MAX_TIMEOUT_MS)}`)));
24
+ if (timeoutMs === 0)
25
+ return Promise.resolve(err(new HopperTimeoutError(0, method, id, "not_started", hopperOperationStage(method))));
15
26
  return new Promise((resolve) => {
16
27
  let entry;
17
28
  const onAbort = options.signal === undefined ? undefined : () => this.#cancel(entry);
@@ -25,12 +36,18 @@ export class HopperRequestQueue {
25
36
  onAbort,
26
37
  callerState: "waiting",
27
38
  callerSettled: false,
39
+ transmitted: false,
28
40
  startedAt: undefined,
29
41
  heartbeat: undefined,
42
+ deadline: undefined,
43
+ deadlineAt: timeoutMs === undefined ? undefined : performance.now() + timeoutMs,
44
+ timeoutMs,
30
45
  };
31
46
  this.#queue.push(entry);
32
47
  if (onAbort !== undefined)
33
48
  options.signal?.addEventListener("abort", onAbort, { once: true });
49
+ if (timeoutMs !== undefined)
50
+ entry.deadline = setTimeout(() => this.#cancel(entry, this.#timeoutError(entry, timeoutMs)), timeoutMs);
34
51
  if (this.#active !== undefined || this.#queue.length > 1)
35
52
  this.#report(entry, `${method} queued behind ${String(this.#size() - 1)} Hopper request(s)`);
36
53
  this.#drain();
@@ -41,17 +58,10 @@ export class HopperRequestQueue {
41
58
  const entry = this.#active;
42
59
  if (entry === undefined || entry.id !== id)
43
60
  return false;
61
+ this.#expireIfElapsed(entry);
44
62
  this.#releaseWire(entry);
45
- if (!entry.callerSettled) {
46
- const contextual = !result.ok && result.error instanceof HopperRemoteError
47
- ? err(new HopperRemoteError(result.error.code, result.error.safeMessage, {
48
- diagnosticType: result.error.diagnosticType,
49
- operation: entry.method,
50
- requestId: entry.id,
51
- }))
52
- : result;
53
- this.#settleCaller(entry, contextual, "waiting");
54
- }
63
+ if (!entry.callerSettled)
64
+ this.#settleCaller(entry, result.ok ? result : err(withRequestContext(result.error, entry)), "waiting");
55
65
  this.#active = undefined;
56
66
  this.#drain();
57
67
  return true;
@@ -120,6 +130,10 @@ export class HopperRequestQueue {
120
130
  const entry = this.#queue.shift();
121
131
  if (entry === undefined)
122
132
  return;
133
+ if (this.#expireIfElapsed(entry)) {
134
+ this.#drain();
135
+ return;
136
+ }
123
137
  if (entry.signal?.aborted === true) {
124
138
  this.#settleCaller(entry, err(new HopperCancelledError()), "cancelled");
125
139
  this.#drain();
@@ -128,6 +142,17 @@ export class HopperRequestQueue {
128
142
  this.#active = entry;
129
143
  entry.startedAt = performance.now();
130
144
  this.#report(entry, `${entry.method} started on Hopper's serial bridge`);
145
+ this.#expireIfElapsed(entry);
146
+ // A progress observer may cancel or tear down synchronously before send.
147
+ // No native work exists yet, so it is safe to release this reserved slot.
148
+ if (this.#active !== entry || entry.callerSettled) {
149
+ if (this.#active === entry) {
150
+ this.#active = undefined;
151
+ this.#releaseWire(entry);
152
+ this.#drain();
153
+ }
154
+ return;
155
+ }
131
156
  entry.heartbeat = setInterval(() => {
132
157
  if (entry.callerSettled || entry.startedAt === undefined)
133
158
  return;
@@ -135,30 +160,44 @@ export class HopperRequestQueue {
135
160
  this.#report(entry, `${entry.method} is still running in Hopper (${String(elapsed)} ms elapsed)`);
136
161
  }, 1_000);
137
162
  try {
138
- this.send({ id: entry.id, method: entry.method, params: entry.params }, () => this.accept(entry.id, err(new HopperProcessError(null))));
163
+ entry.transmitted = true;
164
+ this.send({ id: entry.id, method: entry.method, params: entry.params }, () => this.accept(entry.id, err(new HopperProcessError(null, undefined, entry.method, entry.id, "unreachable", hopperOperationStage(entry.method)))));
139
165
  }
140
166
  catch (cause) {
141
167
  this.accept(entry.id, err(new HopperProtocolError("Hopper socket write failed", { cause })));
142
168
  }
143
169
  }
144
- #cancel(entry) {
170
+ #timeoutError(entry, timeoutMs) {
171
+ return new HopperTimeoutError(timeoutMs, entry.method, entry.id, entry.transmitted ? "busy" : "not_started", hopperOperationStage(entry.method));
172
+ }
173
+ #expireIfElapsed(entry) {
174
+ if (entry.deadlineAt !== undefined &&
175
+ entry.timeoutMs !== undefined &&
176
+ performance.now() >= entry.deadlineAt)
177
+ this.#settleCaller(entry, err(this.#timeoutError(entry, entry.timeoutMs)), "cancelled");
178
+ return entry.callerSettled;
179
+ }
180
+ #cancel(entry, error = new HopperCancelledError()) {
145
181
  if (entry.callerSettled)
146
182
  return;
147
183
  if (this.#active === entry) {
148
- this.#settleCaller(entry, err(new HopperCancelledError()), "cancelled");
184
+ this.#settleCaller(entry, err(error), "cancelled");
149
185
  return;
150
186
  }
151
187
  const index = this.#queue.indexOf(entry);
152
188
  if (index < 0)
153
189
  return;
154
190
  this.#queue.splice(index, 1);
155
- this.#settleCaller(entry, err(new HopperCancelledError()), "cancelled");
191
+ this.#settleCaller(entry, err(error), "cancelled");
156
192
  }
157
193
  #settleCaller(entry, result, callerState) {
158
194
  if (entry.callerSettled)
159
195
  return;
160
196
  entry.callerSettled = true;
161
197
  entry.callerState = callerState;
198
+ if (entry.deadline !== undefined)
199
+ clearTimeout(entry.deadline);
200
+ entry.deadline = undefined;
162
201
  if (this.#active === entry && entry.heartbeat !== undefined) {
163
202
  clearInterval(entry.heartbeat);
164
203
  entry.heartbeat = undefined;
@@ -195,6 +234,16 @@ export class HopperRequestQueue {
195
234
  }
196
235
  }
197
236
  }
198
- const withRequestContext = (error, entry) => error instanceof HopperProcessError
199
- ? new HopperProcessError(error.exitCode, error.diagnostic, entry.method, entry.id)
200
- : error;
237
+ const withRequestContext = (error, entry) => {
238
+ if (error instanceof HopperProcessError)
239
+ return new HopperProcessError(error.exitCode, error.diagnostic, error.operation ?? entry.method, error.requestId ?? entry.id, error.providerState, error.operation === undefined && error.stage === "connection"
240
+ ? hopperOperationStage(entry.method)
241
+ : error.stage);
242
+ if (error instanceof HopperRemoteError)
243
+ return new HopperRemoteError(error.code, error.safeMessage, {
244
+ diagnosticType: error.diagnosticType,
245
+ operation: error.operation ?? entry.method,
246
+ requestId: error.requestId ?? entry.id,
247
+ });
248
+ return error;
249
+ };
@@ -4,10 +4,11 @@ import { createConnection, createServer, } from "node:net";
4
4
  import { join, resolve } from "node:path";
5
5
  import { HopperStartError } from "../domain/hopperErrors.js";
6
6
  import { safeParseJson } from "../domain/safeJson.js";
7
- const leaseDirectory = join("/tmp", `rea-hopper-${process.getuid?.() ?? 0}`);
7
+ /** Shared private parent of per-target lease sockets; it outlives individual sessions. */
8
+ export const HOPPER_TARGET_LEASE_DIRECTORY = join("/tmp", `rea-hopper-${process.getuid?.() ?? 0}`);
8
9
  /** Keep two REA processes from opening duplicate Hopper documents for one target/profile. */
9
10
  export const acquireHopperTargetLease = async (input) => {
10
- const directory = input.directory ?? leaseDirectory;
11
+ const directory = input.directory ?? HOPPER_TARGET_LEASE_DIRECTORY;
11
12
  await ensureLeaseDirectory(directory);
12
13
  // The canonical path only derives the lease key; it never authorizes access.
13
14
  // Common expected `realpath` failures include a missing target or path
@@ -6,6 +6,7 @@ import { parseLinuxPrivateDisplayDiagnostic } from "./LinuxPrivateDisplayDiagnos
6
6
  const PYTHON_PATH = "/usr/bin/python3";
7
7
  const UNSHARE_PATH = "/usr/bin/unshare";
8
8
  const DEFAULT_PROBE_TIMEOUT_MS = 5_000;
9
+ const isAborted = (signal) => signal?.aborted === true;
9
10
  /** Probe the exact Xvfb boundary and select the least-privileged viable strategy. */
10
11
  export const selectLinuxPrivateDisplayStrategy = async (options) => {
11
12
  const timeoutMs = options.timeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
@@ -39,7 +40,7 @@ export const selectLinuxPrivateDisplayStrategy = async (options) => {
39
40
  };
40
41
  /** Run one helper probe in an owned process group and retain its full diagnostics. */
41
42
  export const runLinuxPrivateDisplayProbe = async (strategy, options) => {
42
- if (options.signal?.aborted === true)
43
+ if (isAborted(options.signal))
43
44
  return emptyProcessResult("cancelled");
44
45
  const command = privateDisplayProbeCommand(options.helperPath, strategy);
45
46
  let started;
@@ -49,12 +50,13 @@ export const runLinuxPrivateDisplayProbe = async (strategy, options) => {
49
50
  arguments: command.arguments,
50
51
  runId: randomUUID(),
51
52
  expectedCommand: null,
53
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
52
54
  });
53
55
  }
54
56
  catch (cause) {
55
57
  // best-effort cleanup: probe spawn failure is reported as launch-failed.
56
58
  void cause;
57
- return emptyProcessResult("launch-failed");
59
+ return emptyProcessResult(isAborted(options.signal) ? "cancelled" : "launch-failed");
58
60
  }
59
61
  const launch = {
60
62
  process: started.process,
@@ -1,6 +1,12 @@
1
1
  import { pathToFileURL } from "node:url";
2
2
  import { browserOriginSchema, sanitizeBrowserUrl, } from "../domain/browserObservation.js";
3
+ import { AnalysisCancelledError } from "../domain/analysisErrorCore.js";
3
4
  import { authorizedElectronFile } from "../browser/ElectronFileScope.js";
5
+ /** Throw the operation's typed cancellation error whenever its signal is aborted. */
6
+ export const throwIfRuntimeObservationCancelled = (signal) => {
7
+ if (signal?.aborted === true)
8
+ throw new AnalysisCancelledError("observe_javascript_runtime");
9
+ };
4
10
  /**
5
11
  * Wire bucket for inspector script exclusions. The V8 observation schemas
6
12
  * fix the `unsupported_location` key, so every canonical denial reason maps
@@ -13,7 +19,8 @@ export const inspectorExclusionKey = (reason) => {
13
19
  return "unsupported_location";
14
20
  };
15
21
  /** Resolve a protocol location exposed by the explicitly selected Inspector endpoint. */
16
- export const authorizeRuntimeLocation = async (value) => {
22
+ export const authorizeRuntimeLocation = async (value, signal) => {
23
+ throwIfRuntimeObservationCancelled(signal);
17
24
  if (value.startsWith("node:") && value.length > 0)
18
25
  return {
19
26
  allowed: true,
@@ -21,6 +28,7 @@ export const authorizeRuntimeLocation = async (value) => {
21
28
  };
22
29
  if (value.startsWith("file:")) {
23
30
  const filePath = await authorizedElectronFile(value);
31
+ throwIfRuntimeObservationCancelled(signal);
24
32
  return filePath === undefined
25
33
  ? { allowed: false, reason: "not_approved" }
26
34
  : { allowed: true, location: { kind: "file", file_path: filePath } };
@@ -1,5 +1,5 @@
1
1
  import { createHash } from "node:crypto";
2
- import { authorizeRuntimeLocation, inspectorExclusionKey, } from "./JavaScriptRuntimeScope.js";
2
+ import { authorizeRuntimeLocation, inspectorExclusionKey, throwIfRuntimeObservationCancelled, } from "./JavaScriptRuntimeScope.js";
3
3
  /** Empty durable-location exclusion counters. */
4
4
  export const createInspectorExclusionCounts = () => ({
5
5
  unsupported_location: 0,
@@ -15,7 +15,8 @@ export const describeInspectorTargetLimitations = () => [
15
15
  ];
16
16
  const LOCATION_AUTHORIZATION_WORKERS = 8;
17
17
  /** Canonically authorize, deduplicate, and sort one bounded raw capture. */
18
- export const finalizeInspectorCapture = async ({ input, runtime, target, state, authorizeLocation = authorizeRuntimeLocation, }) => {
18
+ export const finalizeInspectorCapture = async ({ input, runtime, target, state, authorizeLocation = authorizeRuntimeLocation, signal, }) => {
19
+ throwIfRuntimeObservationCancelled(signal);
19
20
  const exclusions = createInspectorExclusionCounts();
20
21
  const scripts = new Map();
21
22
  const draftsByUrl = new Map();
@@ -31,6 +32,7 @@ export const finalizeInspectorCapture = async ({ input, runtime, target, state,
31
32
  const worker = async () => {
32
33
  try {
33
34
  for (;;) {
35
+ throwIfRuntimeObservationCancelled(signal);
34
36
  if (stopScheduling)
35
37
  return;
36
38
  const index = nextGroup;
@@ -41,8 +43,9 @@ export const finalizeInspectorCapture = async ({ input, runtime, target, state,
41
43
  const [rawUrl, drafts] = group;
42
44
  authorizedGroups[index] = {
43
45
  drafts,
44
- decision: await authorizeLocation(rawUrl),
46
+ decision: await authorizeLocation(rawUrl, signal),
45
47
  };
48
+ throwIfRuntimeObservationCancelled(signal);
46
49
  }
47
50
  }
48
51
  catch (cause) {
@@ -52,6 +55,7 @@ export const finalizeInspectorCapture = async ({ input, runtime, target, state,
52
55
  };
53
56
  const workerResults = await Promise.allSettled(Array.from({ length: Math.min(LOCATION_AUTHORIZATION_WORKERS, groups.length) }, worker));
54
57
  const failedWorker = workerResults.find((result) => result.status === "rejected");
58
+ throwIfRuntimeObservationCancelled(signal);
55
59
  if (failedWorker?.status === "rejected")
56
60
  throw failedWorker.reason;
57
61
  for (const { drafts, decision } of authorizedGroups) {
@@ -81,6 +85,7 @@ export const finalizeInspectorCapture = async ({ input, runtime, target, state,
81
85
  : left.context_key > right.context_key
82
86
  ? 1
83
87
  : 0);
88
+ throwIfRuntimeObservationCancelled(signal);
84
89
  return {
85
90
  runtime,
86
91
  target: {
@@ -12,6 +12,11 @@ import { discoverV8Inspector, } from "./V8InspectorEndpoint.js";
12
12
  /** Public identity committed by passive V8 Inspector observations. */
13
13
  export { V8_INSPECTOR_PROVIDER_IDENTITY } from "./providerIdentity.js";
14
14
  import { V8_INSPECTOR_PROVIDER_IDENTITY } from "./providerIdentity.js";
15
+ /** Maximum decoded CDP message accepted while observing one Inspector target. */
16
+ export const INSPECTOR_MAX_PAYLOAD_BYTES = 16 * 1024 * 1024;
17
+ /** Aggregate retained metadata budget, including an estimate of JS object overhead. */
18
+ export const INSPECTOR_MAX_RETAINED_METADATA_BYTES = 8 * 1024 * 1024;
19
+ const RETAINED_OBJECT_OVERHEAD_BYTES = 512;
15
20
  /** Attach-only provider; sends only Runtime.enable and Debugger.enable. */
16
21
  export class V8InspectorProvider {
17
22
  identity() {
@@ -61,7 +66,7 @@ export class V8InspectorProvider {
61
66
  const target = await authorizedTarget(discovery.targets, input, discovery.runtime.product);
62
67
  if (input.runtime_kind !== undefined)
63
68
  assertRuntimeKind(target, input.runtime_kind);
64
- connection = await CdpConnection.connect(target.webSocketUrl, "observe_javascript_runtime", options.signal);
69
+ connection = await CdpConnection.connect(target.webSocketUrl, "observe_javascript_runtime", options.signal, { maxPayloadBytes: INSPECTOR_MAX_PAYLOAD_BYTES });
65
70
  const state = emptyCaptureState();
66
71
  const removeListener = connection.onEvent((event) => ingestEvent(event, input, state));
67
72
  try {
@@ -77,6 +82,7 @@ export class V8InspectorProvider {
77
82
  runtime: discovery.runtime,
78
83
  target,
79
84
  state,
85
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
80
86
  });
81
87
  outcome = ok(javascriptRuntimeObservationSchema.parse(result));
82
88
  }
@@ -206,15 +212,24 @@ const ingestScript = (event, input, state) => {
206
212
  length: nonnegativeInteger(value?.length),
207
213
  isModule: value?.isModule === true,
208
214
  };
209
- const bytes = metadataBytes(draft);
210
- retainEvent(state, bytes);
215
+ const bytes = retainedMetadataBytes(draft);
216
+ if (!retainEvent(state, bytes))
217
+ return;
211
218
  state.scripts.push(draft);
212
219
  };
213
220
  const ingestContext = (event, input, state) => {
214
221
  if (event.method === "Runtime.executionContextsCleared") {
215
- for (const context of state.contexts.values())
216
- context.state = "cleared";
217
- retainEvent(state, 0);
222
+ let byteDelta = 0;
223
+ for (const context of state.contexts.values()) {
224
+ byteDelta +=
225
+ retainedMetadataBytes({ ...context, state: "cleared" }) -
226
+ retainedMetadataBytes(context);
227
+ }
228
+ if (replaceRetainedMetadata(state, byteDelta)) {
229
+ for (const context of state.contexts.values())
230
+ context.state = "cleared";
231
+ retainEvent(state, 0);
232
+ }
218
233
  return;
219
234
  }
220
235
  const parameters = recordValue(event.params);
@@ -238,18 +253,33 @@ const ingestContext = (event, input, state) => {
238
253
  : "destroyed",
239
254
  origin: origin === "" ? null : origin,
240
255
  };
241
- const bytes = metadataBytes(draft);
242
- retainEvent(state, bytes);
256
+ const previous = state.contexts.get(key);
257
+ const bytes = retainedMetadataBytes(draft) -
258
+ (previous === undefined ? 0 : retainedMetadataBytes(previous));
259
+ if (!retainEvent(state, bytes))
260
+ return;
243
261
  state.contexts.set(key, draft);
244
262
  };
245
263
  const retainEvent = (state, bytes) => {
246
- state.metadataBytes += bytes;
264
+ if (!replaceRetainedMetadata(state, bytes))
265
+ return false;
247
266
  state.eventsRetained += 1;
267
+ return true;
268
+ };
269
+ const replaceRetainedMetadata = (state, byteDelta) => {
270
+ if (state.metadataBytes + byteDelta > INSPECTOR_MAX_RETAINED_METADATA_BYTES) {
271
+ state.eventsDropped += 1;
272
+ state.truncated = true;
273
+ state.truncationReasons.add("retained_metadata_budget_exceeded");
274
+ return false;
275
+ }
276
+ state.metadataBytes += byteDelta;
277
+ return true;
248
278
  };
249
279
  const waitForCapture = async (connection, observationMs, signal) => {
250
280
  let removeDisconnect = () => undefined;
251
281
  const disconnected = new Promise((_resolve, reject) => {
252
- removeDisconnect = connection.onDisconnect(() => reject(new BrowserObservationError("observe_javascript_runtime", "disconnected")));
282
+ removeDisconnect = connection.onDisconnect((error) => reject(error));
253
283
  });
254
284
  try {
255
285
  await Promise.race([
@@ -261,7 +291,13 @@ const waitForCapture = async (connection, observationMs, signal) => {
261
291
  removeDisconnect();
262
292
  }
263
293
  };
264
- const metadataBytes = (value) => Buffer.byteLength(JSON.stringify(value));
294
+ const retainedMetadataBytes = (value) => {
295
+ const strings = "rawUrl" in value
296
+ ? [value.rawUrl, value.rawUrl, value.executionContextKey, value.cdpHash]
297
+ : [value.contextKey, value.origin];
298
+ return (RETAINED_OBJECT_OVERHEAD_BYTES +
299
+ strings.reduce((total, text) => total + (text?.length ?? 0) * 2, 0));
300
+ };
265
301
  const nonnegativeInteger = (value) => {
266
302
  const parsed = numberValue(value);
267
303
  return parsed === undefined ? 0 : Math.max(0, Math.trunc(parsed));
@@ -51,8 +51,11 @@ export const runWakaruCommand = async (context) => {
51
51
  runId,
52
52
  cwd: context.cwd,
53
53
  hostEnvironment: context.environment,
54
+ ...(context.signal === undefined ? {} : { signal: context.signal }),
54
55
  env: { TMPDIR: context.cwd, RAYON_NUM_THREADS: "1", NO_COLOR: "1" },
55
56
  }).catch((cause) => {
57
+ if (context.signal?.aborted === true)
58
+ throw new AnalysisCancelledError(OPERATION);
56
59
  throw new ProviderAdapterError("wakaru", OPERATION, {
57
60
  cause,
58
61
  diagnostics: {
@@ -0,0 +1,47 @@
1
+ import { TraceMap, decodedMappings } from "@jridgewell/trace-mapping";
2
+ import { SourceMapFormatFailure, } from "./SourceMapFormat.js";
3
+ /** Determine whether a leaf-local mapping falls before its enclosing boundary. */
4
+ export const isBeforeSourceMapLeafStop = (leaf, line, column) => {
5
+ if (leaf.stop === null)
6
+ return true;
7
+ const generatedLine = leaf.offset.line + line;
8
+ const generatedColumn = column + (line === 0 ? leaf.offset.column : 0);
9
+ return (generatedLine < leaf.stop.line ||
10
+ (generatedLine === leaf.stop.line && generatedColumn < leaf.stop.column));
11
+ };
12
+ /** Resolve one declaration with the same pinned upstream implementation used by full maps. */
13
+ export const resolveSourceMapSource = (source, sourceRoot, mapUrl) => {
14
+ const map = new TraceMap({
15
+ version: 3,
16
+ names: [],
17
+ sources: [source ?? ""],
18
+ ...(sourceRoot == null ? {} : { sourceRoot }),
19
+ mappings: "",
20
+ }, mapUrl);
21
+ const resolved = map.resolvedSources[0];
22
+ if (resolved === undefined)
23
+ throw new SourceMapFormatFailure("format", "Source-map resolver did not return the requested source identity.");
24
+ return resolved;
25
+ };
26
+ /** Decode leaf mappings and validate producer indices before any consumer publishes them. */
27
+ export const decodeValidatedSourceMapLeaves = (leaves, mapUrl, check) => leaves.map((leaf) => {
28
+ check?.();
29
+ const map = new TraceMap(JSON.stringify(leaf.map), mapUrl);
30
+ const rows = decodedMappings(map);
31
+ for (const [line, row] of rows.entries()) {
32
+ if ((line & 255) === 0)
33
+ check?.();
34
+ for (const segment of row) {
35
+ const generatedLine = leaf.offset.line + line;
36
+ const generatedColumn = segment[0] + (line === 0 ? leaf.offset.column : 0);
37
+ if (!Number.isSafeInteger(generatedLine) ||
38
+ !Number.isSafeInteger(generatedColumn) ||
39
+ ![1, 4, 5].includes(segment.length) ||
40
+ segment.some((value) => !Number.isSafeInteger(value) || value < 0) ||
41
+ (segment.length !== 1 && segment[1] >= leaf.map.sources.length) ||
42
+ (segment.length === 5 && segment[4] >= leaf.map.names.length))
43
+ throw new SourceMapFormatFailure("format", "Decoded local or absolute position, source index or name index is invalid.");
44
+ }
45
+ }
46
+ return { leaf, rows, resolvedSources: map.resolvedSources };
47
+ });