rea-agents 4.0.1 → 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
@@ -0,0 +1,34 @@
1
+ import { constants, createReadStream } from "node:fs";
2
+ import { chmod, copyFile } from "node:fs/promises";
3
+ import { createHash } from "node:crypto";
4
+ import { join } from "node:path";
5
+ import { AnalysisInputError } from "../domain/analysisErrorCore.js";
6
+ /** Stream a local file digest without retaining the APK or JAR in memory. */
7
+ export const hashAndroidFile = async (path) => {
8
+ const hash = createHash("sha256");
9
+ for await (const chunk of createReadStream(path))
10
+ hash.update(chunk);
11
+ return hash.digest("hex");
12
+ };
13
+ /** Bind decompiler input to the admitted artifact, even if the original changes. */
14
+ export const snapshotAndroidTarget = async (path, sha256, root, operation) => {
15
+ const snapshot = join(root, "target.apk");
16
+ await copyFile(path, snapshot, constants.COPYFILE_EXCL);
17
+ await chmod(snapshot, 0o400);
18
+ if ((await hashAndroidFile(snapshot)) !== sha256)
19
+ throw new AnalysisInputError(operation, undefined, [
20
+ {
21
+ path: ["path"],
22
+ reason: "invalid_value",
23
+ message: "APK bytes changed after admission; retry against a stable file.",
24
+ },
25
+ ]);
26
+ return snapshot;
27
+ };
28
+ /** Fingerprint the actual immutable engine bytes executed for this observation. */
29
+ export const snapshotAndroidEngine = async (source, root) => {
30
+ const path = join(root, "engine.jar");
31
+ await copyFile(source, path, constants.COPYFILE_EXCL);
32
+ await chmod(path, 0o400);
33
+ return { path, sha256: await hashAndroidFile(path) };
34
+ };
@@ -0,0 +1,191 @@
1
+ import { androidResultSchemas } from "../domain/androidAnalysis.js";
2
+ import { AnalysisCapabilityUnavailableError, AnalysisInputError, AnalysisOutputError, } from "../domain/analysisErrorCore.js";
3
+ import { jadxAppSchema, jadxClassPageSchema, jadxClassSchema, jadxLoadSchema, jadxMethodSchema, jadxXrefsSchema, normalizeJadxText, } from "./JadxProtocol.js";
4
+ const methodsOf = (summary) => {
5
+ const seen = new Map();
6
+ return summary.methods.map((method) => {
7
+ const index = seen.get(method.name) ?? 0;
8
+ seen.set(method.name, index + 1);
9
+ return {
10
+ name: method.name,
11
+ reported_signature: method.signature,
12
+ overload_index: index,
13
+ is_constructor: method.is_constructor,
14
+ dex_descriptor: null,
15
+ };
16
+ });
17
+ };
18
+ const inputFailure = (request, field, message) => {
19
+ throw new AnalysisInputError(request.operation, undefined, [
20
+ { path: [field], reason: "invalid_value", message },
21
+ ]);
22
+ };
23
+ const classSummary = async (tools, request) => {
24
+ const raw = await tools.json("get_class_summary", {
25
+ class_name: request.input.class_name,
26
+ });
27
+ if (raw !== null &&
28
+ typeof raw === "object" &&
29
+ !Array.isArray(raw) &&
30
+ typeof raw.error === "string")
31
+ throw new AnalysisOutputError(request.operation, `JADX class summary failed: ${raw.error}`);
32
+ const summary = jadxClassSchema.safeParse(raw);
33
+ if (!summary.success)
34
+ throw new AnalysisOutputError(request.operation, "JADX class summary failed or was malformed; negative counts are not an empty class", { cause: summary.error });
35
+ const value = summary.data;
36
+ if (value.full_name !== request.input.class_name)
37
+ inputFailure(request, "class_name", `Exact class ${request.input.class_name} resolved to ${value.full_name}; use the fully qualified class name from search_android_classes.`);
38
+ if (value.method_count !== value.methods.length ||
39
+ value.field_count !== value.fields.length ||
40
+ value.inner_class_count !== value.inner_classes.length)
41
+ throw new AnalysisOutputError(request.operation, "JADX class member counts do not match the returned inventory");
42
+ return value;
43
+ };
44
+ const inspectPackage = async (tools, loaded, engine) => {
45
+ const app = jadxAppSchema.parse(await tools.json("get_app_info", {}));
46
+ const manifest = normalizeJadxText(await tools.text("get_android_manifest", {}));
47
+ return androidResultSchemas.inspect_android_package.parse({
48
+ engine,
49
+ package_name: app.package || null,
50
+ version_name: app.version_name || null,
51
+ version_code: app.version_code || null,
52
+ min_sdk: app.min_sdk || null,
53
+ target_sdk: app.target_sdk || null,
54
+ permissions: app.permissions,
55
+ manifest,
56
+ class_count: loaded.class_count,
57
+ resource_count: loaded.resource_count,
58
+ signature_verification: "not_performed",
59
+ });
60
+ };
61
+ const searchClasses = async (tools, request, loaded, engine) => {
62
+ const classes = [];
63
+ let total;
64
+ do {
65
+ const page = jadxClassPageSchema.parse(await tools.json("list_classes", {
66
+ offset: classes.length,
67
+ limit: 200,
68
+ }));
69
+ if ((total !== undefined && total !== page.total) ||
70
+ page.offset !== classes.length ||
71
+ page.limit !== 200 ||
72
+ page.items.length > 200)
73
+ throw new AnalysisOutputError(request.operation, "JADX class pagination changed identity or counts");
74
+ total = page.total;
75
+ classes.push(...page.items);
76
+ if (classes.length > total ||
77
+ (page.items.length === 0 && classes.length < total))
78
+ throw new AnalysisOutputError(request.operation, "JADX class pagination is incomplete");
79
+ } while (classes.length < total);
80
+ if (new Set(classes).size !== classes.length || total !== loaded.class_count)
81
+ throw new AnalysisOutputError(request.operation, "JADX class inventory is duplicated or differs from the loaded class count");
82
+ return androidResultSchemas.search_android_classes.parse({
83
+ engine,
84
+ query: request.input.query,
85
+ total_classes: total,
86
+ matches: classes.filter((name) => name.includes(request.input.query)),
87
+ coverage: "complete",
88
+ });
89
+ };
90
+ const matchingMethods = (summary, request) => {
91
+ const candidates = methodsOf(summary).filter((method) => method.name === request.input.method_name);
92
+ if (request.input.method_name !== undefined && candidates.length === 0)
93
+ inputFailure(request, "method_name", `Method ${summary.full_name}.${request.input.method_name} was not found; inspect_android_class lists available methods.`);
94
+ return candidates;
95
+ };
96
+ const inspectMethod = async (tools, request, summary, engine) => {
97
+ const candidates = matchingMethods(summary, request);
98
+ if (candidates.length > 1 && request.input.overload_index === undefined)
99
+ inputFailure(request, "overload_index", `Select one of ${candidates.length} overloads: ${candidates.map((method) => `${method.overload_index}: ${method.reported_signature}`).join("; ")}`);
100
+ const index = request.input.overload_index ?? 0;
101
+ const selected = candidates[index];
102
+ if (selected === undefined)
103
+ inputFailure(request, "overload_index", `Index ${index} is outside the ${candidates.length} matching overloads.`);
104
+ const body = jadxMethodSchema.parse(await tools.json("get_method_body", {
105
+ class_name: summary.full_name,
106
+ method_name: request.input.method_name,
107
+ overload_index: index,
108
+ smali_fallback: true,
109
+ }));
110
+ if (body.class_name !== summary.full_name ||
111
+ body.method_name !== request.input.method_name ||
112
+ body.overload_index !== index ||
113
+ body.overload_count !== candidates.length)
114
+ throw new AnalysisOutputError(request.operation, "JADX returned a different method or overload inventory");
115
+ if (body.body.startsWith("// ERROR:"))
116
+ throw new AnalysisOutputError(request.operation, `JADX did not produce method source: ${body.body}`);
117
+ if (body.mode === "smali" && candidates.length > 1)
118
+ throw new AnalysisCapabilityUnavailableError("jadx", request.operation, `JADX 0.7.1 smali fallback joins all same-name overloads for ${summary.full_name}.${request.input.method_name}; it cannot establish source for only overload ${index}.`);
119
+ return androidResultSchemas.inspect_android_method.parse({
120
+ engine,
121
+ class_name: summary.full_name,
122
+ method: selected,
123
+ overload_count: candidates.length,
124
+ representation: body.mode,
125
+ body_status: body.body.length === 0 ||
126
+ body.body ===
127
+ "// method exists but has no decompiled body (native/abstract)"
128
+ ? "not_available"
129
+ : "available",
130
+ fell_back: body.fell_back,
131
+ markers: body.markers,
132
+ source: normalizeJadxText(body.body),
133
+ });
134
+ };
135
+ /** Normalize only the selected analyst outcome and reject ambiguous engine selectors. */
136
+ export const analyzeJadxRequest = async (tools, request, loaded, engine) => {
137
+ if (request.operation === "inspect_android_package")
138
+ return inspectPackage(tools, loaded, engine);
139
+ if (request.operation === "search_android_classes")
140
+ return searchClasses(tools, request, loaded, engine);
141
+ const summary = await classSummary(tools, request);
142
+ if (request.operation === "inspect_android_class")
143
+ return androidResultSchemas.inspect_android_class.parse({
144
+ engine,
145
+ class_name: summary.full_name,
146
+ methods: methodsOf(summary),
147
+ fields: summary.fields.map((field) => ({
148
+ name: field.name,
149
+ reported_type: field.type,
150
+ })),
151
+ inner_classes: summary.inner_classes,
152
+ });
153
+ if (request.operation === "inspect_android_method")
154
+ return inspectMethod(tools, request, summary, engine);
155
+ return traceReferences(tools, request, summary, engine);
156
+ };
157
+ const traceReferences = async (tools, request, summary, engine) => {
158
+ const methodName = request.input.method_name;
159
+ const candidates = matchingMethods(summary, request);
160
+ if (candidates.length > 1)
161
+ throw new AnalysisCapabilityUnavailableError("jadx", request.operation, `JADX 0.7.1 references select the first same-name method; ${summary.full_name}.${methodName} has ${candidates.length} overloads. No unambiguous reference result is available.`);
162
+ const expectedTarget = methodName === undefined
163
+ ? summary.full_name
164
+ : `${summary.full_name}.${methodName}`;
165
+ const xrefs = jadxXrefsSchema.parse(await tools.json(methodName === undefined ? "get_xrefs_to_class" : "get_xrefs_to_method", {
166
+ class_name: summary.full_name,
167
+ ...(methodName === undefined ? {} : { method_name: methodName }),
168
+ limit: 2_147_483_647,
169
+ resolve_line: false,
170
+ }));
171
+ if (xrefs.target !== expectedTarget ||
172
+ xrefs.total !== xrefs.count ||
173
+ xrefs.count !== xrefs.items.length)
174
+ throw new AnalysisOutputError(request.operation, "JADX references are incomplete or refer to another target");
175
+ return androidResultSchemas.trace_android_references.parse({
176
+ engine,
177
+ class_name: summary.full_name,
178
+ method_name: methodName ?? null,
179
+ total: xrefs.total,
180
+ references: xrefs.items.map((reference) => ({
181
+ kind: reference.kind,
182
+ name: reference.name,
183
+ reported_full_name: reference.full_name,
184
+ containing_class: reference.containing_class,
185
+ top_class: reference.top_class,
186
+ source_line: null,
187
+ dex_offset: null,
188
+ })),
189
+ coverage: "complete",
190
+ });
191
+ };
@@ -0,0 +1,41 @@
1
+ import { access, realpath, stat } from "node:fs/promises";
2
+ import { constants } from "node:fs";
3
+ import { isAbsolute, join } from "node:path";
4
+ import { AnalysisCapabilityUnavailableError } from "../domain/analysisErrorCore.js";
5
+ /** Admit explicit local tooling without installing or changing host configuration. */
6
+ export const resolveJadxConfiguration = async (environment, operation) => {
7
+ const unavailable = (reason) => new AnalysisCapabilityUnavailableError("jadx", operation, reason);
8
+ if (process.platform !== "linux" && process.platform !== "darwin")
9
+ throw unavailable(`Android JADX subprocess ownership is unsupported on ${process.platform}; use Linux or macOS. Only Linux has real-provider verification.`);
10
+ const jar = environment.REA_JADX_MCP_JAR;
11
+ if (environment.JAVA_HOME !== undefined && !isAbsolute(environment.JAVA_HOME))
12
+ throw unavailable("JAVA_HOME must select an existing JDK by absolute path; omit it to use java on PATH.");
13
+ if (jar === undefined || !isAbsolute(jar))
14
+ throw unavailable("Set REA_JADX_MCP_JAR to the absolute path of a caller-supplied jadx-headless-mcp 0.7.1 JAR. REA does not download or install it.");
15
+ const java = environment.JAVA_HOME === undefined
16
+ ? "java"
17
+ : join(environment.JAVA_HOME, "bin", "java");
18
+ try {
19
+ await access(jar, constants.R_OK);
20
+ if (!(await stat(jar)).isFile())
21
+ throw unavailable(`REA_JADX_MCP_JAR is not a regular file: ${jar}`);
22
+ }
23
+ catch (cause) {
24
+ if (cause instanceof AnalysisCapabilityUnavailableError)
25
+ throw cause;
26
+ throw unavailable(`Cannot read REA_JADX_MCP_JAR ${jar}: ${cause instanceof Error ? cause.message : String(cause)}`);
27
+ }
28
+ if (environment.JAVA_HOME !== undefined) {
29
+ try {
30
+ await access(java, constants.R_OK | constants.X_OK);
31
+ if (!(await stat(java)).isFile())
32
+ throw unavailable(`JAVA_HOME java is not a regular file: ${java}`);
33
+ }
34
+ catch (cause) {
35
+ if (cause instanceof AnalysisCapabilityUnavailableError)
36
+ throw cause;
37
+ throw unavailable(`Cannot execute JAVA_HOME java ${java}: ${cause instanceof Error ? cause.message : String(cause)}`);
38
+ }
39
+ }
40
+ return { jar: await realpath(jar), java };
41
+ };
@@ -0,0 +1,145 @@
1
+ import { deserializeMessage, serializeMessage, } from "@modelcontextprotocol/client";
2
+ import { randomUUID } from "node:crypto";
3
+ import { ProviderProcessSupervisor, spawnOwnedProviderProcess, } from "../process/ProviderProcess.js";
4
+ import { cleanupOwnedProcessGroup } from "../process/ProcessOwnership.js";
5
+ import { ProviderCleanupError } from "../domain/providerCleanupError.js";
6
+ const MAX_FRAME_BYTES = 8 * 1024 * 1024;
7
+ const MAX_SESSION_BYTES = 32 * 1024 * 1024;
8
+ /** SDK-framed stdio with REA-owned process cleanup rather than an unowned child. */
9
+ export class JadxMcpTransport {
10
+ options;
11
+ launcher;
12
+ onclose;
13
+ onerror;
14
+ onmessage;
15
+ runId = randomUUID();
16
+ #spawned;
17
+ #supervisor;
18
+ #buffer = Buffer.alloc(0);
19
+ #bytes = 0;
20
+ #started = false;
21
+ #closed = false;
22
+ #closePromise;
23
+ #starting;
24
+ #failure = null;
25
+ constructor(options, launcher = spawnOwnedProviderProcess) {
26
+ this.options = options;
27
+ this.launcher = launcher;
28
+ }
29
+ /** Acquires exactly one protocol process after the SDK installs callbacks. */
30
+ start() {
31
+ if (this.#started || this.#closed)
32
+ throw new Error("JADX transport cannot be restarted");
33
+ this.#started = true;
34
+ this.#starting = this.#acquire();
35
+ return this.#starting;
36
+ }
37
+ async #acquire() {
38
+ const spawned = await this.launcher({
39
+ ...this.options,
40
+ runId: this.runId,
41
+ stdin: "pipe",
42
+ });
43
+ this.#spawned = spawned;
44
+ this.#supervisor = new ProviderProcessSupervisor({
45
+ ...spawned,
46
+ ownsProcessLifetime: true,
47
+ cleanup: spawned.cleanup ?? (() => cleanupOwnedProcessGroup(spawned.ownership)),
48
+ });
49
+ if (spawned.process.stdin === undefined ||
50
+ spawned.process.stdin === null ||
51
+ spawned.process.stdout === null)
52
+ throw new Error("JADX launcher did not supply protocol stdin/stdout");
53
+ spawned.process.stdout.on("data", this.#read);
54
+ spawned.process.stderr?.on("data", this.#countStderr);
55
+ spawned.process.on("error", this.#error);
56
+ spawned.process.once("exit", this.#exit);
57
+ spawned.process.stdin.on("error", this.#error);
58
+ if (this.#closed)
59
+ throw new Error("JADX transport closed during startup");
60
+ }
61
+ /** Writes SDK-serialized messages and observes stream backpressure. */
62
+ async send(message) {
63
+ const input = this.#spawned?.process.stdin;
64
+ if (this.#closed || input === undefined || input === null)
65
+ throw new Error("JADX protocol process is not writable");
66
+ await new Promise((resolve, reject) => {
67
+ input.write(serializeMessage(message), (cause) => cause === null || cause === undefined ? resolve() : reject(cause));
68
+ });
69
+ }
70
+ /** Verifies owned process exit before declaring the transport closed. */
71
+ close() {
72
+ this.#closePromise ??= this.#stop();
73
+ return this.#closePromise;
74
+ }
75
+ /** Captured provider stderr without persisting inherited environment values. */
76
+ diagnostics() {
77
+ return this.#supervisor?.snapshot().stderr.text ?? "";
78
+ }
79
+ /** Preserve the failed protocol/resource constraint after the SDK closes requests. */
80
+ failureReason() {
81
+ return this.#failure;
82
+ }
83
+ async #stop() {
84
+ this.#closed = true;
85
+ // A cancellation may race acquisition. Join it before inspecting ownership.
86
+ await this.#starting?.catch(() => undefined);
87
+ const process = this.#spawned?.process;
88
+ process?.stdout?.off("data", this.#read);
89
+ process?.stderr?.off("data", this.#countStderr);
90
+ process?.off("error", this.#error);
91
+ process?.off("exit", this.#exit);
92
+ process?.stdin?.off("error", this.#error);
93
+ const stopped = await this.#supervisor?.stop();
94
+ this.onclose?.();
95
+ if (stopped?.status === "incomplete")
96
+ throw new ProviderCleanupError("jadx", [this.runId], {
97
+ reason: stopped.reason,
98
+ stderr: this.diagnostics(),
99
+ });
100
+ }
101
+ #error = (error) => {
102
+ this.onerror?.(error);
103
+ };
104
+ #exit = () => {
105
+ this.onclose?.();
106
+ };
107
+ #countStderr = (chunk) => {
108
+ this.#bytes += Buffer.byteLength(chunk);
109
+ if (this.#bytes > MAX_SESSION_BYTES)
110
+ this.#fail(new Error(`JADX session output exceeds ${MAX_SESSION_BYTES} bytes; no complete result is available`));
111
+ };
112
+ #read = (chunk) => {
113
+ if (this.#closed)
114
+ return;
115
+ const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
116
+ this.#bytes += bytes.length;
117
+ if (this.#bytes > MAX_SESSION_BYTES) {
118
+ this.#fail(new Error(`JADX session output exceeds ${MAX_SESSION_BYTES} bytes; no complete result is available`));
119
+ return;
120
+ }
121
+ this.#buffer = Buffer.concat([this.#buffer, bytes]);
122
+ try {
123
+ let newline;
124
+ while ((newline = this.#buffer.indexOf(10)) !== -1) {
125
+ if (newline > MAX_FRAME_BYTES)
126
+ throw new Error(`JADX MCP frame exceeds ${MAX_FRAME_BYTES} bytes`);
127
+ const line = this.#buffer.subarray(0, newline).toString("utf8");
128
+ this.#buffer = this.#buffer.subarray(newline + 1);
129
+ this.onmessage?.(deserializeMessage(line));
130
+ }
131
+ if (this.#buffer.length > MAX_FRAME_BYTES)
132
+ throw new Error(`JADX MCP frame exceeds ${MAX_FRAME_BYTES} bytes`);
133
+ }
134
+ catch (cause) {
135
+ this.#fail(cause instanceof Error ? cause : new Error(String(cause)));
136
+ }
137
+ };
138
+ #fail(error) {
139
+ this.#failure ??= error.message;
140
+ this.onerror?.(error);
141
+ // Closing immediately rejects the SDK's outstanding request. The owner
142
+ // awaits close again and retains a cleanup failure in the returned Result.
143
+ void this.close().catch((cause) => this.onerror?.(cause instanceof Error ? cause : new Error(String(cause))));
144
+ }
145
+ }
@@ -0,0 +1,101 @@
1
+ import { z } from "zod";
2
+ import { AnalysisOutputError } from "../domain/analysisErrorCore.js";
3
+ import { jsonValueSchema } from "../domain/jsonValue.js";
4
+ const count = z.number().int().nonnegative();
5
+ export const jadxLoadSchema = z.object({
6
+ state: z.literal("LOADED"),
7
+ apk_path: z.string(),
8
+ class_count: count,
9
+ resource_count: count,
10
+ threads: z.literal(1),
11
+ resources: z.literal("full"),
12
+ });
13
+ export const jadxAppSchema = z.object({
14
+ package: z.string(),
15
+ version_name: z.string(),
16
+ version_code: z.string(),
17
+ min_sdk: z.string(),
18
+ target_sdk: z.string(),
19
+ permissions: z.array(z.string()),
20
+ });
21
+ export const jadxClassPageSchema = z.object({
22
+ total: count,
23
+ offset: count,
24
+ limit: count,
25
+ items: z.array(z.string()),
26
+ });
27
+ export const jadxClassSchema = z.object({
28
+ full_name: z.string(),
29
+ name: z.string(),
30
+ method_count: count,
31
+ field_count: count,
32
+ inner_class_count: count,
33
+ methods: z.array(z.object({
34
+ name: z.string(),
35
+ signature: z.string(),
36
+ is_constructor: z.boolean(),
37
+ def_pos: z.number().int(),
38
+ })),
39
+ fields: z.array(z.object({ name: z.string(), type: z.string(), def_pos: z.number().int() })),
40
+ inner_classes: z.array(z.string()),
41
+ });
42
+ export const jadxMethodSchema = z.object({
43
+ class_name: z.string(),
44
+ method_name: z.string(),
45
+ full_name: z.string(),
46
+ overload_index: count,
47
+ overload_count: count,
48
+ mode: z.enum(["java", "smali"]),
49
+ fell_back: z.boolean(),
50
+ markers: z.array(z.string()),
51
+ body: z.string(),
52
+ });
53
+ export const jadxXrefsSchema = z.object({
54
+ target: z.string(),
55
+ total: count,
56
+ count,
57
+ resolve_line: z.literal(false),
58
+ items: z.array(z.object({
59
+ kind: z.string(),
60
+ name: z.string(),
61
+ full_name: z.string(),
62
+ containing_class: z.string(),
63
+ top_class: z.string(),
64
+ def_pos: z.number().int(),
65
+ })),
66
+ });
67
+ const toolResponse = z.object({
68
+ content: z
69
+ .array(z.object({ type: z.literal("text"), text: z.string() }))
70
+ .length(1),
71
+ isError: z.boolean().optional(),
72
+ });
73
+ /** Parse the upstream text-only envelope, preserving errors at the producing boundary. */
74
+ export const parseJadxEnvelope = (response, operation) => {
75
+ const parsed = toolResponse.safeParse(response);
76
+ if (!parsed.success || parsed.data.content[0] === undefined)
77
+ throw new AnalysisOutputError(operation, "JADX returned an unsupported MCP content envelope");
78
+ return {
79
+ text: parsed.data.content[0].text,
80
+ failed: parsed.data.isError === true,
81
+ };
82
+ };
83
+ /** Decode an upstream JSON text payload without trusting its contents. */
84
+ export const parseJadxJson = (text, operation) => {
85
+ try {
86
+ return jsonValueSchema.parse(JSON.parse(text));
87
+ }
88
+ catch (cause) {
89
+ throw new AnalysisOutputError(operation, "JADX returned malformed JSON text", { cause });
90
+ }
91
+ };
92
+ /** Upstream byte truncation is reported rather than promoted to a complete source. */
93
+ export const normalizeJadxText = (text) => {
94
+ const marker = /\n\n\.\.\. \[truncated: exceeds (\d+) bytes, total (\d+) bytes\]$/u.exec(text);
95
+ const total = marker?.[2] === undefined ? null : Number(marker[2]);
96
+ return {
97
+ status: marker === null ? "complete" : "partial",
98
+ text,
99
+ reported_total_bytes: total !== null && Number.isSafeInteger(total) ? total : null,
100
+ };
101
+ };
@@ -0,0 +1,170 @@
1
+ import { z } from "zod";
2
+ import { AnalysisError } from "../domain/analysisErrorBase.js";
3
+ import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisOutputError, AnalysisTimeoutError, } from "../domain/analysisErrorCore.js";
4
+ import { ProviderAdapterError } from "../domain/providerAdapterError.js";
5
+ import { ProviderCleanupError } from "../domain/providerCleanupError.js";
6
+ import { err, ok } from "../domain/result.js";
7
+ import { PrivateRuntimeRoot } from "../process/PrivateRuntimeRoot.js";
8
+ import { snapshotAndroidEngine, snapshotAndroidTarget, } from "./AndroidTargetSnapshot.js";
9
+ import { resolveJadxConfiguration } from "./JadxConfiguration.js";
10
+ import { JadxSession } from "./JadxSession.js";
11
+ const OPERATION_TIMEOUT_MS = 120_000;
12
+ const waitForTurn = (predecessor, request, signal) => new Promise((resolve, reject) => {
13
+ const abort = () => reject(new AnalysisCancelledError(request.operation));
14
+ signal?.addEventListener("abort", abort, { once: true });
15
+ if (signal?.aborted === true)
16
+ abort();
17
+ void predecessor.then(() => {
18
+ signal?.removeEventListener("abort", abort);
19
+ resolve();
20
+ });
21
+ });
22
+ const executionError = (context) => {
23
+ const { cause, request, timeout, signal, session } = context;
24
+ if (signal?.aborted === true)
25
+ return new AnalysisCancelledError(request.operation);
26
+ if (timeout.aborted)
27
+ return new AnalysisTimeoutError(request.operation, OPERATION_TIMEOUT_MS);
28
+ if (cause instanceof AnalysisError)
29
+ return cause;
30
+ const protocolFailure = session?.transport.failureReason();
31
+ if (protocolFailure !== undefined && protocolFailure !== null)
32
+ return new AnalysisOutputError(request.operation, protocolFailure, {
33
+ cause,
34
+ });
35
+ if (cause instanceof z.ZodError)
36
+ return new AnalysisOutputError(request.operation, "JADX response violated the pinned upstream protocol", { cause });
37
+ return new ProviderAdapterError("jadx", request.operation, {
38
+ cause,
39
+ diagnostics: {
40
+ reason: cause instanceof Error ? cause.message : String(cause),
41
+ stderr: session?.transport.diagnostics() ?? "",
42
+ },
43
+ });
44
+ };
45
+ const cleanup = async (session, root, previous) => {
46
+ const diagnostics = {
47
+ previous_error: previous.ok
48
+ ? null
49
+ : { tag: previous.error._tag, message: previous.error.message },
50
+ };
51
+ try {
52
+ await session?.close();
53
+ }
54
+ catch (cause) {
55
+ // Retain an uncertain workspace until the caller can resolve process ownership.
56
+ return err(new ProviderCleanupError("jadx", [
57
+ session?.transport.runId ?? "unknown",
58
+ ...(root === undefined ? [] : [root.path]),
59
+ ], {
60
+ ...diagnostics,
61
+ reason: cause instanceof Error ? cause.message : String(cause),
62
+ provider_cleanup: cause instanceof ProviderCleanupError
63
+ ? (cause.diagnostics ?? null)
64
+ : null,
65
+ }, { cause }));
66
+ }
67
+ try {
68
+ await root?.close();
69
+ }
70
+ catch (cause) {
71
+ return err(new ProviderCleanupError("jadx", [root?.path ?? "unknown"], {
72
+ ...diagnostics,
73
+ reason: cause instanceof Error ? cause.message : String(cause),
74
+ }, { cause }));
75
+ }
76
+ return previous;
77
+ };
78
+ /** One queued engine per REA instance, with a fresh owned workspace for every request. */
79
+ export class JadxProvider {
80
+ environment;
81
+ launcher;
82
+ #tail = Promise.resolve();
83
+ #cleanupFailure;
84
+ constructor(environment = process.env, launcher) {
85
+ this.environment = environment;
86
+ this.launcher = launcher;
87
+ }
88
+ /** Serialize expensive work and bind both raw and normalized results to the APK. */
89
+ async execute(target, request, options) {
90
+ const predecessor = this.#tail;
91
+ let release = () => { };
92
+ this.#tail = new Promise((resolve) => {
93
+ release = resolve;
94
+ });
95
+ try {
96
+ await waitForTurn(predecessor, request, options?.signal);
97
+ }
98
+ catch {
99
+ void predecessor.then(release);
100
+ return err(new AnalysisCancelledError(request.operation));
101
+ }
102
+ try {
103
+ if (options?.signal?.aborted === true)
104
+ return err(new AnalysisCancelledError(request.operation));
105
+ if (this.#cleanupFailure !== undefined)
106
+ return err(this.#cleanupFailure);
107
+ const outcome = await this.#execute(target, request, options);
108
+ if (!outcome.ok && outcome.error.cleanupIncomplete)
109
+ this.#cleanupFailure = outcome.error;
110
+ return outcome;
111
+ }
112
+ finally {
113
+ release();
114
+ }
115
+ }
116
+ async #execute(target, request, options) {
117
+ const timeout = AbortSignal.timeout(OPERATION_TIMEOUT_MS);
118
+ const signal = options?.signal === undefined
119
+ ? timeout
120
+ : AbortSignal.any([options.signal, timeout]);
121
+ let root;
122
+ let session;
123
+ let outcome;
124
+ try {
125
+ if (target.format !== "apk")
126
+ throw new AnalysisCapabilityUnavailableError("jadx", request.operation, `Target ${target.path} is ${target.format}; provide one standalone APK.`);
127
+ const configuration = await resolveJadxConfiguration(this.environment, request.operation);
128
+ signal.throwIfAborted();
129
+ root = await PrivateRuntimeRoot.create({ prefix: "rea-android-" });
130
+ const engine = await snapshotAndroidEngine(configuration.jar, root.path);
131
+ const snapshot = await snapshotAndroidTarget(target.path, target.sha256, root.path, request.operation);
132
+ signal.throwIfAborted();
133
+ session = new JadxSession({
134
+ command: configuration.java,
135
+ arguments: [
136
+ "-Xmx512m",
137
+ "-XX:ActiveProcessorCount=1",
138
+ "-jar",
139
+ engine.path,
140
+ "--threads",
141
+ "1",
142
+ "--max-source-bytes",
143
+ "1048576",
144
+ "--decompile-timeout-ms",
145
+ "90000",
146
+ ],
147
+ cwd: root.path,
148
+ hostEnvironment: this.environment,
149
+ env: { _JAVA_OPTIONS: "-Xmx512m -XX:ActiveProcessorCount=1" },
150
+ }, this.launcher);
151
+ outcome = ok(await session.execute({
152
+ request,
153
+ target,
154
+ snapshot,
155
+ jarHash: engine.sha256,
156
+ signal,
157
+ }));
158
+ }
159
+ catch (cause) {
160
+ outcome = err(executionError({
161
+ cause,
162
+ request,
163
+ timeout,
164
+ signal: options?.signal,
165
+ session,
166
+ }));
167
+ }
168
+ return cleanup(session, root, outcome);
169
+ }
170
+ }