rea-agents 6.1.0 → 6.3.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 (573) hide show
  1. package/README.md +24 -24
  2. package/bridge/ghidra/ReaGhidraBridge.java +32 -4
  3. package/bridge/hopper_bridge.py +8 -1
  4. package/dist/android/JadxConfiguration.js +87 -7
  5. package/dist/android/JadxMcpTransport.js +14 -2
  6. package/dist/android/JadxProvider.js +64 -36
  7. package/dist/android/JadxSession.js +51 -9
  8. package/dist/application/BinaryTargetResolver.js +68 -20
  9. package/dist/application/BrowserEvidence.js +3 -8
  10. package/dist/application/BrowserScenarioEvidence.js +4 -20
  11. package/dist/application/CapabilityInventory.js +43 -9
  12. package/dist/application/ClientConfigurationDocument.js +97 -25
  13. package/dist/application/ClientRegistrationStatus.js +19 -6
  14. package/dist/application/DirectAnalysis.js +41 -20
  15. package/dist/application/DirectAnalysisCleanup.js +71 -0
  16. package/dist/application/DirectAnalysisStatus.js +3 -7
  17. package/dist/application/Doctor.js +40 -53
  18. package/dist/application/DoctorDiagnostics.js +2 -3
  19. package/dist/application/EnhancedTools.js +51 -6
  20. package/dist/application/EvidenceBundleFiles.js +8 -3
  21. package/dist/application/InvestigationProviders.js +13 -5
  22. package/dist/application/JsonFiles.js +56 -23
  23. package/dist/application/LinuxHopper.js +11 -7
  24. package/dist/application/MacHopper.js +15 -18
  25. package/dist/application/RealHopperAssertions.js +0 -11
  26. package/dist/application/ReconstructionObligationCandidates.js +10 -3
  27. package/dist/application/ReconstructionObligationLedgerProjection.js +3 -1
  28. package/dist/application/ReferenceSourceImportEntries.js +1 -1
  29. package/dist/application/RegularFileRead.js +17 -0
  30. package/dist/application/Setup.js +26 -23
  31. package/dist/application/SetupClientConfiguration.js +18 -7
  32. package/dist/application/SetupHost.js +20 -29
  33. package/dist/application/SetupPlan.js +24 -20
  34. package/dist/application/SetupSkill.js +57 -8
  35. package/dist/application/SupportedClients.js +43 -0
  36. package/dist/application/Uninstall.js +98 -30
  37. package/dist/application/UpdateMaintenance.js +13 -7
  38. package/dist/application/UpdateRuntime.js +12 -12
  39. package/dist/application/Utf8JsonInput.js +64 -0
  40. package/dist/application/WebScriptExportService.js +38 -5
  41. package/dist/application/WorkflowEvidence.js +25 -2
  42. package/dist/application/XrefsAddressResolution.js +45 -0
  43. package/dist/application/analysisView/AnalysisViewService.js +76 -0
  44. package/dist/application/android/AndroidAnalysisService.js +1 -1
  45. package/dist/application/binary/AnalysisClientCleanup.js +30 -5
  46. package/dist/application/binary/AnalysisProviderEvaluation.js +1 -2
  47. package/dist/application/binary/AnalysisProviderRegistry.js +2 -6
  48. package/dist/application/binary/AnalysisSnapshotCache.js +13 -10
  49. package/dist/application/binary/BinarySession.js +86 -29
  50. package/dist/application/binary/BinarySessionComposition.js +1 -3
  51. package/dist/application/binary/BinarySessionExecution.js +3 -5
  52. package/dist/application/binary/BinarySessionOpen.js +10 -2
  53. package/dist/application/binary/BinarySessionRecords.js +1 -1
  54. package/dist/application/binary/BinarySessionStatus.js +1 -6
  55. package/dist/application/binary/CompositeProvider.js +4 -18
  56. package/dist/application/binary/LazyAnalysisProvider.js +5 -5
  57. package/dist/application/binary/SessionProviderRouter.js +27 -135
  58. package/dist/application/homebrew.js +48 -0
  59. package/dist/application/javascript/ElectronActiveEvidence.js +10 -14
  60. package/dist/application/javascript/ElectronBoundaryAnalysis.js +2 -2
  61. package/dist/application/javascript/ElectronBoundaryGraphNative.js +5 -1
  62. package/dist/application/javascript/JavaScriptApplicationEvidence.js +3 -6
  63. package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +107 -46
  64. package/dist/application/javascript/JavaScriptApplicationService.js +7 -1
  65. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +59 -45
  66. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +5 -9
  67. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +19 -27
  68. package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +11 -3
  69. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +9 -0
  70. package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +8 -5
  71. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +46 -29
  72. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +0 -1
  73. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +86 -27
  74. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +52 -9
  75. package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +1 -0
  76. package/dist/application/javascript/JavaScriptJsonModules.js +2 -2
  77. package/dist/application/javascript/JavaScriptModuleRelationships.js +6 -18
  78. package/dist/application/javascript/JavaScriptRuntimeObservationService.js +3 -3
  79. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +11 -27
  80. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +4 -5
  81. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +8 -6
  82. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +2 -3
  83. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +7 -5
  84. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +3 -4
  85. package/dist/application/javascript/JavaScriptSemanticGraphEvidence.js +1 -1
  86. package/dist/application/javascript/JavaScriptSemanticGraphFingerprintProjection.js +2 -2
  87. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +3 -7
  88. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +76 -47
  89. package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +4 -4
  90. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +3 -4
  91. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +51 -25
  92. package/dist/application/javascript/JavaScriptSemanticTraceService.js +15 -10
  93. package/dist/application/managed/ManagedMemberComparisonService.js +2 -1
  94. package/dist/application/managed/ManagedNativeVerificationService.js +2 -1
  95. package/dist/application/native/NativeCallRoutes.js +2 -4
  96. package/dist/application/process/ProcessCli.js +11 -11
  97. package/dist/application/process/ProcessEvidence.js +0 -1
  98. package/dist/artifacts/ArtifactProvider.js +53 -30
  99. package/dist/artifacts/ArtifactProviderMetadata.js +1 -4
  100. package/dist/artifacts/ArtifactReader.js +31 -0
  101. package/dist/artifacts/AsarArtifactReader.js +81 -17
  102. package/dist/artifacts/DirectoryArtifactReader.js +2 -1
  103. package/dist/artifacts/MachOSliceArtifactReader.js +9 -2
  104. package/dist/artifacts/NativeDmgArtifactReader.js +207 -77
  105. package/dist/artifacts/NativeDmgOwnership.js +109 -0
  106. package/dist/artifacts/SafeOutputTree.js +16 -2
  107. package/dist/artifacts/ZipArtifactReader.js +11 -4
  108. package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +4 -2
  109. package/dist/artifacts/apple/DylibResolutionReader.js +17 -7
  110. package/dist/artifacts/apple/KeyedArchiveReader.js +68 -42
  111. package/dist/artifacts/apple/MachoLoadCommandReader.js +36 -6
  112. package/dist/artifacts/extraction/ArtifactExtraction.js +104 -29
  113. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +71 -66
  114. package/dist/artifacts/inventory/ArtifactInventory.js +0 -1
  115. package/dist/artifacts/inventory/classify.js +33 -14
  116. package/dist/artifacts/inventory/hashStableRootArtifact.js +37 -0
  117. package/dist/artifacts/inventory/reader.js +3 -3
  118. package/dist/artifacts/inventory/scanCanonical.js +64 -34
  119. package/dist/artifacts/inventory/scanReader.js +12 -20
  120. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +65 -27
  121. package/dist/browser/BrowserScenarioPartialObservation.js +106 -0
  122. package/dist/browser/CdpBrowserProvider.js +6 -6
  123. package/dist/browser/CdpCaptureEventHandlers.js +2 -4
  124. package/dist/browser/CdpCaptureEvents.js +0 -1
  125. package/dist/browser/CdpCaptureStorageFingerprints.js +3 -3
  126. package/dist/browser/CdpCaptureValues.js +20 -0
  127. package/dist/browser/CdpElectronInspection.js +2 -2
  128. package/dist/browser/CdpElectronProvider.js +4 -5
  129. package/dist/browser/CdpElectronScriptEvents.js +2 -8
  130. package/dist/browser/CdpElectronScripts.js +4 -5
  131. package/dist/browser/CdpPageCaptureScripts.js +2 -3
  132. package/dist/browser/CdpSafeMetadata.js +10 -10
  133. package/dist/browser/CdpWebMcpDiscovery.js +16 -13
  134. package/dist/browser/PlaywrightBrowserScenarioProvider.js +64 -49
  135. package/dist/browser/PlaywrightElectronActiveActions.js +2 -56
  136. package/dist/browser/PlaywrightElectronActiveProvider.js +10 -6
  137. package/dist/browser/PlaywrightScenarioArtifacts.js +1 -1
  138. package/dist/browser/PlaywrightScenarioBrowser.js +269 -66
  139. package/dist/browser/PlaywrightScenarioEvents.js +1 -1
  140. package/dist/browser/PlaywrightScenarioSession.js +41 -32
  141. package/dist/browser/WebSourceMapFetcher.js +32 -6
  142. package/dist/browser/assets/ScenarioScriptCapture.js +8 -12
  143. package/dist/browser/assets/ScriptCaptureAdapters.js +1 -1
  144. package/dist/browser/history/CaptureFailures.js +6 -2
  145. package/dist/browser/history/MitmproxyCaptureAdapter.js +4 -2
  146. package/dist/catalogIdentity.js +0 -1
  147. package/dist/cli/analysisViewCommands.js +36 -0
  148. package/dist/cli/artifactCommands.js +11 -12
  149. package/dist/cli/coreAnalysisCommands.js +3 -3
  150. package/dist/cli/coreBinaryCommands.js +37 -28
  151. package/dist/cli/coreNativeCommands.js +9 -10
  152. package/dist/cli/electronCommands.js +12 -13
  153. package/dist/cli/interactiveSetup.js +6 -6
  154. package/dist/cli/javascriptApplicationAnalysis.js +2 -12
  155. package/dist/cli/jsonOutput.js +3 -2
  156. package/dist/cli/managedCommands.js +7 -8
  157. package/dist/cli/nativeCallCommands.js +1 -2
  158. package/dist/cli/omittableDefaults.js +50 -0
  159. package/dist/cli/processCommands.js +3 -2
  160. package/dist/cli/setupCommands.js +16 -15
  161. package/dist/cli/streamedJsonOutput.js +83 -4
  162. package/dist/cli/utilityCommands.js +10 -12
  163. package/dist/cli.js +19 -8
  164. package/dist/cliBrowserScenarioCommands.js +2 -2
  165. package/dist/cliCommandNames.js +1 -0
  166. package/dist/cliJsonFile.js +179 -0
  167. package/dist/cliJsonInput.js +60 -33
  168. package/dist/cliObservationOptions.js +4 -0
  169. package/dist/cliOutput.js +0 -38
  170. package/dist/composition/auxiliaryAnalysisProviders.js +30 -25
  171. package/dist/composition/binary.js +9 -9
  172. package/dist/composition/browserScenario.js +2 -1
  173. package/dist/composition/directAnalysis.js +20 -14
  174. package/dist/composition/electronScenario.js +1 -1
  175. package/dist/composition/optionalObservationProviders.js +12 -7
  176. package/dist/config/environment.js +6 -0
  177. package/dist/config/ghidraStartupTimeout.js +4 -9
  178. package/dist/config/homeDirectory.js +12 -0
  179. package/dist/config/mcpResponseBudget.js +9 -1
  180. package/dist/config/parseConfig.js +7 -3
  181. package/dist/config/parsers.js +19 -22
  182. package/dist/contracts/analysisViewToolContracts.js +56 -0
  183. package/dist/contracts/applicationToolContracts.js +5 -4
  184. package/dist/contracts/artifactComparisonExample.js +7 -7
  185. package/dist/contracts/artifactToolContracts.js +1 -1
  186. package/dist/contracts/browserScenarioToolContracts.js +1 -1
  187. package/dist/contracts/browserToolContracts.js +19 -15
  188. package/dist/contracts/enhancedInputs.js +2 -2
  189. package/dist/contracts/enhancedToolContracts.js +4 -3
  190. package/dist/contracts/errorSchemas.js +3 -1
  191. package/dist/contracts/evm/evmToolContracts.js +1 -1
  192. package/dist/contracts/functionComparisonExample.js +8 -0
  193. package/dist/contracts/functionWorkflowToolContracts.js +1 -1
  194. package/dist/contracts/inputSchemaPresentation.js +181 -0
  195. package/dist/contracts/investigationExamples.js +4 -3
  196. package/dist/contracts/javascript/electronToolContracts.js +3 -2
  197. package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +3 -22
  198. package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +248 -0
  199. package/dist/contracts/javascript/javascriptRuntimeObservationToolContracts.js +1 -1
  200. package/dist/contracts/javascript/javascriptRuntimeReconciliationExample.js +8 -7
  201. package/dist/contracts/managed/managedToolContracts.js +8 -12
  202. package/dist/contracts/managed/managedWorkflowToolContracts.js +1 -1
  203. package/dist/contracts/mobileApplicationGraphExamples.js +8 -8
  204. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +1 -1
  205. package/dist/contracts/native/nativeToolContracts.js +2 -2
  206. package/dist/contracts/officialToolContracts.js +2 -1
  207. package/dist/contracts/promptContracts.js +2 -2
  208. package/dist/contracts/providerSelection.js +1 -1
  209. package/dist/contracts/sessionLifecycleInputs.js +4 -3
  210. package/dist/contracts/sessionStatusContract.js +3 -2
  211. package/dist/contracts/sessionToolContracts.js +17 -4
  212. package/dist/contracts/sessionToolSchemas.js +4 -16
  213. package/dist/contracts/toolContracts.js +2 -0
  214. package/dist/contracts/toolEffects.js +1 -0
  215. package/dist/contracts/toolOutputSchemaGroups.js +138 -94
  216. package/dist/contracts/toolOutputSchemaPrimitives.js +13 -26
  217. package/dist/contracts/toolSchemaMetadata.js +18 -69
  218. package/dist/contracts/webNetworkCaptureToolContracts.js +1 -1
  219. package/dist/contracts/webRuntimeToolContracts.js +1 -1
  220. package/dist/contracts/webScriptToolContracts.js +1 -1
  221. package/dist/doctorRuntime.js +7 -5
  222. package/dist/domain/analysisErrorBase.js +5 -0
  223. package/dist/domain/analysisErrorCore.js +3 -0
  224. package/dist/domain/analysisErrorPresentation.js +22 -5
  225. package/dist/domain/analysisErrorProjection.js +24 -5
  226. package/dist/domain/analysisSnapshot.js +31 -31
  227. package/dist/domain/analysisView/analysisView.js +241 -0
  228. package/dist/domain/analysisView/analysisViewCoverage.js +19 -0
  229. package/dist/domain/analysisView/binaryLayoutView.js +159 -0
  230. package/dist/domain/analysisView/javascriptApplicationView.js +238 -0
  231. package/dist/domain/android/androidApplication.js +1 -1
  232. package/dist/domain/android/androidPartialObservation.js +36 -0
  233. package/dist/domain/apple/appleApplication.js +1 -1
  234. package/dist/domain/apple/dylibResolution.js +10 -3
  235. package/dist/domain/apple/interfaceBuilderGraph.js +0 -1
  236. package/dist/domain/apple/keyedArchive.js +26 -2
  237. package/dist/domain/artifactComparison.js +15 -6
  238. package/dist/domain/artifactGraph.js +17 -4
  239. package/dist/domain/artifactIdentity.js +8 -8
  240. package/dist/domain/artifactInspection.js +8 -8
  241. package/dist/domain/artifactInventoryEvidence.js +9 -16
  242. package/dist/domain/artifactOperationError.js +3 -3
  243. package/dist/domain/artifactPartialObservation.js +1 -0
  244. package/dist/domain/artifactPathSyntax.js +49 -0
  245. package/dist/domain/binaryTarget.js +39 -13
  246. package/dist/domain/browserCaptureComparison.js +13 -49
  247. package/dist/domain/browserCompleteness.js +3 -2
  248. package/dist/domain/browserNetworkEvidence.js +10 -4
  249. package/dist/domain/browserObservation.js +0 -1
  250. package/dist/domain/browserObservationSchemas.js +14 -3
  251. package/dist/domain/browserScenario.js +0 -1
  252. package/dist/domain/browserScenarioCapture.js +1 -2
  253. package/dist/domain/browserScenarioCaptureValues.js +2 -2
  254. package/dist/domain/browserScenarioDiff.js +0 -2
  255. package/dist/domain/browserScenarioDiffEvidence.js +0 -12
  256. package/dist/domain/browserScenarioDiffValues.js +2 -2
  257. package/dist/domain/browserScenarioNormalization.js +3 -3
  258. package/dist/domain/browserScenarioValues.js +6 -6
  259. package/dist/domain/callPath.js +15 -18
  260. package/dist/domain/callPathSchemas.js +2 -2
  261. package/dist/domain/canonicalDigest.js +7 -1
  262. package/dist/domain/canonicalOrdering.js +1 -13
  263. package/dist/domain/changedBehavior.js +5 -6
  264. package/dist/domain/comparisonSemantics.js +0 -5
  265. package/dist/domain/completionLedgerGeneration.js +2 -1
  266. package/dist/domain/configurationErrors.js +12 -0
  267. package/dist/domain/conformancePackage.js +4 -3
  268. package/dist/domain/digests.js +0 -3
  269. package/dist/domain/evidence.js +19 -40
  270. package/dist/domain/evidenceBundle.js +58 -42
  271. package/dist/domain/evidenceCompletionLedger.js +2 -1
  272. package/dist/domain/firmware/firmwareAnalysis.js +4 -3
  273. package/dist/domain/functionComparison.js +6 -6
  274. package/dist/domain/functionComparisonDimensions.js +120 -87
  275. package/dist/domain/functionComparisonNormalization.js +26 -36
  276. package/dist/domain/functionComparisonResults.js +3 -6
  277. package/dist/domain/functionComparisonSchemas.js +2 -8
  278. package/dist/domain/functionDossierEvidence.js +4 -38
  279. package/dist/domain/hopperValues.js +11 -15
  280. package/dist/domain/javascript/electronActiveObservation.js +29 -71
  281. package/dist/domain/javascript/electronObservation.js +14 -3
  282. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +12 -11
  283. package/dist/domain/javascript/electronStaticAnalysisIpc.js +11 -2
  284. package/dist/domain/javascript/electronStaticAnalysisNative.js +7 -4
  285. package/dist/domain/javascript/electronStaticAnalysisValues.js +8 -4
  286. package/dist/domain/javascript/javascriptApplicationAnalysis.js +3 -1
  287. package/dist/domain/javascript/javascriptApplicationChangeGraph.js +12 -8
  288. package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +6 -0
  289. package/dist/domain/javascript/javascriptApplicationGraph.js +41 -16
  290. package/dist/domain/javascript/javascriptApplicationGraphSchemas.js +9 -2
  291. package/dist/domain/javascript/javascriptApplicationVersionComparison.js +4 -4
  292. package/dist/domain/javascript/javascriptApplicationVersionComparisonSchemas.js +37 -22
  293. package/dist/domain/javascript/javascriptApplicationVersionItems.js +50 -36
  294. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +9 -8
  295. package/dist/domain/javascript/javascriptAstFingerprint.js +2 -2
  296. package/dist/domain/javascript/javascriptAstValues.js +22 -0
  297. package/dist/{application/javascript/JavaScriptReturnShapeProjection.js → domain/javascript/javascriptExportReturnShapeProjection.js} +4 -4
  298. package/dist/domain/javascript/javascriptExportShapeComparison.js +10 -3
  299. package/dist/domain/javascript/javascriptExportShapeComparisonIdentity.js +6 -1
  300. package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +58 -22
  301. package/dist/domain/javascript/javascriptExportShapeSelection.js +7 -7
  302. package/dist/domain/javascript/javascriptExportShapeVariants.js +70 -16
  303. package/dist/domain/javascript/javascriptFeatureSeed.js +25 -3
  304. package/dist/domain/javascript/javascriptFeatureTrace.js +7 -6
  305. package/dist/domain/javascript/javascriptFeatureTraceSchemas.js +17 -9
  306. package/dist/domain/javascript/javascriptFeatureTraversal.js +4 -5
  307. package/dist/domain/javascript/javascriptNativeHandoff.js +7 -7
  308. package/dist/domain/javascript/javascriptRuntimeLoadState.js +0 -1
  309. package/dist/domain/javascript/javascriptRuntimeObservation.js +18 -7
  310. package/dist/domain/javascript/javascriptRuntimeReconciliation.js +12 -6
  311. package/dist/domain/javascript/javascriptRuntimeReconciliationActive.js +9 -8
  312. package/dist/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js +212 -0
  313. package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +5 -4
  314. package/dist/domain/javascript/javascriptRuntimeReconciliationInputValidation.js +28 -0
  315. package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +6 -6
  316. package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +12 -222
  317. package/dist/domain/javascript/javascriptRuntimeReconciliationResult.js +2 -2
  318. package/dist/domain/javascript/javascriptRuntimeReconciliationRuntime.js +15 -4
  319. package/dist/domain/javascript/javascriptRuntimeReconciliationSchemas.js +2 -2
  320. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +7 -7
  321. package/dist/domain/javascript/javascriptSemanticAnalysis.js +209 -11
  322. package/dist/domain/javascript/javascriptSemanticAsyncEffects.js +2 -1
  323. package/dist/domain/javascript/javascriptSemanticCallResolution.js +9 -7
  324. package/dist/domain/javascript/javascriptSemanticCalls.js +2 -1
  325. package/dist/domain/javascript/javascriptSemanticChildProcesses.js +4 -3
  326. package/dist/domain/javascript/javascriptSemanticCoverage.js +20 -0
  327. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +7 -9
  328. package/dist/domain/javascript/javascriptSemanticDataEffects.js +4 -11
  329. package/dist/domain/javascript/javascriptSemanticFingerprints.js +2 -2
  330. package/dist/domain/javascript/javascriptSemanticGraph.js +220 -71
  331. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +19 -1
  332. package/dist/domain/javascript/javascriptSemanticIr.js +0 -4
  333. package/dist/domain/javascript/javascriptSemanticIterationSources.js +106 -0
  334. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +515 -74
  335. package/dist/domain/javascript/javascriptSemanticMutationInitializers.js +190 -0
  336. package/dist/domain/javascript/javascriptSemanticMutationValues.js +44 -36
  337. package/dist/domain/javascript/javascriptSemanticObjects.js +79 -42
  338. package/dist/domain/javascript/javascriptSemanticPrimitives.js +8 -14
  339. package/dist/domain/javascript/javascriptSemanticProjection.js +21 -16
  340. package/dist/domain/javascript/javascriptSemanticPromises.js +16 -21
  341. package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +23 -0
  342. package/dist/domain/javascript/javascriptSemanticProvenance.js +3 -3
  343. package/dist/domain/javascript/javascriptSemanticQuery.js +8 -2
  344. package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +3 -2
  345. package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -9
  346. package/dist/domain/javascript/javascriptSemanticRequireOrigin.js +16 -10
  347. package/dist/domain/javascript/javascriptSemanticResourceLimits.js +1 -1
  348. package/dist/domain/javascript/javascriptSemanticResources.js +1 -1
  349. package/dist/domain/javascript/javascriptSemanticReturns.js +55 -44
  350. package/dist/domain/javascript/javascriptSemanticSlots.js +72 -0
  351. package/dist/domain/javascript/javascriptSemanticTraversal.js +6 -1
  352. package/dist/domain/javascript/javascriptSemanticValues.js +180 -76
  353. package/dist/domain/javascript/javascriptSourceMapPaths.js +114 -0
  354. package/dist/domain/javascript/javascriptSourceParser.js +34 -9
  355. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -6
  356. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +2 -1
  357. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +26 -16
  358. package/dist/domain/javascript/sourceToBundleComparison.js +19 -8
  359. package/dist/domain/javascript/sourceToBundleSignals.js +53 -25
  360. package/dist/domain/jsonSerialization.js +109 -55
  361. package/dist/domain/jsonShape.js +46 -19
  362. package/dist/domain/localPath.js +10 -4
  363. package/dist/domain/managed/managedApplicationGraph.js +10 -6
  364. package/dist/domain/managed/managedApplicationGraphNodes.js +82 -57
  365. package/dist/domain/managed/managedArtifact.js +6 -4
  366. package/dist/domain/managed/managedMemberComparison.js +2 -9
  367. package/dist/domain/managed/managedMemberComparisonMatch.js +6 -7
  368. package/dist/domain/managed/managedNativeVerification.js +0 -2
  369. package/dist/domain/managed/managedNativeVerificationMatch.js +9 -3
  370. package/dist/domain/native/binaryLayout.js +2 -3
  371. package/dist/domain/native/nativeApiBoundary.js +1 -1
  372. package/dist/domain/native/nativeCallObservation.js +3 -3
  373. package/dist/domain/native/nativeInstruction.js +7 -0
  374. package/dist/domain/native/nativeValueFlow.js +5 -11
  375. package/dist/domain/native/objcSwiftMetadata.js +15 -17
  376. package/dist/domain/native/recordedCrash.js +2 -3
  377. package/dist/domain/offsetDateTime.js +17 -0
  378. package/dist/domain/process/processCapture.js +22 -20
  379. package/dist/domain/process/processCaptureCoverage.js +70 -0
  380. package/dist/domain/process/processCaptureExample.js +45 -1
  381. package/dist/domain/process/processCaptureParsing.js +1 -34
  382. package/dist/domain/process/processCaptureValidation.js +82 -13
  383. package/dist/domain/process/processComparison.js +39 -43
  384. package/dist/domain/process/processObservation.js +10 -2
  385. package/dist/domain/process/processScenario.js +24 -2
  386. package/dist/domain/process/processTraceComparison.js +0 -2
  387. package/dist/domain/process/processTraceDimensionProjection.js +1 -1
  388. package/dist/domain/process/processTraceEvaluation.js +19 -15
  389. package/dist/domain/process/processTraceSpecification.js +4 -7
  390. package/dist/domain/providerAdapterError.js +2 -0
  391. package/dist/domain/providerCleanupError.js +6 -2
  392. package/dist/domain/reconstructionCoverage.js +7 -3
  393. package/dist/domain/reconstructionObligationLedgerSchemas.js +2 -1
  394. package/dist/domain/reconstructionReadinessSchemas.js +2 -1
  395. package/dist/domain/reconstructionUnknowns.js +4 -3
  396. package/dist/domain/reconstructionVerification.js +6 -5
  397. package/dist/domain/reconstructionVerificationSchemas.js +2 -1
  398. package/dist/domain/referenceSourceGraph.js +27 -28
  399. package/dist/domain/referenceSourceImportParsing.js +34 -45
  400. package/dist/domain/residualUnknown.js +3 -2
  401. package/dist/domain/staticRuntimeCorrelation.js +4 -3
  402. package/dist/domain/stringPatterns.js +6 -0
  403. package/dist/domain/swiftSymbolClassification.js +66 -0
  404. package/dist/domain/symbolAnalysis.js +83 -20
  405. package/dist/domain/unicodeCodePointOrder.js +6 -0
  406. package/dist/domain/webBundleAnalyzerInspection.js +9 -1
  407. package/dist/domain/webCaptureDiff.js +71 -30
  408. package/dist/domain/webCaptureDiffSchemas.js +8 -11
  409. package/dist/domain/webEventListeners.js +3 -2
  410. package/dist/domain/webExecution.js +3 -2
  411. package/dist/domain/webInventory.js +3 -2
  412. package/dist/domain/webMcpDiscovery.js +4 -3
  413. package/dist/domain/webRuntime.js +0 -2
  414. package/dist/domain/webScriptExport.js +2 -2
  415. package/dist/dotnet/ManagedArtifactInspector.js +2 -19
  416. package/dist/dotnet/ManagedMemberInspector.js +12 -18
  417. package/dist/dotnet/ManagedMemberInspectorCore.js +47 -44
  418. package/dist/dotnet/ManagedMemberInstructionDecoder.js +1 -2
  419. package/dist/dotnet/ManagedMemberRows.js +75 -62
  420. package/dist/dotnet/ManagedMetadataInventory.js +16 -22
  421. package/dist/dotnet/ManagedMethodBodyReader.js +4 -0
  422. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +109 -94
  423. package/dist/dotnet/ManagedNativeBoundaryInspector.js +12 -21
  424. package/dist/dotnet/ManagedReaderFailure.js +16 -0
  425. package/dist/dotnet/ManagedStaticProvider.js +13 -12
  426. package/dist/dotnet/ManagedStaticProviderMetadata.js +1 -4
  427. package/dist/evaluation/AgentEvaluationFixtures.js +250 -0
  428. package/dist/evaluation/AgentEvaluationReport.js +28 -0
  429. package/dist/evaluation/CodexAgentEval.js +12 -8
  430. package/dist/evaluation/KnownAnswerEvaluation.js +281 -0
  431. package/dist/evm/EvmoleInterfaceProvider.js +2 -1
  432. package/dist/filesystem/RegularFile.js +41 -0
  433. package/dist/firmware/FirmwareCommand.js +9 -5
  434. package/dist/firmware/FirmwareProvider.js +4 -4
  435. package/dist/generatedPackageMetadata.js +2 -2
  436. package/dist/ghidra/GhidraAnalysisProfile.js +3 -6
  437. package/dist/ghidra/GhidraClient.js +105 -36
  438. package/dist/ghidra/GhidraClientStartup.js +0 -2
  439. package/dist/ghidra/GhidraDoctor.js +6 -5
  440. package/dist/ghidra/GhidraFunctionValues.js +3 -5
  441. package/dist/ghidra/GhidraInstallation.js +151 -22
  442. package/dist/ghidra/GhidraJavaLaunch.js +6 -2
  443. package/dist/ghidra/GhidraLauncher.js +58 -26
  444. package/dist/ghidra/GhidraProvider.js +6 -2
  445. package/dist/ghidra/GhidraProviderCapabilities.js +6 -0
  446. package/dist/ghidra/GhidraProviderClient.js +13 -3
  447. package/dist/ghidra/GhidraSessionError.js +2 -0
  448. package/dist/ghidra/GhidraSessionRoot.js +39 -0
  449. package/dist/ghidra/extensions/GhidraExtensions.js +17 -10
  450. package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +8 -2
  451. package/dist/hopper/BridgeLauncher.js +34 -45
  452. package/dist/hopper/HopperAnalysisProfile.js +3 -8
  453. package/dist/hopper/HopperCleanup.js +56 -27
  454. package/dist/hopper/HopperClient.js +86 -65
  455. package/dist/hopper/HopperMachOImage.js +3 -2
  456. package/dist/hopper/HopperProvider.js +16 -18
  457. package/dist/hopper/HopperRegexSearch.js +3 -6
  458. package/dist/hopper/HopperTargetLease.js +132 -49
  459. package/dist/hopper/LinuxPrivateDisplayProbe.js +6 -0
  460. package/dist/ida/IdaConfiguration.js +8 -3
  461. package/dist/ida/IdaInput.js +1 -7
  462. package/dist/ida/IdaMcpConnection.js +8 -4
  463. package/dist/ida/IdaOperationRunner.js +5 -3
  464. package/dist/ida/IdaProvider.js +8 -12
  465. package/dist/ida/IdaSessionClient.js +24 -20
  466. package/dist/ida/IdaWorkspace.js +12 -13
  467. package/dist/inspector/JavaScriptRuntimeScope.js +9 -5
  468. package/dist/inspector/V8InspectorCaptureProjection.js +47 -14
  469. package/dist/inspector/V8InspectorProvider.js +97 -35
  470. package/dist/javascript/recovery/WakaruCommand.js +7 -2
  471. package/dist/javascript/recovery/WakaruExecution.js +5 -2
  472. package/dist/main/shutdown.js +81 -29
  473. package/dist/main/startup.js +9 -2
  474. package/dist/main/transport.js +23 -3
  475. package/dist/main.js +11 -18
  476. package/dist/native/AppleMachoSelection.js +16 -6
  477. package/dist/native/AppleObjcDispatchFacets.js +3 -3
  478. package/dist/native/AppleObjcProperties.js +17 -7
  479. package/dist/native/CommandRunner.js +9 -7
  480. package/dist/native/LldbCallTracer.js +249 -77
  481. package/dist/native/NativeMacOSProvider.js +32 -17
  482. package/dist/native/NativeMacOSProviderMetadata.js +1 -2
  483. package/dist/native/NativeUiHelperRuntime.js +11 -2
  484. package/dist/native/NativeUiObservation.js +2 -2
  485. package/dist/native/pwntools/PwntoolsDecoder.js +2 -1
  486. package/dist/process/DarwinProcessRunTokenReader.js +16 -2
  487. package/dist/process/ExecFileOutput.js +88 -6
  488. package/dist/process/PrivateRuntimeRoot.js +10 -5
  489. package/dist/process/ProcessOwnership.js +1 -4
  490. package/dist/process/ProcessOwnershipObservation.js +18 -16
  491. package/dist/process/ProviderProcess.js +1 -3
  492. package/dist/process/capture/FilesystemSnapshot.js +131 -24
  493. package/dist/process/capture/ProcessCaptureError.js +13 -0
  494. package/dist/process/capture/ProcessCaptureLifecycle.js +148 -74
  495. package/dist/process/capture/ProcessFilesystemEffects.js +51 -6
  496. package/dist/process/capture/ProcessHarness.js +16 -33
  497. package/dist/process/capture/ProcessNormalization.js +20 -2
  498. package/dist/process/capture/ProcessSampling.js +25 -2
  499. package/dist/process/capture/TerminalRenderer.js +14 -0
  500. package/dist/process/snapshotEnvironment.js +14 -0
  501. package/dist/server/EvidenceMcpServer.js +25 -14
  502. package/dist/server/analysisAdmission.js +8 -0
  503. package/dist/server/createServer.js +71 -59
  504. package/dist/server/mcpClientMetadata.js +12 -5
  505. package/dist/server/promptCompletion.js +3 -8
  506. package/dist/server/registerAnalysisViewTool.js +15 -0
  507. package/dist/server/registerAndroidTools.js +2 -3
  508. package/dist/server/registerApplicationTools/compareExportShapes.js +6 -6
  509. package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
  510. package/dist/server/registerApplicationTools/compareVersions.js +4 -5
  511. package/dist/server/registerApplicationTools/coverage.js +1 -2
  512. package/dist/server/registerApplicationTools/helpers.js +4 -4
  513. package/dist/server/registerApplicationTools/obligationLedger.js +4 -5
  514. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -4
  515. package/dist/server/registerApplicationTools/traceFeature.js +4 -5
  516. package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
  517. package/dist/server/registerArtifactComparisonTool.js +4 -5
  518. package/dist/server/registerArtifactTools.js +2 -2
  519. package/dist/server/registerBinaryDiagnosticsTools.js +2 -3
  520. package/dist/server/registerBrowserScenarioTool.js +3 -4
  521. package/dist/server/registerBrowserTools.js +13 -16
  522. package/dist/server/registerBundleComparisonTool.js +5 -6
  523. package/dist/server/registerCloseLifecycleTool.js +8 -7
  524. package/dist/server/registerElectronTools.js +10 -13
  525. package/dist/server/registerEnhancedTools.js +82 -77
  526. package/dist/server/registerEvidenceTools.js +54 -47
  527. package/dist/server/registerEvmTools.js +2 -3
  528. package/dist/server/registerFirmwareTools.js +2 -3
  529. package/dist/server/registerFunctionComparisonTool.js +7 -8
  530. package/dist/server/registerInvestigationTools.js +14 -15
  531. package/dist/server/registerJavaScriptRecoveryTool.js +2 -3
  532. package/dist/server/registerJavaScriptRuntimeObservationTools.js +6 -6
  533. package/dist/server/registerManagedTools.js +7 -4
  534. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +5 -6
  535. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +4 -5
  536. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +6 -7
  537. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +6 -7
  538. package/dist/server/registerOfficialTools.js +32 -41
  539. package/dist/server/registerProcessComparisonTool.js +8 -8
  540. package/dist/server/registerRecordedCrashTools.js +2 -3
  541. package/dist/server/registerSessionRecordTools.js +15 -19
  542. package/dist/server/registerSessionStatusTool.js +3 -4
  543. package/dist/server/registerSessionTools.js +19 -19
  544. package/dist/server/registerWebModuleTool.js +2 -3
  545. package/dist/server/registerWebNetworkCaptureTool.js +2 -3
  546. package/dist/server/registerWebRuntimeTools.js +4 -5
  547. package/dist/server/registerWebScriptTool.js +2 -3
  548. package/dist/server/registerWebSourceLocationTool.js +2 -3
  549. package/dist/server/toolResult.js +66 -94
  550. package/dist/server/toolResultEncoding.js +11 -10
  551. package/dist/windows/WindowsNativeLoader.js +1 -0
  552. package/dist/windows/WindowsOwnedProcess.js +60 -15
  553. package/dist/windows/WindowsPrivateRuntime.js +7 -8
  554. package/native/windows/README.md +3 -1
  555. package/native/windows/build/manifest.json +2 -2
  556. package/native/windows/build/rea-windows-x64.node +0 -0
  557. package/package.json +42 -30
  558. package/scripts/rea.mjs +3 -6
  559. package/skills/reverse-engineer-anything/SKILL.md +14 -13
  560. package/skills/reverse-engineer-anything/references/android-applications.md +6 -3
  561. package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -4
  562. package/skills/reverse-engineer-anything/references/javascript-applications.md +16 -6
  563. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +18 -0
  564. package/dist/artifacts/inventory/policy.js +0 -2
  565. package/dist/config.js +0 -1
  566. package/dist/contracts/browserCaptureToolInputSchema.js +0 -43
  567. package/dist/contracts/process/processCaptureExample.js +0 -2
  568. package/dist/contracts/toolOutputSchemas.js +0 -2
  569. package/dist/domain/managed/managedApplicationGraphNodeCoverage.js +0 -6
  570. package/dist/main/reload.js +0 -12
  571. package/dist/main/state.js +0 -3
  572. package/dist/server/registerNativeTools.js +0 -6
  573. package/dist/server/sessionToolPolicies.js +0 -2
