rea-agents 6.3.0 → 6.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (487) hide show
  1. package/README.md +7 -4
  2. package/bridge/ghidra/ReaGhidraApplySeeds.java +151 -0
  3. package/bridge/ghidra/ReaGhidraBridge.java +597 -209
  4. package/bridge/ghidra/ReaGhidraNoReturnFix.java +123 -0
  5. package/dist/adb/AdbConfiguration.js +88 -0
  6. package/dist/adb/AdbDeviceOutput.js +186 -0
  7. package/dist/adb/AdbProvider.js +1190 -0
  8. package/dist/adb/AdbShellOutput.js +309 -0
  9. package/dist/android/AndroidTargetSnapshot.js +104 -22
  10. package/dist/android/JadxConfiguration.js +44 -24
  11. package/dist/android/JadxProvider.js +51 -19
  12. package/dist/apktool/ApktoolConfiguration.js +84 -0
  13. package/dist/apktool/ApktoolDecodeOutput.js +59 -0
  14. package/dist/apktool/ApktoolProvider.js +506 -0
  15. package/dist/application/AnalysisProvider.js +8 -2
  16. package/dist/application/AppBundleExecutable.js +27 -22
  17. package/dist/application/BinaryTargetResolver.js +22 -2
  18. package/dist/application/CapabilityInventory.js +11 -1
  19. package/dist/application/ClientConfigurationDocument.js +70 -0
  20. package/dist/application/ClientConfigurationFiles.js +91 -0
  21. package/dist/application/ClientRegistrationEnvironment.js +35 -0
  22. package/dist/application/ClientRegistrationStatus.js +66 -31
  23. package/dist/application/DirectAnalysis.js +2 -2
  24. package/dist/application/DirectAnalysisCleanup.js +1 -1
  25. package/dist/application/DirectAnalysisStatus.js +1 -1
  26. package/dist/application/Doctor.js +5 -3
  27. package/dist/application/DoctorDiagnostics.js +1 -1
  28. package/dist/application/EvidenceBundleCommands.js +6 -12
  29. package/dist/application/GeminiClientSettings.js +139 -0
  30. package/dist/application/HermesClientHome.js +115 -0
  31. package/dist/application/HopperDownload.js +39 -0
  32. package/dist/application/InvestigationProviders.js +6 -0
  33. package/dist/application/JsonFiles.js +6 -5
  34. package/dist/{cliJsonFile.js → application/JsonInputFile.js} +108 -35
  35. package/dist/application/LinuxHopper.js +4 -12
  36. package/dist/application/MacHopper.js +172 -149
  37. package/dist/application/MipsElfAbiFlags.js +140 -0
  38. package/dist/application/ProviderOperationExecution.js +31 -0
  39. package/dist/application/ReconstructionObligationCandidates.js +9 -3
  40. package/dist/application/ReferenceSourceImport.js +76 -29
  41. package/dist/application/ReferenceSourceImportEntries.js +18 -9
  42. package/dist/application/ReferenceSourceImportPolicy.js +99 -23
  43. package/dist/application/ReferenceSourceImportTypes.js +30 -22
  44. package/dist/application/ReferenceSourceVcsAdapter.js +145 -30
  45. package/dist/application/RegularFileRead.js +93 -7
  46. package/dist/application/Setup.js +54 -6
  47. package/dist/application/SetupClientConfiguration.js +116 -16
  48. package/dist/application/SetupHost.js +102 -24
  49. package/dist/application/SetupPlan.js +5 -8
  50. package/dist/application/SetupSkill.js +58 -39
  51. package/dist/application/SupportedClients.js +290 -65
  52. package/dist/application/Uninstall.js +158 -10
  53. package/dist/application/UpdateMaintenance.js +17 -21
  54. package/dist/application/Utf8JsonInput.js +7 -0
  55. package/dist/application/WebScriptExportService.js +131 -65
  56. package/dist/application/WebSourceLocationService.js +3 -0
  57. package/dist/application/adb/AdbDeviceAnalysisPort.js +1 -0
  58. package/dist/application/adb/AdbDeviceAnalysisService.js +13 -0
  59. package/dist/application/analysisView/AnalysisViewService.js +40 -2
  60. package/dist/application/apktool/ApktoolResourceAnalysisPort.js +1 -0
  61. package/dist/application/apktool/ApktoolResourceAnalysisService.js +13 -0
  62. package/dist/application/binary/AnalysisClientCleanup.js +0 -24
  63. package/dist/application/binary/BinarySession.js +2 -1
  64. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +2 -1
  65. package/dist/application/binaryDiagnostics/PeResourcesPort.js +1 -0
  66. package/dist/application/binaryDiagnostics/PeResourcesService.js +111 -0
  67. package/dist/application/binaryDiagnostics/RecordedCrashService.js +2 -1
  68. package/dist/application/evm/EvmInterfaceService.js +3 -0
  69. package/dist/application/firmware/FirmwareAnalysisService.js +3 -0
  70. package/dist/application/investigation/InspectEvidenceBundle.js +18 -0
  71. package/dist/application/javascript/ElectronBoundaryGraphContext.js +3 -2
  72. package/dist/application/javascript/ElectronBoundaryGraphIpc.js +2 -2
  73. package/dist/application/javascript/ElectronBoundaryGraphNative.js +19 -6
  74. package/dist/application/javascript/ElectronBoundaryGraphWindows.js +3 -3
  75. package/dist/application/javascript/JavaScriptApplicationService.js +22 -11
  76. package/dist/application/javascript/JavaScriptApplicationWorkflowEvidence.js +5 -6
  77. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +171 -30
  78. package/dist/application/javascript/JavaScriptArtifactGraphAccumulator.js +14 -16
  79. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +67 -19
  80. package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +4 -3
  81. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +11 -5
  82. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +19 -16
  83. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +92 -10
  84. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +258 -235
  85. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +115 -26
  86. package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +4 -1
  87. package/dist/application/javascript/JavaScriptModuleRelationships.js +6 -4
  88. package/dist/application/javascript/JavaScriptRecoveryService.js +3 -0
  89. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +9 -3
  90. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +199 -61
  91. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +12 -19
  92. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +4 -1
  93. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +5 -3
  94. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +5 -3
  95. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +19 -8
  96. package/dist/application/jeb/JebAnalysisPort.js +1 -0
  97. package/dist/application/jeb/JebAnalysisService.js +13 -0
  98. package/dist/application/managed/ManagedApplicationGraphService.js +1 -1
  99. package/dist/application/native/NativeUiActionTrace.js +16 -8
  100. package/dist/application/native/NativeValueTrace.js +23 -6
  101. package/dist/application/process/ProcessCli.js +25 -20
  102. package/dist/artifacts/ArtifactPaths.js +129 -8
  103. package/dist/artifacts/ArtifactProvider.js +20 -15
  104. package/dist/artifacts/ArtifactReader.js +23 -0
  105. package/dist/artifacts/ArtifactResourceScope.js +100 -0
  106. package/dist/artifacts/AsarArtifactReader.js +176 -102
  107. package/dist/artifacts/AsarHeader.js +24 -0
  108. package/dist/artifacts/DirectoryArtifactReader.js +168 -65
  109. package/dist/artifacts/MachOSliceArtifactReader.js +116 -39
  110. package/dist/artifacts/NativeDmgArtifactReader.js +29 -22
  111. package/dist/artifacts/SafeOutputTree.js +245 -70
  112. package/dist/artifacts/SafeOutputTreeCleanup.js +45 -0
  113. package/dist/artifacts/SafeOutputTreeCreationFailure.js +20 -0
  114. package/dist/artifacts/SafeOutputTreeIdentity.js +42 -0
  115. package/dist/artifacts/SafeOutputTreeReadback.js +33 -0
  116. package/dist/artifacts/ZipArtifactReader.js +77 -27
  117. package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +58 -18
  118. package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +62 -24
  119. package/dist/artifacts/apple/KeyedArchiveReader.js +32 -13
  120. package/dist/artifacts/extraction/ArtifactExtraction.js +110 -86
  121. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +110 -43
  122. package/dist/artifacts/inventory/ArtifactInventory.js +5 -4
  123. package/dist/artifacts/inventory/classify.js +75 -32
  124. package/dist/artifacts/inventory/hashStableRootArtifact.js +48 -15
  125. package/dist/artifacts/inventory/reader.js +13 -5
  126. package/dist/artifacts/inventory/scanCanonical.js +62 -25
  127. package/dist/artifacts/inventory/scanReader.js +38 -11
  128. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +15 -9
  129. package/dist/artifacts/javascript/JavaScriptSourceAnalysis.js +3 -0
  130. package/dist/browser/BrowserScenarioPartialObservation.js +8 -2
  131. package/dist/browser/BrowserScenarioSecrets.js +52 -37
  132. package/dist/browser/CdpBrowserProvider.js +5 -0
  133. package/dist/browser/CdpCaptureDocuments.js +40 -6
  134. package/dist/browser/CdpCaptureDomSvg.js +210 -0
  135. package/dist/browser/CdpCaptureEventBodyShapes.js +4 -8
  136. package/dist/browser/CdpCaptureEventHandlers.js +26 -9
  137. package/dist/browser/CdpCaptureEvents.js +4 -9
  138. package/dist/browser/CdpConnection.js +22 -5
  139. package/dist/browser/CdpPageCapture.js +1 -1
  140. package/dist/browser/CdpTargetSession.js +30 -34
  141. package/dist/browser/CdpWebMcpDiscovery.js +32 -10
  142. package/dist/browser/ElectronFileScope.js +99 -9
  143. package/dist/browser/PlaywrightBrowserScenarioProvider.js +60 -4
  144. package/dist/browser/PlaywrightElectronActiveProvider.js +11 -6
  145. package/dist/browser/PlaywrightScenarioArtifacts.js +5 -5
  146. package/dist/browser/PlaywrightScenarioBrowser.js +69 -7
  147. package/dist/browser/PlaywrightScenarioSession.js +127 -54
  148. package/dist/browser/PlaywrightScenarioStorage.js +507 -0
  149. package/dist/browser/PngVisualDiff.js +198 -29
  150. package/dist/browser/WebSourceMapFetcher.js +3 -3
  151. package/dist/browser/assets/LocalWebScriptArtifacts.js +3 -1
  152. package/dist/browser/assets/PublishWebScripts.js +75 -20
  153. package/dist/browser/assets/WebArtifactReads.js +23 -1
  154. package/dist/browser/assets/WebSourceLocationArtifacts.js +1 -0
  155. package/dist/browser/execution/CdpExecutionCapture.js +3 -3
  156. package/dist/browser/execution/CdpPreciseCoverage.js +5 -8
  157. package/dist/browser/history/HarCapture.js +14 -0
  158. package/dist/browser/history/HarCaptureProcess.js +2 -10
  159. package/dist/browser/history/MitmproxyCaptureAdapter.js +3 -1
  160. package/dist/browser/modules/WebModuleArtifacts.js +1 -0
  161. package/dist/cli/adbCommands.js +337 -0
  162. package/dist/cli/analysisViewCommands.js +39 -1
  163. package/dist/cli/apktoolCommands.js +53 -0
  164. package/dist/cli/artifactCommands.js +8 -11
  165. package/dist/cli/binaryDiagnosticsCommands.js +19 -1
  166. package/dist/cli/browserAdvancedCommands.js +65 -36
  167. package/dist/cli/coreBinaryCommands.js +0 -5
  168. package/dist/cli/coreNativeCommands.js +1 -14
  169. package/dist/cli/electronCommands.js +6 -1
  170. package/dist/cli/evmCommands.js +13 -4
  171. package/dist/cli/firmwareCommands.js +7 -2
  172. package/dist/cli/javascriptApplicationAnalysis.js +17 -1
  173. package/dist/cli/javascriptRecoveryCommands.js +22 -15
  174. package/dist/cli/jebCommands.js +99 -0
  175. package/dist/cli/jsonOutput.js +11 -4
  176. package/dist/cli/referenceSourceImportStatus.js +7 -0
  177. package/dist/cli/setupCommands.js +15 -3
  178. package/dist/cli/utilityCommands.js +66 -18
  179. package/dist/cli/webScriptCommands.js +20 -1
  180. package/dist/cli/webSourceLocationCommands.js +21 -9
  181. package/dist/cli.js +6 -0
  182. package/dist/cliBrowserScenarioCommands.js +2 -1
  183. package/dist/cliCommandNames.js +32 -0
  184. package/dist/cliJsonInput.js +2 -2
  185. package/dist/cliObservationOptions.js +3 -0
  186. package/dist/composition/adb.js +3 -0
  187. package/dist/composition/apktool.js +3 -0
  188. package/dist/composition/binaryDiagnostics.js +4 -0
  189. package/dist/composition/directAnalysis.js +12 -4
  190. package/dist/composition/javascriptAnalysisWorkerProcess.js +48 -0
  191. package/dist/composition/jeb.js +6 -0
  192. package/dist/config/environment.js +10 -0
  193. package/dist/config/ghidraLanguageOverride.js +9 -0
  194. package/dist/config/mcpInputSchemaProfile.js +27 -0
  195. package/dist/config/parseConfig.js +28 -1
  196. package/dist/contracts/adb/adbToolContracts.js +353 -0
  197. package/dist/contracts/advertisedInputExamples.js +48 -0
  198. package/dist/contracts/analysisDetail.js +10 -0
  199. package/dist/contracts/analysisViewToolContracts.js +17 -2
  200. package/dist/contracts/apktool/apktoolToolContracts.js +33 -0
  201. package/dist/contracts/artifactToolContracts.js +8 -5
  202. package/dist/contracts/browserToolContracts.js +1 -1
  203. package/dist/contracts/compactInputSchema.js +256 -0
  204. package/dist/contracts/functionWorkflowToolContracts.js +1 -1
  205. package/dist/contracts/inputSchemaPresentation.js +10 -10
  206. package/dist/contracts/javascript/electronToolContracts.js +15 -3
  207. package/dist/contracts/javascript/javascriptRecoveryToolContracts.js +1 -1
  208. package/dist/contracts/jeb/jebToolContracts.js +64 -0
  209. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +25 -3
  210. package/dist/contracts/officialToolContracts.js +5 -5
  211. package/dist/contracts/sessionToolContracts.js +2 -2
  212. package/dist/contracts/sessionToolSchemas.js +6 -2
  213. package/dist/contracts/toolContractExamples.js +6 -0
  214. package/dist/contracts/toolContractTypes.js +3 -0
  215. package/dist/contracts/toolContracts.js +6 -0
  216. package/dist/contracts/toolEffects.js +167 -0
  217. package/dist/contracts/toolOutputSchemaGroups.js +5 -3
  218. package/dist/contracts/toolSchemaMetadata.js +82 -7
  219. package/dist/domain/adb/adbDeviceAnalysis.js +583 -0
  220. package/dist/domain/analysisErrorCleanup.js +29 -0
  221. package/dist/domain/analysisErrorPresentation.js +18 -6
  222. package/dist/domain/analysisErrorProjection.js +4 -1
  223. package/dist/domain/analysisSnapshot.js +2 -1
  224. package/dist/domain/analysisView/analysisView.js +52 -2
  225. package/dist/domain/analysisView/binaryLayoutView.js +2 -0
  226. package/dist/domain/analysisView/javascriptApplicationView.js +2 -0
  227. package/dist/domain/analysisView/nativeFunctionView.js +155 -0
  228. package/dist/domain/android/androidApplication.js +25 -20
  229. package/dist/domain/apktool/apktoolResourceAnalysis.js +77 -0
  230. package/dist/domain/apple/appleApplication.js +40 -23
  231. package/dist/domain/apple/appleBundleAnatomy.js +95 -28
  232. package/dist/domain/apple/dyldPaths.js +9 -1
  233. package/dist/domain/apple/dylibResolution.js +2 -2
  234. package/dist/domain/apple/interfaceBuilderGraph.js +22 -19
  235. package/dist/domain/apple/interfaceBuilderKeyedArchive.js +10 -1
  236. package/dist/domain/artifactComparison.js +35 -7
  237. package/dist/domain/artifactGraph.js +5 -3
  238. package/dist/domain/artifactIdentity.js +30 -2
  239. package/dist/domain/artifactInspection.js +3 -43
  240. package/dist/domain/artifactIntegrityPolicy.js +10 -0
  241. package/dist/domain/artifactInventoryEvidence.js +11 -12
  242. package/dist/domain/artifactPathSyntax.js +1 -1
  243. package/dist/domain/binaryTarget.js +16 -0
  244. package/dist/domain/binaryTargetTypes.js +8 -1
  245. package/dist/domain/browserObservationSchemas.js +8 -4
  246. package/dist/domain/canonicalJsonDigestSteps.js +34 -12
  247. package/dist/domain/compactStringIdentity.js +9 -0
  248. package/dist/domain/evidence.js +2 -1
  249. package/dist/domain/evidenceRecordSummary.js +144 -0
  250. package/dist/domain/inputIssueProjection.js +16 -1
  251. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +12 -13
  252. package/dist/domain/javascript/electronStaticAnalysisIpc.js +11 -20
  253. package/dist/domain/javascript/electronStaticAnalysisNative.js +70 -40
  254. package/dist/domain/javascript/electronStaticAnalysisValues.js +16 -0
  255. package/dist/domain/javascript/javascriptAnalysisResourceControls.js +45 -0
  256. package/dist/domain/javascript/javascriptApplicationAnalysis.js +4 -1
  257. package/dist/domain/javascript/javascriptApplicationChangeGraph.js +6 -6
  258. package/dist/domain/javascript/javascriptApplicationGraph.js +79 -18
  259. package/dist/domain/javascript/javascriptApplicationProjectionResources.js +35 -0
  260. package/dist/domain/javascript/javascriptApplicationVersionItems.js +28 -12
  261. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +9 -1
  262. package/dist/domain/javascript/javascriptAstFingerprint.js +58 -31
  263. package/dist/domain/javascript/javascriptAstValues.js +32 -0
  264. package/dist/domain/javascript/javascriptElectronMemberWrites.js +50 -0
  265. package/dist/domain/javascript/javascriptModuleSemanticIr.js +15 -0
  266. package/dist/domain/javascript/javascriptNativeHandoff.js +6 -1
  267. package/dist/domain/javascript/javascriptRpcEndpoints.js +253 -0
  268. package/dist/domain/javascript/javascriptRuntimeLoadState.js +1 -3
  269. package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +7 -2
  270. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +8 -11
  271. package/dist/domain/javascript/javascriptSemanticAnalysis.js +190 -33
  272. package/dist/domain/javascript/javascriptSemanticCallableResults.js +42 -0
  273. package/dist/domain/javascript/javascriptSemanticCalls.js +8 -1
  274. package/dist/domain/javascript/javascriptSemanticDerivedAnalysis.js +15 -4
  275. package/dist/domain/javascript/javascriptSemanticFileProjection.js +1 -0
  276. package/dist/domain/javascript/javascriptSemanticFingerprints.js +42 -41
  277. package/dist/domain/javascript/javascriptSemanticGraph.js +69 -23
  278. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +2 -10
  279. package/dist/domain/javascript/javascriptSemanticIterationSources.js +40 -7
  280. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +341 -87
  281. package/dist/domain/javascript/javascriptSemanticMutationValues.js +78 -35
  282. package/dist/domain/javascript/javascriptSemanticObjectReferences.js +381 -0
  283. package/dist/domain/javascript/javascriptSemanticObjects.js +7 -1
  284. package/dist/domain/javascript/javascriptSemanticProjection.js +52 -14
  285. package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +77 -0
  286. package/dist/domain/javascript/javascriptSemanticQuery.js +27 -29
  287. package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +1 -3
  288. package/dist/domain/javascript/javascriptSemanticReturnedReferences.js +219 -0
  289. package/dist/domain/javascript/javascriptSemanticReturns.js +13 -23
  290. package/dist/domain/javascript/javascriptSemanticState.js +22 -2
  291. package/dist/domain/javascript/javascriptSemanticTraversal.js +19 -1
  292. package/dist/domain/javascript/javascriptSemanticValues.js +47 -19
  293. package/dist/domain/javascript/javascriptSourceAnalysis.js +1 -0
  294. package/dist/domain/javascript/javascriptStaticAnalysis.js +29 -17
  295. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +8 -6
  296. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +49 -5
  297. package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +8 -4
  298. package/dist/domain/javascript/javascriptStaticAnalysisState.js +1 -0
  299. package/dist/domain/jeb/jebAnalysis.js +114 -0
  300. package/dist/domain/jsonShape.js +63 -52
  301. package/dist/domain/jsonValue.js +3 -0
  302. package/dist/domain/managed/managedApplicationGraph.js +37 -0
  303. package/dist/domain/managed/managedApplicationGraphCoverage.js +8 -2
  304. package/dist/domain/managed/managedApplicationGraphNodes.js +32 -22
  305. package/dist/domain/managed/managedArtifact.js +1 -0
  306. package/dist/domain/managed/managedInspectionEvidence.js +13 -0
  307. package/dist/domain/native/nativeAotPe.js +1408 -0
  308. package/dist/domain/native/nativeInstruction.js +21 -0
  309. package/dist/domain/native/nativeMetadataRecovery.js +79 -6
  310. package/dist/domain/native/peResources.js +94 -0
  311. package/dist/domain/nativeConvention.js +33 -0
  312. package/dist/domain/process/processCapture.js +91 -1
  313. package/dist/domain/process/processCaptureExample.js +24 -0
  314. package/dist/domain/process/processCaptureValidation.js +79 -0
  315. package/dist/domain/process/processScenario.js +59 -7
  316. package/dist/domain/propertyListKeys.js +3 -1
  317. package/dist/domain/referenceSourceGraph.js +25 -16
  318. package/dist/domain/referenceSourceImportParsing.js +6 -3
  319. package/dist/domain/referenceSourcePathIdentity.js +22 -0
  320. package/dist/domain/referenceSourceRequireBindings.js +137 -0
  321. package/dist/domain/webBundleAnalyzerInspection.js +14 -2
  322. package/dist/domain/webCaptureDiff.js +102 -4
  323. package/dist/domain/webScriptExportError.js +10 -4
  324. package/dist/domain/webScriptExportPlan.js +7 -13
  325. package/dist/domain/zipPackageFormat.js +4 -1
  326. package/dist/domain/zodCollectionSteps.js +24 -0
  327. package/dist/dotnet/ManagedArtifactInspector.js +55 -43
  328. package/dist/dotnet/ManagedDecodeBudget.js +80 -0
  329. package/dist/dotnet/ManagedMemberInspector.js +13 -6
  330. package/dist/dotnet/ManagedMemberInspectorCore.js +2 -2
  331. package/dist/dotnet/ManagedMemberInstructionDecoder.js +4 -2
  332. package/dist/dotnet/ManagedMemberRows.js +9 -4
  333. package/dist/dotnet/ManagedMetadataHeaps.js +15 -5
  334. package/dist/dotnet/ManagedMetadataInventoryRows.js +20 -11
  335. package/dist/dotnet/ManagedMetadataLayout.js +10 -4
  336. package/dist/dotnet/ManagedMethodBodyReader.js +8 -3
  337. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +3 -2
  338. package/dist/dotnet/ManagedNativeBoundaryInspector.js +49 -34
  339. package/dist/dotnet/ManagedPeReader.js +41 -25
  340. package/dist/dotnet/ManagedReaderFailure.js +2 -1
  341. package/dist/dotnet/ManagedStaticProvider.js +55 -24
  342. package/dist/evaluation/AgentEvaluationReport.js +9 -5
  343. package/dist/evaluation/CodexAgentEval.js +43 -13
  344. package/dist/evm/EvmoleFailures.js +0 -2
  345. package/dist/evm/EvmoleInterfaceProvider.js +67 -2
  346. package/dist/filesystem/OwnedDirectoryHandle.js +29 -0
  347. package/dist/filesystem/OwnedFileHandle.js +36 -0
  348. package/dist/filesystem/RegularFile.js +33 -1
  349. package/dist/filesystem/StableFileHash.js +46 -0
  350. package/dist/filesystem/readFileHandleChunks.js +26 -0
  351. package/dist/firmware/FirmwareCommand.js +25 -3
  352. package/dist/firmware/FirmwareFiles.js +23 -8
  353. package/dist/firmware/FirmwareProvider.js +156 -32
  354. package/dist/firmware/FirmwarePublication.js +24 -3
  355. package/dist/firmware/FirmwareRelease.js +1 -0
  356. package/dist/generatedPackageMetadata.js +2 -2
  357. package/dist/ghidra/GhidraAnalysisProfile.js +55 -4
  358. package/dist/ghidra/GhidraAnalysisSeeds.js +211 -0
  359. package/dist/ghidra/GhidraClient.js +76 -4
  360. package/dist/ghidra/GhidraDiagnostics.js +11 -8
  361. package/dist/ghidra/GhidraFunctionValues.js +26 -2
  362. package/dist/ghidra/GhidraInstallation.js +1 -1
  363. package/dist/ghidra/GhidraInventoryValues.js +23 -1
  364. package/dist/ghidra/GhidraLanguageCatalog.js +99 -0
  365. package/dist/ghidra/GhidraLauncher.js +80 -39
  366. package/dist/ghidra/GhidraLoadImageAttest.js +49 -2
  367. package/dist/ghidra/GhidraMipsProfile.js +79 -0
  368. package/dist/ghidra/GhidraProvider.js +57 -9
  369. package/dist/ghidra/GhidraProviderCapabilities.js +18 -8
  370. package/dist/ghidra/GhidraProviderClient.js +282 -21
  371. package/dist/ghidra/GhidraSessionValues.js +9 -2
  372. package/dist/hopper/HopperAnalysisProfile.js +2 -0
  373. package/dist/hopper/HopperClient.js +15 -6
  374. package/dist/hopper/HopperMachOImage.js +2 -0
  375. package/dist/hopper/HopperProvider.js +13 -2
  376. package/dist/ida/IdaOperationRunner.js +8 -2
  377. package/dist/ida/IdaProvider.js +7 -0
  378. package/dist/ida/IdaSessionClient.js +3 -1
  379. package/dist/ida/IdaWorkspace.js +4 -2
  380. package/dist/javascript/analysis/JavaScriptAnalysisTransfer.js +326 -0
  381. package/dist/javascript/analysis/JavaScriptAnalysisWorker.js +520 -0
  382. package/dist/javascript/analysis/JavaScriptAnalysisWorkerProtocol.js +63 -0
  383. package/dist/javascript/analysis/JavaScriptAnalysisWorkerSchemas.js +521 -0
  384. package/dist/javascript/analysis/JavaScriptAnalysisWorkerServer.js +116 -0
  385. package/dist/javascript/recovery/RecoveryFiles.js +18 -7
  386. package/dist/javascript/recovery/WakaruCommand.js +22 -9
  387. package/dist/javascript/recovery/WakaruExecution.js +11 -7
  388. package/dist/javascript/recovery/WakaruProvider.js +139 -16
  389. package/dist/javascript/recovery/WakaruPublication.js +14 -4
  390. package/dist/javascript/recovery/WakaruRelease.js +10 -3
  391. package/dist/javascript/recovery/WakaruReport.js +12 -7
  392. package/dist/javascript/recovery/WakaruVersion.js +24 -0
  393. package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -3
  394. package/dist/javascript/sourceMaps/SourceMapDecoder.js +63 -7
  395. package/dist/javascript/sourceMaps/SourceMapFormat.js +15 -4
  396. package/dist/jeb/JebMcpConnection.js +179 -0
  397. package/dist/jeb/JebMcpEndpoint.js +40 -0
  398. package/dist/jeb/JebProvider.js +299 -0
  399. package/dist/mcpDoctor.js +15 -6
  400. package/dist/native/AppleDispatchCoverage.js +25 -12
  401. package/dist/native/AppleDispatchMetadata.js +14 -7
  402. package/dist/native/AppleMachoFixups.js +71 -15
  403. package/dist/native/AppleMachoSelection.js +23 -3
  404. package/dist/native/NativeMacOSProvider.js +91 -16
  405. package/dist/native/NativeMachoInspection.js +11 -7
  406. package/dist/native/NativeUiHelperRuntime.js +6 -1
  407. package/dist/native/NativeUiObservation.js +4 -3
  408. package/dist/native/pe/PeResourceLayout.js +120 -0
  409. package/dist/native/pe/PeResourceParser.js +286 -0
  410. package/dist/native/pe/PeResourcesProvider.js +63 -0
  411. package/dist/process/BoundedFileBytes.js +30 -7
  412. package/dist/process/DarwinProcessRunTokenReader.js +8 -3
  413. package/dist/process/OwnedCommand.js +4 -3
  414. package/dist/process/ProcessOwnership.js +104 -112
  415. package/dist/process/ProcessOwnershipObservation.js +96 -39
  416. package/dist/process/ProcessOwnershipProcessTree.js +4 -4
  417. package/dist/process/ProcessRunTokenObservations.js +48 -0
  418. package/dist/process/ProviderDiagnosticRedaction.js +17 -0
  419. package/dist/process/ProviderProcess.js +4 -3
  420. package/dist/process/capture/FilesystemSnapshot.js +28 -4
  421. package/dist/process/capture/ProcessCaptureLifecycle.js +350 -59
  422. package/dist/process/capture/ProcessCaptureProgress.js +62 -0
  423. package/dist/process/capture/ProcessHarness.js +194 -26
  424. package/dist/process/capture/ProcessNormalization.js +3 -1
  425. package/dist/process/capture/ProcessScenarioRuntimeValidation.js +5 -2
  426. package/dist/process/capture/TerminalRenderer.js +24 -7
  427. package/dist/reference/ReferenceSourceReader.js +22 -5
  428. package/dist/reference/ReferenceSourceReaderEntries.js +114 -51
  429. package/dist/reference/ReferenceSourceReaderErrors.js +12 -0
  430. package/dist/reference/ReferenceSourceReaderFile.js +50 -10
  431. package/dist/reference/ReferenceSourceReaderValidate.js +4 -4
  432. package/dist/server/EvidenceMcpServer.js +36 -1
  433. package/dist/server/admittedToolOperation.js +9 -0
  434. package/dist/server/contractToolHandler.js +21 -0
  435. package/dist/server/createServer.js +97 -25
  436. package/dist/server/registerAdbTools.js +36 -0
  437. package/dist/server/registerAnalysisViewTool.js +4 -9
  438. package/dist/server/registerAndroidTools.js +3 -12
  439. package/dist/server/registerApktoolTools.js +14 -0
  440. package/dist/server/registerApplicationTools/compareExportShapes.js +4 -6
  441. package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
  442. package/dist/server/registerApplicationTools/compareVersions.js +3 -2
  443. package/dist/server/registerApplicationTools/coverage.js +3 -2
  444. package/dist/server/registerApplicationTools/obligationLedger.js +3 -2
  445. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -2
  446. package/dist/server/registerApplicationTools/traceFeature.js +3 -2
  447. package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
  448. package/dist/server/registerArtifactComparisonTool.js +5 -2
  449. package/dist/server/registerBinaryDiagnosticsTools.js +16 -4
  450. package/dist/server/registerBrowserScenarioTool.js +10 -7
  451. package/dist/server/registerBrowserTools.js +12 -9
  452. package/dist/server/registerBundleComparisonTool.js +16 -2
  453. package/dist/server/registerCloseLifecycleTool.js +32 -3
  454. package/dist/server/registerElectronTools.js +28 -10
  455. package/dist/server/registerEvmTools.js +4 -9
  456. package/dist/server/registerFirmwareTools.js +3 -11
  457. package/dist/server/registerFunctionComparisonTool.js +5 -2
  458. package/dist/server/registerJavaScriptRecoveryTool.js +4 -9
  459. package/dist/server/registerJavaScriptRuntimeObservationTools.js +9 -6
  460. package/dist/server/registerJebTools.js +16 -0
  461. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -6
  462. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -2
  463. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +3 -2
  464. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +3 -2
  465. package/dist/server/registerPeResourcesTool.js +9 -0
  466. package/dist/server/registerProcessComparisonTool.js +5 -2
  467. package/dist/server/registerRecordedCrashTools.js +4 -9
  468. package/dist/server/registerSessionRecordTools.js +2 -1
  469. package/dist/server/registerSessionTools.js +49 -18
  470. package/dist/server/registerWebModuleTool.js +4 -9
  471. package/dist/server/registerWebNetworkCaptureTool.js +4 -9
  472. package/dist/server/registerWebRuntimeTools.js +6 -5
  473. package/dist/server/registerWebScriptTool.js +6 -3
  474. package/dist/server/registerWebSourceLocationTool.js +4 -9
  475. package/dist/server/toolResult.js +21 -2
  476. package/dist/windows/WindowsPrivateRuntime.js +12 -5
  477. package/install.sh +7 -4
  478. package/licenses/nativeaot-parser-MIT.txt +28 -0
  479. package/native/windows/build/manifest.json +2 -2
  480. package/native/windows/build/rea-windows-x64.node +0 -0
  481. package/package.json +33 -5
  482. package/scripts/rea.mjs +16 -1
  483. package/skills/reverse-engineer-anything/SKILL.md +52 -51
  484. package/skills/reverse-engineer-anything/references/connection-and-recovery.md +127 -0
  485. package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -0
  486. package/skills/reverse-engineer-anything/references/javascript-applications.md +92 -13
  487. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +22 -1
