rea-agents 4.0.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (416) hide show
  1. package/README.md +93 -30
  2. package/bridge/ghidra/ReaGhidraBridge.java +358 -15
  3. package/bridge/ghidra/ReaGhidraExtensions.java +113 -0
  4. package/bridge/ghidra/ReaGhidraPrepareCom.java +32 -0
  5. package/dist/android/AndroidTargetSnapshot.js +34 -0
  6. package/dist/android/JadxAnalysis.js +191 -0
  7. package/dist/android/JadxConfiguration.js +41 -0
  8. package/dist/android/JadxMcpTransport.js +145 -0
  9. package/dist/android/JadxProtocol.js +101 -0
  10. package/dist/android/JadxProvider.js +170 -0
  11. package/dist/android/JadxRelease.js +19 -0
  12. package/dist/android/JadxSession.js +97 -0
  13. package/dist/application/AnalysisContextQueries.js +2 -1
  14. package/dist/application/AnalysisProviderEvaluation.js +5 -3
  15. package/dist/application/AnalysisProviderRegistry.js +2 -1
  16. package/dist/application/AnalysisSnapshotCache.js +4 -1
  17. package/dist/application/AnalysisSnapshotFiles.js +1 -1
  18. package/dist/application/AndroidAnalysisPort.js +1 -0
  19. package/dist/application/AndroidAnalysisService.js +37 -0
  20. package/dist/application/ArtifactExtraction.js +7 -4
  21. package/dist/application/ArtifactGraphConstruction.js +10 -17
  22. package/dist/application/ArtifactInventory/scanCanonical.js +8 -7
  23. package/dist/application/BinarySession.js +16 -3
  24. package/dist/application/BinarySessionExecution.js +4 -1
  25. package/dist/application/BinarySessionOpen.js +3 -2
  26. package/dist/application/BinarySessionRecords.js +9 -3
  27. package/dist/application/BinaryTargetResolver.js +25 -6
  28. package/dist/application/BrowserObservationService.js +2 -1
  29. package/dist/application/BrowserScenarioCaptureService.js +2 -1
  30. package/dist/application/BrowserScenarioEvidence.js +2 -2
  31. package/dist/application/CallPathTracing.js +2 -1
  32. package/dist/application/CapabilityInventory.js +18 -0
  33. package/dist/application/ClientConfigPath.js +3 -1
  34. package/dist/application/ClientConfigurationDocument.js +11 -1
  35. package/dist/application/ClientRegistrationStatus.js +8 -1
  36. package/dist/application/CompositeProvider.js +1 -1
  37. package/dist/application/DirectAnalysis.js +23 -7
  38. package/dist/application/DirectAnalysisStatus.js +3 -3
  39. package/dist/application/Doctor.js +48 -8
  40. package/dist/application/DoctorDiagnostics.js +7 -5
  41. package/dist/application/DoctorScope.js +1 -1
  42. package/dist/application/ElectronActiveEvidence.js +2 -2
  43. package/dist/application/ElectronActiveObservationService.js +2 -1
  44. package/dist/application/ElectronBoundaryAnalysis.js +1 -1
  45. package/dist/application/ElectronObservationService.js +2 -1
  46. package/dist/application/EnhancedLiteralTracing.js +2 -1
  47. package/dist/application/EnhancedToolTypes.js +2 -1
  48. package/dist/application/EnhancedTools.js +3 -1
  49. package/dist/application/EvidenceBundleCommands.js +2 -1
  50. package/dist/application/EvidenceBundleFiles.js +1 -1
  51. package/dist/application/EvidenceInputResolver.js +30 -0
  52. package/dist/application/EvidenceLedger.js +2 -1
  53. package/dist/application/FirmwareAnalysisPort.js +1 -0
  54. package/dist/application/FirmwareAnalysisService.js +35 -0
  55. package/dist/application/FunctionAnalysisEvidence.js +32 -0
  56. package/dist/application/InventoryProjectionEvidence.js +2 -1
  57. package/dist/application/JavaScriptApplicationService.js +50 -3
  58. package/dist/application/JavaScriptApplicationWorkflowService.js +2 -1
  59. package/dist/application/JavaScriptArtifactAnalysis.js +4 -2
  60. package/dist/application/JavaScriptArtifactFiles.js +4 -2
  61. package/dist/application/JavaScriptArtifactPathResolution.js +6 -2
  62. package/dist/application/JavaScriptJsonModules.js +3 -2
  63. package/dist/application/JavaScriptModuleRelationships.js +4 -2
  64. package/dist/application/JavaScriptRuntimeObservationService.js +2 -1
  65. package/dist/application/JavaScriptRuntimeReconciliationService.js +2 -1
  66. package/dist/application/JavaScriptSemanticGraphProjection.js +1 -1
  67. package/dist/application/JavaScriptSemanticTraceService.js +2 -1
  68. package/dist/application/JsonFiles.js +1 -1
  69. package/dist/application/LazyAnalysisProvider.js +3 -1
  70. package/dist/application/LinuxHopper.js +12 -4
  71. package/dist/application/MacHopper.js +20 -7
  72. package/dist/application/ManagedApplicationGraphService.js +2 -1
  73. package/dist/application/ManagedMemberComparisonService.js +3 -1
  74. package/dist/application/ManagedNativeVerificationService.js +2 -1
  75. package/dist/application/ManagedReconstructionService.js +2 -1
  76. package/dist/application/NativeCallRoutes.js +1 -1
  77. package/dist/application/NativeDispatchMetadataInspection.js +1 -1
  78. package/dist/application/NativeUiActionTrace.js +2 -1
  79. package/dist/application/NativeValueTrace.js +1 -1
  80. package/dist/application/ProcessCaptureError.js +1 -1
  81. package/dist/application/ProcessCaptureJournal.js +3 -1
  82. package/dist/application/ProcessCaptureLifecycle.js +6 -3
  83. package/dist/application/ProcessCli.js +9 -5
  84. package/dist/application/ProcessEvidence.js +2 -6
  85. package/dist/application/ProcessHarness.js +3 -2
  86. package/dist/application/ProcessNormalization.js +12 -5
  87. package/dist/application/ProcessSampling.js +3 -1
  88. package/dist/application/ReconstructionCoverageService.js +2 -1
  89. package/dist/application/ReconstructionObligationLedgerService.js +2 -1
  90. package/dist/application/ReferenceSourceImportEntries.js +2 -0
  91. package/dist/application/ReferenceSourceImportPolicy.js +4 -2
  92. package/dist/application/ReferenceSourceVcsAdapter.js +35 -4
  93. package/dist/application/SessionProviderRouter.js +4 -1
  94. package/dist/application/Setup.js +1 -128
  95. package/dist/application/SetupClientConfiguration.js +17 -6
  96. package/dist/application/SetupHost.js +111 -0
  97. package/dist/application/SetupRegistrationEnvironment.js +1 -2
  98. package/dist/application/SetupSkill.js +9 -3
  99. package/dist/application/SetupTypes.js +17 -0
  100. package/dist/application/StoreFileLock.js +7 -2
  101. package/dist/application/SupportedClients.js +8 -0
  102. package/dist/application/Uninstall.js +9 -4
  103. package/dist/application/UpdateRuntime.js +5 -2
  104. package/dist/application/WindowsCapabilities.js +7 -7
  105. package/dist/application/runtime.js +3 -1
  106. package/dist/artifacts/ArtifactProvider.js +3 -1
  107. package/dist/artifacts/DirectoryArtifactReader.js +2 -0
  108. package/dist/artifacts/NativeDmgArtifactReader.js +10 -3
  109. package/dist/artifacts/NibArchive.js +4 -2
  110. package/dist/artifacts/SafeOutputTree.js +26 -10
  111. package/dist/artifacts/ZipArtifactReader.js +1 -0
  112. package/dist/browser/BrowserProcessStartup.js +3 -1
  113. package/dist/browser/CdpAuthorizedMainFrame.js +1 -1
  114. package/dist/browser/CdpBrowserProvider.js +4 -1
  115. package/dist/browser/CdpCaptureDocuments.js +3 -1
  116. package/dist/browser/CdpCaptureEventHandlers.js +6 -2
  117. package/dist/browser/CdpCaptureStorageFingerprints.js +1 -1
  118. package/dist/browser/CdpCaptureValues.js +6 -2
  119. package/dist/browser/CdpConnection.js +8 -6
  120. package/dist/browser/CdpElectronInspection.js +3 -3
  121. package/dist/browser/CdpElectronProvider.js +4 -1
  122. package/dist/browser/CdpElectronScripts.js +2 -2
  123. package/dist/browser/CdpEndpoint.js +22 -10
  124. package/dist/browser/CdpObservationSession.js +2 -1
  125. package/dist/browser/CdpOptionalCommand.js +1 -1
  126. package/dist/browser/CdpPageCapture.js +2 -1
  127. package/dist/browser/CdpSafeMetadata.js +53 -8
  128. package/dist/browser/CdpScreenshot.js +1 -1
  129. package/dist/browser/CdpTargetSession.js +8 -5
  130. package/dist/browser/CdpWebMcpDiscovery.js +1 -1
  131. package/dist/browser/ElectronFileScope.js +9 -3
  132. package/dist/browser/JavaScriptRuntimeScope.js +3 -1
  133. package/dist/browser/PlaywrightBrowserScenarioProvider.js +3 -1
  134. package/dist/browser/PlaywrightElectronActiveActions.js +1 -1
  135. package/dist/browser/PlaywrightElectronActiveProvider.js +6 -2
  136. package/dist/browser/PlaywrightExecutionBoundary.js +1 -1
  137. package/dist/browser/PlaywrightScenarioArtifacts.js +10 -5
  138. package/dist/browser/PlaywrightScenarioBrowser.js +3 -1
  139. package/dist/browser/PlaywrightScenarioEvents.js +6 -2
  140. package/dist/browser/PlaywrightScenarioSession.js +5 -2
  141. package/dist/browser/V8InspectorEndpoint.js +2 -1
  142. package/dist/browser/V8InspectorProvider.js +6 -1
  143. package/dist/browser/WebSourceMapFetcher.js +24 -11
  144. package/dist/cli/androidCommands.js +81 -0
  145. package/dist/{cliApplicationCommands.js → cli/applicationCommands.js} +18 -16
  146. package/dist/{cliBrowserAdvancedCommands.js → cli/browserAdvancedCommands.js} +13 -16
  147. package/dist/{cliBrowserCommands.js → cli/browserCommands.js} +9 -9
  148. package/dist/cli/commandCancellation.js +24 -0
  149. package/dist/cli/coreAnalysisCommands.js +110 -17
  150. package/dist/{cliElectronCommands.js → cli/electronCommands.js} +14 -13
  151. package/dist/cli/firmwareCommands.js +75 -0
  152. package/dist/{cliSetup.js → cli/interactiveSetup.js} +1 -1
  153. package/dist/cli/javascriptApplicationAnalysis.js +1 -1
  154. package/dist/cli/managedCommands.js +1 -1
  155. package/dist/cli/managedProjectGraphCommand.js +1 -1
  156. package/dist/cli/options.js +7 -1
  157. package/dist/{cliProcessCommands.js → cli/processCommands.js} +3 -3
  158. package/dist/cli/referenceSourceImportStatus.js +10 -0
  159. package/dist/cli/setupCommands.js +4 -2
  160. package/dist/cli/utilityCommands.js +3 -2
  161. package/dist/cli.js +10 -15
  162. package/dist/cliBrowserContext.js +1 -1
  163. package/dist/cliBrowserScenarioCommands.js +2 -1
  164. package/dist/cliCommandNames.js +11 -2
  165. package/dist/cliEvidenceCommands.js +2 -1
  166. package/dist/cliJavaScriptRuntimeCommands.js +2 -1
  167. package/dist/cliJsonInput.js +26 -11
  168. package/dist/cliLogging.js +2 -1
  169. package/dist/cliOutput.js +15 -16
  170. package/dist/config/environment.js +11 -1
  171. package/dist/config/parseConfig.js +7 -1
  172. package/dist/config/parsers.js +1 -1
  173. package/dist/contracts/androidToolContracts.js +77 -0
  174. package/dist/contracts/applicationToolContracts.js +32 -5
  175. package/dist/contracts/applicationWorkflowInputContracts.js +13 -13
  176. package/dist/contracts/artifactComparisonExample.js +7 -14
  177. package/dist/contracts/enhancedToolContracts.js +31 -0
  178. package/dist/contracts/errorSchemas.js +4 -2
  179. package/dist/contracts/evidenceInputContracts.js +13 -0
  180. package/dist/contracts/firmwareToolContracts.js +38 -0
  181. package/dist/contracts/officialToolContracts.js +66 -0
  182. package/dist/contracts/promptContracts.js +1 -1
  183. package/dist/contracts/sessionLifecycleInputs.js +4 -0
  184. package/dist/contracts/sessionToolContracts.js +43 -0
  185. package/dist/contracts/sessionToolSchemas.js +1 -1
  186. package/dist/contracts/toolContractExamples.js +5 -0
  187. package/dist/contracts/toolContractTypes.js +2 -0
  188. package/dist/contracts/toolContracts.js +7 -130
  189. package/dist/contracts/toolEffects.js +43 -0
  190. package/dist/contracts/toolOutputSchemaGroups.js +4 -0
  191. package/dist/contracts/toolOutputSchemaPrimitives.js +1 -0
  192. package/dist/doctorRuntime.js +5 -1
  193. package/dist/domain/analysisErrorBase.js +33 -0
  194. package/dist/domain/analysisErrorCore.js +60 -0
  195. package/dist/domain/analysisErrorPresentation.js +22 -2
  196. package/dist/domain/analysisErrorProjection.js +24 -3
  197. package/dist/domain/analysisSnapshot.js +1 -0
  198. package/dist/domain/androidAnalysis.js +141 -0
  199. package/dist/domain/appleAssetCatalog.js +1 -1
  200. package/dist/domain/artifactGraph.js +1 -0
  201. package/dist/domain/artifactInspection.js +19 -17
  202. package/dist/domain/artifactInventoryEvidence.js +20 -25
  203. package/dist/domain/artifactOperationError.js +16 -0
  204. package/dist/domain/browserObservation.js +12 -4
  205. package/dist/domain/browserObservationError.js +23 -0
  206. package/dist/domain/browserScenario.js +1 -1
  207. package/dist/domain/browserScenarioCapture.js +1 -1
  208. package/dist/domain/browserScenarioDiff.js +1 -1
  209. package/dist/domain/browserScenarioNormalization.js +6 -11
  210. package/dist/domain/browserScenarioValues.js +3 -1
  211. package/dist/domain/callPath.js +47 -7
  212. package/dist/domain/canonicalDigest.js +65 -0
  213. package/dist/domain/canonicalOrdering.js +11 -0
  214. package/dist/domain/changedBehavior.js +8 -7
  215. package/dist/domain/comparisonSemantics.js +2 -4
  216. package/dist/domain/configurationErrors.js +25 -0
  217. package/dist/domain/dosCom.js +8 -0
  218. package/dist/domain/electronActiveObservation.js +3 -1
  219. package/dist/domain/electronStaticAnalysisBrowser.js +13 -23
  220. package/dist/domain/electronStaticAnalysisNative.js +2 -1
  221. package/dist/domain/electronStaticAnalysisValues.js +23 -3
  222. package/dist/domain/evidence.js +3 -11
  223. package/dist/domain/evidenceErrors.js +30 -0
  224. package/dist/domain/firmwareAnalysis.js +121 -0
  225. package/dist/domain/functionComparison.js +4 -2
  226. package/dist/domain/functionComparisonDimensions.js +6 -4
  227. package/dist/domain/functionComparisonNormalization.js +8 -1
  228. package/dist/domain/functionComparisonResults.js +1 -4
  229. package/dist/domain/hopperErrors.js +78 -0
  230. package/dist/domain/hopperValues.js +2 -1
  231. package/dist/domain/interfaceBuilderGraph.js +3 -1
  232. package/dist/domain/javascriptApplicationChangeGraph.js +2 -2
  233. package/dist/domain/javascriptApplicationGraph.js +13 -22
  234. package/dist/domain/javascriptApplicationVersionComparison.js +3 -11
  235. package/dist/domain/javascriptApplicationVersionItems.js +3 -3
  236. package/dist/domain/javascriptApplicationVersionKeys.js +1 -1
  237. package/dist/domain/javascriptAstFingerprint.js +1 -1
  238. package/dist/domain/javascriptExportShapeComparison.js +1 -2
  239. package/dist/domain/javascriptExportShapeSelection.js +1 -1
  240. package/dist/domain/javascriptExportShapeVariants.js +7 -3
  241. package/dist/domain/javascriptFeatureSeed.js +29 -9
  242. package/dist/domain/javascriptFeatureTrace.js +9 -13
  243. package/dist/domain/javascriptFeatureTraversal.js +2 -1
  244. package/dist/domain/javascriptNativeHandoff.js +2 -1
  245. package/dist/domain/javascriptRuntimeLoadState.js +2 -2
  246. package/dist/domain/javascriptRuntimeReconciliationActive.js +3 -10
  247. package/dist/domain/javascriptRuntimeReconciliationGraph.js +2 -2
  248. package/dist/domain/javascriptRuntimeReconciliationMatching.js +4 -3
  249. package/dist/domain/javascriptRuntimeReconciliationParsing.js +8 -14
  250. package/dist/domain/javascriptRuntimeReconciliationResult.js +4 -4
  251. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +5 -2
  252. package/dist/domain/javascriptRuntimeStaticCandidates.js +8 -4
  253. package/dist/domain/javascriptSemanticAnalysis.js +40 -3
  254. package/dist/domain/javascriptSemanticCallResolution.js +2 -1
  255. package/dist/domain/javascriptSemanticChildProcesses.js +2 -1
  256. package/dist/domain/javascriptSemanticDataEffects.js +2 -1
  257. package/dist/domain/javascriptSemanticFingerprints.js +1 -1
  258. package/dist/domain/javascriptSemanticGraph.js +23 -28
  259. package/dist/domain/javascriptSemanticPrimitives.js +9 -2
  260. package/dist/domain/javascriptSemanticProjection.js +2 -1
  261. package/dist/domain/javascriptSemanticPromises.js +2 -1
  262. package/dist/domain/javascriptSemanticProvenance.js +1 -1
  263. package/dist/domain/javascriptSemanticQuery.js +7 -8
  264. package/dist/domain/javascriptSemanticQueryAssessment.js +1 -2
  265. package/dist/domain/javascriptSemanticQueryIdentity.js +1 -2
  266. package/dist/domain/javascriptSemanticReturns.js +2 -1
  267. package/dist/domain/javascriptSemanticValues.js +50 -16
  268. package/dist/domain/javascriptSourceParser.js +4 -2
  269. package/dist/domain/javascriptStaticAnalysis.js +1 -1
  270. package/dist/domain/javascriptStaticAnalysisBundler.js +2 -1
  271. package/dist/domain/javascriptStaticAnalysisCalls.js +14 -6
  272. package/dist/domain/javascriptStaticAnalysisHelpers.js +31 -4
  273. package/dist/domain/jsonShape.js +6 -2
  274. package/dist/domain/managedMemberComparison.js +1 -0
  275. package/dist/domain/managedMemberComparisonItems.js +2 -0
  276. package/dist/domain/managedNativeVerificationMatch.js +5 -3
  277. package/dist/domain/nativeDataType.js +2 -0
  278. package/dist/domain/nativeFunctionAnnotations.js +43 -0
  279. package/dist/domain/nativeLoadImage.js +95 -0
  280. package/dist/domain/nativeMetadataRecovery.js +55 -0
  281. package/dist/domain/processCapture.js +0 -1
  282. package/dist/domain/processEvidenceProvider.js +11 -0
  283. package/dist/domain/processTraceComparison.js +1 -1
  284. package/dist/domain/providerAdapterError.js +17 -0
  285. package/dist/domain/providerCleanupError.js +1 -1
  286. package/dist/domain/providerSelectionError.js +44 -0
  287. package/dist/domain/reconstructionUnknowns.js +1 -1
  288. package/dist/domain/reconstructionVerification.js +22 -8
  289. package/dist/domain/referenceSourceClassification.js +5 -6
  290. package/dist/domain/referenceSourceGraph.js +9 -17
  291. package/dist/domain/referenceSourceImportParsing.js +38 -23
  292. package/dist/domain/runtimeIdentification.js +1 -1
  293. package/dist/domain/runtimeVersion.js +4 -7
  294. package/dist/domain/safeJson.js +13 -0
  295. package/dist/domain/sourceToBundleComparison.js +5 -7
  296. package/dist/domain/sourceToBundleSignals.js +6 -6
  297. package/dist/domain/staticRuntimeCorrelation.js +9 -7
  298. package/dist/domain/unknownRegistryError.js +10 -0
  299. package/dist/domain/webBundleAnalyzerAst.js +22 -5
  300. package/dist/domain/webBundleAnalyzerInspection.js +20 -14
  301. package/dist/dotnet/ManagedMemberRows.js +1 -1
  302. package/dist/dotnet/ManagedMetadataHeaps.js +3 -2
  303. package/dist/dotnet/ManagedMetadataInventoryRows.js +4 -2
  304. package/dist/dotnet/ManagedMethodBodyReader.js +8 -1
  305. package/dist/dotnet/ManagedStaticProvider.js +3 -1
  306. package/dist/firmware/FirmwareCommand.js +163 -0
  307. package/dist/firmware/FirmwareFiles.js +190 -0
  308. package/dist/firmware/FirmwareProvider.js +258 -0
  309. package/dist/firmware/FirmwarePublication.js +84 -0
  310. package/dist/firmware/FirmwareRelease.js +32 -0
  311. package/dist/firmware/FirmwareReports.js +223 -0
  312. package/dist/generatedMcpToolCatalog.js +1 -1
  313. package/dist/generatedPackageMetadata.js +5 -5
  314. package/dist/ghidra/GhidraAnalysisProfile.js +37 -8
  315. package/dist/ghidra/GhidraClient.js +52 -6
  316. package/dist/ghidra/GhidraDiagnostics.js +3 -0
  317. package/dist/ghidra/GhidraDoctor.js +38 -14
  318. package/dist/ghidra/GhidraFunctionValues.js +10 -4
  319. package/dist/ghidra/GhidraInstallation.js +10 -4
  320. package/dist/ghidra/GhidraInventoryValues.js +39 -2
  321. package/dist/ghidra/GhidraLauncher.js +91 -26
  322. package/dist/ghidra/GhidraLoadImageValues.js +199 -0
  323. package/dist/ghidra/GhidraProvider.js +129 -13
  324. package/dist/ghidra/GhidraProviderCapabilities.js +52 -15
  325. package/dist/ghidra/GhidraRequestQueue.js +2 -2
  326. package/dist/ghidra/GhidraSessionError.js +31 -4
  327. package/dist/ghidra/GhidraSessionValues.js +10 -7
  328. package/dist/ghidra/GhidraTargetSnapshot.js +16 -2
  329. package/dist/ghidra/GhidraTransport.js +12 -0
  330. package/dist/ghidra/extensions/GhidraExtensionFailures.js +20 -0
  331. package/dist/ghidra/extensions/GhidraExtensions.js +170 -0
  332. package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +21 -0
  333. package/dist/ghidra/extensions/nativeaot/NativeAotReport.js +84 -0
  334. package/dist/hopper/BridgeLauncher.js +4 -2
  335. package/dist/hopper/HopperAnalysisProfile.js +7 -2
  336. package/dist/hopper/HopperCleanup.js +55 -9
  337. package/dist/hopper/HopperClient.js +14 -4
  338. package/dist/hopper/HopperProcessDiagnostic.js +1 -1
  339. package/dist/hopper/HopperProvider.js +8 -4
  340. package/dist/hopper/HopperRequestQueue.js +7 -3
  341. package/dist/hopper/HopperSessionValues.js +1 -1
  342. package/dist/hopper/HopperSocketConnection.js +1 -1
  343. package/dist/hopper/HopperTargetLease.js +23 -15
  344. package/dist/hopper/LinuxPrivateDisplayDiagnostic.js +7 -8
  345. package/dist/hopper/LinuxPrivateDisplayProbe.js +6 -2
  346. package/dist/hopper/protocol.js +8 -8
  347. package/dist/ida/IdaConfiguration.js +56 -0
  348. package/dist/ida/IdaDoctor.js +53 -0
  349. package/dist/ida/IdaInput.js +62 -0
  350. package/dist/ida/IdaMcpConnection.js +111 -0
  351. package/dist/ida/IdaOperationRunner.js +299 -0
  352. package/dist/ida/IdaProtocolValues.js +178 -0
  353. package/dist/ida/IdaProvider.js +126 -0
  354. package/dist/ida/IdaProviderCapabilities.js +60 -0
  355. package/dist/ida/IdaSessionClient.js +306 -0
  356. package/dist/ida/IdaWorkspace.js +54 -0
  357. package/dist/main/shutdown.js +21 -1
  358. package/dist/main/startup.js +1 -1
  359. package/dist/main/transport.js +8 -4
  360. package/dist/main.js +5 -2
  361. package/dist/native/AppleDispatchMetadata.js +31 -10
  362. package/dist/native/NativeMacOSProvider.js +87 -15
  363. package/dist/native/NativeMachoInspection.js +42 -12
  364. package/dist/native/NativeUiHelperRuntime.js +7 -1
  365. package/dist/native/NativeUiObservation.js +6 -2
  366. package/dist/native/parsers/demangle.js +1 -1
  367. package/dist/native/parsers/dyldInfo.js +3 -3
  368. package/dist/native/parsers/otool.js +4 -1
  369. package/dist/native/parsers/plist.js +11 -3
  370. package/dist/process/PrivateRuntimeRoot.js +13 -3
  371. package/dist/process/ProcessOwnership.js +5 -73
  372. package/dist/process/ProcessOwnershipObservation.js +62 -2
  373. package/dist/process/ProcessOwnershipProcessTree.js +13 -0
  374. package/dist/process/ProviderProcess.js +24 -7
  375. package/dist/process/ProviderRunLineage.js +1 -1
  376. package/dist/process/WindowsAuthority.js +20 -1
  377. package/dist/reference/ReferenceSourceReaderEntries.js +5 -1
  378. package/dist/reference/ReferenceSourceReaderFile.js +1 -0
  379. package/dist/server/createServer.js +25 -2
  380. package/dist/server/mcpProgress.js +2 -1
  381. package/dist/server/promptCompletion.js +3 -3
  382. package/dist/server/registerAndroidTools.js +30 -0
  383. package/dist/server/registerApplicationTools/compareExportShapes.js +5 -1
  384. package/dist/server/registerApplicationTools/compareSourceToBundle.js +7 -2
  385. package/dist/server/registerApplicationTools/compareVersions.js +5 -1
  386. package/dist/server/registerApplicationTools/traceFeature.js +7 -2
  387. package/dist/server/registerApplicationTools/traceSemantics.js +7 -2
  388. package/dist/server/registerEnhancedTools.js +28 -1
  389. package/dist/server/registerFirmwareTools.js +22 -0
  390. package/dist/server/registerFunctionComparisonTool.js +1 -1
  391. package/dist/server/registerInvestigationTools/helpers.js +2 -1
  392. package/dist/server/registerManagedTools.js +1 -1
  393. package/dist/server/registerManagedWorkflowTools/evidence.js +1 -1
  394. package/dist/server/registerOfficialTools.js +4 -1
  395. package/dist/server/registerProcessComparisonTool.js +5 -2
  396. package/dist/server/registerSessionTools.js +3 -1
  397. package/dist/server/runDerivedOperation.js +1 -1
  398. package/dist/server/sessionAvailabilityPolicy.js +3 -0
  399. package/dist/server/sessionEvidence.js +1 -1
  400. package/dist/server/toolResult.js +2 -1
  401. package/dist/windows/WindowsNativeLoader.js +108 -0
  402. package/dist/windows/WindowsOwnedProcess.js +168 -0
  403. package/dist/windows/WindowsPrivateRuntime.js +137 -0
  404. package/install.sh +4 -6
  405. package/native/windows/README.md +102 -0
  406. package/native/windows/build/manifest.json +9 -0
  407. package/native/windows/build/rea-windows-x64.node +0 -0
  408. package/package.json +38 -24
  409. package/scripts/rea.mjs +1 -1
  410. package/scripts/verify-windows-native-artifact.mjs +39 -0
  411. package/skills/reverse-engineer-anything/SKILL.md +92 -24
  412. package/skills/reverse-engineer-anything/references/android-applications.md +31 -0
  413. package/skills/reverse-engineer-anything/references/javascript-applications.md +19 -2
  414. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +52 -4
  415. package/dist/browser/CdpCanonicalJsonDigest.js +0 -9
  416. package/dist/domain/errors.js +0 -324