@@ -9,6 +9,10 @@ import { spawnOwnedProviderProcess, ProviderProcessSupervisor, } from "../proces
9
9
  import { cleanupOwnedProcessGroup } from "../process/ProcessOwnership.js";
10
10
  import { FIRMWARE_LIMITS } from "./FirmwareRelease.js";
11
11
  import { hashFirmwareFile, inventoryFirmwareOutput, readFirmwareReport, } from "./FirmwareFiles.js";
12
+ /** Refuse an unmet host or tool requirement, which another target cannot satisfy. */
13
+ export const firmwareToolUnavailable = (engine, operation, reason) => new AnalysisCapabilityUnavailableError(engine, operation, reason, {
14
+ userMessage: reason,
15
+ });
12
16
  /** Resolve explicitly supplied executable paths; never install or search for engines. */
13
17
  export const resolveFirmwareCommand = async (environment, engine, operation) => {
14
18
  const variable = engine === "binwalk" ? "REA_BINWALK_COMMAND" : "REA_UNBLOB_COMMAND";
@@ -16,9 +20,9 @@ export const resolveFirmwareCommand = async (environment, engine, operation) =>
16
20
  if (process.platform !== "linux" ||
17
21
  configured === undefined ||
18
22
  !isAbsolute(configured))
19
- throw new AnalysisCapabilityUnavailableError(engine, operation, `This integration requires Linux and an absolute ${variable} path to the caller-supplied tool`);
23
+ throw firmwareToolUnavailable(engine, operation, `This integration requires Linux and an absolute ${variable} path to the caller-supplied tool`);
20
24
  const command = await realpath(configured).catch((cause) => {
21
- throw new AnalysisCapabilityUnavailableError(engine, operation, `${variable} is unavailable: ${cause instanceof Error ? cause.message : String(cause)}`);
25
+ throw firmwareToolUnavailable(engine, operation, `${variable} is unavailable: ${cause instanceof Error ? cause.message : String(cause)}`);
22
26
  });
23
27
  let sha256;
24
28
  try {
@@ -28,18 +32,18 @@ export const resolveFirmwareCommand = async (environment, engine, operation) =>
28
32
  sha256 = await hashFirmwareFile(command);
29
33
  }
30
34
  catch (cause) {
31
- throw new AnalysisCapabilityUnavailableError(engine, operation, `${variable} is not a readable executable regular file: ${command}: ${cause instanceof Error ? cause.message : String(cause)}`);
35
+ throw firmwareToolUnavailable(engine, operation, `${variable} is not a readable executable regular file: ${command}: ${cause instanceof Error ? cause.message : String(cause)}`);
32
36
  }
33
37
  const limiter = environment.REA_FIRMWARE_PRLIMIT_COMMAND ?? "/usr/bin/prlimit";
34
38
  if (!isAbsolute(limiter))
35
- throw new AnalysisCapabilityUnavailableError(engine, operation, "REA_FIRMWARE_PRLIMIT_COMMAND must be absolute");
39
+ throw firmwareToolUnavailable(engine, operation, "REA_FIRMWARE_PRLIMIT_COMMAND must be absolute");
36
40
  try {
37
41
  await access(limiter, constants.X_OK);
38
42
  if (!(await stat(limiter)).isFile())
39
43
  throw new TypeError("Configured path is not a regular file");
40
44
  }
41
45
  catch (cause) {
42
- throw new AnalysisCapabilityUnavailableError(engine, operation, `Resource limiter is not an executable regular file: ${limiter}: ${cause instanceof Error ? cause.message : String(cause)}; provide util-linux prlimit`);
46
+ throw firmwareToolUnavailable(engine, operation, `Resource limiter is not an executable regular file: ${limiter}: ${cause instanceof Error ? cause.message : String(cause)}; provide util-linux prlimit`);
43
47
  }
44
48
  return { command, limiter, sha256 };
45
49
  };