@@ -1,17 +1,103 @@
1
- import { openRegularFile } from "../filesystem/RegularFile.js";
1
+ import { lstat, stat } from "node:fs/promises";
2
+ import { RegularFileAdmissionFailure, openRegularFile, sameRegularFileState, RegularFileChangedError, } from "../filesystem/RegularFile.js";
3
+ import { OwnedFileHandle } from "../filesystem/OwnedFileHandle.js";
4
+ import { readBoundedFileBytes } from "../process/BoundedFileBytes.js";
5
+ /** A close failed after reading; this error transfers the exact handle owner. */
6
+ export class RegularFileCleanupFailure extends Error {
7
+ path;
8
+ owner;
9
+ outcome;
10
+ cleanupCause;
11
+ constructor(path, owner, outcome, cleanupCause) {
12
+ super(`Regular file cleanup failed: ${path}`, {
13
+ cause: outcome.kind === "failed" ? outcome.cause : cleanupCause,
14
+ });
15
+ this.path = path;
16
+ this.owner = owner;
17
+ this.outcome = outcome;
18
+ this.cleanupCause = cleanupCause;
19
+ this.name = "RegularFileCleanupFailure";
20
+ }
21
+ }
22
+ /** Retry a failed close through its retained owner and report any remaining cleanup. */
23
+ export const retryRegularFileCleanup = async (failure, resources) => {
24
+ const released = await resources.release({
25
+ kind: "file-handle",
26
+ handle: failure.owner,
27
+ resource: failure.path,
28
+ });
29
+ if (released.kind === "released")
30
+ return { outcome: failure.outcome };
31
+ return {
32
+ outcome: failure.outcome,
33
+ cleanup: {
34
+ reason: `${failureMessage(failure.cleanupCause)}; retry: ${failureMessage(released.cause)}`,
35
+ resources: [failure.path],
36
+ },
37
+ };
38
+ };
39
+ const failureMessage = (cause) => cause instanceof Error ? cause.message : String(cause);
2
40
  /** 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 });
41
+ export const withRegularFile = async (path, read, options = {}) => {
42
+ const { signal } = options;
43
+ let handle;
44
+ try {
45
+ handle = await openRegularFile(path, {
46
+ symlinks: options.symlinks ?? "follow",
47
+ signal,
48
+ });
49
+ }
50
+ catch (cause) {
51
+ if (!(cause instanceof RegularFileAdmissionFailure))
52
+ throw cause;
53
+ throw new RegularFileCleanupFailure(path, cause.owner, { kind: "failed", cause: cause.cause }, cause.cleanupCause);
54
+ }
55
+ const owner = new OwnedFileHandle(handle);
56
+ let outcome;
5
57
  try {
6
58
  const stats = await handle.stat();
7
59
  signal?.throwIfAborted();
8
60
  const value = await read(handle, stats);
9
61
  signal?.throwIfAborted();
10
- return value;
62
+ const [opened, currentPath] = await Promise.all([
63
+ handle.stat(),
64
+ options.symlinks === "reject" ? lstat(path) : stat(path),
65
+ ]);
66
+ if (!sameRegularFileState(stats, opened) ||
67
+ !sameRegularFileState(stats, currentPath))
68
+ throw new RegularFileChangedError(path);
69
+ outcome = { kind: "completed", value };
70
+ }
71
+ catch (cause) {
72
+ outcome = { kind: "failed", cause };
11
73
  }
12
- finally {
13
- await handle.close();
74
+ try {
75
+ await owner.close();
76
+ }
77
+ catch (cleanupCause) {
78
+ throw new RegularFileCleanupFailure(path, owner, outcome, cleanupCause);
14
79
  }
80
+ if (outcome.kind === "failed")
81
+ throw outcome.cause;
82
+ return outcome.value;
15
83
  };
16
84
  /** 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);
85
+ export const readRegularFile = (path, options = {}) => withRegularFile(path, async (handle, stats) => {
86
+ const bytes = await readBoundedFileBytes(handle, stats.size, options.signal);
87
+ if (bytes === undefined || bytes.length !== stats.size)
88
+ throw new RegularFileChangedError(path);
89
+ return bytes;
90
+ }, options);
91
+ /** Read one admitted regular file as UTF-8 without waiting on a pipe. */
92
+ export const readRegularFileText = async (path, options = {}) => {
93
+ try {
94
+ return (await readRegularFile(path, options)).toString("utf8");
95
+ }
96
+ catch (cause) {
97
+ if (cause instanceof RegularFileCleanupFailure &&
98
+ cause.outcome.kind === "completed" &&
99
+ Buffer.isBuffer(cause.outcome.value))
100
+ throw new RegularFileCleanupFailure(cause.path, cause.owner, { kind: "completed", value: cause.outcome.value.toString("utf8") }, cause.cleanupCause);
101
+ throw cause;
102
+ }
103
+ };
@@ -2,8 +2,49 @@ import { manualRegistrationRemediation, } from "./SupportedClients.js";
2
2
  import { configureDetectedClients } from "./SetupClients.js";
