rea-agents 6.3.0 → 6.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (487) hide show
  1. package/README.md +7 -4
  2. package/bridge/ghidra/ReaGhidraApplySeeds.java +151 -0
  3. package/bridge/ghidra/ReaGhidraBridge.java +597 -209
  4. package/bridge/ghidra/ReaGhidraNoReturnFix.java +123 -0
  5. package/dist/adb/AdbConfiguration.js +88 -0
  6. package/dist/adb/AdbDeviceOutput.js +186 -0
  7. package/dist/adb/AdbProvider.js +1190 -0
  8. package/dist/adb/AdbShellOutput.js +309 -0
  9. package/dist/android/AndroidTargetSnapshot.js +104 -22
  10. package/dist/android/JadxConfiguration.js +44 -24
  11. package/dist/android/JadxProvider.js +51 -19
  12. package/dist/apktool/ApktoolConfiguration.js +84 -0
  13. package/dist/apktool/ApktoolDecodeOutput.js +59 -0
  14. package/dist/apktool/ApktoolProvider.js +506 -0
  15. package/dist/application/AnalysisProvider.js +8 -2
  16. package/dist/application/AppBundleExecutable.js +27 -22
  17. package/dist/application/BinaryTargetResolver.js +22 -2
  18. package/dist/application/CapabilityInventory.js +11 -1
  19. package/dist/application/ClientConfigurationDocument.js +70 -0
  20. package/dist/application/ClientConfigurationFiles.js +91 -0
  21. package/dist/application/ClientRegistrationEnvironment.js +35 -0
  22. package/dist/application/ClientRegistrationStatus.js +66 -31
  23. package/dist/application/DirectAnalysis.js +2 -2
  24. package/dist/application/DirectAnalysisCleanup.js +1 -1
  25. package/dist/application/DirectAnalysisStatus.js +1 -1
  26. package/dist/application/Doctor.js +5 -3
  27. package/dist/application/DoctorDiagnostics.js +1 -1
  28. package/dist/application/EvidenceBundleCommands.js +6 -12
  29. package/dist/application/GeminiClientSettings.js +139 -0
  30. package/dist/application/HermesClientHome.js +115 -0
  31. package/dist/application/HopperDownload.js +39 -0
  32. package/dist/application/InvestigationProviders.js +6 -0
  33. package/dist/application/JsonFiles.js +6 -5
  34. package/dist/{cliJsonFile.js → application/JsonInputFile.js} +108 -35
  35. package/dist/application/LinuxHopper.js +4 -12
  36. package/dist/application/MacHopper.js +172 -149
  37. package/dist/application/MipsElfAbiFlags.js +140 -0
  38. package/dist/application/ProviderOperationExecution.js +31 -0
  39. package/dist/application/ReconstructionObligationCandidates.js +9 -3
  40. package/dist/application/ReferenceSourceImport.js +76 -29
  41. package/dist/application/ReferenceSourceImportEntries.js +18 -9
  42. package/dist/application/ReferenceSourceImportPolicy.js +99 -23
  43. package/dist/application/ReferenceSourceImportTypes.js +30 -22
  44. package/dist/application/ReferenceSourceVcsAdapter.js +145 -30
  45. package/dist/application/RegularFileRead.js +93 -7
  46. package/dist/application/Setup.js +54 -6
  47. package/dist/application/SetupClientConfiguration.js +116 -16
  48. package/dist/application/SetupHost.js +102 -24
  49. package/dist/application/SetupPlan.js +5 -8
  50. package/dist/application/SetupSkill.js +58 -39
  51. package/dist/application/SupportedClients.js +290 -65
  52. package/dist/application/Uninstall.js +158 -10
  53. package/dist/application/UpdateMaintenance.js +17 -21
  54. package/dist/application/Utf8JsonInput.js +7 -0
  55. package/dist/application/WebScriptExportService.js +131 -65
  56. package/dist/application/WebSourceLocationService.js +3 -0
  57. package/dist/application/adb/AdbDeviceAnalysisPort.js +1 -0
  58. package/dist/application/adb/AdbDeviceAnalysisService.js +13 -0
  59. package/dist/application/analysisView/AnalysisViewService.js +40 -2
  60. package/dist/application/apktool/ApktoolResourceAnalysisPort.js +1 -0
  61. package/dist/application/apktool/ApktoolResourceAnalysisService.js +13 -0
  62. package/dist/application/binary/AnalysisClientCleanup.js +0 -24
  63. package/dist/application/binary/BinarySession.js +2 -1
  64. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +2 -1
  65. package/dist/application/binaryDiagnostics/PeResourcesPort.js +1 -0
  66. package/dist/application/binaryDiagnostics/PeResourcesService.js +111 -0
  67. package/dist/application/binaryDiagnostics/RecordedCrashService.js +2 -1
  68. package/dist/application/evm/EvmInterfaceService.js +3 -0
  69. package/dist/application/firmware/FirmwareAnalysisService.js +3 -0
  70. package/dist/application/investigation/InspectEvidenceBundle.js +18 -0
  71. package/dist/application/javascript/ElectronBoundaryGraphContext.js +3 -2
  72. package/dist/application/javascript/ElectronBoundaryGraphIpc.js +2 -2
  73. package/dist/application/javascript/ElectronBoundaryGraphNative.js +19 -6
  74. package/dist/application/javascript/ElectronBoundaryGraphWindows.js +3 -3
  75. package/dist/application/javascript/JavaScriptApplicationService.js +22 -11
  76. package/dist/application/javascript/JavaScriptApplicationWorkflowEvidence.js +5 -6
  77. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +171 -30
  78. package/dist/application/javascript/JavaScriptArtifactGraphAccumulator.js +14 -16
  79. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +67 -19
  80. package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +4 -3
  81. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +11 -5
  82. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +19 -16
  83. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +92 -10
  84. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +258 -235
  85. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +115 -26
  86. package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +4 -1
  87. package/dist/application/javascript/JavaScriptModuleRelationships.js +6 -4
  88. package/dist/application/javascript/JavaScriptRecoveryService.js +3 -0
  89. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +9 -3
  90. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +199 -61
  91. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +12 -19
  92. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +4 -1
  93. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +5 -3
  94. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +5 -3
  95. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +19 -8
  96. package/dist/application/jeb/JebAnalysisPort.js +1 -0
  97. package/dist/application/jeb/JebAnalysisService.js +13 -0
  98. package/dist/application/managed/ManagedApplicationGraphService.js +1 -1
  99. package/dist/application/native/NativeUiActionTrace.js +16 -8
  100. package/dist/application/native/NativeValueTrace.js +23 -6
  101. package/dist/application/process/ProcessCli.js +25 -20
  102. package/dist/artifacts/ArtifactPaths.js +129 -8
  103. package/dist/artifacts/ArtifactProvider.js +20 -15
  104. package/dist/artifacts/ArtifactReader.js +23 -0
  105. package/dist/artifacts/ArtifactResourceScope.js +100 -0
  106. package/dist/artifacts/AsarArtifactReader.js +176 -102
  107. package/dist/artifacts/AsarHeader.js +24 -0
  108. package/dist/artifacts/DirectoryArtifactReader.js +168 -65
  109. package/dist/artifacts/MachOSliceArtifactReader.js +116 -39
  110. package/dist/artifacts/NativeDmgArtifactReader.js +29 -22
  111. package/dist/artifacts/SafeOutputTree.js +245 -70
  112. package/dist/artifacts/SafeOutputTreeCleanup.js +45 -0
  113. package/dist/artifacts/SafeOutputTreeCreationFailure.js +20 -0
  114. package/dist/artifacts/SafeOutputTreeIdentity.js +42 -0
  115. package/dist/artifacts/SafeOutputTreeReadback.js +33 -0
  116. package/dist/artifacts/ZipArtifactReader.js +77 -27
  117. package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +58 -18
  118. package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +62 -24
  119. package/dist/artifacts/apple/KeyedArchiveReader.js +32 -13
  120. package/dist/artifacts/extraction/ArtifactExtraction.js +110 -86
  121. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +110 -43
  122. package/dist/artifacts/inventory/ArtifactInventory.js +5 -4
  123. package/dist/artifacts/inventory/classify.js +75 -32
  124. package/dist/artifacts/inventory/hashStableRootArtifact.js +48 -15
  125. package/dist/artifacts/inventory/reader.js +13 -5
  126. package/dist/artifacts/inventory/scanCanonical.js +62 -25
  127. package/dist/artifacts/inventory/scanReader.js +38 -11
  128. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +15 -9
  129. package/dist/artifacts/javascript/JavaScriptSourceAnalysis.js +3 -0
  130. package/dist/browser/BrowserScenarioPartialObservation.js +8 -2
  131. package/dist/browser/BrowserScenarioSecrets.js +52 -37
  132. package/dist/browser/CdpBrowserProvider.js +5 -0
  133. package/dist/browser/CdpCaptureDocuments.js +40 -6
  134. package/dist/browser/CdpCaptureDomSvg.js +210 -0
  135. package/dist/browser/CdpCaptureEventBodyShapes.js +4 -8
  136. package/dist/browser/CdpCaptureEventHandlers.js +26 -9
  137. package/dist/browser/CdpCaptureEvents.js +4 -9
  138. package/dist/browser/CdpConnection.js +22 -5
  139. package/dist/browser/CdpPageCapture.js +1 -1
  140. package/dist/browser/CdpTargetSession.js +30 -34
  141. package/dist/browser/CdpWebMcpDiscovery.js +32 -10
  142. package/dist/browser/ElectronFileScope.js +99 -9
  143. package/dist/browser/PlaywrightBrowserScenarioProvider.js +60 -4
  144. package/dist/browser/PlaywrightElectronActiveProvider.js +11 -6
  145. package/dist/browser/PlaywrightScenarioArtifacts.js +5 -5
  146. package/dist/browser/PlaywrightScenarioBrowser.js +69 -7
  147. package/dist/browser/PlaywrightScenarioSession.js +127 -54
  148. package/dist/browser/PlaywrightScenarioStorage.js +507 -0
  149. package/dist/browser/PngVisualDiff.js +198 -29
  150. package/dist/browser/WebSourceMapFetcher.js +3 -3
  151. package/dist/browser/assets/LocalWebScriptArtifacts.js +3 -1
  152. package/dist/browser/assets/PublishWebScripts.js +75 -20
  153. package/dist/browser/assets/WebArtifactReads.js +23 -1
  154. package/dist/browser/assets/WebSourceLocationArtifacts.js +1 -0
  155. package/dist/browser/execution/CdpExecutionCapture.js +3 -3
  156. package/dist/browser/execution/CdpPreciseCoverage.js +5 -8
  157. package/dist/browser/history/HarCapture.js +14 -0
  158. package/dist/browser/history/HarCaptureProcess.js +2 -10
  159. package/dist/browser/history/MitmproxyCaptureAdapter.js +3 -1
  160. package/dist/browser/modules/WebModuleArtifacts.js +1 -0
  161. package/dist/cli/adbCommands.js +337 -0
  162. package/dist/cli/analysisViewCommands.js +39 -1
  163. package/dist/cli/apktoolCommands.js +53 -0
  164. package/dist/cli/artifactCommands.js +8 -11
  165. package/dist/cli/binaryDiagnosticsCommands.js +19 -1
  166. package/dist/cli/browserAdvancedCommands.js +65 -36
  167. package/dist/cli/coreBinaryCommands.js +0 -5
  168. package/dist/cli/coreNativeCommands.js +1 -14
  169. package/dist/cli/electronCommands.js +6 -1
  170. package/dist/cli/evmCommands.js +13 -4
  171. package/dist/cli/firmwareCommands.js +7 -2
  172. package/dist/cli/javascriptApplicationAnalysis.js +17 -1
  173. package/dist/cli/javascriptRecoveryCommands.js +22 -15
  174. package/dist/cli/jebCommands.js +99 -0
  175. package/dist/cli/jsonOutput.js +11 -4
  176. package/dist/cli/referenceSourceImportStatus.js +7 -0
  177. package/dist/cli/setupCommands.js +15 -3
  178. package/dist/cli/utilityCommands.js +66 -18
  179. package/dist/cli/webScriptCommands.js +20 -1
  180. package/dist/cli/webSourceLocationCommands.js +21 -9
  181. package/dist/cli.js +6 -0
  182. package/dist/cliBrowserScenarioCommands.js +2 -1
  183. package/dist/cliCommandNames.js +32 -0
  184. package/dist/cliJsonInput.js +2 -2
  185. package/dist/cliObservationOptions.js +3 -0
  186. package/dist/composition/adb.js +3 -0
  187. package/dist/composition/apktool.js +3 -0
  188. package/dist/composition/binaryDiagnostics.js +4 -0
  189. package/dist/composition/directAnalysis.js +12 -4
  190. package/dist/composition/javascriptAnalysisWorkerProcess.js +48 -0
  191. package/dist/composition/jeb.js +6 -0
  192. package/dist/config/environment.js +10 -0
  193. package/dist/config/ghidraLanguageOverride.js +9 -0
  194. package/dist/config/mcpInputSchemaProfile.js +27 -0
  195. package/dist/config/parseConfig.js +28 -1
  196. package/dist/contracts/adb/adbToolContracts.js +353 -0
  197. package/dist/contracts/advertisedInputExamples.js +48 -0
  198. package/dist/contracts/analysisDetail.js +10 -0
  199. package/dist/contracts/analysisViewToolContracts.js +17 -2
  200. package/dist/contracts/apktool/apktoolToolContracts.js +33 -0
  201. package/dist/contracts/artifactToolContracts.js +8 -5
  202. package/dist/contracts/browserToolContracts.js +1 -1
  203. package/dist/contracts/compactInputSchema.js +256 -0
  204. package/dist/contracts/functionWorkflowToolContracts.js +1 -1
  205. package/dist/contracts/inputSchemaPresentation.js +10 -10
  206. package/dist/contracts/javascript/electronToolContracts.js +15 -3
  207. package/dist/contracts/javascript/javascriptRecoveryToolContracts.js +1 -1
  208. package/dist/contracts/jeb/jebToolContracts.js +64 -0
  209. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +25 -3
  210. package/dist/contracts/officialToolContracts.js +5 -5
  211. package/dist/contracts/sessionToolContracts.js +2 -2
  212. package/dist/contracts/sessionToolSchemas.js +6 -2
  213. package/dist/contracts/toolContractExamples.js +6 -0
  214. package/dist/contracts/toolContractTypes.js +3 -0
  215. package/dist/contracts/toolContracts.js +6 -0
  216. package/dist/contracts/toolEffects.js +167 -0
  217. package/dist/contracts/toolOutputSchemaGroups.js +5 -3
  218. package/dist/contracts/toolSchemaMetadata.js +82 -7
  219. package/dist/domain/adb/adbDeviceAnalysis.js +583 -0
  220. package/dist/domain/analysisErrorCleanup.js +29 -0
  221. package/dist/domain/analysisErrorPresentation.js +18 -6
  222. package/dist/domain/analysisErrorProjection.js +4 -1
  223. package/dist/domain/analysisSnapshot.js +2 -1
  224. package/dist/domain/analysisView/analysisView.js +52 -2
  225. package/dist/domain/analysisView/binaryLayoutView.js +2 -0
  226. package/dist/domain/analysisView/javascriptApplicationView.js +2 -0
  227. package/dist/domain/analysisView/nativeFunctionView.js +155 -0
  228. package/dist/domain/android/androidApplication.js +25 -20
  229. package/dist/domain/apktool/apktoolResourceAnalysis.js +77 -0
  230. package/dist/domain/apple/appleApplication.js +40 -23
  231. package/dist/domain/apple/appleBundleAnatomy.js +95 -28
  232. package/dist/domain/apple/dyldPaths.js +9 -1
  233. package/dist/domain/apple/dylibResolution.js +2 -2
  234. package/dist/domain/apple/interfaceBuilderGraph.js +22 -19
  235. package/dist/domain/apple/interfaceBuilderKeyedArchive.js +10 -1
  236. package/dist/domain/artifactComparison.js +35 -7
  237. package/dist/domain/artifactGraph.js +5 -3
  238. package/dist/domain/artifactIdentity.js +30 -2
  239. package/dist/domain/artifactInspection.js +3 -43
  240. package/dist/domain/artifactIntegrityPolicy.js +10 -0
  241. package/dist/domain/artifactInventoryEvidence.js +11 -12
  242. package/dist/domain/artifactPathSyntax.js +1 -1
  243. package/dist/domain/binaryTarget.js +16 -0
  244. package/dist/domain/binaryTargetTypes.js +8 -1
  245. package/dist/domain/browserObservationSchemas.js +8 -4
  246. package/dist/domain/canonicalJsonDigestSteps.js +34 -12
  247. package/dist/domain/compactStringIdentity.js +9 -0
  248. package/dist/domain/evidence.js +2 -1
  249. package/dist/domain/evidenceRecordSummary.js +144 -0
  250. package/dist/domain/inputIssueProjection.js +16 -1
  251. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +12 -13
  252. package/dist/domain/javascript/electronStaticAnalysisIpc.js +11 -20
  253. package/dist/domain/javascript/electronStaticAnalysisNative.js +70 -40
  254. package/dist/domain/javascript/electronStaticAnalysisValues.js +16 -0
  255. package/dist/domain/javascript/javascriptAnalysisResourceControls.js +45 -0
  256. package/dist/domain/javascript/javascriptApplicationAnalysis.js +4 -1
  257. package/dist/domain/javascript/javascriptApplicationChangeGraph.js +6 -6
  258. package/dist/domain/javascript/javascriptApplicationGraph.js +79 -18
  259. package/dist/domain/javascript/javascriptApplicationProjectionResources.js +35 -0
  260. package/dist/domain/javascript/javascriptApplicationVersionItems.js +28 -12
  261. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +9 -1
  262. package/dist/domain/javascript/javascriptAstFingerprint.js +58 -31
  263. package/dist/domain/javascript/javascriptAstValues.js +32 -0
  264. package/dist/domain/javascript/javascriptElectronMemberWrites.js +50 -0
  265. package/dist/domain/javascript/javascriptModuleSemanticIr.js +15 -0
  266. package/dist/domain/javascript/javascriptNativeHandoff.js +6 -1
  267. package/dist/domain/javascript/javascriptRpcEndpoints.js +253 -0
  268. package/dist/domain/javascript/javascriptRuntimeLoadState.js +1 -3
  269. package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +7 -2
  270. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +8 -11
  271. package/dist/domain/javascript/javascriptSemanticAnalysis.js +190 -33
  272. package/dist/domain/javascript/javascriptSemanticCallableResults.js +42 -0
  273. package/dist/domain/javascript/javascriptSemanticCalls.js +8 -1
  274. package/dist/domain/javascript/javascriptSemanticDerivedAnalysis.js +15 -4
  275. package/dist/domain/javascript/javascriptSemanticFileProjection.js +1 -0
  276. package/dist/domain/javascript/javascriptSemanticFingerprints.js +42 -41
  277. package/dist/domain/javascript/javascriptSemanticGraph.js +69 -23
  278. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +2 -10
  279. package/dist/domain/javascript/javascriptSemanticIterationSources.js +40 -7
  280. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +341 -87
  281. package/dist/domain/javascript/javascriptSemanticMutationValues.js +78 -35
  282. package/dist/domain/javascript/javascriptSemanticObjectReferences.js +381 -0
  283. package/dist/domain/javascript/javascriptSemanticObjects.js +7 -1
  284. package/dist/domain/javascript/javascriptSemanticProjection.js +52 -14
  285. package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +77 -0
  286. package/dist/domain/javascript/javascriptSemanticQuery.js +27 -29
  287. package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +1 -3
  288. package/dist/domain/javascript/javascriptSemanticReturnedReferences.js +219 -0
  289. package/dist/domain/javascript/javascriptSemanticReturns.js +13 -23
  290. package/dist/domain/javascript/javascriptSemanticState.js +22 -2
  291. package/dist/domain/javascript/javascriptSemanticTraversal.js +19 -1
  292. package/dist/domain/javascript/javascriptSemanticValues.js +47 -19
  293. package/dist/domain/javascript/javascriptSourceAnalysis.js +1 -0
  294. package/dist/domain/javascript/javascriptStaticAnalysis.js +29 -17
  295. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +8 -6
  296. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +49 -5
  297. package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +8 -4
  298. package/dist/domain/javascript/javascriptStaticAnalysisState.js +1 -0
  299. package/dist/domain/jeb/jebAnalysis.js +114 -0
  300. package/dist/domain/jsonShape.js +63 -52
  301. package/dist/domain/jsonValue.js +3 -0
  302. package/dist/domain/managed/managedApplicationGraph.js +37 -0
  303. package/dist/domain/managed/managedApplicationGraphCoverage.js +8 -2
  304. package/dist/domain/managed/managedApplicationGraphNodes.js +32 -22
  305. package/dist/domain/managed/managedArtifact.js +1 -0
  306. package/dist/domain/managed/managedInspectionEvidence.js +13 -0
  307. package/dist/domain/native/nativeAotPe.js +1408 -0
  308. package/dist/domain/native/nativeInstruction.js +21 -0
  309. package/dist/domain/native/nativeMetadataRecovery.js +79 -6
  310. package/dist/domain/native/peResources.js +94 -0
  311. package/dist/domain/nativeConvention.js +33 -0
  312. package/dist/domain/process/processCapture.js +91 -1
  313. package/dist/domain/process/processCaptureExample.js +24 -0
  314. package/dist/domain/process/processCaptureValidation.js +79 -0
  315. package/dist/domain/process/processScenario.js +59 -7
  316. package/dist/domain/propertyListKeys.js +3 -1
  317. package/dist/domain/referenceSourceGraph.js +25 -16
  318. package/dist/domain/referenceSourceImportParsing.js +6 -3
  319. package/dist/domain/referenceSourcePathIdentity.js +22 -0
  320. package/dist/domain/referenceSourceRequireBindings.js +137 -0
  321. package/dist/domain/webBundleAnalyzerInspection.js +14 -2
  322. package/dist/domain/webCaptureDiff.js +102 -4
  323. package/dist/domain/webScriptExportError.js +10 -4
  324. package/dist/domain/webScriptExportPlan.js +7 -13
  325. package/dist/domain/zipPackageFormat.js +4 -1
  326. package/dist/domain/zodCollectionSteps.js +24 -0
  327. package/dist/dotnet/ManagedArtifactInspector.js +55 -43
  328. package/dist/dotnet/ManagedDecodeBudget.js +80 -0
  329. package/dist/dotnet/ManagedMemberInspector.js +13 -6
  330. package/dist/dotnet/ManagedMemberInspectorCore.js +2 -2
  331. package/dist/dotnet/ManagedMemberInstructionDecoder.js +4 -2
  332. package/dist/dotnet/ManagedMemberRows.js +9 -4
  333. package/dist/dotnet/ManagedMetadataHeaps.js +15 -5
  334. package/dist/dotnet/ManagedMetadataInventoryRows.js +20 -11
  335. package/dist/dotnet/ManagedMetadataLayout.js +10 -4
  336. package/dist/dotnet/ManagedMethodBodyReader.js +8 -3
  337. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +3 -2
  338. package/dist/dotnet/ManagedNativeBoundaryInspector.js +49 -34
  339. package/dist/dotnet/ManagedPeReader.js +41 -25
  340. package/dist/dotnet/ManagedReaderFailure.js +2 -1
  341. package/dist/dotnet/ManagedStaticProvider.js +55 -24
  342. package/dist/evaluation/AgentEvaluationReport.js +9 -5
  343. package/dist/evaluation/CodexAgentEval.js +43 -13
  344. package/dist/evm/EvmoleFailures.js +0 -2
  345. package/dist/evm/EvmoleInterfaceProvider.js +67 -2
  346. package/dist/filesystem/OwnedDirectoryHandle.js +29 -0
  347. package/dist/filesystem/OwnedFileHandle.js +36 -0
  348. package/dist/filesystem/RegularFile.js +33 -1
  349. package/dist/filesystem/StableFileHash.js +46 -0
  350. package/dist/filesystem/readFileHandleChunks.js +26 -0
  351. package/dist/firmware/FirmwareCommand.js +25 -3
  352. package/dist/firmware/FirmwareFiles.js +23 -8
  353. package/dist/firmware/FirmwareProvider.js +156 -32
  354. package/dist/firmware/FirmwarePublication.js +24 -3
  355. package/dist/firmware/FirmwareRelease.js +1 -0
  356. package/dist/generatedPackageMetadata.js +2 -2
  357. package/dist/ghidra/GhidraAnalysisProfile.js +55 -4
  358. package/dist/ghidra/GhidraAnalysisSeeds.js +211 -0
  359. package/dist/ghidra/GhidraClient.js +76 -4
  360. package/dist/ghidra/GhidraDiagnostics.js +11 -8
  361. package/dist/ghidra/GhidraFunctionValues.js +26 -2
  362. package/dist/ghidra/GhidraInstallation.js +1 -1
  363. package/dist/ghidra/GhidraInventoryValues.js +23 -1
  364. package/dist/ghidra/GhidraLanguageCatalog.js +99 -0
  365. package/dist/ghidra/GhidraLauncher.js +80 -39
  366. package/dist/ghidra/GhidraLoadImageAttest.js +49 -2
  367. package/dist/ghidra/GhidraMipsProfile.js +79 -0
  368. package/dist/ghidra/GhidraProvider.js +57 -9
  369. package/dist/ghidra/GhidraProviderCapabilities.js +18 -8
  370. package/dist/ghidra/GhidraProviderClient.js +282 -21
  371. package/dist/ghidra/GhidraSessionValues.js +9 -2
  372. package/dist/hopper/HopperAnalysisProfile.js +2 -0
  373. package/dist/hopper/HopperClient.js +15 -6
  374. package/dist/hopper/HopperMachOImage.js +2 -0
  375. package/dist/hopper/HopperProvider.js +13 -2
  376. package/dist/ida/IdaOperationRunner.js +8 -2
  377. package/dist/ida/IdaProvider.js +7 -0
  378. package/dist/ida/IdaSessionClient.js +3 -1
  379. package/dist/ida/IdaWorkspace.js +4 -2
  380. package/dist/javascript/analysis/JavaScriptAnalysisTransfer.js +326 -0
  381. package/dist/javascript/analysis/JavaScriptAnalysisWorker.js +520 -0
  382. package/dist/javascript/analysis/JavaScriptAnalysisWorkerProtocol.js +63 -0
  383. package/dist/javascript/analysis/JavaScriptAnalysisWorkerSchemas.js +521 -0
  384. package/dist/javascript/analysis/JavaScriptAnalysisWorkerServer.js +116 -0
  385. package/dist/javascript/recovery/RecoveryFiles.js +18 -7
  386. package/dist/javascript/recovery/WakaruCommand.js +22 -9
  387. package/dist/javascript/recovery/WakaruExecution.js +11 -7
  388. package/dist/javascript/recovery/WakaruProvider.js +139 -16
  389. package/dist/javascript/recovery/WakaruPublication.js +14 -4
  390. package/dist/javascript/recovery/WakaruRelease.js +10 -3
  391. package/dist/javascript/recovery/WakaruReport.js +12 -7
  392. package/dist/javascript/recovery/WakaruVersion.js +24 -0
  393. package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -3
  394. package/dist/javascript/sourceMaps/SourceMapDecoder.js +63 -7
  395. package/dist/javascript/sourceMaps/SourceMapFormat.js +15 -4
  396. package/dist/jeb/JebMcpConnection.js +179 -0
  397. package/dist/jeb/JebMcpEndpoint.js +40 -0
  398. package/dist/jeb/JebProvider.js +299 -0
  399. package/dist/mcpDoctor.js +15 -6
  400. package/dist/native/AppleDispatchCoverage.js +25 -12
  401. package/dist/native/AppleDispatchMetadata.js +14 -7
  402. package/dist/native/AppleMachoFixups.js +71 -15
  403. package/dist/native/AppleMachoSelection.js +23 -3
  404. package/dist/native/NativeMacOSProvider.js +91 -16
  405. package/dist/native/NativeMachoInspection.js +11 -7
  406. package/dist/native/NativeUiHelperRuntime.js +6 -1
  407. package/dist/native/NativeUiObservation.js +4 -3
  408. package/dist/native/pe/PeResourceLayout.js +120 -0
  409. package/dist/native/pe/PeResourceParser.js +286 -0
  410. package/dist/native/pe/PeResourcesProvider.js +63 -0
  411. package/dist/process/BoundedFileBytes.js +30 -7
  412. package/dist/process/DarwinProcessRunTokenReader.js +8 -3
  413. package/dist/process/OwnedCommand.js +4 -3
  414. package/dist/process/ProcessOwnership.js +104 -112
  415. package/dist/process/ProcessOwnershipObservation.js +96 -39
  416. package/dist/process/ProcessOwnershipProcessTree.js +4 -4
  417. package/dist/process/ProcessRunTokenObservations.js +48 -0
  418. package/dist/process/ProviderDiagnosticRedaction.js +17 -0
  419. package/dist/process/ProviderProcess.js +4 -3
  420. package/dist/process/capture/FilesystemSnapshot.js +28 -4
  421. package/dist/process/capture/ProcessCaptureLifecycle.js +350 -59
  422. package/dist/process/capture/ProcessCaptureProgress.js +62 -0
  423. package/dist/process/capture/ProcessHarness.js +194 -26
  424. package/dist/process/capture/ProcessNormalization.js +3 -1
  425. package/dist/process/capture/ProcessScenarioRuntimeValidation.js +5 -2
  426. package/dist/process/capture/TerminalRenderer.js +24 -7
  427. package/dist/reference/ReferenceSourceReader.js +22 -5
  428. package/dist/reference/ReferenceSourceReaderEntries.js +114 -51
  429. package/dist/reference/ReferenceSourceReaderErrors.js +12 -0
  430. package/dist/reference/ReferenceSourceReaderFile.js +50 -10
  431. package/dist/reference/ReferenceSourceReaderValidate.js +4 -4
  432. package/dist/server/EvidenceMcpServer.js +36 -1
  433. package/dist/server/admittedToolOperation.js +9 -0
  434. package/dist/server/contractToolHandler.js +21 -0
  435. package/dist/server/createServer.js +97 -25
  436. package/dist/server/registerAdbTools.js +36 -0
  437. package/dist/server/registerAnalysisViewTool.js +4 -9
  438. package/dist/server/registerAndroidTools.js +3 -12
  439. package/dist/server/registerApktoolTools.js +14 -0
  440. package/dist/server/registerApplicationTools/compareExportShapes.js +4 -6
  441. package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
  442. package/dist/server/registerApplicationTools/compareVersions.js +3 -2
  443. package/dist/server/registerApplicationTools/coverage.js +3 -2
  444. package/dist/server/registerApplicationTools/obligationLedger.js +3 -2
  445. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -2
  446. package/dist/server/registerApplicationTools/traceFeature.js +3 -2
  447. package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
  448. package/dist/server/registerArtifactComparisonTool.js +5 -2
  449. package/dist/server/registerBinaryDiagnosticsTools.js +16 -4
  450. package/dist/server/registerBrowserScenarioTool.js +10 -7
  451. package/dist/server/registerBrowserTools.js +12 -9
  452. package/dist/server/registerBundleComparisonTool.js +16 -2
  453. package/dist/server/registerCloseLifecycleTool.js +32 -3
  454. package/dist/server/registerElectronTools.js +28 -10
  455. package/dist/server/registerEvmTools.js +4 -9
  456. package/dist/server/registerFirmwareTools.js +3 -11
  457. package/dist/server/registerFunctionComparisonTool.js +5 -2
  458. package/dist/server/registerJavaScriptRecoveryTool.js +4 -9
  459. package/dist/server/registerJavaScriptRuntimeObservationTools.js +9 -6
  460. package/dist/server/registerJebTools.js +16 -0
  461. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -6
  462. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -2
  463. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +3 -2
  464. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +3 -2
  465. package/dist/server/registerPeResourcesTool.js +9 -0
  466. package/dist/server/registerProcessComparisonTool.js +5 -2
  467. package/dist/server/registerRecordedCrashTools.js +4 -9
  468. package/dist/server/registerSessionRecordTools.js +2 -1
  469. package/dist/server/registerSessionTools.js +49 -18
  470. package/dist/server/registerWebModuleTool.js +4 -9
  471. package/dist/server/registerWebNetworkCaptureTool.js +4 -9
  472. package/dist/server/registerWebRuntimeTools.js +6 -5
  473. package/dist/server/registerWebScriptTool.js +6 -3
  474. package/dist/server/registerWebSourceLocationTool.js +4 -9
  475. package/dist/server/toolResult.js +21 -2
  476. package/dist/windows/WindowsPrivateRuntime.js +12 -5
  477. package/install.sh +7 -4
  478. package/licenses/nativeaot-parser-MIT.txt +28 -0
  479. package/native/windows/build/manifest.json +2 -2
  480. package/native/windows/build/rea-windows-x64.node +0 -0
  481. package/package.json +33 -5
  482. package/scripts/rea.mjs +16 -1
  483. package/skills/reverse-engineer-anything/SKILL.md +52 -51
  484. package/skills/reverse-engineer-anything/references/connection-and-recovery.md +127 -0
  485. package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -0
  486. package/skills/reverse-engineer-anything/references/javascript-applications.md +92 -13
  487. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +22 -1
