@amoree-code/ocean 0.0.0-stage → 1.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 (304) 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/dist/memory/signal-detection.js +66 -0
  112. package/node_modules/@ocean/brain/package.json +11 -0
  113. package/node_modules/@ocean/context/dist/context/context-compression.js +66 -0
  114. package/node_modules/@ocean/context/dist/context/context-cost.js +587 -0
  115. package/node_modules/@ocean/context/dist/context/context-ladder.js +363 -0
  116. package/node_modules/@ocean/context/dist/context/context-packet.js +213 -0
  117. package/node_modules/@ocean/context/dist/context/context-references.js +255 -0
  118. package/node_modules/@ocean/context/dist/context/intent-router.js +259 -0
  119. package/node_modules/@ocean/context/dist/context/resource-injection.js +36 -0
  120. package/node_modules/@ocean/context/package.json +11 -0
  121. package/node_modules/@ocean/core/dist/domain/brain/brain-record.js +22 -0
  122. package/node_modules/@ocean/core/dist/domain/brain/record-scope.js +22 -0
  123. package/node_modules/@ocean/core/dist/domain/capabilities/browser-contract.js +64 -0
  124. package/node_modules/@ocean/core/dist/domain/capabilities/capability-contract.js +16 -0
  125. package/node_modules/@ocean/core/dist/domain/capabilities/capability-manifest.js +72 -0
  126. package/node_modules/@ocean/core/dist/domain/context/context-validator.js +5 -0
  127. package/node_modules/@ocean/core/dist/domain/context/context.js +34 -0
  128. package/node_modules/@ocean/core/dist/domain/context/project-id.js +30 -0
  129. package/node_modules/@ocean/core/dist/domain/evidence/evidence.js +16 -0
  130. package/node_modules/@ocean/core/dist/domain/mcp/mcp-contract.js +36 -0
  131. package/node_modules/@ocean/core/dist/domain/mcp/memory-contract.js +41 -0
  132. package/node_modules/@ocean/core/dist/domain/ports/brain-index-port.js +7 -0
  133. package/node_modules/@ocean/core/dist/domain/ports/browser-port.js +8 -0
  134. package/node_modules/@ocean/core/dist/domain/ports/embedder-port.js +2 -0
  135. package/node_modules/@ocean/core/dist/domain/ports/platform-ports.js +2 -0
  136. package/node_modules/@ocean/core/dist/domain/ports/runtime-ports.js +2 -0
  137. package/node_modules/@ocean/core/dist/domain/ports/session-store-port.js +2 -0
  138. package/node_modules/@ocean/core/dist/domain/process/process-events.js +5 -0
  139. package/node_modules/@ocean/core/dist/domain/profiles/profile-distribution.js +19 -0
  140. package/node_modules/@ocean/core/dist/domain/profiles/profile-policy.js +34 -0
  141. package/node_modules/@ocean/core/dist/domain/profiles/profile-selection.js +73 -0
  142. package/node_modules/@ocean/core/dist/domain/profiles/profile-upgrade.js +123 -0
  143. package/node_modules/@ocean/core/dist/domain/profiles/profile-validator.js +5 -0
  144. package/node_modules/@ocean/core/dist/domain/profiles/profile.js +218 -0
  145. package/node_modules/@ocean/core/dist/domain/profiles/runtime-config.js +30 -0
  146. package/node_modules/@ocean/core/dist/domain/providers/provider-capability.js +28 -0
  147. package/node_modules/@ocean/core/dist/domain/providers/provider.js +2 -0
  148. package/node_modules/@ocean/core/dist/domain/redaction/redaction.js +86 -0
  149. package/node_modules/@ocean/core/dist/domain/runs/agent-tools.js +92 -0
  150. package/node_modules/@ocean/core/dist/domain/runs/execution-plan.js +71 -0
  151. package/node_modules/@ocean/core/dist/domain/runs/run-contract.js +38 -0
  152. package/node_modules/@ocean/core/dist/domain/sessions/entry-contract.js +31 -0
  153. package/node_modules/@ocean/core/dist/domain/sessions/handoff.js +78 -0
  154. package/node_modules/@ocean/core/dist/domain/sessions/session.js +58 -0
  155. package/node_modules/@ocean/core/dist/domain/skills/default-skills.js +29 -0
  156. package/node_modules/@ocean/core/dist/domain/skills/skill-validator.js +5 -0
  157. package/node_modules/@ocean/core/dist/domain/skills/skill.js +11 -0
  158. package/node_modules/@ocean/core/dist/domain/tasks/task-id.js +85 -0
  159. package/node_modules/@ocean/core/dist/shared/fs-utils.js +212 -0
  160. package/node_modules/@ocean/core/dist/shared/local-date.js +16 -0
  161. package/node_modules/@ocean/core/dist/shared/paths.js +324 -0
  162. package/node_modules/@ocean/core/dist/shared/project-resolution.js +1065 -0
  163. package/node_modules/@ocean/core/dist/shared/task-reference.js +133 -0
  164. package/node_modules/@ocean/core/package.json +14 -0
  165. package/node_modules/@ocean/loop/dist/handoff/handoff-service.js +133 -0
  166. package/node_modules/@ocean/loop/dist/hooks/lifecycle-hooks.js +15 -0
  167. package/node_modules/@ocean/loop/dist/hooks/session-end-hook.js +183 -0
  168. package/node_modules/@ocean/loop/dist/hooks/session-start-hook.js +237 -0
  169. package/node_modules/@ocean/loop/dist/infrastructure/persistence/session-store.js +690 -0
  170. package/node_modules/@ocean/loop/dist/infrastructure/persistence/session-validator.js +5 -0
  171. package/node_modules/@ocean/loop/dist/loops/iteration-graph.js +147 -0
  172. package/node_modules/@ocean/loop/dist/loops/task-loop-record.js +2 -0
  173. package/node_modules/@ocean/loop/dist/loops/task-loop.js +281 -0
  174. package/node_modules/@ocean/loop/dist/operations/memory-knowledge-operations.js +263 -0
  175. package/node_modules/@ocean/loop/dist/operations/operation-contract.js +227 -0
  176. package/node_modules/@ocean/loop/dist/operations/operation-scope.js +28 -0
  177. package/node_modules/@ocean/loop/dist/operations/project-operations.js +93 -0
  178. package/node_modules/@ocean/loop/dist/operations/record-io.js +65 -0
  179. package/node_modules/@ocean/loop/dist/operations/record-operations.js +45 -0
  180. package/node_modules/@ocean/loop/dist/operations/task-linker.js +40 -0
  181. package/node_modules/@ocean/loop/dist/operations/task-operations.js +279 -0
  182. package/node_modules/@ocean/loop/dist/operations/write-guard.js +157 -0
  183. package/node_modules/@ocean/loop/dist/runs/prompt-assembly.js +112 -0
  184. package/node_modules/@ocean/loop/dist/runs/run-agent.js +425 -0
  185. package/node_modules/@ocean/loop/dist/runs/run-authorization.js +24 -0
  186. package/node_modules/@ocean/loop/dist/runs/tool-loop.js +173 -0
  187. package/node_modules/@ocean/loop/dist/sessions/session-closeout.js +150 -0
  188. package/node_modules/@ocean/loop/dist/sessions/session-pointer.js +133 -0
  189. package/node_modules/@ocean/loop/dist/sessions/session-projects.js +26 -0
  190. package/node_modules/@ocean/loop/dist/sessions/session-retention.js +132 -0
  191. package/node_modules/@ocean/loop/dist/tasks/archive-tasks.js +210 -0
  192. package/node_modules/@ocean/loop/dist/tasks/checkpoint-task.js +31 -0
  193. package/node_modules/@ocean/loop/dist/tasks/claim-task.js +126 -0
  194. package/node_modules/@ocean/loop/dist/tasks/list-tasks.js +113 -0
  195. package/node_modules/@ocean/loop/dist/tasks/new-task.js +42 -0
  196. package/node_modules/@ocean/loop/dist/tasks/renumber-tasks.js +134 -0
  197. package/node_modules/@ocean/loop/dist/tasks/verification-readiness.js +78 -0
  198. package/node_modules/@ocean/loop/dist/tasks/verify-task.js +234 -0
  199. package/node_modules/@ocean/loop/package.json +11 -0
  200. package/node_modules/@ocean/market/dist/adapters/mcp-adapter.js +64 -0
  201. package/node_modules/@ocean/market/dist/adapters/owned-directory.js +89 -0
  202. package/node_modules/@ocean/market/dist/adapters/plugin-adapter.js +39 -0
  203. package/node_modules/@ocean/market/dist/adapters/skill-adapter.js +32 -0
  204. package/node_modules/@ocean/market/dist/capability/adapter.js +2 -0
  205. package/node_modules/@ocean/market/dist/capability/catalog.js +63 -0
  206. package/node_modules/@ocean/market/dist/capability/content-digest.js +40 -0
  207. package/node_modules/@ocean/market/dist/capability/registry.js +81 -0
  208. package/node_modules/@ocean/market/dist/install/default-marketplace.js +47 -0
  209. package/node_modules/@ocean/market/dist/install/lock.js +34 -0
  210. package/node_modules/@ocean/market/dist/install/marketplace-service.js +165 -0
  211. package/node_modules/@ocean/market/dist/mcp/browser-bridge.js +263 -0
  212. package/node_modules/@ocean/market/dist/mcp/mcp-connection.js +67 -0
  213. package/node_modules/@ocean/market/dist/mcp/mcp-gateway.js +317 -0
  214. package/node_modules/@ocean/market/dist/mcp/mcp-launch.js +102 -0
  215. package/node_modules/@ocean/market/dist/mcp/mcp-runner.js +32 -0
  216. package/node_modules/@ocean/market/dist/security/description-scan.js +45 -0
  217. package/node_modules/@ocean/market/dist/security/permissions.js +57 -0
  218. package/node_modules/@ocean/market/dist/security/sandbox.js +74 -0
  219. package/node_modules/@ocean/market/dist/skills/core-skill-sync.js +113 -0
  220. package/node_modules/@ocean/market/dist/skills/signal-detection.js +84 -0
  221. package/node_modules/@ocean/market/dist/skills/skill-curation.js +123 -0
  222. package/node_modules/@ocean/market/dist/skills/skill-hub.js +220 -0
  223. package/node_modules/@ocean/market/dist/skills/task-observer.js +165 -0
  224. package/node_modules/@ocean/market/package.json +11 -0
  225. package/node_modules/@ocean/services/dist/browser/browser-service.js +124 -0
  226. package/node_modules/@ocean/services/dist/browser/browser-session.js +287 -0
  227. package/node_modules/@ocean/services/dist/browser/browser-task-runner.js +70 -0
  228. package/node_modules/@ocean/services/dist/doctor/workspace-doctor.js +547 -0
  229. package/node_modules/@ocean/services/dist/infrastructure/mcp/call-ledger.js +114 -0
  230. package/node_modules/@ocean/services/dist/infrastructure/mcp/mcp-client.js +162 -0
  231. package/node_modules/@ocean/services/dist/infrastructure/mcp/obsidian-server.js +251 -0
  232. package/node_modules/@ocean/services/dist/infrastructure/mcp/ocean-server.js +880 -0
  233. package/node_modules/@ocean/services/dist/infrastructure/mcp/server-version.js +20 -0
  234. package/node_modules/@ocean/services/dist/infrastructure/mcp/tool-registry.js +29 -0
  235. package/node_modules/@ocean/services/dist/obsidian/conflict-log.js +68 -0
  236. package/node_modules/@ocean/services/dist/obsidian/inbox-promotion.js +80 -0
  237. package/node_modules/@ocean/services/dist/obsidian/vault-discovery.js +113 -0
  238. package/node_modules/@ocean/services/dist/obsidian/vault-ingestion.js +77 -0
  239. package/node_modules/@ocean/services/dist/obsidian/vault-sync.js +73 -0
  240. package/node_modules/@ocean/services/dist/obsidian/vault-writer.js +75 -0
  241. package/node_modules/@ocean/services/package.json +11 -0
  242. package/ocean-marketplace.json +415 -0
  243. package/package.json +67 -4
  244. package/skills/core/business-logic/SKILL.md +22 -0
  245. package/skills/core/catch-up/SKILL.md +17 -0
  246. package/skills/core/core-thinking/SKILL.md +11 -0
  247. package/skills/core/design-thinking/SKILL.md +19 -0
  248. package/skills/core/graft/SKILL.md +156 -0
  249. package/skills/core/loop/SKILL.md +20 -0
  250. package/skills/core/session-handoff/SKILL.md +15 -0
  251. package/skills/core/use-browser/SKILL.md +69 -0
  252. package/skills/core/verification/SKILL.md +11 -0
  253. package/skills/index.json +56 -0
  254. package/templates/README.md +4 -0
  255. package/templates/profiles/default.json +51 -0
  256. package/templates/profiles/developer.json +51 -0
  257. package/templates/profiles/reviewer.json +51 -0
  258. package/templates/profiles/strategist.json +51 -0
  259. package/templates/workspace/00-inbox/INBOX.md +7 -0
  260. package/templates/workspace/00-inbox/candidates/.gitkeep +0 -0
  261. package/templates/workspace/00-inbox/native/.gitkeep +0 -0
  262. package/templates/workspace/01-daily/.gitkeep +0 -0
  263. package/templates/workspace/02-personal/CONFLICTS.md +7 -0
  264. package/templates/workspace/02-personal/MEMORY.md +15 -0
  265. package/templates/workspace/02-personal/goals/.gitkeep +0 -0
  266. package/templates/workspace/02-personal/identity/.gitkeep +0 -0
  267. package/templates/workspace/02-personal/preferences/.gitkeep +0 -0
  268. package/templates/workspace/03-professional/.gitkeep +0 -0
  269. package/templates/workspace/04-projects/PROJECTS.md +5 -0
  270. package/templates/workspace/04-projects/_template/docs/.gitkeep +0 -0
  271. package/templates/workspace/04-projects/_template/memory/.gitkeep +0 -0
  272. package/templates/workspace/04-projects/_template/tasks/.gitkeep +0 -0
  273. package/templates/workspace/05-knowledge/KNOWLEDGE.md +8 -0
  274. package/templates/workspace/05-knowledge/decisions/.gitkeep +0 -0
  275. package/templates/workspace/05-knowledge/lessons/.gitkeep +0 -0
  276. package/templates/workspace/06-templates/TEMPLATES.md +25 -0
  277. package/templates/workspace/06-templates/decision.md +8 -0
  278. package/templates/workspace/06-templates/intelligence.md +32 -0
  279. package/templates/workspace/06-templates/project-claude.md +48 -0
  280. package/templates/workspace/06-templates/session.md +38 -0
  281. package/templates/workspace/06-templates/task.md +42 -0
  282. package/templates/workspace/MANIFEST.json +51 -0
  283. package/templates/workspace/bridge/config/CONFIG.md +21 -0
  284. package/templates/workspace/bridge/config/runtime.json +4 -0
  285. package/templates/workspace/charter/core.md +104 -0
  286. package/templates/workspace/charter/policies/README.md +31 -0
  287. package/templates/workspace/charter/policies/claude-code-context.md +90 -0
  288. package/templates/workspace/charter/policies/concise-output.md +29 -0
  289. package/templates/workspace/charter/policies/context.md +91 -0
  290. package/templates/workspace/charter/policies/contracts/task.md +189 -0
  291. package/templates/workspace/charter/policies/git.md +60 -0
  292. package/templates/workspace/charter/policies/graph.md +47 -0
  293. package/templates/workspace/charter/policies/knowledge.md +33 -0
  294. package/templates/workspace/charter/policies/lifecycle.md +119 -0
  295. package/templates/workspace/charter/policies/memory.md +67 -0
  296. package/templates/workspace/charter/policies/minimal-change.md +43 -0
  297. package/templates/workspace/charter/policies/models.md +57 -0
  298. package/templates/workspace/charter/policies/privacy-terms.txt +3 -0
  299. package/templates/workspace/charter/policies/response.md +39 -0
  300. package/templates/workspace/charter/policies/skill-observer.md +44 -0
  301. package/templates/workspace/charter/policies/stack.md +23 -0
  302. package/templates/workspace/charter/policies/task.md +139 -0
  303. package/templates/workspace/charter/policies/verification.md +29 -0
  304. package/templates/workspace/sessions/.gitkeep +0 -0