@@ -3,7 +3,7 @@ import { z } from "zod";
3
3
  import { createAnalysisExecution, } from "../application/AnalysisProvider.js";
4
4
  import { firmwareResultSchemas, } from "../domain/firmware/firmwareAnalysis.js";
5
5
  import { AnalysisError } from "../domain/analysisErrorBase.js";
6
- import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisInputError, AnalysisOutputError, AnalysisTimeoutError, } from "../domain/analysisErrorCore.js";
6
+ import { AnalysisCancelledError, AnalysisInputError, AnalysisOutputError, AnalysisTimeoutError, } from "../domain/analysisErrorCore.js";
7
7
  import { ProviderAdapterError } from "../domain/providerAdapterError.js";
8
8
  import { ProviderCleanupError } from "../domain/providerCleanupError.js";
9
9
  import { err, ok } from "../domain/result.js";
@@ -11,7 +11,7 @@ import { PrivateRuntimeRoot } from "../process/PrivateRuntimeRoot.js";
11
11
  import { publishFirmwareExtraction } from "./FirmwarePublication.js";
12
12
  import { FIRMWARE_LIMITS, BINWALK_PROVIDER_IDENTITY, UNBLOB_PROVIDER_IDENTITY, } from "./FirmwareRelease.js";
13
13
  import { admitFirmwareVersion } from "./FirmwareVersion.js";