3
3
  import { discoverSetupState, planSetupActions } from "./SetupPlan.js";
4
4
  import { filterClientsNeedingConfigure, hostRemediation, systemSetupHost, } from "./SetupHost.js";
5
+ import { AnalysisError } from "../domain/analysisErrorBase.js";
6
+ import { analysisErrorWithCleanupFailure } from "../domain/analysisErrorCleanup.js";
7
+ import { ProviderCleanupError } from "../domain/providerCleanupError.js";
5
8
  /** Discover, approve, and apply setup actions idempotently. */
6
9
  export const runSetup = async (options, host = systemSetupHost(), confirm) => {
10
+ let result;
11
+ let primaryFailure;
12
+ let threw = false;
13
+ try {
14
+ result = await runSetupWorkflow(options, host, confirm);
15
+ }
16
+ catch (cause) {
17
+ threw = true;
18
+ primaryFailure = cause;
19
+ }
20
+ let cleanupFailure;
21
+ try {
22
+ cleanupFailure = await host.close?.();
23
+ }
24
+ catch (cause) {
25
+ cleanupFailure = `Setup resource cleanup failed: ${failureMessage(cause)}`;
26
+ }
27
+ if (threw) {
28
+ if (cleanupFailure !== undefined && primaryFailure instanceof AnalysisError)
29
+ throw analysisErrorWithCleanupFailure(primaryFailure, new ProviderCleanupError("setup", primaryFailure.cleanupResources, { reason: cleanupFailure }, { operation: "setup" }), "setup");
30
+ if (cleanupFailure !== undefined)
31
+ throw new AggregateError([primaryFailure, new Error(cleanupFailure)], "Setup and resource cleanup failed.", { cause: primaryFailure });
32
+ throw primaryFailure;
33
+ }
34
+ if (result === undefined)
35
+ throw new Error("Setup returned no result.");
36
+ if (cleanupFailure === undefined)
37
+ return result;
38
+ return {
39
+ ...result,
40
+ status: "needs_human",
41
+ code: result.code ?? "cleanup_failed",
42
+ remediation: result.remediation
43
+ ? `${result.remediation} ${cleanupFailure}`
44
+ : cleanupFailure,
45
+ };
46
+ };
47
+ const runSetupWorkflow = async (options, host, confirm) => {
7
48
  const appliedActions = [];
8
49
  let plannedActions = [];
9
50
  const clients = {};
@@ -27,6 +68,7 @@ export const runSetup = async (options, host = systemSetupHost(), confirm) => {
27
68
  options.readinessScope?.clients === undefined &&
28
69
  options.allDetectedClients !== true &&
29
70
  options.installHopper !== true &&
71
+ options.skillClientIds === undefined &&
30
72
  options.installSkill === undefined;
31
73
  const interactiveSelection = confirm !== undefined && !options.structured && clientSelectionAllowed;
32
74
  let selectedClientIds = options.allDetectedClients
@@ -34,9 +76,11 @@ export const runSetup = async (options, host = systemSetupHost(), confirm) => {
34
76
  : (options.clientIds ??
35
77
  options.readinessScope?.clients ??
36
78
  discovery.defaultClientIds);
37
- let skillNeedsInstall = await host.skillNeedsInstall(selectedClientIds);
79
+ let selectedSkillClientIds = options.skillClientIds ?? selectedClientIds;
80
+ let skillNeedsInstall = await host.skillNeedsInstall(selectedSkillClientIds);
38
81
  let skillSelected = options.installSkill === true ||
39
- (options.installSkill !== false && selectedClientIds.length > 0);
82
+ (options.installSkill !== false &&
83
+ (selectedClientIds.length > 0 || selectedSkillClientIds.length > 0));
40
84
  let installSkill = skillSelected && skillNeedsInstall;
41
85
  let planDiscovery = discovery;
42
86
  if (interactiveSelection) {
@@ -89,6 +133,7 @@ export const runSetup = async (options, host = systemSetupHost(), confirm) => {
89
133
  selectedClientIds.length === 0) ||
90
134
  (options.installSkill !== false && selectedClientIds.length > 0);
91
135
  installSkill = skillSelected && skillNeedsInstall;
136
+ selectedSkillClientIds = selectedClientIds;
92
137
  }
93
138
  const planned = await planSetupActions({
94
139
  discovery: planDiscovery,
@@ -96,7 +141,7 @@ export const runSetup = async (options, host = systemSetupHost(), confirm) => {
96
141
  providerEnvironment,
97
142
  command: host.registrationCommand,
98
143
  clientIds: selectedClientIds,
99
- skillClientIds: selectedClientIds,
144
+ skillClientIds: selectedSkillClientIds,
100
145
  installSkill,
101
146
  });
102
147
  plannedActions = planned.plannedActions;
@@ -188,7 +233,7 @@ export const runSetup = async (options, host = systemSetupHost(), confirm) => {
188
233
  if (clientFailure !== undefined)
189
234
  return fail(clientFailure);
190
235
  if (planSelection.installSkill &&
191
- !(await installSkillAction(host, options, appliedActions, selectedClientIds)))
236
+ !(await installSkillAction(host, options, appliedActions, selectedSkillClientIds)))
192
237
  return fail("REA analysis skill could not be installed or verified. Check permissions for its planned skill directories, then rerun setup.");
193
238
  const doctor = summarizeDoctor(await host.doctor(readinessScope));
194
239
  const remediation = combineRemediation(finalSetupRemediation(host.platform, appliedActions.includes("installed_hopper"), doctor.healthy, hopperPath), manualRemediation);
@@ -234,8 +279,10 @@ const installHopperAction = async (input) => {
234
279
  emitProgress(input.options, {
235
280
  actionId: "install_hopper",
236
281
  label,
237
- state: "completed",
238
- detail: installed.launcherPath,
282
+ state: installed.cleanupFailure === undefined ? "completed" : "warning",
283
+ detail: installed.cleanupFailure === undefined
284
+ ? installed.launcherPath
285
+ : `${installed.launcherPath}; ${installed.cleanupFailure}`,
239
286
  });
240
287
  const providerEnvironment = {
241
288
  ...input.providerEnvironment,
@@ -345,3 +392,4 @@ const summarizeDoctor = (report) => ({
345
392
  },
346
393
  }),
347
394
  });
395
+ const failureMessage = (cause) => cause instanceof Error ? cause.message : String(cause);
@@ -1,42 +1,82 @@
1
+ import { readClientPolicyBlock } from "./GeminiClientSettings.js";
2
+ import { readClientConfigurationFiles } from "./ClientConfigurationFiles.js";
1
3
  import { clientRegistrationEntry, clientConfigurationValuesEqual, clientServerListedDisabled, clientServerPath, legacyClientServerPath, OMP_DISABLED_SERVERS_KEY, parseClientConfiguration, serializeClientConfiguration, withClientServers, } from "./ClientConfigurationDocument.js";
2
4
  import { constants as fsConstants } from "node:fs";
3
- import { copyFile, mkdir, readFile, rm, writeFile } from "node:fs/promises";
5
+ import { copyFile, mkdir, rm, writeFile } from "node:fs/promises";
4
6
  import { dirname } from "node:path";
5
7
  import writeFileAtomic from "write-file-atomic";
8
+ import { clientRegistrationEnvironment } from "./ClientRegistrationEnvironment.js";
6
9
  import { PRODUCT_IDENTITY } from "../identity.js";
7
10
  import { npxRegistrationCommand } from "./ClientRegistrationIdentity.js";
8
11
  import { MCP_STARTUP_POLICY } from "../mcpStartupPolicy.js";
9
12
  import { resolveClientConfigTransactionPath } from "./ClientConfigPath.js";
13
+ import { readRegularFileText, RegularFileCleanupFailure, } from "./RegularFileRead.js";
10
14
  /** Configure one supported client's native stdio MCP registration shape. */
11
15
  export const configureClientConfiguration = (client, environment = {}, command = npxRegistrationCommand()) => {
12
- if (client.format === undefined || client.format === "unsupported")
13
- return Promise.resolve({ status: "failed", reason: "readback" });
14
- return configureClientDocument(client, environment, command, client.format);
16
+ if (client.configPathError !== undefined)
17
+ return Promise.resolve({ status: "failed", reason: "path" });
18
+ return configureClientDocument(client, environment, command);
15
19
  };
16
- const configureClientDocument = async (client, environment, command, format) => {
20
+ const configureClientDocument = async (client, environment, command) => {
21
+ const format = client.format;
22
+ if (format === undefined || format === "unsupported")
23
+ return { status: "failed", reason: "readback" };
24
+ const files = await readClientConfigurationFiles(client);
25
+ if (!files.ok) {
26
+ throwCleanupFailure(files.error);
27
+ return { status: "failed", reason: "readback" };
28
+ }
29
+ const policy = await readClientPolicyBlock(client, undefined, clientConfigurationDesired(client, environment, command, files.value.at(-1)));
30
+ if (!policy.ok) {
31
+ throwCleanupFailure(policy.error);
32
+ return { status: "failed", reason: "readback" };
33
+ }
34
+ if (policy.value !== undefined)
35
+ return { status: "failed", reason: "readback" };
17
36
  const transactionPath = await resolveClientConfigTransactionPath(client.configPath);
18
37
  if (transactionPath === undefined)
19
38
  return { status: "failed", reason: "path" };
20
39
  let original;
21
40
  try {
22
- original = await readFile(transactionPath, "utf8");
41
+ original = await readRegularFileText(transactionPath);
23
42
  }
24
43
  catch (cause) {
44
+ if (cause instanceof RegularFileCleanupFailure)
45
+ throw cause;
25
46
  if (!isMissing(cause))
26
47
  return { status: "failed", reason: "readback" };
27
48
  }
28
49
  let parsed;
29
50
  try {
30
51
  parsed = parseClientConfiguration(original ?? (format === "toml" || format === "grok" ? "" : "{}"), format);
52
+ const policy = await readClientPolicyBlock(client, parsed, clientConfigurationDesired(client, environment, command, parsed));
53
+ if (!policy.ok) {
54
+ throwCleanupFailure(policy.error);
55
+ return { status: "failed", reason: "readback" };
56
+ }
57
+ if (policy.value !== undefined)
58
+ return { status: "failed", reason: "readback" };
31
59
  }
32
60
  catch (cause) {
61
+ if (cause instanceof RegularFileCleanupFailure)
62
+ throw cause;
33
63
  // Malformed existing configuration fails the readback gate.
34
64
  void cause;
35
65
  return { status: "failed", reason: "readback" };
36
66
  }
37
- const desired = clientConfigurationDesired(client, environment, command, parsed.dialect);
67
+ const desired = clientConfigurationDesired(client, environment, command, parsed);
38
68
  if (registrationCurrent(parsed, desired))
39
69
  return { status: "unchanged" };
70
+ return persistClientConfiguration({
71
+ client,
72
+ transactionPath,
73
+ format,
74
+ original,
75
+ parsed,
76
+ desired,
77
+ });
78
+ };
79
+ const persistClientConfiguration = async ({ client, transactionPath, format, original, parsed, desired, }) => {
40
80
  const backupPath = original === undefined ? undefined : `${client.configPath}.rea.backup`;
41
81
  if (backupPath !== undefined &&
42
82
  !(await preserveConfigBackup(transactionPath, backupPath)))
@@ -74,13 +114,15 @@ const configureClientDocument = async (client, environment, command, format) =>
74
114
  return { status: "failed", reason: "write" };
75
115
  }
76
116
  try {
77
- const readback = parseClientConfiguration(await readFile(transactionPath, "utf8"), format);
117
+ const readback = parseClientConfiguration(await readRegularFileText(transactionPath), format);
78
118
  if (!registrationCurrent(readback, desired)) {
79
119
  await restoreConfig(transactionPath, original);
80
120
  return { status: "failed", reason: "readback" };
81
121
  }
82
122
  }
83
123
  catch (cause) {
124
+ if (cause instanceof RegularFileCleanupFailure)
125
+ throw cause;
84
126
  // Readback failure restores the transaction before reporting.
85
127
  void cause;
86
128
  await restoreConfig(transactionPath, original);
@@ -93,12 +135,27 @@ const configureClientDocument = async (client, environment, command, format) =>
93
135
  };
94
136
  /** Determine whether an existing client configuration matches the desired registration. */
95
137
  export const clientConfigurationAligned = async (client, providerEnvironment, command) => {
138
+ if (client.configPathError !== undefined)
139
+ return false;
96
140
  try {
97
- const original = await readFile(client.configPath, "utf8");
141
+ const files = await readClientConfigurationFiles(client);
142
+ if (!files.ok) {
143
+ throwCleanupFailure(files.error);
144
+ return false;
145
+ }
146
+ const original = await readRegularFileText(client.configPath);
98
147
  const parsed = parseClientConfiguration(original, client.format);
99
- return registrationCurrent(parsed, clientConfigurationDesired(client, providerEnvironment, command, parsed.dialect));
148
+ const policy = await readClientPolicyBlock(client, parsed, clientConfigurationDesired(client, providerEnvironment, command, parsed));
149
+ if (!policy.ok) {
150
+ throwCleanupFailure(policy.error);
151
+ return false;
152
+ }
153
+ return (policy.value === undefined &&
154
+ registrationCurrent(parsed, clientConfigurationDesired(client, providerEnvironment, command, parsed)));
100
155
  }
101
156
  catch (cause) {
157
+ if (cause instanceof RegularFileCleanupFailure)
158
+ throw cause;
102
159
  // Unreadable configuration is treated as not aligned so setup repairs it.
103
160
  void cause;
104
161
  return false;
@@ -106,8 +163,28 @@ export const clientConfigurationAligned = async (client, providerEnvironment, co
106
163
  };
107
164
  /** Preflight one client configuration before setup presents any mutations. */
108
165
  export const inspectClientConfiguration = async (client, providerEnvironment, command) => {
166
+ if (client.configPathError !== undefined)
167
+ return { status: "invalid", remediation: client.configPathError };
109
168
  if (client.format === "unsupported")
110
169
  return { status: "already_current" };
170
+ const files = await readClientConfigurationFiles(client);
171
+ if (!files.ok) {
172
+ throwCleanupFailure(files.error);
173
+ return {
174
+ status: "invalid",
175
+ remediation: files.error.detail,
176
+ };
177
+ }
178
+ const policy = await readClientPolicyBlock(client, undefined, clientConfigurationDesired(client, providerEnvironment, command, files.value.at(-1)));
179
+ if (!policy.ok) {
180
+ throwCleanupFailure(policy.error);
181
+ return {
182
+ status: "invalid",
183
+ remediation: policy.error.detail,
184
+ };
185
+ }
186
+ if (policy.value !== undefined)
187
+ return { status: "invalid", remediation: policy.value };
111
188
  const transactionPath = await resolveClientConfigTransactionPath(client.configPath);
112
189
  if (transactionPath === undefined)
113
190
  return {
@@ -116,23 +193,37 @@ export const inspectClientConfiguration = async (client, providerEnvironment, co
116
193
  };
117
194
  let original;
118
195
  try {
119
- original = await readFile(transactionPath, "utf8");
196
+ original = await readRegularFileText(transactionPath);
120
197
  }
121
198
  catch (cause) {
199
+ if (cause instanceof RegularFileCleanupFailure)
200
+ throw cause;
122
201
  if (isMissing(cause))
123
202
  return { status: "create" };
124
203
  return {
125
204
  status: "invalid",
126
- remediation: "The configuration file could not be read. Check its permissions before rerunning setup.",
205
+ remediation: `The configuration file could not be read. Check its permissions before rerunning setup. ${cause instanceof Error ? cause.message : String(cause)}`,
127
206
  };
128
207
  }
129
208
  try {
130
209
  const parsed = parseClientConfiguration(original, client.format);
131
- const desired = clientConfigurationDesired(client, providerEnvironment, command, parsed.dialect);
210
+ const policy = await readClientPolicyBlock(client, parsed, clientConfigurationDesired(client, providerEnvironment, command, parsed));
211
+ if (!policy.ok) {
212
+ throwCleanupFailure(policy.error);
213
+ return {
214
+ status: "invalid",
215
+ remediation: policy.error.detail,
216
+ };
217
+ }
218
+ if (policy.value !== undefined)
219
+ return { status: "invalid", remediation: policy.value };
220
+ const desired = clientConfigurationDesired(client, providerEnvironment, command, parsed);
132
221
  if (registrationCurrent(parsed, desired))
133
222
  return { status: "already_current" };
134
223
  }
135
224
  catch (cause) {
225
+ if (cause instanceof RegularFileCleanupFailure)
226
+ throw cause;
136
227
  // Malformed configuration is reported with the invalid remediation.
137
228
  void cause;
138
229
  return {
@@ -146,6 +237,10 @@ export const inspectClientConfiguration = async (client, providerEnvironment, co
146
237
  };
147
238
  };
148
239
  const isMissing = (cause) => cause instanceof Error && "code" in cause && cause.code === "ENOENT";
240
+ const throwCleanupFailure = (error) => {
241
+ if (error.cleanupFailure !== undefined)
242
+ throw error.cleanupFailure;
243
+ };
149
244
  const preserveConfigBackup = async (source, destination) => {
150
245
  try {
151
246
  await copyFile(source, destination, fsConstants.COPYFILE_EXCL);
@@ -171,9 +266,14 @@ const restoreConfig = async (path, original) => {
171
266
  const registrationCurrent = (parsed, desired) => clientConfigurationValuesEqual(parsed.servers[PRODUCT_IDENTITY.mcpServerKey], desired) &&
172
267
  !Object.hasOwn(parsed.legacyServers, PRODUCT_IDENTITY.mcpServerKey) &&
173
268
  !clientServerListedDisabled(parsed, PRODUCT_IDENTITY.mcpServerKey);
174
- const clientConfigurationDesired = (client, providerEnvironment, command, format) => {
175
- const environment = Object.fromEntries(Object.entries(providerEnvironment).sort(([left], [right]) => left.localeCompare(right)));
176
- const registration = clientRegistrationEntry(format ?? "json", command.length === 0 ? [PRODUCT_IDENTITY.cliBinary, "mcp"] : command, environment);
269
+ const clientConfigurationDesired = (client, providerEnvironment, command, parsed) => {
270
+ const format = parsed?.dialect ?? client.format ?? "json";
271
+ // Preserve explicitly configured server settings, never the ambient process
272
+ // environment. Newly discovered provider paths win only for their own keys.
273
+ const environment = clientRegistrationEnvironment(parsed, providerEnvironment);
274
+ if (!environment.ok)
275
+ throw environment.error;
276
+ const registration = clientRegistrationEntry(format, command.length === 0 ? [PRODUCT_IDENTITY.cliBinary, "mcp"] : command, environment.value);
177
277
  return {
178
278
  ...registration,
179
279
  ...(client.name === "codex" || client.name === "grok_build"
@@ -1,15 +1,19 @@
1
1
  import { access } from "node:fs/promises";
2
2
  import { resolve } from "node:path";
3
+ import { ArtifactResourceScope } from "../artifacts/ArtifactResourceScope.js";
4
+ import { ArtifactReaderFailure } from "../artifacts/ArtifactReader.js";
5
+ import { ConfigurationError } from "../domain/configurationErrors.js";
3
6
  import { PRODUCT_IDENTITY } from "../identity.js";
4
7
  import { npxRegistrationCommand } from "./ClientRegistrationIdentity.js";
5
8
  import { SUPPORTED_NODE_VERSION_PROSE, supportsNodeVersion, } from "../domain/runtimeVersion.js";
6
9
  import { runDoctor, systemDoctorHost } from "./Doctor.js";
7
10
  import { installLinuxHopper, readLinuxDistribution, systemLinuxHopperInstallHost, } from "./LinuxHopper.js";
8
11
  import { installMacHopper, systemMacHopperInstallHost } from "./MacHopper.js";
9
- import { supportedClients } from "./SupportedClients.js";
10
- import { claudeCodeSkillsDirectory as resolveClaudeCodeSkillsDirectory, canonicalSkillNeedsInstall, installCanonicalSkill, } from "./SetupSkill.js";
12
+ import { clientEvidencePaths, supportedClients, } from "./SupportedClients.js";
13
+ import { skillDestinations, canonicalSkillNeedsInstall, installCanonicalSkill, } from "./SetupSkill.js";
11
14
  import { clientConfigurationAligned, configureClientConfiguration, inspectClientConfiguration, } from "./SetupClientConfiguration.js";
12
15
  import { setupInstallFailure } from "./SetupInstallFailure.js";
16
+ import { RegularFileCleanupFailure, retryRegularFileCleanup, } from "./RegularFileRead.js";
13
17
  import { providerRegistrationEnvironment } from "./SetupRegistrationEnvironment.js";
14
18
  /** Resolve the executable and arguments used in a managed MCP registration. */
15
19
  export const setupRegistrationCommand = (platform, useNpmRunner) => useNpmRunner
@@ -40,22 +44,26 @@ export const hostRemediation = async (host, installHopper) => {
40
44
  }
41
45
  if ((await host.linuxDistribution())?.supported === true)
42
46
  return undefined;
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.";
47
+ return "Automated Hopper setup supports Ubuntu 24.04+, Fedora 41+, Nobara 44+, 64-bit Arch Linux, CachyOS, and Omarchy; configure an existing supported provider instead.";
44
48
  };
45
49
  /** Production setup effects for Hopper, agent configuration, and the canonical skill directory. */
46
50
  export const systemSetupHost = (selectedDoctorHost = undefined, environment = process.env) => {
47
51
  const doctorHost = selectedDoctorHost ?? systemDoctorHost({ environment });
48
52
  const platform = doctorHost.platform;
49
53
  const { homeDirectory } = doctorHost;
50
- const claudeSkillsDirectory = resolveClaudeCodeSkillsDirectory(homeDirectory, environment);
54
+ const macHopperHost = platform === "darwin"
55
+ ? systemMacHopperInstallHost(homeDirectory, environment)
56
+ : undefined;
57
+ const resources = new ArtifactResourceScope();
51
58
  return {
52
59
  platform,
53
60
  homeDirectory,
54
- claudeCodeSkillsDirectory: claudeSkillsDirectory,
61
+ skillDestinations: (clientIds) => skillDestinations(homeDirectory, clientIds, environment, platform),
55
62
  registrationCommand: setupRegistrationCommand(platform, environment.npm_command === "exec"),
56
63
  nodeVersion: process.versions.node,
57
64
  macosVersion: () => doctorHost.macosVersion(),
58
65
  linuxDistribution: readLinuxDistribution,
66
+ close: () => closeSetupResources(resources, macHopperHost),
59
67
  initialSetupState: async (scope) => {
60
68
  const diagnosis = await runDoctor(undefined, doctorHost, scope);
61
69
  return {
@@ -72,41 +80,111 @@ export const systemSetupHost = (selectedDoctorHost = undefined, environment = pr
72
80
  };
73
81
  },
74
82
  installHopper: async (replaceExisting) => {
75
- const result = platform === "linux"
76
- ? await installLinuxHopper(systemLinuxHopperInstallHost(environment))
77
- : await installMacHopper({ replaceExisting }, systemMacHopperInstallHost(homeDirectory, environment));
83
+ if (platform === "linux") {
84
+ const result = await installLinuxHopper(systemLinuxHopperInstallHost(environment));
85
+ return result.status === "installed"
86
+ ? result
87
+ : setupInstallFailure(result.reason);
88
+ }
89
+ if (macHopperHost === undefined)
90
+ return setupInstallFailure("unsupported_host");
91
+ const result = await installMacHopper({ replaceExisting }, macHopperHost);
78
92
  if (result.status === "installed")
79
- return result;
80
- return setupInstallFailure(result.reason);
93
+ return {
94
+ status: "installed",
95
+ launcherPath: result.launcherPath,
96
+ ...(result.cleanupFailure === undefined
97
+ ? {}
98
+ : { cleanupFailure: result.cleanupFailure }),
99
+ };
100
+ const failure = setupInstallFailure(result.reason);
101
+ if (result.cleanupFailure === undefined)
102
+ return failure;
103
+ return failure.status === "failed"
104
+ ? {
105
+ ...failure,
106
+ remediation: `${failure.remediation} ${result.cleanupFailure}`,
107
+ }
108
+ : failure;
81
109
  },
82
110
  detectedClients: () => detectClients(homeDirectory, platform, environment),
83
111
  supportedClients: () => Promise.resolve(supportedClients(homeDirectory, platform, environment)),
84
- configureClient: (client, providerEnvironment, command) => client.format === "unsupported"
85
- ? Promise.resolve({ status: "skipped" })
86
- : configureClientConfiguration(client, providerEnvironment, command),
87
- clientNeedsConfigure: (client, providerEnvironment, command) => client.format === "unsupported"
88
- ? Promise.resolve(false)
89
- : clientConfigurationAligned(client, providerEnvironment, command).then((aligned) => !aligned),
90
- inspectClientConfiguration: inspectClientConfiguration,
91
- skillNeedsInstall: (clientIds) => canonicalSkillNeedsInstall(homeDirectory, clientIds, claudeSkillsDirectory),
92
- installSkill: (clientIds) => installCanonicalSkill(homeDirectory, clientIds, claudeSkillsDirectory),
112
+ ...clientConfigurationOperations(resources),
113
+ skillNeedsInstall: (clientIds) => canonicalSkillNeedsInstall(homeDirectory, clientIds, environment, platform),
114
+ installSkill: (clientIds) => installCanonicalSkill(homeDirectory, clientIds, environment, platform),
93
115
  doctor: (scope) => runDoctor(undefined, doctorHost, scope),
94
116
  };
95
117
  };
118
+ const clientConfigurationOperations = (resources) => ({
119
+ configureClient: (client, providerEnvironment, command) => runClientConfigurationOperation(resources, async () => client.format === "unsupported"
120
+ ? { status: "skipped" }
121
+ : configureClientConfiguration(client, providerEnvironment, command)),
122
+ clientNeedsConfigure: (client, providerEnvironment, command) => runClientConfigurationOperation(resources, async () => client.format === "unsupported"
123
+ ? false
124
+ : !(await clientConfigurationAligned(client, providerEnvironment, command))),
125
+ inspectClientConfiguration: (client, providerEnvironment, command) => runClientConfigurationOperation(resources, () => inspectClientConfiguration(client, providerEnvironment, command)),
126
+ });
127
+ const closeSetupResources = async (resources, macHopperHost) => {
128
+ const [resourceCleanup, hopperCleanup] = await Promise.allSettled([
129
+ resources.close(),
130
+ Promise.resolve().then(() => macHopperHost?.close()),
131
+ ]);
132
+ const failures = [];
133
+ if (hopperCleanup.status === "rejected")
134
+ failures.push(`Hopper host cleanup failed: ${errorMessage(hopperCleanup.reason)}`);
135
+ else if (hopperCleanup.value !== undefined)
136
+ failures.push(hopperCleanup.value);
137
+ if (resourceCleanup.status === "rejected")
138
+ failures.push(errorMessage(resourceCleanup.reason));
139
+ return failures.length === 0 ? undefined : failures.join("; ");
140
+ };
141
+ const runClientConfigurationOperation = async (resources, operation) => {
142
+ try {
143
+ return await resources.run(async () => {
144
+ try {
145
+ return await operation();
146
+ }
147
+ catch (cause) {
148
+ if (!(cause instanceof RegularFileCleanupFailure))
149
+ throw cause;
150
+ const cleanup = await retryRegularFileCleanup(cause, resources);
151
+ const primary = cleanup.outcome.kind === "failed"
152
+ ? cleanup.outcome.cause
153
+ : cause.cleanupCause;
154
+ throw configurationCleanupError(`Could not safely access client configuration at ${cause.path}: ${errorMessage(primary)}`, cause, cleanup.cleanup);
155
+ }
156
+ });
157
+ }
158
+ catch (cause) {
159
+ if (cause instanceof ArtifactReaderFailure)
160
+ throw configurationCleanupError(cause.message, cause, cause.cleanup);
161
+ throw cause;
162
+ }
163
+ };
164
+ const configurationCleanupError = (message, cause, cleanup) => new ConfigurationError(message, {
165
+ cause,
166
+ settings: [{ setting: "client configuration", constraint: message }],
167
+ ...(cleanup === undefined ? {} : { cleanup }),
168
+ });
169
+ const errorMessage = (cause) => cause instanceof Error ? cause.message : String(cause);
96
170
  /** Detect supported agents from their config files or stable installation markers. */
97
171
  export const detectClients = async (home, platform = process.platform, environment = process.env) => {
98
172
  const detected = [];
99
173
  for (const candidate of supportedClients(home, platform, environment)) {
100
- const [hasConfig, hasMarker] = await Promise.all([
101
- exists(candidate.configPath),
102
- candidate.markerPath === undefined ? false : exists(candidate.markerPath),
103
- ]);
104
- if (hasConfig || hasMarker)
174
+ if (candidate.configPathError !== undefined)
175
+ continue;
176
+ if (await clientEvidencePresent(candidate))
105
177
  detected.push(candidate);
106
178
  }
107
179
  return detected;
108
180
  };
109
181
  const major = (version) => Number.parseInt(version.split(".")[0] ?? "0", 10);
182
+ const clientEvidencePresent = async (client) => {
183
+ for (const path of clientEvidencePaths(client))
184
+ if (await exists(path))
185
+ return true;
186
+ return false;
187
+ };
110
188
  const exists = async (path) => {
111
189
  try {
112
190
  await access(path);