rea-agents 6.2.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 (636) hide show
  1. package/README.md +24 -23
  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/bridge/hopper_bridge.py +2 -0
  6. package/dist/adb/AdbConfiguration.js +88 -0
  7. package/dist/adb/AdbDeviceOutput.js +186 -0
  8. package/dist/adb/AdbProvider.js +1190 -0
  9. package/dist/adb/AdbShellOutput.js +309 -0
  10. package/dist/android/AndroidTargetSnapshot.js +104 -22
  11. package/dist/android/JadxConfiguration.js +44 -24
  12. package/dist/android/JadxProvider.js +59 -21
  13. package/dist/android/JadxSession.js +51 -9
  14. package/dist/apktool/ApktoolConfiguration.js +84 -0
  15. package/dist/apktool/ApktoolDecodeOutput.js +59 -0
  16. package/dist/apktool/ApktoolProvider.js +506 -0
  17. package/dist/application/AnalysisProvider.js +8 -2
  18. package/dist/application/AppBundleExecutable.js +27 -22
  19. package/dist/application/BinaryTargetResolver.js +85 -19
  20. package/dist/application/BrowserScenarioEvidence.js +2 -2
  21. package/dist/application/CapabilityInventory.js +11 -1
  22. package/dist/application/ClientConfigurationDocument.js +98 -0
  23. package/dist/application/ClientConfigurationFiles.js +91 -0
  24. package/dist/application/ClientRegistrationEnvironment.js +35 -0
  25. package/dist/application/ClientRegistrationStatus.js +75 -27
  26. package/dist/application/DirectAnalysis.js +14 -8
  27. package/dist/application/DirectAnalysisCleanup.js +1 -2
  28. package/dist/application/DirectAnalysisStatus.js +3 -6
  29. package/dist/application/Doctor.js +27 -34
  30. package/dist/application/DoctorDiagnostics.js +1 -1
  31. package/dist/application/EvidenceBundleCommands.js +6 -12
  32. package/dist/application/EvidenceBundleFiles.js +1 -1
  33. package/dist/application/GeminiClientSettings.js +139 -0
  34. package/dist/application/HermesClientHome.js +115 -0
  35. package/dist/application/HopperDownload.js +39 -0
  36. package/dist/application/InvestigationProviders.js +10 -4
  37. package/dist/application/JsonFiles.js +16 -15
  38. package/dist/application/JsonInputFile.js +252 -0
  39. package/dist/application/LinuxHopper.js +6 -13
  40. package/dist/application/MacHopper.js +172 -149
  41. package/dist/application/MipsElfAbiFlags.js +140 -0
  42. package/dist/application/ProviderOperationExecution.js +31 -0
  43. package/dist/application/ReconstructionObligationCandidates.js +16 -3
  44. package/dist/application/ReconstructionObligationLedgerProjection.js +3 -1
  45. package/dist/application/ReferenceSourceImport.js +76 -29
  46. package/dist/application/ReferenceSourceImportEntries.js +18 -9
  47. package/dist/application/ReferenceSourceImportPolicy.js +99 -23
  48. package/dist/application/ReferenceSourceImportTypes.js +30 -22
  49. package/dist/application/ReferenceSourceVcsAdapter.js +145 -30
  50. package/dist/application/RegularFileRead.js +103 -0
  51. package/dist/application/Setup.js +69 -10
  52. package/dist/application/SetupClientConfiguration.js +134 -23
  53. package/dist/application/SetupHost.js +102 -22
  54. package/dist/application/SetupPlan.js +18 -17
  55. package/dist/application/SetupSkill.js +81 -13
  56. package/dist/application/SupportedClients.js +305 -37
  57. package/dist/application/Uninstall.js +172 -8
  58. package/dist/application/UpdateMaintenance.js +23 -23
  59. package/dist/application/Utf8JsonInput.js +71 -0
  60. package/dist/application/WebScriptExportService.js +130 -57
  61. package/dist/application/WebSourceLocationService.js +3 -0
  62. package/dist/application/adb/AdbDeviceAnalysisPort.js +1 -0
  63. package/dist/application/adb/AdbDeviceAnalysisService.js +13 -0
  64. package/dist/application/analysisView/AnalysisViewService.js +40 -2
  65. package/dist/application/android/AndroidAnalysisService.js +1 -1
  66. package/dist/application/apktool/ApktoolResourceAnalysisPort.js +1 -0
  67. package/dist/application/apktool/ApktoolResourceAnalysisService.js +13 -0
  68. package/dist/application/binary/AnalysisClientCleanup.js +0 -24
  69. package/dist/application/binary/AnalysisSnapshotCache.js +5 -4
  70. package/dist/application/binary/BinarySession.js +18 -1
  71. package/dist/application/binary/BinarySessionOpen.js +9 -1
  72. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +2 -1
  73. package/dist/application/binaryDiagnostics/PeResourcesPort.js +1 -0
  74. package/dist/application/binaryDiagnostics/PeResourcesService.js +111 -0
  75. package/dist/application/binaryDiagnostics/RecordedCrashService.js +2 -1
  76. package/dist/application/evm/EvmInterfaceService.js +3 -0
  77. package/dist/application/firmware/FirmwareAnalysisService.js +3 -0
  78. package/dist/application/investigation/InspectEvidenceBundle.js +18 -0
  79. package/dist/application/javascript/ElectronActiveEvidence.js +2 -2
  80. package/dist/application/javascript/ElectronBoundaryAnalysis.js +2 -2
  81. package/dist/application/javascript/ElectronBoundaryGraphContext.js +3 -2
  82. package/dist/application/javascript/ElectronBoundaryGraphIpc.js +2 -2
  83. package/dist/application/javascript/ElectronBoundaryGraphNative.js +20 -3
  84. package/dist/application/javascript/ElectronBoundaryGraphWindows.js +3 -3
  85. package/dist/application/javascript/JavaScriptApplicationEvidence.js +1 -0
  86. package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +107 -46
  87. package/dist/application/javascript/JavaScriptApplicationService.js +23 -11
  88. package/dist/application/javascript/JavaScriptApplicationWorkflowEvidence.js +5 -6
  89. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +59 -45
  90. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +171 -36
  91. package/dist/application/javascript/JavaScriptArtifactGraphAccumulator.js +14 -16
  92. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +74 -36
  93. package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +4 -3
  94. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +11 -5
  95. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +53 -42
  96. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +92 -10
  97. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +293 -238
  98. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +120 -28
  99. package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +4 -0
  100. package/dist/application/javascript/JavaScriptJsonModules.js +2 -2
  101. package/dist/application/javascript/JavaScriptModuleRelationships.js +10 -20
  102. package/dist/application/javascript/JavaScriptRecoveryService.js +3 -0
  103. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +11 -27
  104. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +11 -5
  105. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +206 -66
  106. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -1
  107. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +18 -23
  108. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +5 -2
  109. package/dist/application/javascript/JavaScriptSemanticGraphEvidence.js +1 -1
  110. package/dist/application/javascript/JavaScriptSemanticGraphFingerprintProjection.js +2 -2
  111. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +7 -5
  112. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +6 -4
  113. package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +4 -4
  114. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +1 -1
  115. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +29 -15
  116. package/dist/application/javascript/JavaScriptSemanticTraceService.js +15 -10
  117. package/dist/application/jeb/JebAnalysisPort.js +1 -0
  118. package/dist/application/jeb/JebAnalysisService.js +13 -0
  119. package/dist/application/managed/ManagedApplicationGraphService.js +1 -1
  120. package/dist/application/native/NativeCallRoutes.js +2 -4
  121. package/dist/application/native/NativeUiActionTrace.js +16 -8
  122. package/dist/application/native/NativeValueTrace.js +23 -6
  123. package/dist/application/process/ProcessCli.js +25 -20
  124. package/dist/artifacts/ArtifactPaths.js +129 -8
  125. package/dist/artifacts/ArtifactProvider.js +34 -31
  126. package/dist/artifacts/ArtifactProviderMetadata.js +1 -4
  127. package/dist/artifacts/ArtifactReader.js +23 -0
  128. package/dist/artifacts/ArtifactResourceScope.js +100 -0
  129. package/dist/artifacts/AsarArtifactReader.js +218 -80
  130. package/dist/artifacts/AsarHeader.js +24 -0
  131. package/dist/artifacts/DirectoryArtifactReader.js +168 -65
  132. package/dist/artifacts/MachOSliceArtifactReader.js +116 -39
  133. package/dist/artifacts/NativeDmgArtifactReader.js +179 -87
  134. package/dist/artifacts/NativeDmgOwnership.js +109 -0
  135. package/dist/artifacts/SafeOutputTree.js +245 -70
  136. package/dist/artifacts/SafeOutputTreeCleanup.js +45 -0
  137. package/dist/artifacts/SafeOutputTreeCreationFailure.js +20 -0
  138. package/dist/artifacts/SafeOutputTreeIdentity.js +42 -0
  139. package/dist/artifacts/SafeOutputTreeReadback.js +33 -0
  140. package/dist/artifacts/ZipArtifactReader.js +77 -27
  141. package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +58 -18
  142. package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +62 -24
  143. package/dist/artifacts/apple/KeyedArchiveReader.js +76 -49
  144. package/dist/artifacts/apple/MachoLoadCommandReader.js +36 -6
  145. package/dist/artifacts/extraction/ArtifactExtraction.js +134 -92
  146. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +116 -50
  147. package/dist/artifacts/inventory/ArtifactInventory.js +5 -4
  148. package/dist/artifacts/inventory/classify.js +87 -25
  149. package/dist/artifacts/inventory/hashStableRootArtifact.js +70 -0
  150. package/dist/artifacts/inventory/reader.js +13 -5
  151. package/dist/artifacts/inventory/scanCanonical.js +73 -30
  152. package/dist/artifacts/inventory/scanReader.js +43 -20
  153. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +72 -28
  154. package/dist/artifacts/javascript/JavaScriptSourceAnalysis.js +3 -0
  155. package/dist/browser/BrowserScenarioPartialObservation.js +8 -2
  156. package/dist/browser/BrowserScenarioSecrets.js +52 -37
  157. package/dist/browser/CdpBrowserProvider.js +9 -3
  158. package/dist/browser/CdpCaptureDocuments.js +40 -6
  159. package/dist/browser/CdpCaptureDomSvg.js +210 -0
  160. package/dist/browser/CdpCaptureEventBodyShapes.js +4 -8
  161. package/dist/browser/CdpCaptureEventHandlers.js +26 -9
  162. package/dist/browser/CdpCaptureEvents.js +4 -9
  163. package/dist/browser/CdpCaptureStorageFingerprints.js +3 -3
  164. package/dist/browser/CdpConnection.js +22 -5
  165. package/dist/browser/CdpElectronInspection.js +2 -2
  166. package/dist/browser/CdpElectronProvider.js +4 -3
  167. package/dist/browser/CdpElectronScripts.js +2 -2
  168. package/dist/browser/CdpPageCapture.js +1 -1
  169. package/dist/browser/CdpTargetSession.js +30 -34
  170. package/dist/browser/CdpWebMcpDiscovery.js +48 -23
  171. package/dist/browser/ElectronFileScope.js +99 -9
  172. package/dist/browser/PlaywrightBrowserScenarioProvider.js +63 -7
  173. package/dist/browser/PlaywrightElectronActiveProvider.js +11 -6
  174. package/dist/browser/PlaywrightScenarioArtifacts.js +5 -5
  175. package/dist/browser/PlaywrightScenarioBrowser.js +208 -43
  176. package/dist/browser/PlaywrightScenarioSession.js +130 -65
  177. package/dist/browser/PlaywrightScenarioStorage.js +507 -0
  178. package/dist/browser/PngVisualDiff.js +198 -29
  179. package/dist/browser/WebSourceMapFetcher.js +35 -9
  180. package/dist/browser/assets/LocalWebScriptArtifacts.js +3 -1
  181. package/dist/browser/assets/PublishWebScripts.js +75 -20
  182. package/dist/browser/assets/ScenarioScriptCapture.js +8 -12
  183. package/dist/browser/assets/WebArtifactReads.js +23 -1
  184. package/dist/browser/assets/WebSourceLocationArtifacts.js +1 -0
  185. package/dist/browser/execution/CdpExecutionCapture.js +3 -3
  186. package/dist/browser/execution/CdpPreciseCoverage.js +5 -8
  187. package/dist/browser/history/HarCapture.js +14 -0
  188. package/dist/browser/history/HarCaptureProcess.js +2 -10
  189. package/dist/browser/history/MitmproxyCaptureAdapter.js +3 -1
  190. package/dist/browser/modules/WebModuleArtifacts.js +1 -0
  191. package/dist/cli/adbCommands.js +337 -0
  192. package/dist/cli/analysisViewCommands.js +39 -1
  193. package/dist/cli/apktoolCommands.js +53 -0
  194. package/dist/cli/artifactCommands.js +8 -11
  195. package/dist/cli/binaryDiagnosticsCommands.js +19 -1
  196. package/dist/cli/browserAdvancedCommands.js +65 -36
  197. package/dist/cli/coreAnalysisCommands.js +2 -2
  198. package/dist/cli/coreBinaryCommands.js +12 -13
  199. package/dist/cli/coreNativeCommands.js +1 -14
  200. package/dist/cli/electronCommands.js +14 -10
  201. package/dist/cli/evmCommands.js +13 -4
  202. package/dist/cli/firmwareCommands.js +7 -2
  203. package/dist/cli/javascriptApplicationAnalysis.js +19 -13
  204. package/dist/cli/javascriptRecoveryCommands.js +22 -15
  205. package/dist/cli/jebCommands.js +99 -0
  206. package/dist/cli/jsonOutput.js +12 -4
  207. package/dist/cli/referenceSourceImportStatus.js +7 -0
  208. package/dist/cli/setupCommands.js +15 -3
  209. package/dist/cli/streamedJsonOutput.js +83 -4
  210. package/dist/cli/utilityCommands.js +68 -22
  211. package/dist/cli/webScriptCommands.js +20 -1
  212. package/dist/cli/webSourceLocationCommands.js +21 -9
  213. package/dist/cli.js +11 -2
  214. package/dist/cliBrowserScenarioCommands.js +2 -1
  215. package/dist/cliCommandNames.js +32 -0
  216. package/dist/cliJsonInput.js +47 -34
  217. package/dist/cliObservationOptions.js +7 -0
  218. package/dist/composition/adb.js +3 -0
  219. package/dist/composition/apktool.js +3 -0
  220. package/dist/composition/auxiliaryAnalysisProviders.js +5 -4
  221. package/dist/composition/binaryDiagnostics.js +4 -0
  222. package/dist/composition/browserScenario.js +2 -2
  223. package/dist/composition/directAnalysis.js +14 -7
  224. package/dist/composition/javascriptAnalysisWorkerProcess.js +48 -0
  225. package/dist/composition/jeb.js +6 -0
  226. package/dist/config/environment.js +10 -0
  227. package/dist/config/ghidraLanguageOverride.js +9 -0
  228. package/dist/config/mcpInputSchemaProfile.js +27 -0
  229. package/dist/config/parseConfig.js +28 -1
  230. package/dist/contracts/adb/adbToolContracts.js +353 -0
  231. package/dist/contracts/advertisedInputExamples.js +48 -0
  232. package/dist/contracts/analysisDetail.js +10 -0
  233. package/dist/contracts/analysisViewToolContracts.js +17 -2
  234. package/dist/contracts/apktool/apktoolToolContracts.js +33 -0
  235. package/dist/contracts/artifactComparisonExample.js +5 -5
  236. package/dist/contracts/artifactToolContracts.js +8 -5
  237. package/dist/contracts/browserToolContracts.js +1 -1
  238. package/dist/contracts/compactInputSchema.js +256 -0
  239. package/dist/contracts/errorSchemas.js +3 -1
  240. package/dist/contracts/functionComparisonExample.js +8 -0
  241. package/dist/contracts/functionWorkflowToolContracts.js +1 -1
  242. package/dist/contracts/inputSchemaPresentation.js +104 -13
  243. package/dist/contracts/javascript/electronToolContracts.js +16 -3
  244. package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +3 -2
  245. package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +6 -3
  246. package/dist/contracts/javascript/javascriptRecoveryToolContracts.js +1 -1
  247. package/dist/contracts/javascript/javascriptRuntimeReconciliationExample.js +8 -7
  248. package/dist/contracts/jeb/jebToolContracts.js +64 -0
  249. package/dist/contracts/managed/managedToolContracts.js +3 -2
  250. package/dist/contracts/mobileApplicationGraphExamples.js +5 -5
  251. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +25 -3
  252. package/dist/contracts/native/nativeToolContracts.js +1 -1
  253. package/dist/contracts/officialToolContracts.js +5 -5
  254. package/dist/contracts/sessionLifecycleInputs.js +4 -3
  255. package/dist/contracts/sessionStatusContract.js +3 -2
  256. package/dist/contracts/sessionToolContracts.js +5 -4
  257. package/dist/contracts/sessionToolSchemas.js +9 -4
  258. package/dist/contracts/toolContractExamples.js +6 -0
  259. package/dist/contracts/toolContractTypes.js +3 -0
  260. package/dist/contracts/toolContracts.js +6 -0
  261. package/dist/contracts/toolEffects.js +167 -0
  262. package/dist/contracts/toolOutputSchemaGroups.js +7 -5
  263. package/dist/contracts/toolOutputSchemaPrimitives.js +2 -5
  264. package/dist/contracts/toolSchemaMetadata.js +82 -7
  265. package/dist/domain/adb/adbDeviceAnalysis.js +583 -0
  266. package/dist/domain/analysisErrorBase.js +5 -0
  267. package/dist/domain/analysisErrorCleanup.js +29 -0
  268. package/dist/domain/analysisErrorPresentation.js +18 -4
  269. package/dist/domain/analysisErrorProjection.js +4 -1
  270. package/dist/domain/analysisSnapshot.js +5 -2
  271. package/dist/domain/analysisView/analysisView.js +53 -5
  272. package/dist/domain/analysisView/binaryLayoutView.js +2 -0
  273. package/dist/domain/analysisView/javascriptApplicationView.js +2 -0
  274. package/dist/domain/analysisView/nativeFunctionView.js +155 -0
  275. package/dist/domain/android/androidApplication.js +25 -20
  276. package/dist/domain/android/androidPartialObservation.js +36 -0
  277. package/dist/domain/apktool/apktoolResourceAnalysis.js +77 -0
  278. package/dist/domain/apple/appleApplication.js +40 -23
  279. package/dist/domain/apple/appleBundleAnatomy.js +95 -28
  280. package/dist/domain/apple/dyldPaths.js +9 -1
  281. package/dist/domain/apple/dylibResolution.js +3 -3
  282. package/dist/domain/apple/interfaceBuilderGraph.js +22 -19
  283. package/dist/domain/apple/interfaceBuilderKeyedArchive.js +10 -1
  284. package/dist/domain/artifactComparison.js +39 -11
  285. package/dist/domain/artifactGraph.js +6 -4
  286. package/dist/domain/artifactIdentity.js +37 -9
  287. package/dist/domain/artifactInspection.js +10 -50
  288. package/dist/domain/artifactIntegrityPolicy.js +10 -0
  289. package/dist/domain/artifactInventoryEvidence.js +16 -17
  290. package/dist/domain/artifactPathSyntax.js +1 -1
  291. package/dist/domain/binaryTarget.js +16 -0
  292. package/dist/domain/binaryTargetTypes.js +8 -1
  293. package/dist/domain/browserCompleteness.js +3 -2
  294. package/dist/domain/browserObservationSchemas.js +8 -4
  295. package/dist/domain/browserScenarioCaptureValues.js +2 -2
  296. package/dist/domain/browserScenarioNormalization.js +3 -3
  297. package/dist/domain/browserScenarioValues.js +3 -2
  298. package/dist/domain/callPath.js +8 -10
  299. package/dist/domain/canonicalDigest.js +7 -1
  300. package/dist/domain/canonicalJsonDigestSteps.js +34 -12
  301. package/dist/domain/canonicalOrdering.js +1 -13
  302. package/dist/domain/changedBehavior.js +2 -3
  303. package/dist/domain/compactStringIdentity.js +9 -0
  304. package/dist/domain/comparisonSemantics.js +0 -5
  305. package/dist/domain/digests.js +0 -3
  306. package/dist/domain/evidence.js +12 -6
  307. package/dist/domain/evidenceBundle.js +51 -33
  308. package/dist/domain/evidenceRecordSummary.js +144 -0
  309. package/dist/domain/firmware/firmwareAnalysis.js +4 -3
  310. package/dist/domain/functionComparison.js +2 -1
  311. package/dist/domain/functionComparisonNormalization.js +4 -3
  312. package/dist/domain/functionComparisonResults.js +2 -2
  313. package/dist/domain/functionDossierEvidence.js +2 -1
  314. package/dist/domain/hopperValues.js +11 -15
  315. package/dist/domain/inputIssueProjection.js +16 -1
  316. package/dist/domain/javascript/electronActiveObservation.js +4 -3
  317. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +14 -15
  318. package/dist/domain/javascript/electronStaticAnalysisIpc.js +20 -21
  319. package/dist/domain/javascript/electronStaticAnalysisNative.js +73 -41
  320. package/dist/domain/javascript/electronStaticAnalysisValues.js +24 -4
  321. package/dist/domain/javascript/javascriptAnalysisResourceControls.js +45 -0
  322. package/dist/domain/javascript/javascriptApplicationAnalysis.js +6 -1
  323. package/dist/domain/javascript/javascriptApplicationChangeGraph.js +18 -14
  324. package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +4 -0
  325. package/dist/domain/javascript/javascriptApplicationGraph.js +91 -28
  326. package/dist/domain/javascript/javascriptApplicationProjectionResources.js +35 -0
  327. package/dist/domain/javascript/javascriptApplicationVersionComparison.js +4 -4
  328. package/dist/domain/javascript/javascriptApplicationVersionComparisonSchemas.js +37 -22
  329. package/dist/domain/javascript/javascriptApplicationVersionItems.js +72 -45
  330. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +16 -8
  331. package/dist/domain/javascript/javascriptAstFingerprint.js +60 -33
  332. package/dist/domain/javascript/javascriptAstValues.js +54 -0
  333. package/dist/domain/javascript/javascriptElectronMemberWrites.js +50 -0
  334. package/dist/domain/javascript/javascriptExportShapeComparison.js +3 -2
  335. package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +31 -23
  336. package/dist/domain/javascript/javascriptExportShapeSelection.js +2 -2
  337. package/dist/domain/javascript/javascriptExportShapeVariants.js +3 -2
  338. package/dist/domain/javascript/javascriptFeatureSeed.js +5 -3
  339. package/dist/domain/javascript/javascriptFeatureTrace.js +7 -6
  340. package/dist/domain/javascript/javascriptFeatureTraceSchemas.js +17 -9
  341. package/dist/domain/javascript/javascriptFeatureTraversal.js +4 -4
  342. package/dist/domain/javascript/javascriptModuleSemanticIr.js +15 -0
  343. package/dist/domain/javascript/javascriptNativeHandoff.js +12 -7
  344. package/dist/domain/javascript/javascriptRpcEndpoints.js +253 -0
  345. package/dist/domain/javascript/javascriptRuntimeLoadState.js +1 -3
  346. package/dist/domain/javascript/javascriptRuntimeObservation.js +8 -5
  347. package/dist/domain/javascript/javascriptRuntimeReconciliation.js +12 -6
  348. package/dist/domain/javascript/javascriptRuntimeReconciliationActive.js +9 -8
  349. package/dist/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js +212 -0
  350. package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +12 -6
  351. package/dist/domain/javascript/javascriptRuntimeReconciliationInputValidation.js +28 -0
  352. package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +5 -5
  353. package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +12 -223
  354. package/dist/domain/javascript/javascriptRuntimeReconciliationResult.js +2 -2
  355. package/dist/domain/javascript/javascriptRuntimeReconciliationRuntime.js +15 -4
  356. package/dist/domain/javascript/javascriptRuntimeReconciliationSchemas.js +2 -2
  357. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +15 -17
  358. package/dist/domain/javascript/javascriptSemanticAnalysis.js +379 -30
  359. package/dist/domain/javascript/javascriptSemanticCallResolution.js +9 -7
  360. package/dist/domain/javascript/javascriptSemanticCallableResults.js +42 -0
  361. package/dist/domain/javascript/javascriptSemanticCalls.js +8 -1
  362. package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -2
  363. package/dist/domain/javascript/javascriptSemanticCoverage.js +20 -0
  364. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +7 -9
  365. package/dist/domain/javascript/javascriptSemanticDataEffects.js +4 -11
  366. package/dist/domain/javascript/javascriptSemanticDerivedAnalysis.js +15 -4
  367. package/dist/domain/javascript/javascriptSemanticFileProjection.js +1 -0
  368. package/dist/domain/javascript/javascriptSemanticFingerprints.js +43 -42
  369. package/dist/domain/javascript/javascriptSemanticGraph.js +205 -52
  370. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +21 -11
  371. package/dist/domain/javascript/javascriptSemanticIr.js +0 -4
  372. package/dist/domain/javascript/javascriptSemanticIterationSources.js +139 -0
  373. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +774 -136
  374. package/dist/domain/javascript/javascriptSemanticMutationInitializers.js +190 -0
  375. package/dist/domain/javascript/javascriptSemanticMutationValues.js +98 -41
  376. package/dist/domain/javascript/javascriptSemanticObjectReferences.js +381 -0
  377. package/dist/domain/javascript/javascriptSemanticObjects.js +9 -7
  378. package/dist/domain/javascript/javascriptSemanticPrimitives.js +7 -2
  379. package/dist/domain/javascript/javascriptSemanticProjection.js +72 -28
  380. package/dist/domain/javascript/javascriptSemanticPromises.js +15 -21
  381. package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +100 -0
  382. package/dist/domain/javascript/javascriptSemanticProvenance.js +3 -3
  383. package/dist/domain/javascript/javascriptSemanticQuery.js +33 -29
  384. package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +4 -5
  385. package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -9
  386. package/dist/domain/javascript/javascriptSemanticRequireOrigin.js +16 -10
  387. package/dist/domain/javascript/javascriptSemanticReturnedReferences.js +219 -0
  388. package/dist/domain/javascript/javascriptSemanticReturns.js +34 -48
  389. package/dist/domain/javascript/javascriptSemanticState.js +22 -2
  390. package/dist/domain/javascript/javascriptSemanticTraversal.js +25 -2
  391. package/dist/domain/javascript/javascriptSemanticValues.js +169 -30
  392. package/dist/domain/javascript/javascriptSourceAnalysis.js +1 -0
  393. package/dist/domain/javascript/javascriptSourceMapPaths.js +11 -1
  394. package/dist/domain/javascript/javascriptSourceParser.js +34 -9
  395. package/dist/domain/javascript/javascriptStaticAnalysis.js +29 -17
  396. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +13 -12
  397. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +49 -5
  398. package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +8 -4
  399. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +26 -15
  400. package/dist/domain/javascript/javascriptStaticAnalysisState.js +1 -0
  401. package/dist/domain/javascript/sourceToBundleComparison.js +7 -5
  402. package/dist/domain/javascript/sourceToBundleSignals.js +7 -7
  403. package/dist/domain/jeb/jebAnalysis.js +114 -0
  404. package/dist/domain/jsonSerialization.js +109 -55
  405. package/dist/domain/jsonShape.js +69 -31
  406. package/dist/domain/jsonValue.js +3 -0
  407. package/dist/domain/localPath.js +10 -4
  408. package/dist/domain/managed/managedApplicationGraph.js +47 -6
  409. package/dist/domain/managed/managedApplicationGraphCoverage.js +8 -2
  410. package/dist/domain/managed/managedApplicationGraphNodes.js +94 -59
  411. package/dist/domain/managed/managedArtifact.js +1 -0
  412. package/dist/domain/managed/managedInspectionEvidence.js +13 -0
  413. package/dist/domain/managed/managedMemberComparisonMatch.js +6 -7
  414. package/dist/domain/native/nativeAotPe.js +1408 -0
  415. package/dist/domain/native/nativeCallObservation.js +2 -4
  416. package/dist/domain/native/nativeInstruction.js +21 -0
  417. package/dist/domain/native/nativeMetadataRecovery.js +79 -6
  418. package/dist/domain/native/nativeValueFlow.js +5 -11
  419. package/dist/domain/native/objcSwiftMetadata.js +15 -17
  420. package/dist/domain/native/peResources.js +94 -0
  421. package/dist/domain/nativeConvention.js +33 -0
  422. package/dist/domain/process/processCapture.js +102 -11
  423. package/dist/domain/process/processCaptureCoverage.js +8 -5
  424. package/dist/domain/process/processCaptureExample.js +67 -0
  425. package/dist/domain/process/processCaptureValidation.js +83 -3
  426. package/dist/domain/process/processComparison.js +0 -23
  427. package/dist/domain/process/processScenario.js +62 -10
  428. package/dist/domain/process/processTraceEvaluation.js +4 -4
  429. package/dist/domain/process/processTraceSpecification.js +1 -3
  430. package/dist/domain/propertyListKeys.js +3 -1
  431. package/dist/domain/providerCleanupError.js +6 -2
  432. package/dist/domain/reconstructionCoverage.js +2 -1
  433. package/dist/domain/reconstructionUnknowns.js +4 -3
  434. package/dist/domain/reconstructionVerification.js +3 -2
  435. package/dist/domain/referenceSourceGraph.js +32 -23
  436. package/dist/domain/referenceSourceImportParsing.js +40 -48
  437. package/dist/domain/referenceSourcePathIdentity.js +22 -0
  438. package/dist/domain/referenceSourceRequireBindings.js +137 -0
  439. package/dist/domain/residualUnknown.js +3 -2
  440. package/dist/domain/staticRuntimeCorrelation.js +2 -1
  441. package/dist/domain/swiftSymbolClassification.js +6 -1
  442. package/dist/domain/symbolAnalysis.js +17 -2
  443. package/dist/domain/unicodeCodePointOrder.js +6 -0
  444. package/dist/domain/webBundleAnalyzerInspection.js +23 -3
  445. package/dist/domain/webCaptureDiff.js +170 -30
  446. package/dist/domain/webCaptureDiffSchemas.js +2 -8
  447. package/dist/domain/webInventory.js +3 -2
  448. package/dist/domain/webMcpDiscovery.js +4 -3
  449. package/dist/domain/webScriptExport.js +1 -1
  450. package/dist/domain/webScriptExportError.js +10 -4
  451. package/dist/domain/webScriptExportPlan.js +7 -13
  452. package/dist/domain/zipPackageFormat.js +4 -1
  453. package/dist/domain/zodCollectionSteps.js +24 -0
  454. package/dist/dotnet/ManagedArtifactInspector.js +55 -43
  455. package/dist/dotnet/ManagedDecodeBudget.js +80 -0
  456. package/dist/dotnet/ManagedMemberInspector.js +13 -6
  457. package/dist/dotnet/ManagedMemberInspectorCore.js +2 -2
  458. package/dist/dotnet/ManagedMemberInstructionDecoder.js +5 -4
  459. package/dist/dotnet/ManagedMemberRows.js +9 -4
  460. package/dist/dotnet/ManagedMetadataHeaps.js +15 -5
  461. package/dist/dotnet/ManagedMetadataInventoryRows.js +20 -11
  462. package/dist/dotnet/ManagedMetadataLayout.js +10 -4
  463. package/dist/dotnet/ManagedMethodBodyReader.js +8 -3
  464. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +3 -2
  465. package/dist/dotnet/ManagedNativeBoundaryInspector.js +49 -34
  466. package/dist/dotnet/ManagedPeReader.js +41 -25
  467. package/dist/dotnet/ManagedReaderFailure.js +2 -1
  468. package/dist/dotnet/ManagedStaticProvider.js +65 -31
  469. package/dist/dotnet/ManagedStaticProviderMetadata.js +1 -4
  470. package/dist/evaluation/AgentEvaluationReport.js +9 -5
  471. package/dist/evaluation/CodexAgentEval.js +43 -13
  472. package/dist/evm/EvmoleFailures.js +0 -2
  473. package/dist/evm/EvmoleInterfaceProvider.js +67 -2
  474. package/dist/filesystem/OwnedDirectoryHandle.js +29 -0
  475. package/dist/filesystem/OwnedFileHandle.js +36 -0
  476. package/dist/filesystem/RegularFile.js +73 -0
  477. package/dist/filesystem/StableFileHash.js +46 -0
  478. package/dist/filesystem/readFileHandleChunks.js +26 -0
  479. package/dist/firmware/FirmwareCommand.js +25 -3
  480. package/dist/firmware/FirmwareFiles.js +23 -8
  481. package/dist/firmware/FirmwareProvider.js +156 -32
  482. package/dist/firmware/FirmwarePublication.js +24 -3
  483. package/dist/firmware/FirmwareRelease.js +1 -0
  484. package/dist/generatedPackageMetadata.js +2 -2
  485. package/dist/ghidra/GhidraAnalysisProfile.js +55 -4
  486. package/dist/ghidra/GhidraAnalysisSeeds.js +211 -0
  487. package/dist/ghidra/GhidraClient.js +90 -8
  488. package/dist/ghidra/GhidraDiagnostics.js +11 -8
  489. package/dist/ghidra/GhidraFunctionValues.js +26 -2
  490. package/dist/ghidra/GhidraInstallation.js +111 -10
  491. package/dist/ghidra/GhidraInventoryValues.js +23 -1
  492. package/dist/ghidra/GhidraLanguageCatalog.js +99 -0
  493. package/dist/ghidra/GhidraLauncher.js +123 -58
  494. package/dist/ghidra/GhidraLoadImageAttest.js +49 -2
  495. package/dist/ghidra/GhidraMipsProfile.js +79 -0
  496. package/dist/ghidra/GhidraProvider.js +57 -9
  497. package/dist/ghidra/GhidraProviderCapabilities.js +18 -8
  498. package/dist/ghidra/GhidraProviderClient.js +282 -21
  499. package/dist/ghidra/GhidraSessionValues.js +9 -2
  500. package/dist/hopper/HopperAnalysisProfile.js +2 -0
  501. package/dist/hopper/HopperCleanup.js +1 -1
  502. package/dist/hopper/HopperClient.js +15 -6
  503. package/dist/hopper/HopperMachOImage.js +2 -0
  504. package/dist/hopper/HopperProvider.js +13 -2
  505. package/dist/ida/IdaOperationRunner.js +10 -2
  506. package/dist/ida/IdaProvider.js +7 -0
  507. package/dist/ida/IdaSessionClient.js +7 -3
  508. package/dist/ida/IdaWorkspace.js +4 -2
  509. package/dist/inspector/JavaScriptRuntimeScope.js +9 -5
  510. package/dist/inspector/V8InspectorCaptureProjection.js +46 -13
  511. package/dist/inspector/V8InspectorProvider.js +60 -8
  512. package/dist/javascript/analysis/JavaScriptAnalysisTransfer.js +326 -0
  513. package/dist/javascript/analysis/JavaScriptAnalysisWorker.js +520 -0
  514. package/dist/javascript/analysis/JavaScriptAnalysisWorkerProtocol.js +63 -0
  515. package/dist/javascript/analysis/JavaScriptAnalysisWorkerSchemas.js +521 -0
  516. package/dist/javascript/analysis/JavaScriptAnalysisWorkerServer.js +116 -0
  517. package/dist/javascript/recovery/RecoveryFiles.js +18 -7
  518. package/dist/javascript/recovery/WakaruCommand.js +22 -9
  519. package/dist/javascript/recovery/WakaruExecution.js +11 -7
  520. package/dist/javascript/recovery/WakaruProvider.js +139 -16
  521. package/dist/javascript/recovery/WakaruPublication.js +14 -4
  522. package/dist/javascript/recovery/WakaruRelease.js +10 -3
  523. package/dist/javascript/recovery/WakaruReport.js +12 -7
  524. package/dist/javascript/recovery/WakaruVersion.js +24 -0
  525. package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -3
  526. package/dist/javascript/sourceMaps/SourceMapDecoder.js +63 -7
  527. package/dist/javascript/sourceMaps/SourceMapFormat.js +15 -4
  528. package/dist/jeb/JebMcpConnection.js +179 -0
  529. package/dist/jeb/JebMcpEndpoint.js +40 -0
  530. package/dist/jeb/JebProvider.js +299 -0
  531. package/dist/main/shutdown.js +76 -32
  532. package/dist/main/transport.js +1 -1
  533. package/dist/mcpDoctor.js +15 -6
  534. package/dist/native/AppleDispatchCoverage.js +25 -12
  535. package/dist/native/AppleDispatchMetadata.js +14 -7
  536. package/dist/native/AppleMachoFixups.js +71 -15
  537. package/dist/native/AppleMachoSelection.js +23 -3
  538. package/dist/native/AppleObjcDispatchFacets.js +3 -3
  539. package/dist/native/AppleObjcProperties.js +17 -7
  540. package/dist/native/LldbCallTracer.js +241 -75
  541. package/dist/native/NativeMacOSProvider.js +100 -20
  542. package/dist/native/NativeMacOSProviderMetadata.js +1 -2
  543. package/dist/native/NativeMachoInspection.js +11 -7
  544. package/dist/native/NativeUiHelperRuntime.js +6 -1
  545. package/dist/native/NativeUiObservation.js +4 -3
  546. package/dist/native/pe/PeResourceLayout.js +120 -0
  547. package/dist/native/pe/PeResourceParser.js +286 -0
  548. package/dist/native/pe/PeResourcesProvider.js +63 -0
  549. package/dist/process/BoundedFileBytes.js +30 -7
  550. package/dist/process/DarwinProcessRunTokenReader.js +8 -3
  551. package/dist/process/OwnedCommand.js +4 -3
  552. package/dist/process/ProcessOwnership.js +104 -112
  553. package/dist/process/ProcessOwnershipObservation.js +104 -51
  554. package/dist/process/ProcessOwnershipProcessTree.js +4 -4
  555. package/dist/process/ProcessRunTokenObservations.js +48 -0
  556. package/dist/process/ProviderDiagnosticRedaction.js +17 -0
  557. package/dist/process/ProviderProcess.js +4 -3
  558. package/dist/process/capture/FilesystemSnapshot.js +116 -22
  559. package/dist/process/capture/ProcessCaptureLifecycle.js +363 -86
  560. package/dist/process/capture/ProcessCaptureProgress.js +62 -0
  561. package/dist/process/capture/ProcessFilesystemEffects.js +19 -4
  562. package/dist/process/capture/ProcessHarness.js +202 -47
  563. package/dist/process/capture/ProcessNormalization.js +3 -1
  564. package/dist/process/capture/ProcessScenarioRuntimeValidation.js +5 -2
  565. package/dist/process/capture/TerminalRenderer.js +24 -7
  566. package/dist/reference/ReferenceSourceReader.js +22 -5
  567. package/dist/reference/ReferenceSourceReaderEntries.js +114 -51
  568. package/dist/reference/ReferenceSourceReaderErrors.js +12 -0
  569. package/dist/reference/ReferenceSourceReaderFile.js +50 -10
  570. package/dist/reference/ReferenceSourceReaderValidate.js +4 -4
  571. package/dist/server/EvidenceMcpServer.js +36 -1
  572. package/dist/server/admittedToolOperation.js +9 -0
  573. package/dist/server/analysisAdmission.js +8 -0
  574. package/dist/server/contractToolHandler.js +21 -0
  575. package/dist/server/createServer.js +118 -47
  576. package/dist/server/registerAdbTools.js +36 -0
  577. package/dist/server/registerAnalysisViewTool.js +4 -9
  578. package/dist/server/registerAndroidTools.js +3 -12
  579. package/dist/server/registerApktoolTools.js +14 -0
  580. package/dist/server/registerApplicationTools/compareExportShapes.js +6 -7
  581. package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
  582. package/dist/server/registerApplicationTools/compareVersions.js +3 -2
  583. package/dist/server/registerApplicationTools/coverage.js +3 -2
  584. package/dist/server/registerApplicationTools/helpers.js +3 -2
  585. package/dist/server/registerApplicationTools/obligationLedger.js +3 -2
  586. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -2
  587. package/dist/server/registerApplicationTools/traceFeature.js +3 -2
  588. package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
  589. package/dist/server/registerArtifactComparisonTool.js +5 -2
  590. package/dist/server/registerArtifactTools.js +2 -2
  591. package/dist/server/registerBinaryDiagnosticsTools.js +16 -4
  592. package/dist/server/registerBrowserScenarioTool.js +10 -7
  593. package/dist/server/registerBrowserTools.js +12 -9
  594. package/dist/server/registerBundleComparisonTool.js +16 -2
  595. package/dist/server/registerCloseLifecycleTool.js +36 -5
  596. package/dist/server/registerElectronTools.js +28 -10
  597. package/dist/server/registerEnhancedTools.js +78 -73
  598. package/dist/server/registerEvidenceTools.js +54 -46
  599. package/dist/server/registerEvmTools.js +4 -9
  600. package/dist/server/registerFirmwareTools.js +3 -11
  601. package/dist/server/registerFunctionComparisonTool.js +5 -2
  602. package/dist/server/registerJavaScriptRecoveryTool.js +4 -9
  603. package/dist/server/registerJavaScriptRuntimeObservationTools.js +9 -6
  604. package/dist/server/registerJebTools.js +16 -0
  605. package/dist/server/registerManagedTools.js +7 -4
  606. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -6
  607. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -2
  608. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +3 -2
  609. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +3 -2
  610. package/dist/server/registerOfficialTools.js +31 -25
  611. package/dist/server/registerPeResourcesTool.js +9 -0
  612. package/dist/server/registerProcessComparisonTool.js +5 -2
  613. package/dist/server/registerRecordedCrashTools.js +4 -9
  614. package/dist/server/registerSessionRecordTools.js +2 -1
  615. package/dist/server/registerSessionTools.js +58 -21
  616. package/dist/server/registerWebModuleTool.js +4 -9
  617. package/dist/server/registerWebNetworkCaptureTool.js +4 -9
  618. package/dist/server/registerWebRuntimeTools.js +6 -5
  619. package/dist/server/registerWebScriptTool.js +6 -3
  620. package/dist/server/registerWebSourceLocationTool.js +4 -9
  621. package/dist/server/toolResult.js +21 -2
  622. package/dist/windows/WindowsPrivateRuntime.js +12 -5
  623. package/install.sh +7 -4
  624. package/licenses/nativeaot-parser-MIT.txt +28 -0
  625. package/native/windows/build/manifest.json +2 -2
  626. package/native/windows/build/rea-windows-x64.node +0 -0
  627. package/package.json +38 -7
  628. package/scripts/rea.mjs +16 -1
  629. package/skills/reverse-engineer-anything/SKILL.md +52 -51
  630. package/skills/reverse-engineer-anything/references/connection-and-recovery.md +127 -0
  631. package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -0
  632. package/skills/reverse-engineer-anything/references/javascript-applications.md +92 -13
  633. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +31 -1
  634. package/dist/artifacts/inventory/policy.js +0 -2
  635. package/dist/domain/managed/managedApplicationGraphNodeCoverage.js +0 -6
  636. package/dist/server/registerNativeTools.js +0 -6