14
- import { resolveFirmwareCommand, runFirmwareCommand, readFirmwareCommandReport, } from "./FirmwareCommand.js";
14
+ import { firmwareToolUnavailable, resolveFirmwareCommand, runFirmwareCommand, readFirmwareCommandReport, } from "./FirmwareCommand.js";
15
15
  import { inventoryFirmwareOutput, snapshotFirmware } from "./FirmwareFiles.js";
16
16
  import { normalizeBinwalkReport, normalizeUnblobReport, } from "./FirmwareReports.js";
17
17
  const waitForPredecessor = (predecessor, operation, signal) => new Promise((resolve, reject) => {
@@ -96,10 +96,10 @@ export class FirmwareProvider {
96
96
  const versionRun = await run(["--version"]);
97
97
  const version = versionRun.stdout.text.trim();
98
98
  if (versionRun.stdout.bytes > 1024)
99
- throw new AnalysisCapabilityUnavailableError(engineName, request.operation, `Tool version banner is ${String(versionRun.stdout.bytes)} bytes; expected a short ${engineName} version line.`);
99
+ throw firmwareToolUnavailable(engineName, request.operation, `Tool version banner is ${String(versionRun.stdout.bytes)} bytes; expected a short ${engineName} version line.`);
100
100
  const admitted = admitFirmwareVersion(engineName, version);
101
101
  if (admitted.status === "unsupported" || admitted.status === "unresolved")
102
- throw new AnalysisCapabilityUnavailableError(engineName, request.operation, admitted.message);
102
+ throw firmwareToolUnavailable(engineName, request.operation, admitted.message);
103
103
  const engine = {
104
104
  name: engineName,
105
105
  version: admitted.version,
@@ -1,9 +1,9 @@
1
1
  /** Generated from package.json and package-lock.json; do not edit. */
2
2
  export const PACKAGE_METADATA = {
3
3
  name: "rea-agents",
4
- version: "6.1.0", // x-release-please-version
4
+ version: "6.3.0", // x-release-please-version
5
5
  serverSdkVersion: "2.3.1",
6
6
  clientSdkVersion: "2.3.1",
7
7
  coreSdkVersion: "2.3.1",
8
- skillVersion: "33",
8
+ skillVersion: "34",
9
9
  };
@@ -8,7 +8,7 @@ export const resolveGhidraAnalysisProfile = (target, identity, installation, sig
8
8
  if (signal?.aborted === true)
9
9
  return Promise.resolve(err(new AnalysisCancelledError("open_binary")));
10
10
  if (target.kind !== "executable")
11
- return Promise.resolve(ok({ profile: null, compatibility: {} }));
11
+ return Promise.resolve(ok({ profile: null }));
12
12
  if (installation.status === "unavailable")
13
13
  return Promise.resolve(err(new ProviderAdapterError(identity.id, "resolve_analysis_profile")));
14
14
  const provider = { ...identity, version: installation.providerVersion };
@@ -28,7 +28,8 @@ export const resolveGhidraAnalysisProfile = (target, identity, installation, sig
28
28
  load_image_observations: "source-mappings-entry-context-v2",
29
29
  function_body_evidence: "complete-inclusive-ranges-v1",
30
30
  function_references: "complete-body-and-entry-reference-manager-v2",
31
- location_resolution: "explicit-address-exact-name-first-v2",
31
+ location_resolution: "explicit-address-exact-entry-symbol-first-v3",
32
+ instruction_flow_evidence: "decoded-return-pcode-v1",
32
33
  process_launch: installation.platform === "win32"
33
34
  ? "official-headless-script-v1"
34
35
  : "inspected-jvm-launch-support-v1",
@@ -68,9 +69,5 @@ export const resolveGhidraAnalysisProfile = (target, identity, installation, sig
68
69
  : {}),
69
70
  analyzer_preset: "ghidra-default",
70
71
  }),
71
- compatibility: {
72
- languageId: dos ? "x86:LE:16:Real Mode" : "auto",
73
- compilerSpecId: dos ? "default" : "auto",
74
- },
75
72
  }));
76
73
  };
