rea-agents 5.0.0 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (507) hide show
  1. package/README.md +168 -655
  2. package/bridge/android/ReaJadxBridge.java +14 -5
  3. package/bridge/ghidra/ReaGhidraBridge.java +173 -47
  4. package/bridge/hopper_bridge.py +310 -128
  5. package/bridge/mitmproxy/capture.py +208 -0
  6. package/bridge/native/rea_lldb_tracer.py +839 -0
  7. package/bridge/process/ProcessRunTokenReader.swift +297 -0
  8. package/bridge/process/ProcessRunTokenReaderMain.swift +35 -0
  9. package/bridge/pwndbg/core_context.py +101 -0
  10. package/bridge/pwndbg/launch.py +39 -0
  11. package/bridge/pwndbg/launch_impl.py +34 -0
  12. package/bridge/pwntools/decoder_runtime.py +59 -0
  13. package/bridge/pwntools/layout.py +39 -0
  14. package/bridge/pwntools/layout_impl.py +309 -0
  15. package/bridge/pwntools/recorded_crash.py +39 -0
  16. package/bridge/pwntools/recorded_crash_impl.py +147 -0
  17. package/dist/android/JadxConfiguration.js +196 -33
  18. package/dist/android/JadxMcpTransport.js +4 -0
  19. package/dist/android/JadxProtocol.js +6 -0
  20. package/dist/android/JadxProvider.js +20 -2
  21. package/dist/android/JadxSession.js +23 -4
  22. package/dist/application/AnalysisContextQueries.js +8 -35
  23. package/dist/application/AnalysisDocument.js +32 -0
  24. package/dist/application/AppBundleExecutable.js +67 -21
  25. package/dist/application/CallPathTracing.js +19 -3
  26. package/dist/application/CapabilityInventory.js +27 -3
  27. package/dist/application/ClientConfigurationDocument.js +871 -6
  28. package/dist/application/ClientRegistrationIdentity.js +26 -5
  29. package/dist/application/ClientRegistrationStatus.js +29 -14
  30. package/dist/application/DirectAnalysis.js +97 -33
  31. package/dist/application/Doctor.js +4 -2
  32. package/dist/application/DoctorScope.js +25 -13
  33. package/dist/application/EnhancedLiteralTracing.js +22 -25
  34. package/dist/application/EnhancedTools.js +13 -11
  35. package/dist/application/EvidenceBundleFiles.js +24 -12
  36. package/dist/application/FunctionAnalysisEvidence.js +2 -3
  37. package/dist/application/InventoryProjectionEvidence.js +4 -3
  38. package/dist/application/InvestigationProviders.js +3 -2
  39. package/dist/application/JsonFiles.js +50 -28
  40. package/dist/application/ProcedureAddressResolution.js +11 -0
  41. package/dist/application/ReconstructionCoverageService.js +7 -4
  42. package/dist/application/ReconstructionObligationCandidates.js +5 -1
  43. package/dist/application/ReconstructionObligationLedgerService.js +4 -3
  44. package/dist/application/Setup.js +13 -1
  45. package/dist/application/SetupClientConfiguration.js +10 -15
  46. package/dist/application/SetupHost.js +5 -2
  47. package/dist/application/SetupPlan.js +5 -3
  48. package/dist/application/SupportedClients.js +34 -1
  49. package/dist/application/Uninstall.js +4 -3
  50. package/dist/application/Update.js +18 -3
  51. package/dist/application/UpdateRuntime.js +46 -25
  52. package/dist/application/WebModuleTraceService.js +4 -2
  53. package/dist/application/WebNetworkCapturePort.js +1 -0
  54. package/dist/application/WebNetworkCaptureService.js +134 -0
  55. package/dist/application/WebRuntimeService.js +5 -3
  56. package/dist/application/WebScriptExportService.js +2 -2
  57. package/dist/application/WebSourceLocationService.js +4 -2
  58. package/dist/application/WindowsCapabilities.js +1 -1
  59. package/dist/application/WorkflowEvidence.js +82 -0
  60. package/dist/application/binary/AnalysisProviderEvaluation.js +21 -5
  61. package/dist/application/binary/AnalysisProviderRegistry.js +2 -0
  62. package/dist/application/binary/AnalysisSnapshotCache.js +52 -12
  63. package/dist/application/binary/BinarySession.js +131 -76
  64. package/dist/application/binary/BinarySessionOpen.js +19 -6
  65. package/dist/application/binary/BinarySessionRecords.js +45 -3
  66. package/dist/application/binary/BinarySessionStatus.js +17 -1
  67. package/dist/application/binary/CompositeProvider.js +13 -0
  68. package/dist/application/binary/LazyAnalysisProvider.js +3 -0
  69. package/dist/application/binaryDiagnostics/BinaryLayoutPort.js +1 -0
  70. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +59 -0
  71. package/dist/application/binaryDiagnostics/RecordedCrashPort.js +1 -0
  72. package/dist/application/binaryDiagnostics/RecordedCrashService.js +62 -0
  73. package/dist/application/evm/EvmInterfacePort.js +1 -0
  74. package/dist/application/evm/EvmInterfaceService.js +64 -0
  75. package/dist/application/investigation/EvidenceLedger.js +21 -7
  76. package/dist/application/investigation/InvestigationRecords.js +8 -0
  77. package/dist/application/javascript/JavaScriptAnalysisControl.js +34 -0
  78. package/dist/application/javascript/JavaScriptApplicationEvidence.js +25 -5
  79. package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +19 -2
  80. package/dist/application/javascript/JavaScriptApplicationService.js +34 -14
  81. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +5 -5
  82. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +47 -27
  83. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +39 -7
  84. package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +26 -2
  85. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +80 -27
  86. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +33 -12
  87. package/dist/application/javascript/JavaScriptModuleRelationships.js +37 -8
  88. package/dist/application/javascript/JavaScriptRecoveryService.js +4 -2
  89. package/dist/application/javascript/JavaScriptRuntimeObservationService.js +3 -1
  90. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +3 -3
  91. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +7 -7
  92. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +149 -72
  93. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +14 -15
  94. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +41 -1
  95. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +7 -7
  96. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +5 -9
  97. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +3 -3
  98. package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +118 -12
  99. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +3 -3
  100. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +27 -5
  101. package/dist/application/managed/ManagedApplicationGraphService.js +4 -3
  102. package/dist/application/managed/ManagedMemberComparisonService.js +7 -4
  103. package/dist/application/managed/ManagedNativeVerificationService.js +4 -3
  104. package/dist/application/managed/ManagedReconstructionService.js +4 -3
  105. package/dist/application/{ProcessCli.js → process/ProcessCli.js} +23 -15
  106. package/dist/application/{ProcessEvidence.js → process/ProcessEvidence.js} +8 -7
  107. package/dist/application/workflowInputError.js +18 -0
  108. package/dist/artifacts/ArtifactProvider.js +42 -5
  109. package/dist/artifacts/ArtifactProviderMetadata.js +2 -1
  110. package/dist/artifacts/MachOSliceArtifactReader.js +98 -14
  111. package/dist/artifacts/NativeDmgArtifactReader.js +13 -6
  112. package/dist/artifacts/ZipArtifactReader.js +3 -0
  113. package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +22 -3
  114. package/dist/artifacts/apple/DylibResolutionReader.js +259 -0
  115. package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +176 -56
  116. package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +195 -0
  117. package/dist/artifacts/apple/KeyedArchiveReader.js +36 -22
  118. package/dist/artifacts/apple/MachoLoadCommandReader.js +355 -0
  119. package/dist/artifacts/apple/NibArchive.js +81 -14
  120. package/dist/artifacts/apple/NibViewHierarchy.js +10 -3
  121. package/dist/artifacts/apple/PlistNumberLiterals.js +164 -0
  122. package/dist/{application → artifacts/extraction}/ArtifactExtraction.js +10 -10
  123. package/dist/{application → artifacts/inventory}/ArtifactGraphConstruction.js +16 -11
  124. package/dist/{application → artifacts/inventory}/ArtifactInventory.js +4 -4
  125. package/dist/{application/ArtifactInventory → artifacts/inventory}/classify.js +2 -2
  126. package/dist/{application/ArtifactInventory → artifacts/inventory}/reader.js +5 -5
  127. package/dist/{application/ArtifactInventory → artifacts/inventory}/scanCanonical.js +14 -17
  128. package/dist/{application/ArtifactInventory → artifacts/inventory}/scanReader.js +5 -5
  129. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +6 -2
  130. package/dist/artifacts/readStableArtifact.js +20 -4
  131. package/dist/browser/CdpCaptureCompleteness.js +2 -0
  132. package/dist/browser/CdpCaptureEventHandlers.js +165 -12
  133. package/dist/browser/CdpCaptureEventTypes.js +5 -1
  134. package/dist/browser/CdpCaptureEvents.js +34 -0
  135. package/dist/browser/CdpConnection.js +30 -11
  136. package/dist/browser/CdpOptionalCommand.js +2 -3
  137. package/dist/browser/CdpPageCapture.js +23 -1
  138. package/dist/browser/PlaywrightElectronActiveActions.js +32 -23
  139. package/dist/browser/PlaywrightElectronActiveProjection.js +141 -0
  140. package/dist/browser/PlaywrightElectronActiveProvider.js +130 -122
  141. package/dist/browser/WebSourceMapFetcher.js +426 -72
  142. package/dist/browser/assets/LocalWebScriptArtifacts.js +2 -2
  143. package/dist/browser/history/CaptureFailures.js +137 -0
  144. package/dist/browser/history/CaptureFormatError.js +10 -0
  145. package/dist/browser/history/CaptureRedaction.js +65 -0
  146. package/dist/browser/history/CaptureRelease.js +17 -0
  147. package/dist/browser/history/HarCapture.js +165 -0
  148. package/dist/browser/history/HarCaptureAdapter.js +20 -0
  149. package/dist/browser/history/HarCaptureProcess.js +57 -0
  150. package/dist/browser/history/HarJson.js +92 -0
  151. package/dist/browser/history/HarSchema.js +72 -0
  152. package/dist/browser/history/HistoricalCaptureDecoder.js +188 -0
  153. package/dist/browser/history/HistoricalCaptureFormatAdapter.js +1 -0
  154. package/dist/browser/history/MitmproxyCaptureAdapter.js +42 -0
  155. package/dist/cli/analysisSelector.js +23 -0
  156. package/dist/cli/applicationCommands.js +2 -3
  157. package/dist/cli/artifactCommands.js +26 -1
  158. package/dist/cli/binaryDiagnosticsCommands.js +39 -0
  159. package/dist/cli/coreAnalysisCommands.js +2 -2
  160. package/dist/cli/coreBinaryCommands.js +78 -20
  161. package/dist/cli/electronCommands.js +21 -13
  162. package/dist/cli/evmCommands.js +24 -0
  163. package/dist/cli/firmwareCommands.js +6 -3
  164. package/dist/cli/javascriptApplicationAnalysis.js +20 -3
  165. package/dist/cli/jsonOutput.js +38 -0
  166. package/dist/cli/nativeCallCommands.js +34 -0
  167. package/dist/cli/processCommands.js +1 -1
  168. package/dist/cli/streamedJsonOutput.js +56 -0
  169. package/dist/cli/utilityCommands.js +2 -0
  170. package/dist/cli/webNetworkCaptureCommands.js +40 -0
  171. package/dist/cli/webRuntimeCommands.js +8 -8
  172. package/dist/cli.js +11 -4
  173. package/dist/cliBrowserScenarioCommands.js +2 -2
  174. package/dist/cliCommandNames.js +6 -1
  175. package/dist/cliJsonInput.js +35 -1
  176. package/dist/cliOutput.js +21 -6
  177. package/dist/composition/binaryDiagnostics.js +8 -0
  178. package/dist/composition/evm.js +4 -0
  179. package/dist/composition/webNetworkCaptures.js +6 -0
  180. package/dist/config/environment.js +4 -0
  181. package/dist/config/ghidraStartupTimeout.js +17 -0
  182. package/dist/config/mcpResponseBudget.js +22 -0
  183. package/dist/config/parseConfig.js +2 -1
  184. package/dist/contracts/artifactToolContracts.js +6 -0
  185. package/dist/contracts/browserCaptureToolInputSchema.js +43 -0
  186. package/dist/contracts/browserToolContracts.js +4 -3
  187. package/dist/contracts/enhancedInputs.js +5 -3
  188. package/dist/contracts/enhancedToolContracts.js +3 -3
  189. package/dist/contracts/errorSchemas.js +8 -1
  190. package/dist/contracts/evm/evmToolContracts.js +20 -0
  191. package/dist/contracts/hopperMemoryContracts.js +2 -5
  192. package/dist/contracts/investigationExamples.js +2 -2
  193. package/dist/contracts/javascript/electronToolContracts.js +1 -1
  194. package/dist/contracts/managed/managedToolContracts.js +8 -6
  195. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +42 -0
  196. package/dist/contracts/native/nativeToolContracts.js +21 -3
  197. package/dist/contracts/officialToolContracts.js +26 -24
  198. package/dist/contracts/process/processCaptureExample.js +2 -0
  199. package/dist/contracts/promptContracts.js +3 -3
  200. package/dist/contracts/sessionLifecycleInputs.js +18 -5
  201. package/dist/contracts/sessionStatusContract.js +8 -2
  202. package/dist/contracts/sessionToolContracts.js +8 -3
  203. package/dist/contracts/sessionToolSchemas.js +8 -4
  204. package/dist/contracts/toolContractExamples.js +1 -2
  205. package/dist/contracts/toolContractHelpers.js +4 -1
  206. package/dist/contracts/toolContracts.js +6 -0
  207. package/dist/contracts/toolEffects.js +30 -1
  208. package/dist/contracts/toolOutputSchemaGroups.js +33 -28
  209. package/dist/contracts/toolOutputSchemaPrimitives.js +19 -1
  210. package/dist/contracts/toolSchemaMetadata.js +69 -10
  211. package/dist/contracts/webNetworkCaptureToolContracts.js +24 -0
  212. package/dist/domain/analysisErrorBase.js +22 -2
  213. package/dist/domain/analysisErrorCore.js +61 -5
  214. package/dist/domain/analysisErrorPresentation.js +95 -12
  215. package/dist/domain/analysisErrorProjection.js +148 -19
  216. package/dist/domain/analysisSnapshot.js +166 -2
  217. package/dist/domain/android/androidAnalysis.js +2 -4
  218. package/dist/domain/android/androidApplication.js +17 -9
  219. package/dist/domain/apple/appleApplication.js +41 -14
  220. package/dist/domain/apple/dyldEnvironment.js +73 -0
  221. package/dist/domain/apple/dyldPaths.js +81 -0
  222. package/dist/domain/apple/dylibResolution.js +478 -0
  223. package/dist/domain/apple/dylibResolutionFindings.js +77 -0
  224. package/dist/domain/apple/interfaceBuilderGraph.js +25 -13
  225. package/dist/domain/apple/interfaceBuilderKeyedArchive.js +13 -3
  226. package/dist/domain/apple/keyedArchive.js +9 -1
  227. package/dist/domain/apple/machoContainer.js +54 -0
  228. package/dist/domain/apple/plistNumbers.js +76 -0
  229. package/dist/domain/artifactIdentity.js +29 -0
  230. package/dist/domain/artifactInventoryEvidence.js +19 -24
  231. package/dist/domain/artifactPathSyntax.js +1 -1
  232. package/dist/domain/bridgeCandidateProjection.js +71 -0
  233. package/dist/domain/browserCompleteness.js +1 -0
  234. package/dist/domain/browserObservation.js +1 -1
  235. package/dist/domain/browserObservationError.js +24 -5
  236. package/dist/domain/browserObservationSchemas.js +13 -0
  237. package/dist/domain/browserScenarioValues.js +5 -2
  238. package/dist/domain/bundleComparison.js +3 -2
  239. package/dist/domain/callPathSchemas.js +1 -1
  240. package/dist/domain/canonicalDigest.js +13 -1
  241. package/dist/domain/canonicalJsonDigestSteps.js +133 -0
  242. package/dist/domain/canonicalOrdering.js +9 -5
  243. package/dist/domain/changedBehavior.js +9 -9
  244. package/dist/domain/comparisonSourceEvidence.js +40 -0
  245. package/dist/domain/comparisonStatus.js +2 -30
  246. package/dist/domain/configurationErrors.js +1 -1
  247. package/dist/domain/conformanceTrustGate.js +0 -16
  248. package/dist/domain/evidence.js +78 -11
  249. package/dist/domain/evidenceBundle.js +42 -1
  250. package/dist/domain/evidenceErrors.js +12 -1
  251. package/dist/domain/evm/evmInterface.js +63 -0
  252. package/dist/domain/explicitSensitiveFailure.js +108 -0
  253. package/dist/domain/explicitSensitiveValues.js +10 -0
  254. package/dist/domain/firmware/firmwareAnalysis.js +10 -4
  255. package/dist/domain/hopperErrors.js +23 -2
  256. package/dist/domain/hopperValues.js +51 -8
  257. package/dist/domain/immutableJson.js +114 -0
  258. package/dist/domain/inputIssueProjection.js +3 -0
  259. package/dist/domain/javascript/electronActiveObservation.js +37 -6
  260. package/dist/domain/javascript/electronStaticAnalysisValues.js +6 -12
  261. package/dist/domain/javascript/htmlArtifactReferences.js +40 -0
  262. package/dist/domain/javascript/javascriptApplicationAnalysis.js +71 -23
  263. package/dist/domain/javascript/javascriptApplicationGraph.js +13 -0
  264. package/dist/domain/javascript/javascriptAstValues.js +20 -0
  265. package/dist/domain/javascript/javascriptExportShapeComparison.js +21 -5
  266. package/dist/domain/javascript/javascriptExportShapeVariants.js +0 -10
  267. package/dist/domain/javascript/javascriptRecovery.js +3 -8
  268. package/dist/domain/javascript/javascriptSemanticAnalysis.js +97 -2
  269. package/dist/domain/javascript/javascriptSemanticCoverage.js +6 -5
  270. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +9 -17
  271. package/dist/domain/javascript/javascriptSemanticDataEffects.js +22 -5
  272. package/dist/domain/javascript/javascriptSemanticGraph.js +34 -5
  273. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +1 -0
  274. package/dist/domain/javascript/javascriptSemanticPrimitives.js +25 -17
  275. package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -4
  276. package/dist/domain/javascript/javascriptSemanticResourceLimits.js +77 -0
  277. package/dist/domain/javascript/javascriptSemanticValues.js +83 -11
  278. package/dist/domain/javascript/javascriptSourceParser.js +6 -2
  279. package/dist/domain/javascript/javascriptStaticAnalysis.js +22 -17
  280. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -3
  281. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +14 -4
  282. package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +66 -7
  283. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +28 -16
  284. package/dist/domain/javascript/javascriptStaticAnalysisState.js +3 -2
  285. package/dist/domain/jsonSerialization.js +109 -0
  286. package/dist/domain/jsonValue.js +91 -3
  287. package/dist/domain/localPath.js +8 -0
  288. package/dist/domain/managed/managedApplicationGraph.js +10 -10
  289. package/dist/domain/managed/managedInspectionEvidence.js +16 -0
  290. package/dist/domain/managed/managedMemberComparisonMatch.js +5 -9
  291. package/dist/domain/managed/managedNativeVerification.js +3 -9
  292. package/dist/domain/native/binaryLayout.js +357 -0
  293. package/dist/domain/native/fileOffsetPartialObservation.js +1 -0
  294. package/dist/domain/native/nativeCallObservation.js +186 -0
  295. package/dist/domain/native/nativeCallPartialObservation.js +33 -0
  296. package/dist/domain/native/objcSwiftMetadata.js +0 -39
  297. package/dist/domain/native/recordedCrash.js +266 -0
  298. package/dist/domain/native/recordedCrashNoteCoverage.js +73 -0
  299. package/dist/domain/{processCapture.js → process/processCapture.js} +143 -2
  300. package/dist/domain/{processCaptureExample.js → process/processCaptureExample.js} +5 -0
  301. package/dist/domain/process/processCaptureParsing.js +54 -0
  302. package/dist/domain/{processCaptureValidation.js → process/processCaptureValidation.js} +18 -2
  303. package/dist/domain/{processComparison.js → process/processComparison.js} +39 -5
  304. package/dist/domain/{processObservation.js → process/processObservation.js} +1 -1
  305. package/dist/domain/{processScenario.js → process/processScenario.js} +11 -10
  306. package/dist/domain/{processTraceSpecification.js → process/processTraceSpecification.js} +1 -1
  307. package/dist/domain/propertyListKeys.js +1 -1
  308. package/dist/domain/propertyListXmlText.js +19 -0
  309. package/dist/domain/providerAdapterError.js +1 -1
  310. package/dist/domain/providerOperationHealth.js +54 -0
  311. package/dist/domain/providerSelectionError.js +4 -2
  312. package/dist/domain/reconstructionVerification.js +9 -46
  313. package/dist/domain/reconstructionVerificationSchemas.js +3 -3
  314. package/dist/domain/residualUnknown.js +3 -2
  315. package/dist/domain/staticRuntimeCorrelation.js +9 -46
  316. package/dist/domain/webBundleAnalysis.js +20 -8
  317. package/dist/domain/webBundleAnalyzerInspection.js +13 -8
  318. package/dist/domain/webBundleAnalyzerResult.js +41 -2
  319. package/dist/domain/webCaptureDiff.js +1 -0
  320. package/dist/domain/webNetworkCapture.js +118 -0
  321. package/dist/domain/webNetworkCaptureCoordinates.js +58 -0
  322. package/dist/domain/webRuntime.js +19 -5
  323. package/dist/domain/webSourceLocation.js +1 -0
  324. package/dist/dotnet/ManagedExceptionRegionValidation.js +41 -0
  325. package/dist/dotnet/ManagedMemberInspector.js +4 -2
  326. package/dist/dotnet/ManagedMemberInspectorCore.js +38 -32
  327. package/dist/dotnet/ManagedMemberInstructionDecoder.js +23 -7
  328. package/dist/dotnet/ManagedMemberRows.js +14 -3
  329. package/dist/dotnet/ManagedMetadataHeaps.js +20 -2
  330. package/dist/dotnet/ManagedMetadataInventory.js +38 -28
  331. package/dist/dotnet/ManagedMetadataInventoryRows.js +24 -10
  332. package/dist/dotnet/ManagedMethodBodyReader.js +7 -1
  333. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +15 -3
  334. package/dist/dotnet/ManagedNativeBoundaryInspector.js +3 -1
  335. package/dist/dotnet/ManagedPeReader.js +11 -0
  336. package/dist/evm/EvmBytecodeCarrier.js +21 -0
  337. package/dist/evm/EvmWorkerLimits.js +40 -0
  338. package/dist/evm/EvmoleFailures.js +126 -0
  339. package/dist/evm/EvmoleInterfaceAdapter.js +53 -0
  340. package/dist/evm/EvmoleInterfaceProvider.js +273 -0
  341. package/dist/evm/EvmoleInterfaceWorker.js +87 -0
  342. package/dist/evm/EvmoleRelease.js +16 -0
  343. package/dist/firmware/FirmwareCommand.js +1 -0
  344. package/dist/firmware/FirmwareFiles.js +1 -1
  345. package/dist/generatedPackageMetadata.js +2 -2
  346. package/dist/ghidra/GhidraAnalysisProfile.js +5 -0
  347. package/dist/ghidra/GhidraClient.js +47 -14
  348. package/dist/ghidra/GhidraDiagnostics.js +7 -7
  349. package/dist/ghidra/GhidraFunctionValues.js +10 -7
  350. package/dist/ghidra/GhidraInstallation.js +18 -21
  351. package/dist/ghidra/GhidraInventoryValues.js +14 -4
  352. package/dist/ghidra/GhidraJavaLaunch.js +62 -0
  353. package/dist/ghidra/GhidraLauncher.js +34 -16
  354. package/dist/ghidra/GhidraProvider.js +2 -2
  355. package/dist/ghidra/GhidraProviderCapabilities.js +15 -3
  356. package/dist/ghidra/GhidraProviderClient.js +23 -12
  357. package/dist/ghidra/GhidraSessionError.js +11 -7
  358. package/dist/ghidra/GhidraTargetSnapshot.js +47 -12
  359. package/dist/ghidra/GhidraTransport.js +20 -0
  360. package/dist/hopper/BridgeLauncher.js +33 -11
  361. package/dist/hopper/HopperAnalysisProfile.js +62 -4
  362. package/dist/hopper/HopperCleanup.js +15 -3
  363. package/dist/hopper/HopperClient.js +222 -14
  364. package/dist/hopper/HopperFileOffset.js +237 -0
  365. package/dist/hopper/HopperMachOImage.js +196 -0
  366. package/dist/hopper/HopperOperationStage.js +6 -0
  367. package/dist/hopper/HopperProvider.js +63 -9
  368. package/dist/hopper/HopperProviderCapabilities.js +19 -1
  369. package/dist/hopper/HopperRegexSearch.js +137 -0
  370. package/dist/hopper/HopperRegexWorker.js +27 -0
  371. package/dist/hopper/HopperRequestQueue.js +68 -19
  372. package/dist/hopper/HopperTargetLease.js +3 -2
  373. package/dist/hopper/LinuxPrivateDisplayProbe.js +4 -2
  374. package/dist/inspector/JavaScriptRuntimeScope.js +9 -1
  375. package/dist/inspector/V8InspectorCaptureProjection.js +8 -3
  376. package/dist/inspector/V8InspectorProvider.js +47 -11
  377. package/dist/javascript/recovery/WakaruCommand.js +3 -0
  378. package/dist/javascript/sourceMaps/DecodedSourceMap.js +47 -0
  379. package/dist/javascript/sourceMaps/SourceMapCommand.js +17 -0
  380. package/dist/javascript/sourceMaps/SourceMapFormat.js +79 -31
  381. package/dist/javascript/sourceMaps/TraceSourceMap.js +14 -28
  382. package/dist/mcpDoctor.js +62 -2
  383. package/dist/native/AppleDispatchCoverage.js +47 -6
  384. package/dist/native/AppleDispatchDecodeFacts.js +6 -0
  385. package/dist/native/AppleDispatchMetadata.js +6 -3
  386. package/dist/native/AppleMachoFixups.js +48 -24
  387. package/dist/native/AppleMachoSelection.js +32 -16
  388. package/dist/native/AppleObjcCategories.js +6 -2
  389. package/dist/native/AppleObjcDispatchFacets.js +5 -2
  390. package/dist/native/AppleObjcProperties.js +2 -1
  391. package/dist/native/AppleSwiftDispatchFacets.js +27 -21
  392. package/dist/native/AppleSwiftVtables.js +21 -15
  393. package/dist/native/CommandRunner.js +82 -84
  394. package/dist/native/LldbCallTracer.js +541 -0
  395. package/dist/native/LldbRetainedObservations.js +178 -0
  396. package/dist/native/NativeCallObservation.js +194 -0
  397. package/dist/native/NativeMacOSProvider.js +117 -20
  398. package/dist/native/NativeMacOSProviderMetadata.js +8 -3
  399. package/dist/native/SignatureTargetBinding.js +155 -0
  400. package/dist/native/parsers/lipo.js +71 -1
  401. package/dist/native/pwndbg/PwndbgCoreContext.js +180 -0
  402. package/dist/native/pwntools/PwntoolsDecoder.js +203 -0
  403. package/dist/native/pwntools/PwntoolsFailures.js +180 -0
  404. package/dist/native/pwntools/PwntoolsLayoutProvider.js +36 -0
  405. package/dist/native/pwntools/PwntoolsRecordedCrashProvider.js +75 -0
  406. package/dist/native/pwntools/PwntoolsRelease.js +19 -0
  407. package/dist/native/pwntools/PwntoolsResourceLimits.js +76 -0
  408. package/dist/native/pwntools/RecordedCrashSourceBindings.js +46 -0
  409. package/dist/native/pwntools/RecordedCrashStructureBindings.js +103 -0
  410. package/dist/process/DarwinProcessRunTokenReader.js +293 -0
  411. package/dist/process/ExecFileOutput.js +20 -0
  412. package/dist/process/OwnedCommand.js +118 -0
  413. package/dist/process/ProcessOwnership.js +431 -51
  414. package/dist/process/ProcessOwnershipObservation.js +209 -27
  415. package/dist/process/ProviderProcess.js +68 -10
  416. package/dist/{application → process/capture}/ProcessCaptureCapability.js +15 -0
  417. package/dist/{application → process/capture}/ProcessCaptureError.js +18 -2
  418. package/dist/process/capture/ProcessCaptureLifecycle.js +681 -0
  419. package/dist/{application → process/capture}/ProcessHarness.js +195 -29
  420. package/dist/{application → process/capture}/ProcessSampling.js +2 -2
  421. package/dist/server/EvidenceMcpServer.js +146 -0
  422. package/dist/server/createServer.js +37 -8
  423. package/dist/server/promptCompletion.js +10 -3
  424. package/dist/server/registerAndroidTools.js +2 -4
  425. package/dist/server/registerApplicationTools/helpers.js +2 -4
  426. package/dist/server/registerArtifactComparisonTool.js +11 -7
  427. package/dist/server/registerBinaryDiagnosticsTools.js +15 -0
  428. package/dist/server/registerBrowserScenarioTool.js +2 -4
  429. package/dist/server/registerBrowserTools.js +2 -4
  430. package/dist/server/registerBundleComparisonTool.js +2 -3
  431. package/dist/server/registerCloseLifecycleTool.js +8 -18
  432. package/dist/server/registerElectronTools.js +2 -4
  433. package/dist/server/registerEnhancedTools.js +18 -59
  434. package/dist/server/registerEvidenceTools.js +3 -5
  435. package/dist/server/registerEvmTools.js +15 -0
  436. package/dist/server/registerFirmwareTools.js +2 -4
  437. package/dist/server/registerFunctionComparisonTool.js +10 -6
  438. package/dist/server/registerInvestigationTools.js +7 -7
  439. package/dist/server/registerJavaScriptRecoveryTool.js +2 -4
  440. package/dist/server/registerJavaScriptRuntimeObservationTools.js +2 -4
  441. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +2 -4
  442. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +2 -4
  443. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +2 -4
  444. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +2 -4
  445. package/dist/server/registerOfficialTools.js +2 -4
  446. package/dist/server/registerProcessComparisonTool.js +72 -46
  447. package/dist/server/registerRecordedCrashTools.js +15 -0
  448. package/dist/server/registerSessionRecordTools.js +5 -6
  449. package/dist/server/registerSessionStatusTool.js +17 -3
  450. package/dist/server/registerSessionTools.js +13 -5
  451. package/dist/server/registerWebModuleTool.js +2 -4
  452. package/dist/server/registerWebNetworkCaptureTool.js +26 -0
  453. package/dist/server/registerWebRuntimeTools.js +3 -7
  454. package/dist/server/registerWebScriptTool.js +2 -4
  455. package/dist/server/registerWebSourceLocationTool.js +2 -4
  456. package/dist/server/runDerivedOperation.js +15 -3
  457. package/dist/server/sessionAvailabilityPolicy.js +3 -1
  458. package/dist/server/sessionToolPolicies.js +1 -1
  459. package/dist/server/toolRegistrationOptions.js +2 -2
  460. package/dist/server/toolResult.js +63 -11
  461. package/dist/server/toolResultEncoding.js +33 -0
  462. package/install.sh +1 -1
  463. package/native/windows/build/manifest.json +2 -2
  464. package/native/windows/build/rea-windows-x64.node +0 -0
  465. package/package.json +42 -9
  466. package/scripts/electron-active-hook-boundaries.cjs +18 -20
  467. package/scripts/electron-active-hook.cjs +241 -37
  468. package/scripts/rea.mjs +11 -3
  469. package/skills/reverse-engineer-anything/SKILL.md +32 -4
  470. package/skills/reverse-engineer-anything/references/javascript-applications.md +8 -1
  471. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +29 -0
  472. package/third_party/README.md +60 -0
  473. package/third_party/evmole/LICENSE +21 -0
  474. package/third_party/evmole/README.md +22 -0
  475. package/third_party/pwndbg/LICENSE.md +21 -0
  476. package/third_party/pwndbg/README.md +23 -0
  477. package/third_party/pwntools/README.md +40 -0
  478. package/dist/application/AuthorizedArtifactInventory.js +0 -7
  479. package/dist/application/ProcessCaptureLifecycle.js +0 -299
  480. package/dist/application/StoreFileLock.js +0 -124
  481. package/dist/contracts/processCaptureExample.js +0 -2
  482. package/dist/domain/bytecodeProvider.js +0 -178
  483. package/dist/domain/customProtocolCapture.js +0 -137
  484. package/dist/domain/eventProcessTree.js +0 -225
  485. package/dist/domain/mobileApplicationInvestigation.js +0 -159
  486. package/dist/domain/packageAnalysis.js +0 -123
  487. package/dist/domain/peInspection.js +0 -197
  488. package/dist/domain/processCaptureParsing.js +0 -21
  489. package/dist/domain/protocolCapture.js +0 -217
  490. package/dist/domain/runtimeIdentification.js +0 -212
  491. package/dist/generatedMcpToolCatalog.js +0 -37
  492. package/dist/ghidra/GhidraDefaults.js +0 -2
  493. /package/dist/application/{ArtifactExtractionDestination.js → artifacts/ArtifactExtractionDestination.js} +0 -0
  494. /package/dist/{application/ArtifactInventory → artifacts/inventory}/policy.js +0 -0
  495. /package/dist/{application/ArtifactInventory → artifacts/inventory}/types.js +0 -0
  496. /package/dist/domain/{processEvidenceProvider.js → process/processEvidenceProvider.js} +0 -0
  497. /package/dist/domain/{processTraceComparison.js → process/processTraceComparison.js} +0 -0
  498. /package/dist/domain/{processTraceDimensionProjection.js → process/processTraceDimensionProjection.js} +0 -0
  499. /package/dist/domain/{processTraceEvaluation.js → process/processTraceEvaluation.js} +0 -0
  500. /package/dist/{application → process/capture}/FilesystemSnapshot.js +0 -0
  501. /package/dist/{application → process/capture}/ProcessCaptureEnvironment.js +0 -0
  502. /package/dist/{application → process/capture}/ProcessCaptureJournal.js +0 -0
  503. /package/dist/{application → process/capture}/ProcessFilesystemEffects.js +0 -0
  504. /package/dist/{application → process/capture}/ProcessNormalization.js +0 -0
  505. /package/dist/{application → process/capture}/ProcessScenarioRuntimeValidation.js +0 -0
  506. /package/dist/{application → process/capture}/ProcessTimer.js +0 -0
  507. /package/dist/{application → process/capture}/TerminalRenderer.js +0 -0
