rea-agents 4.0.0 → 4.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 (416) hide show
  1. package/README.md +93 -30
  2. package/bridge/ghidra/ReaGhidraBridge.java +358 -15
  3. package/bridge/ghidra/ReaGhidraExtensions.java +113 -0
  4. package/bridge/ghidra/ReaGhidraPrepareCom.java +32 -0
  5. package/dist/android/AndroidTargetSnapshot.js +34 -0
  6. package/dist/android/JadxAnalysis.js +191 -0
  7. package/dist/android/JadxConfiguration.js +41 -0
  8. package/dist/android/JadxMcpTransport.js +145 -0
  9. package/dist/android/JadxProtocol.js +101 -0
  10. package/dist/android/JadxProvider.js +170 -0
  11. package/dist/android/JadxRelease.js +19 -0
  12. package/dist/android/JadxSession.js +97 -0
  13. package/dist/application/AnalysisContextQueries.js +2 -1
  14. package/dist/application/AnalysisProviderEvaluation.js +5 -3
  15. package/dist/application/AnalysisProviderRegistry.js +2 -1
  16. package/dist/application/AnalysisSnapshotCache.js +4 -1
  17. package/dist/application/AnalysisSnapshotFiles.js +1 -1
  18. package/dist/application/AndroidAnalysisPort.js +1 -0
  19. package/dist/application/AndroidAnalysisService.js +37 -0
  20. package/dist/application/ArtifactExtraction.js +7 -4
  21. package/dist/application/ArtifactGraphConstruction.js +10 -17
  22. package/dist/application/ArtifactInventory/scanCanonical.js +8 -7
  23. package/dist/application/BinarySession.js +16 -3
  24. package/dist/application/BinarySessionExecution.js +4 -1
  25. package/dist/application/BinarySessionOpen.js +3 -2
  26. package/dist/application/BinarySessionRecords.js +9 -3
  27. package/dist/application/BinaryTargetResolver.js +25 -6
  28. package/dist/application/BrowserObservationService.js +2 -1
  29. package/dist/application/BrowserScenarioCaptureService.js +2 -1
  30. package/dist/application/BrowserScenarioEvidence.js +2 -2
  31. package/dist/application/CallPathTracing.js +2 -1
  32. package/dist/application/CapabilityInventory.js +18 -0
  33. package/dist/application/ClientConfigPath.js +3 -1
  34. package/dist/application/ClientConfigurationDocument.js +11 -1
  35. package/dist/application/ClientRegistrationStatus.js +8 -1
  36. package/dist/application/CompositeProvider.js +1 -1
  37. package/dist/application/DirectAnalysis.js +23 -7
  38. package/dist/application/DirectAnalysisStatus.js +3 -3
  39. package/dist/application/Doctor.js +48 -8
  40. package/dist/application/DoctorDiagnostics.js +7 -5
  41. package/dist/application/DoctorScope.js +1 -1
  42. package/dist/application/ElectronActiveEvidence.js +2 -2
  43. package/dist/application/ElectronActiveObservationService.js +2 -1
  44. package/dist/application/ElectronBoundaryAnalysis.js +1 -1
  45. package/dist/application/ElectronObservationService.js +2 -1
  46. package/dist/application/EnhancedLiteralTracing.js +2 -1
  47. package/dist/application/EnhancedToolTypes.js +2 -1
  48. package/dist/application/EnhancedTools.js +3 -1
  49. package/dist/application/EvidenceBundleCommands.js +2 -1
  50. package/dist/application/EvidenceBundleFiles.js +1 -1
  51. package/dist/application/EvidenceInputResolver.js +30 -0
  52. package/dist/application/EvidenceLedger.js +2 -1
  53. package/dist/application/FirmwareAnalysisPort.js +1 -0
  54. package/dist/application/FirmwareAnalysisService.js +35 -0
  55. package/dist/application/FunctionAnalysisEvidence.js +32 -0
  56. package/dist/application/InventoryProjectionEvidence.js +2 -1
  57. package/dist/application/JavaScriptApplicationService.js +50 -3
  58. package/dist/application/JavaScriptApplicationWorkflowService.js +2 -1
  59. package/dist/application/JavaScriptArtifactAnalysis.js +4 -2
  60. package/dist/application/JavaScriptArtifactFiles.js +4 -2
  61. package/dist/application/JavaScriptArtifactPathResolution.js +6 -2
  62. package/dist/application/JavaScriptJsonModules.js +3 -2
  63. package/dist/application/JavaScriptModuleRelationships.js +4 -2
  64. package/dist/application/JavaScriptRuntimeObservationService.js +2 -1
  65. package/dist/application/JavaScriptRuntimeReconciliationService.js +2 -1
  66. package/dist/application/JavaScriptSemanticGraphProjection.js +1 -1
  67. package/dist/application/JavaScriptSemanticTraceService.js +2 -1
  68. package/dist/application/JsonFiles.js +1 -1
  69. package/dist/application/LazyAnalysisProvider.js +3 -1
  70. package/dist/application/LinuxHopper.js +12 -4
  71. package/dist/application/MacHopper.js +20 -7
  72. package/dist/application/ManagedApplicationGraphService.js +2 -1
  73. package/dist/application/ManagedMemberComparisonService.js +3 -1
  74. package/dist/application/ManagedNativeVerificationService.js +2 -1
  75. package/dist/application/ManagedReconstructionService.js +2 -1
  76. package/dist/application/NativeCallRoutes.js +1 -1
  77. package/dist/application/NativeDispatchMetadataInspection.js +1 -1
  78. package/dist/application/NativeUiActionTrace.js +2 -1
  79. package/dist/application/NativeValueTrace.js +1 -1
  80. package/dist/application/ProcessCaptureError.js +1 -1
  81. package/dist/application/ProcessCaptureJournal.js +3 -1
  82. package/dist/application/ProcessCaptureLifecycle.js +6 -3
  83. package/dist/application/ProcessCli.js +9 -5
  84. package/dist/application/ProcessEvidence.js +2 -6
  85. package/dist/application/ProcessHarness.js +3 -2
  86. package/dist/application/ProcessNormalization.js +12 -5
  87. package/dist/application/ProcessSampling.js +3 -1
  88. package/dist/application/ReconstructionCoverageService.js +2 -1
  89. package/dist/application/ReconstructionObligationLedgerService.js +2 -1
  90. package/dist/application/ReferenceSourceImportEntries.js +2 -0
  91. package/dist/application/ReferenceSourceImportPolicy.js +4 -2
  92. package/dist/application/ReferenceSourceVcsAdapter.js +35 -4
  93. package/dist/application/SessionProviderRouter.js +4 -1
  94. package/dist/application/Setup.js +1 -128
  95. package/dist/application/SetupClientConfiguration.js +17 -6
  96. package/dist/application/SetupHost.js +111 -0
  97. package/dist/application/SetupRegistrationEnvironment.js +1 -2
  98. package/dist/application/SetupSkill.js +9 -3
  99. package/dist/application/SetupTypes.js +17 -0
  100. package/dist/application/StoreFileLock.js +7 -2
  101. package/dist/application/SupportedClients.js +8 -0
  102. package/dist/application/Uninstall.js +9 -4
  103. package/dist/application/UpdateRuntime.js +5 -2
  104. package/dist/application/WindowsCapabilities.js +7 -7
  105. package/dist/application/runtime.js +3 -1
  106. package/dist/artifacts/ArtifactProvider.js +3 -1
  107. package/dist/artifacts/DirectoryArtifactReader.js +2 -0
  108. package/dist/artifacts/NativeDmgArtifactReader.js +10 -3
  109. package/dist/artifacts/NibArchive.js +4 -2
  110. package/dist/artifacts/SafeOutputTree.js +26 -10
  111. package/dist/artifacts/ZipArtifactReader.js +1 -0
  112. package/dist/browser/BrowserProcessStartup.js +3 -1
  113. package/dist/browser/CdpAuthorizedMainFrame.js +1 -1
  114. package/dist/browser/CdpBrowserProvider.js +4 -1
  115. package/dist/browser/CdpCaptureDocuments.js +3 -1
  116. package/dist/browser/CdpCaptureEventHandlers.js +6 -2
  117. package/dist/browser/CdpCaptureStorageFingerprints.js +1 -1
  118. package/dist/browser/CdpCaptureValues.js +6 -2
  119. package/dist/browser/CdpConnection.js +8 -6
  120. package/dist/browser/CdpElectronInspection.js +3 -3
  121. package/dist/browser/CdpElectronProvider.js +4 -1
  122. package/dist/browser/CdpElectronScripts.js +2 -2
  123. package/dist/browser/CdpEndpoint.js +22 -10
  124. package/dist/browser/CdpObservationSession.js +2 -1
  125. package/dist/browser/CdpOptionalCommand.js +1 -1
  126. package/dist/browser/CdpPageCapture.js +2 -1
  127. package/dist/browser/CdpSafeMetadata.js +53 -8
  128. package/dist/browser/CdpScreenshot.js +1 -1
  129. package/dist/browser/CdpTargetSession.js +8 -5
  130. package/dist/browser/CdpWebMcpDiscovery.js +1 -1
  131. package/dist/browser/ElectronFileScope.js +9 -3
  132. package/dist/browser/JavaScriptRuntimeScope.js +3 -1
  133. package/dist/browser/PlaywrightBrowserScenarioProvider.js +3 -1
  134. package/dist/browser/PlaywrightElectronActiveActions.js +1 -1
  135. package/dist/browser/PlaywrightElectronActiveProvider.js +6 -2
  136. package/dist/browser/PlaywrightExecutionBoundary.js +1 -1
  137. package/dist/browser/PlaywrightScenarioArtifacts.js +10 -5
  138. package/dist/browser/PlaywrightScenarioBrowser.js +3 -1
  139. package/dist/browser/PlaywrightScenarioEvents.js +6 -2
  140. package/dist/browser/PlaywrightScenarioSession.js +5 -2
  141. package/dist/browser/V8InspectorEndpoint.js +2 -1
  142. package/dist/browser/V8InspectorProvider.js +6 -1
  143. package/dist/browser/WebSourceMapFetcher.js +24 -11
  144. package/dist/cli/androidCommands.js +81 -0
  145. package/dist/{cliApplicationCommands.js → cli/applicationCommands.js} +18 -16
  146. package/dist/{cliBrowserAdvancedCommands.js → cli/browserAdvancedCommands.js} +13 -16
  147. package/dist/{cliBrowserCommands.js → cli/browserCommands.js} +9 -9
  148. package/dist/cli/commandCancellation.js +24 -0
  149. package/dist/cli/coreAnalysisCommands.js +110 -17
  150. package/dist/{cliElectronCommands.js → cli/electronCommands.js} +14 -13
  151. package/dist/cli/firmwareCommands.js +75 -0
  152. package/dist/{cliSetup.js → cli/interactiveSetup.js} +1 -1
  153. package/dist/cli/javascriptApplicationAnalysis.js +1 -1
  154. package/dist/cli/managedCommands.js +1 -1
  155. package/dist/cli/managedProjectGraphCommand.js +1 -1
  156. package/dist/cli/options.js +7 -1
  157. package/dist/{cliProcessCommands.js → cli/processCommands.js} +3 -3
  158. package/dist/cli/referenceSourceImportStatus.js +10 -0
  159. package/dist/cli/setupCommands.js +4 -2
  160. package/dist/cli/utilityCommands.js +3 -2
  161. package/dist/cli.js +10 -15
  162. package/dist/cliBrowserContext.js +1 -1
  163. package/dist/cliBrowserScenarioCommands.js +2 -1
  164. package/dist/cliCommandNames.js +11 -2
  165. package/dist/cliEvidenceCommands.js +2 -1
  166. package/dist/cliJavaScriptRuntimeCommands.js +2 -1
  167. package/dist/cliJsonInput.js +26 -11
  168. package/dist/cliLogging.js +2 -1
  169. package/dist/cliOutput.js +15 -16
  170. package/dist/config/environment.js +11 -1
  171. package/dist/config/parseConfig.js +7 -1
  172. package/dist/config/parsers.js +1 -1
  173. package/dist/contracts/androidToolContracts.js +77 -0
  174. package/dist/contracts/applicationToolContracts.js +32 -5
  175. package/dist/contracts/applicationWorkflowInputContracts.js +13 -13
  176. package/dist/contracts/artifactComparisonExample.js +7 -14
  177. package/dist/contracts/enhancedToolContracts.js +31 -0
  178. package/dist/contracts/errorSchemas.js +4 -2
  179. package/dist/contracts/evidenceInputContracts.js +13 -0
  180. package/dist/contracts/firmwareToolContracts.js +38 -0
  181. package/dist/contracts/officialToolContracts.js +66 -0
  182. package/dist/contracts/promptContracts.js +1 -1
  183. package/dist/contracts/sessionLifecycleInputs.js +4 -0
  184. package/dist/contracts/sessionToolContracts.js +43 -0
  185. package/dist/contracts/sessionToolSchemas.js +1 -1
  186. package/dist/contracts/toolContractExamples.js +5 -0
  187. package/dist/contracts/toolContractTypes.js +2 -0
  188. package/dist/contracts/toolContracts.js +7 -130
  189. package/dist/contracts/toolEffects.js +43 -0
  190. package/dist/contracts/toolOutputSchemaGroups.js +4 -0
  191. package/dist/contracts/toolOutputSchemaPrimitives.js +1 -0
  192. package/dist/doctorRuntime.js +5 -1
  193. package/dist/domain/analysisErrorBase.js +33 -0
  194. package/dist/domain/analysisErrorCore.js +60 -0
  195. package/dist/domain/analysisErrorPresentation.js +22 -2
  196. package/dist/domain/analysisErrorProjection.js +24 -3
  197. package/dist/domain/analysisSnapshot.js +1 -0
  198. package/dist/domain/androidAnalysis.js +141 -0
  199. package/dist/domain/appleAssetCatalog.js +1 -1
  200. package/dist/domain/artifactGraph.js +1 -0
  201. package/dist/domain/artifactInspection.js +19 -17
  202. package/dist/domain/artifactInventoryEvidence.js +20 -25
  203. package/dist/domain/artifactOperationError.js +16 -0
  204. package/dist/domain/browserObservation.js +12 -4
  205. package/dist/domain/browserObservationError.js +23 -0
  206. package/dist/domain/browserScenario.js +1 -1
  207. package/dist/domain/browserScenarioCapture.js +1 -1
  208. package/dist/domain/browserScenarioDiff.js +1 -1
  209. package/dist/domain/browserScenarioNormalization.js +6 -11
  210. package/dist/domain/browserScenarioValues.js +3 -1
  211. package/dist/domain/callPath.js +47 -7
  212. package/dist/domain/canonicalDigest.js +65 -0
  213. package/dist/domain/canonicalOrdering.js +11 -0
  214. package/dist/domain/changedBehavior.js +8 -7
  215. package/dist/domain/comparisonSemantics.js +2 -4
  216. package/dist/domain/configurationErrors.js +25 -0
  217. package/dist/domain/dosCom.js +8 -0
  218. package/dist/domain/electronActiveObservation.js +3 -1
  219. package/dist/domain/electronStaticAnalysisBrowser.js +13 -23
  220. package/dist/domain/electronStaticAnalysisNative.js +2 -1
  221. package/dist/domain/electronStaticAnalysisValues.js +23 -3
  222. package/dist/domain/evidence.js +3 -11
  223. package/dist/domain/evidenceErrors.js +30 -0
  224. package/dist/domain/firmwareAnalysis.js +121 -0
  225. package/dist/domain/functionComparison.js +4 -2
  226. package/dist/domain/functionComparisonDimensions.js +6 -4
  227. package/dist/domain/functionComparisonNormalization.js +8 -1
  228. package/dist/domain/functionComparisonResults.js +1 -4
  229. package/dist/domain/hopperErrors.js +78 -0
  230. package/dist/domain/hopperValues.js +2 -1
  231. package/dist/domain/interfaceBuilderGraph.js +3 -1
  232. package/dist/domain/javascriptApplicationChangeGraph.js +2 -2
  233. package/dist/domain/javascriptApplicationGraph.js +13 -22
  234. package/dist/domain/javascriptApplicationVersionComparison.js +3 -11
  235. package/dist/domain/javascriptApplicationVersionItems.js +3 -3
  236. package/dist/domain/javascriptApplicationVersionKeys.js +1 -1
  237. package/dist/domain/javascriptAstFingerprint.js +1 -1
  238. package/dist/domain/javascriptExportShapeComparison.js +1 -2
  239. package/dist/domain/javascriptExportShapeSelection.js +1 -1
  240. package/dist/domain/javascriptExportShapeVariants.js +7 -3
  241. package/dist/domain/javascriptFeatureSeed.js +29 -9
  242. package/dist/domain/javascriptFeatureTrace.js +9 -13
  243. package/dist/domain/javascriptFeatureTraversal.js +2 -1
  244. package/dist/domain/javascriptNativeHandoff.js +2 -1
  245. package/dist/domain/javascriptRuntimeLoadState.js +2 -2
  246. package/dist/domain/javascriptRuntimeReconciliationActive.js +3 -10
  247. package/dist/domain/javascriptRuntimeReconciliationGraph.js +2 -2
  248. package/dist/domain/javascriptRuntimeReconciliationMatching.js +4 -3
  249. package/dist/domain/javascriptRuntimeReconciliationParsing.js +8 -14
  250. package/dist/domain/javascriptRuntimeReconciliationResult.js +4 -4
  251. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +5 -2
  252. package/dist/domain/javascriptRuntimeStaticCandidates.js +8 -4
  253. package/dist/domain/javascriptSemanticAnalysis.js +40 -3
  254. package/dist/domain/javascriptSemanticCallResolution.js +2 -1
  255. package/dist/domain/javascriptSemanticChildProcesses.js +2 -1
  256. package/dist/domain/javascriptSemanticDataEffects.js +2 -1
  257. package/dist/domain/javascriptSemanticFingerprints.js +1 -1
  258. package/dist/domain/javascriptSemanticGraph.js +23 -28
  259. package/dist/domain/javascriptSemanticPrimitives.js +9 -2
  260. package/dist/domain/javascriptSemanticProjection.js +2 -1
  261. package/dist/domain/javascriptSemanticPromises.js +2 -1
  262. package/dist/domain/javascriptSemanticProvenance.js +1 -1
  263. package/dist/domain/javascriptSemanticQuery.js +7 -8
  264. package/dist/domain/javascriptSemanticQueryAssessment.js +1 -2
  265. package/dist/domain/javascriptSemanticQueryIdentity.js +1 -2
  266. package/dist/domain/javascriptSemanticReturns.js +2 -1
  267. package/dist/domain/javascriptSemanticValues.js +50 -16
  268. package/dist/domain/javascriptSourceParser.js +4 -2
  269. package/dist/domain/javascriptStaticAnalysis.js +1 -1
  270. package/dist/domain/javascriptStaticAnalysisBundler.js +2 -1
  271. package/dist/domain/javascriptStaticAnalysisCalls.js +14 -6
  272. package/dist/domain/javascriptStaticAnalysisHelpers.js +31 -4
  273. package/dist/domain/jsonShape.js +6 -2
  274. package/dist/domain/managedMemberComparison.js +1 -0
  275. package/dist/domain/managedMemberComparisonItems.js +2 -0
  276. package/dist/domain/managedNativeVerificationMatch.js +5 -3
  277. package/dist/domain/nativeDataType.js +2 -0
  278. package/dist/domain/nativeFunctionAnnotations.js +43 -0
  279. package/dist/domain/nativeLoadImage.js +95 -0
  280. package/dist/domain/nativeMetadataRecovery.js +55 -0
  281. package/dist/domain/processCapture.js +0 -1
  282. package/dist/domain/processEvidenceProvider.js +11 -0
  283. package/dist/domain/processTraceComparison.js +1 -1
  284. package/dist/domain/providerAdapterError.js +17 -0
  285. package/dist/domain/providerCleanupError.js +1 -1
  286. package/dist/domain/providerSelectionError.js +44 -0
  287. package/dist/domain/reconstructionUnknowns.js +1 -1
  288. package/dist/domain/reconstructionVerification.js +22 -8
  289. package/dist/domain/referenceSourceClassification.js +5 -6
  290. package/dist/domain/referenceSourceGraph.js +9 -17
  291. package/dist/domain/referenceSourceImportParsing.js +38 -23
  292. package/dist/domain/runtimeIdentification.js +1 -1
  293. package/dist/domain/runtimeVersion.js +4 -7
  294. package/dist/domain/safeJson.js +13 -0
  295. package/dist/domain/sourceToBundleComparison.js +5 -7
  296. package/dist/domain/sourceToBundleSignals.js +6 -6
  297. package/dist/domain/staticRuntimeCorrelation.js +9 -7
  298. package/dist/domain/unknownRegistryError.js +10 -0
  299. package/dist/domain/webBundleAnalyzerAst.js +22 -5
  300. package/dist/domain/webBundleAnalyzerInspection.js +20 -14
  301. package/dist/dotnet/ManagedMemberRows.js +1 -1
  302. package/dist/dotnet/ManagedMetadataHeaps.js +3 -2
  303. package/dist/dotnet/ManagedMetadataInventoryRows.js +4 -2
  304. package/dist/dotnet/ManagedMethodBodyReader.js +8 -1
  305. package/dist/dotnet/ManagedStaticProvider.js +3 -1
  306. package/dist/firmware/FirmwareCommand.js +163 -0
  307. package/dist/firmware/FirmwareFiles.js +190 -0
  308. package/dist/firmware/FirmwareProvider.js +258 -0
  309. package/dist/firmware/FirmwarePublication.js +84 -0
  310. package/dist/firmware/FirmwareRelease.js +32 -0
  311. package/dist/firmware/FirmwareReports.js +223 -0
  312. package/dist/generatedMcpToolCatalog.js +1 -1
  313. package/dist/generatedPackageMetadata.js +5 -5
  314. package/dist/ghidra/GhidraAnalysisProfile.js +37 -8
  315. package/dist/ghidra/GhidraClient.js +52 -6
  316. package/dist/ghidra/GhidraDiagnostics.js +3 -0
  317. package/dist/ghidra/GhidraDoctor.js +38 -14
  318. package/dist/ghidra/GhidraFunctionValues.js +10 -4
  319. package/dist/ghidra/GhidraInstallation.js +10 -4
  320. package/dist/ghidra/GhidraInventoryValues.js +39 -2
  321. package/dist/ghidra/GhidraLauncher.js +91 -26
  322. package/dist/ghidra/GhidraLoadImageValues.js +199 -0
  323. package/dist/ghidra/GhidraProvider.js +129 -13
  324. package/dist/ghidra/GhidraProviderCapabilities.js +52 -15
  325. package/dist/ghidra/GhidraRequestQueue.js +2 -2
  326. package/dist/ghidra/GhidraSessionError.js +31 -4
  327. package/dist/ghidra/GhidraSessionValues.js +10 -7
  328. package/dist/ghidra/GhidraTargetSnapshot.js +16 -2
  329. package/dist/ghidra/GhidraTransport.js +12 -0
  330. package/dist/ghidra/extensions/GhidraExtensionFailures.js +20 -0
  331. package/dist/ghidra/extensions/GhidraExtensions.js +170 -0
  332. package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +21 -0
  333. package/dist/ghidra/extensions/nativeaot/NativeAotReport.js +84 -0
  334. package/dist/hopper/BridgeLauncher.js +4 -2
  335. package/dist/hopper/HopperAnalysisProfile.js +7 -2
  336. package/dist/hopper/HopperCleanup.js +55 -9
  337. package/dist/hopper/HopperClient.js +14 -4
  338. package/dist/hopper/HopperProcessDiagnostic.js +1 -1
  339. package/dist/hopper/HopperProvider.js +8 -4
  340. package/dist/hopper/HopperRequestQueue.js +7 -3
  341. package/dist/hopper/HopperSessionValues.js +1 -1
  342. package/dist/hopper/HopperSocketConnection.js +1 -1
  343. package/dist/hopper/HopperTargetLease.js +23 -15
  344. package/dist/hopper/LinuxPrivateDisplayDiagnostic.js +7 -8
  345. package/dist/hopper/LinuxPrivateDisplayProbe.js +6 -2
  346. package/dist/hopper/protocol.js +8 -8
  347. package/dist/ida/IdaConfiguration.js +56 -0
  348. package/dist/ida/IdaDoctor.js +53 -0
  349. package/dist/ida/IdaInput.js +62 -0
  350. package/dist/ida/IdaMcpConnection.js +111 -0
  351. package/dist/ida/IdaOperationRunner.js +299 -0
  352. package/dist/ida/IdaProtocolValues.js +178 -0
  353. package/dist/ida/IdaProvider.js +126 -0
  354. package/dist/ida/IdaProviderCapabilities.js +60 -0
  355. package/dist/ida/IdaSessionClient.js +306 -0
  356. package/dist/ida/IdaWorkspace.js +54 -0
  357. package/dist/main/shutdown.js +21 -1
  358. package/dist/main/startup.js +1 -1
  359. package/dist/main/transport.js +8 -4
  360. package/dist/main.js +5 -2
  361. package/dist/native/AppleDispatchMetadata.js +31 -10
  362. package/dist/native/NativeMacOSProvider.js +87 -15
  363. package/dist/native/NativeMachoInspection.js +42 -12
  364. package/dist/native/NativeUiHelperRuntime.js +7 -1
  365. package/dist/native/NativeUiObservation.js +6 -2
  366. package/dist/native/parsers/demangle.js +1 -1
  367. package/dist/native/parsers/dyldInfo.js +3 -3
  368. package/dist/native/parsers/otool.js +4 -1
  369. package/dist/native/parsers/plist.js +11 -3
  370. package/dist/process/PrivateRuntimeRoot.js +13 -3
  371. package/dist/process/ProcessOwnership.js +5 -73
  372. package/dist/process/ProcessOwnershipObservation.js +62 -2
  373. package/dist/process/ProcessOwnershipProcessTree.js +13 -0
  374. package/dist/process/ProviderProcess.js +24 -7
  375. package/dist/process/ProviderRunLineage.js +1 -1
  376. package/dist/process/WindowsAuthority.js +20 -1
  377. package/dist/reference/ReferenceSourceReaderEntries.js +5 -1
  378. package/dist/reference/ReferenceSourceReaderFile.js +1 -0
  379. package/dist/server/createServer.js +25 -2
  380. package/dist/server/mcpProgress.js +2 -1
  381. package/dist/server/promptCompletion.js +3 -3
  382. package/dist/server/registerAndroidTools.js +30 -0
  383. package/dist/server/registerApplicationTools/compareExportShapes.js +5 -1
  384. package/dist/server/registerApplicationTools/compareSourceToBundle.js +7 -2
  385. package/dist/server/registerApplicationTools/compareVersions.js +5 -1
  386. package/dist/server/registerApplicationTools/traceFeature.js +7 -2
  387. package/dist/server/registerApplicationTools/traceSemantics.js +7 -2
  388. package/dist/server/registerEnhancedTools.js +28 -1
  389. package/dist/server/registerFirmwareTools.js +22 -0
  390. package/dist/server/registerFunctionComparisonTool.js +1 -1
  391. package/dist/server/registerInvestigationTools/helpers.js +2 -1
  392. package/dist/server/registerManagedTools.js +1 -1
  393. package/dist/server/registerManagedWorkflowTools/evidence.js +1 -1
  394. package/dist/server/registerOfficialTools.js +4 -1
  395. package/dist/server/registerProcessComparisonTool.js +5 -2
  396. package/dist/server/registerSessionTools.js +3 -1
  397. package/dist/server/runDerivedOperation.js +1 -1
  398. package/dist/server/sessionAvailabilityPolicy.js +3 -0
  399. package/dist/server/sessionEvidence.js +1 -1
  400. package/dist/server/toolResult.js +2 -1
  401. package/dist/windows/WindowsNativeLoader.js +108 -0
  402. package/dist/windows/WindowsOwnedProcess.js +168 -0
  403. package/dist/windows/WindowsPrivateRuntime.js +137 -0
  404. package/install.sh +4 -6
  405. package/native/windows/README.md +102 -0
  406. package/native/windows/build/manifest.json +9 -0
  407. package/native/windows/build/rea-windows-x64.node +0 -0
  408. package/package.json +38 -24
  409. package/scripts/rea.mjs +1 -1
  410. package/scripts/verify-windows-native-artifact.mjs +39 -0
  411. package/skills/reverse-engineer-anything/SKILL.md +92 -24
  412. package/skills/reverse-engineer-anything/references/android-applications.md +31 -0
  413. package/skills/reverse-engineer-anything/references/javascript-applications.md +19 -2
  414. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +52 -4
  415. package/dist/browser/CdpCanonicalJsonDigest.js +0 -9
  416. package/dist/domain/errors.js +0 -324
