@amoree-code/ocean 0.0.0-stage → 1.2.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 (300) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +284 -2
  3. package/dist/application/auth/auth-orchestrator.js +77 -0
  4. package/dist/application/clients/clients.js +646 -0
  5. package/dist/application/clients/editors.js +398 -0
  6. package/dist/application/clients/hooks.js +335 -0
  7. package/dist/application/clients/native.js +410 -0
  8. package/dist/application/clients/opencode-plugin.js +158 -0
  9. package/dist/application/clients/registry.js +188 -0
  10. package/dist/application/gateway/webhook-gateway.js +137 -0
  11. package/dist/application/install/provider-installer.js +184 -0
  12. package/dist/application/integrations/charter-copies.js +76 -0
  13. package/dist/application/integrations/claude-vscode.js +106 -0
  14. package/dist/application/integrations/engine-entry-repair.js +105 -0
  15. package/dist/application/integrations/skill-filter.js +254 -0
  16. package/dist/application/layout/layout-apply.js +443 -0
  17. package/dist/application/layout/layout-plan.js +236 -0
  18. package/dist/application/layout/workspace-template.js +34 -0
  19. package/dist/application/onboarding/state.js +23 -0
  20. package/dist/application/onboarding/steps.js +249 -0
  21. package/dist/application/profiles/profile-distribution.js +53 -0
  22. package/dist/application/profiles/profile-suggestion.js +39 -0
  23. package/dist/application/profiles/profile-upgrade-service.js +208 -0
  24. package/dist/application/pull/history-index.js +476 -0
  25. package/dist/application/pull/project-match.js +132 -0
  26. package/dist/application/pull/pull.js +202 -0
  27. package/dist/application/pull/server-capture.js +307 -0
  28. package/dist/application/scheduler/local-scheduler.js +210 -0
  29. package/dist/composition/runtime.js +64 -0
  30. package/dist/engine-root.js +9 -0
  31. package/dist/infrastructure/filesystem/profile-loader.js +46 -0
  32. package/dist/infrastructure/filesystem/runtime-config-loader.js +29 -0
  33. package/dist/infrastructure/filesystem/skill-loader.js +84 -0
  34. package/dist/infrastructure/filesystem/workspace-capability.js +37 -0
  35. package/dist/infrastructure/observability/runtime-logger.js +16 -0
  36. package/dist/infrastructure/process/agent-tool-executor.js +99 -0
  37. package/dist/infrastructure/process/cli-process.js +49 -0
  38. package/dist/infrastructure/process/interactive-process.js +145 -0
  39. package/dist/infrastructure/process/process-supervisor.js +194 -0
  40. package/dist/infrastructure/process/service.js +252 -0
  41. package/dist/infrastructure/providers/browser-provider.js +2 -0
  42. package/dist/infrastructure/providers/claude-sdk.js +137 -0
  43. package/dist/infrastructure/providers/client-home.js +14 -0
  44. package/dist/infrastructure/providers/fake-browser-provider.js +146 -0
  45. package/dist/infrastructure/providers/ollama-embedder.js +74 -0
  46. package/dist/infrastructure/providers/openai-compatible.js +268 -0
  47. package/dist/infrastructure/providers/playwright-browser-provider.js +380 -0
  48. package/dist/infrastructure/providers/provider-capabilities.js +50 -0
  49. package/dist/infrastructure/providers/provider-invocation.js +184 -0
  50. package/dist/infrastructure/providers/provider-registry.js +77 -0
  51. package/dist/infrastructure/providers/providers.js +134 -0
  52. package/dist/infrastructure/wrappers/wrapper-manager.js +374 -0
  53. package/dist/interfaces/cli/auth-command.js +54 -0
  54. package/dist/interfaces/cli/browser-bridge-command.js +93 -0
  55. package/dist/interfaces/cli/browser-command.js +119 -0
  56. package/dist/interfaces/cli/capture-command.js +125 -0
  57. package/dist/interfaces/cli/client-test-command.js +133 -0
  58. package/dist/interfaces/cli/clients-command.js +129 -0
  59. package/dist/interfaces/cli/command-registry.js +1211 -0
  60. package/dist/interfaces/cli/context-command.js +172 -0
  61. package/dist/interfaces/cli/daily-command.js +131 -0
  62. package/dist/interfaces/cli/governance-command.js +55 -0
  63. package/dist/interfaces/cli/handoff-command.js +35 -0
  64. package/dist/interfaces/cli/help-command.js +207 -0
  65. package/dist/interfaces/cli/idea-command.js +47 -0
  66. package/dist/interfaces/cli/intercept-command.js +317 -0
  67. package/dist/interfaces/cli/layout-command.js +27 -0
  68. package/dist/interfaces/cli/market-command.js +52 -0
  69. package/dist/interfaces/cli/mcp-gateway-command.js +30 -0
  70. package/dist/interfaces/cli/memory-command.js +317 -0
  71. package/dist/interfaces/cli/migrate-command.js +26 -0
  72. package/dist/interfaces/cli/observe-command.js +78 -0
  73. package/dist/interfaces/cli/onboard-command.js +123 -0
  74. package/dist/interfaces/cli/operate-command.js +59 -0
  75. package/dist/interfaces/cli/profiles-command.js +70 -0
  76. package/dist/interfaces/cli/pull-command.js +54 -0
  77. package/dist/interfaces/cli/setup-command.js +143 -0
  78. package/dist/interfaces/cli/tasks-command.js +249 -0
  79. package/dist/main.js +49 -0
  80. package/dist/node-warnings.js +17 -0
  81. package/dist/version.js +8 -0
  82. package/market/mcp/chrome-devtools/ocean.capability.json +28 -0
  83. package/market/mcp/gateway/ocean.capability.json +21 -0
  84. package/market/mcp/obsidian/ocean.capability.json +21 -0
  85. package/market/mcp/ocean/ocean.capability.json +21 -0
  86. package/market/mcp/playwright/ocean.capability.json +23 -0
  87. package/node_modules/@ocean/brain/dist/brain/brain-eval.js +29 -0
  88. package/node_modules/@ocean/brain/dist/brain/brain-markdown.js +226 -0
  89. package/node_modules/@ocean/brain/dist/brain/brain-reindex.js +247 -0
  90. package/node_modules/@ocean/brain/dist/brain/brain-service.js +320 -0
  91. package/node_modules/@ocean/brain/dist/capture/inbox-sync.js +22 -0
  92. package/node_modules/@ocean/brain/dist/evidence/verification-report.js +13 -0
  93. package/node_modules/@ocean/brain/dist/infrastructure/brain/brain-index.js +285 -0
  94. package/node_modules/@ocean/brain/dist/memory/brain-dump.js +145 -0
  95. package/node_modules/@ocean/brain/dist/memory/daily-narrative.js +142 -0
  96. package/node_modules/@ocean/brain/dist/memory/index-sync.js +124 -0
  97. package/node_modules/@ocean/brain/dist/memory/lesson-activation.js +93 -0
  98. package/node_modules/@ocean/brain/dist/memory/lesson-learning.js +188 -0
  99. package/node_modules/@ocean/brain/dist/memory/lessons.js +321 -0
  100. package/node_modules/@ocean/brain/dist/memory/memory-audit.js +100 -0
  101. package/node_modules/@ocean/brain/dist/memory/memory-digest.js +49 -0
  102. package/node_modules/@ocean/brain/dist/memory/memory-harvest.js +345 -0
  103. package/node_modules/@ocean/brain/dist/memory/memory-paths.js +174 -0
  104. package/node_modules/@ocean/brain/dist/memory/memory-review.js +278 -0
  105. package/node_modules/@ocean/brain/dist/memory/memory-trash.js +152 -0
  106. package/node_modules/@ocean/brain/dist/memory/memory-write.js +216 -0
  107. package/node_modules/@ocean/brain/dist/memory/model-narrative.js +129 -0
  108. package/node_modules/@ocean/brain/dist/memory/profile-facts.js +103 -0
  109. package/node_modules/@ocean/brain/dist/memory/session-promotion.js +61 -0
  110. package/node_modules/@ocean/brain/dist/memory/session-summary.js +113 -0
  111. package/node_modules/@ocean/brain/package.json +11 -0
  112. package/node_modules/@ocean/context/dist/context/context-compression.js +66 -0
  113. package/node_modules/@ocean/context/dist/context/context-cost.js +587 -0
  114. package/node_modules/@ocean/context/dist/context/context-ladder.js +363 -0
  115. package/node_modules/@ocean/context/dist/context/context-packet.js +213 -0
  116. package/node_modules/@ocean/context/dist/context/context-references.js +255 -0
  117. package/node_modules/@ocean/context/dist/context/intent-router.js +259 -0
  118. package/node_modules/@ocean/context/dist/context/resource-injection.js +36 -0
  119. package/node_modules/@ocean/context/package.json +11 -0
  120. package/node_modules/@ocean/core/dist/domain/brain/brain-record.js +22 -0
  121. package/node_modules/@ocean/core/dist/domain/brain/record-scope.js +22 -0
  122. package/node_modules/@ocean/core/dist/domain/capabilities/browser-contract.js +64 -0
  123. package/node_modules/@ocean/core/dist/domain/capabilities/capability-contract.js +16 -0
  124. package/node_modules/@ocean/core/dist/domain/capabilities/capability-manifest.js +72 -0
  125. package/node_modules/@ocean/core/dist/domain/context/context-validator.js +5 -0
  126. package/node_modules/@ocean/core/dist/domain/context/context.js +34 -0
  127. package/node_modules/@ocean/core/dist/domain/context/project-id.js +30 -0
  128. package/node_modules/@ocean/core/dist/domain/evidence/evidence.js +16 -0
  129. package/node_modules/@ocean/core/dist/domain/mcp/mcp-contract.js +36 -0
  130. package/node_modules/@ocean/core/dist/domain/mcp/memory-contract.js +41 -0
  131. package/node_modules/@ocean/core/dist/domain/ports/brain-index-port.js +7 -0
  132. package/node_modules/@ocean/core/dist/domain/ports/browser-port.js +8 -0
  133. package/node_modules/@ocean/core/dist/domain/ports/embedder-port.js +2 -0
  134. package/node_modules/@ocean/core/dist/domain/ports/platform-ports.js +2 -0
  135. package/node_modules/@ocean/core/dist/domain/ports/runtime-ports.js +2 -0
  136. package/node_modules/@ocean/core/dist/domain/ports/session-store-port.js +2 -0
  137. package/node_modules/@ocean/core/dist/domain/process/process-events.js +5 -0
  138. package/node_modules/@ocean/core/dist/domain/profiles/profile-distribution.js +19 -0
  139. package/node_modules/@ocean/core/dist/domain/profiles/profile-policy.js +34 -0
  140. package/node_modules/@ocean/core/dist/domain/profiles/profile-selection.js +73 -0
  141. package/node_modules/@ocean/core/dist/domain/profiles/profile-upgrade.js +123 -0
  142. package/node_modules/@ocean/core/dist/domain/profiles/profile-validator.js +5 -0
  143. package/node_modules/@ocean/core/dist/domain/profiles/profile.js +218 -0
  144. package/node_modules/@ocean/core/dist/domain/profiles/runtime-config.js +30 -0
  145. package/node_modules/@ocean/core/dist/domain/providers/provider-capability.js +28 -0
  146. package/node_modules/@ocean/core/dist/domain/providers/provider.js +2 -0
  147. package/node_modules/@ocean/core/dist/domain/redaction/redaction.js +86 -0
  148. package/node_modules/@ocean/core/dist/domain/runs/agent-tools.js +92 -0
  149. package/node_modules/@ocean/core/dist/domain/runs/execution-plan.js +71 -0
  150. package/node_modules/@ocean/core/dist/domain/runs/run-contract.js +38 -0
  151. package/node_modules/@ocean/core/dist/domain/sessions/entry-contract.js +31 -0
  152. package/node_modules/@ocean/core/dist/domain/sessions/handoff.js +78 -0
  153. package/node_modules/@ocean/core/dist/domain/sessions/session.js +58 -0
  154. package/node_modules/@ocean/core/dist/domain/skills/default-skills.js +29 -0
  155. package/node_modules/@ocean/core/dist/domain/skills/skill-validator.js +5 -0
  156. package/node_modules/@ocean/core/dist/domain/skills/skill.js +11 -0
  157. package/node_modules/@ocean/core/dist/domain/tasks/task-id.js +85 -0
  158. package/node_modules/@ocean/core/dist/shared/fs-utils.js +212 -0
  159. package/node_modules/@ocean/core/dist/shared/local-date.js +16 -0
  160. package/node_modules/@ocean/core/dist/shared/paths.js +324 -0
  161. package/node_modules/@ocean/core/dist/shared/project-resolution.js +1065 -0
  162. package/node_modules/@ocean/core/dist/shared/task-reference.js +133 -0
  163. package/node_modules/@ocean/core/package.json +14 -0
  164. package/node_modules/@ocean/loop/dist/handoff/handoff-service.js +133 -0
  165. package/node_modules/@ocean/loop/dist/hooks/lifecycle-hooks.js +15 -0
  166. package/node_modules/@ocean/loop/dist/hooks/session-end-hook.js +183 -0
  167. package/node_modules/@ocean/loop/dist/hooks/session-start-hook.js +237 -0
  168. package/node_modules/@ocean/loop/dist/infrastructure/persistence/session-store.js +690 -0
  169. package/node_modules/@ocean/loop/dist/infrastructure/persistence/session-validator.js +5 -0
  170. package/node_modules/@ocean/loop/dist/loops/iteration-graph.js +147 -0
  171. package/node_modules/@ocean/loop/dist/loops/task-loop-record.js +2 -0
  172. package/node_modules/@ocean/loop/dist/loops/task-loop.js +281 -0
  173. package/node_modules/@ocean/loop/dist/operations/memory-knowledge-operations.js +263 -0
  174. package/node_modules/@ocean/loop/dist/operations/operation-contract.js +227 -0
  175. package/node_modules/@ocean/loop/dist/operations/operation-scope.js +28 -0
  176. package/node_modules/@ocean/loop/dist/operations/project-operations.js +93 -0
  177. package/node_modules/@ocean/loop/dist/operations/record-io.js +65 -0
  178. package/node_modules/@ocean/loop/dist/operations/record-operations.js +45 -0
  179. package/node_modules/@ocean/loop/dist/operations/task-linker.js +40 -0
  180. package/node_modules/@ocean/loop/dist/operations/task-operations.js +279 -0
  181. package/node_modules/@ocean/loop/dist/operations/write-guard.js +157 -0
  182. package/node_modules/@ocean/loop/dist/runs/prompt-assembly.js +112 -0
  183. package/node_modules/@ocean/loop/dist/runs/run-agent.js +425 -0
  184. package/node_modules/@ocean/loop/dist/runs/run-authorization.js +24 -0
  185. package/node_modules/@ocean/loop/dist/runs/tool-loop.js +173 -0
  186. package/node_modules/@ocean/loop/dist/sessions/session-closeout.js +150 -0
  187. package/node_modules/@ocean/loop/dist/sessions/session-pointer.js +133 -0
  188. package/node_modules/@ocean/loop/dist/sessions/session-projects.js +26 -0
  189. package/node_modules/@ocean/loop/dist/sessions/session-retention.js +132 -0
  190. package/node_modules/@ocean/loop/dist/tasks/archive-tasks.js +210 -0
  191. package/node_modules/@ocean/loop/dist/tasks/checkpoint-task.js +31 -0
  192. package/node_modules/@ocean/loop/dist/tasks/claim-task.js +126 -0
  193. package/node_modules/@ocean/loop/dist/tasks/list-tasks.js +113 -0
  194. package/node_modules/@ocean/loop/dist/tasks/new-task.js +42 -0
  195. package/node_modules/@ocean/loop/dist/tasks/renumber-tasks.js +134 -0
  196. package/node_modules/@ocean/loop/dist/tasks/verification-readiness.js +78 -0
  197. package/node_modules/@ocean/loop/dist/tasks/verify-task.js +234 -0
  198. package/node_modules/@ocean/loop/package.json +11 -0
  199. package/node_modules/@ocean/market/dist/adapters/mcp-adapter.js +64 -0
  200. package/node_modules/@ocean/market/dist/adapters/owned-directory.js +89 -0
  201. package/node_modules/@ocean/market/dist/adapters/plugin-adapter.js +39 -0
  202. package/node_modules/@ocean/market/dist/adapters/skill-adapter.js +32 -0
  203. package/node_modules/@ocean/market/dist/capability/adapter.js +2 -0
  204. package/node_modules/@ocean/market/dist/capability/catalog.js +63 -0
  205. package/node_modules/@ocean/market/dist/capability/content-digest.js +40 -0
  206. package/node_modules/@ocean/market/dist/capability/registry.js +81 -0
  207. package/node_modules/@ocean/market/dist/install/default-marketplace.js +47 -0
  208. package/node_modules/@ocean/market/dist/install/lock.js +34 -0
  209. package/node_modules/@ocean/market/dist/install/marketplace-service.js +165 -0
  210. package/node_modules/@ocean/market/dist/mcp/browser-bridge.js +263 -0
  211. package/node_modules/@ocean/market/dist/mcp/mcp-connection.js +67 -0
  212. package/node_modules/@ocean/market/dist/mcp/mcp-gateway.js +317 -0
  213. package/node_modules/@ocean/market/dist/mcp/mcp-launch.js +102 -0
  214. package/node_modules/@ocean/market/dist/mcp/mcp-runner.js +32 -0
  215. package/node_modules/@ocean/market/dist/security/description-scan.js +45 -0
  216. package/node_modules/@ocean/market/dist/security/permissions.js +57 -0
  217. package/node_modules/@ocean/market/dist/skills/core-skill-sync.js +113 -0
  218. package/node_modules/@ocean/market/dist/skills/signal-detection.js +84 -0
  219. package/node_modules/@ocean/market/dist/skills/skill-hub.js +220 -0
  220. package/node_modules/@ocean/market/package.json +11 -0
  221. package/node_modules/@ocean/services/dist/browser/browser-service.js +124 -0
  222. package/node_modules/@ocean/services/dist/browser/browser-session.js +287 -0
  223. package/node_modules/@ocean/services/dist/browser/browser-task-runner.js +70 -0
  224. package/node_modules/@ocean/services/dist/doctor/workspace-doctor.js +547 -0
  225. package/node_modules/@ocean/services/dist/infrastructure/mcp/call-ledger.js +114 -0
  226. package/node_modules/@ocean/services/dist/infrastructure/mcp/mcp-client.js +162 -0
  227. package/node_modules/@ocean/services/dist/infrastructure/mcp/obsidian-server.js +251 -0
  228. package/node_modules/@ocean/services/dist/infrastructure/mcp/ocean-server.js +880 -0
  229. package/node_modules/@ocean/services/dist/infrastructure/mcp/server-version.js +20 -0
  230. package/node_modules/@ocean/services/dist/infrastructure/mcp/tool-registry.js +29 -0
  231. package/node_modules/@ocean/services/dist/obsidian/conflict-log.js +68 -0
  232. package/node_modules/@ocean/services/dist/obsidian/inbox-promotion.js +80 -0
  233. package/node_modules/@ocean/services/dist/obsidian/vault-discovery.js +113 -0
  234. package/node_modules/@ocean/services/dist/obsidian/vault-ingestion.js +77 -0
  235. package/node_modules/@ocean/services/dist/obsidian/vault-sync.js +73 -0
  236. package/node_modules/@ocean/services/dist/obsidian/vault-writer.js +75 -0
  237. package/node_modules/@ocean/services/package.json +11 -0
  238. package/ocean-marketplace.json +415 -0
  239. package/package.json +67 -4
  240. package/skills/core/business-logic/SKILL.md +22 -0
  241. package/skills/core/catch-up/SKILL.md +17 -0
  242. package/skills/core/core-thinking/SKILL.md +11 -0
  243. package/skills/core/design-thinking/SKILL.md +19 -0
  244. package/skills/core/graft/SKILL.md +156 -0
  245. package/skills/core/loop/SKILL.md +20 -0
  246. package/skills/core/session-handoff/SKILL.md +15 -0
  247. package/skills/core/use-browser/SKILL.md +69 -0
  248. package/skills/core/verification/SKILL.md +11 -0
  249. package/skills/index.json +56 -0
  250. package/templates/README.md +4 -0
  251. package/templates/profiles/default.json +51 -0
  252. package/templates/profiles/developer.json +51 -0
  253. package/templates/profiles/reviewer.json +51 -0
  254. package/templates/profiles/strategist.json +51 -0
  255. package/templates/workspace/00-inbox/INBOX.md +7 -0
  256. package/templates/workspace/00-inbox/candidates/.gitkeep +0 -0
  257. package/templates/workspace/00-inbox/native/.gitkeep +0 -0
  258. package/templates/workspace/01-daily/.gitkeep +0 -0
  259. package/templates/workspace/02-personal/CONFLICTS.md +7 -0
  260. package/templates/workspace/02-personal/MEMORY.md +15 -0
  261. package/templates/workspace/02-personal/goals/.gitkeep +0 -0
  262. package/templates/workspace/02-personal/identity/.gitkeep +0 -0
  263. package/templates/workspace/02-personal/preferences/.gitkeep +0 -0
  264. package/templates/workspace/03-professional/.gitkeep +0 -0
  265. package/templates/workspace/04-projects/PROJECTS.md +5 -0
  266. package/templates/workspace/04-projects/_template/docs/.gitkeep +0 -0
  267. package/templates/workspace/04-projects/_template/memory/.gitkeep +0 -0
  268. package/templates/workspace/04-projects/_template/tasks/.gitkeep +0 -0
  269. package/templates/workspace/05-knowledge/KNOWLEDGE.md +8 -0
  270. package/templates/workspace/05-knowledge/decisions/.gitkeep +0 -0
  271. package/templates/workspace/05-knowledge/lessons/.gitkeep +0 -0
  272. package/templates/workspace/06-templates/TEMPLATES.md +25 -0
  273. package/templates/workspace/06-templates/decision.md +8 -0
  274. package/templates/workspace/06-templates/intelligence.md +32 -0
  275. package/templates/workspace/06-templates/project-claude.md +48 -0
  276. package/templates/workspace/06-templates/session.md +38 -0
  277. package/templates/workspace/06-templates/task.md +42 -0
  278. package/templates/workspace/MANIFEST.json +51 -0
  279. package/templates/workspace/bridge/config/CONFIG.md +21 -0
  280. package/templates/workspace/bridge/config/runtime.json +4 -0
  281. package/templates/workspace/charter/core.md +104 -0
  282. package/templates/workspace/charter/policies/README.md +31 -0
  283. package/templates/workspace/charter/policies/claude-code-context.md +90 -0
  284. package/templates/workspace/charter/policies/concise-output.md +29 -0
  285. package/templates/workspace/charter/policies/context.md +91 -0
  286. package/templates/workspace/charter/policies/contracts/task.md +189 -0
  287. package/templates/workspace/charter/policies/git.md +60 -0
  288. package/templates/workspace/charter/policies/graph.md +47 -0
  289. package/templates/workspace/charter/policies/knowledge.md +33 -0
  290. package/templates/workspace/charter/policies/lifecycle.md +119 -0
  291. package/templates/workspace/charter/policies/memory.md +67 -0
  292. package/templates/workspace/charter/policies/minimal-change.md +43 -0
  293. package/templates/workspace/charter/policies/models.md +57 -0
  294. package/templates/workspace/charter/policies/privacy-terms.txt +3 -0
  295. package/templates/workspace/charter/policies/response.md +39 -0
  296. package/templates/workspace/charter/policies/skill-observer.md +44 -0
  297. package/templates/workspace/charter/policies/stack.md +23 -0
  298. package/templates/workspace/charter/policies/task.md +139 -0
  299. package/templates/workspace/charter/policies/verification.md +29 -0
  300. package/templates/workspace/sessions/.gitkeep +0 -0
