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
@@ -1,10 +1,11 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { execFile } from "node:child_process";
3
3
  import { access, mkdir, mkdtemp, readdir, rename, rm, writeFile, } from "node:fs/promises";
4
- import { homedir, tmpdir } from "node:os";
4
+ import { tmpdir } from "node:os";
5
5
  import { join } from "node:path";
6
6
  import { promisify } from "node:util";
7
7
  import { z } from "zod";
8
+ import { homeDirectoryFromEnvironment } from "../config/homeDirectory.js";
8
9
  const execFileAsync = promisify(execFile);
9
10
  const RELEASES_URL = "https://www.hopperapp.com/include/files-api.php?request=releases&public=true";
10
11
  const DOWNLOAD_PREFIX = "https://www.hopperapp.com:443/downloader/public/";
@@ -21,7 +22,7 @@ export const macHopperInstallDisclosure = {
21
22
  ],
22
23
  };
23
24
  /** Download, verify, and install Hopper into the current user's Applications directory. */
24
- export const installMacHopper = async (options = {}, host = systemMacHopperInstallHost()) => {
25
+ export const installMacHopper = async (options = {}, host = systemMacHopperInstallHost(homeDirectoryFromEnvironment(process.env, process.platform), process.env)) => {
25
26
  let temporary;
26
27
  let mounted = false;
27
28
  try {
@@ -77,7 +78,8 @@ export const installMacHopper = async (options = {}, host = systemMacHopperInsta
77
78
  }
78
79
  }
79
80
  };
80
- const systemMacHopperInstallHost = () => ({
81
+ /** Compose installer paths and subprocesses from one selected caller context. */
82
+ export const systemMacHopperInstallHost = (homeDirectory, environment) => ({
81
83
  download: downloadPackage,
82
84
  createTemporaryDirectory: () => mkdtemp(join(tmpdir(), "rea-hopper-mac-")),
83
85
  createMountDirectory: (path) => mkdir(path),
@@ -90,10 +92,10 @@ const systemMacHopperInstallHost = () => ({
90
92
  "-mountpoint",
91
93
  mountPath,
92
94
  packagePath,
93
- ]);
95
+ ], environment);
94
96
  },
95
97
  async unmount(mountPath) {
96
- await commandSucceeds("hdiutil", ["detach", mountPath, "-force"]);
98
+ await commandSucceeds("hdiutil", ["detach", mountPath, "-force"], environment);
97
99
  },
98
100
  async appBundle(mountPath) {
99
101
  const entries = await readdir(mountPath, { withFileTypes: true });
@@ -101,19 +103,14 @@ const systemMacHopperInstallHost = () => ({
101
103
  return app === undefined ? undefined : join(mountPath, app.name);
102
104
  },
103
105
  async validBundle(appPath) {
104
- if (!(await commandSucceeds("codesign", [
105
- "--verify",
106
- "--deep",
107
- "--strict",
108
- appPath,
109
- ])))
106
+ if (!(await commandSucceeds("codesign", ["--verify", "--deep", "--strict", appPath], environment)))
110
107
  return false;
111
108
  try {
112
109
  const identifier = (await execFileAsync("/usr/libexec/PlistBuddy", [
113
110
  "-c",
114
111
  "Print :CFBundleIdentifier",
115
112
  join(appPath, "Contents/Info.plist"),
116
- ])).stdout.trim();
113
+ ], { env: environment })).stdout.trim();
117
114
  return identifier === BUNDLE_IDENTIFIER;
118
115
  }
119
116
  catch (cause) {
@@ -136,10 +133,10 @@ const systemMacHopperInstallHost = () => ({
136
133
  async installBundle(source, destination, stage, replaceExisting) {
137
134
  const previous = `${stage}-previous`;
138
135
  try {
139
- await mkdir(join(homedir(), "Applications"), { recursive: true });
136
+ await mkdir(join(homeDirectory, "Applications"), { recursive: true });
140
137
  await rm(stage, { recursive: true, force: true });
141
138
  await rm(previous, { recursive: true, force: true });
142
- await execFileAsync("ditto", [source, stage]);
139
+ await execFileAsync("ditto", [source, stage], { env: environment });
143
140
  await access(join(stage, "Contents/MacOS/hopper"));
144
141
  if (replaceExisting)
145
142
  await rename(destination, previous);
@@ -176,10 +173,10 @@ const systemMacHopperInstallHost = () => ({
176
173
  }
177
174
  },
178
175
  async openApplication(path) {
179
- await execFileAsync("open", [path]);
176
+ await execFileAsync("open", [path], { env: environment });
180
177
  },
181
178
  cleanup: (path) => rm(path, { recursive: true, force: true }),
182
- destination: () => join(homedir(), "Applications/Hopper Disassembler.app"),
179
+ destination: () => join(homeDirectory, "Applications/Hopper Disassembler.app"),
183
180
  });
184
181
  const downloadPackage = async (url) => {
185
182
  const response = await fetch(url, {
@@ -196,9 +193,9 @@ const parseJson = (bytes) => JSON.parse(new TextDecoder().decode(bytes));
196
193
  const integrityMatches = (bytes, release) => bytes.byteLength === Number(release.file_length) &&
197
194
  bytes.byteLength <= MAX_PACKAGE_BYTES &&
198
195
  createHash("sha1").update(bytes).digest("hex") === release.file_hash;
199
- const commandSucceeds = async (command, args) => {
196
+ const commandSucceeds = async (command, args, environment) => {
200
197
  try {
201
- await execFileAsync(command, args);
198
+ await execFileAsync(command, args, { env: environment });
202
199
  return true;
203
200
  }
204
201
  catch (cause) {
@@ -11,17 +11,6 @@ export const firstProcedureAddress = (input) => {
11
11
  throw new TypeError("Procedure inventory was empty");
12
12
  return first.address;
13
13
  };
14
- /** Reject two target paths that resolve to the same binary content. */
15
- export const requireDistinctTargetHashes = (firstHash, secondHash) => {
16
- if (typeof firstHash !== "string" ||
17
- typeof secondHash !== "string" ||
18
- firstHash.length === 0 ||
19
- secondHash.length === 0) {
20
- throw new TypeError("Target hashes must be non-empty strings");
21
- }
22
- if (firstHash === secondHash)
23
- throw new TypeError("Real-Hopper verification requires distinct binaries");
24
- };
25
14
  /** Reject empty and success-shaped embedded decompilation failures. */
26
15
  export const requirePseudocode = (input, operation) => {
27
16
  if (typeof input !== "string" || input.trim().length === 0)
@@ -1,7 +1,8 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import canonicalize from "canonicalize";
3
3
  import { parseEvidenceBundle, } from "../domain/evidenceBundle.js";
4
- import { parseProcessCapture } from "../domain/process/processCapture.js";
4
+ import { parseProcessCapture } from "../domain/process/processCaptureParsing.js";
5
+ import { resolveJavaScriptSemanticEvidence } from "../domain/javascript/javascriptSemanticGraph.js";
5
6
  import { parseApplicationGraphEvidence } from "./javascript/JavaScriptApplicationEvidenceGraph.js";
6
7
  import { applicationObligationPolicy, semanticObligationPolicy, } from "./ReconstructionObligationPolicies.js";
7
8
  /** Derive conservative candidates from graph, process, and reviewed inputs. */
@@ -29,7 +30,12 @@ const deriveApplicationCandidates = (evidence, records, candidates, limitations)
29
30
  ].includes(evidence.operation))
30
31
  return;
31
32
  try {
32
- const source = parseApplicationGraphEvidence(evidence);
33
+ const parsed = parseApplicationGraphEvidence(evidence);
34
+ if (!parsed.ok) {
35
+ limitations.add(`Application Evidence ${evidence.evidence_id} could not generate candidates because it failed graph validation.`);
36
+ return;
37
+ }
38
+ const source = parsed.value;
33
39
  for (const node of source.graph.nodes) {
34
40
  const candidatePolicy = applicationObligationPolicy(node.kind);
35
41
  if (candidatePolicy === undefined) {
@@ -54,6 +60,7 @@ const deriveApplicationCandidates = (evidence, records, candidates, limitations)
54
60
  const candidatePolicy = semanticObligationPolicy(node.kind);
55
61
  if (candidatePolicy === undefined)
56
62
  continue;
63
+ const evidenceContext = resolveJavaScriptSemanticEvidence(source.semanticGraph, node.evidence);
57
64
  addCandidate(candidates, generatedCandidate({
58
65
  key: `semantic:${node.node_id}:${candidatePolicy.family}`,
59
66
  title: node.label ?? `${node.kind} semantic boundary`,
@@ -63,7 +70,7 @@ const deriveApplicationCandidates = (evidence, records, candidates, limitations)
63
70
  semanticNodeId: node.node_id,
64
71
  location: `semantic-graph:${source.semanticGraph.graph_id}/nodes/${node.node_id}`,
65
72
  authorityReferences: [
66
- graphReference(evidence, records, node.evidence, `${source.semanticGraph.graph_id}/node/${node.node_id}`),
73
+ graphReference(evidence, records, evidenceContext, `${source.semanticGraph.graph_id}/node/${node.node_id}`),
67
74
  ],
68
75
  }));
69
76
  }
@@ -1,5 +1,7 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import canonicalize from "canonicalize";
3
+ import { canonicalJson } from "../domain/comparisonSemantics.js";
4
+ import { compareUnicodeCodePoints } from "../domain/unicodeCodePointOrder.js";
3
5
  export const obligationLedgerCoverage = (incomplete) => ({
4
6
  status: incomplete ? "partial" : "complete",
5
7
  });
@@ -64,7 +66,7 @@ export const obligationLedgerStatus = (obligations) => {
64
66
  return "unknown";
65
67
  return requiredOpen.length === 0 ? "ready" : "open";
66
68
  };
67
- export const obligationEdgeOrder = (left, right) => JSON.stringify(left).localeCompare(JSON.stringify(right));
69
+ export const obligationEdgeOrder = (left, right) => compareUnicodeCodePoints(canonicalJson(left), canonicalJson(right));
68
70
  export const digestObligationLedgerValue = (value) => {
69
71
  const encoded = canonicalize(value);
70
72
  if (encoded === undefined)
@@ -32,7 +32,7 @@ const failedEntry = (entry) => {
32
32
  return {
33
33
  path: entry.path,
34
34
  kind: "symlink",
35
- target: "<unreadable>",
35
+ target: null,
36
36
  target_state: "unreadable",
37
37
  classifications,
38
38
  limitations: [limitation],
@@ -0,0 +1,17 @@
1
+ import { openRegularFile } from "../filesystem/RegularFile.js";
2
+ /** Admit one regular-file handle, retain it through the consumer, and always close it. */
3
+ export const withRegularFile = async (path, read, signal) => {
4
+ const handle = await openRegularFile(path, { symlinks: "follow", signal });
5
+ try {
6
+ const stats = await handle.stat();
7
+ signal?.throwIfAborted();
8
+ const value = await read(handle, stats);
9
+ signal?.throwIfAborted();
10
+ return value;
11
+ }
12
+ finally {
13
+ await handle.close();
14
+ }
15
+ };
16
+ /** Admit a regular file without waiting for a pipe, then read its verified handle. */
17
+ export const readRegularFile = (path, signal) => withRegularFile(path, (handle) => handle.readFile({ signal }), signal);
@@ -1,7 +1,7 @@
1
1
  import { manualRegistrationRemediation, } from "./SupportedClients.js";
2
2
  import { configureDetectedClients } from "./SetupClients.js";
3
3
  import { discoverSetupState, planSetupActions } from "./SetupPlan.js";
4
- import { filterClientsNeedingConfigure, hostRemediation, initialProviderEnvironment, setupRegistrationCommand, systemSetupHost, } from "./SetupHost.js";
4
+ import { filterClientsNeedingConfigure, hostRemediation, systemSetupHost, } from "./SetupHost.js";
5
5
  /** Discover, approve, and apply setup actions idempotently. */
6
6
  export const runSetup = async (options, host = systemSetupHost(), confirm) => {
7
7
  const appliedActions = [];
@@ -13,22 +13,14 @@ export const runSetup = async (options, host = systemSetupHost(), confirm) => {
13
13
  const unsupported = await hostRemediation(host, false);
14
14
  if (unsupported !== undefined)
15
15
  return fail(unsupported);
16
- const initialState = await host.initialSetupState?.(options.readinessScope);
17
- let hopperPath = initialState === undefined
18
- ? await host.hopperPath()
19
- : initialState.hopperPath;
20
- let providerEnvironment = initialState === undefined
21
- ? await initialProviderEnvironment(host, hopperPath)
22
- : initialState.providerEnvironment;
16
+ const initialState = await host.initialSetupState(options.readinessScope);
17
+ let { hopperPath, providerEnvironment } = initialState;
23
18
  const discovery = await discoverSetupState({
24
19
  host,
25
20
  providerEnvironment,
26
21
  forceHopperInstall: options.installHopper,
27
22
  proposeHopper: options.proposeHopper ?? (confirm !== undefined && !options.structured),
28
- doctorScope: options.readinessScope,
29
- ...(initialState === undefined
30
- ? {}
31
- : { initialDoctor: initialState.doctor }),
23
+ initialDoctor: initialState.doctor,
32
24
  });
33
25
  clientStates = discovery.clientStates;
34
26
  const clientSelectionAllowed = options.clientIds === undefined &&
@@ -42,18 +34,27 @@ export const runSetup = async (options, host = systemSetupHost(), confirm) => {
42
34
  : (options.clientIds ??
43
35
  options.readinessScope?.clients ??
44
36
  discovery.defaultClientIds);
37
+ let skillNeedsInstall = await host.skillNeedsInstall(selectedClientIds);
45
38
  let skillSelected = options.installSkill === true ||
46
39
  (options.installSkill !== false && selectedClientIds.length > 0);
47
- let installSkill = skillSelected && discovery.skillNeedsInstall;
40
+ let installSkill = skillSelected && skillNeedsInstall;
48
41
  let planDiscovery = discovery;
49
42
  if (interactiveSelection) {
50
- const offerSkillAction = options.installSkill !== false && discovery.skillNeedsInstall;
43
+ const selectionSkillClientIds = [
44
+ ...new Set([
45
+ ...discovery.defaultClientIds,
46
+ ...discovery.detectedClientIds,
47
+ ]),
48
+ ];
49
+ const selectionSkillNeedsInstall = await host.skillNeedsInstall(selectionSkillClientIds);
50
+ const offerSkillAction = options.installSkill !== false && selectionSkillNeedsInstall;
51
51
  const selectionActions = await planSetupActions({
52
52
  discovery,
53
53
  host,
54
54
  providerEnvironment,
55
- command: setupRegistrationCommand(host.platform),
55
+ command: host.registrationCommand,
56
56
  clientIds: [],
57
+ skillClientIds: selectionSkillClientIds,
57
58
  installSkill: offerSkillAction,
58
59
  });
59
60
  const decision = await confirm(selectionActions.plannedActions, {
@@ -75,6 +76,7 @@ export const runSetup = async (options, host = systemSetupHost(), confirm) => {
75
76
  selectedClientIds = [...selectedActionIds]
76
77
  .filter((id) => id.startsWith("configure_client:"))
77
78
  .map((id) => id.slice("configure_client:".length));
79
+ skillNeedsInstall = await host.skillNeedsInstall(selectedClientIds);
78
80
  const proposedInstallAction = selectionActions.plannedActions.some(({ id }) => id === "install_hopper");
79
81
  planDiscovery = {
80
82
  ...discovery,
@@ -86,14 +88,15 @@ export const runSetup = async (options, host = systemSetupHost(), confirm) => {
86
88
  (selectedActionIds.has("install_skill") &&
87
89
  selectedClientIds.length === 0) ||
88
90
  (options.installSkill !== false && selectedClientIds.length > 0);
89
- installSkill = skillSelected && discovery.skillNeedsInstall;
91
+ installSkill = skillSelected && skillNeedsInstall;
90
92
  }
91
93
  const planned = await planSetupActions({
92
94
  discovery: planDiscovery,
93
95
  host,
94
96
  providerEnvironment,
95
- command: setupRegistrationCommand(host.platform),
97
+ command: host.registrationCommand,
96
98
  clientIds: selectedClientIds,
99
+ skillClientIds: selectedClientIds,
97
100
  installSkill,
98
101
  });
99
102
  plannedActions = planned.plannedActions;
@@ -175,7 +178,7 @@ export const runSetup = async (options, host = systemSetupHost(), confirm) => {
175
178
  host,
176
179
  detectedClients: selectedClients,
177
180
  providerEnvironment,
178
- command: setupRegistrationCommand(host.platform),
181
+ command: host.registrationCommand,
179
182
  clients,
180
183
  appliedActions,
181
184
  ...(options.onProgress === undefined
@@ -185,8 +188,8 @@ export const runSetup = async (options, host = systemSetupHost(), confirm) => {
185
188
  if (clientFailure !== undefined)
186
189
  return fail(clientFailure);
187
190
  if (planSelection.installSkill &&
188
- !(await installSkillAction(host, options, appliedActions)))
189
- return fail("REA analysis skill could not be installed or verified. Check permissions for `~/.agents/skills`, then rerun setup.");
191
+ !(await installSkillAction(host, options, appliedActions, selectedClientIds)))
192
+ return fail("REA analysis skill could not be installed or verified. Check permissions for its planned skill directories, then rerun setup.");
190
193
  const doctor = summarizeDoctor(await host.doctor(readinessScope));
191
194
  const remediation = combineRemediation(finalSetupRemediation(host.platform, appliedActions.includes("installed_hopper"), doctor.healthy, hopperPath), manualRemediation);
192
195
  return {
@@ -241,17 +244,17 @@ const installHopperAction = async (input) => {
241
244
  return {
242
245
  hopperPath: installed.launcherPath,
243
246
  providerEnvironment,
244
- selectedClients: await filterClientsNeedingConfigure(input.host, input.selectedClients, providerEnvironment, setupRegistrationCommand(input.host.platform)),
247
+ selectedClients: await filterClientsNeedingConfigure(input.host, input.selectedClients, providerEnvironment, input.host.registrationCommand),
245
248
  };
246
249
  };
247
- const installSkillAction = async (host, options, appliedActions) => {
250
+ const installSkillAction = async (host, options, appliedActions, skillClientIds) => {
248
251
  const label = "REA reverse-engineering skill";
249
252
  emitProgress(options, {
250
253
  actionId: "install_skill",
251
254
  label,
252
255
  state: "started",
253
256
  });
254
- const skill = await host.installSkill();
257
+ const skill = await host.installSkill(skillClientIds);
255
258
  if (skill === "failed") {
256
259
  emitProgress(options, {
257
260
  actionId: "install_skill",
@@ -1,4 +1,4 @@
1
- import { clientRegistrationEntry, clientConfigurationValuesEqual, clientServerPath, grokServerListedDisabled, legacyClientServerPath, parseClientConfiguration, serializeClientConfiguration, withClientServers, } from "./ClientConfigurationDocument.js";
1
+ import { clientRegistrationEntry, clientConfigurationValuesEqual, clientServerListedDisabled, clientServerPath, legacyClientServerPath, OMP_DISABLED_SERVERS_KEY, parseClientConfiguration, serializeClientConfiguration, withClientServers, } from "./ClientConfigurationDocument.js";
2
2
  import { constants as fsConstants } from "node:fs";
3
3
  import { copyFile, mkdir, readFile, rm, writeFile } from "node:fs/promises";
4
4
  import { dirname } from "node:path";
@@ -7,9 +7,8 @@ import { PRODUCT_IDENTITY } from "../identity.js";
7
7
  import { npxRegistrationCommand } from "./ClientRegistrationIdentity.js";
8
8
  import { MCP_STARTUP_POLICY } from "../mcpStartupPolicy.js";
9
9
  import { resolveClientConfigTransactionPath } from "./ClientConfigPath.js";
10
- const defaultCommand = () => npxRegistrationCommand();
11
10
  /** Configure one supported client's native stdio MCP registration shape. */
12
- export const configureClientConfiguration = (client, environment = {}, command = defaultCommand()) => {
11
+ export const configureClientConfiguration = (client, environment = {}, command = npxRegistrationCommand()) => {
13
12
  if (client.format === undefined || client.format === "unsupported")
14
13
  return Promise.resolve({ status: "failed", reason: "readback" });
15
14
  return configureClientDocument(client, environment, command, client.format);
@@ -45,12 +44,25 @@ const configureClientDocument = async (client, environment, command, format) =>
45
44
  // A native OpenCode V2 entry replaces REA's legacy V1 entry, which would
46
45
  // otherwise conflict with it.
47
46
  const legacyPath = legacyClientServerPath(parsed, PRODUCT_IDENTITY.mcpServerKey);
48
- const document = withClientServers(parsed, { ...parsed.servers, [PRODUCT_IDENTITY.mcpServerKey]: desired }, PRODUCT_IDENTITY.mcpServerKey);
47
+ const registered = withClientServers(parsed, { ...parsed.servers, [PRODUCT_IDENTITY.mcpServerKey]: desired }, PRODUCT_IDENTITY.mcpServerKey);
48
+ // OMP's denylist would hide the registration; keep every other listed name.
49
+ const ompDisabled = parsed.dialect === "omp"
50
+ ? parsed.document[OMP_DISABLED_SERVERS_KEY]
51
+ : undefined;
52
+ const enableOmp = Array.isArray(ompDisabled) &&
53
+ ompDisabled.includes(PRODUCT_IDENTITY.mcpServerKey);
54
+ const document = enableOmp && Array.isArray(ompDisabled)
55
+ ? {
56
+ ...registered,
57
+ [OMP_DISABLED_SERVERS_KEY]: ompDisabled.filter((name) => name !== PRODUCT_IDENTITY.mcpServerKey),
58
+ }
59
+ : registered;
49
60
  try {
50
61
  await mkdir(dirname(client.configPath), { recursive: true });
51
62
  await writeFileAtomic(transactionPath, serializeClientConfiguration(document, format, original, [
52
63
  clientServerPath(parsed, PRODUCT_IDENTITY.mcpServerKey),
53
64
  ...(legacyPath === undefined ? [] : [legacyPath]),
65
+ ...(enableOmp ? [[OMP_DISABLED_SERVERS_KEY]] : []),
54
66
  ]), {
55
67
  encoding: "utf8",
56
68
  mode: 0o600,
@@ -155,11 +167,10 @@ const restoreConfig = async (path, original) => {
155
167
  void cause;
156
168
  }
157
169
  };
158
- /** Whether REA's entry matches, no legacy entry remains, and Grok is not suppressing it. */
170
+ /** Whether REA's entry matches, no legacy entry remains, and no client disable list suppresses it. */
159
171
  const registrationCurrent = (parsed, desired) => clientConfigurationValuesEqual(parsed.servers[PRODUCT_IDENTITY.mcpServerKey], desired) &&
160
172
  !Object.hasOwn(parsed.legacyServers, PRODUCT_IDENTITY.mcpServerKey) &&
161
- !(parsed.dialect === "grok" &&
162
- grokServerListedDisabled(parsed.document, PRODUCT_IDENTITY.mcpServerKey));
173
+ !clientServerListedDisabled(parsed, PRODUCT_IDENTITY.mcpServerKey);
163
174
  const clientConfigurationDesired = (client, providerEnvironment, command, format) => {
164
175
  const environment = Object.fromEntries(Object.entries(providerEnvironment).sort(([left], [right]) => left.localeCompare(right)));
165
176
  const registration = clientRegistrationEntry(format ?? "json", command.length === 0 ? [PRODUCT_IDENTITY.cliBinary, "mcp"] : command, environment);
@@ -1,19 +1,18 @@
1
1
  import { access } from "node:fs/promises";
2
- import { homedir } from "node:os";
3
2
  import { resolve } from "node:path";
4
3
  import { PRODUCT_IDENTITY } from "../identity.js";
5
4
  import { npxRegistrationCommand } from "./ClientRegistrationIdentity.js";
6
5
  import { SUPPORTED_NODE_VERSION_PROSE, supportsNodeVersion, } from "../domain/runtimeVersion.js";
7
6
  import { runDoctor, systemDoctorHost } from "./Doctor.js";
8
- import { installLinuxHopper, readLinuxDistribution } from "./LinuxHopper.js";
9
- import { installMacHopper } from "./MacHopper.js";
7
+ import { installLinuxHopper, readLinuxDistribution, systemLinuxHopperInstallHost, } from "./LinuxHopper.js";
8
+ import { installMacHopper, systemMacHopperInstallHost } from "./MacHopper.js";
10
9
  import { supportedClients } from "./SupportedClients.js";
11
- import { canonicalSkillNeedsInstall, installCanonicalSkill, } from "./SetupSkill.js";
10
+ import { claudeCodeSkillsDirectory as resolveClaudeCodeSkillsDirectory, canonicalSkillNeedsInstall, installCanonicalSkill, } from "./SetupSkill.js";
12
11
  import { clientConfigurationAligned, configureClientConfiguration, inspectClientConfiguration, } from "./SetupClientConfiguration.js";
13
12
  import { setupInstallFailure } from "./SetupInstallFailure.js";
14
13
  import { providerRegistrationEnvironment } from "./SetupRegistrationEnvironment.js";
15
14
  /** Resolve the executable and arguments used in a managed MCP registration. */
16
- export const setupRegistrationCommand = (platform, useNpmRunner = process.env.npm_command === "exec") => useNpmRunner
15
+ export const setupRegistrationCommand = (platform, useNpmRunner) => useNpmRunner
17
16
  ? npxRegistrationCommand(platform)
18
17
  : platform === "win32"
19
18
  ? [
@@ -26,10 +25,6 @@ export const filterClientsNeedingConfigure = async (host, detectedClients, provi
26
25
  const needs = await Promise.all(detectedClients.map((client) => host.clientNeedsConfigure(client, providerEnvironment, command)));
27
26
  return detectedClients.filter((_, index) => needs[index]);
28
27
  };
29
- export const initialProviderEnvironment = async (host, hopperPath) => ({
30
- ...(await host.providerEnvironment?.()),
31
- ...(hopperPath === undefined ? {} : { HOPPER_LAUNCHER_PATH: hopperPath }),
32
- });
33
28
  export const hostRemediation = async (host, installHopper) => {
34
29
  if (!supportsNodeVersion(host.nodeVersion))
35
30
  return `Install ${SUPPORTED_NODE_VERSION_PROSE} and rerun setup.`;
@@ -45,17 +40,22 @@ export const hostRemediation = async (host, installHopper) => {
45
40
  }
46
41
  if ((await host.linuxDistribution())?.supported === true)
47
42
  return undefined;
48
- return "Automated Hopper setup supports Ubuntu 24.04+, Fedora 41+, 64-bit Arch Linux, and CachyOS; configure an existing supported provider instead.";
43
+ return "Automated Hopper setup supports Ubuntu 24.04+, Fedora 41+, Nobara 44+, 64-bit Arch Linux, and CachyOS; configure an existing supported provider instead.";
49
44
  };
50
45
  /** Production setup effects for Hopper, agent configuration, and the canonical skill directory. */
51
- export const systemSetupHost = (doctorHost = systemDoctorHost()) => {
46
+ export const systemSetupHost = (selectedDoctorHost = undefined, environment = process.env) => {
47
+ const doctorHost = selectedDoctorHost ?? systemDoctorHost({ environment });
52
48
  const platform = doctorHost.platform;
49
+ const { homeDirectory } = doctorHost;
50
+ const claudeSkillsDirectory = resolveClaudeCodeSkillsDirectory(homeDirectory, environment);
53
51
  return {
54
52
  platform,
53
+ homeDirectory,
54
+ claudeCodeSkillsDirectory: claudeSkillsDirectory,
55
+ registrationCommand: setupRegistrationCommand(platform, environment.npm_command === "exec"),
55
56
  nodeVersion: process.versions.node,
56
57
  macosVersion: () => doctorHost.macosVersion(),
57
58
  linuxDistribution: readLinuxDistribution,
58
- hopperPath: async () => (await runDoctor(undefined, doctorHost)).hopperPath,
59
59
  initialSetupState: async (scope) => {
60
60
  const diagnosis = await runDoctor(undefined, doctorHost, scope);
61
61
  return {
@@ -71,25 +71,16 @@ export const systemSetupHost = (doctorHost = systemDoctorHost()) => {
71
71
  doctor: diagnosis,
72
72
  };
73
73
  },
74
- providerEnvironment: async () => {
75
- const diagnosis = await runDoctor(undefined, doctorHost);
76
- return {
77
- ...providerRegistrationEnvironment(diagnosis.providerInspections ?? []),
78
- ...(diagnosis.hopperPath === undefined
79
- ? {}
80
- : { HOPPER_LAUNCHER_PATH: diagnosis.hopperPath }),
81
- };
82
- },
83
74
  installHopper: async (replaceExisting) => {
84
75
  const result = platform === "linux"
85
- ? await installLinuxHopper()
86
- : await installMacHopper({ replaceExisting });
76
+ ? await installLinuxHopper(systemLinuxHopperInstallHost(environment))
77
+ : await installMacHopper({ replaceExisting }, systemMacHopperInstallHost(homeDirectory, environment));
87
78
  if (result.status === "installed")
88
79
  return result;
89
80
  return setupInstallFailure(result.reason);
90
81
  },
91
- detectedClients: () => detectClients(homedir()),
92
- supportedClients: () => Promise.resolve(supportedClients(homedir())),
82
+ detectedClients: () => detectClients(homeDirectory, platform, environment),
83
+ supportedClients: () => Promise.resolve(supportedClients(homeDirectory, platform, environment)),
93
84
  configureClient: (client, providerEnvironment, command) => client.format === "unsupported"
94
85
  ? Promise.resolve({ status: "skipped" })
95
86
  : configureClientConfiguration(client, providerEnvironment, command),
@@ -97,15 +88,15 @@ export const systemSetupHost = (doctorHost = systemDoctorHost()) => {
97
88
  ? Promise.resolve(false)
98
89
  : clientConfigurationAligned(client, providerEnvironment, command).then((aligned) => !aligned),
99
90
  inspectClientConfiguration: inspectClientConfiguration,
100
- skillNeedsInstall: () => canonicalSkillNeedsInstall(homedir()),
101
- installSkill: () => installCanonicalSkill(homedir()),
91
+ skillNeedsInstall: (clientIds) => canonicalSkillNeedsInstall(homeDirectory, clientIds, claudeSkillsDirectory),
92
+ installSkill: (clientIds) => installCanonicalSkill(homeDirectory, clientIds, claudeSkillsDirectory),
102
93
  doctor: (scope) => runDoctor(undefined, doctorHost, scope),
103
94
  };
104
95
  };
105
96
  /** Detect supported agents from their config files or stable installation markers. */
106
- export const detectClients = async (home) => {
97
+ export const detectClients = async (home, platform = process.platform, environment = process.env) => {
107
98
  const detected = [];
108
- for (const candidate of supportedClients(home)) {
99
+ for (const candidate of supportedClients(home, platform, environment)) {
109
100
  const [hasConfig, hasMarker] = await Promise.all([
110
101
  exists(candidate.configPath),
111
102
  candidate.markerPath === undefined ? false : exists(candidate.markerPath),
@@ -1,12 +1,11 @@
1
- import { homedir } from "node:os";
2
1
  import { join } from "node:path";
3
- import { PRODUCT_IDENTITY } from "../identity.js";
4
2
  import { isOwnedClientRegistrationCommand } from "./ClientRegistrationIdentity.js";
5
3
  import { linuxHopperInstallDisclosure, } from "./LinuxHopper.js";
4
+ import { skillDestinations } from "./SetupSkill.js";
6
5
  import { macHopperInstallDisclosure } from "./MacHopper.js";
7
6
  /** Discover supported clients and current registrations without mutation. */
8
7
  export const discoverSetupState = async (input) => {
9
- const initialDoctor = input.initialDoctor ?? (await input.host.doctor(input.doctorScope));
8
+ const { initialDoctor } = input;
10
9
  const linuxHopperRepairNeeded = initialDoctor.checks.some(({ name, ok, detail }) => !ok &&
11
10
  (name === "hopper-demo-runtime" ||
12
11
  (name === "hopper-version" && detail === "/opt/hopper/bin/Hopper")));
@@ -21,10 +20,9 @@ export const discoverSetupState = async (input) => {
21
20
  input.proposeHopper &&
22
21
  (Object.keys(input.providerEnvironment).length === 0 ||
23
22
  linuxHopperRepairNeeded));
24
- const [clients, detectedClients, skillNeedsInstall] = await Promise.all([
25
- input.host.supportedClients?.() ?? input.host.detectedClients(),
23
+ const [clients, detectedClients] = await Promise.all([
24
+ input.host.supportedClients(),
26
25
  input.host.detectedClients(),
27
- input.host.skillNeedsInstall(),
28
26
  ]);
29
27
  const detectedIds = new Set(detectedClients.map(({ name }) => name));
30
28
  const registrations = initialDoctor.identity?.registrations ?? [];
@@ -57,7 +55,6 @@ export const discoverSetupState = async (input) => {
57
55
  return {
58
56
  initialDoctor,
59
57
  installHopper,
60
- skillNeedsInstall,
61
58
  clients,
62
59
  detectedClientIds: [...detectedIds],
63
60
  defaultClientIds,
@@ -85,7 +82,7 @@ export const planSetupActions = async (input) => {
85
82
  });
86
83
  const inspections = await Promise.all(selectedClients.map(async (client) => ({
87
84
  client,
88
- inspection: (await input.host.inspectClientConfiguration?.(client, input.providerEnvironment, input.command)) ?? { status: "update" },
85
+ inspection: await input.host.inspectClientConfiguration(client, input.providerEnvironment, input.command),
89
86
  })));
90
87
  const invalid = inspections.find(({ inspection }) => inspection.status === "invalid");
91
88
  if (invalid?.inspection.status === "invalid") {
@@ -117,8 +114,11 @@ export const planSetupActions = async (input) => {
117
114
  return {
118
115
  plannedActions: setupPlan({
119
116
  platform: input.host.platform,
117
+ homeDirectory: input.host.homeDirectory,
120
118
  installHopper: input.discovery.installHopper,
121
119
  installSkill: input.installSkill,
120
+ skillClientIds: input.skillClientIds,
121
+ claudeCodeSkillsDirectory: input.host.claudeCodeSkillsDirectory,
122
122
  clients: clientPlans,
123
123
  providerEnvironment: input.providerEnvironment,
124
124
  ...(input.discovery.linuxPackageFamily === undefined
@@ -139,7 +139,7 @@ const setupPlan = (input) => [
139
139
  kind: "install_hopper",
140
140
  label: "Hopper deep-analysis provider",
141
141
  target: input.platform === "darwin"
142
- ? join(homedir(), "Applications/Hopper Disassembler.app")
142
+ ? join(input.homeDirectory, "Applications/Hopper Disassembler.app")
143
143
  : "system package manager",
144
144
  detail: input.platform === "linux"
145
145
  ? "Download, verify, and install Hopper plus its Xvfb demo-session dependencies. For the supported demo build, REA uses a private display and selects Hopper's offered demo mode for each analysis session."
@@ -170,17 +170,21 @@ const setupPlan = (input) => [
170
170
  ...(backupPath === undefined ? {} : { backupPath }),
171
171
  })),
172
172
  ...(input.installSkill
173
- ? [
174
- {
175
- id: "install_skill",
176
- kind: "install_skill",
177
- label: "REA reverse-engineering skill",
178
- target: join(homedir(), ".agents/skills", PRODUCT_IDENTITY.skillName),
179
- detail: "Install or update the bundled REA reverse-engineering skill and on-demand references.",
180
- external: false,
181
- operation: "install",
182
- },
183
- ]
173
+ ? skillDestinations(input.homeDirectory, input.skillClientIds, input.claudeCodeSkillsDirectory).map(({ client, path }) => ({
174
+ id: client === "claude_code"
175
+ ? "install_skill:claude_code"
176
+ : "install_skill",
177
+ kind: "install_skill",
178
+ label: client === "claude_code"
179
+ ? "REA skill for Claude Code"
180
+ : "REA reverse-engineering skill",
181
+ target: path,
182
+ detail: client === "claude_code"
183
+ ? "Install or update the REA skill in Claude Code's personal skill directory."
184
+ : "Install or update the bundled REA reverse-engineering skill and on-demand references.",
185
+ external: false,
186
+ operation: "install",
187
+ }))
184
188
  : []),
185
189
  ];
186
190
  const linuxDisclosure = (family) => {