@@ -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
@@ -1,14 +1,15 @@
1
- import { execFile } from "node:child_process";
2
- import { lstat, readdir, readFile, realpath, stat } from "node:fs/promises";
1
+ import { lstat, opendir, readFile, realpath, stat } from "node:fs/promises";
3
2
  import { join } from "node:path";
4
- import { promisify } from "node:util";
3
+ import { parseBinary } from "plist";
5
4
  import { z } from "zod";
5
+ import { preflightPropertyListDecode } from "../artifacts/apple/InterfaceBuilderDecodeBudget.js";
6
6
  import { BinaryTargetError } from "../domain/configurationErrors.js";
7
7
  import { isPathWithinRoot } from "../domain/localPath.js";
8
- import { parseXmlPropertyList } from "../domain/propertyListKeys.js";
8
+ import { omitPrototypeKeys, parseXmlPropertyList, } from "../domain/propertyListKeys.js";
9
9
  import { decodeXmlPlistText } from "../domain/propertyListXmlText.js";
10
10
  import { err, ok } from "../domain/result.js";
11
- const execFileAsync = promisify(execFile);
11
+ /** Decoded representation bound for one binary Info.plist. */
12
+ const BINARY_PLIST_DECODE_BYTES = 16 * 1024 * 1024;
12
13
  const BUNDLE_LAYOUTS = [
13
14
  // macOS bundles keep both under Contents.
14
15
  {
@@ -105,11 +106,15 @@ const wrappedBundle = async (bundle) => {
105
106
  return undefined;
106
107
  throw cause;
107
108
  }
108
- const apps = (await readdir(wrapper, { withFileTypes: true })).filter((entry) => entry.isDirectory() && entry.name.toLowerCase().endsWith(".app"));
109
- const [app] = apps;
110
- return apps.length === 1 && app !== undefined
111
- ? join(wrapper, app.name)
112
- : undefined;
109
+ let app;
110
+ for await (const entry of await opendir(wrapper)) {
111
+ if (!entry.isDirectory() || !entry.name.toLowerCase().endsWith(".app"))
112
+ continue;
113
+ if (app !== undefined)
114
+ return undefined;
115
+ app = join(wrapper, entry.name);
116
+ }
117
+ return app;
113
118
  };
114
119
  const resolveLayoutExecutable = async (bundle, layout, fileSystem) => {
115
120
  const plistPath = join(bundle, ...layout.plist);
@@ -128,7 +133,8 @@ const resolveLayoutExecutable = async (bundle, layout, fileSystem) => {
128
133
  try {
129
134
  name =
130
135
  plist.subarray(0, 6).toString("ascii") === "bplist"
131
- ? await (fileSystem.decodeBinaryPlist ?? readBinaryPlistExecutable)(plistPath)
136
+ ? await (fileSystem.decodeBinaryPlist?.(plistPath) ??
137
+ parseBinaryPlistExecutable(plist))
132
138
  : parseXmlPlistExecutable(decodeXmlPlistText(plist));
133
139
  }
134
140
  catch (cause) {
@@ -163,23 +169,22 @@ const resolveLayoutExecutable = async (bundle, layout, fileSystem) => {
163
169
  const parseXmlPlistExecutable = (plist) => {
164
170
  // An unrelated `__proto__` entry must not make the bundle unreadable.
165
171
  const { value } = parseXmlPropertyList(plist);
172
+ return executableName(value);
173
+ };
174
+ const executableName = (value) => {
166
175
  const executable = executableEntrySchema.safeParse(value);
167
176
  if (!executable.success)
168
177
  throw new Error("CFBundleExecutable is missing");
169
178
  return executable.data.CFBundleExecutable;
170
179
  };
171
180
  const executableEntrySchema = z.looseObject({ CFBundleExecutable: z.string() });
172
- const readBinaryPlistExecutable = async (plistPath) =>
173
- // `-n` strips only the newline plutil appends; it requires macOS 12+.
174
- (await execFileAsync("/usr/bin/plutil", [
175
- "-extract",
176
- "CFBundleExecutable",
177
- "raw",
178
- "-n",
179
- "-o",
180
- "-",
181
- plistPath,
182
- ])).stdout;
181
+ /** Decode a binary plist in-process, so no host plist tool is required. */
182
+ const parseBinaryPlistExecutable = (plist) => {
183
+ preflightPropertyListDecode(plist, BINARY_PLIST_DECODE_BYTES);
184
+ // `plist` assigns a `__proto__` key as the prototype; copying drops it, as
185
+ // the XML path does.
186
+ return executableName(omitPrototypeKeys(parseBinary(plist)).value);
187
+ };
183
188
  const isSafeExecutableName = (name) => name.length > 0 &&
184
189
  name !== "." &&
185
190
  name !== ".." &&