@@ -1,7 +1,8 @@
1
1
  import { parse as parseToml, stringify as stringifyToml } from "smol-toml";
2
2
  import { isDeepStrictEqual } from "node:util";
3
- import { applyEdits, modify, parse as parseJsonc, printParseErrorCode, } from "jsonc-parser";
3
+ import { applyEdits, findNodeAtLocation, modify, parse as parseJsonc, parseTree, printParseErrorCode, } from "jsonc-parser";
4
4
  import { z } from "zod";
5
+ import { PRODUCT_IDENTITY } from "../identity.js";
5
6
  const objectSchema = z.record(z.string(), z.unknown());
6
7
  /** Compare parsed configuration values without depending on parser prototypes. */
7
8
  export const clientConfigurationValuesEqual = (left, right) => isDeepStrictEqual(normalizeConfigurationValue(left), normalizeConfigurationValue(right));
@@ -18,6 +19,7 @@ const normalizeConfigurationValue = (value) => {
18
19
  export const clientConfigurationServersKey = (format) => {
19
20
  switch (format) {
20
21
  case "toml":
22
+ case "grok":
21
23
  return "mcp_servers";
22
24
  case "opencode":
23
25
  return "mcp";
@@ -27,9 +29,18 @@ export const clientConfigurationServersKey = (format) => {
27
29
  return "mcpServers";
28
30
  }
29
31
  };
32
+ /**
33
+ * Whether raw configuration text holds no settings to preserve. Some clients
34
+ * create a zero-byte config file before any server is added.
35
+ */
36
+ const isEmptyClientConfigurationText = (text) => text.replace(/^\uFEFF/, "").trim() === "";
30
37
  const parseDocument = (text, format) => {
31
- if (format === "toml")
38
+ if (format === "toml" || format === "grok")
32
39
  return objectSchema.parse(parseToml(text));
40
+ // An empty file, which some clients create before any server is added,
41
+ // holds no settings to preserve.
42
+ if (isEmptyClientConfigurationText(text))
43
+ return {};
33
44
  const errors = [];
34
45
  // Accept a UTF-8 BOM without shifting diagnostics or editing the original text.
35
46
  const jsonText = text.startsWith("\uFEFF") ? ` ${text.slice(1)}` : text;
@@ -101,16 +112,870 @@ const valueAt = (document, path) => {
101
112
  }
102
113
  return current;
103
114
  };
115
+ const TOML_BASIC_ESCAPES = {
116
+ b: "\b",
117
+ t: "\t",
118
+ n: "\n",
119
+ f: "\f",
120
+ r: "\r",
121
+ e: "\u001b",
122
+ '"': '"',
123
+ "\\": "\\",
124
+ };
125
+ const skipHorizontalSpace = (line, index) => {
126
+ let next = index;
127
+ while (line[next] === " " || line[next] === "\t")
128
+ next += 1;
129
+ return next;
130
+ };
131
+ const decodeBasicEscape = (line, slash) => {
132
+ const escape = line[slash + 1];
133
+ if (escape === undefined)
134
+ return undefined;
135
+ const simple = TOML_BASIC_ESCAPES[escape];
136
+ if (simple !== undefined)
137
+ return { value: simple, next: slash + 2 };
138
+ // smol-toml accepts `\xHH` even though TOML 1.0 does not.
139
+ if (escape === "x") {
140
+ const hex = line.slice(slash + 2, slash + 4);
141
+ if (!/^[0-9A-Fa-f]{2}$/u.test(hex))
142
+ return undefined;
143
+ return {
144
+ value: String.fromCodePoint(Number.parseInt(hex, 16)),
145
+ next: slash + 4,
146
+ };
147
+ }
148
+ if (escape !== "u" && escape !== "U")
149
+ return undefined;
150
+ const length = escape === "u" ? 4 : 8;
151
+ const hex = line.slice(slash + 2, slash + 2 + length);
152
+ if (!new RegExp(`^[0-9A-Fa-f]{${String(length)}}$`, "u").test(hex))
153
+ return undefined;
154
+ const code = Number.parseInt(hex, 16);
155
+ if (code > 0x10ffff || (code >= 0xd800 && code <= 0xdfff))
156
+ return undefined;
157
+ return { value: String.fromCodePoint(code), next: slash + 2 + length };
158
+ };
159
+ /** Read one single-line quoted key. Multiline quotes are not a header key. */
160
+ const parseQuotedKey = (line, start) => {
161
+ const quote = line[start];
162
+ if ((quote !== '"' && quote !== "'") ||
163
+ line.startsWith(quote === '"' ? '"""' : "'''", start))
164
+ return undefined;
165
+ if (quote === "'") {
166
+ const end = line.indexOf("'", start + 1);
167
+ if (end < 0 || line.slice(start + 1, end).includes("\n"))
168
+ return undefined;
169
+ return { value: line.slice(start + 1, end), next: end + 1 };
170
+ }
171
+ let value = "";
172
+ let index = start + 1;
173
+ while (index < line.length) {
174
+ const char = line[index];
175
+ if (char === "\n" || char === "\r")
176
+ return undefined;
177
+ if (char === '"')
178
+ return { value, next: index + 1 };
179
+ if (char !== "\\") {
180
+ value += char ?? "";
181
+ index += 1;
182
+ continue;
183
+ }
184
+ const decoded = decodeBasicEscape(line, index);
185
+ if (decoded === undefined)
186
+ return undefined;
187
+ value += decoded.value;
188
+ index = decoded.next;
189
+ }
190
+ return undefined;
191
+ };
192
+ const parseBareKey = (line, start) => {
193
+ let index = start;
194
+ while (/[A-Za-z0-9_-]/u.test(line[index] ?? ""))
195
+ index += 1;
196
+ if (index === start)
197
+ return undefined;
198
+ return { value: line.slice(start, index), next: index };
199
+ };
200
+ /**
201
+ * Parse a table header. Quoted segments stay one key, so `mcp_servers."rea.env"`
202
+ * is not the dotted path `mcp_servers.rea.env`.
203
+ */
204
+ const parseTomlTableHeader = (line) => {
205
+ let index = skipHorizontalSpace(line, 0);
206
+ const array = line.startsWith("[[", index);
207
+ if (!array && line[index] !== "[")
208
+ return undefined;
209
+ index += array ? 2 : 1;
210
+ const path = [];
211
+ for (;;) {
212
+ index = skipHorizontalSpace(line, index);
213
+ const key = line[index] === '"' || line[index] === "'"
214
+ ? parseQuotedKey(line, index)
215
+ : parseBareKey(line, index);
216
+ if (key === undefined)
217
+ return undefined;
218
+ path.push(key.value);
219
+ index = skipHorizontalSpace(line, key.next);
220
+ if (line[index] !== ".")
221
+ break;
222
+ index += 1;
223
+ }
224
+ const close = array ? "]]" : "]";
225
+ if (!line.startsWith(close, index))
226
+ return undefined;
227
+ index = skipHorizontalSpace(line, index + close.length);
228
+ if (index < line.length && line[index] !== "#")
229
+ return undefined;
230
+ return { path };
231
+ };
232
+ /**
233
+ * String state after one physical line, starting at `start`. A multiline
234
+ * closer does not end the scan: `""", """` closes one string and opens another.
235
+ */
236
+ const tomlStringModeAfter = (line, mode, start = 0) => {
237
+ if (mode === "ml-basic" || mode === "ml-literal") {
238
+ const delimiter = mode === "ml-basic" ? '"""' : "'''";
239
+ const closed = closeMultiline(line, start, delimiter, mode === "ml-basic");
240
+ if (closed === undefined)
241
+ return mode;
242
+ return tomlStringModeAfter(line, "none", closed);
243
+ }
244
+ let index = start;
245
+ while (index < line.length) {
246
+ if (line[index] === "#")
247
+ return "none";
248
+ if (line.startsWith('"""', index)) {
249
+ const closed = closeMultiline(line, index + 3, '"""', true);
250
+ if (closed === undefined)
251
+ return "ml-basic";
252
+ index = closed;
253
+ continue;
254
+ }
255
+ if (line.startsWith("'''", index)) {
256
+ const closed = closeMultiline(line, index + 3, "'''", false);
257
+ if (closed === undefined)
258
+ return "ml-literal";
259
+ index = closed;
260
+ continue;
261
+ }
262
+ const quote = line[index];
263
+ if (quote === '"' || quote === "'") {
264
+ const quoted = parseQuotedKey(line, index);
265
+ if (quoted === undefined)
266
+ return "none";
267
+ index = quoted.next;
268
+ continue;
269
+ }
270
+ index += 1;
271
+ }
272
+ return "none";
273
+ };
274
+ /** Index after a multiline delimiter, or undefined when this line does not close it. */
275
+ const closeMultiline = (line, start, delimiter, escapes) => {
276
+ let index = start;
277
+ while (index < line.length) {
278
+ if (escapes && line[index] === "\\") {
279
+ if (line[index + 1] === undefined)
280
+ return undefined;
281
+ index += 2;
282
+ continue;
283
+ }
284
+ if (line.startsWith(delimiter, index)) {
285
+ // One or two quotes before the closer belong to the string: """keep""""
286
+ let end = index + delimiter.length;
287
+ const quote = delimiter[0];
288
+ let extra = 0;
289
+ while (extra < 2 && line[end] === quote) {
290
+ extra += 1;
291
+ end += 1;
292
+ }
293
+ return end;
294
+ }
295
+ index += 1;
296
+ }
297
+ return undefined;
298
+ };
299
+ const isBlankOrComment = (line) => {
300
+ const trimmed = line.trimStart();
301
+ return trimmed === "" || trimmed.startsWith("#");
302
+ };
303
+ const looksLikeTomlHeader = (line) => line.trimStart().startsWith("[");
304
+ /** `mcp_servers.<server>` and tables nested under it, compared by key segment. */
305
+ const isGrokServerTable = (path, serverKey) => path[0] === "mcp_servers" && path[1] === serverKey;
306
+ const parseKeyPath = (text, start) => {
307
+ const segments = [];
308
+ let index = start;
309
+ for (;;) {
310
+ index = skipHorizontalSpace(text, index);
311
+ const current = text[index];
312
+ if (current === undefined || current === "\n" || current === "\r")
313
+ return undefined;
314
+ const key = current === '"' || current === "'"
315
+ ? parseQuotedKey(text, index)
316
+ : parseBareKey(text, index);
317
+ if (key === undefined)
318
+ return undefined;
319
+ segments.push(key.value);
320
+ index = skipHorizontalSpace(text, key.next);
321
+ if (text[index] !== ".")
322
+ return { segments, next: index };
323
+ index += 1;
324
+ }
325
+ };
326
+ const parseAssignment = (line) => {
327
+ const key = parseKeyPath(line, 0);
328
+ if (key === undefined)
329
+ return undefined;
330
+ const equals = skipHorizontalSpace(line, key.next);
331
+ if (line[equals] !== "=")
332
+ return undefined;
333
+ return { segments: key.segments, equals };
334
+ };
335
+ const skipWsAndComments = (text, start) => {
336
+ let index = start;
337
+ while (index < text.length) {
338
+ const char = text[index];
339
+ if (char === " " || char === "\t" || char === "\n" || char === "\r") {
340
+ index += 1;
341
+ continue;
342
+ }
343
+ if (char === "#") {
344
+ while (index < text.length && text[index] !== "\n")
345
+ index += 1;
346
+ continue;
347
+ }
348
+ return index;
349
+ }
350
+ return index;
351
+ };
352
+ /** Index after one TOML value. Containers and multiline strings may cross lines. */
353
+ const endOfTomlValue = (text, start) => {
354
+ const index = skipWsAndComments(text, start);
355
+ if (index >= text.length)
356
+ return index;
357
+ if (text.startsWith('"""', index)) {
358
+ const closed = closeMultiline(text, index + 3, '"""', true);
359
+ return closed ?? text.length;
360
+ }
361
+ if (text.startsWith("'''", index)) {
362
+ const closed = closeMultiline(text, index + 3, "'''", false);
363
+ return closed ?? text.length;
364
+ }
365
+ const quote = text[index];
366
+ if (quote === '"' || quote === "'") {
367
+ const quoted = parseQuotedKey(text, index);
368
+ return quoted === undefined ? text.length : quoted.next;
369
+ }
370
+ if (quote === "{" || quote === "[")
371
+ return endOfContainer(text, index);
372
+ let cursor = index;
373
+ while (cursor < text.length) {
374
+ const char = text[cursor];
375
+ if (char === "\n" ||
376
+ char === "#" ||
377
+ char === "," ||
378
+ char === "}" ||
379
+ char === "]")
380
+ break;
381
+ cursor += 1;
382
+ }
383
+ return cursor;
384
+ };
385
+ const endOfContainer = (text, open) => {
386
+ const closers = [text[open] === "{" ? "}" : "]"];
387
+ let index = open + 1;
388
+ while (index < text.length && closers.length > 0) {
389
+ if (text.startsWith('"""', index)) {
390
+ const closed = closeMultiline(text, index + 3, '"""', true);
391
+ if (closed === undefined)
392
+ return text.length;
393
+ index = closed;
394
+ continue;
395
+ }
396
+ if (text.startsWith("'''", index)) {
397
+ const closed = closeMultiline(text, index + 3, "'''", false);
398
+ if (closed === undefined)
399
+ return text.length;
400
+ index = closed;
401
+ continue;
402
+ }
403
+ const quote = text[index];
404
+ if (quote === '"' || quote === "'") {
405
+ const quoted = parseQuotedKey(text, index);
406
+ if (quoted === undefined)
407
+ return text.length;
408
+ index = quoted.next;
409
+ continue;
410
+ }
411
+ if (quote === "#") {
412
+ while (index < text.length && text[index] !== "\n")
413
+ index += 1;
414
+ continue;
415
+ }
416
+ if (quote === "{" || quote === "[") {
417
+ closers.push(quote === "{" ? "}" : "]");
418
+ index += 1;
419
+ continue;
420
+ }
421
+ if (quote === closers[closers.length - 1]) {
422
+ closers.pop();
423
+ index += 1;
424
+ continue;
425
+ }
426
+ index += 1;
427
+ }
428
+ return index;
429
+ };
430
+ /** TOML basic string. JSON leaves U+007F raw, which TOML rejects. */
431
+ const tomlBasicString = (value) => JSON.stringify(value).replaceAll("\u007f", "\\u007f");
432
+ const tomlInlineKey = (key) => /^[A-Za-z0-9_-]+$/u.test(key) ? key : tomlBasicString(key);
433
+ const tomlInlineValue = (value) => {
434
+ if (typeof value === "string")
435
+ return tomlBasicString(value);
436
+ if (typeof value === "boolean")
437
+ return value ? "true" : "false";
438
+ if (typeof value === "number" && Number.isFinite(value))
439
+ return String(value);
440
+ if (Array.isArray(value))
441
+ return `[${value.map((item) => tomlInlineValue(item)).join(", ")}]`;
442
+ if (typeof value === "object" && value !== null) {
443
+ const body = Object.entries(value)
444
+ .map(([key, nested]) => `${tomlInlineKey(key)} = ${tomlInlineValue(nested)}`)
445
+ .join(", ");
446
+ return `{ ${body} }`;
447
+ }
448
+ return '""';
449
+ };
450
+ const readTrivia = (text, start, limit) => {
451
+ let index = start;
452
+ while (index < limit) {
453
+ const char = text[index];
454
+ if (char === " " ||
455
+ char === "\t" ||
456
+ char === "\n" ||
457
+ char === "\r" ||
458
+ char === ",") {
459
+ index += 1;
460
+ continue;
461
+ }
462
+ if (char === "#") {
463
+ while (index < limit && text[index] !== "\n")
464
+ index += 1;
465
+ continue;
466
+ }
467
+ break;
468
+ }
469
+ return { text: text.slice(start, index), next: index };
470
+ };
471
+ const commasOutsideComments = (trivia) => trivia
472
+ .split("\n")
473
+ .map((part) => {
474
+ const comment = part.indexOf("#");
475
+ if (comment < 0)
476
+ return part.replaceAll(",", "");
477
+ return `${part.slice(0, comment).replaceAll(",", "")}${part.slice(comment)}`;
478
+ })
479
+ .join("\n");
480
+ const hasSeparatorComma = (trivia) => trivia.split("\n").some((part) => {
481
+ const comment = part.indexOf("#");
482
+ const code = comment < 0 ? part : part.slice(0, comment);
483
+ return code.includes(",");
484
+ });
485
+ /**
486
+ * Replace or remove `serverKey` inside one `{ ... }` table. A closed inline
487
+ * table cannot later grow a `[mcp_servers.rea]` header.
488
+ */
489
+ const editGrokInlineTable = (table, serverKey, entry) => {
490
+ if (!table.startsWith("{"))
491
+ return undefined;
492
+ const end = endOfContainer(table, 0);
493
+ if (table[end - 1] !== "}")
494
+ return undefined;
495
+ const pairs = [];
496
+ let index = 1;
497
+ let trailing = "";
498
+ while (index < end - 1) {
499
+ const trivia = readTrivia(table, index, end - 1);
500
+ if (trivia.next >= end - 1) {
501
+ trailing = trivia.text;
502
+ break;
503
+ }
504
+ const key = parseKeyPath(table, trivia.next);
505
+ if (key === undefined)
506
+ return undefined;
507
+ const equals = skipWsAndComments(table, key.next);
508
+ if (table[equals] !== "=")
509
+ return undefined;
510
+ const valueEnd = endOfTomlValue(table, equals + 1);
511
+ if (valueEnd > end - 1)
512
+ return undefined;
513
+ pairs.push({
514
+ leading: trivia.text,
515
+ text: table.slice(trivia.next, valueEnd),
516
+ drop: key.segments[0] === serverKey,
517
+ });
518
+ index = valueEnd;
519
+ }
520
+ const insertion = entry === undefined
521
+ ? undefined
522
+ : `${tomlInlineKey(serverKey)} = ${tomlInlineValue(entry)}`;
523
+ if (insertion === undefined && pairs.every((pair) => !pair.drop))
524
+ return table;
525
+ return rebuildInlineTable(pairs, trailing, insertion);
526
+ };
527
+ const rebuildInlineTable = (pairs, trailing, insertion) => rebuildDelimitedEntries(pairs, trailing, insertion, "{", "}");
528
+ /**
529
+ * Rebuild `{ ... }` or `[ ... ]` after dropping entries. An empty container
530
+ * keeps comment trivia; a table with no comments stays `{}`.
531
+ */
532
+ const rebuildDelimitedEntries = (pairs, trailing, insertion, open, close) => {
533
+ const parts = [open];
534
+ let emitted = false;
535
+ // A comma already emitted in a dropped pair's comment trivia.
536
+ let separatorPending = false;
537
+ for (const pair of pairs) {
538
+ if (pair.drop) {
539
+ if (!pair.leading.includes("#"))
540
+ continue;
541
+ // A separator already emitted must not be repeated for the next field.
542
+ const dropped = !emitted || separatorPending
543
+ ? commasOutsideComments(pair.leading)
544
+ : pair.leading;
545
+ parts.push(dropped);
546
+ separatorPending = separatorPending || hasSeparatorComma(dropped);
547
+ continue;
548
+ }
549
+ const kept = emitted ? pair.leading : commasOutsideComments(pair.leading);
550
+ parts.push(separatorPending ? commasOutsideComments(kept) : kept);
551
+ if (emitted && !separatorPending && !pair.leading.includes(","))
552
+ parts.push(", ");
553
+ separatorPending = false;
554
+ parts.push(pair.text);
555
+ emitted = true;
556
+ }
557
+ if (insertion !== undefined) {
558
+ if (!(emitted && separatorPending))
559
+ parts.push(emitted ? ", " : " ");
560
+ parts.push(insertion);
561
+ emitted = true;
562
+ }
563
+ if (!emitted) {
564
+ const retained = `${parts.slice(1).join("")}${commasOutsideComments(trailing)}`;
565
+ return retained.includes("#")
566
+ ? `${open}${retained}${close}`
567
+ : `${open}${close}`;
568
+ }
569
+ const tail = commasOutsideComments(trailing);
570
+ parts.push(tail);
571
+ if (tail === "" && open === "{")
572
+ parts.push(" ");
573
+ parts.push(close);
574
+ return parts.join("");
575
+ };
576
+ /**
577
+ * Decoded TOML string, or undefined when the token is not a string.
578
+ * The document parser accepts multiline basic and literal strings.
579
+ */
580
+ const tomlStringValue = (text) => {
581
+ try {
582
+ const value = parseToml(`value = ${text}`)["value"];
583
+ return typeof value === "string" ? value : undefined;
584
+ }
585
+ catch (cause) {
586
+ void cause;
587
+ return undefined;
588
+ }
589
+ };
590
+ /**
591
+ * Array text with `serverKey` removed. `""` means the assignment itself can
592
+ * be deleted. Undefined when the array cannot be edited safely.
593
+ */
594
+ const tomlArrayWithoutString = (array, serverKey) => {
595
+ if (!array.startsWith("["))
596
+ return undefined;
597
+ const end = endOfContainer(array, 0);
598
+ if (end !== array.length || array[end - 1] !== "]")
599
+ return undefined;
600
+ const pairs = [];
601
+ let index = 1;
602
+ let trailing = "";
603
+ while (index < end - 1) {
604
+ const trivia = readTrivia(array, index, end - 1);
605
+ if (trivia.next >= end - 1) {
606
+ trailing = trivia.text;
607
+ break;
608
+ }
609
+ const valueEnd = endOfTomlValue(array, trivia.next);
610
+ if (valueEnd > end - 1)
611
+ return undefined;
612
+ const text = array.slice(trivia.next, valueEnd);
613
+ pairs.push({
614
+ leading: trivia.text,
615
+ text,
616
+ drop: tomlStringValue(text) === serverKey,
617
+ });
618
+ index = valueEnd;
619
+ }
620
+ if (pairs.every((pair) => !pair.drop))
621
+ return array;
622
+ const rebuilt = rebuildDelimitedEntries(pairs, trailing, undefined, "[", "]");
623
+ return rebuilt === "[]" ? "" : rebuilt;
624
+ };
625
+ /** Drop `serverKey` from a root `disabled_mcp_servers` array while installing. */
626
+ const disabledServerListEdit = (input) => {
627
+ if (input.entry === undefined ||
628
+ input.tablePath.length !== 0 ||
629
+ input.segments.length !== 1 ||
630
+ input.segments[0] !== "disabled_mcp_servers")
631
+ return { kind: "ignore" };
632
+ const open = skipWsAndComments(input.text, input.valueOffset);
633
+ if (input.text[open] !== "[")
634
+ return { kind: "ignore" };
635
+ const arrayText = input.text.slice(open, input.valueEnd);
636
+ const edited = tomlArrayWithoutString(arrayText, input.serverKey);
637
+ if (edited === undefined || edited === arrayText)
638
+ return { kind: "keep" };
639
+ if (edited === "") {
640
+ const suffix = input.text.slice(input.valueEnd, input.statementEnd);
641
+ const hash = suffix.indexOf("#");
642
+ return {
643
+ kind: "delete",
644
+ comment: hash < 0 ? undefined : suffix.slice(hash),
645
+ };
646
+ }
647
+ return {
648
+ kind: "replace",
649
+ text: `${input.text.slice(input.lineStart, open)}${edited}${input.text.slice(input.valueEnd, input.statementEnd)}`,
650
+ };
651
+ };
652
+ /** Lines that replace a disabled-server assignment, or undefined to leave it. */
653
+ const disabledServerListLines = (edit, lines, lineIndex, endLine) => {
654
+ switch (edit.kind) {
655
+ case "ignore":
656
+ return undefined;
657
+ case "keep":
658
+ return lines.slice(lineIndex, endLine + 1);
659
+ case "replace":
660
+ return edit.text.split("\n");
661
+ case "delete":
662
+ return edit.comment === undefined ? [] : [edit.comment];
663
+ default: {
664
+ const unreachable = edit;
665
+ return unreachable;
666
+ }
667
+ }
668
+ };
669
+ /**
670
+ * Replace REA's Grok server tables and assignments. Comments that introduce a
671
+ * following table stay. Text inside strings is not treated as a header.
672
+ */
673
+ const upsertGrokServerSection = (originalText, serverKey, entry) => {
674
+ // smol-toml accepts a leading BOM. Leave it in place or the first header is missed.
675
+ const bom = originalText.startsWith("\uFEFF");
676
+ const source = bom ? originalText.slice(1) : originalText;
677
+ // Keep a preceding \r on each line. Rewriting \r\n in the whole file would
678
+ // change string values. A file whose every break is CRLF gets a CRLF section.
679
+ const crlf = source.includes("\r\n") && !source.replaceAll("\r\n", "").includes("\n");
680
+ const text = source;
681
+ const lines = text.split("\n");
682
+ const lineStarts = [];
683
+ let cursor = 0;
684
+ for (const line of lines) {
685
+ lineStarts.push(cursor);
686
+ cursor += line.length + 1;
687
+ }
688
+ const kept = [];
689
+ const pending = [];
690
+ let skipping = false;
691
+ let inlineServerTable = false;
692
+ let mode = "none";
693
+ let tablePath = [];
694
+ const discardPending = () => {
695
+ pending.length = 0;
696
+ };
697
+ const flushPending = () => {
698
+ kept.push(...pending);
699
+ pending.length = 0;
700
+ };
701
+ const lineIndexAt = (offset) => {
702
+ let line = 0;
703
+ for (let index = 0; index < lineStarts.length; index += 1)
704
+ if ((lineStarts[index] ?? 0) <= offset)
705
+ line = index;
706
+ return line;
707
+ };
708
+ let lineIndex = 0;
709
+ while (lineIndex < lines.length) {
710
+ const physical = lines[lineIndex] ?? "";
711
+ const line = physical.endsWith("\r") ? physical.slice(0, -1) : physical;
712
+ if (mode !== "none") {
713
+ mode = tomlStringModeAfter(line, mode);
714
+ if (skipping)
715
+ discardPending();
716
+ else
717
+ kept.push(physical);
718
+ lineIndex += 1;
719
+ continue;
720
+ }
721
+ const header = parseTomlTableHeader(line);
722
+ if (header !== undefined) {
723
+ tablePath = header.path;
724
+ if (isGrokServerTable(header.path, serverKey)) {
725
+ discardPending();
726
+ skipping = true;
727
+ lineIndex += 1;
728
+ continue;
729
+ }
730
+ skipping = false;
731
+ flushPending();
732
+ kept.push(physical);
733
+ lineIndex += 1;
734
+ continue;
735
+ }
736
+ const assignment = parseAssignment(line);
737
+ if (assignment !== undefined) {
738
+ const lineStart = lineStarts[lineIndex] ?? 0;
739
+ const valueOffset = lineStart + assignment.equals + 1;
740
+ const valueEnd = endOfTomlValue(text, valueOffset);
741
+ let statementEnd = valueEnd;
742
+ while (statementEnd < text.length && text[statementEnd] !== "\n")
743
+ statementEnd += 1;
744
+ const endLine = lineIndexAt(Math.max(statementEnd - 1, lineStart));
745
+ if (skipping) {
746
+ discardPending();
747
+ lineIndex = endLine + 1;
748
+ mode = "none";
749
+ continue;
750
+ }
751
+ const disabledLines = disabledServerListLines(disabledServerListEdit({
752
+ text,
753
+ lineStart,
754
+ valueOffset,
755
+ valueEnd,
756
+ statementEnd,
757
+ tablePath,
758
+ segments: assignment.segments,
759
+ serverKey,
760
+ entry,
761
+ }), lines, lineIndex, endLine);
762
+ if (disabledLines !== undefined) {
763
+ flushPending();
764
+ kept.push(...disabledLines);
765
+ lineIndex = endLine + 1;
766
+ mode = "none";
767
+ continue;
768
+ }
769
+ const absolute = [...tablePath, ...assignment.segments];
770
+ const open = skipWsAndComments(text, valueOffset);
771
+ const closesServerTable = absolute.length === 1 &&
772
+ absolute[0] === "mcp_servers" &&
773
+ text[open] === "{";
774
+ if (closesServerTable || isGrokServerTable(absolute, serverKey)) {
775
+ if (closesServerTable) {
776
+ flushPending();
777
+ const edited = editGrokInlineTable(text.slice(open, valueEnd), serverKey, entry);
778
+ const prefix = text.slice(lineStart, open);
779
+ const suffix = text.slice(valueEnd, statementEnd);
780
+ const replacement = edited === undefined
781
+ ? text.slice(lineStart, statementEnd)
782
+ : `${prefix}${edited}${suffix}`;
783
+ kept.push(...replacement.split("\n"));
784
+ inlineServerTable = true;
785
+ }
786
+ else
787
+ discardPending();
788
+ }
789
+ else {
790
+ flushPending();
791
+ for (let index = lineIndex; index <= endLine; index += 1)
792
+ kept.push(lines[index] ?? "");
793
+ }
794
+ lineIndex = endLine + 1;
795
+ mode = "none";
796
+ continue;
797
+ }
798
+ if (isBlankOrComment(line)) {
799
+ pending.push(physical);
800
+ lineIndex += 1;
801
+ continue;
802
+ }
803
+ mode = tomlStringModeAfter(line, "none");
804
+ if (skipping) {
805
+ if (looksLikeTomlHeader(line)) {
806
+ flushPending();
807
+ skipping = false;
808
+ tablePath = ["\0"];
809
+ kept.push(physical);
810
+ }
811
+ else
812
+ discardPending();
813
+ }
814
+ else {
815
+ flushPending();
816
+ kept.push(physical);
817
+ }
818
+ lineIndex += 1;
819
+ }
820
+ if (!skipping)
821
+ flushPending();
822
+ let body = kept.join("\n");
823
+ // The last kept CRLF line has no following LF from the join.
824
+ if (body.endsWith("\r"))
825
+ body += "\n";
826
+ if (entry !== undefined && !inlineServerTable) {
827
+ let fragment = stringifyToml({
828
+ mcp_servers: { [serverKey]: entry },
829
+ }).replace(/\n+$/u, "");
830
+ if (crlf)
831
+ fragment = fragment.replaceAll("\n", "\r\n");
832
+ const nl = crlf ? "\r\n" : "\n";
833
+ const endedWithNewline = body.endsWith("\n");
834
+ const base = body.replace(/\n+$/u, "");
835
+ const trimmed = endedWithNewline && base.endsWith("\r") ? base.slice(0, -1) : base;
836
+ body =
837
+ trimmed.length === 0
838
+ ? `${fragment}${nl}`
839
+ : `${trimmed}${nl}${nl}${fragment}${nl}`;
840
+ }
841
+ return bom ? `\uFEFF${body}` : body;
842
+ };
843
+ const grokServerEntry = (document, serverKey) => {
844
+ const servers = objectSchema.safeParse(document.mcp_servers);
845
+ if (!servers.success || !Object.hasOwn(servers.data, serverKey))
846
+ return undefined;
847
+ return servers.data[serverKey];
848
+ };
849
+ /** Whether Grok Build's root disable list names `serverKey`. */
850
+ export const grokServerListedDisabled = (document, serverKey) => Array.isArray(document.disabled_mcp_servers) &&
851
+ document.disabled_mcp_servers.includes(serverKey);
852
+ /** Keep an existing Grok document intact aside from the REA server tables. */
853
+ const serializeGrokConfiguration = (document, originalText) => {
854
+ const entry = grokServerEntry(document, PRODUCT_IDENTITY.mcpServerKey);
855
+ if (originalText === undefined)
856
+ return stringifyToml(document);
857
+ return upsertGrokServerSection(originalText, PRODUCT_IDENTITY.mcpServerKey, entry);
858
+ };
859
+ /** Comments in the trivia between two properties. `undefined` when there are none. */
860
+ const commentsBetweenProperties = (gap) => {
861
+ const pieces = [];
862
+ let index = 0;
863
+ while (index < gap.length) {
864
+ const line = gap.indexOf("//", index);
865
+ const block = gap.indexOf("/*", index);
866
+ if (line < 0 && block < 0)
867
+ break;
868
+ const start = line < 0 ? block : block < 0 ? line : Math.min(line, block);
869
+ const lineComment = start === line;
870
+ const close = lineComment
871
+ ? gap.indexOf("\n", start)
872
+ : gap.indexOf("*/", start + 2);
873
+ if (!lineComment && close < 0)
874
+ return undefined;
875
+ const end = lineComment ? (close < 0 ? gap.length : close) : close + 2;
876
+ const comment = gap.slice(start, end);
877
+ const lineBreak = gap.lastIndexOf("\n", start - 1);
878
+ if (lineBreak < 0)
879
+ pieces.push(` ${comment}`);
880
+ else {
881
+ const prefix = gap.slice(lineBreak + 1, start);
882
+ let indentEnd = 0;
883
+ while (prefix[indentEnd] === " " || prefix[indentEnd] === "\t")
884
+ indentEnd += 1;
885
+ const newline = lineBreak > 0 && gap[lineBreak - 1] === "\r" ? "\r\n" : "\n";
886
+ pieces.push(`${newline}${prefix.slice(0, indentEnd)}${comment}`);
887
+ }
888
+ index = end;
889
+ }
890
+ return pieces.length === 0 ? undefined : pieces.join("");
891
+ };
892
+ /**
893
+ * Delete an object property without taking a comment from the gap before it.
894
+ * jsonc-parser's removal span includes that gap, so a trailing comment on the
895
+ * previous property would disappear. Returns `undefined` to keep the stock edit.
896
+ */
897
+ const deleteJsonPropertyPreservingComments = (text, path) => {
898
+ const root = parseTree(text, [], { allowTrailingComma: true });
899
+ const value = root === undefined ? undefined : findNodeAtLocation(root, [...path]);
900
+ const property = value?.parent;
901
+ const parent = property?.parent;
902
+ if (property === undefined ||
903
+ parent?.type !== "object" ||
904
+ property.type !== "property" ||
905
+ parent.children === undefined)
906
+ return undefined;
907
+ const propertyIndex = parent.children.indexOf(property);
908
+ const previous = parent.children[propertyIndex - 1];
909
+ if (propertyIndex <= 0 || previous === undefined)
910
+ return undefined;
911
+ const comments = commentsBetweenProperties(text.slice(previous.offset + previous.length, property.offset));
912
+ if (comments === undefined)
913
+ return undefined;
914
+ let removeEnd = property.offset + property.length;
915
+ const hasNext = parent.children[propertyIndex + 1] !== undefined;
916
+ if (hasNext) {
917
+ let comma = removeEnd;
918
+ while (comma < text.length) {
919
+ const char = text[comma];
920
+ if (char === " " || char === "\t" || char === "\r" || char === "\n") {
921
+ comma += 1;
922
+ continue;
923
+ }
924
+ if (text.startsWith("/*", comma)) {
925
+ const close = text.indexOf("*/", comma + 2);
926
+ if (close < 0)
927
+ return undefined;
928
+ comma = close + 2;
929
+ continue;
930
+ }
931
+ if (text.startsWith("//", comma)) {
932
+ while (comma < text.length &&
933
+ text[comma] !== "\n" &&
934
+ text[comma] !== "\r")
935
+ comma += 1;
936
+ continue;
937
+ }
938
+ break;
939
+ }
940
+ if (text[comma] !== ",")
941
+ return undefined;
942
+ removeEnd = comma + 1;
943
+ }
944
+ // A line comment runs to the next break. Keep the following token outside it.
945
+ const remainder = text.slice(removeEnd);
946
+ let suffix = `${hasNext ? "," : ""}${comments}`;
947
+ if (suffix.includes("//") &&
948
+ !suffix.endsWith("\n") &&
949
+ !suffix.endsWith("\r") &&
950
+ !remainder.startsWith("\n") &&
951
+ !remainder.startsWith("\r"))
952
+ suffix += "\n";
953
+ return `${text.slice(0, previous.offset + previous.length)}${suffix}${remainder}`;
954
+ };
104
955
  /** Serialize a validated client document, retaining JSONC comments. */
105
956
  export const serializeClientConfiguration = (document, format, originalText, editedPaths) => {
106
957
  if (format === undefined || format === "unsupported")
107
958
  throw new TypeError("client does not have a supported MCP config format");
108
959
  if (format === "toml")
109
960
  return stringifyToml(document);
110
- if (originalText !== undefined && editedPaths !== undefined)
111
- return editedPaths.reduce((text, path) => applyEdits(text, modify(text, [...path], valueAt(document, path), {
112
- formattingOptions: { insertSpaces: true, tabSize: 2, eol: "\n" },
113
- })), originalText);
961
+ if (format === "grok")
962
+ return serializeGrokConfiguration(document, originalText);
963
+ // An empty original holds no comments or settings to preserve. Writing a
964
+ // fresh document also keeps a lone BOM from shifting past the closing brace.
965
+ if (originalText !== undefined &&
966
+ !isEmptyClientConfigurationText(originalText) &&
967
+ editedPaths !== undefined)
968
+ return editedPaths.reduce((text, path) => {
969
+ const value = valueAt(document, path);
970
+ if (value === undefined) {
971
+ const preserved = deleteJsonPropertyPreservingComments(text, path);
972
+ if (preserved !== undefined)
973
+ return preserved;
974
+ }
975
+ return applyEdits(text, modify(text, [...path], value, {
976
+ formattingOptions: { insertSpaces: true, tabSize: 2, eol: "\n" },
977
+ }));
978
+ }, originalText);
114
979
  return `${JSON.stringify(document, null, 2)}\n`;
115
980
  };
116
981
  /** Key path of a named registration in the server table. */