@@ -0,0 +1,324 @@
1
+ import { existsSync, readdirSync, realpathSync, statSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { isValidProjectId, PROJECT_CATEGORY_FOLDERS, UNCATEGORIZED, } from "../domain/context/project-id.js";
6
+ // The engine root is the `ocean` package root — skills/, templates/, dist/main.js. Core
7
+ // cannot find it from its own location (in an installed tree the two packages can sit
8
+ // anywhere), so the CLI publishes it under this global key before core loads
9
+ // (packages/harness/src/engine-root.ts) — early enough for the module-level layout
10
+ // constants below. Without it (tests, or core imported directly) it is the workspace
11
+ // sibling packages/harness.
12
+ const ENGINE_ROOT_KEY = Symbol.for("ocean.engineRoot");
13
+ const workspaceEngineRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..", "..", "harness");
14
+ export function registerEngineRoot(directory) {
15
+ globalThis[ENGINE_ROOT_KEY] =
16
+ path.resolve(directory);
17
+ }
18
+ export function engineRoot() {
19
+ const registered = globalThis[ENGINE_ROOT_KEY];
20
+ return typeof registered === "string" ? registered : workspaceEngineRoot;
21
+ }
22
+ export function enginePath(...parts) {
23
+ return path.join(engineRoot(), ...parts);
24
+ }
25
+ // The entry clients and shims launch: the kernel checkout's own build.
26
+ export function liveEngineEntry(root = engineRoot()) {
27
+ return path.join(root, "dist", "main.js");
28
+ }
29
+ // The pnpm workspace root (kernel/), two directories above the engine root
30
+ // (packages/harness → packages → kernel). Repo-wide tooling that lives outside any
31
+ // workspace package (e.g. scripts/ shared across packages) is anchored here, not on
32
+ // engineRoot(), which is this package's own root.
33
+ export function repoRoot() {
34
+ return path.resolve(engineRoot(), "..", "..");
35
+ }
36
+ export function repoPath(...parts) {
37
+ return path.join(repoRoot(), ...parts);
38
+ }
39
+ // Single point of truth for the top-level layout under oceanRoot(). Flipped in
40
+ // T-224 stage B to the Ocean/PARA layout (~/ocean/brain/..., ~/ocean/kernel/bridge)
41
+ // now that every call site (stage A) reads these constants instead of a literal.
42
+ //
43
+ // T-243 phase 6 flattens it: brain/<area> moves up to <area>, and kernel/bridge leaves the
44
+ // public repo for bridge. Each half keys on a sentinel directory it always holds — never on a
45
+ // bare folder, so an empty one created by accident cannot hide the real data — and falls back
46
+ // to the old location, so one build runs before, during and after the data move. Decided once
47
+ // per process against the root it starts with; a process started before the move keeps the old
48
+ // layout until it restarts.
49
+ function layoutPrefix(root, flat, nested, sentinel) {
50
+ if (isDirectory(path.join(root, flat, sentinel)))
51
+ return flat;
52
+ if (isDirectory(path.join(root, nested, sentinel)))
53
+ return nested;
54
+ return flat;
55
+ }
56
+ const recordsPrefix = (root) => layoutPrefix(root, "", "brain", "04-projects");
57
+ const bridgePrefix = (root) => layoutPrefix(root, "bridge", "kernel/bridge", "sessions");
58
+ // Which layout each half of a root is on, by the same rule the constants below are built with.
59
+ export function workspaceLayout(root = oceanRoot()) {
60
+ return {
61
+ records: recordsPrefix(root) === "" ? "flat" : "nested",
62
+ bridge: bridgePrefix(root) === "bridge" ? "flat" : "nested",
63
+ };
64
+ }
65
+ const BRAIN_PREFIX = recordsPrefix(oceanRoot());
66
+ const brainArea = (area) => path.posix.join(BRAIN_PREFIX, area);
67
+ //
68
+ // The old flat `personal/` directory had five children (memory, knowledge, daily,
69
+ // inbox[+brain-dump], templates) that PARA scatters to five independent, sibling
70
+ // top-level folders under brain/ — not one renamed parent with the same children
71
+ // underneath. PERSONAL_DIR alone can't stand in for all five the way SYSTEM_DIR
72
+ // and PROJECTS_DIR still can for their own (uniform) subtrees, so each gets its
73
+ // own constant. PERSONAL_DIR keeps meaning what `personal/memory` meant: it is
74
+ // 02-personal itself, not a parent with a further "memory" segment under it.
75
+ export const PERSONAL_DIR = brainArea("02-personal");
76
+ export const KNOWLEDGE_DIR = brainArea("05-knowledge");
77
+ export const DAILY_DIR = brainArea("01-daily");
78
+ export const INBOX_DIR = brainArea("00-inbox");
79
+ export const TEMPLATES_DIR = brainArea("06-templates");
80
+ export const INDEX_DIR = brainArea(".index");
81
+ export const PROJECTS_DIR = brainArea("04-projects");
82
+ // Every top-level brain area that holds markdown records (used by the doctor and the
83
+ // context command to scan the private store).
84
+ export const BRAIN_RECORD_DIRS = [
85
+ INBOX_DIR,
86
+ DAILY_DIR,
87
+ PERSONAL_DIR,
88
+ brainArea("03-professional"),
89
+ KNOWLEDGE_DIR,
90
+ TEMPLATES_DIR,
91
+ ];
92
+ // The workspace's own project. Callers use these helpers instead of a literal.
93
+ export const WORKSPACE_PROJECT_ID = "ocean";
94
+ export const WORKSPACE_PROJECT_CATEGORY = "personal";
95
+ export function sameProject(a, b) {
96
+ return a === b || (isWorkspaceProject(a) && isWorkspaceProject(b));
97
+ }
98
+ export function isWorkspaceProject(projectId) {
99
+ return projectId.toLowerCase() === WORKSPACE_PROJECT_ID;
100
+ }
101
+ function isDirectory(target) {
102
+ try {
103
+ return statSync(target).isDirectory();
104
+ }
105
+ catch {
106
+ return false;
107
+ }
108
+ }
109
+ // The folder name to use for a project id.
110
+ export function projectFolder(projectId) {
111
+ return isWorkspaceProject(projectId) ? WORKSPACE_PROJECT_ID : projectId;
112
+ }
113
+ // Every project folder, in a category folder or flat, sorted by id. `_template`-style and dot
114
+ // folders are not projects. Both layouts are read until every project is moved (T-311).
115
+ export function listProjectDirs(root = oceanRoot()) {
116
+ const children = (dir) => {
117
+ try {
118
+ return readdirSync(path.join(root, dir), { withFileTypes: true })
119
+ .filter((entry) => entry.isDirectory())
120
+ .map((entry) => entry.name);
121
+ }
122
+ catch {
123
+ return [];
124
+ }
125
+ };
126
+ const found = [];
127
+ for (const name of children(PROJECTS_DIR)) {
128
+ if (PROJECT_CATEGORY_FOLDERS.includes(name)) {
129
+ const parent = path.posix.join(PROJECTS_DIR, name);
130
+ for (const id of children(parent))
131
+ if (isValidProjectId(id))
132
+ found.push({
133
+ id,
134
+ category: name,
135
+ dir: path.posix.join(parent, id),
136
+ });
137
+ }
138
+ else if (isValidProjectId(name))
139
+ found.push({ id: name, dir: path.posix.join(PROJECTS_DIR, name) });
140
+ }
141
+ // One id in two folders sorts in the order projectDir searches.
142
+ const rank = (entry) => entry.category === undefined
143
+ ? PROJECT_CATEGORY_FOLDERS.length
144
+ : PROJECT_CATEGORY_FOLDERS.indexOf(entry.category);
145
+ return found.sort((a, b) => a.id === b.id ? rank(a) - rank(b) : a.id < b.id ? -1 : 1);
146
+ }
147
+ // One project's folder relative to a 04-projects directory, `<category>/<id>` or a flat
148
+ // `<id>`: where it is now, or, for a project that does not exist yet, where a new one goes —
149
+ // UNCATEGORIZED, except the workspace's own project, which is the owner's: personal.
150
+ export function projectSubdir(projectsDir, projectId) {
151
+ const id = projectFolder(projectId);
152
+ // Not an id (a category name, `..`): left as written for the caller's own checks to refuse.
153
+ if (!isValidProjectId(id))
154
+ return id;
155
+ // A folder holding project.json wins over a bare one of the same name, so a stray empty
156
+ // folder never hides the project.
157
+ const found = [
158
+ ...PROJECT_CATEGORY_FOLDERS.map((category) => path.posix.join(category, id)),
159
+ id,
160
+ ].filter((candidate) => isDirectory(path.join(projectsDir, candidate)));
161
+ const withManifest = found.find((candidate) => existsSync(path.join(projectsDir, candidate, "project.json")));
162
+ if (withManifest ?? found[0])
163
+ return (withManifest ?? found[0]);
164
+ return path.posix.join(id === WORKSPACE_PROJECT_ID ? WORKSPACE_PROJECT_CATEGORY : UNCATEGORIZED, id);
165
+ }
166
+ // The same folder relative to the Ocean root.
167
+ export function projectDir(projectId, root = oceanRoot()) {
168
+ return path.posix.join(PROJECTS_DIR, projectSubdir(path.join(root, PROJECTS_DIR), projectId));
169
+ }
170
+ // A path under PROJECTS_DIR, split into the project it names and what follows: either layout,
171
+ // `<id>/…` or `<category>/<id>/…`, so a path written before a project moved still finds it.
172
+ // Resolve the project's folder with projectDir, never from the category written here.
173
+ export function projectPathParts(parts) {
174
+ const [first, second, ...more] = parts;
175
+ if (first && PROJECT_CATEGORY_FOLDERS.includes(first))
176
+ return second && isValidProjectId(second)
177
+ ? { id: second, rest: more }
178
+ : null;
179
+ return first && isValidProjectId(first)
180
+ ? { id: first, rest: second === undefined ? [] : [second, ...more] }
181
+ : null;
182
+ }
183
+ // A workspace-relative path with any category folder dropped (`04-projects/<id>/…`), so one
184
+ // record compares equal before and after its project moves between category folders.
185
+ export function withoutProjectCategory(relative) {
186
+ if (!relative.startsWith(`${PROJECTS_DIR}/`))
187
+ return relative;
188
+ const project = projectPathParts(relative.slice(PROJECTS_DIR.length + 1).split("/"));
189
+ return project
190
+ ? [PROJECTS_DIR, project.id, ...project.rest].join("/")
191
+ : relative;
192
+ }
193
+ // Inverse of a project's tasks root (`<ocean>/04-projects/[<category>/]<id>/tasks`): the
194
+ // project id, or null for any other directory.
195
+ export function projectOfTasksRoot(root) {
196
+ const resolved = path.resolve(root);
197
+ if (path.basename(resolved) !== "tasks")
198
+ return null;
199
+ const folder = path.dirname(resolved);
200
+ const id = path.basename(folder);
201
+ if (!isValidProjectId(id))
202
+ return null;
203
+ const projects = path.resolve(oceanPath(PROJECTS_DIR));
204
+ const parent = path.dirname(folder);
205
+ if (parent === projects)
206
+ return id;
207
+ return path.dirname(parent) === projects &&
208
+ PROJECT_CATEGORY_FOLDERS.includes(path.basename(parent))
209
+ ? id
210
+ : null;
211
+ }
212
+ export function workspaceTasksRoot(root = oceanRoot()) {
213
+ return path.join(root, projectDir(WORKSPACE_PROJECT_ID, root), "tasks");
214
+ }
215
+ export const SYSTEM_DIR = bridgePrefix(oceanRoot());
216
+ export const REGISTRY_DIR = `${SYSTEM_DIR}/registry`;
217
+ export const LEGACY_REGISTRY_DIR = `${SYSTEM_DIR}/control-plane/registry`;
218
+ // Governance is private: the charter and the policies it routes to live in the brain.
219
+ export const CHARTER_DIR = brainArea("charter");
220
+ export const POLICIES_DIR = `${CHARTER_DIR}/policies`;
221
+ // The brain index (brain-reindex.ts, brain-service.ts, context-ladder.ts) stores and
222
+ // resolves records as "<store>/<relative path>" (e.g. "memory/foo.md",
223
+ // "knowledge/decisions/bar.md") — a format that predates the PARA split and is kept as
224
+ // the on-disk/index convention. This is the one place that maps a store name back to its
225
+ // real root, now that "memory" and "knowledge" are no longer subfolders of one shared
226
+ // parent.
227
+ export const STORE_DIR = {
228
+ memory: PERSONAL_DIR,
229
+ knowledge: KNOWLEDGE_DIR,
230
+ };
231
+ // Brain-index records are "<store>/<path inside store>" ("memory/x.md", "knowledge/decisions/y.md").
232
+ // Project memory (T-296) is "project/<id>/<path>" for 04-projects/<id>/memory/<path>, and
233
+ // project docs (T-307) "project-docs/<id>/<path>" for 04-projects/<id>/docs/<path>.
234
+ // These map that convention back to the real PARA location.
235
+ function storeParts(storePath, root) {
236
+ const [store, ...rest] = storePath.split("/");
237
+ if (store === "project" || store === "project-docs") {
238
+ const [project, ...inside] = rest;
239
+ if (!project || project === "." || project === "..")
240
+ throw new Error(`invalid project store path '${storePath}'`);
241
+ return [
242
+ ...projectDir(project, root).split("/"),
243
+ store === "project" ? "memory" : "docs",
244
+ ...inside,
245
+ ];
246
+ }
247
+ const dir = STORE_DIR[store];
248
+ if (!dir)
249
+ throw new Error(`unknown brain store '${store}'`);
250
+ return [dir, ...rest];
251
+ }
252
+ export function resolveStorePath(root, storePath) {
253
+ return resolveWithin(root, ...storeParts(storePath, root));
254
+ }
255
+ export function storeRelativeToRoot(storePath, root = oceanRoot()) {
256
+ return storeParts(storePath, root).join("/");
257
+ }
258
+ export function oceanEnv(name, env = process.env) {
259
+ return env[`OCEAN_${name}`];
260
+ }
261
+ export function oceanEnvPair(name, value) {
262
+ return { [`OCEAN_${name}`]: value };
263
+ }
264
+ export function oceanRoot() {
265
+ const root = oceanEnv("ROOT");
266
+ return root ? path.resolve(root) : defaultOceanRoot();
267
+ }
268
+ // A dev checkout (~/ocean/kernel/packages/harness) serves the workspace three directories up,
269
+ // once that holds one; a global npm install sits under the npm prefix, so it uses ~/ocean.
270
+ function defaultOceanRoot() {
271
+ const checkoutParent = path.resolve(engineRoot(), "..", "..", "..");
272
+ const isWorkspace = [
273
+ "04-projects",
274
+ "brain/04-projects",
275
+ "bridge/sessions",
276
+ "kernel/bridge/sessions",
277
+ ].some((sentinel) => isDirectory(path.join(checkoutParent, sentinel)));
278
+ return isWorkspace ? checkoutParent : path.join(homedir(), "ocean");
279
+ }
280
+ export function oceanPath(...parts) {
281
+ return path.join(oceanRoot(), ...parts);
282
+ }
283
+ // path.resolve is purely lexical: it never follows symlinks. Resolves the real location
284
+ // of the deepest existing ancestor of `candidate` and rejoins the (possibly not-yet-created)
285
+ // remainder onto it, so a caller can bounds-check a write target that doesn't exist yet
286
+ // without requiring the whole path to exist first.
287
+ export function realDeepestExisting(candidate) {
288
+ let current = candidate;
289
+ const pendingSuffix = [];
290
+ for (;;) {
291
+ try {
292
+ return path.join(realpathSync(current), ...pendingSuffix.reverse());
293
+ }
294
+ catch {
295
+ const parent = path.dirname(current);
296
+ if (parent === current)
297
+ return candidate;
298
+ pendingSuffix.push(path.basename(current));
299
+ current = parent;
300
+ }
301
+ }
302
+ }
303
+ function escapesRoot(root, candidate) {
304
+ const isFilesystemRoot = root === path.parse(root).root;
305
+ return (candidate !== root &&
306
+ !isFilesystemRoot &&
307
+ !candidate.startsWith(`${root}${path.sep}`));
308
+ }
309
+ export function resolveWithin(root, ...parts) {
310
+ const resolvedRoot = path.resolve(root);
311
+ const resolved = path.resolve(resolvedRoot, ...parts);
312
+ if (escapesRoot(resolvedRoot, resolved)) {
313
+ throw new Error("Path escapes its allowed root");
314
+ }
315
+ // A symlink anywhere under the lexically-allowed path can still point outside root; the
316
+ // lexical check above can't see that. Re-check against each path's real location too.
317
+ const realRoot = realDeepestExisting(resolvedRoot);
318
+ const realResolved = realDeepestExisting(resolved);
319
+ if (escapesRoot(realRoot, realResolved)) {
320
+ throw new Error("Path escapes its allowed root");
321
+ }
322
+ return resolved;
323
+ }
324
+ //# sourceMappingURL=paths.js.map