@@ -1,5 +1,6 @@
1
1
  import { randomBytes, randomUUID } from "node:crypto";
2
- import { tmpdir } from "node:os";
2
+ import { AnalysisError } from "../domain/analysisErrorBase.js";
3
+ import { ProviderCleanupError } from "../domain/providerCleanupError.js";
3
4
  import { err, ok } from "../domain/result.js";
4
5
  import { silentLogger } from "../logger.js";
5
6
  import { PendingOperations } from "../process/PendingOperations.js";
@@ -9,6 +10,7 @@ import { ProviderRunLineage } from "../process/ProviderRunLineage.js";
9
10
  import { ProviderProcessSupervisor, } from "../process/ProviderProcess.js";
10
11
  import { DEFAULT_GHIDRA_STARTUP_TIMEOUT_MS } from "../config/ghidraStartupTimeout.js";
11
12
  import { createGhidraDiagnostics } from "./GhidraDiagnostics.js";
13
+ import { GhidraLaunchError } from "./GhidraLauncher.js";
12
14
  import { GhidraResponseBuffer } from "./GhidraResponseBuffer.js";
13
15
  import { GhidraResponseRouter } from "./GhidraResponseRouter.js";
14
16
  import { GhidraRequestQueue } from "./GhidraRequestQueue.js";