@@ -0,0 +1,54 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import { createReadStream, constants } from "node:fs";
3
+ import { copyFile } from "node:fs/promises";
4
+ import { tmpdir } from "node:os";
5
+ import { basename, join, normalize } from "node:path";
6
+ import { AnalysisProtocolError } from "../domain/analysisErrorCore.js";
7
+ import { PrivateRuntimeRoot } from "../process/PrivateRuntimeRoot.js";
8
+ /** Read a file digest with bounded memory rather than retaining binary bytes. */
9
+ export const idaFileDigest = async (path) => {
10
+ const hash = createHash("sha256");
11
+ for await (const chunk of createReadStream(path))
12
+ hash.update(chunk);
13
+ return hash.digest("hex");
14
+ };
15
+ /** Compare host-local paths without confusing Windows paths with POSIX coordinates. */
16
+ export const sameIdaHostPath = (left, right) => process.platform === "win32"
17
+ ? normalize(left).toLowerCase() === normalize(right).toLowerCase()
18
+ : normalize(left) === normalize(right);
19
+ /** Private input copy isolates upstream database and sidecar writes from the original. */
20
+ export class IdaWorkspace {
21
+ runtime;
22
+ inputPath;
23
+ sessionId = `rea-${randomUUID()}`;
24
+ constructor(runtime, inputPath) {
25
+ this.runtime = runtime;
26
+ this.inputPath = inputPath;
27
+ }
28
+ /** Filesystem root owned exclusively by this headless session. */
29
+ get directory() {
30
+ return this.runtime.path;
31
+ }
32
+ /** Allocate a protected workspace and copy the admitted input with digest verification. */
33
+ static async create(target, root = tmpdir()) {
34
+ const runtime = await PrivateRuntimeRoot.create({
35
+ parent: normalize(root),
36
+ prefix: "rea-ida-",
37
+ });
38
+ const inputPath = join(runtime.path, basename(target.path));
39
+ try {
40
+ await copyFile(target.path, inputPath, constants.COPYFILE_EXCL);
41
+ if ((await idaFileDigest(inputPath)) !== target.sha256)
42
+ throw new AnalysisProtocolError("IDA target changed between admission and the private input copy; reopen the target.");
43
+ return new IdaWorkspace(runtime, inputPath);
44
+ }
45
+ catch (cause) {
46
+ await runtime.close();
47
+ throw cause;
48
+ }
49
+ }
50
+ /** Delete only this object's privately allocated directory after worker cleanup. */
51
+ async remove() {
52
+ await this.runtime.close();
53
+ }
54
+ }
@@ -13,7 +13,8 @@ export const createShutdown = (input) => {
13
13
  return shutdownPromise;
14
14
  };