@@ -1,10 +1,8 @@
1
1
  import { execFile } from "node:child_process";
2
- import { readFile } from "node:fs/promises";
3
2
  import { promisify } from "node:util";
4
- import { observeOwnedProcessGroupWithHost, observeOwnedProcessLineageWithHost, } from "./ProcessOwnershipObservation.js";
3
+ import { createSystemProcessOwnershipHost, errorMessage, } from "./ProcessOwnershipObservation.js";
5
4
  import { launcherIdentityFailure } from "./ProcessOwnershipIdentity.js";
6
5
  import { descendantsOf, liveProcesses } from "./ProcessOwnershipProcessTree.js";
7
- import { execFileOutput } from "./ExecFileOutput.js";
8
6
  const execFileAsync = promisify(execFile);
9
7
  /**
10
8
  * Terminate one Windows process tree through the platform utility.
@@ -20,71 +18,16 @@ export const cleanupWindowsProcessTree = async (rootPid, host = systemWindowsPro
20
18
  const result = await host.terminateTree(rootPid);
21
19
  return { cleaned: true, signaled: result === "terminated" };
22
20
  }
23
- catch {
21
+ catch (cause) {
22
+ // The reason string is a pinned validation contract; keep it stable and
23
+ // do not interpolate the cause into caller-visible diagnostics here.
24
+ void cause;
24
25
  return {
25
26
  cleaned: false,
26
27
  reason: "Windows P0 process-tree termination failed; Job Object ownership is unavailable",
27
28
  };
28
29
  }
29
30
  };
30
- /** Select the PTY root group and groups led by an observed captured process. */
31
- export const selectCapturedProcessGroupIds = (rootPid, samples) => {
32
- const processGroupIds = new Set([rootPid]);
33
- for (const sample of samples) {
34
- // A sampled member may transiently inherit an unrelated group. POSIX group
35
- // leaders have pid === pgid, so only that observation establishes that the
36
- // group leader itself belonged to the captured tree. Token checks below
37
- // remain the final authority immediately before observation or signaling.
38
- if (sample.pid === sample.process_group_id)
39
- processGroupIds.add(sample.pid);
40
- }
41
- return [...processGroupIds];
42
- };
43
- /** Parse the NUL-delimited Linux process environment without nameless keys. */
44
- export const parseProcessEnvironment = (value) => Object.fromEntries(value
45
- .split("\0")
46
- .filter((entry) => entry.indexOf("=") > 0)
47
- .map((entry) => {
48
- const separator = entry.indexOf("=");
49
- return [entry.slice(0, separator), entry.slice(separator + 1)];
50
- }));
51
- /** Create the operating-system process inspector for an explicit host context. */
52
- export const createSystemProcessOwnershipHost = (platform = process.platform, hostEnvironment = process.env) => ({
53
- platform,
54
- async listProcesses() {
55
- if (platform === "win32")
56
- return [];
57
- const { stdout } = await execFileOutput("ps", ["-axo", "pid=,ppid=,pgid=,stat=,command="], { env: hostEnvironment });
58
- return stdout
59
- .split("\n")
60
- .map((line) => /\s*(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(.*)/u.exec(line))
61
- .filter((match) => match !== null)
62
- .map((match) => ({
63
- pid: Number(match[1]),
64
- parentPid: Number(match[2]),
65
- processGroupId: Number(match[3]),
66
- state: match[4] ?? "",
67
- command: match[5] ?? "",
68
- }));
69
- },
70
- async environment(pid) {
71
- if (platform === "linux")
72
- return parseProcessEnvironment(await readFile(`/proc/${pid}/environ`, "utf8"));
73
- const { stdout } = await execFileOutput("ps", ["eww", "-p", String(pid)], {
74
- env: hostEnvironment,
75
- });
76
- const observedEnvironment = {};
77
- for (const match of stdout.matchAll(/(?:^|\s)([A-Za-z_][A-Za-z0-9_]*)=([^\s]*)/gu)) {
78
- const name = match[1];
79
- if (name !== undefined)
80
- observedEnvironment[name] = match[2] ?? "";
81
- }
82
- return observedEnvironment;
83
- },
84
- signalGroup(processGroupId, signal) {
85
- process.kill(-processGroupId, signal);
86
- },
87
- });
88
31
  const systemHost = createSystemProcessOwnershipHost();
89
32
  const systemWindowsProcessTreeHost = {
90
33
  async terminateTree(rootPid) {
@@ -309,14 +252,3 @@ const scanTokenOwnedProcesses = async (processes, runId, host) => {
309
252
  }
310
253
  return { owned, failures };
311
254
  };
312
- const errorMessage = (cause) => cause instanceof Error ? cause.message : String(cause);
313
- /** Observe one group without signaling it, failing closed on identity doubt. */
314
- export const observeOwnedProcessGroup = async (ownership, host = systemHost) => observeOwnedProcessGroupWithHost(ownership, host);
315
- /**
316
- * Record the live launcher and descendant lineage after run-token validation.
317
- *
318
- * The observation is intentionally point-in-time. A verified empty descendant
319
- * list means no descendants were live during this observation, not that the
320
- * run never created a short-lived child.
321
- */
322
- export const observeOwnedProcessLineage = async (ownership, host = systemHost) => observeOwnedProcessLineageWithHost(ownership, host);
@@ -1,5 +1,7 @@
1
+ import { readFile } from "node:fs/promises";
1
2
  import { launcherIdentityFailure } from "./ProcessOwnershipIdentity.js";
2
3
  import { descendantsOf, liveProcesses } from "./ProcessOwnershipProcessTree.js";
4
+ import { execFileOutput } from "./ExecFileOutput.js";
3
5
  /** Observe one group without signaling it, failing closed on identity doubt. */
4
6
  export const observeOwnedProcessGroupWithHost = async (ownership, host) => {
5
7
  let members;
@@ -95,12 +97,70 @@ const unavailableLineage = (ownership, reason) => ({
95
97
  processGroupId: ownership.processGroupId,
96
98
  reason,
97
99
  });
100
+ /** Parse the NUL-delimited Linux process environment without nameless keys. */
101
+ export const parseProcessEnvironment = (value) => Object.fromEntries(value
102
+ .split("\0")
103
+ .filter((entry) => entry.indexOf("=") > 0)
104
+ .map((entry) => {
105
+ const separator = entry.indexOf("=");
106
+ return [entry.slice(0, separator), entry.slice(separator + 1)];
107
+ }));
108
+ /** Create the operating-system process inspector for an explicit host context. */
109
+ export const createSystemProcessOwnershipHost = (platform = process.platform, hostEnvironment = process.env) => ({
110
+ platform,
111
+ async listProcesses() {
112
+ if (platform === "win32")
113
+ return [];
114
+ const { stdout } = await execFileOutput("ps", ["-axo", "pid=,ppid=,pgid=,stat=,command="], { env: hostEnvironment });
115
+ return stdout
116
+ .split("\n")
117
+ .map((line) => /\s*(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(.*)/u.exec(line))
118
+ .filter((match) => match !== null)
119
+ .map((match) => ({
120
+ pid: Number(match[1]),
121
+ parentPid: Number(match[2]),
122
+ processGroupId: Number(match[3]),
123
+ state: match[4] ?? "",
124
+ command: match[5] ?? "",
125
+ }));
126
+ },
127
+ async environment(pid) {
128
+ if (platform === "linux")
129
+ return parseProcessEnvironment(await readFile(`/proc/${pid}/environ`, "utf8"));
130
+ const { stdout } = await execFileOutput("ps", ["eww", "-p", String(pid)], {
131
+ env: hostEnvironment,
132
+ });
133
+ const observedEnvironment = {};
134
+ for (const match of stdout.matchAll(/(?:^|\s)([A-Za-z_][A-Za-z0-9_]*)=([^\s]*)/gu)) {
135
+ const name = match[1];
136
+ if (name !== undefined)
137
+ observedEnvironment[name] = match[2] ?? "";
138
+ }
139
+ return observedEnvironment;
140
+ },
141
+ signalGroup(processGroupId, signal) {
142
+ process.kill(-processGroupId, signal);
143
+ },
144
+ });
145
+ const systemHost = createSystemProcessOwnershipHost();
146
+ /** Observe one group without signaling it, failing closed on identity doubt. */
147
+ export const observeOwnedProcessGroup = async (ownership, host = systemHost) => observeOwnedProcessGroupWithHost(ownership, host);
148
+ /**
149
+ * Record the live launcher and descendant lineage after run-token validation.
150
+ *
151
+ * The observation is intentionally point-in-time. A verified empty descendant
152
+ * list means no descendants were live during this observation, not that the
153
+ * run never created a short-lived child.
154
+ */
155
+ export const observeOwnedProcessLineage = async (ownership, host = systemHost) => observeOwnedProcessLineageWithHost(ownership, host);
98
156
  const processIsGone = async (host, pid) => {
99
157
  try {
100
158
  return !liveProcesses(await host.listProcesses()).some((process) => process.pid === pid);
101
159
  }
102
- catch {
160
+ catch (cause) {
161
+ // best-effort cleanup: optional liveness probing; failure means not gone.
162
+ void cause;
103
163
  return false;
104
164
  }
105
165
  };
106
- const errorMessage = (cause) => cause instanceof Error ? cause.message : String(cause);
166
+ export const errorMessage = (cause) => cause instanceof Error ? cause.message : String(cause);
@@ -20,3 +20,16 @@ export const descendantsOf = (launcherPid, processes) => {
20
20
  }
21
21
  return descendants;
22
22
  };
23
+ /** Select the PTY root group and groups led by an observed captured process. */
24
+ export const selectCapturedProcessGroupIds = (rootPid, samples) => {
25
+ const processGroupIds = new Set([rootPid]);
26
+ for (const sample of samples) {
27
+ // A sampled member may transiently inherit an unrelated group. POSIX group
28
+ // leaders have pid === pgid, so only that observation establishes that the
29
+ // group leader itself belonged to the captured tree. Token checks below
30
+ // remain the final authority immediately before observation or signaling.
31
+ if (sample.pid === sample.process_group_id)
32
+ processGroupIds.add(sample.pid);
33
+ }
34
+ return [...processGroupIds];
35
+ };
@@ -1,8 +1,9 @@
1
1
  import { spawn } from "node:child_process";
2
+ import { WindowsOwnedProcess } from "../windows/WindowsOwnedProcess.js";
2
3
  const DEFAULT_TERMINATION_GRACE_MS = 250;
3
4
  const DEFAULT_KILL_GRACE_MS = 1_000;
4
5
  /**
5
- * Spawn a provider in a dedicated POSIX process group with an ownership token.
6
+ * Spawn a provider in an owned Windows job or dedicated POSIX process group.
6
7
  *
7
8
  * The caller remains responsible for persisting any ownership manifest and for
8
9
  * selecting provider-specific command arguments or environment values.
@@ -10,17 +11,33 @@ const DEFAULT_KILL_GRACE_MS = 1_000;
10
11
  export const spawnOwnedProviderProcess = async (options) => {
11
12
  const platform = options.platform ?? process.platform;
12
13
  const hostEnvironment = options.hostEnvironment ?? process.env;
14
+ const environment = {
15
+ ...hostEnvironment,
16
+ ...options.env,
17
+ REA_PROCESS_RUN_ID: options.runId,
18
+ };
19
+ if (platform === "win32" && process.platform === "win32") {
20
+ if (options.stdin === "pipe")
21
+ throw new Error("Owned Windows provider processes do not support protocol stdin");
22
+ const child = new WindowsOwnedProcess(options.command, options.arguments, options.cwd, environment, options.windowsVerbatimArguments ?? false);
23
+ return {
24
+ process: child,
25
+ ownership: {
26
+ runId: options.runId,
27
+ leaderPid: child.pid,
28
+ processGroupId: child.pid,
29
+ expectedParentPid: process.pid,
30
+ },
31
+ cleanup: () => child.cleanup(),
32
+ };
33
+ }
13
34
  const child = spawn(options.command, [...options.arguments], {
14
35
  shell: false,
15
36
  windowsHide: true,
16
- stdio: ["ignore", "pipe", "pipe"],
37
+ stdio: [options.stdin ?? "ignore", "pipe", "pipe"],
17
38
  detached: platform !== "win32",
18
39
  windowsVerbatimArguments: options.windowsVerbatimArguments ?? false,
19
- env: {
20
- ...hostEnvironment,
21
- ...options.env,
22
- REA_PROCESS_RUN_ID: options.runId,
23
- },
40
+ env: environment,
24
41
  ...(options.cwd === undefined ? {} : { cwd: options.cwd }),
25
42
  });
26
43
  await waitForSpawn(child);
@@ -1,4 +1,4 @@
1
- import { observeOwnedProcessLineage } from "./ProcessOwnership.js";
1
+ import { observeOwnedProcessLineage } from "./ProcessOwnershipObservation.js";
2
2
  /** Retain the latest truthful process-lineage observation for one client. */
3
3
  export class ProviderRunLineage {
4
4
  #observation = null;
@@ -1,5 +1,6 @@
1
+ import { systemWindowsNativeAuthority } from "../windows/WindowsNativeLoader.js";
1
2
  /** Stable explanation used whenever the native Windows authority is absent. */
2
- export const WINDOWS_NATIVE_AUTHORITY_UNAVAILABLE_REASON = "Verified Windows native authority is unavailable: Job Object process ownership, private runtime DACL enforcement, and reparse-safe path admission are not implemented; chmod(0700) is insufficient for Windows private DACL proof, and taskkill is not a Job Object security proof";
3
+ export const WINDOWS_NATIVE_AUTHORITY_UNAVAILABLE_REASON = "Windows native controls are unavailable in this runtime; use the Windows x64 REA package with its matching bundled native artifact.";
3
4
  /**
4
5
  * Describe native Windows controls without inferring them from taskkill,
5
6
  * chmod, symlink creation, or a numeric POSIX open flag.
@@ -17,6 +18,21 @@ export const windowsNativeCapabilities = (platform) => {
17
18
  reparse_safe_path_admission: notApplicable,
18
19
  };
19
20
  }
21
+ if (process.platform === "win32") {
22
+ const loaded = systemWindowsNativeAuthority();
23
+ const capability = loaded.available
24
+ ? { available: true, reason: null, proof: "native-authority" }
25
+ : {
26
+ available: false,
27
+ reason: loaded.reason,
28
+ proof: "not-proven",
29
+ };
30
+ return {
31
+ job_object_process_ownership: capability,
32
+ private_runtime_dacl: capability,
33
+ reparse_safe_path_admission: capability,
34
+ };
35
+ }
20
36
  const notProven = {
21
37
  available: false,
22
38
  reason: WINDOWS_NATIVE_AUTHORITY_UNAVAILABLE_REASON,
@@ -30,3 +46,6 @@ export const windowsNativeCapabilities = (platform) => {
30
46
  };
31
47
  /** Whether every native control needed for Windows isolation is proven. */
32
48
  export const hasWindowsNativeAuthority = (platform) => Object.values(windowsNativeCapabilities(platform)).every(({ available }) => available);
49
+ /** Preserve the actual loader or operating-system constraint in provider errors. */
50
+ export const windowsNativeAuthorityUnavailableReason = (platform) => windowsNativeCapabilities(platform).job_object_process_ownership.reason ??
51
+ WINDOWS_NATIVE_AUTHORITY_UNAVAILABLE_REASON;
@@ -189,7 +189,11 @@ const applyExclusion = (shouldExclude, path) => {
189
189
  try {
190
190
  return { ok: true, value: shouldExclude?.(path) === true };
191
191
  }
192
- catch {
192
+ catch (cause) {
193
+ // Exclusion predicates are caller-supplied; a throwing predicate fails
194
+ // closed and the caller-visible `{ ok: false }` preserves the rejection
195
+ // without propagating an arbitrary predicate cause.
196
+ void cause;
193
197
  return { ok: false };
194
198
  }
195
199
  };
@@ -102,6 +102,7 @@ export const readStableFile = async (request) => {
102
102
  return entryFailure(path, "file", "io", message, safeSize(expected.size));
103
103
  }
104
104
  finally {
105
+ // best-effort cleanup: file-handle close must not mask the read result.
105
106
  await handle?.close().catch(() => undefined);
106
107
  }
107
108
  };
@@ -1,4 +1,5 @@
1
1
  import { McpServer } from "@modelcontextprotocol/server";
2
+ import { isAbsolute } from "node:path";
2
3
  import { PRODUCT_IDENTITY } from "../identity.js";
3
4
  import { silentLogger } from "../logger.js";
4
5
  import { registerApplicationTools } from "./registerApplicationTools.js";
@@ -9,6 +10,12 @@ import { registerElectronTools } from "./registerElectronTools.js";
9
10
  import { registerEnhancedTools } from "./registerEnhancedTools.js";
10
11
  import { registerJavaScriptRuntimeObservationTools } from "./registerJavaScriptRuntimeObservationTools.js";
11
12
  import { registerManagedTools } from "./registerManagedTools.js";
13
+ import { registerFirmwareTools } from "./registerFirmwareTools.js";
14
+ import { FirmwareAnalysisService } from "../application/FirmwareAnalysisService.js";
15
+ import { FirmwareProvider } from "../firmware/FirmwareProvider.js";
16
+ import { registerAndroidTools } from "./registerAndroidTools.js";
17
+ import { AndroidAnalysisService } from "../application/AndroidAnalysisService.js";
18
+ import { JadxProvider } from "../android/JadxProvider.js";
12
19
  import { registerManagedWorkflowTools } from "./registerManagedWorkflowTools.js";
13
20
  import { registerNativeTools } from "./registerNativeTools.js";
14
21
  import { registerOfficialTools } from "./registerOfficialTools.js";
@@ -22,6 +29,15 @@ const installSessionToolAvailability = (server, session, options) => {
22
29
  return undefined;
23
30
  const policy = sessionAvailabilityPolicy(options.availabilityPolicy, {
24
31
  optionalFeatures: {
32
+ firmwareInspectionEnabled: options.firmwareAnalysis !== undefined ||
33
+ (process.platform === "linux" &&
34
+ isAbsolute(process.env.REA_BINWALK_COMMAND ?? "")),
35
+ firmwareExtractionEnabled: options.firmwareAnalysis !== undefined ||
36
+ (process.platform === "linux" &&
37
+ isAbsolute(process.env.REA_UNBLOB_COMMAND ?? "")),
38
+ androidAnalysisEnabled: options.androidAnalysis !== undefined ||
39
+ ((process.platform === "linux" || process.platform === "darwin") &&
40
+ isAbsolute(process.env.REA_JADX_MCP_JAR ?? "")),
25
41
  browserObservationEnabled: options.browserObservation !== undefined,
26
42
  browserScenarioEnabled: options.browserScenarioCapture !== undefined,
27
43
  electronObservationEnabled: options.electronObservation !== undefined,
@@ -53,18 +69,21 @@ export const createServer = (analysis, session, options = {}) => {
53
69
  const server = createMcpServer(session);
54
70
  const availability = installSessionToolAvailability(server, session, options);
55
71
  const toolLogger = logger.child({ layer: "server" });
56
- const { activeTarget, recordEvidence, recordEvidenceWithUnknown } = createSessionRecorders(server, session);
72
+ const { evidenceById, activeTarget, recordEvidence, recordEvidenceWithUnknown, } = createSessionRecorders(server, session);
57
73
  const toolContext = {
58
74
  server,
59
75
  analysis,
60
76
  session,
61
77
  options,
62
78
  logger: toolLogger,
79
+ evidenceById,
63
80
  activeTarget,
64
81
  recordEvidence,
65
82
  recordEvidenceWithUnknown,
66
83
  };
67
84
  registerBinaryAnalysisTools(toolContext);
85
+ registerAndroidTools(server, new AndroidAnalysisService(options.androidAnalysis ?? new JadxProvider()), toolLogger, recordEvidence);
86
+ registerFirmwareTools(server, new FirmwareAnalysisService(options.firmwareAnalysis ?? new FirmwareProvider()), toolLogger, recordEvidence);
68
87
  registerObservationTools(toolContext);
69
88
  registerGuidedPrompts(server, analysis, session);
70
89
  if (session !== undefined) {
@@ -79,6 +98,9 @@ export const createServer = (analysis, session, options = {}) => {
79
98
  return server;
80
99
  };
81
100
  const createSessionRecorders = (server, session) => ({
101
+ evidenceById: session === undefined
102
+ ? undefined
103
+ : (evidenceId) => session.evidenceById(evidenceId),
82
104
  activeTarget: session === undefined ? undefined : () => session.activeTarget(),
83
105
  recordEvidence: session === undefined
84
106
  ? undefined
@@ -125,7 +147,7 @@ const registerBinaryAnalysisTools = ({ server, analysis, session, logger, active
125
147
  session,
126
148
  });
127
149
  };
128
- const registerObservationTools = ({ server, options, logger, recordEvidence, recordEvidenceWithUnknown, }) => {
150
+ const registerObservationTools = ({ evidenceById, server, options, logger, recordEvidence, recordEvidenceWithUnknown, }) => {
129
151
  const common = { logger, recordEvidence };
130
152
  registerBrowserTools(server, {
131
153
  ...common,
@@ -145,6 +167,7 @@ const registerObservationTools = ({ server, options, logger, recordEvidence, rec
145
167
  runtime: options.javascriptRuntimeObservation,
146
168
  });
147
169
  registerApplicationTools(server, {
170
+ evidenceById,
148
171
  logger,
149
172
  recordEvidence,
150
173
  recordEvidenceWithUnknown,
@@ -16,8 +16,9 @@ export const mcpProgressReporter = (context) => {
16
16
  },
17
17
  });
18
18
  }
19
- catch {
19
+ catch (cause) {
20
20
  // Progress is observational; transport failure cannot change tool truth.
21
+ void cause;
21
22
  }
22
23
  }, { minimumIntervalMs: 100 });
23
24
  };
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { uniqueSorted } from "../domain/canonicalOrdering.js";
2
3
  import { artifactInventoryResultSchema } from "../domain/artifactGraph.js";
3
4
  import { artifactInspectionResultSchema } from "../domain/artifactInspection.js";
4
5
  import { processCaptureSchema } from "../domain/processCapture.js";
@@ -14,7 +15,8 @@ export const createPromptCompletionSource = (analysis, session) => ({
14
15
  async complete(kind, value, context) {
15
16
  const candidates = await completionCandidates(kind, analysis, session, context);
16
17
  const prefix = normalize(value);
17
- return uniqueSorted(candidates).filter((candidate) => normalize(candidate).startsWith(prefix));
18
+ const nonEmpty = candidates.filter((candidate) => candidate.length > 0);
19
+ return uniqueSorted(nonEmpty).filter((candidate) => normalize(candidate).startsWith(prefix));
18
20
  },
19
21
  });
20
22
  const completionCandidates = async (kind, analysis, session, context) => {
@@ -121,6 +123,4 @@ const unknownCandidates = (session) => session === undefined
121
123
  .listUnknowns()
122
124
  .filter(({ status }) => status !== "resolved")
123
125
  .map(({ unknown_id: id }) => id);
124
- const uniqueSorted = (values) => [...new Set(values.filter((value) => value.length > 0))].sort(compareText);
125
- const compareText = (left, right) => left < right ? -1 : left > right ? 1 : 0;
126
126
  const normalize = (value) => value.normalize("NFKC").toLowerCase();
@@ -0,0 +1,30 @@
1
+ import { AndroidAnalysisService } from "../application/AndroidAnalysisService.js";
2
+ import { toolContract } from "../contracts/toolContracts.js";
3
+ import { logToolExecution } from "./toolLogging.js";
4
+ import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
5
+ import { toCallToolResult } from "./toolResult.js";
6
+ /** Bind Android handlers to their exact named contracts through shared workflows. */
7
+ export const registerAndroidTools = (server, service, logger, recordEvidence) => {
8
+ const handler = (contract) => {
9
+ const name = contract.name;
10
+ return async (input, context) => {
11
+ const result = await logToolExecution(logger, name, () => service.execute(name, input, { signal: context.mcpReq.signal }));
12
+ if (!result.ok)
13
+ return toCallToolResult(result, contract);
14
+ const recorded = recordEvidence?.(result.value);
15
+ return recorded !== undefined && !recorded.ok
16
+ ? toCallToolResult(recorded, contract)
17
+ : toCallToolResult(result, contract);
18
+ };
19
+ };
20
+ const packageContract = toolContract("inspect_android_package");
21
+ server.registerTool(packageContract.name, toolRegistrationOptions(packageContract), handler(packageContract));
22
+ const searchContract = toolContract("search_android_classes");
23
+ server.registerTool(searchContract.name, toolRegistrationOptions(searchContract), handler(searchContract));
24
+ const classContract = toolContract("inspect_android_class");
25
+ server.registerTool(classContract.name, toolRegistrationOptions(classContract), handler(classContract));
26
+ const methodContract = toolContract("inspect_android_method");
27
+ server.registerTool(methodContract.name, toolRegistrationOptions(methodContract), handler(methodContract));
28
+ const referencesContract = toolContract("trace_android_references");
29
+ server.registerTool(referencesContract.name, toolRegistrationOptions(referencesContract), handler(referencesContract));
30
+ };
@@ -1,3 +1,4 @@
1
+ import { resolvePairedEvidenceRequest } from "../../application/EvidenceInputResolver.js";
1
2
  import { recordSessionEvidenceSources } from "../sessionEvidence.js";
2
3
  import { compareJavaScriptExportShapesEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
3
4
  import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
@@ -10,7 +11,10 @@ const contract = applicationToolContract("compare_javascript_export_shapes");
10
11
  /** Register the execution-free exact JavaScript export-shape comparison. */
11
12
  export const registerCompareJavaScriptExportShapesTool = (server, options) => {
12
13
  server.registerTool(contract.name, toolRegistrationOptions(contract), async (input) => {
13
- const parsed = input;
14
+ const resolved = resolvePairedEvidenceRequest(input, options.evidenceById);
15
+ if (!resolved.ok)
16
+ return toCallToolResult(resolved, contract);
17
+ const parsed = resolved.value;
14
18
  const result = await logToolExecution(options.logger, contract.name, () => Promise.resolve(compareJavaScriptExportShapesEvidenceValidated(parsed)));
15
19
  if (!result.ok)
16
20
  return toCallToolResult(result, contract);
@@ -1,3 +1,4 @@
1
+ import { resolveApplicationEvidenceRequest } from "../../application/EvidenceInputResolver.js";
1
2
  import { recordSessionEvidenceSources } from "../sessionEvidence.js";
2
3
  import { compareSourceToBundleEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
3
4
  import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
@@ -10,11 +11,15 @@ const contract = applicationToolContract("compare_source_to_bundle");
10
11
  /** Register conservative historical-source to bundle comparison. */
11
12
  export const registerCompareSourceToBundleTool = (server, options) => {
12
13
  server.registerTool(contract.name, toolRegistrationOptions(contract), async (input) => {
13
- const result = await logToolExecution(options.logger, contract.name, () => Promise.resolve(compareSourceToBundleEvidenceValidated(input)));
14
+ const resolved = resolveApplicationEvidenceRequest(input, options.evidenceById);
15
+ if (!resolved.ok)
16
+ return toCallToolResult(resolved, contract);
17
+ const parsed = resolved.value;
18
+ const result = await logToolExecution(options.logger, contract.name, () => Promise.resolve(compareSourceToBundleEvidenceValidated(parsed)));
14
19
  if (!result.ok)
15
20
  return toCallToolResult(result, contract);
16
21
  const recorded = recordSessionEvidenceSources(options.recordEvidence, [
17
- input.application,
22
+ parsed.application,
18
23
  ]);
19
24
  if (!recorded.ok)
20
25
  return toCallToolResult(recorded, contract);
@@ -1,3 +1,4 @@
1
+ import { resolvePairedEvidenceRequest } from "../../application/EvidenceInputResolver.js";
1
2
  import { recordSessionEvidenceSources } from "../sessionEvidence.js";
2
3
  import { compareApplicationVersionsEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
3
4
  import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
@@ -10,7 +11,10 @@ const compareContract = applicationToolContract("compare_application_versions");
10
11
  /** Register the provider-neutral JavaScript version comparison tool. */
11
12
  export const registerCompareApplicationVersionsTool = (server, options) => {
12
13
  server.registerTool(compareContract.name, toolRegistrationOptions(compareContract), async (input) => {
13
- const parsed = input;
14
+ const resolved = resolvePairedEvidenceRequest(input, options.evidenceById);
15
+ if (!resolved.ok)
16
+ return toCallToolResult(resolved, compareContract);
17
+ const parsed = resolved.value;
14
18
  const result = await logToolExecution(options.logger, compareContract.name, () => Promise.resolve(compareApplicationVersionsEvidenceValidated(parsed)));
15
19
  if (!result.ok)
16
20
  return toCallToolResult(result, compareContract);
@@ -1,3 +1,4 @@
1
+ import { resolveApplicationEvidenceRequest } from "../../application/EvidenceInputResolver.js";
1
2
  import { recordSessionEvidenceSources } from "../sessionEvidence.js";
2
3
  import { traceApplicationFeatureEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
3
4
  import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
@@ -9,10 +10,14 @@ const traceContract = applicationToolContract("trace_application_feature");
9
10
  /** Register the provider-neutral JavaScript feature trace tool. */
10
11
  export const registerTraceFeatureTool = (server, options) => {
11
12
  server.registerTool(traceContract.name, toolRegistrationOptions(traceContract), async (input) => {
12
- const result = await logToolExecution(options.logger, traceContract.name, () => Promise.resolve(traceApplicationFeatureEvidenceValidated(input)));
13
+ const resolved = resolveApplicationEvidenceRequest(input, options.evidenceById);
14
+ if (!resolved.ok)
15
+ return toCallToolResult(resolved, traceContract);
16
+ const parsed = resolved.value;
17
+ const result = await logToolExecution(options.logger, traceContract.name, () => Promise.resolve(traceApplicationFeatureEvidenceValidated(parsed)));
13
18
  if (!result.ok)
14
19
  return toCallToolResult(result, traceContract);
15
- const sources = [input.application, ...input.native_observations];
20
+ const sources = [parsed.application, ...parsed.native_observations];
16
21
  const recorded = recordSessionEvidenceSources(options.recordEvidence, sources);
17
22
  if (!recorded.ok)
18
23
  return toCallToolResult(recorded, traceContract);
@@ -1,3 +1,4 @@
1
+ import { resolveApplicationEvidenceRequest } from "../../application/EvidenceInputResolver.js";
1
2
  import { recordSessionEvidenceSources } from "../sessionEvidence.js";
2
3
  import { traceJavaScriptSemanticsEvidenceValidated } from "../../application/JavaScriptSemanticTraceService.js";
3
4
  import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
@@ -9,11 +10,15 @@ const contract = applicationToolContract("trace_javascript_semantics");
9
10
  /** Register the bounded JavaScript semantic relation trace tool. */
10
11
  export const registerTraceJavaScriptSemanticsTool = (server, options) => {
11
12
  server.registerTool(contract.name, toolRegistrationOptions(contract), async (input) => {
12
- const result = await logToolExecution(options.logger, contract.name, () => Promise.resolve(traceJavaScriptSemanticsEvidenceValidated(input)));
13
+ const resolved = resolveApplicationEvidenceRequest(input, options.evidenceById);
14
+ if (!resolved.ok)
15
+ return toCallToolResult(resolved, contract);
16
+ const parsed = resolved.value;
17
+ const result = await logToolExecution(options.logger, contract.name, () => Promise.resolve(traceJavaScriptSemanticsEvidenceValidated(parsed)));
13
18
  if (!result.ok)
14
19
  return toCallToolResult(result, contract);
15
20
  const recorded = recordSessionEvidenceSources(options.recordEvidence, [
16
- input.application,
21
+ parsed.application,
17
22
  ]);
18
23
  if (!recorded.ok)
19
24
  return toCallToolResult(recorded, contract);
@@ -1,12 +1,13 @@
1
1
  import { EnhancedTools, } from "../application/EnhancedTools.js";
2
2
  import { REA_WORKFLOW_PROVIDER, workflowAnalysisProfile, } from "../application/InvestigationProviders.js";
3
3
  import { toolContract } from "../contracts/toolContracts.js";
4
- import { UnknownRegistryError } from "../domain/errors.js";
4
+ import { UnknownRegistryError } from "../domain/unknownRegistryError.js";
5
5
  import { createEvidence } from "../domain/evidence.js";
6
6
  import { mcpProgressReporter } from "./mcpProgress.js";
7
7
  import { logToolExecution } from "./toolLogging.js";
8
8
  import { toolRegistrationOptions } from "./toolRegistrationOptions.js";
9
9
  import { toCallToolResult } from "./toolResult.js";
10
+ import { executeFunctionAnalysisEvidence } from "../application/FunctionAnalysisEvidence.js";
10
11
  /** Register composed workflows against the same port as direct bridge tools. */
11
12
  // oxlint-disable-next-line max-lines-per-function -- direct SDK calls retain each schema-handler type correlation.
12
13
  export const registerEnhancedTools = (server, analysis, options) => {
@@ -93,6 +94,11 @@ const executeEnhancedTool = async (analysis, registration, contract, request) =>
93
94
  });
94
95
  const parsedInput = validatedCall.input;
95
96
  const parameters = jsonParameters(parsedInput);
97
+ if (name === "analyze_function")
98
+ return executeFunctionTool(analysis, registration, contract, {
99
+ context,
100
+ parameters,
101
+ });
96
102
  const services = new EnhancedTools({
97
103
  execute: (operation, operationParameters, executionOptions) => analysis.execute(operation, operationParameters, {
98
104
  ...executionOptions,
@@ -138,6 +144,27 @@ const executeEnhancedTool = async (analysis, registration, contract, request) =>
138
144
  }
139
145
  return toCallToolResult(result, contract);
140
146
  };
147
+ const executeFunctionTool = async (analysis, registration, contract, request) => {
148
+ const { context, parameters } = request;
149
+ const progress = mcpProgressReporter(context);
150
+ const result = await logToolExecution(registration.logger, "analyze_function", () => executeFunctionAnalysisEvidence(analysis, parameters, registration.activeTarget?.(), {
151
+ signal: context.mcpReq.signal,
152
+ progress,
153
+ }));
154
+ await progress.report({
155
+ phase: "analyze_function",
156
+ completed: 1,
157
+ total: 1,
158
+ message: result.ok ? "completed" : "failed",
159
+ terminal: true,
160
+ });
161
+ if (result.ok) {
162
+ const recorded = registration.recordEvidence?.(result.value);
163
+ if (recorded !== undefined && !recorded.ok)
164
+ return toCallToolResult(recorded, contract);
165
+ }
166
+ return toCallToolResult(result, contract);
167
+ };
141
168
  const jsonParameters = (input) => Object.fromEntries(Object.entries(input).filter((entry) => entry[1] !== undefined));
142
169
  const recordWorkflowUnknowns = ({ name, result, evidenceId, recordUnknown, }) => {
143
170
  if (!["trace_feature", "trace_call_path", "inspect_native_api"].includes(name) ||