@@ -20,8 +22,9 @@ import { connectGhidraSocket } from "./GhidraSocketConnection.js";
20
22
  import { createGhidraEndpoint, } from "./GhidraTransport.js";
21
23
  import { GhidraWire } from "./GhidraClientWire.js";
22
24
  import { completeGhidraStartupHandshake } from "./GhidraClientStartup.js";
25
+ import { ghidraSessionRoot } from "./GhidraSessionRoot.js";
23
26
  const SHUTDOWN_TIMEOUT_MS = 10_000;
24
- const SESSION_ROOT = tmpdir();
27
+ const SESSION_ROOT = ghidraSessionRoot();
25
28
  /** Owns an authenticated private Ghidra session with transport-bound mutation authority. */
26
29
  export class GhidraClient {
27
30
  #options;
@@ -91,10 +94,12 @@ export class GhidraClient {
91
94
  /** Launch Ghidra once and require its exact post-analysis handshake. */
92
95
  start(signal) {
93
96
  if (this.#closePromise !== undefined)
94
- return this.#closePromise.then(() => this.start(signal));
97
+ return this.#closePromise.then(() => this.start(signal), (cause) => err(new GhidraSessionError("process", "Ghidra cleanup remains incomplete", this.#diagnostics(), { cause, cleanupFailure: this.#cleanupError(cause) })));
95
98
  if (this.#startPromise !== undefined) {
96
99
  if (this.#startupController?.signal.aborted && !signal?.aborted)
97
- return this.#startPromise.then((result) => result.ok ? result : this.start(signal));
100
+ return this.#startPromise.then((result) => result.ok || result.error.cleanupFailure !== undefined
101
+ ? result
102
+ : this.start(signal));
98
103
  return this.#startPromise;
99
104
  }
100
105
  const controller = new AbortController();
@@ -153,8 +158,43 @@ export class GhidraClient {
153
158
  }
154
159
  }
155
160
  /** Stop the owned process group and remove all project/runtime artifacts. */
156
- close() {
157
- return this.#requestClose(false);
161
+ async close() {
162
+ try {
163
+ await this.#requestClose(false);
164
+ return ok(null);
165
+ }
166
+ catch (cause) {
167
+ return err(this.#cleanupError(cause));
168
+ }
169
+ }
170
+ #cleanupError(cause) {
171
+ if (cause instanceof AnalysisError && cause.cleanupIncomplete)
172
+ return cause;
173
+ return new ProviderCleanupError("ghidra", [
174
+ ...(this.#process === undefined ? [] : ["ghidra-process"]),
175
+ ...[this.#runtimeRoot, this.#socketRoot].flatMap((root) => root === undefined ? [] : [root.path]),
176
+ ], {
177
+ reason: cause instanceof Error ? cause.message : String(cause),
178
+ diagnostics: this.#diagnostics(),
179
+ }, { cause });
180
+ }
181
+ async #startupFailure(primary) {
182
+ try {
183
+ await this.#cleanup();
184
+ return err(primary);
185
+ }
186
+ catch (cause) {
187
+ return err(new GhidraSessionError(primary.kind, primary.message, primary.diagnostics, {
188
+ ...(primary.cause === undefined ? {} : { cause: primary.cause }),
189
+ ...(primary.timeoutMs === undefined
190
+ ? {}
191
+ : { timeoutMs: primary.timeoutMs }),
192
+ ...(primary.remoteCode === undefined
193
+ ? {}
194
+ : { remoteCode: primary.remoteCode }),
195
+ cleanupFailure: this.#cleanupError(cause),
196
+ }));
197
+ }
158
198
  }
159
199
  #requestClose(forceStop) {
160
200
  const starting = this.#startPromise;
@@ -218,8 +258,7 @@ export class GhidraClient {
218
258
  }
219
259
  catch (cause) {
220
260
  const failure = this.#failure("start", "Ghidra private endpoint allocation failed", cause);
221
- await this.#cleanup();
222
- return err(failure);
261
+ return this.#startupFailure(failure);
223
262
  }
224
263
  try {
225
264
  const snapshot = await createGhidraTargetSnapshot(this.#options.targetPath, this.#runtimeRoot.path, this.#options.targetSha256, { signal: deadline.signal, platform: this.#options.platform });
@@ -230,8 +269,7 @@ export class GhidraClient {
230
269
  if (deadline.signal.aborted)
231
270
  return this.#startupInterrupted(deadline);
232
271
  const failure = this.#failure("start", "Ghidra target snapshot failed admission", cause);
233
- await this.#cleanup();
234
- return err(failure);
272
+ return this.#startupFailure(failure);
235
273
  }
236
274
  if (deadline.signal.aborted)
237
275
  return this.#startupInterrupted(deadline);
@@ -253,13 +291,21 @@ export class GhidraClient {
253
291
  }, { signal: deadline.signal })
254
292
  .catch((cause) => err(this.#failure("start", "Ghidra launcher failed", cause)));
255
293
  if (!launched.ok) {
294
+ const partialLaunch = launched.error instanceof GhidraLaunchError
295
+ ? launched.error.partialLaunch
296
+ : undefined;
297
+ if (partialLaunch !== undefined) {
298
+ this.#launch = partialLaunch;
299
+ this.#process = new ProviderProcessSupervisor(partialLaunch, {
300
+ onDiagnostic: (event) => this.#onProcessDiagnostic(event),
301
+ });
302
+ }
256
303
  const failure = deadline.signal.aborted
257
- ? this.#interruptionFailure(deadline)
304
+ ? this.#interruptionFailure(deadline, launched.error)
258
305
  : launched.error instanceof GhidraSessionError
259
306
  ? launched.error
260
307
  : this.#failure("start", launched.error.message, launched.error);
261
- await this.#cleanup();
262
- return err(failure);
308
+ return this.#startupFailure(failure);
263
309
  }
264
310
  this.#launch = launched.value;
265
311
  this.#process = new ProviderProcessSupervisor(launched.value, {
@@ -268,21 +314,19 @@ export class GhidraClient {
268
314
  const connected = await this.#connect(endpoint, deadline);
269
315
  if (!connected.ok) {
270
316
  const failure = connected.error;
271
- await this.#cleanup();
272
- return err(failure);
317
+ return this.#startupFailure(failure);
273
318
  }
274
319
  const completed = await completeGhidraStartupHandshake({
275
320
  deadline,
276
321
  request: (method, params, requestOptions) => this.#wire.request(method, params, requestOptions),
277
322
  parseSessionInfo: (value) => this.#parseSessionInfo(value),
278
- cleanup: () => this.#cleanup(),
279
323
  failure: this.#failure,
280
324
  startupTimeoutMs: this.#options.startupTimeoutMs,
281
325
  });
282
- if (completed.ok) {
283
- await this.#lineage.observe(this.#launch);
284
- this.#requestQueue.reopen();
285
- }
326
+ if (!completed.ok)
327
+ return this.#startupFailure(completed.error);
328
+ await this.#lineage.observe(this.#launch);
329
+ this.#requestQueue.reopen();
286
330
  return completed;
287
331
  }
288
332
  async #connect(endpoint, deadline) {
@@ -389,18 +433,8 @@ export class GhidraClient {
389
433
  this.#lastDiagnostics = this.#diagnostics();
390
434
  this.#process = undefined;
391
435
  this.#launch = undefined;
392
- const runtimeRoot = this.#runtimeRoot;
393
- const socketRoot = this.#socketRoot;
394
- this.#runtimeRoot = undefined;
395
- this.#socketRoot = undefined;
396
436
  try {
397
- const removed = await Promise.allSettled([
398
- runtimeRoot?.close(),
399
- socketRoot?.close(),
400
- ]);
401
- const failed = removed.find((result) => result.status === "rejected");
402
- if (failed?.status === "rejected")
403
- throw failed.reason;
437
+ await this.#removeRuntimeRoots();
404
438
  }
405
439
  catch (cause) {
406
440
  if (forceStop)
@@ -420,6 +454,42 @@ export class GhidraClient {
420
454
  this.#closing = false;
421
455
  }
422
456
  }
457
+ /**
458
+ * Remove the runtime and socket roots, keeping each one that could not be
459
+ * removed so a later close retries it rather than reporting success.
460
+ */
461
+ async #removeRuntimeRoots() {
462
+ const roots = [
463
+ {
464
+ root: this.#runtimeRoot,
465
+ release: () => (this.#runtimeRoot = undefined),
466
+ },
467
+ { root: this.#socketRoot, release: () => (this.#socketRoot = undefined) },
468
+ ];
469
+ const leftovers = [];
470
+ let firstCause;
471
+ for (const { root, release } of roots) {
472
+ if (root === undefined)
473
+ continue;
474
+ try {
475
+ await root.close();
476
+ release();
477
+ }
478
+ catch (cause) {
479
+ firstCause ??= cause;
480
+ leftovers.push({
481
+ path: root.path,
482
+ reason: cause instanceof Error ? cause.message : String(cause),
483
+ });
484
+ }
485
+ }
486
+ if (leftovers.length > 0)
487
+ throw new ProviderCleanupError("ghidra", leftovers.map(({ path }) => path), {
488
+ reason: "Ghidra's private runtime directory could not be removed; it is retained for a later close.",
489
+ leftover_paths: leftovers.map(({ path }) => path),
490
+ failures: leftovers.map(({ path, reason }) => `${path}: ${reason}`),
491
+ }, { cause: firstCause });
492
+ }
423
493
  #redactAuthentication(value) {
424
494
  for (const token of this.#authenticationTokens)
425
495
  value = value.replaceAll(token, "[REDACTED]");
@@ -457,13 +527,12 @@ export class GhidraClient {
457
527
  }
458
528
  async #startupInterrupted(deadline) {
459
529
  const failure = this.#interruptionFailure(deadline);
460
- await this.#cleanup();
461
- return err(failure);
530
+ return this.#startupFailure(failure);
462
531
  }
463
- #interruptionFailure(deadline) {
532
+ #interruptionFailure(deadline, cause) {
464
533
  return deadline.interruption === "cancelled"
465
- ? this.#failure("cancelled", "Ghidra startup was cancelled")
466
- : this.#failure("timeout", "Ghidra startup deadline elapsed", undefined, {
534
+ ? this.#failure("cancelled", "Ghidra startup was cancelled", cause)
535
+ : this.#failure("timeout", "Ghidra startup deadline elapsed", cause, {
467
536
  timeoutMs: deadline.timeoutMs,
468
537
  });
469
538
  }
@@ -9,7 +9,6 @@ export async function completeGhidraStartupHandshake(options) {
9
9
  const failure = options.deadline.signal.aborted
10
10
  ? interruptionFailure(options)
11
11
  : ping.error;
12
- await options.cleanup();
13
12
  return err(failure);
14
13
  }
15
14
  const parsed = options.parseSessionInfo(ping.value);
@@ -17,7 +16,6 @@ export async function completeGhidraStartupHandshake(options) {
17
16
  const failure = parsed.ok
18
17
  ? options.failure("analysis_timeout", "Ghidra auto-analysis reached its per-file deadline")
19
18
  : parsed.error;
20
- await options.cleanup();
21
19
  return err(failure);
22
20
  }
23
21
  return parsed;
@@ -38,13 +38,14 @@ export const projectGhidraDoctorInspection = (inspection) => {
38
38
  };
39
39
  };
40
40
  /** Inspect the process-configured BYO Ghidra installation for `rea doctor`. */
41
- export const inspectSystemGhidraProvider = () => Promise.resolve(projectGhidraDoctorInspection(inspectGhidraInstallation({
42
- ...(process.env.GHIDRA_INSTALL_DIR === undefined
41
+ export const inspectSystemGhidraProvider = (environment) => Promise.resolve(projectGhidraDoctorInspection(inspectGhidraInstallation({
42
+ environment,
43
+ ...(environment.GHIDRA_INSTALL_DIR === undefined
43
44
  ? {}
44
- : { installDir: process.env.GHIDRA_INSTALL_DIR }),
45
- ...(process.env.JAVA_HOME === undefined
45
+ : { installDir: environment.GHIDRA_INSTALL_DIR }),
46
+ ...(environment.JAVA_HOME === undefined
46
47
  ? {}
47
- : { javaHome: process.env.JAVA_HOME }),
48
+ : { javaHome: environment.JAVA_HOME }),
48
49
  })));
49
50
  const selectedChecks = (inspection) => {
50
51
  const byName = new Map(inspection.checks.map((candidate) => [candidate.name, candidate]));
@@ -112,13 +112,11 @@ const procedureReferences = z
112
112
  procedure: procedureIdentity,
113
113
  direction: z.enum(["incoming", "outgoing"]),
114
114
  references: z.array(referenceEdge),
115
- reference_kinds_available: z.boolean().default(true),
116
- unresolved_calls: z
117
- .array(z.strictObject({
115
+ reference_kinds_available: z.boolean(),
116
+ unresolved_calls: z.array(z.strictObject({
118
117
  address: ghidraCanonicalAddressSchema,
119
118
  reason: z.string(),
120
- }))
121
- .default([]),
119
+ })),
122
120
  })
123
121
  .strict();
124
122
  const procedureInfo = z
@@ -1,14 +1,84 @@
1
+ import { snapshotEnvironment } from "../process/snapshotEnvironment.js";
1
2
  import { spawnSync } from "node:child_process";
2
3
  import { constants } from "node:fs";
3
- import { accessSync, readFileSync } from "node:fs";
4
+ import { accessSync, closeSync, fstatSync, openSync, readFileSync, readSync, statSync, } from "node:fs";
4
5
  import { posix, win32 } from "node:path";
6
+ import { parseExecutableHeader, } from "../domain/binaryTarget.js";
5
7
  import { ghidraApplicationProperties, ghidraJavaMajorAccepted, ghidraJavaRangeLabel, ghidraJavaRequirement, ghidraReleaseAccepted, ghidraReleaseCompatibility, ghidraReleaseLine, ghidraVersionDetail, SUPPORTED_GHIDRA_JAVA_MAJOR, SUPPORTED_GHIDRA_VERSION, } from "./GhidraInstallationPolicy.js";
6
- export { SUPPORTED_GHIDRA_JAVA_MAJOR, SUPPORTED_GHIDRA_VERSION };
7
8
  const NATIVE_PLATFORMS = {
8
9
  linux: { x64: "linux_x86_64", arm64: "linux_arm_64" },
9
10
  darwin: { x64: "mac_x86_64", arm64: "mac_arm_64" },
10
11
  win32: { x64: "win_x86_64" },
11
12
  };
13
+ /** Executable format each supported host runs its own Ghidra native tools as. */
14
+ const NATIVE_TOOL_FORMATS = {
15
+ linux: "elf",
16
+ darwin: "mach-o",
17
+ win32: "pe",
18
+ };
19
+ /** Node architecture identifiers as the executable-header parser reports them. */
20
+ const NATIVE_ARCHITECTURES = [
21
+ { node: "x64", binary: "x86_64" },
22
+ { node: "ia32", binary: "x86" },
23
+ { node: "arm", binary: "arm" },
24
+ { node: "arm64", binary: "arm64" },
25
+ ];
26
+ /** Bound installation discovery reads; larger headers remain unknown. */
27
+ const EXECUTABLE_HEADER_PROBE_BYTES = 4096;
28
+ /**
29
+ * Judge a native decompiler by its own executable header instead of the
30
+ * directory name that admits it.
31
+ *
32
+ * Only a header that positively contradicts the host is `incompatible`. An
33
+ * absent, unreadable, truncated, or unrecognized header stays `unknown`, so a
34
+ * file the other checks already accept is never refused on missing evidence.
35
+ */
36
+ const assessNativeDecompiler = (path, platform, architecture, probe) => {
37
+ const expectedFormat = NATIVE_TOOL_FORMATS[platform];
38
+ const expectedArchitecture = NATIVE_ARCHITECTURES.find(({ node }) => node === architecture)?.binary;
39
+ if (expectedFormat === undefined || expectedArchitecture === undefined)
40
+ return {
41
+ status: "unknown",
42
+ detail: `${path} is executable, but no native tool format is defined for ${platform}/${architecture}`,
43
+ };
44
+ let parsed = probe === undefined
45
+ ? undefined
46
+ : parseExecutableHeader(probe.bytes, architecture, probe.size);
47
+ if (probe !== undefined && parsed !== undefined && !parsed.ok) {
48
+ // FAT parsing selects a host slice. A validated foreign slice can still
49
+ // prove that its complete architecture table excludes this host. If the
50
+ // host is listed but its slice is malformed, preserve the unknown outcome.
51
+ for (const { node } of NATIVE_ARCHITECTURES) {
52
+ if (node === architecture)
53
+ continue;
54
+ const alternative = parseExecutableHeader(probe.bytes, node, probe.size);
55
+ if (alternative.ok &&
56
+ !alternative.value.availableArchitectures.includes(expectedArchitecture)) {
57
+ parsed = alternative;
58
+ break;
59
+ }
60
+ }
61
+ }
62
+ if (parsed === undefined || !parsed.ok)
63
+ return {
64
+ status: "unknown",
65
+ detail: `${path} is executable, but its executable format for ${platform}/${architecture} could not be established`,
66
+ };
67
+ const observed = `${parsed.value.format} ${parsed.value.architecture}`;
68
+ const expected = `${expectedFormat} ${expectedArchitecture}`;
69
+ if (observed === expected)
70
+ return {
71
+ status: "compatible",
72
+ detail: `${path} reports ${observed}, which matches ${platform}/${architecture}`,
73
+ };
74
+ const nativeDirectory = NATIVE_PLATFORMS[platform]?.[architecture];
75
+ const executable = platform === "win32" ? "decompile.exe" : "decompile";
76
+ return {
77
+ status: "incompatible",
78
+ detail: `${path} reports ${observed}, but ${platform}/${architecture} requires ${expected}`,
79
+ remediation: `Provide an executable Ghidra/Features/Decompiler/os/${nativeDirectory ?? "<platform>"}/${executable} built for ${expected}, or its build/os equivalent. REA does not build or install native tools.`,
80
+ };
81
+ };
12
82
  /** Inspect an installation without importing a target or modifying Ghidra. */
13
83
  export const inspectGhidraInstallation = (options, host = systemGhidraInstallationHost()) => {
14
84
  const platform = options.platform ?? process.platform;
@@ -97,17 +167,15 @@ const installationCoordinates = (options, platform, architecture, host) => {
97
167
  ? undefined
98
168
  : ghidraApplicationProperties(properties),
99
169
  javaCommand,
100
- java: host.probeJava(javaCommand, ghidraJavaEnvironment(options.javaHome, process.env, platform)),
170
+ // The configuration check rejects a relative JAVA_HOME. Probing it would
171
+ // run whatever `bin/java` the current directory holds.
172
+ java: options.javaHome === undefined || path.isAbsolute(options.javaHome)
173
+ ? host.probeJava(javaCommand, ghidraJavaEnvironment(options.javaHome, options.environment, platform))
174
+ : undefined,
101
175
  };
102
176
  };
103
177
  const installationChecks = ({ coordinates, platform, architecture, javaHome, host, }) => [
104
- installationCheck({
105
- name: "configuration",
106
- passed: coordinates.installDir !== null,
107
- code: "not_configured",
108
- detail: coordinates.installDir ?? "GHIDRA_INSTALL_DIR is not set",
109
- remediation: `Set GHIDRA_INSTALL_DIR to an extracted Ghidra ${ghidraReleaseLine()} release directory.`,
110
- }),
178
+ configurationCheck(coordinates.installDir, javaHome, platform),
111
179
  installationCheck({
112
180
  name: "platform",
113
181
  passed: NATIVE_PLATFORMS[platform] !== undefined,
@@ -139,16 +207,38 @@ const installationChecks = ({ coordinates, platform, architecture, javaHome, hos
139
207
  detail: coordinates.analyzeHeadlessPath ?? "analyzeHeadless unavailable",
140
208
  remediation: "Restore support/analyzeHeadless or support/analyzeHeadless.bat from the official Ghidra release.",
141
209
  }),
142
- installationCheck({
143
- name: "native_decompiler",
144
- passed: coordinates.nativeDecompilerPath !== null,
145
- code: "executable_missing",
146
- detail: coordinates.nativeDecompilerPath ??
147
- `Matching native decompiler for ${platform}/${architecture} was not found`,
148
- remediation: `Provide an executable Ghidra/Features/Decompiler/os/${NATIVE_PLATFORMS[platform]?.[architecture] ?? "<platform>"}/${platform === "win32" ? "decompile.exe" : "decompile"}, or its build/os equivalent. REA does not build or install native tools.`,
149
- }),
210
+ nativeDecompilerCheck({ coordinates, platform, architecture, host }),
150
211
  javaCheck(coordinates.java, coordinates.javaCommand, javaHome, coordinates.properties),
151
212
  ];
213
+ /**
214
+ * REA's configuration parser, and so the MCP server and analysis, accept only
215
+ * absolute paths; a relative one that happens to resolve here must not pass.
216
+ */
217
+ const configurationCheck = (installDir, javaHome, platform) => {
218
+ const { isAbsolute } = platform === "win32" ? win32 : posix;
219
+ const relative = [
220
+ ...(installDir !== null && !isAbsolute(installDir)
221
+ ? ["GHIDRA_INSTALL_DIR"]
222
+ : []),
223
+ ...(javaHome !== undefined && !isAbsolute(javaHome) ? ["JAVA_HOME"] : []),
224
+ ];
225
+ if (installDir === null || relative.length === 0)
226
+ return installationCheck({
227
+ name: "configuration",
228
+ passed: installDir !== null,
229
+ code: "not_configured",
230
+ detail: installDir ?? "GHIDRA_INSTALL_DIR is not set",
231
+ remediation: `Set GHIDRA_INSTALL_DIR to an extracted Ghidra ${ghidraReleaseLine()} release directory.`,
232
+ });
233
+ const settings = relative.join(" and ");
234
+ return installationCheck({
235
+ name: "configuration",
236
+ passed: false,
237
+ code: "not_configured",
238
+ detail: `${settings} must be absolute`,
239
+ remediation: `Set ${settings} to ${relative.length === 1 ? "an absolute path" : "absolute paths"}. REA's analysis and MCP server reject relative paths even when they resolve from the current directory.`,
240
+ });
241
+ };
152
242
  /** Project an installation probe into caller-visible, secret-free diagnostics. */
153
243
  export const ghidraInstallationDiagnostics = (inspection) => ({
154
244
  install_dir: inspection.installDir,
@@ -169,9 +259,10 @@ export const ghidraInstallationDiagnostics = (inspection) => ({
169
259
  })),
170
260
  });
171
261
  /** Environment that makes an explicitly selected JDK win over PATH discovery. */
172
- export const ghidraJavaEnvironment = (javaHome, environment = process.env, platform = process.platform) => {
262
+ export const ghidraJavaEnvironment = (javaHome, environment, platform = process.platform) => {
263
+ const selectedEnvironment = snapshotEnvironment(environment, platform);
173
264
  const boundedEnvironment = {
174
- ...environment,
265
+ ...selectedEnvironment,
175
266
  _JAVA_OPTIONS: "",
176
267
  JAVA_TOOL_OPTIONS: "",
177
268
  JDK_JAVA_OPTIONS: "",
@@ -182,7 +273,7 @@ export const ghidraJavaEnvironment = (javaHome, environment = process.env, platf
182
273
  : {
183
274
  ...boundedEnvironment,
184
275
  JAVA_HOME: javaHome,
185
- PATH: `${(platform === "win32" ? win32 : posix).join(javaHome, "bin")}${platform === "win32" ? win32.delimiter : posix.delimiter}${environment.PATH ?? ""}`,
276
+ PATH: `${(platform === "win32" ? win32 : posix).join(javaHome, "bin")}${platform === "win32" ? win32.delimiter : posix.delimiter}${selectedEnvironment.PATH ?? ""}`,
186
277
  };
187
278
  };
188
279
  const installationCheck = (options) => options.passed
@@ -198,6 +289,23 @@ const installationCheck = (options) => options.passed
198
289
  detail: options.detail,
199
290
  remediation: options.remediation,
200
291
  };
292
+ /** Require a present native decompiler without positively incompatible bytes. */
293
+ const nativeDecompilerCheck = ({ coordinates, platform, architecture, host, }) => {
294
+ const path = coordinates.nativeDecompilerPath;
295
+ const compatibility = path === null
296
+ ? undefined
297
+ : assessNativeDecompiler(path, platform, architecture, host.executableHeader?.(path));
298
+ return installationCheck({
299
+ name: "native_decompiler",
300
+ passed: path !== null && compatibility?.status !== "incompatible",
301
+ code: "executable_missing",
302
+ detail: compatibility?.detail ??
303
+ `Matching native decompiler for ${platform}/${architecture} was not found`,
304
+ remediation: compatibility?.status === "incompatible"
305
+ ? compatibility.remediation
306
+ : `Provide an executable Ghidra/Features/Decompiler/os/${NATIVE_PLATFORMS[platform]?.[architecture] ?? "<platform>"}/${platform === "win32" ? "decompile.exe" : "decompile"}, or its build/os equivalent. REA does not build or install native tools.`,
307
+ });
308
+ };
201
309
  const versionCheck = (properties) => {
202
310
  const raw = properties?.providerVersion;
203
311
  return installationCheck({
@@ -252,10 +360,31 @@ const systemGhidraInstallationHost = () => ({
252
360
  return undefined;
253
361
  }
254
362
  },
363
+ executableHeader(path) {
364
+ let handle;
365
+ try {
366
+ handle = openSync(path, constants.O_RDONLY | constants.O_NONBLOCK | constants.O_NOCTTY);
367
+ const metadata = fstatSync(handle);
368
+ if (!metadata.isFile())
369
+ return undefined;
370
+ const bytes = Buffer.alloc(EXECUTABLE_HEADER_PROBE_BYTES);
371
+ const read = readSync(handle, bytes, 0, bytes.length, 0);
372
+ return { bytes: bytes.subarray(0, read), size: metadata.size };
373
+ }
374
+ catch (cause) {
375
+ // best-effort cleanup: a header that cannot be read stays unknown.
376
+ void cause;
377
+ return undefined;
378
+ }
379
+ finally {
380
+ if (handle !== undefined)
381
+ closeSync(handle);
382
+ }
383
+ },
255
384
  executable(path) {
256
385
  try {
257
386
  accessSync(path, constants.X_OK);
258
- return true;
387
+ return statSync(path).isFile();
259
388
  }
260
389
  catch (cause) {
261
390
  // best-effort cleanup: optional executable probing; failure means missing.