15
15
  const requestShutdown = () => {
16
- shutdown().catch(() => {
16
+ shutdown().catch((cause) => {
17
+ serverLogger.debug({ failure_cause: describeShutdownFailure(cause) }, "MCP shutdown rejected");
17
18
  dependencies.setExitCode(1);
18
19
  serverLogger.error(MCP_SHUTDOWN_FAILED);
19
20
  dependencies.writeStderr(`${MCP_SHUTDOWN_FAILED}\n`);
@@ -22,3 +23,22 @@ export const createShutdown = (input) => {
22
23
  unregisterShutdown = dependencies.registerShutdown(requestShutdown);
23
24
  return { shutdown, request: requestShutdown };
24
25
  };
26
+ const describeShutdownFailure = (cause) => {
27
+ if (cause instanceof Error) {
28
+ const code = "code" in cause ? cause.code : undefined;
29
+ return {
30
+ name: cause.name,
31
+ message: cause.message,
32
+ ...(typeof code === "string" ||
33
+ (typeof code === "number" && Number.isFinite(code))
34
+ ? { code }
35
+ : {}),
36
+ };
37
+ }
38
+ if (cause === null ||
39
+ typeof cause === "string" ||
40
+ typeof cause === "boolean" ||
41
+ (typeof cause === "number" && Number.isFinite(cause)))
42
+ return { type: cause === null ? "null" : typeof cause, value: cause };
43
+ return { type: typeof cause };
44
+ };
@@ -1,4 +1,4 @@
1
- import { projectAnalysisError } from "../domain/errors.js";
1
+ import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
2
2
  export const openInitialTarget = async (session, config, serverLogger, writeStderr) => {
3
3
  if (config.hopperTargetPath === undefined)
4
4
  return { ok: true };
@@ -6,8 +6,10 @@ export const startMcpTransport = async (dependencies, session, serverContext) =>
6
6
  try {
7
7
  optionalProviders = await serverContext.loadOptionalProviders();
8
8
  }
9
- catch {
10
- serverLogger.warn("Optional MCP providers could not load; affected tools remain unavailable");
9
+ catch (cause) {
10
+ serverLogger.warn({
11
+ error: cause instanceof Error ? cause.message : String(cause),
12
+ }, "Optional MCP providers could not load; affected tools remain unavailable");
11
13
  }
12
14
  let handle;
13
15
  try {
@@ -21,9 +23,11 @@ export const startMcpTransport = async (dependencies, session, serverContext) =>
21
23
  },
22
24
  });
23
25
  }
24
- catch {
26
+ catch (cause) {
25
27
  await session.close();
26
- serverLogger.error(MCP_CONNECTION_START_FAILED);
28
+ serverLogger.error({
29
+ error: cause instanceof Error ? cause.message : String(cause),
30
+ }, MCP_CONNECTION_START_FAILED);
27
31
  dependencies.writeStderr(`${MCP_CONNECTION_START_FAILED}\n`);
28
32
  return { ok: false };
29
33
  }
package/dist/main.js CHANGED
@@ -5,7 +5,7 @@ import { serveStdio } from "@modelcontextprotocol/server/stdio";
5
5
  import { parseConfig } from "./config.js";
6
6
  import { createBinarySession } from "./application/runtime.js";
7
7
  import { createLogger } from "./logger.js";
8
- import { projectAnalysisError } from "./domain/errors.js";
8
+ import { projectAnalysisError } from "./domain/analysisErrorProjection.js";
9
9
  import { SERVER_START_FAILED } from "./main/messages.js";
10
10
  import { createRuntimeState } from "./main/state.js";
11
11
  import { openInitialTarget } from "./main/startup.js";
@@ -98,7 +98,10 @@ export const runEntrypoint = async (start = () => run(), writeStderr = (text) =>
98
98
  try {
99
99
  setExitCode(await start());
100
100
  }
101
- catch {
101
+ catch (cause) {
102
+ // Intentionally redact the startup cause from caller-visible output;
103
+ // unexpected failures must not leak internal details.
104
+ void cause;
102
105
  writeStderr(`${SERVER_START_FAILED}\n`);
103
106
  setExitCode(1);
104
107
  }
@@ -2,7 +2,8 @@ import { createHash } from "node:crypto";
2
2
  import { open } from "node:fs/promises";
3
3
  import { constants } from "node:fs";
4
4
  import { objcSwiftMetadataSchema, nativeDispatchMetadataResultSchema, } from "../domain/objcSwiftMetadata.js";
5
- import { AnalysisCancelledError, EvidenceIntegrityError, } from "../domain/errors.js";
5
+ import { AnalysisCancelledError } from "../domain/analysisErrorCore.js";
6
+ import { EvidenceIntegrityError } from "../domain/evidenceErrors.js";
6
7
  import { decodeSwiftClassVtables } from "./AppleSwiftVtables.js";
7
8
  import { createObjcProtocolReader } from "./AppleObjcProtocols.js";
8
9
  const hex = (value) => `0x${value.toString(16)}`;
@@ -125,8 +126,9 @@ export const decodeAppleDispatchMetadata = (bytes, maxRecords, provenance, archi
125
126
  try {
126
127
  fileOffset = offset(target);
127
128
  }
128
- catch {
129
- /* serialized target remains unresolved */
129
+ catch (cause) {
130
+ // best-effort cleanup: serialized target remains unresolved.
131
+ void cause;
130
132
  }
131
133
  if (admit())
132
134
  result.relative_pointers.push({
@@ -154,8 +156,9 @@ export const decodeAppleDispatchMetadata = (bytes, maxRecords, provenance, archi
154
156
  throw new RangeError("Method implementation is not in an executable segment");
155
157
  implementationLocation = location(implementation);
156
158
  }
157
- catch {
158
- /* external/chained pointers remain unresolved */
159
+ catch (cause) {
160
+ // best-effort cleanup: external/chained pointers remain unresolved.
161
+ void cause;
159
162
  }
160
163
  result.objc_dispatch_implementations.push({
161
164
  class_name: className,
@@ -213,7 +216,9 @@ export const decodeAppleDispatchMetadata = (bytes, maxRecords, provenance, archi
213
216
  try {
214
217
  superclassName = string(pointer((pointer(superclass + 32n) & ~7n) + 24n));
215
218
  }
216
- catch {
219
+ catch (cause) {
220
+ // Superclass resolution failure is recorded; the cause adds no identity.
221
+ void cause;
217
222
  failures.push(`Superclass pointer ${hex(superclass)} of ${name} requires unsupported binding/fixup resolution`);
218
223
  }
219
224
  }
@@ -235,7 +240,9 @@ export const decodeAppleDispatchMetadata = (bytes, maxRecords, provenance, archi
235
240
  try {
236
241
  value = u32(encodedOffset);
237
242
  }
238
- catch {
243
+ catch (cause) {
244
+ // Unresolved offsets are recorded; the cause adds no identity.
245
+ void cause;
239
246
  failures.push(`Unresolved ivar offset pointer ${hex(encodedOffset)}`);
240
247
  }
241
248
  result.objc_ivars.push({
@@ -538,10 +545,10 @@ export const inspectAppleDispatchMetadata = async (target, maxRecords, signal) =
538
545
  };
539
546
  const selectMachoSlice = (bytes, architecture) => {
540
547
  const magic = bytes.readUInt32BE(0);
541
- const littleEndian = magic === 0xbebafeca || magic === 0xbfbafeca;
542
- if (magic !== 0xcafebabe && magic !== 0xcafebabf && !littleEndian)
548
+ const header = fatHeaderFormat(magic);
549
+ if (header === null)
543
550
  return { slice: 0, sliceEnd: bytes.length };
544
- const fat64 = magic === 0xcafebabf || magic === 0xbfbafeca;
551
+ const { littleEndian, fat64 } = header;
545
552
  const stride = fat64 ? 32 : 20;
546
553
  const readUInt32 = littleEndian
547
554
  ? (offset) => bytes.readUInt32LE(offset)
@@ -580,3 +587,17 @@ const selectMachoSlice = (bytes, architecture) => {
580
587
  throw invalid("Requested FAT architecture is absent");
581
588
  return selected;
582
589
  };
590
+ const fatHeaderFormat = (magic) => {
591
+ switch (magic) {
592
+ case 0xcafebabe:
593
+ return { littleEndian: false, fat64: false };
594
+ case 0xcafebabf:
595
+ return { littleEndian: false, fat64: true };
596
+ case 0xbebafeca:
597
+ return { littleEndian: true, fat64: false };
598
+ case 0xbfbafeca:
599
+ return { littleEndian: true, fat64: true };
600
+ default:
601
+ return null;
602
+ }
603
+ };
@@ -6,7 +6,9 @@ import { parse as parseXmlPlist } from "plist";
6
6
  import { z } from "zod";
7
7
  import { createAnalysisExecution, } from "../application/AnalysisProvider.js";
8
8
  import { NATIVE_TOOL_CONTRACTS, } from "../contracts/nativeToolContracts.js";
9
- import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisOutputError, ProviderAdapterError, AnalysisError, } from "../domain/errors.js";
9
+ import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisOutputError, } from "../domain/analysisErrorCore.js";
10
+ import { ProviderAdapterError } from "../domain/providerAdapterError.js";
11
+ import { AnalysisError } from "../domain/analysisErrorBase.js";
10
12
  import { jsonValueSchema } from "../domain/jsonValue.js";
11
13
  import { demangleSwiftSchema, inspectPlistSchema, inspectSignatureSchema, listArchitecturesSchema, } from "../domain/nativeInspection.js";
12
14
  import { err, ok } from "../domain/result.js";
@@ -209,28 +211,45 @@ class NativeMacOSClient {
209
211
  const display = await this.#run("inspect_signature", "codesign", ["-d", "--verbose=4", this.target.path], { signal, acceptNonZero: true });
210
212
  if (!display.ok)
211
213
  return display;
212
- const unsigned = /not signed at all|code object is not signed/iu.test(`${display.value.stdout}\n${display.value.stderr}`);
213
- if (!unsigned && display.value.exitCode !== 0)
214
- return err(translateCommandFailure("inspect_signature", new NativeCommandFailure("codesign", "nonzero-exit", display.value.exitCode)));
215
- const requirements = await this.#run("inspect_signature", "codesign", ["-d", "-r-", this.target.path], { signal, acceptNonZero: unsigned });
214
+ const displayOutput = commandOutput(display.value);
215
+ const unsigned = isUnsignedCodeSignObservation(display.value);
216
+ const displayFailure = codeSignCaptureFailure(display.value);
217
+ if (displayFailure !== null)
218
+ return err(displayFailure);
219
+ const requirements = await this.#run("inspect_signature", "codesign", ["-d", "-r-", this.target.path], { signal, acceptNonZero: true });
216
220
  if (!requirements.ok)
217
221
  return requirements;
218
- const entitlements = await this.#run("inspect_signature", "codesign", ["-d", "--entitlements", ":-", this.target.path], { signal, acceptNonZero: unsigned });
222
+ const requirementsFailure = codeSignCaptureFailure(requirements.value);
223
+ if (requirementsFailure !== null)
224
+ return err(requirementsFailure);
225
+ const entitlements = await this.#run("inspect_signature", "codesign", ["-d", "--entitlements", ":-", this.target.path], { signal, acceptNonZero: true });
219
226
  if (!entitlements.ok)
220
227
  return entitlements;
221
- const parsed = parseCodeSignature(`${display.value.stdout}\n${display.value.stderr}`, unsigned);
222
- const requirementText = /designated\s*=>\s*(.+)$/mu.exec(`${requirements.value.stdout}\n${requirements.value.stderr}`)?.[1] ?? null;
223
- const entitlementValue = parseEntitlements(`${entitlements.value.stdout}\n${entitlements.value.stderr}`);
224
- const provenance = [
225
- display.value,
226
- requirements.value,
227
- entitlements.value,
228
- ].map((capture) => invocation(capture, this.target.path));
228
+ const entitlementsFailure = codeSignCaptureFailure(entitlements.value);
229
+ if (entitlementsFailure !== null)
230
+ return err(entitlementsFailure);
231
+ const parsed = parseCodeSignature(displayOutput, unsigned);
232
+ const requirementText = /designated\s*=>\s*(.+)$/mu.exec(commandOutput(requirements.value))?.[1] ?? null;
233
+ const entitlementValue = parseEntitlements(commandOutput(entitlements.value));
234
+ const captures = [display.value, requirements.value, entitlements.value];
235
+ const limitations = [...parsed.limitations];
236
+ const mixedSigning = !unsigned &&
237
+ (isNonzeroUnsignedObservation(requirements.value) ||
238
+ isNonzeroUnsignedObservation(entitlements.value));
239
+ if (mixedSigning) {
240
+ const slices = await this.#inspectMixedSignatureSlices(displayOutput, requirements.value.exitCode !== 0, entitlements.value.exitCode !== 0, signal);
241
+ if (!slices.ok)
242
+ return slices;
243
+ captures.push(...slices.value.captures);
244
+ limitations.push(...slices.value.limitations);
245
+ }
246
+ const provenance = captures.map((capture) => invocation(capture, this.target.path));
229
247
  const result = inspectSignatureSchema.parse({
230
248
  ...parsed,
231
249
  designated_requirement: requirementText,
232
250
  entitlements: entitlementValue,
233
251
  provenance,
252
+ limitations,
234
253
  });
235
254
  return ok({
236
255
  result: jsonValueSchema.parse(result),
@@ -239,6 +258,35 @@ class NativeMacOSClient {
239
258
  locations: [],
240
259
  });
241
260
  }
261
+ async #inspectMixedSignatureSlices(displayOutput, requirementsUnavailable, entitlementsUnavailable, signal) {
262
+ const captures = [];
263
+ const unsigned = [];
264
+ const unclassified = [];
265
+ for (const architecture of codeSignArchitectures(displayOutput, this.target)) {
266
+ const slice = await this.#run("inspect_signature", "codesign", ["-d", "-a", architecture, "--verbose=4", this.target.path], { signal, acceptNonZero: true });
267
+ if (!slice.ok)
268
+ return slice;
269
+ captures.push(slice.value);
270
+ if (slice.value.exitCode === 0)
271
+ continue;
272
+ if (isNonzeroUnsignedObservation(slice.value))
273
+ unsigned.push(architecture);
274
+ else
275
+ unclassified.push(architecture);
276
+ }
277
+ const limitations = [
278
+ unsigned.length > 0
279
+ ? `Unsigned Mach-O slices: ${unsigned.join(", ")}.`
280
+ : "One or more Mach-O slices are unsigned, but their architectures could not be classified.",
281
+ ];
282
+ if (unclassified.length > 0)
283
+ limitations.push(`Signature state could not be classified for Mach-O slices: ${unclassified.join(", ")}.`);
284
+ if (requirementsUnavailable)
285
+ limitations.push("The aggregate designated requirement is unavailable because Mach-O slices have mixed signing states.");
286
+ if (entitlementsUnavailable)
287
+ limitations.push("The aggregate entitlements are unavailable because Mach-O slices have mixed signing states.");
288
+ return ok({ captures, limitations });
289
+ }
242
290
  async #inspectPlist(parameters, signal) {
243
291
  const requested = parameters.path;
244
292
  if (requested !== undefined && typeof requested !== "string")
@@ -253,6 +301,8 @@ class NativeMacOSClient {
253
301
  if (!capture.ok)
254
302
  return capture;
255
303
  const parsed = parsePlistJson(capture.value.stdout);
304
+ if (!parsed.ok)
305
+ return parsed;
256
306
  const provenance = [classified.value, capture.value].map((item) => invocation(item, plist.value, "$PLIST"));
257
307
  const result = inspectPlistSchema.parse({
258
308
  format: /binary property list/iu.test(classified.value.stdout)
@@ -260,7 +310,7 @@ class NativeMacOSClient {
260
310
  : /XML|text/iu.test(classified.value.stdout)
261
311
  ? "xml"
262
312
  : "unknown",
263
- ...parsed,
313
+ ...parsed.value,
264
314
  source_path: plist.value,
265
315
  provenance,
266
316
  limitations: [],
@@ -302,6 +352,28 @@ const translateCommandFailure = (operation, failure) => {
302
352
  return new AnalysisCancelledError(operation);
303
353
  return new ProviderAdapterError(IDENTITY.id, operation, { cause: failure });
304
354
  };
355
+ const translateCodeSignExitFailure = (capture) => translateCommandFailure("inspect_signature", new NativeCommandFailure("codesign", "nonzero-exit", capture.exitCode));
356
+ const commandOutput = (capture) => `${capture.stdout}\n${capture.stderr}`;
357
+ const isUnsignedCodeSignObservation = (capture) => /not signed at all|code object is not signed/iu.test(commandOutput(capture));
358
+ const isNonzeroUnsignedObservation = (capture) => capture.exitCode !== null &&
359
+ capture.exitCode !== 0 &&
360
+ isUnsignedCodeSignObservation(capture);
361
+ const codeSignCaptureFailure = (capture) => capture.exitCode === 0 || isNonzeroUnsignedObservation(capture)
362
+ ? null
363
+ : translateCodeSignExitFailure(capture);
364
+ const codeSignArchitectures = (displayOutput, target) => {
365
+ const universal = /^Format=Mach-O universal \(([^)\r\n]+)\)$/mu.exec(displayOutput)?.[1];
366
+ if (universal !== undefined) {
367
+ const architectures = universal
368
+ .split(/\s+/u)
369
+ .filter((architecture) => /^(?:i386|x86_64|armv7|arm64|arm64e)$/u.test(architecture));
370
+ if (architectures.length > 0)
371
+ return [...new Set(architectures)];
372
+ }
373
+ if (target.kind !== "executable" || target.format !== "mach-o")
374
+ return [];
375
+ return target.availableArchitectures.map((architecture) => architecture === "x86" ? "i386" : architecture);
376
+ };
305
377
  const invocation = (capture, artifactPath, alias = "$ARTIFACT") => ({
306
378
  tool: capture.tool,
307
379
  command: [
@@ -4,9 +4,11 @@ import { err, ok } from "../domain/result.js";
4
4
  import { parseDyldSymbols } from "./parsers/dyldInfo.js";
5
5
  import { parseLipoArchitectures } from "./parsers/lipo.js";
6
6
  import { parseOtoolLoadCommands } from "./parsers/otool.js";
7
- const REQUIRED_COMMANDS = [
7
+ const DISCOVERY_COMMANDS = [
8
8
  ["file", ["-b"]],
9
9
  ["lipo", ["-detailed_info"]],
10
+ ];
11
+ const REQUIRED_SLICE_COMMANDS = [
10
12
  ["otool", ["-h", "-l"]],
11
13
  ["nm", ["-gjU"]],
12
14
  ["dyld_info", ["-imports"]],
@@ -18,10 +20,20 @@ const VTOOL_UNAVAILABLE_LIMITATION = "vtool is unavailable; build metadata is no
18
20
  /** Inspect one Mach-O with the required native commands and normalized output. */
19
21
  export const inspectNativeMacho = async (context) => {
20
22
  const captures = [];
21
- for (const [tool, prefix] of REQUIRED_COMMANDS) {
23
+ for (const [tool, prefix] of DISCOVERY_COMMANDS) {
24
+ const captured = await context.run(tool, [...prefix, context.target.path], context.signal);
25
+ if (!captured.ok)
26
+ return err(captured.error);
27
+ captures.push(captured.value);
28
+ }
29
+ const lipo = captures.find(({ tool }) => tool === "lipo");
30
+ if (lipo === undefined)
31
+ throw new TypeError("Missing lipo capture");
32
+ const selectedArchitecture = selectArchitecture(context.target, parseLipoArchitectures(lipo.stdout).map(({ name }) => name));
33
+ for (const [tool, prefix] of REQUIRED_SLICE_COMMANDS) {
22
34
  const captured = await context.run(tool, [
23
35
  ...prefix,
24
- ...selectedArchitectureArguments(tool, context.target),
36
+ ...selectedArchitectureArguments(tool, selectedArchitecture),
25
37
  context.target.path,
26
38
  ], context.signal);
27
39
  if (!captured.ok)
@@ -32,7 +44,7 @@ export const inspectNativeMacho = async (context) => {
32
44
  const [tool, prefix] = OPTIONAL_VTOOL_COMMAND;
33
45
  const optional = await context.run(tool, [
34
46
  ...prefix,
35
- ...selectedArchitectureArguments(tool, context.target),
47
+ ...selectedArchitectureArguments(tool, selectedArchitecture),
36
48
  context.target.path,
37
49
  ], context.signal);
38
50
  if (optional.ok)
@@ -170,14 +182,32 @@ export const architectureLocations = (architectures) => {
170
182
  }
171
183
  return locations;
172
184
  };
173
- const selectedArchitectureArguments = (tool, target) => {
174
- if (target.kind !== "executable" ||
175
- target.availableArchitectures.length < 2 ||
176
- tool === "file" ||
177
- tool === "lipo")
185
+ const selectedArchitectureArguments = (tool, architecture) => {
186
+ if (architecture === null)
178
187
  return [];
179
- const architecture = target.architecture === "x86" ? "i386" : target.architecture;
188
+ const baseArchitecture = architecture.split(".")[0] ?? architecture;
189
+ // dyld_info distinguishes arm64e ABI variants; the other Apple tools use
190
+ // the base CPU-family spelling for the same slice.
191
+ const toolArchitecture = tool === "dyld_info" ? architecture : baseArchitecture;
180
192
  return tool === "dwarfdump"
181
- ? [`--arch=${architecture}`]
182
- : ["-arch", architecture];
193
+ ? [`--arch=${toolArchitecture}`]
194
+ : ["-arch", toolArchitecture];
195
+ };
196
+ const selectArchitecture = (target, available) => {
197
+ if (target.kind !== "executable" || target.availableArchitectures.length < 2)
198
+ return null;
199
+ const normalized = target.architecture === "x86" ? "i386" : target.architecture;
200
+ if (available.includes(normalized))
201
+ return normalized;
202
+ // BinaryTarget intentionally normalizes ARM64 CPU subtypes. Recover the
203
+ // concrete arm64e slice name from lipo before invoking slice-aware tools.
204
+ if (normalized === "arm64") {
205
+ const arm64e = available.find((architecture) => architecture === "arm64e");
206
+ if (arm64e !== undefined)
207
+ return arm64e;
208
+ const variant = available.find((architecture) => /^arm64e\.[A-Za-z0-9_]+$/u.test(architecture));
209
+ if (variant !== undefined)
210
+ return variant;
211
+ }
212
+ return normalized;
183
213
  };
@@ -3,6 +3,7 @@ import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import { execFileOutput } from "../process/ExecFileOutput.js";
6
+ import { safeParseJson } from "../domain/safeJson.js";
6
7
  /** Lazily compile one owned helper per observation/scenario and remove its compiler cache. */
7
8
  export const createNativeUiHelperRuntime = () => {
8
9
  let root;
@@ -30,7 +31,12 @@ export const createNativeUiHelperRuntime = () => {
30
31
  maxBuffer: 16 * 1024 * 1024,
31
32
  ...(signal === undefined ? {} : { signal }),
32
33
  });
33
- return JSON.parse(output.stdout);
34
+ const parsed = safeParseJson(output.stdout);
35
+ if (!parsed.ok)
36
+ throw new Error(`Native helper returned invalid JSON: ${parsed.error}`, {
37
+ cause: parsed.cause,
38
+ });
39
+ return parsed.value;
34
40
  };
35
41
  return {
36
42
  invoke,
@@ -1,7 +1,9 @@
1
1
  import { fileURLToPath } from "node:url";
2
2
  import { z } from "zod";
3
3
  import { nativeUiObservationInputSchema, nativeUiScenarioInputSchema, nativeUiSnapshotSchema, nativeUiResultSchema, } from "../domain/nativeUiObservation.js";
4
- import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisInputError, ProviderAdapterError, } from "../domain/errors.js";
4
+ import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisInputError, } from "../domain/analysisErrorCore.js";
5
+ import { ProviderAdapterError } from "../domain/providerAdapterError.js";
6
+ import {} from "../domain/analysisErrorBase.js";
5
7
  import { err, ok } from "../domain/result.js";
6
8
  import { createNativeUiHelperRuntime } from "./NativeUiHelperRuntime.js";
7
9
  const helper = fileURLToPath(new URL("../../bridge/native/ReaNativeUI.swift", import.meta.url));
@@ -122,7 +124,9 @@ const observeWithHelper = async (target, operation, parameters, options) => {
122
124
  abort();
123
125
  });
124
126
  }
125
- catch {
127
+ catch (cause) {
128
+ // Cancellation is recorded as a cancelled outcome.
129
+ void cause;
126
130
  results.push({
127
131
  index,
128
132
  kind: step.kind,
@@ -6,7 +6,7 @@ const resultSchema = z.object({
6
6
  });
7
7
  /** Preserve input ordering while parsing `swift-demangle --compact` lines. */
8
8
  export const parseDemangledSymbols = (inputs, output) => {
9
- const lines = output.trimEnd().split(/\r?\n/u);
9
+ const lines = output.replace(/\r?\n$/u, "").split(/\r?\n/u);
10
10
  if (lines.length !== inputs.length)
11
11
  throw new TypeError("swift-demangle output count does not match input");
12
12
  return inputs.map((input, index) => {
@@ -4,7 +4,7 @@ export const parseDyldSymbols = (output, mode, imageBase = null) => {
4
4
  return output.split(/\r?\n/u).flatMap((rawLine) => {
5
5
  const line = rawLine.trim();
6
6
  if (mode === "imports") {
7
- const imported = /^(?:0x[\da-f]+\s+)?(\S+)(?:\s+\[([^\]]+)\])?\s+\(from (.+)\)$/iu.exec(line);
7
+ const imported = /^(?:0x[\da-f]+\s+)?(.+?)(?:\s+\[([^\]]+)\])?\s+\(from (.+)\)$/iu.exec(line);
8
8
  if (imported?.[1] !== undefined)
9
9
  return [
10
10
  {
@@ -17,7 +17,7 @@ export const parseDyldSymbols = (output, mode, imageBase = null) => {
17
17
  ];
18
18
  return [];
19
19
  }
20
- const reexport = /^\[re-export\]\s+(\S+)(?:\s+\(from (.+)\))?$/u.exec(line);
20
+ const reexport = /^\[re-export\]\s+(.+?)(?:\s+\(from (.+)\))?$/u.exec(line);
21
21
  if (reexport?.[1] !== undefined)
22
22
  return [
23
23
  {
@@ -28,7 +28,7 @@ export const parseDyldSymbols = (output, mode, imageBase = null) => {
28
28
  source: reexport[2] ?? null,
29
29
  },
30
30
  ];
31
- const exported = /^(0x[\da-f]+)\s+(\S+)(?:\s+\[([^\]]+)\])?$/iu.exec(line);
31
+ const exported = /^(0x[\da-f]+)\s+(.+?)(?:\s+\[([^\]]+)\])?$/iu.exec(line);
32
32
  if (exported?.[1] === undefined || exported[2] === undefined)
33
33
  return [];
34
34
  const absolute = /\babsolute\b/u.test(exported[3] ?? "");
@@ -137,7 +137,10 @@ const parseFields = (block) => {
137
137
  if (match?.[1] === undefined || match[2] === undefined)
138
138
  continue;
139
139
  const value = match[2].trim();
140
- fields[match[1]] = numeric(value) ?? value;
140
+ fields[match[1]] =
141
+ match[1] === "segname" || match[1] === "sectname"
142
+ ? value
143
+ : (numeric(value) ?? value);
141
144
  }
142
145
  return fields;
143
146
  };
@@ -1,9 +1,17 @@
1
1
  import { z } from "zod";
2
+ import { AnalysisOutputError } from "../../domain/analysisErrorCore.js";
3
+ import { err, ok } from "../../domain/result.js";
4
+ import { safeParseJson } from "../../domain/safeJson.js";
2
5
  const plistObject = z.record(z.string(), z.unknown());
3
6
  /** Parse plutil JSON output and project stable bundle metadata. */
4
7
  export const parsePlistJson = (output) => {
5
8
  // plutil output can carry a UTF-8 BOM, which JSON.parse rejects outright.
6
- const value = JSON.parse(output.replace(/^\uFEFF/u, ""));
9
+ const parsed = safeParseJson(output.replace(/^\uFEFF/u, ""));
10
+ if (!parsed.ok)
11
+ return err(new AnalysisOutputError("inspect_plist", parsed.error, {
12
+ cause: parsed.cause,
13
+ }));
14
+ const value = parsed.value;
7
15
  const object = plistObject.safeParse(value);
8
16
  const field = (name) => {
9
17
  if (!object.success)
@@ -11,7 +19,7 @@ export const parsePlistJson = (output) => {
11
19
  const candidate = object.data[name];
12
20
  return typeof candidate === "string" ? candidate : null;
13
21
  };
14
- return {
22
+ return ok({
15
23
  value,
16
24
  bundle: {
17
25
  identifier: field("CFBundleIdentifier"),
@@ -20,5 +28,5 @@ export const parsePlistJson = (output) => {
20
28
  version: field("CFBundleVersion"),
21
29
  short_version: field("CFBundleShortVersionString"),
22
30
  },
23
- };
31
+ });
24
32
  };
@@ -1,6 +1,7 @@
1
1
  import { chmod, mkdtemp, rm } from "node:fs/promises";
2
2
  import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
+ import { WindowsPrivateRuntime } from "../windows/WindowsPrivateRuntime.js";
4
5
  import { windowsNativeCapabilities, } from "./WindowsAuthority.js";
5
6
  /** Report whether this process can establish a private runtime root. */
6
7
  export const privateRuntimeRootCapability = (platform = process.platform) => platform === "win32"
@@ -15,7 +16,7 @@ export class PrivateRuntimeRootUnavailableError extends Error {
15
16
  }
16
17
  }
17
18
  /**
18
- * Owns one POSIX mode-0700 temporary runtime root and removes it idempotently.
19
+ * Owns a private temporary runtime root and removes it idempotently.
19
20
  *
20
21
  * Protocol adapters decide what belongs inside the directory; this primitive
21
22
  * establishes a private filesystem boundary on POSIX and deterministic cleanup.
@@ -23,9 +24,11 @@ export class PrivateRuntimeRootUnavailableError extends Error {
23
24
  */
24
25
  export class PrivateRuntimeRoot {
25
26
  path;
27
+ windowsRuntime;
26
28
  #closePromise;
27
- constructor(path) {
29
+ constructor(path, windowsRuntime) {
28
30
  this.path = path;
31
+ this.windowsRuntime = windowsRuntime;
29
32
  }
30
33
  /** Allocate a new private runtime root without performing protocol work. */
31
34
  static async create(options = {}) {
@@ -33,6 +36,10 @@ export class PrivateRuntimeRoot {
33
36
  const capability = privateRuntimeRootCapability(platform);
34
37
  if (!capability.available)
35
38
  throw new PrivateRuntimeRootUnavailableError(capability.reason);
39
+ if (platform === "win32") {
40
+ const runtime = WindowsPrivateRuntime.create(options.parent ?? tmpdir(), options.prefix ?? "rea-provider-");
41
+ return new PrivateRuntimeRoot(runtime.observation.path, runtime);
42
+ }
36
43
  const path = await mkdtemp(join(options.parent ?? tmpdir(), options.prefix ?? "rea-provider-"));
37
44
  try {
38
45
  await chmod(path, 0o700);
@@ -45,7 +52,10 @@ export class PrivateRuntimeRoot {
45
52
  }
46
53
  /** Remove the runtime root; concurrent and repeated callers share cleanup. */
47
54
  close() {
48
- this.#closePromise ??= rm(this.path, { recursive: true, force: true });
55
+ this.#closePromise ??=
56
+ this.windowsRuntime === undefined
57
+ ? rm(this.path, { recursive: true, force: true })
58
+ : Promise.resolve().then(() => this.windowsRuntime?.close());
49
59
  return this.#closePromise;
50
60
  }
51
61
  }