@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,16 @@
1
+ import { z } from "zod";
2
+ export const capabilityContractSchema = z.object({
3
+ capability: z.string().min(1),
4
+ operation: z.string().min(1),
5
+ authority: z.enum(["profile", "session", "owner"]),
6
+ idempotency: z.enum(["safe", "repeatable", "non-repeatable"]),
7
+ verification: z.string().min(1),
8
+ });
9
+ export const workspaceReadContract = capabilityContractSchema.parse({
10
+ capability: "workspace",
11
+ operation: "read",
12
+ authority: "profile",
13
+ idempotency: "safe",
14
+ verification: "sha256 content hash",
15
+ });
16
+ //# sourceMappingURL=capability-contract.js.map
@@ -0,0 +1,72 @@
1
+ import { z } from "zod";
2
+ // The `ocean.capability.json` envelope (T-229). It is kind-agnostic on purpose: `kind` is an
3
+ // open string and `spec` is opaque here, so a new kind is added by registering an adapter in
4
+ // `@ocean/market`, never by editing this file.
5
+ const sha256 = z
6
+ .string()
7
+ .regex(/^[0-9a-f]{64}$/, "expected a lowercase sha256 hex digest");
8
+ export const semverPattern = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
9
+ export const capabilityKindSchema = z
10
+ .string()
11
+ .regex(/^[a-z][a-z0-9-]{0,31}$/, "expected a lowercase kind such as `skill` or `mcp`");
12
+ // Reverse-DNS, optionally followed by `/<name>` the way the official MCP registry names servers
13
+ // (`io.github.owner/server`).
14
+ export const capabilityNameSchema = z
15
+ .string()
16
+ .max(200)
17
+ .regex(/^[a-z0-9-]+(\.[a-z0-9-]+)+(\/[a-z0-9._-]+)?$/, "expected a reverse-DNS name such as `dev.ocean.skills.ship`");
18
+ const relativePath = z
19
+ .string()
20
+ .min(1)
21
+ .refine((value) => !/^([\\/]|[A-Za-z]:)/.test(value) && !value.split(/[\\/]/).includes(".."), "expected a relative path that stays inside the index");
22
+ export const capabilitySourceSchema = z.discriminatedUnion("type", [
23
+ z.object({ type: z.literal("path"), path: relativePath }).strict(),
24
+ z
25
+ .object({ type: z.literal("url"), url: z.url({ protocol: /^https$/ }) })
26
+ .strict(),
27
+ ]);
28
+ const permissionList = z.array(z.string().min(1)).default([]);
29
+ // Declared up front so install can ask for consent and the runtime can refuse anything else.
30
+ export const capabilityPermissionsSchema = z
31
+ .object({
32
+ filesystem: z
33
+ .object({ read: permissionList, write: permissionList })
34
+ .strict()
35
+ .default({ read: [], write: [] }),
36
+ network: permissionList,
37
+ env: permissionList,
38
+ exec: permissionList,
39
+ })
40
+ .strict();
41
+ export const capabilityManifestSchema = z
42
+ .object({
43
+ kind: capabilityKindSchema,
44
+ name: capabilityNameSchema,
45
+ version: z.string().regex(semverPattern, "expected a semver version"),
46
+ description: z.string().max(1000).optional(),
47
+ engines: z.object({ ocean: z.string().min(1) }).strict(),
48
+ source: capabilitySourceSchema,
49
+ integrity: z.object({ sha256 }).strict(),
50
+ provenance: z
51
+ .object({ type: z.literal("sigstore"), bundle: z.string().min(1) })
52
+ .strict()
53
+ .optional(),
54
+ permissions: capabilityPermissionsSchema.default({
55
+ filesystem: { read: [], write: [] },
56
+ network: [],
57
+ env: [],
58
+ exec: [],
59
+ }),
60
+ spec: z.unknown(),
61
+ })
62
+ .strict();
63
+ // `ocean-marketplace.json`: one index, many manifests. Several indexes (local, cached, the
64
+ // official MCP registry) are merged by the catalog in `@ocean/market`.
65
+ export const marketplaceIndexSchema = z
66
+ .object({
67
+ schemaVersion: z.literal(1),
68
+ name: z.string().min(1),
69
+ capabilities: z.array(capabilityManifestSchema),
70
+ })
71
+ .strict();
72
+ //# sourceMappingURL=capability-manifest.js.map
@@ -0,0 +1,5 @@
1
+ import { contextManifestSchema } from "./context.js";
2
+ export function validateContextManifest(input) {
3
+ return contextManifestSchema.parse(input);
4
+ }
5
+ //# sourceMappingURL=context-validator.js.map
@@ -0,0 +1,34 @@
1
+ import { z } from "zod";
2
+ // A file the prompt points at instead of inlining. `path` is always relative: to the run cwd
3
+ // for a profile contextSources entry, to the Ocean root for a context-packet record.
4
+ export const contextReferenceSchema = z.object({
5
+ path: z.string().min(1),
6
+ base: z.enum(["cwd", "ocean-root"]),
7
+ recordType: z.string().min(1),
8
+ reason: z.string().min(1),
9
+ bytes: z.number().int().nonnegative().nullable(),
10
+ });
11
+ export const contextManifestSchema = z.object({
12
+ files: z.array(z.string()),
13
+ bytes: z.number().int().nonnegative(),
14
+ compactedSummary: z.string().nullable(),
15
+ lastContextCheckpoint: z.string().min(1),
16
+ maxBytes: z.number().int().positive().default(32_000),
17
+ omitted: z.array(z.string()).default([]),
18
+ compression: z
19
+ .object({
20
+ sourceId: z.string().min(1),
21
+ sourceHash: z.string().min(1),
22
+ originalBytes: z.number().int().nonnegative(),
23
+ compressedBytes: z.number().int().nonnegative(),
24
+ method: z.string().min(1),
25
+ budget: z.number().int().positive(),
26
+ omittedSections: z.array(z.string()),
27
+ recoveryRef: z.string().min(1),
28
+ safeToUse: z.boolean(),
29
+ })
30
+ .nullable()
31
+ .default(null),
32
+ references: z.array(contextReferenceSchema).default([]),
33
+ });
34
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1,30 @@
1
+ // A project id names a folder under 04-projects, so it must be one plain path segment. It is
2
+ // lowercase because folders are case-insensitive on macOS and Windows: `Ocean-Language` and
3
+ // `ocean-language` would be two ids for one folder, and one write would clobber the other.
4
+ export const PROJECT_ID = /^[a-z0-9][a-z0-9._-]*$/;
5
+ // Who a project belongs to (T-311). A project lives in the folder of its category,
6
+ // 04-projects/<category>/<id>/; a new one lands in UNCATEGORIZED until it is moved.
7
+ export const PROJECT_CATEGORIES = [
8
+ "company",
9
+ "personal",
10
+ "freelance",
11
+ "former-company",
12
+ "vendor",
13
+ ];
14
+ export const UNCATEGORIZED = "uncategorized";
15
+ // The folders directly under 04-projects that hold projects instead of being one.
16
+ export const PROJECT_CATEGORY_FOLDERS = [
17
+ ...PROJECT_CATEGORIES,
18
+ UNCATEGORIZED,
19
+ ];
20
+ export function isProjectCategory(value) {
21
+ return PROJECT_CATEGORIES.includes(value);
22
+ }
23
+ // A category folder name is never an id, so a flat folder and a category folder cannot be
24
+ // confused while both layouts are read.
25
+ export function isValidProjectId(value) {
26
+ return (PROJECT_ID.test(value) &&
27
+ !value.includes("..") &&
28
+ !PROJECT_CATEGORY_FOLDERS.includes(value));
29
+ }
30
+ //# sourceMappingURL=project-id.js.map
@@ -0,0 +1,16 @@
1
+ import { z } from "zod";
2
+ const evidenceResultSchema = z.enum(["proven", "not_proven", "limitation"]);
3
+ export const evidenceSchema = z.object({
4
+ evidenceId: z.string().min(1),
5
+ sessionId: z.string().min(1),
6
+ type: z.string().min(1),
7
+ source: z.string().min(1),
8
+ observedAt: z.string().datetime(),
9
+ result: evidenceResultSchema,
10
+ criterion: z.string().min(1).nullable(),
11
+ payload: z.string().max(64_000),
12
+ });
13
+ export function validateEvidence(input) {
14
+ return evidenceSchema.parse(input);
15
+ }
16
+ //# sourceMappingURL=evidence.js.map
@@ -0,0 +1,36 @@
1
+ import { createHash } from "node:crypto";
2
+ import { z } from "zod";
3
+ export const mcpToolSchema = z.object({
4
+ name: z.string().min(1),
5
+ description: z.string().optional(),
6
+ inputSchema: z.record(z.string(), z.unknown()).optional(),
7
+ // Hints for the client's own permission UI. They are not enforcement: the server's own
8
+ // checks (roots, secrets, the writes switch) decide what a call may do.
9
+ annotations: z
10
+ .object({
11
+ readOnlyHint: z.boolean().optional(),
12
+ destructiveHint: z.boolean().optional(),
13
+ idempotentHint: z.boolean().optional(),
14
+ })
15
+ .optional(),
16
+ });
17
+ export const mcpApprovalSchema = z.object({
18
+ approved: z.literal(true),
19
+ fingerprint: z.string().length(64),
20
+ });
21
+ export function actionFingerprint(name, args) {
22
+ const canonical = (value) => {
23
+ if (Array.isArray(value))
24
+ return value.map(canonical);
25
+ if (value && typeof value === "object")
26
+ return Object.fromEntries(Object.entries(value)
27
+ .filter(([key]) => key !== "approval" && key !== "approved")
28
+ .sort(([a], [b]) => a.localeCompare(b))
29
+ .map(([key, item]) => [key, canonical(item)]));
30
+ return value;
31
+ };
32
+ return createHash("sha256")
33
+ .update(JSON.stringify({ name, arguments: canonical(args) }))
34
+ .digest("hex");
35
+ }
36
+ //# sourceMappingURL=mcp-contract.js.map
@@ -0,0 +1,41 @@
1
+ // The memory contract every MCP client of the `ocean` server receives (T-296). One source:
2
+ // the server sends MEMORY_INSTRUCTIONS in `initialize`, and the memory tools refuse with one of
3
+ // MEMORY_ERROR_CODES so a client can recover deterministically instead of parsing messages.
4
+ export const MEMORY_CONTRACT_VERSION = 1;
5
+ export const MEMORY_INSTRUCTIONS = [
6
+ "Ocean is this user's single memory and environment; do not keep durable facts only in this client's own memory.",
7
+ // Only Ocean's server sends this text, so it is true wherever it is read. A record listing
8
+ // clients that cannot connect is not about this session (T-307: Desktop chat misread it).
9
+ "If you can call these tools, this client is connected to Ocean.",
10
+ "Before answering about the user, their projects or past decisions, search with brain_search, read with brain_read or memory_read, and cite the record path.",
11
+ "Use memory_write only when the user explicitly asks you to remember or change something: search first, then mode create for a new record, or mode update with the current sha256 from memory_read as expectedHash.",
12
+ "Facts you infer yourself, and anything imported from another tool's memory, go to memory_propose for the user's review, never to memory_write.",
13
+ "Never store secrets, credentials or temporary state. If a new fact contradicts a record, tell the user instead of overwriting it.",
14
+ "memory_delete is a soft delete; memory_history and memory_restore undo changes.",
15
+ "Without a session-start hook, call ocean_context once. Use ocean_handoff_create only when the user asks for a handoff.",
16
+ ].join(" ");
17
+ export const MEMORY_ERROR_CODES = [
18
+ "EXISTS",
19
+ "EXISTS_SIMILAR",
20
+ "MISSING",
21
+ "OUT_OF_ROOT",
22
+ "PROTECTED",
23
+ "SYMLINK",
24
+ "HARDLINK",
25
+ "SECRET",
26
+ "CONFLICT",
27
+ "TOO_LARGE",
28
+ "INVALID",
29
+ "WRITES_OFF",
30
+ ];
31
+ export class MemoryContractError extends Error {
32
+ code;
33
+ details;
34
+ constructor(code, message, details = {}) {
35
+ super(message);
36
+ this.name = "MemoryContractError";
37
+ this.code = code;
38
+ this.details = details;
39
+ }
40
+ }
41
+ //# sourceMappingURL=memory-contract.js.map
@@ -0,0 +1,7 @@
1
+ // Port for the brain (T-228) index driver. application/brain/* depends only on this — the
2
+ // concrete node:sqlite + sqlite-vec implementation lives in infrastructure/brain/brain-index.ts
3
+ // and is wired in through composition/runtime.js, never imported directly by application
4
+ // code (enforced by tests/architecture.test.mjs).
5
+ // 2: docs carry a scope. The index is a disposable cache, so a bump means "reindex", not a migration.
6
+ export const BRAIN_INDEX_SCHEMA_VERSION = "2";
7
+ //# sourceMappingURL=brain-index-port.js.map
@@ -0,0 +1,8 @@
1
+ // The browser provider boundary. Everything above this file is Ocean: capability,
2
+ // authority, verification, session identity. A provider is the only place a browser
3
+ // engine may be named — see infrastructure/providers/playwright-browser-provider.ts.
4
+ // Every call here returns a plain, JSON-safe value; a provider never decides whether
5
+ // an action was verified, it only reports what it observed. Verification re-reads
6
+ // state separately. These are pure interfaces, so they live in the domain layer.
7
+ export {};
8
+ //# sourceMappingURL=browser-port.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=embedder-port.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=platform-ports.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=runtime-ports.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=session-store-port.js.map
@@ -0,0 +1,5 @@
1
+ // Pure process I/O contracts. These are the shapes exchanged with a headless
2
+ // child process; they carry no behavior, so they live in the domain layer and
3
+ // infrastructure/process/cli-process.ts re-exports them.
4
+ export {};
5
+ //# sourceMappingURL=process-events.js.map
@@ -0,0 +1,19 @@
1
+ import { z } from "zod";
2
+ const profileDistributionSchema = z
3
+ .object({
4
+ name: z.string().min(1),
5
+ version: z.string().min(1),
6
+ description: z.string().default(""),
7
+ oceanRequires: z.string().optional(),
8
+ clients: z.array(z.string().min(1)).default([]),
9
+ files: z.array(z.string().min(1)).default([]),
10
+ distributionOwned: z.array(z.string().min(1)).default(["profile.json"]),
11
+ })
12
+ .transform(({ oceanRequires, ...rest }) => ({
13
+ ...rest,
14
+ oceanRequires: oceanRequires ?? "*",
15
+ }));
16
+ export function validateProfileDistribution(input) {
17
+ return profileDistributionSchema.parse(input);
18
+ }
19
+ //# sourceMappingURL=profile-distribution.js.map
@@ -0,0 +1,34 @@
1
+ import path from "node:path";
2
+ import { isApiClient } from "./profile.js";
3
+ const providerCommand = {
4
+ claude: "claude",
5
+ codex: "codex",
6
+ gemini: "gemini",
7
+ antigravity: "agy",
8
+ hermes: "hermes",
9
+ kilo: "kilo",
10
+ kimi: "kimi",
11
+ };
12
+ export function executionPolicy(profile, cwd) {
13
+ const command = isApiClient(profile.provider)
14
+ ? null
15
+ : providerCommand[profile.provider];
16
+ if (command !== null &&
17
+ profile.allowedCommands.length &&
18
+ !profile.allowedCommands.some((allowed) => command === allowed ||
19
+ path.basename(command) === path.basename(allowed))) {
20
+ throw new Error(`Policy denied provider command: ${command}`);
21
+ }
22
+ if (profile.writePolicy === "allowed-paths" &&
23
+ profile.allowedPaths.length === 0) {
24
+ throw new Error("Policy denied writable run without allowed paths");
25
+ }
26
+ if (!path.isAbsolute(cwd))
27
+ throw new Error("Policy denied non-absolute working directory");
28
+ return {
29
+ providerCommand: command,
30
+ writePolicy: profile.writePolicy,
31
+ allowedPaths: profile.allowedPaths,
32
+ };
33
+ }
34
+ //# sourceMappingURL=profile-policy.js.map
@@ -0,0 +1,73 @@
1
+ // Profile suggestion for a task (T-296 §3.10): a fixed rule table over the task record —
2
+ // its `kind`, title and objective, plus `class`/`risk` — picks one installed profile and says
3
+ // why. First matching rule wins; nothing matching, or a profile that is not installed, falls
4
+ // back to `default`. The suggestion never widens anything by itself: `ocean run` uses it only
5
+ // when runtime.json turns `autoProfile` on, and an explicit --profile always wins.
6
+ export const PROFILE_RULES = [
7
+ {
8
+ rule: "security",
9
+ profile: "security-auditor",
10
+ words: /\b(security|privacy|secrets?|vulnerab\w*|auth(entication|orization)?|permissions?|leaks?)\b/,
11
+ },
12
+ {
13
+ rule: "review",
14
+ profile: "reviewer",
15
+ words: /\b(review\w*|audit\w*|inspect\w*)\b/,
16
+ },
17
+ {
18
+ rule: "test",
19
+ profile: "tester",
20
+ words: /\b(tests?|testing|regressions?|reproduc\w*|flaky|coverage)\b/,
21
+ },
22
+ {
23
+ rule: "delivery",
24
+ profile: "devops",
25
+ words: /\b(deploy\w*|release\w*|ci|pipelines?|docker\w*|infra\w*|runtime|rollout)\b/,
26
+ },
27
+ {
28
+ rule: "research",
29
+ profile: "researcher",
30
+ words: /\b(research\w*|investigat\w*|compar\w*|evaluat\w*|spike|explor\w*)\b/,
31
+ },
32
+ {
33
+ rule: "planning",
34
+ profile: "strategist",
35
+ words: /\b(plan|planning|design|architecture|strategy|roadmap|proposal|decide)\b/,
36
+ },
37
+ {
38
+ rule: "implementation",
39
+ profile: "developer",
40
+ words: /\b(implement\w*|fix\w*|build\w*|add\w*|feat\w*|bugs?|refactor\w*|wire\w*|migrat\w*)\b/,
41
+ },
42
+ ];
43
+ export function suggestProfile(task, installed) {
44
+ // The kind is a declared signal and is tried alone first; title and objective are prose.
45
+ const sources = [task.kind ?? "", `${task.title} ${task.objective ?? ""}`];
46
+ let match;
47
+ for (const text of sources) {
48
+ const lower = text.toLowerCase().slice(0, 2_000);
49
+ match = PROFILE_RULES.find((rule) => rule.words.test(lower));
50
+ if (match)
51
+ break;
52
+ }
53
+ const highRisk = [task.class, task.risk].some((value) => value?.toLowerCase() === "high");
54
+ const riskNote = highRisk ? "; high risk — verify before completing" : "";
55
+ if (!match)
56
+ return {
57
+ profile: "default",
58
+ rule: "fallback",
59
+ reason: `no rule matched ${task.id}${riskNote}`,
60
+ };
61
+ if (!installed.includes(match.profile))
62
+ return {
63
+ profile: "default",
64
+ rule: match.rule,
65
+ reason: `${match.rule} work suggests ${match.profile}, which is not installed${riskNote}`,
66
+ };
67
+ return {
68
+ profile: match.profile,
69
+ rule: match.rule,
70
+ reason: `${match.rule} work in ${task.id}${riskNote}`,
71
+ };
72
+ }
73
+ //# sourceMappingURL=profile-selection.js.map
@@ -0,0 +1,123 @@
1
+ import { redactSecrets } from "../redaction/redaction.js";
2
+ import { isApiClient, selectProfileClient } from "./profile.js";
3
+ import { validateProfile } from "./profile-validator.js";
4
+ const credentialKey = /api[-_]?key|token|secret|password|credential|bearer/i;
5
+ // Paths only, never values: the report is printed and must not repeat a secret.
6
+ function credentialIssues(value, at) {
7
+ if (typeof value === "string")
8
+ return redactSecrets(value).includes("[REDACTED]")
9
+ ? [`${at}: value looks like a credential`]
10
+ : [];
11
+ if (Array.isArray(value))
12
+ return value.flatMap((item, index) => credentialIssues(item, `${at}[${index}]`));
13
+ if (value && typeof value === "object")
14
+ return Object.entries(value).flatMap(([key, item]) => [
15
+ ...(credentialKey.test(key)
16
+ ? [`${at}.${key}: credential-like field`]
17
+ : []),
18
+ ...credentialIssues(item, `${at}.${key}`),
19
+ ]);
20
+ return [];
21
+ }
22
+ const credentialHint = "credentials never belong in a profile; set DEEPSEEK_API_KEY or OPENROUTER_API_KEY in the environment instead";
23
+ function enabledClients(profile) {
24
+ return Object.entries(profile.clients)
25
+ .filter(([, binding]) => binding.enabled)
26
+ .map(([client]) => client);
27
+ }
28
+ // What a run would actually get from a profile, per enabled client. The upgrade must not
29
+ // change any of it.
30
+ function behaviour(profile) {
31
+ return {
32
+ defaultClient: profile.defaultClient,
33
+ clients: Object.fromEntries((enabledClients(profile).length
34
+ ? enabledClients(profile)
35
+ : [profile.provider]).map((client) => [client, selectProfileClient(profile, client).model])),
36
+ allowedPaths: profile.allowedPaths,
37
+ allowedCommands: profile.allowedCommands,
38
+ writePolicy: profile.writePolicy,
39
+ approvalRequired: profile.governance?.approvalRequired ?? false,
40
+ skills: profile.skills,
41
+ contextSources: profile.contextSources,
42
+ instructions: profile.instructions,
43
+ memoryEnabled: profile.memory.enabled && profile.memory.scope !== "disabled",
44
+ verification: profile.verification,
45
+ contextCompression: profile.contextCompression,
46
+ };
47
+ }
48
+ export function upgradeProfile(raw) {
49
+ const input = (raw ?? {});
50
+ const credentials = credentialIssues(raw, "profile");
51
+ if (credentials.length)
52
+ return { status: "rejected", issues: [...credentials, credentialHint] };
53
+ let v1;
54
+ try {
55
+ v1 = validateProfile(raw);
56
+ }
57
+ catch (error) {
58
+ return { status: "rejected", issues: [error.message] };
59
+ }
60
+ if (v1.schemaVersion === 2)
61
+ return { status: "current" };
62
+ const changes = [];
63
+ const rawClients = (input.clients ?? {});
64
+ const clientNames = Object.keys(rawClients).length
65
+ ? Object.keys(rawClients)
66
+ : [v1.provider];
67
+ const clients = Object.fromEntries(clientNames.map((client) => {
68
+ const binding = rawClients[client] ?? { enabled: true };
69
+ // The model a v1 run of this client gets, made explicit.
70
+ const model = binding.model ??
71
+ (client === v1.provider ? v1.model : "provider-managed");
72
+ if (binding.model === undefined)
73
+ changes.push(`clients.${client}.model: explicit "${model}"`);
74
+ return [
75
+ client,
76
+ {
77
+ ...binding,
78
+ transport: isApiClient(client) ? "openai-compatible-api" : "cli",
79
+ model,
80
+ },
81
+ ];
82
+ }));
83
+ const scope = v1.memory.scope === "disabled" ? "disabled" : "profile";
84
+ if (scope !== v1.memory.scope)
85
+ changes.push(`memory.scope: "${v1.memory.scope}" -> "${scope}"`);
86
+ const governance = (input.governance ?? {});
87
+ const profile = {
88
+ schemaVersion: 2,
89
+ name: v1.name,
90
+ description: v1.description,
91
+ version: v1.version,
92
+ role: v1.role,
93
+ // The raw list: an empty list still means "the role's default skills".
94
+ skills: Array.isArray(input.skills) ? input.skills : [],
95
+ contextSources: v1.contextSources,
96
+ defaultClient: v1.defaultClient,
97
+ clients,
98
+ governance: {
99
+ ...governance,
100
+ allowedPaths: v1.allowedPaths,
101
+ allowedCommands: v1.allowedCommands,
102
+ writePolicy: v1.writePolicy,
103
+ },
104
+ memory: { enabled: v1.memory.enabled, scope },
105
+ verification: v1.verification,
106
+ contextCompression: v1.contextCompression,
107
+ instructions: v1.instructions,
108
+ };
109
+ let v2;
110
+ try {
111
+ v2 = validateProfile(profile);
112
+ }
113
+ catch (error) {
114
+ return { status: "rejected", issues: [error.message] };
115
+ }
116
+ if (JSON.stringify(behaviour(v1)) !== JSON.stringify(behaviour(v2)))
117
+ return {
118
+ status: "rejected",
119
+ issues: ["upgrade would change how this profile runs"],
120
+ };
121
+ return { status: "upgrade", profile, changes };
122
+ }
123
+ //# sourceMappingURL=profile-upgrade.js.map
@@ -0,0 +1,5 @@
1
+ import { profileSchema } from "./profile.js";
2
+ export function validateProfile(input) {
3
+ return profileSchema.parse(input);
4
+ }
5
+ //# sourceMappingURL=profile-validator.js.map