@@ -0,0 +1,398 @@
1
+ // Format-preserving edits of one MCP server table inside a client's own config (T-296 P2).
2
+ // An editor reads the servers it can understand and applies set / rename / remove of whole
3
+ // server entries; every other byte of the file is left as it was. When a file cannot be edited
4
+ // that way (unparseable, non-canonical JSON, a YAML list), the editor says so and nothing is
5
+ // written: the change becomes a manual step instead of a rewrite.
6
+ // The keys an Ocean-managed entry may carry. An entry with any other key (env, headers…) is the
7
+ // user's and is never rewritten.
8
+ export const ENTRY_KEYS = ["command", "args", "cwd", "type", "enabled"];
9
+ export class ManualEdit extends Error {
10
+ }
11
+ // --- JSON: parse and re-serialize, only when the file is already in that exact form ----------
12
+ // Parses a JSON file that re-serializes to exactly its own bytes; anything else is a manual edit.
13
+ export function canonicalJson(text) {
14
+ const source = text.trim() ? text : "{}\n";
15
+ const parsed = JSON.parse(source);
16
+ const indent = /\n(\t| +)"/.exec(source)?.[1] ?? " ";
17
+ const trailing = source.endsWith("\n");
18
+ const render = (value) => `${JSON.stringify(value, null, indent)}${trailing ? "\n" : ""}`;
19
+ if (render(parsed) !== source)
20
+ throw new ManualEdit("the file is not in canonical JSON form; rewriting it would change unrelated bytes");
21
+ return { parsed, render };
22
+ }
23
+ export function jsonEditor(tablePath, toNative = (value) => value, fromNative = (node) => node) {
24
+ const parse = canonicalJson;
25
+ const table = (root, create) => {
26
+ let node = root;
27
+ for (const key of tablePath) {
28
+ if (node[key] === undefined && create)
29
+ node[key] = {};
30
+ const next = node[key];
31
+ if (!next || typeof next !== "object" || Array.isArray(next))
32
+ return null;
33
+ node = next;
34
+ }
35
+ return node;
36
+ };
37
+ return {
38
+ servers(text) {
39
+ try {
40
+ const source = text.trim() ? text : "{}";
41
+ const found = table(JSON.parse(source), false);
42
+ return new Map(Object.entries(found ?? {}).map(([key, node]) => [
43
+ key,
44
+ fromNative(node),
45
+ ]));
46
+ }
47
+ catch {
48
+ return null;
49
+ }
50
+ },
51
+ apply(text, ops) {
52
+ const { parsed, render } = parse(text);
53
+ const servers = table(parsed, true);
54
+ if (!servers)
55
+ throw new ManualEdit("the server table is not an object");
56
+ for (const op of ops) {
57
+ if (op.kind === "set")
58
+ servers[op.key] = toNative(op.value);
59
+ else if (op.kind === "remove")
60
+ delete servers[op.key];
61
+ else {
62
+ // In place, so a rename and its undo leave the key order as it was.
63
+ const entries = Object.entries(servers);
64
+ for (const [key] of entries)
65
+ delete servers[key];
66
+ for (const [key, value] of entries)
67
+ servers[key === op.key ? op.to : key] = value;
68
+ }
69
+ }
70
+ return render(parsed);
71
+ },
72
+ };
73
+ }
74
+ // --- shared scalar handling for TOML / YAML ---------------------------------------------------
75
+ function parseScalar(raw) {
76
+ const value = raw.trim();
77
+ if (value.startsWith('"'))
78
+ return JSON.parse(value);
79
+ if (value.startsWith("'") && value.endsWith("'"))
80
+ return value.slice(1, -1);
81
+ if (value === "true" || value === "false")
82
+ return value === "true";
83
+ if (value.startsWith("["))
84
+ return JSON.parse(value.replace(/'([^']*)'/g, '"$1"'));
85
+ return value;
86
+ }
87
+ const quote = (value) => JSON.stringify(value);
88
+ // --- TOML: one `[<table>.<key>]` section per server -------------------------------------------
89
+ export function tomlEditor(table) {
90
+ const header = /^\s*\[([^\]]+)\]\s*$/;
91
+ const sections = (lines) => {
92
+ const found = [];
93
+ lines.forEach((line, index) => {
94
+ const match = header.exec(line);
95
+ if (!match)
96
+ return;
97
+ if (found.length)
98
+ found[found.length - 1].end = index;
99
+ found.push({ name: match[1].trim(), start: index, end: lines.length });
100
+ });
101
+ return found;
102
+ };
103
+ const prefix = `${table}.`;
104
+ const serverKey = (name) => name.startsWith(prefix) &&
105
+ /^[A-Za-z0-9_-]+$/.test(name.slice(prefix.length))
106
+ ? name.slice(prefix.length)
107
+ : null;
108
+ const render = (key, value) => [
109
+ `[${prefix}${key}]`,
110
+ ...ENTRY_KEYS.filter((field) => value[field] !== undefined).map((field) => `${field} = ${Array.isArray(value[field])
111
+ ? `[${value[field].map(quote).join(", ")}]`
112
+ : quote(value[field])}`),
113
+ ];
114
+ const read = (lines, section) => {
115
+ const value = {};
116
+ const body = lines.slice(section.start + 1, section.end).join("\n");
117
+ // Multi-line arrays are joined first, then each `key = value` is read.
118
+ const statements = body
119
+ .replace(/\[\s*\n([\s\S]*?)\]/g, (match) => match.replace(/\s*\n\s*/g, " "))
120
+ .split("\n")
121
+ .map((line) => line.trim())
122
+ .filter((line) => line && !line.startsWith("#"));
123
+ for (const statement of statements) {
124
+ const match = /^([A-Za-z0-9_-]+)\s*=\s*(.+)$/.exec(statement);
125
+ if (!match)
126
+ throw new ManualEdit(`cannot read '${statement}'`);
127
+ value[match[1]] = parseScalar(match[2].replace(/,\s*\]$/, "]"));
128
+ }
129
+ return value;
130
+ };
131
+ return {
132
+ servers(text) {
133
+ try {
134
+ const lines = text.split("\n");
135
+ const all = sections(lines);
136
+ const result = new Map();
137
+ for (const section of all) {
138
+ const key = serverKey(section.name);
139
+ if (!key)
140
+ continue;
141
+ const value = read(lines, section);
142
+ // A sub-table (`[mcp_servers.x.env]`) belongs to the entry: mark it as not ours.
143
+ if (all.some((other) => other.name.startsWith(`${section.name}.`)))
144
+ value.__subtables = true;
145
+ result.set(key, value);
146
+ }
147
+ return result;
148
+ }
149
+ catch {
150
+ return null;
151
+ }
152
+ },
153
+ apply(text, ops) {
154
+ let lines = text.split("\n");
155
+ for (const op of ops) {
156
+ const all = sections(lines);
157
+ const own = (key) => all.filter((section) => section.name === `${prefix}${key}` ||
158
+ section.name.startsWith(`${prefix}${key}.`));
159
+ if (op.kind === "rename") {
160
+ for (const section of own(op.key))
161
+ lines[section.start] = lines[section.start].replace(`${prefix}${op.key}`, `${prefix}${op.to}`);
162
+ continue;
163
+ }
164
+ const existing = own(op.key);
165
+ const replacement = op.kind === "set" ? render(op.key, op.value) : [];
166
+ if (existing.length &&
167
+ !replacement.length &&
168
+ existing[existing.length - 1].end === lines.length) {
169
+ // The last section goes with the blank lines before it: undoing an append.
170
+ let start = existing[0].start;
171
+ while (start > 0 && lines[start - 1].trim() === "")
172
+ start--;
173
+ lines = [...lines.slice(0, start), ""];
174
+ }
175
+ else if (existing.length) {
176
+ const start = existing[0].start;
177
+ const end = existing[existing.length - 1].end;
178
+ // Keep the blank line that separated this section from the next.
179
+ const blank = end > start && lines[end - 1].trim() === "" ? [""] : [];
180
+ lines = [
181
+ ...lines.slice(0, start),
182
+ ...(replacement.length ? [...replacement, ...blank] : []),
183
+ ...lines.slice(end),
184
+ ];
185
+ }
186
+ else if (replacement.length) {
187
+ while (lines.length && lines[lines.length - 1] === "")
188
+ lines.pop();
189
+ lines = [...lines, ...(lines.length ? [""] : []), ...replacement, ""];
190
+ }
191
+ }
192
+ return lines.join("\n");
193
+ },
194
+ };
195
+ }
196
+ // --- YAML: a top-level `<table>:` mapping of block-style entries -------------------------------
197
+ export function yamlEditor(table) {
198
+ const indentOf = (line) => line.length - line.trimStart().length;
199
+ const isContent = (line) => line.trim() !== "";
200
+ const layout = (lines) => {
201
+ const top = lines.findIndex((line) => line.trimEnd() === `${table}:`);
202
+ if (top < 0)
203
+ return null;
204
+ let end = top + 1;
205
+ while (end < lines.length &&
206
+ (!isContent(lines[end]) || indentOf(lines[end]) > 0))
207
+ end++;
208
+ // Trailing blank lines belong to whatever follows.
209
+ while (end > top + 1 && !isContent(lines[end - 1]))
210
+ end--;
211
+ const childIndent = lines.slice(top + 1, end).find(isContent);
212
+ const indent = childIndent ? indentOf(childIndent) : 2;
213
+ const blocks = [];
214
+ for (let index = top + 1; index < end; index++) {
215
+ const line = lines[index];
216
+ if (!isContent(line) || indentOf(line) !== indent)
217
+ continue;
218
+ if (line.trimStart().startsWith("- "))
219
+ throw new ManualEdit(`${table} is a YAML list, not a mapping`);
220
+ const match = /^\s*([A-Za-z0-9_-]+):\s*$/.exec(line);
221
+ if (!match)
222
+ throw new ManualEdit(`cannot read '${line.trim()}'`);
223
+ if (blocks.length)
224
+ blocks[blocks.length - 1].end = index;
225
+ blocks.push({ key: match[1], start: index, end });
226
+ }
227
+ return { top, end, indent, blocks };
228
+ };
229
+ const read = (lines, block, indent) => {
230
+ const value = {};
231
+ let list = null;
232
+ for (const line of lines.slice(block.start + 1, block.end)) {
233
+ if (!isContent(line) || line.trimStart().startsWith("#"))
234
+ continue;
235
+ const text = line.trim();
236
+ if (list && text.startsWith("- ")) {
237
+ list.push(parseScalar(text.slice(2)));
238
+ continue;
239
+ }
240
+ if (indentOf(line) !== indent * 2)
241
+ throw new ManualEdit(`unexpected nesting at '${text}'`);
242
+ const match = /^([A-Za-z0-9_-]+):\s*(.*)$/.exec(text);
243
+ if (!match)
244
+ throw new ManualEdit(`cannot read '${text}'`);
245
+ if (match[2] === "") {
246
+ list = [];
247
+ value[match[1]] = list;
248
+ }
249
+ else {
250
+ list = null;
251
+ value[match[1]] = parseScalar(match[2]);
252
+ }
253
+ }
254
+ return value;
255
+ };
256
+ const render = (key, value, indent) => {
257
+ const pad = " ".repeat(indent);
258
+ const out = [`${pad}${key}:`];
259
+ for (const field of ENTRY_KEYS) {
260
+ const item = value[field];
261
+ if (item === undefined)
262
+ continue;
263
+ if (Array.isArray(item)) {
264
+ out.push(`${pad}${pad}${field}:`);
265
+ for (const entry of item)
266
+ out.push(`${pad}${pad}${pad}- ${quote(entry)}`);
267
+ }
268
+ else
269
+ out.push(`${pad}${pad}${field}: ${quote(item)}`);
270
+ }
271
+ return out;
272
+ };
273
+ return {
274
+ servers(text) {
275
+ try {
276
+ const lines = text.split("\n");
277
+ const shape = layout(lines);
278
+ if (!shape)
279
+ return new Map();
280
+ return new Map(shape.blocks.map((block) => [
281
+ block.key,
282
+ read(lines, block, shape.indent),
283
+ ]));
284
+ }
285
+ catch {
286
+ return null;
287
+ }
288
+ },
289
+ apply(text, ops) {
290
+ let lines = text.split("\n");
291
+ for (const op of ops) {
292
+ const shape = layout(lines);
293
+ if (!shape) {
294
+ if (op.kind !== "set")
295
+ continue;
296
+ while (lines.length && lines[lines.length - 1] === "")
297
+ lines.pop();
298
+ lines = [
299
+ ...lines,
300
+ ...(lines.length ? [""] : []),
301
+ `${table}:`,
302
+ ...render(op.key, op.value, 2),
303
+ "",
304
+ ];
305
+ continue;
306
+ }
307
+ const block = shape.blocks.find((item) => item.key === op.key);
308
+ if (op.kind === "rename") {
309
+ if (block)
310
+ lines[block.start] = lines[block.start].replace(`${op.key}:`, `${op.to}:`);
311
+ continue;
312
+ }
313
+ const replacement = op.kind === "set" ? render(op.key, op.value, shape.indent) : [];
314
+ if (block)
315
+ lines = [
316
+ ...lines.slice(0, block.start),
317
+ ...replacement,
318
+ ...lines.slice(block.end),
319
+ ];
320
+ else if (replacement.length)
321
+ lines = [
322
+ ...lines.slice(0, shape.end),
323
+ ...replacement,
324
+ ...lines.slice(shape.end),
325
+ ];
326
+ }
327
+ return lines.join("\n");
328
+ },
329
+ };
330
+ }
331
+ // --- YAML list: a top-level `<table>:` list of `- name: <key>` entries, read only -------------
332
+ // Reads the list so a hand-made entry can be checked; every change stays a manual step.
333
+ export function yamlListEditor(table) {
334
+ const indentOf = (line) => line.length - line.trimStart().length;
335
+ return {
336
+ servers(text) {
337
+ const lines = text.split("\n");
338
+ const top = lines.findIndex((line) => line.trimEnd() === `${table}:`);
339
+ const servers = new Map();
340
+ if (top < 0)
341
+ return servers;
342
+ const items = [];
343
+ let current = null;
344
+ let list = null;
345
+ let itemIndent = -1;
346
+ try {
347
+ for (const line of lines.slice(top + 1)) {
348
+ const text = line.trim();
349
+ if (text === "" || text.startsWith("#"))
350
+ continue;
351
+ const indent = indentOf(line);
352
+ if (indent === 0)
353
+ break;
354
+ if (text.startsWith("- ") &&
355
+ (itemIndent < 0 || indent === itemIndent)) {
356
+ itemIndent = indent;
357
+ current = {};
358
+ list = null;
359
+ const match = /^- ([A-Za-z0-9_-]+):\s*(.*)$/.exec(text);
360
+ if (!match)
361
+ return null;
362
+ current[match[1]] = parseScalar(match[2]);
363
+ items.push(current);
364
+ continue;
365
+ }
366
+ if (!current)
367
+ return null;
368
+ if (list && text.startsWith("- ")) {
369
+ list.push(parseScalar(text.slice(2)));
370
+ continue;
371
+ }
372
+ const match = /^([A-Za-z0-9_-]+):\s*(.*)$/.exec(text);
373
+ if (!match)
374
+ return null;
375
+ if (match[2] === "") {
376
+ list = [];
377
+ current[match[1]] = list;
378
+ }
379
+ else {
380
+ list = null;
381
+ current[match[1]] = parseScalar(match[2]);
382
+ }
383
+ }
384
+ }
385
+ catch {
386
+ return null;
387
+ }
388
+ for (const { name, ...value } of items)
389
+ if (typeof name === "string")
390
+ servers.set(name, value);
391
+ return servers;
392
+ },
393
+ apply() {
394
+ throw new ManualEdit(`${table} is a YAML list; Ocean does not rewrite it`);
395
+ },
396
+ };
397
+ }
398
+ //# sourceMappingURL=editors.js.map