@@ -0,0 +1,84 @@
1
+ import { AnalysisCancelledError } from "../domain/analysisErrorCore.js";
2
+ import { isAbsolute } from "node:path";
3
+ import { execFileOutput, execFileOutputFailure, } from "../process/ExecFileOutput.js";
4
+ /** Environment key selecting the caller's apktool launcher. */
5
+ export const APKTOOL_COMMAND_ENV = "REA_APKTOOL_COMMAND";
6
+ const VERSION_TIMEOUT_MS = 20_000;
7
+ const VERSION_MAX_OUTPUT_BYTES = 64 * 1024;
8
+ /**
9
+ * Resolve the caller-supplied apktool launcher. `REA_APKTOOL_COMMAND` must
10
+ * be absolute so the selection stays explicit; without it, apktool is
11
+ * resolved from `PATH` at run time. Both the upstream wrapper script and
12
+ * `java -jar` launcher scripts work: REA only runs `<command> --version`
13
+ * and `<command> d ...`.
14
+ */
15
+ export const resolveApktoolCommand = (environment) => {
16
+ const configured = environment[APKTOOL_COMMAND_ENV];
17
+ if (configured === undefined || configured.trim() === "")
18
+ return { command: "apktool", commandSource: "path" };
19
+ if (!isAbsolute(configured))
20
+ throw new ApktoolConfigurationFailure("not_absolute", `${APKTOOL_COMMAND_ENV} must be an absolute path to the apktool launcher`, { configured_command: configured });
21
+ return { command: configured, commandSource: "environment" };
22
+ };
23
+ export class ApktoolConfigurationFailure extends Error {
24
+ code;
25
+ diagnostics;
26
+ constructor(code, message, diagnostics = {}, options) {
27
+ super(message, options);
28
+ this.code = code;
29
+ this.diagnostics = diagnostics;
30
+ }
31
+ }
32
+ /** Read the version from `apktool --version` output (first non-empty line). */
33
+ export const parseApktoolVersionOutput = (stdout) => {
34
+ const line = stdout
35
+ .split(/\r?\n/u)
36
+ .map((entry) => entry.trim())
37
+ .find((entry) => entry !== "");
38
+ return { version: line === undefined ? null : line };
39
+ };
40
+ /** Probe the selected apktool launcher without decoding anything. */
41
+ export const inspectApktoolClient = async (selection, signal, environment = process.env) => {
42
+ try {
43
+ const { stdout } = await execFileOutput(selection.command, ["--version"], {
44
+ timeout: VERSION_TIMEOUT_MS,
45
+ stopSignal: "SIGTERM",
46
+ maxBuffer: VERSION_MAX_OUTPUT_BYTES,
47
+ env: { ...process.env, ...environment },
48
+ ...(signal === undefined ? {} : { signal }),
49
+ });
50
+ return parseApktoolVersionOutput(stdout);
51
+ }
52
+ catch (cause) {
53
+ const failure = execFileOutputFailure(cause);
54
+ if (signal?.aborted || failure?.code === "ABORT_ERR")
55
+ throw new AnalysisCancelledError("inspect_apktool_client", { cause });
56
+ if (failure?.code === "ENOENT")
57
+ throw new ApktoolConfigurationFailure("command_missing", `The selected apktool launcher was not found: ${selection.command}`, {
58
+ selected_command: selection.command,
59
+ command_source: selection.commandSource,
60
+ remediation: `Set ${APKTOOL_COMMAND_ENV} to an absolute apktool launcher (the upstream wrapper or a java -jar script)`,
61
+ }, { cause });
62
+ throw new ApktoolConfigurationFailure("version_unresolved", "The selected apktool launcher did not report a usable version", {
63
+ selected_command: selection.command,
64
+ ...(failure === undefined
65
+ ? {}
66
+ : {
67
+ exit_code: failure.code,
68
+ stderr_excerpt: failure.stderr.slice(0, 512),
69
+ }),
70
+ }, { cause });
71
+ }
72
+ };
73
+ /** Availability in the shape shared by every provider. */
74
+ const rejectionCodeOf = (code) => code === "command_missing"
75
+ ? "executable_missing"
76
+ : code === "not_absolute"
77
+ ? "not_configured"
78
+ : "version_unresolved";
79
+ export const apktoolConfigurationAvailability = (cause) => ({
80
+ status: "unavailable",
81
+ code: rejectionCodeOf(cause.code),
82
+ reason: cause.message,
83
+ diagnostics: { ...cause.diagnostics },
84
+ });
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Parsers for the decoded workspace `apktool d --no-src` produces.
3
+ *
4
+ * Apktool's apktool.yml is a small YAML document; the facts REA projects
5
+ * are flat enough that line-oriented extraction stays honest without a
6
+ * YAML dependency, and unrecognized content is ignored rather than guessed.
7
+ */
8
+ /**
9
+ * Project version and SDK facts from apktool.yml. Values keep apktool's
10
+ * own spelling (version codes can print as `45` or `45.1`).
11
+ */
12
+ export const parseApktoolYml = (yml) => {
13
+ const metadata = {
14
+ versionName: null,
15
+ versionCode: null,
16
+ minSdkVersion: null,
17
+ targetSdkVersion: null,
18
+ };
19
+ for (const line of yml.split(/\r?\n/u)) {
20
+ const versionName = /^\s*versionName:\s*(?:'([^']*)'|(.*))$/u.exec(line);
21
+ if (versionName !== null && metadata.versionName === null)
22
+ metadata.versionName = (versionName[1] ?? versionName[2] ?? "").trim();
23
+ const versionCode = /^\s*versionCode:\s*(?:'([^']*)'|(.*))$/u.exec(line);
24
+ if (versionCode !== null && metadata.versionCode === null)
25
+ metadata.versionCode = (versionCode[1] ?? versionCode[2] ?? "").trim();
26
+ const minSdk = /minSdkVersion:\s*'?([0-9]+)'?/u.exec(line);
27
+ if (minSdk !== null && metadata.minSdkVersion === null)
28
+ metadata.minSdkVersion = minSdk[1];
29
+ const targetSdk = /targetSdkVersion:\s*'?([0-9]+)'?/u.exec(line);
30
+ if (targetSdk !== null && metadata.targetSdkVersion === null)
31
+ metadata.targetSdkVersion = targetSdk[1];
32
+ }
33
+ return metadata;
34
+ };
35
+ /** Read the package attribute from decoded AndroidManifest.xml text. */
36
+ export const parseManifestPackage = (manifest) => {
37
+ const match = /<manifest[^>]*\spackage="([^"]+)"/u.exec(manifest);
38
+ return match === null ? null : match[1];
39
+ };
40
+ /**
41
+ * Project `<string name="...">value</string>` entries from one decoded
42
+ * strings.xml. Values are preserved exactly as apktool printed them —
43
+ * escaped entities stay escaped — and entries containing nested markup
44
+ * are counted as unparsed rather than flattened.
45
+ */
46
+ export const parseDecodedStrings = (stringsXml) => {
47
+ const entries = [];
48
+ let unparsedCount = 0;
49
+ const pattern = /<string\s+name="([^"]+)"[^>]*>([\s\S]*?)<\/string>/gu;
50
+ for (let match = pattern.exec(stringsXml); match !== null; match = pattern.exec(stringsXml)) {
51
+ const value = match[2];
52
+ if (value.includes("<")) {
53
+ unparsedCount += 1;
54
+ continue;
55
+ }
56
+ entries.push({ name: match[1], value: value.trim() });
57
+ }
58
+ return { entries, unparsedCount };
59
+ };
@@ -0,0 +1,506 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import { createWriteStream, constants as fsConstants } from "node:fs";
3
+ import { access, chmod, mkdir, mkdtemp, opendir, open, rm, stat, } from "node:fs/promises";
4
+ import { tmpdir } from "node:os";
5
+ import { join } from "node:path";
6
+ import { Transform } from "node:stream";
7
+ import { pipeline } from "node:stream/promises";
8
+ import { createAnalysisExecution, } from "../application/AnalysisProvider.js";
9
+ import { AnalysisCapabilityUnavailableError, AnalysisCancelledError, AnalysisInputError, AnalysisProtocolError, AnalysisResourceConstraintError, AnalysisTimeoutError, AnalysisUnsupportedTargetError, } from "../domain/analysisErrorCore.js";
10
+ import { analysisErrorWithCleanupFailure } from "../domain/analysisErrorCleanup.js";
11
+ import { err, ok } from "../domain/result.js";
12
+ import { ProviderCleanupError } from "../domain/providerCleanupError.js";
13
+ import { openRegularFile, sameRegularFileState, } from "../filesystem/RegularFile.js";
14
+ import { OwnedCommandFailure, runOwnedCommand, } from "../process/OwnedCommand.js";
15
+ import { snapshotEnvironment } from "../process/snapshotEnvironment.js";
16
+ import { ApktoolConfigurationFailure, apktoolConfigurationAvailability, inspectApktoolClient, resolveApktoolCommand, } from "./ApktoolConfiguration.js";
17
+ import { parseApktoolYml, parseDecodedStrings, parseManifestPackage, } from "./ApktoolDecodeOutput.js";
18
+ /** Stable identity for the Apktool resource-decoding provider. */
19
+ export const APKTOOL_PROVIDER_IDENTITY = {
20
+ id: "apktool",
21
+ name: "Apktool",
22
+ version: null,
23
+ };
24
+ const DECODE_TIMEOUT_MS = 600_000;
25
+ const DECODE_MAX_OUTPUT_BYTES = 4 * 1024 * 1024;
26
+ const MANIFEST_MAX_BYTES = 512 * 1024;
27
+ const STRINGS_XML_MAX_BYTES = 8 * 1024 * 1024;
28
+ const MAX_STRINGS = 2_000;
29
+ const MAX_DECODED_ENTRIES_VISITED = 100_000;
30
+ const STDERR_EXCERPT_BYTES = 512;
31
+ const throwIfCancelled = (operation, signal) => {
32
+ if (signal?.aborted === true)
33
+ throw new AnalysisCancelledError(operation);
34
+ };
35
+ /** Read at most the byte budget plus one byte, before decoding UTF-8. */
36
+ const readBoundedText = async (path, budget, operation, signal) => {
37
+ const file = await open(path, "r").catch((cause) => {
38
+ if (cause.code === "ENOENT")
39
+ return null;
40
+ throw cause;
41
+ });
42
+ if (file === null)
43
+ return { text: null, truncated: false };
44
+ try {
45
+ throwIfCancelled(operation, signal);
46
+ const bytes = Buffer.alloc(budget + 1);
47
+ let length = 0;
48
+ while (length < bytes.length) {
49
+ throwIfCancelled(operation, signal);
50
+ const result = await file.read(bytes, length, bytes.length - length, null);
51
+ if (result.bytesRead === 0)
52
+ break;
53
+ length += result.bytesRead;
54
+ }
55
+ throwIfCancelled(operation, signal);
56
+ const truncated = length > budget;
57
+ // A prefix may end within a UTF-8 character; omit those trailing bytes.
58
+ const decoder = new TextDecoder("utf-8");
59
+ return {
60
+ text: decoder.decode(bytes.subarray(0, Math.min(length, budget)), {
61
+ stream: truncated,
62
+ }),
63
+ truncated,
64
+ };
65
+ }
66
+ finally {
67
+ await file.close();
68
+ }
69
+ };
70
+ const localeQualifier = (locale) => locale.replace(/^([a-z]{2,3})-([A-Z]{2}|[0-9]{3})$/u, "$1-r$2");
71
+ const runApktool = async (operation, command, arguments_, limits, signal, environment, onCleanupOwner) => {
72
+ if (signal?.aborted === true)
73
+ return err(new AnalysisCancelledError(operation));
74
+ try {
75
+ const output = await runOwnedCommand({
76
+ command,
77
+ arguments: arguments_,
78
+ runId: randomUUID(),
79
+ hostEnvironment: { ...process.env, ...environment },
80
+ }, {
81
+ timeoutMs: limits.timeoutMs,
82
+ diagnosticBytes: limits.maxOutputBytes,
83
+ }, signal === undefined ? {} : { signal });
84
+ return ok({ stdout: output.stdout.text, stderr: output.stderr.text });
85
+ }
86
+ catch (cause) {
87
+ if (!(cause instanceof OwnedCommandFailure))
88
+ return err(new AnalysisProtocolError(`apktool failed for ${operation}`, { cause }));
89
+ if (cause.cleanupOwner !== undefined)
90
+ onCleanupOwner(cause.cleanupOwner);
91
+ const output = cause.snapshot;
92
+ const capturedOutput = output === null
93
+ ? undefined
94
+ : {
95
+ stdout: output.stdout.text,
96
+ stderr: output.stderr.text,
97
+ truncated: output.diagnosticTruncated === true,
98
+ stdout_bytes: output.stdout.bytes,
99
+ stderr_bytes: output.stderr.bytes,
100
+ exit_code: output.exitCode ?? null,
101
+ signal: output.signal ?? null,
102
+ };
103
+ const cleanup = cause.cleanupFailure === null
104
+ ? undefined
105
+ : {
106
+ reason: cause.cleanupFailure,
107
+ resources: cause.resources,
108
+ };
109
+ if (cause.reason === "cancelled")
110
+ return err(new AnalysisCancelledError(operation, {
111
+ cause,
112
+ ...(cleanup === undefined ? {} : { cleanup }),
113
+ ...(capturedOutput === undefined ? {} : { capturedOutput }),
114
+ }));
115
+ if (cause.reason === "timeout")
116
+ return err(new AnalysisTimeoutError(operation, limits.timeoutMs, {
117
+ cause,
118
+ ...(cleanup === undefined ? {} : { cleanup }),
119
+ ...(capturedOutput === undefined ? {} : { capturedOutput }),
120
+ }));
121
+ if (cause.reason === "output-limit")
122
+ return err(new AnalysisResourceConstraintError(operation, "memory", `apktool output exceeded the ${String(limits.maxOutputBytes)}-byte capture budget`, { max_output_bytes: limits.maxOutputBytes }, {
123
+ cause,
124
+ ...(cleanup === undefined ? {} : { cleanup }),
125
+ ...(capturedOutput === undefined ? {} : { capturedOutput }),
126
+ }));
127
+ return err(new AnalysisUnsupportedTargetError(operation, command, output?.stderr.text.trim().slice(0, STDERR_EXCERPT_BYTES) ||
128
+ `apktool exited with code ${String(output?.exitCode ?? "unknown")} for ${operation}`, {
129
+ cause,
130
+ ...(cleanup === undefined ? {} : { cleanup }),
131
+ ...(capturedOutput === undefined ? {} : { capturedOutput }),
132
+ }));
133
+ }
134
+ };
135
+ /** Count files while bounding streamed directory-entry traversal. */
136
+ const countDecodedFiles = async (root, signal, operation) => {
137
+ let count = 0;
138
+ let capped = false;
139
+ let visited = 0;
140
+ const directories = [root];
141
+ const locales = [];
142
+ while (directories.length > 0 && !capped) {
143
+ throwIfCancelled(operation, signal);
144
+ const directory = directories.pop();
145
+ for await (const entry of await opendir(directory)) {
146
+ throwIfCancelled(operation, signal);
147
+ if (visited >= MAX_DECODED_ENTRIES_VISITED) {
148
+ capped = true;
149
+ break;
150
+ }
151
+ visited += 1;
152
+ const path = join(directory, entry.name);
153
+ if (entry.isDirectory()) {
154
+ directories.push(path);
155
+ if (directory === join(root, "res")) {
156
+ const match = /^values-(.+)$/u.exec(entry.name);
157
+ if (match !== null &&
158
+ (await access(join(path, "strings.xml")).then(() => true, () => false)))
159
+ locales.push(match[1]);
160
+ }
161
+ }
162
+ else if (entry.isFile())
163
+ count += 1;
164
+ }
165
+ }
166
+ return { count, capped, locales: locales.sort() };
167
+ };
168
+ /**
169
+ * Apktool resource decoding over a caller-selected launcher.
170
+ *
171
+ * Decoding happens in a provider-owned temporary workspace that is removed
172
+ * once the requested facts are projected; smali production is skipped
173
+ * (`--no-src`) because Java-source recovery belongs to the JADX family.
174
+ */
175
+ export class ApktoolProvider {
176
+ environment;
177
+ workspaces = new Set();
178
+ removeWorkspace;
179
+ #pendingCommandOwners = new Map();
180
+ #shutdown = new AbortController();
181
+ #active = new Set();
182
+ #closing = false;
183
+ #closePromise;
184
+ constructor(options = {}) {
185
+ this.environment = snapshotEnvironment(options.environment ?? process.env);
186
+ this.removeWorkspace =
187
+ options.removeWorkspace ??
188
+ ((path) => rm(path, { recursive: true, force: true }));
189
+ }
190
+ selection() {
191
+ return resolveApktoolCommand(this.environment);
192
+ }
193
+ /** Probe the selected apktool launcher; decodes nothing. */
194
+ inspectAvailability(signal) {
195
+ if (this.#closing)
196
+ return Promise.reject(new AnalysisCancelledError("inspect_apktool_client"));
197
+ const operationSignal = signal === undefined
198
+ ? this.#shutdown.signal
199
+ : AbortSignal.any([signal, this.#shutdown.signal]);
200
+ return this.#track(this.#inspectAvailability(operationSignal));
201
+ }
202
+ async #inspectAvailability(signal) {
203
+ const selection = this.selection();
204
+ try {
205
+ await inspectApktoolClient(selection, signal, this.environment);
206
+ throwIfCancelled("inspect_apktool_client", signal);
207
+ return {
208
+ status: "available",
209
+ code: null,
210
+ reason: null,
211
+ diagnostics: {
212
+ selected_command: selection.command,
213
+ command_source: selection.commandSource,
214
+ },
215
+ };
216
+ }
217
+ catch (cause) {
218
+ if (cause instanceof ApktoolConfigurationFailure)
219
+ return apktoolConfigurationAvailability(cause);
220
+ throw cause;
221
+ }
222
+ }
223
+ /** Retain failed cleanup ownership and retry it on close. */
224
+ async close() {
225
+ this.#closing = true;
226
+ this.#shutdown.abort();
227
+ this.#closePromise ??= this.#drainAndClean().catch((cause) => {
228
+ this.#closePromise = undefined;
229
+ throw cause;
230
+ });
231
+ return this.#closePromise;
232
+ }
233
+ execute(request, options) {
234
+ if (this.#closing)
235
+ return Promise.resolve(err(new AnalysisCancelledError(request.operation)));
236
+ const signal = options?.signal === undefined
237
+ ? this.#shutdown.signal
238
+ : AbortSignal.any([options.signal, this.#shutdown.signal]);
239
+ return this.#track(this.#execute(request, signal));
240
+ }
241
+ async #execute(request, signal) {
242
+ if (signal?.aborted === true)
243
+ return err(new AnalysisCancelledError(request.operation));
244
+ const selection = this.selection();
245
+ let identity;
246
+ try {
247
+ identity = await inspectApktoolClient(selection, signal, this.environment);
248
+ }
249
+ catch (cause) {
250
+ if (cause instanceof AnalysisCancelledError)
251
+ return err(cause);
252
+ if (cause instanceof ApktoolConfigurationFailure)
253
+ return err(new AnalysisCapabilityUnavailableError(APKTOOL_PROVIDER_IDENTITY.id, request.operation, typeof cause.diagnostics.remediation === "string"
254
+ ? `${cause.message} ${cause.diagnostics.remediation}`
255
+ : cause.message, { cause }));
256
+ return err(new AnalysisProtocolError(`apktool version probe failed for ${request.operation}`, { cause }));
257
+ }
258
+ if (signal.aborted)
259
+ return err(new AnalysisCancelledError(request.operation));
260
+ const client = {
261
+ command: selection.command,
262
+ command_source: selection.commandSource,
263
+ apktool_version: identity.version,
264
+ };
265
+ const provider = {
266
+ ...APKTOOL_PROVIDER_IDENTITY,
267
+ version: identity.version,
268
+ };
269
+ if (request.operation === "inspect_apktool_client")
270
+ return ok(createAnalysisExecution({ client }, provider));
271
+ return this.decodeResources(request.operation, selection, client, provider, request.input, signal);
272
+ }
273
+ #track(operation) {
274
+ const settled = operation.then(() => undefined, () => undefined);
275
+ this.#active.add(settled);
276
+ void settled.then(() => this.#active.delete(settled));
277
+ return operation;
278
+ }
279
+ async #drainAndClean() {
280
+ await Promise.all(this.#active);
281
+ const failures = [];
282
+ for (const [owner, root] of this.#pendingCommandOwners) {
283
+ try {
284
+ const stopped = await owner.stop();
285
+ if (stopped.status === "incomplete")
286
+ throw new Error(stopped.reason);
287
+ this.#pendingCommandOwners.delete(owner);
288
+ }
289
+ catch (cause) {
290
+ failures.push(new Error(`apktool process cleanup remains incomplete for ${root}: ${cause instanceof Error ? cause.message : String(cause)}`, { cause }));
291
+ }
292
+ }
293
+ if (failures.length > 0)
294
+ throw new AggregateError(failures, "Apktool process cleanup failed");
295
+ for (const path of this.workspaces) {
296
+ try {
297
+ await this.removeWorkspace(path);
298
+ this.workspaces.delete(path);
299
+ }
300
+ catch (cause) {
301
+ failures.push(cause);
302
+ }
303
+ }
304
+ if (failures.length > 0)
305
+ throw new AggregateError(failures, "Apktool workspace cleanup failed");
306
+ }
307
+ async decodeResources(operation, selection, client, provider, input, signal) {
308
+ const root = await mkdtemp(join(tmpdir(), "rea-apktool-"));
309
+ this.workspaces.add(root);
310
+ const workspace = join(root, "decoded");
311
+ const snapshot = join(root, "input.apk");
312
+ const framework = join(root, "framework");
313
+ let cleanupFailure = null;
314
+ // The workspace is removed before the result is returned, so an
315
+ // unremovable workspace is reported instead of silently abandoned.
316
+ const removeWorkspace = async () => {
317
+ if ([...this.#pendingCommandOwners.values()].includes(root)) {
318
+ cleanupFailure = `The decode workspace is retained until its apktool process stops: ${root}`;
319
+ return;
320
+ }
321
+ try {
322
+ await this.removeWorkspace(root);
323
+ this.workspaces.delete(root);
324
+ }
325
+ catch {
326
+ cleanupFailure = `The decode workspace could not be removed: ${root}`;
327
+ }
328
+ };
329
+ const failureWithCleanup = (failure) => cleanupFailure === null
330
+ ? failure
331
+ : analysisErrorWithCleanupFailure(failure, new ProviderCleanupError(APKTOOL_PROVIDER_IDENTITY.id, [root], { reason: cleanupFailure }, { operation }), operation);
332
+ let source;
333
+ let sourceAdmissionFailed = false;
334
+ try {
335
+ throwIfCancelled(operation, signal);
336
+ sourceAdmissionFailed = true;
337
+ source = await openRegularFile(input.path, {
338
+ symlinks: "follow",
339
+ ...(signal === undefined ? {} : { signal }),
340
+ });
341
+ const sourceInfo = await source.stat();
342
+ sourceAdmissionFailed = false;
343
+ const sourceSize = sourceInfo.size;
344
+ let copiedBytes = 0;
345
+ const sourceHash = createHash("sha256");
346
+ const boundedSource = new Transform({
347
+ transform(chunk, _encoding, callback) {
348
+ copiedBytes += chunk.length;
349
+ if (copiedBytes > sourceSize) {
350
+ callback(new AnalysisInputError(operation, {
351
+ cause: new Error(`The selected APK changed while being copied: ${input.path}`),
352
+ }));
353
+ return;
354
+ }
355
+ sourceHash.update(chunk);
356
+ callback(null, chunk);
357
+ },
358
+ });
359
+ await pipeline(source.createReadStream({
360
+ start: 0,
361
+ end: sourceSize,
362
+ autoClose: false,
363
+ ...(signal === undefined ? {} : { signal }),
364
+ }), boundedSource, createWriteStream(snapshot, { flags: "wx", mode: 0o600 }), signal === undefined ? {} : { signal });
365
+ const finalSourceInfo = await source.stat();
366
+ if (copiedBytes !== sourceSize ||
367
+ !sameRegularFileState(sourceInfo, finalSourceInfo))
368
+ throw new AnalysisInputError(operation, {
369
+ cause: new Error(`The selected APK changed while being copied: ${input.path}`),
370
+ });
371
+ const sha256 = sourceHash.digest("hex");
372
+ await source.close();
373
+ source = undefined;
374
+ await chmod(snapshot, 0o400);
375
+ throwIfCancelled(operation, signal);
376
+ const snapshotInfo = await stat(snapshot);
377
+ await mkdir(workspace);
378
+ await mkdir(framework);
379
+ const decoded = await runApktool(operation, selection.command, [
380
+ "d",
381
+ "--no-src",
382
+ "-f",
383
+ "-o",
384
+ workspace,
385
+ "--frame-path",
386
+ framework,
387
+ snapshot,
388
+ ], {
389
+ timeoutMs: DECODE_TIMEOUT_MS,
390
+ maxOutputBytes: DECODE_MAX_OUTPUT_BYTES,
391
+ }, signal, this.environment, (owner) => this.#pendingCommandOwners.set(owner, root));
392
+ if (!decoded.ok) {
393
+ await removeWorkspace();
394
+ return err(failureWithCleanup(decoded.error));
395
+ }
396
+ throwIfCancelled(operation, signal);
397
+ const yml = await readBoundedText(join(workspace, "apktool.yml"), MANIFEST_MAX_BYTES, operation, signal);
398
+ if (yml.text === null || yml.truncated) {
399
+ throw new AnalysisProtocolError(`apktool produced missing or oversized apktool.yml: ${input.path}`);
400
+ }
401
+ const metadata = parseApktoolYml(yml.text);
402
+ const manifestRead = await readBoundedText(join(workspace, "AndroidManifest.xml"), MANIFEST_MAX_BYTES, operation, signal);
403
+ const manifest = manifestRead.text;
404
+ const packageName = manifest === null ? null : parseManifestPackage(manifest);
405
+ const stringsDirectory = input.locale === undefined
406
+ ? "values"
407
+ : `values-${localeQualifier(input.locale)}`;
408
+ const stringsRead = input.include_strings
409
+ ? await readBoundedText(join(workspace, "res", stringsDirectory, "strings.xml"), STRINGS_XML_MAX_BYTES, operation, signal)
410
+ : { text: null, truncated: false };
411
+ // Do not parse an incomplete XML document as though its projection were complete.
412
+ const stringsXml = stringsRead.truncated ? null : stringsRead.text;
413
+ const parsedStrings = stringsXml === null
414
+ ? { entries: [], unparsedCount: 0 }
415
+ : parseDecodedStrings(stringsXml);
416
+ const bounded = parsedStrings.entries.slice(0, MAX_STRINGS);
417
+ const files = await countDecodedFiles(workspace, signal, operation);
418
+ throwIfCancelled(operation, signal);
419
+ const coverage = (stringsXml !== null && parsedStrings.entries.length > MAX_STRINGS) ||
420
+ manifestRead.truncated ||
421
+ stringsRead.truncated ||
422
+ parsedStrings.unparsedCount > 0 ||
423
+ files.capped
424
+ ? "partial"
425
+ : "complete";
426
+ await removeWorkspace();
427
+ return ok(createAnalysisExecution({
428
+ client,
429
+ target: { path: input.path, bytes: snapshotInfo.size, sha256 },
430
+ metadata: {
431
+ version_name: metadata.versionName,
432
+ version_code: metadata.versionCode,
433
+ min_sdk_version: metadata.minSdkVersion,
434
+ target_sdk_version: metadata.targetSdkVersion,
435
+ package_name: packageName,
436
+ },
437
+ manifest,
438
+ strings: bounded,
439
+ locale: input.locale ?? null,
440
+ locales: files.locales,
441
+ decoded_file_count: files.count,
442
+ coverage,
443
+ }, provider, {
444
+ limitations: [
445
+ "Decoding skips smali (--no-src); Java-source recovery belongs to the JADX family",
446
+ ...(input.locale !== undefined &&
447
+ stringsRead.text === null &&
448
+ input.include_strings
449
+ ? [`No strings.xml was found for locale ${input.locale}`]
450
+ : []),
451
+ ...(input.include_strings &&
452
+ stringsRead.text === null &&
453
+ input.locale === undefined
454
+ ? [
455
+ "No default res/values/strings.xml was found in the decoded workspace",
456
+ ]
457
+ : []),
458
+ ...(parsedStrings.unparsedCount > 0
459
+ ? [
460
+ `${String(parsedStrings.unparsedCount)} string entries with nested markup were not projected`,
461
+ ]
462
+ : []),
463
+ ...(parsedStrings.entries.length > MAX_STRINGS
464
+ ? [
465
+ `strings reports the first ${String(MAX_STRINGS)} of ${String(parsedStrings.entries.length)} entries`,
466
+ ]
467
+ : []),
468
+ ...(manifestRead.truncated
469
+ ? [
470
+ `manifest is truncated at ${String(MANIFEST_MAX_BYTES)} bytes`,
471
+ ]
472
+ : []),
473
+ ...(stringsRead.truncated
474
+ ? [
475
+ `strings.xml exceeds the ${String(STRINGS_XML_MAX_BYTES)}-byte projection budget`,
476
+ ]
477
+ : []),
478
+ ...(files.capped
479
+ ? [
480
+ `Decoded workspace enumeration stopped after ${String(MAX_DECODED_ENTRIES_VISITED)} entries; decoded_file_count and locales may be partial`,
481
+ ]
482
+ : []),
483
+ ...(cleanupFailure === null ? [] : [cleanupFailure]),
484
+ ],
485
+ }));
486
+ }
487
+ catch (cause) {
488
+ await removeWorkspace();
489
+ return err(failureWithCleanup(signal?.aborted === true
490
+ ? new AnalysisCancelledError(operation, { cause })
491
+ : sourceAdmissionFailed
492
+ ? new AnalysisInputError(operation, { cause })
493
+ : cause instanceof AnalysisInputError
494
+ ? cause
495
+ : cause instanceof AnalysisCancelledError ||
496
+ cause instanceof AnalysisProtocolError
497
+ ? cause
498
+ : new AnalysisProtocolError("Apktool resource projection failed", {
499
+ cause,
500
+ })));
501
+ }
502
+ finally {
503
+ await source?.close().catch(() => undefined);
504
+ }
505
+ }
506
+ }
@@ -1,9 +1,15 @@
1
1
  import { jsonValueSchema } from "../domain/jsonValue.js";
2
- /** Build a validated atomic provider observation at an adapter boundary. */
2
+ /**
3
+ * Build a validated atomic provider observation at an adapter boundary.
4
+ *
5
+ * Pass `rawResult` only for a provider representation distinct from
6
+ * `result`. Omitting it records `null` rather than a second complete copy of
7
+ * the normalized result in every Evidence record and tool response.
8
+ */
3
9
  export const createAnalysisExecution = (result, provider, options = {}) => ({
4
10
  result: jsonValueSchema.parse(result),
5
11
  rawResult: options.rawResult === undefined
6
- ? jsonValueSchema.parse(result)
12
+ ? null
7
13
  : jsonValueSchema.parse(options.rawResult),
8
14
  provider,
9
15
  ...(options.analysisProfile === undefined