@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.
- package/LICENSE +21 -0
- package/README.md +284 -2
- package/dist/application/auth/auth-orchestrator.js +77 -0
- package/dist/application/clients/clients.js +646 -0
- package/dist/application/clients/editors.js +398 -0
- package/dist/application/clients/hooks.js +335 -0
- package/dist/application/clients/native.js +410 -0
- package/dist/application/clients/opencode-plugin.js +158 -0
- package/dist/application/clients/registry.js +188 -0
- package/dist/application/gateway/webhook-gateway.js +137 -0
- package/dist/application/install/provider-installer.js +184 -0
- package/dist/application/integrations/charter-copies.js +76 -0
- package/dist/application/integrations/claude-vscode.js +106 -0
- package/dist/application/integrations/engine-entry-repair.js +105 -0
- package/dist/application/integrations/skill-filter.js +254 -0
- package/dist/application/layout/layout-apply.js +443 -0
- package/dist/application/layout/layout-plan.js +236 -0
- package/dist/application/layout/workspace-template.js +34 -0
- package/dist/application/onboarding/state.js +23 -0
- package/dist/application/onboarding/steps.js +249 -0
- package/dist/application/profiles/profile-distribution.js +53 -0
- package/dist/application/profiles/profile-suggestion.js +39 -0
- package/dist/application/profiles/profile-upgrade-service.js +208 -0
- package/dist/application/pull/history-index.js +476 -0
- package/dist/application/pull/project-match.js +132 -0
- package/dist/application/pull/pull.js +202 -0
- package/dist/application/pull/server-capture.js +307 -0
- package/dist/application/scheduler/local-scheduler.js +210 -0
- package/dist/composition/runtime.js +64 -0
- package/dist/engine-root.js +9 -0
- package/dist/infrastructure/filesystem/profile-loader.js +46 -0
- package/dist/infrastructure/filesystem/runtime-config-loader.js +29 -0
- package/dist/infrastructure/filesystem/skill-loader.js +84 -0
- package/dist/infrastructure/filesystem/workspace-capability.js +37 -0
- package/dist/infrastructure/observability/runtime-logger.js +16 -0
- package/dist/infrastructure/process/agent-tool-executor.js +99 -0
- package/dist/infrastructure/process/cli-process.js +49 -0
- package/dist/infrastructure/process/interactive-process.js +145 -0
- package/dist/infrastructure/process/process-supervisor.js +194 -0
- package/dist/infrastructure/process/service.js +252 -0
- package/dist/infrastructure/providers/browser-provider.js +2 -0
- package/dist/infrastructure/providers/claude-sdk.js +137 -0
- package/dist/infrastructure/providers/client-home.js +14 -0
- package/dist/infrastructure/providers/fake-browser-provider.js +146 -0
- package/dist/infrastructure/providers/ollama-embedder.js +74 -0
- package/dist/infrastructure/providers/openai-compatible.js +268 -0
- package/dist/infrastructure/providers/playwright-browser-provider.js +380 -0
- package/dist/infrastructure/providers/provider-capabilities.js +50 -0
- package/dist/infrastructure/providers/provider-invocation.js +184 -0
- package/dist/infrastructure/providers/provider-registry.js +77 -0
- package/dist/infrastructure/providers/providers.js +134 -0
- package/dist/infrastructure/wrappers/wrapper-manager.js +374 -0
- package/dist/interfaces/cli/auth-command.js +54 -0
- package/dist/interfaces/cli/browser-bridge-command.js +93 -0
- package/dist/interfaces/cli/browser-command.js +119 -0
- package/dist/interfaces/cli/capture-command.js +125 -0
- package/dist/interfaces/cli/client-test-command.js +133 -0
- package/dist/interfaces/cli/clients-command.js +129 -0
- package/dist/interfaces/cli/command-registry.js +1211 -0
- package/dist/interfaces/cli/context-command.js +172 -0
- package/dist/interfaces/cli/daily-command.js +131 -0
- package/dist/interfaces/cli/governance-command.js +55 -0
- package/dist/interfaces/cli/handoff-command.js +35 -0
- package/dist/interfaces/cli/help-command.js +207 -0
- package/dist/interfaces/cli/idea-command.js +47 -0
- package/dist/interfaces/cli/intercept-command.js +317 -0
- package/dist/interfaces/cli/layout-command.js +27 -0
- package/dist/interfaces/cli/market-command.js +52 -0
- package/dist/interfaces/cli/mcp-gateway-command.js +30 -0
- package/dist/interfaces/cli/memory-command.js +317 -0
- package/dist/interfaces/cli/migrate-command.js +26 -0
- package/dist/interfaces/cli/observe-command.js +78 -0
- package/dist/interfaces/cli/onboard-command.js +123 -0
- package/dist/interfaces/cli/operate-command.js +59 -0
- package/dist/interfaces/cli/profiles-command.js +70 -0
- package/dist/interfaces/cli/pull-command.js +54 -0
- package/dist/interfaces/cli/setup-command.js +143 -0
- package/dist/interfaces/cli/tasks-command.js +249 -0
- package/dist/main.js +49 -0
- package/dist/node-warnings.js +17 -0
- package/dist/version.js +8 -0
- package/market/mcp/chrome-devtools/ocean.capability.json +28 -0
- package/market/mcp/gateway/ocean.capability.json +21 -0
- package/market/mcp/obsidian/ocean.capability.json +21 -0
- package/market/mcp/ocean/ocean.capability.json +21 -0
- package/market/mcp/playwright/ocean.capability.json +23 -0
- package/node_modules/@ocean/brain/dist/brain/brain-eval.js +29 -0
- package/node_modules/@ocean/brain/dist/brain/brain-markdown.js +226 -0
- package/node_modules/@ocean/brain/dist/brain/brain-reindex.js +247 -0
- package/node_modules/@ocean/brain/dist/brain/brain-service.js +320 -0
- package/node_modules/@ocean/brain/dist/capture/inbox-sync.js +22 -0
- package/node_modules/@ocean/brain/dist/evidence/verification-report.js +13 -0
- package/node_modules/@ocean/brain/dist/infrastructure/brain/brain-index.js +285 -0
- package/node_modules/@ocean/brain/dist/memory/brain-dump.js +145 -0
- package/node_modules/@ocean/brain/dist/memory/daily-narrative.js +142 -0
- package/node_modules/@ocean/brain/dist/memory/index-sync.js +124 -0
- package/node_modules/@ocean/brain/dist/memory/lesson-activation.js +93 -0
- package/node_modules/@ocean/brain/dist/memory/lesson-learning.js +188 -0
- package/node_modules/@ocean/brain/dist/memory/lessons.js +321 -0
- package/node_modules/@ocean/brain/dist/memory/memory-audit.js +100 -0
- package/node_modules/@ocean/brain/dist/memory/memory-digest.js +49 -0
- package/node_modules/@ocean/brain/dist/memory/memory-harvest.js +345 -0
- package/node_modules/@ocean/brain/dist/memory/memory-paths.js +174 -0
- package/node_modules/@ocean/brain/dist/memory/memory-review.js +278 -0
- package/node_modules/@ocean/brain/dist/memory/memory-trash.js +152 -0
- package/node_modules/@ocean/brain/dist/memory/memory-write.js +216 -0
- package/node_modules/@ocean/brain/dist/memory/model-narrative.js +129 -0
- package/node_modules/@ocean/brain/dist/memory/profile-facts.js +103 -0
- package/node_modules/@ocean/brain/dist/memory/session-promotion.js +61 -0
- package/node_modules/@ocean/brain/dist/memory/session-summary.js +113 -0
- package/node_modules/@ocean/brain/package.json +11 -0
- package/node_modules/@ocean/context/dist/context/context-compression.js +66 -0
- package/node_modules/@ocean/context/dist/context/context-cost.js +587 -0
- package/node_modules/@ocean/context/dist/context/context-ladder.js +363 -0
- package/node_modules/@ocean/context/dist/context/context-packet.js +213 -0
- package/node_modules/@ocean/context/dist/context/context-references.js +255 -0
- package/node_modules/@ocean/context/dist/context/intent-router.js +259 -0
- package/node_modules/@ocean/context/dist/context/resource-injection.js +36 -0
- package/node_modules/@ocean/context/package.json +11 -0
- package/node_modules/@ocean/core/dist/domain/brain/brain-record.js +22 -0
- package/node_modules/@ocean/core/dist/domain/brain/record-scope.js +22 -0
- package/node_modules/@ocean/core/dist/domain/capabilities/browser-contract.js +64 -0
- package/node_modules/@ocean/core/dist/domain/capabilities/capability-contract.js +16 -0
- package/node_modules/@ocean/core/dist/domain/capabilities/capability-manifest.js +72 -0
- package/node_modules/@ocean/core/dist/domain/context/context-validator.js +5 -0
- package/node_modules/@ocean/core/dist/domain/context/context.js +34 -0
- package/node_modules/@ocean/core/dist/domain/context/project-id.js +30 -0
- package/node_modules/@ocean/core/dist/domain/evidence/evidence.js +16 -0
- package/node_modules/@ocean/core/dist/domain/mcp/mcp-contract.js +36 -0
- package/node_modules/@ocean/core/dist/domain/mcp/memory-contract.js +41 -0
- package/node_modules/@ocean/core/dist/domain/ports/brain-index-port.js +7 -0
- package/node_modules/@ocean/core/dist/domain/ports/browser-port.js +8 -0
- package/node_modules/@ocean/core/dist/domain/ports/embedder-port.js +2 -0
- package/node_modules/@ocean/core/dist/domain/ports/platform-ports.js +2 -0
- package/node_modules/@ocean/core/dist/domain/ports/runtime-ports.js +2 -0
- package/node_modules/@ocean/core/dist/domain/ports/session-store-port.js +2 -0
- package/node_modules/@ocean/core/dist/domain/process/process-events.js +5 -0
- package/node_modules/@ocean/core/dist/domain/profiles/profile-distribution.js +19 -0
- package/node_modules/@ocean/core/dist/domain/profiles/profile-policy.js +34 -0
- package/node_modules/@ocean/core/dist/domain/profiles/profile-selection.js +73 -0
- package/node_modules/@ocean/core/dist/domain/profiles/profile-upgrade.js +123 -0
- package/node_modules/@ocean/core/dist/domain/profiles/profile-validator.js +5 -0
- package/node_modules/@ocean/core/dist/domain/profiles/profile.js +218 -0
- package/node_modules/@ocean/core/dist/domain/profiles/runtime-config.js +30 -0
- package/node_modules/@ocean/core/dist/domain/providers/provider-capability.js +28 -0
- package/node_modules/@ocean/core/dist/domain/providers/provider.js +2 -0
- package/node_modules/@ocean/core/dist/domain/redaction/redaction.js +86 -0
- package/node_modules/@ocean/core/dist/domain/runs/agent-tools.js +92 -0
- package/node_modules/@ocean/core/dist/domain/runs/execution-plan.js +71 -0
- package/node_modules/@ocean/core/dist/domain/runs/run-contract.js +38 -0
- package/node_modules/@ocean/core/dist/domain/sessions/entry-contract.js +31 -0
- package/node_modules/@ocean/core/dist/domain/sessions/handoff.js +78 -0
- package/node_modules/@ocean/core/dist/domain/sessions/session.js +58 -0
- package/node_modules/@ocean/core/dist/domain/skills/default-skills.js +29 -0
- package/node_modules/@ocean/core/dist/domain/skills/skill-validator.js +5 -0
- package/node_modules/@ocean/core/dist/domain/skills/skill.js +11 -0
- package/node_modules/@ocean/core/dist/domain/tasks/task-id.js +85 -0
- package/node_modules/@ocean/core/dist/shared/fs-utils.js +212 -0
- package/node_modules/@ocean/core/dist/shared/local-date.js +16 -0
- package/node_modules/@ocean/core/dist/shared/paths.js +324 -0
- package/node_modules/@ocean/core/dist/shared/project-resolution.js +1065 -0
- package/node_modules/@ocean/core/dist/shared/task-reference.js +133 -0
- package/node_modules/@ocean/core/package.json +14 -0
- package/node_modules/@ocean/loop/dist/handoff/handoff-service.js +133 -0
- package/node_modules/@ocean/loop/dist/hooks/lifecycle-hooks.js +15 -0
- package/node_modules/@ocean/loop/dist/hooks/session-end-hook.js +183 -0
- package/node_modules/@ocean/loop/dist/hooks/session-start-hook.js +237 -0
- package/node_modules/@ocean/loop/dist/infrastructure/persistence/session-store.js +690 -0
- package/node_modules/@ocean/loop/dist/infrastructure/persistence/session-validator.js +5 -0
- package/node_modules/@ocean/loop/dist/loops/iteration-graph.js +147 -0
- package/node_modules/@ocean/loop/dist/loops/task-loop-record.js +2 -0
- package/node_modules/@ocean/loop/dist/loops/task-loop.js +281 -0
- package/node_modules/@ocean/loop/dist/operations/memory-knowledge-operations.js +263 -0
- package/node_modules/@ocean/loop/dist/operations/operation-contract.js +227 -0
- package/node_modules/@ocean/loop/dist/operations/operation-scope.js +28 -0
- package/node_modules/@ocean/loop/dist/operations/project-operations.js +93 -0
- package/node_modules/@ocean/loop/dist/operations/record-io.js +65 -0
- package/node_modules/@ocean/loop/dist/operations/record-operations.js +45 -0
- package/node_modules/@ocean/loop/dist/operations/task-linker.js +40 -0
- package/node_modules/@ocean/loop/dist/operations/task-operations.js +279 -0
- package/node_modules/@ocean/loop/dist/operations/write-guard.js +157 -0
- package/node_modules/@ocean/loop/dist/runs/prompt-assembly.js +112 -0
- package/node_modules/@ocean/loop/dist/runs/run-agent.js +425 -0
- package/node_modules/@ocean/loop/dist/runs/run-authorization.js +24 -0
- package/node_modules/@ocean/loop/dist/runs/tool-loop.js +173 -0
- package/node_modules/@ocean/loop/dist/sessions/session-closeout.js +150 -0
- package/node_modules/@ocean/loop/dist/sessions/session-pointer.js +133 -0
- package/node_modules/@ocean/loop/dist/sessions/session-projects.js +26 -0
- package/node_modules/@ocean/loop/dist/sessions/session-retention.js +132 -0
- package/node_modules/@ocean/loop/dist/tasks/archive-tasks.js +210 -0
- package/node_modules/@ocean/loop/dist/tasks/checkpoint-task.js +31 -0
- package/node_modules/@ocean/loop/dist/tasks/claim-task.js +126 -0
- package/node_modules/@ocean/loop/dist/tasks/list-tasks.js +113 -0
- package/node_modules/@ocean/loop/dist/tasks/new-task.js +42 -0
- package/node_modules/@ocean/loop/dist/tasks/renumber-tasks.js +134 -0
- package/node_modules/@ocean/loop/dist/tasks/verification-readiness.js +78 -0
- package/node_modules/@ocean/loop/dist/tasks/verify-task.js +234 -0
- package/node_modules/@ocean/loop/package.json +11 -0
- package/node_modules/@ocean/market/dist/adapters/mcp-adapter.js +64 -0
- package/node_modules/@ocean/market/dist/adapters/owned-directory.js +89 -0
- package/node_modules/@ocean/market/dist/adapters/plugin-adapter.js +39 -0
- package/node_modules/@ocean/market/dist/adapters/skill-adapter.js +32 -0
- package/node_modules/@ocean/market/dist/capability/adapter.js +2 -0
- package/node_modules/@ocean/market/dist/capability/catalog.js +63 -0
- package/node_modules/@ocean/market/dist/capability/content-digest.js +40 -0
- package/node_modules/@ocean/market/dist/capability/registry.js +81 -0
- package/node_modules/@ocean/market/dist/install/default-marketplace.js +47 -0
- package/node_modules/@ocean/market/dist/install/lock.js +34 -0
- package/node_modules/@ocean/market/dist/install/marketplace-service.js +165 -0
- package/node_modules/@ocean/market/dist/mcp/browser-bridge.js +263 -0
- package/node_modules/@ocean/market/dist/mcp/mcp-connection.js +67 -0
- package/node_modules/@ocean/market/dist/mcp/mcp-gateway.js +317 -0
- package/node_modules/@ocean/market/dist/mcp/mcp-launch.js +102 -0
- package/node_modules/@ocean/market/dist/mcp/mcp-runner.js +32 -0
- package/node_modules/@ocean/market/dist/security/description-scan.js +45 -0
- package/node_modules/@ocean/market/dist/security/permissions.js +57 -0
- package/node_modules/@ocean/market/dist/skills/core-skill-sync.js +113 -0
- package/node_modules/@ocean/market/dist/skills/signal-detection.js +84 -0
- package/node_modules/@ocean/market/dist/skills/skill-hub.js +220 -0
- package/node_modules/@ocean/market/package.json +11 -0
- package/node_modules/@ocean/services/dist/browser/browser-service.js +124 -0
- package/node_modules/@ocean/services/dist/browser/browser-session.js +287 -0
- package/node_modules/@ocean/services/dist/browser/browser-task-runner.js +70 -0
- package/node_modules/@ocean/services/dist/doctor/workspace-doctor.js +547 -0
- package/node_modules/@ocean/services/dist/infrastructure/mcp/call-ledger.js +114 -0
- package/node_modules/@ocean/services/dist/infrastructure/mcp/mcp-client.js +162 -0
- package/node_modules/@ocean/services/dist/infrastructure/mcp/obsidian-server.js +251 -0
- package/node_modules/@ocean/services/dist/infrastructure/mcp/ocean-server.js +880 -0
- package/node_modules/@ocean/services/dist/infrastructure/mcp/server-version.js +20 -0
- package/node_modules/@ocean/services/dist/infrastructure/mcp/tool-registry.js +29 -0
- package/node_modules/@ocean/services/dist/obsidian/conflict-log.js +68 -0
- package/node_modules/@ocean/services/dist/obsidian/inbox-promotion.js +80 -0
- package/node_modules/@ocean/services/dist/obsidian/vault-discovery.js +113 -0
- package/node_modules/@ocean/services/dist/obsidian/vault-ingestion.js +77 -0
- package/node_modules/@ocean/services/dist/obsidian/vault-sync.js +73 -0
- package/node_modules/@ocean/services/dist/obsidian/vault-writer.js +75 -0
- package/node_modules/@ocean/services/package.json +11 -0
- package/ocean-marketplace.json +415 -0
- package/package.json +67 -4
- package/skills/core/business-logic/SKILL.md +22 -0
- package/skills/core/catch-up/SKILL.md +17 -0
- package/skills/core/core-thinking/SKILL.md +11 -0
- package/skills/core/design-thinking/SKILL.md +19 -0
- package/skills/core/graft/SKILL.md +156 -0
- package/skills/core/loop/SKILL.md +20 -0
- package/skills/core/session-handoff/SKILL.md +15 -0
- package/skills/core/use-browser/SKILL.md +69 -0
- package/skills/core/verification/SKILL.md +11 -0
- package/skills/index.json +56 -0
- package/templates/README.md +4 -0
- package/templates/profiles/default.json +51 -0
- package/templates/profiles/developer.json +51 -0
- package/templates/profiles/reviewer.json +51 -0
- package/templates/profiles/strategist.json +51 -0
- package/templates/workspace/00-inbox/INBOX.md +7 -0
- package/templates/workspace/00-inbox/candidates/.gitkeep +0 -0
- package/templates/workspace/00-inbox/native/.gitkeep +0 -0
- package/templates/workspace/01-daily/.gitkeep +0 -0
- package/templates/workspace/02-personal/CONFLICTS.md +7 -0
- package/templates/workspace/02-personal/MEMORY.md +15 -0
- package/templates/workspace/02-personal/goals/.gitkeep +0 -0
- package/templates/workspace/02-personal/identity/.gitkeep +0 -0
- package/templates/workspace/02-personal/preferences/.gitkeep +0 -0
- package/templates/workspace/03-professional/.gitkeep +0 -0
- package/templates/workspace/04-projects/PROJECTS.md +5 -0
- package/templates/workspace/04-projects/_template/docs/.gitkeep +0 -0
- package/templates/workspace/04-projects/_template/memory/.gitkeep +0 -0
- package/templates/workspace/04-projects/_template/tasks/.gitkeep +0 -0
- package/templates/workspace/05-knowledge/KNOWLEDGE.md +8 -0
- package/templates/workspace/05-knowledge/decisions/.gitkeep +0 -0
- package/templates/workspace/05-knowledge/lessons/.gitkeep +0 -0
- package/templates/workspace/06-templates/TEMPLATES.md +25 -0
- package/templates/workspace/06-templates/decision.md +8 -0
- package/templates/workspace/06-templates/intelligence.md +32 -0
- package/templates/workspace/06-templates/project-claude.md +48 -0
- package/templates/workspace/06-templates/session.md +38 -0
- package/templates/workspace/06-templates/task.md +42 -0
- package/templates/workspace/MANIFEST.json +51 -0
- package/templates/workspace/bridge/config/CONFIG.md +21 -0
- package/templates/workspace/bridge/config/runtime.json +4 -0
- package/templates/workspace/charter/core.md +104 -0
- package/templates/workspace/charter/policies/README.md +31 -0
- package/templates/workspace/charter/policies/claude-code-context.md +90 -0
- package/templates/workspace/charter/policies/concise-output.md +29 -0
- package/templates/workspace/charter/policies/context.md +91 -0
- package/templates/workspace/charter/policies/contracts/task.md +189 -0
- package/templates/workspace/charter/policies/git.md +60 -0
- package/templates/workspace/charter/policies/graph.md +47 -0
- package/templates/workspace/charter/policies/knowledge.md +33 -0
- package/templates/workspace/charter/policies/lifecycle.md +119 -0
- package/templates/workspace/charter/policies/memory.md +67 -0
- package/templates/workspace/charter/policies/minimal-change.md +43 -0
- package/templates/workspace/charter/policies/models.md +57 -0
- package/templates/workspace/charter/policies/privacy-terms.txt +3 -0
- package/templates/workspace/charter/policies/response.md +39 -0
- package/templates/workspace/charter/policies/skill-observer.md +44 -0
- package/templates/workspace/charter/policies/stack.md +23 -0
- package/templates/workspace/charter/policies/task.md +139 -0
- package/templates/workspace/charter/policies/verification.md +29 -0
- package/templates/workspace/sessions/.gitkeep +0 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { searchHistory } from "../../application/pull/history-index.js";
|
|
2
|
+
import { lastPullRecord, pull } from "../../application/pull/pull.js";
|
|
3
|
+
const usage = "Usage: ocean pull [--yes] [--daily] | search [words…] [--project <id>] [--client <id>] [--limit N] [--json] | report";
|
|
4
|
+
// `ocean pull` (T-305): everything every AI client holds, into Ocean and sorted by project —
|
|
5
|
+
// memory and instruction files as review candidates, claude.ai exports from ~/Downloads, and a
|
|
6
|
+
// searchable index of every conversation. A dry run until --yes; `--daily` skips when the last
|
|
7
|
+
// pull is under a day old. `report` prints the last run's record.
|
|
8
|
+
export async function runPullCommand(args) {
|
|
9
|
+
const flags = ["--client", "--project", "--limit"];
|
|
10
|
+
const value = (flag) => {
|
|
11
|
+
const index = args.indexOf(flag);
|
|
12
|
+
return index >= 0 ? args[index + 1] : undefined;
|
|
13
|
+
};
|
|
14
|
+
if (args[0] === "search") {
|
|
15
|
+
const words = args
|
|
16
|
+
.slice(1)
|
|
17
|
+
.filter((arg, index, all) => !arg.startsWith("--") && !flags.includes(all[index - 1] ?? ""));
|
|
18
|
+
if (!words.length && !value("--project") && !value("--client"))
|
|
19
|
+
throw new Error(usage);
|
|
20
|
+
const limit = Number(value("--limit") ?? 20);
|
|
21
|
+
const hits = await searchHistory(words.join(" "), {
|
|
22
|
+
client: value("--client"),
|
|
23
|
+
project: value("--project"),
|
|
24
|
+
limit: Number.isFinite(limit) && limit > 0 ? limit : 20,
|
|
25
|
+
});
|
|
26
|
+
if (args.includes("--json")) {
|
|
27
|
+
console.log(JSON.stringify(hits, null, 2));
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
for (const hit of hits)
|
|
31
|
+
console.log(`${hit.date} ${hit.project.padEnd(16)} ${hit.client.padEnd(14)} ${hit.title || "(untitled)"}\n ${hit.file}`);
|
|
32
|
+
if (!hits.length)
|
|
33
|
+
console.error("No conversation matches.");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (args[0] === "report") {
|
|
37
|
+
const record = await lastPullRecord();
|
|
38
|
+
if (!record)
|
|
39
|
+
console.error("No pull has run with --yes yet.");
|
|
40
|
+
else
|
|
41
|
+
console.log(JSON.stringify(record, null, 2));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (args.some((arg) => !["--yes", "--daily"].includes(arg)))
|
|
45
|
+
throw new Error(usage);
|
|
46
|
+
const result = await pull({
|
|
47
|
+
apply: args.includes("--yes"),
|
|
48
|
+
daily: args.includes("--daily"),
|
|
49
|
+
});
|
|
50
|
+
console.log(JSON.stringify(result, null, 2));
|
|
51
|
+
if (!result.applied && !result.skipped)
|
|
52
|
+
console.error("Dry run: pass --yes to propose the new memory as candidates and write the history index; review with `ocean memory review list --project <id>`.");
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=pull-command.js.map
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { chmod, mkdir, readdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { registryFile } from "@ocean/core/shared/fs-utils.js";
|
|
5
|
+
import { DAILY_DIR, INBOX_DIR, KNOWLEDGE_DIR, liveEngineEntry, oceanPath, oceanRoot, PERSONAL_DIR, projectDir, REGISTRY_DIR, SYSTEM_DIR, TEMPLATES_DIR, WORKSPACE_PROJECT_ID, } from "@ocean/core/shared/paths.js";
|
|
6
|
+
import { connectObsidianVault } from "@ocean/services/obsidian/vault-discovery.js";
|
|
7
|
+
import { seedWorkspaceTemplate } from "../../application/layout/workspace-template.js";
|
|
8
|
+
import { installShellIntegration, syncProviderWrappers, } from "../../infrastructure/wrappers/wrapper-manager.js";
|
|
9
|
+
const personalDirectories = [
|
|
10
|
+
PERSONAL_DIR,
|
|
11
|
+
KNOWLEDGE_DIR,
|
|
12
|
+
DAILY_DIR,
|
|
13
|
+
INBOX_DIR,
|
|
14
|
+
TEMPLATES_DIR,
|
|
15
|
+
];
|
|
16
|
+
const REGISTRY_FILES = [
|
|
17
|
+
"providers.json",
|
|
18
|
+
"installations.json",
|
|
19
|
+
"project-bindings.json",
|
|
20
|
+
];
|
|
21
|
+
const stateDirectories = [
|
|
22
|
+
`${SYSTEM_DIR}/config/startup`,
|
|
23
|
+
`${SYSTEM_DIR}/profiles`,
|
|
24
|
+
`${SYSTEM_DIR}/sessions`,
|
|
25
|
+
REGISTRY_DIR,
|
|
26
|
+
`${SYSTEM_DIR}/integrations`,
|
|
27
|
+
`${SYSTEM_DIR}/archive`,
|
|
28
|
+
`${SYSTEM_DIR}/runtime/shims`,
|
|
29
|
+
`${SYSTEM_DIR}/runtime/temporary`,
|
|
30
|
+
];
|
|
31
|
+
async function ensureFile(file, contents) {
|
|
32
|
+
try {
|
|
33
|
+
await writeFile(file, contents, { flag: "wx" });
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
if (error.code !== "EEXIST")
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async function restrictDirectories(directory) {
|
|
41
|
+
await chmod(directory, 0o700);
|
|
42
|
+
for (const entry of await readdir(directory, { withFileTypes: true })) {
|
|
43
|
+
if (entry.isDirectory())
|
|
44
|
+
await restrictDirectories(path.join(directory, entry.name));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async function installMacStartup() {
|
|
48
|
+
const launchAgents = path.join(os.homedir(), "Library", "LaunchAgents");
|
|
49
|
+
const label = "com.ocean.runtime";
|
|
50
|
+
const plist = path.join(launchAgents, `${label}.plist`);
|
|
51
|
+
const node = process.execPath;
|
|
52
|
+
const entry = liveEngineEntry();
|
|
53
|
+
const contents = `<?xml version="1.0" encoding="UTF-8"?>
|
|
54
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
55
|
+
<plist version="1.0"><dict>
|
|
56
|
+
<key>Label</key><string>${label}</string>
|
|
57
|
+
<key>ProgramArguments</key><array><string>${node}</string><string>${entry}</string><string>service</string></array>
|
|
58
|
+
<key>WorkingDirectory</key><string>${oceanRoot()}</string>
|
|
59
|
+
<key>RunAtLoad</key><true/>
|
|
60
|
+
<key>KeepAlive</key><true/>
|
|
61
|
+
</dict></plist>
|
|
62
|
+
`;
|
|
63
|
+
await mkdir(launchAgents, { recursive: true });
|
|
64
|
+
await writeFile(plist, contents);
|
|
65
|
+
}
|
|
66
|
+
async function installLinuxStartup() {
|
|
67
|
+
const systemdUser = path.join(os.homedir(), ".config", "systemd", "user");
|
|
68
|
+
const unit = path.join(systemdUser, "ocean.service");
|
|
69
|
+
const contents = `[Unit]
|
|
70
|
+
Description=Ocean local runtime
|
|
71
|
+
|
|
72
|
+
[Service]
|
|
73
|
+
Type=simple
|
|
74
|
+
WorkingDirectory=${oceanRoot()}
|
|
75
|
+
ExecStart=${process.execPath} ${liveEngineEntry()} service
|
|
76
|
+
Restart=on-failure
|
|
77
|
+
|
|
78
|
+
[Install]
|
|
79
|
+
WantedBy=default.target
|
|
80
|
+
`;
|
|
81
|
+
await mkdir(systemdUser, { recursive: true });
|
|
82
|
+
await writeFile(unit, contents);
|
|
83
|
+
}
|
|
84
|
+
async function installWindowsStartup() {
|
|
85
|
+
const startup = path.join(process.env.APPDATA ?? path.join(os.homedir(), "AppData", "Roaming"), "Microsoft", "Windows", "Start Menu", "Programs", "Startup");
|
|
86
|
+
const launcher = path.join(startup, "ocean.cmd");
|
|
87
|
+
const contents = `@echo off\ncd /d "${oceanRoot()}"\n"${process.execPath}" "${liveEngineEntry()}" service\n`;
|
|
88
|
+
await mkdir(startup, { recursive: true });
|
|
89
|
+
await writeFile(launcher, contents);
|
|
90
|
+
}
|
|
91
|
+
export const SETUP_USAGE = "Usage: ocean setup [--obsidian <vault-path>] [--read-write]";
|
|
92
|
+
// `setup` writes shims, the shell profile and the startup entry, so anything it does not
|
|
93
|
+
// understand — `--help` included — must stop it before it writes (T-307).
|
|
94
|
+
export function parseSetupArgs(args) {
|
|
95
|
+
const options = { obsidianMode: "read-only" };
|
|
96
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
97
|
+
const arg = args[index];
|
|
98
|
+
if (arg === "--help" || arg === "-h" || arg === "help")
|
|
99
|
+
return { kind: "help" };
|
|
100
|
+
if (arg === "--read-write")
|
|
101
|
+
options.obsidianMode = "read-write";
|
|
102
|
+
else if (arg === "--obsidian") {
|
|
103
|
+
const value = args[index + 1];
|
|
104
|
+
if (!value || value.startsWith("-"))
|
|
105
|
+
return { kind: "error", message: "--obsidian needs a vault path" };
|
|
106
|
+
options.obsidianPath = value;
|
|
107
|
+
index += 1;
|
|
108
|
+
}
|
|
109
|
+
else
|
|
110
|
+
return { kind: "error", message: `Unknown setup argument: ${arg}` };
|
|
111
|
+
}
|
|
112
|
+
return { kind: "run", options };
|
|
113
|
+
}
|
|
114
|
+
export async function setup(options = {}) {
|
|
115
|
+
await Promise.all([...personalDirectories, `${projectDir(WORKSPACE_PROJECT_ID)}/tasks`].map((directory) => mkdir(oceanPath(directory), { recursive: true })));
|
|
116
|
+
// T-296: charter, policies, templates and indexes for a new workspace; existing files are kept.
|
|
117
|
+
await seedWorkspaceTemplate();
|
|
118
|
+
for (const file of REGISTRY_FILES)
|
|
119
|
+
registryFile(file);
|
|
120
|
+
await Promise.all(stateDirectories.map((directory) => mkdir(oceanPath(directory), { recursive: true })));
|
|
121
|
+
await ensureFile(oceanPath(PERSONAL_DIR, "MEMORY.md"), "# Memory\n\n## Records (generated)\n");
|
|
122
|
+
await ensureFile(oceanPath(KNOWLEDGE_DIR, "KNOWLEDGE.md"), "# Knowledge\n\n## Records (generated)\n");
|
|
123
|
+
await ensureFile(oceanPath(SYSTEM_DIR, "profiles", "default.json"), await readFile(new URL("../../../templates/profiles/default.json", import.meta.url), "utf8"));
|
|
124
|
+
// T-245: the runtime config names the default profile, so `ocean run` without --profile
|
|
125
|
+
// no longer depends on the historical fallback. An existing file is never replaced.
|
|
126
|
+
await ensureFile(oceanPath(SYSTEM_DIR, "config", "runtime.json"), `${JSON.stringify({ schemaVersion: 1, defaultProfile: "default" }, null, 2)}\n`);
|
|
127
|
+
await ensureFile(oceanPath(SYSTEM_DIR, "config", "startup", "STARTUP.md"), "# Ocean startup\n\nManaged by `ocean setup`.\n");
|
|
128
|
+
await syncProviderWrappers();
|
|
129
|
+
const shellProfile = await installShellIntegration();
|
|
130
|
+
if (process.platform === "darwin")
|
|
131
|
+
await installMacStartup();
|
|
132
|
+
if (process.platform === "linux")
|
|
133
|
+
await installLinuxStartup();
|
|
134
|
+
if (process.platform === "win32")
|
|
135
|
+
await installWindowsStartup();
|
|
136
|
+
await restrictDirectories(oceanPath(SYSTEM_DIR));
|
|
137
|
+
if (options.obsidianPath) {
|
|
138
|
+
const result = await connectObsidianVault(options.obsidianPath, options.obsidianMode ?? "read-only");
|
|
139
|
+
console.log(`Obsidian connected: ${result.vaultPath} (${result.noteCount} Markdown notes)`);
|
|
140
|
+
}
|
|
141
|
+
console.log(`Ocean setup complete: ${oceanRoot()} (AI CLI interception enabled in ${shellProfile})`);
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=setup-command.js.map
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { execFile as execFileCallback } from "node:child_process";
|
|
2
|
+
import { writeFile } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { promisify } from "node:util";
|
|
5
|
+
import { enginePath, oceanPath, projectDir, resolveWithin, WORKSPACE_PROJECT_ID, } from "@ocean/core/shared/paths.js";
|
|
6
|
+
import { folderProject, projectsWithTasks, } from "@ocean/core/shared/project-resolution.js";
|
|
7
|
+
import { resolveTaskReference } from "@ocean/core/shared/task-reference.js";
|
|
8
|
+
import { archiveDoneTasks, completeTask, } from "@ocean/loop/tasks/archive-tasks.js";
|
|
9
|
+
import { checkpointTask } from "@ocean/loop/tasks/checkpoint-task.js";
|
|
10
|
+
import { claimTask, releaseTask } from "@ocean/loop/tasks/claim-task.js";
|
|
11
|
+
import { listTasks, listTasksForFolder, } from "@ocean/loop/tasks/list-tasks.js";
|
|
12
|
+
import { newTask } from "@ocean/loop/tasks/new-task.js";
|
|
13
|
+
import { renumberTasks } from "@ocean/loop/tasks/renumber-tasks.js";
|
|
14
|
+
import { verificationReadiness } from "@ocean/loop/tasks/verification-readiness.js";
|
|
15
|
+
import { verifyTask } from "@ocean/loop/tasks/verify-task.js";
|
|
16
|
+
const execFile = promisify(execFileCallback);
|
|
17
|
+
// Re-exported for existing importers (daily/context commands, tests). The
|
|
18
|
+
// implementation and the MCP server both live in the application layer now.
|
|
19
|
+
export { listTasks };
|
|
20
|
+
// The live task an id-based action works on (resolution rules: resolveTaskReference). The
|
|
21
|
+
// action uses the location's own id and project, never the id as typed.
|
|
22
|
+
async function liveTask(id, explicitProject, cwdProject) {
|
|
23
|
+
const location = await resolveTaskReference(id, {
|
|
24
|
+
projectId: explicitProject ?? cwdProject ?? undefined,
|
|
25
|
+
explicit: Boolean(explicitProject),
|
|
26
|
+
});
|
|
27
|
+
if (location.archived)
|
|
28
|
+
throw new Error(`${location.id} is archived`);
|
|
29
|
+
return {
|
|
30
|
+
owner: location.projectId,
|
|
31
|
+
id: location.id,
|
|
32
|
+
root: resolveWithin(oceanPath(projectDir(location.projectId)), "tasks"),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
// `ocean tasks list --pretty`: one aligned row per task, for a person rather than a tool.
|
|
36
|
+
function taskTable(tasks) {
|
|
37
|
+
if (!tasks.length)
|
|
38
|
+
return "No tasks.\n";
|
|
39
|
+
const rows = [
|
|
40
|
+
["PROJECT", "ID", "STATE", "TITLE"],
|
|
41
|
+
...tasks.map((task) => [task.project, task.id, task.state, task.title]),
|
|
42
|
+
];
|
|
43
|
+
const widths = [0, 1, 2].map((column) => Math.max(...rows.map((row) => row[column].length)));
|
|
44
|
+
return rows
|
|
45
|
+
.map((row) => row
|
|
46
|
+
.map((cell, column) => column < 3 ? cell.padEnd(widths[column]) : cell)
|
|
47
|
+
.join(" ")
|
|
48
|
+
.trimEnd())
|
|
49
|
+
.join("\n")
|
|
50
|
+
.concat("\n");
|
|
51
|
+
}
|
|
52
|
+
export async function runTasksCommand(action, args) {
|
|
53
|
+
const projectIndex = args.indexOf("--project");
|
|
54
|
+
const explicitProject = projectIndex >= 0 ? args[projectIndex + 1] : undefined;
|
|
55
|
+
if (projectIndex >= 0 && !explicitProject)
|
|
56
|
+
throw new Error("--project requires a project id");
|
|
57
|
+
// Without --project, the tasks are the folder's project's (T-256): the cwd decides, and only a
|
|
58
|
+
// folder that is no project falls back to the workspace project.
|
|
59
|
+
const cwdProject = explicitProject
|
|
60
|
+
? null
|
|
61
|
+
: await folderProject(process.cwd());
|
|
62
|
+
const projectId = explicitProject ?? cwdProject ?? WORKSPACE_PROJECT_ID;
|
|
63
|
+
if (action === "list") {
|
|
64
|
+
const state = args.find((arg, index) => !arg.startsWith("--") &&
|
|
65
|
+
(projectIndex < 0 || index !== projectIndex + 1));
|
|
66
|
+
const found = await listTasksForFolder({
|
|
67
|
+
cwd: process.cwd(),
|
|
68
|
+
project: explicitProject,
|
|
69
|
+
state,
|
|
70
|
+
});
|
|
71
|
+
if (found.note)
|
|
72
|
+
console.error(found.note);
|
|
73
|
+
if (args.includes("--pretty"))
|
|
74
|
+
process.stdout.write(taskTable(found.tasks));
|
|
75
|
+
else
|
|
76
|
+
console.log(JSON.stringify(found.tasks, null, 2));
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (action === "new") {
|
|
80
|
+
const title = args.find((arg, index) => !arg.startsWith("--") &&
|
|
81
|
+
(projectIndex < 0 || index !== projectIndex + 1));
|
|
82
|
+
const created = await newTask(projectId, title ?? "");
|
|
83
|
+
console.log(JSON.stringify({
|
|
84
|
+
id: created.id,
|
|
85
|
+
project: projectId,
|
|
86
|
+
file: path.relative(oceanPath(), created.file),
|
|
87
|
+
}));
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (action === "doctor") {
|
|
91
|
+
// `--all`: every project with tasks, so a clean cwd project never hides another's drift.
|
|
92
|
+
const projects = args.includes("--all")
|
|
93
|
+
? await projectsWithTasks()
|
|
94
|
+
: [projectId];
|
|
95
|
+
for (const project of projects) {
|
|
96
|
+
const label = projects.length > 1 ? `${project}: ` : "";
|
|
97
|
+
try {
|
|
98
|
+
const result = await execFile(process.execPath, [
|
|
99
|
+
enginePath("scripts", "validate-tasks.mjs"),
|
|
100
|
+
resolveWithin(oceanPath(projectDir(project)), "tasks"),
|
|
101
|
+
]);
|
|
102
|
+
process.stdout.write(`${label}${result.stdout}`);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
const failure = error;
|
|
106
|
+
if (failure.stdout)
|
|
107
|
+
process.stdout.write(`${label}${failure.stdout}`);
|
|
108
|
+
if (failure.stderr)
|
|
109
|
+
process.stderr.write(`${label}${failure.stderr}`);
|
|
110
|
+
process.exitCode = 1;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (action === "index") {
|
|
116
|
+
const tasks = await listTasks(undefined, projectId);
|
|
117
|
+
const body = [
|
|
118
|
+
"# Tasks",
|
|
119
|
+
"",
|
|
120
|
+
"<!-- Generated by `ocean tasks index --write`. Do not edit by hand. -->",
|
|
121
|
+
"",
|
|
122
|
+
"| ID | State | Title | Goal |",
|
|
123
|
+
"|---|---|---|---|",
|
|
124
|
+
...tasks.map((task) => `| ${task.id} | ${task.state} | ${task.title.replaceAll("|", "\\|")} | ${task.goal.replaceAll("|", "\\|")} |`),
|
|
125
|
+
"",
|
|
126
|
+
].join("\n");
|
|
127
|
+
const target = resolveWithin(oceanPath(projectDir(projectId)), "index.md");
|
|
128
|
+
if (args.includes("--write")) {
|
|
129
|
+
await writeFile(target, body, "utf8");
|
|
130
|
+
console.log(`wrote ${path.relative(oceanPath(), target)}`);
|
|
131
|
+
}
|
|
132
|
+
else
|
|
133
|
+
process.stdout.write(body);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (action === "checkpoint") {
|
|
137
|
+
const id = args.find((arg) => !arg.startsWith("--"));
|
|
138
|
+
const noteIndex = args.indexOf("--note");
|
|
139
|
+
const nextIndex = args.indexOf("--next");
|
|
140
|
+
if (!id || noteIndex < 0 || !args[noteIndex + 1])
|
|
141
|
+
throw new Error("Usage: ocean tasks checkpoint <id> --note <text> [--next <text>] [--project <id>]");
|
|
142
|
+
const task = await liveTask(id, explicitProject, cwdProject);
|
|
143
|
+
const result = await checkpointTask(task.id, task.root, {
|
|
144
|
+
note: args[noteIndex + 1],
|
|
145
|
+
next: nextIndex >= 0 ? args[nextIndex + 1] : undefined,
|
|
146
|
+
});
|
|
147
|
+
// Advisory: say now if `tasks complete` will not be able to verify this task (T-291).
|
|
148
|
+
// The checkpoint is already written: a failed check is one more warning, never an error.
|
|
149
|
+
const verification = await verificationReadiness(task.id, task.root).catch((error) => ({
|
|
150
|
+
ready: false,
|
|
151
|
+
warnings: [
|
|
152
|
+
`could not check: ${error instanceof Error ? error.message : String(error)}`,
|
|
153
|
+
],
|
|
154
|
+
}));
|
|
155
|
+
console.log(JSON.stringify({ ...result, project: task.owner, verification }, null, 2));
|
|
156
|
+
if (!verification.ready)
|
|
157
|
+
console.error(`warning: ${task.id} verification: ${verification.warnings.join("; ")}`);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
if (action === "verify") {
|
|
161
|
+
const id = args.find((arg) => !arg.startsWith("--"));
|
|
162
|
+
if (!id) {
|
|
163
|
+
console.error("Usage: ocean tasks verify <id> [--project <id>]");
|
|
164
|
+
process.exitCode = 1;
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const task = await liveTask(id, explicitProject, cwdProject);
|
|
168
|
+
const outcome = await verifyTask(task.id, task.root);
|
|
169
|
+
console.log(JSON.stringify(outcome, null, 2));
|
|
170
|
+
if (!outcome.passed)
|
|
171
|
+
process.exitCode = 1;
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (action === "complete") {
|
|
175
|
+
const id = args[0];
|
|
176
|
+
if (!id) {
|
|
177
|
+
console.error("Usage: ocean tasks complete <id>");
|
|
178
|
+
process.exitCode = 1;
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
if (args.includes("--no-verify")) {
|
|
182
|
+
console.error("Task completion verification cannot be skipped.");
|
|
183
|
+
process.exitCode = 1;
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
try {
|
|
187
|
+
const task = await liveTask(id, explicitProject, cwdProject);
|
|
188
|
+
console.log(JSON.stringify(await completeTask(task.id, task.root), null, 2));
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
192
|
+
process.exitCode = 1;
|
|
193
|
+
}
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
if (action === "claim" || action === "release") {
|
|
197
|
+
const id = args[0];
|
|
198
|
+
const flag = (name) => {
|
|
199
|
+
const at = args.indexOf(name);
|
|
200
|
+
return at >= 0 ? args[at + 1] : undefined;
|
|
201
|
+
};
|
|
202
|
+
const by = flag("--by");
|
|
203
|
+
if (!id || id.startsWith("--") || (action === "claim" && !by)) {
|
|
204
|
+
console.error("Usage: ocean tasks claim <id> --by <name> [--paths a,b] [--force] [--project <id>] | ocean tasks release <id> [--by <name>] [--force]");
|
|
205
|
+
process.exitCode = 1;
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
try {
|
|
209
|
+
const task = await liveTask(id, explicitProject, cwdProject);
|
|
210
|
+
const force = args.includes("--force");
|
|
211
|
+
const result = action === "claim"
|
|
212
|
+
? await claimTask(task.id, task.root, {
|
|
213
|
+
by: by,
|
|
214
|
+
paths: flag("--paths")?.split(",").filter(Boolean),
|
|
215
|
+
force,
|
|
216
|
+
})
|
|
217
|
+
: await releaseTask(task.id, task.root, { by, force });
|
|
218
|
+
console.log(JSON.stringify({ ...result, project: task.owner }, null, 2));
|
|
219
|
+
}
|
|
220
|
+
catch (error) {
|
|
221
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
222
|
+
process.exitCode = 1;
|
|
223
|
+
}
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
if (action === "renumber") {
|
|
227
|
+
const prefixIndex = args.indexOf("--prefix");
|
|
228
|
+
const prefix = prefixIndex >= 0 ? args[prefixIndex + 1] : undefined;
|
|
229
|
+
if (!explicitProject || !prefix)
|
|
230
|
+
throw new Error("Usage: ocean tasks renumber --project <id> --prefix <PREFIX> [--write]");
|
|
231
|
+
console.log(JSON.stringify(await renumberTasks({
|
|
232
|
+
project: explicitProject,
|
|
233
|
+
prefix,
|
|
234
|
+
write: args.includes("--write"),
|
|
235
|
+
}), null, 2));
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
if (action !== "archive") {
|
|
239
|
+
console.error("Usage: ocean tasks list [state] [--project <id>] [--pretty]|new <title> [--project <id>]|doctor [--all]|index [--write]|checkpoint <id> --note <text> [--next <text>]|verify <id>|complete <id>|claim <id> --by <name> [--paths a,b] [--force]|release <id> [--by <name>] [--force]|archive [--apply|--auto]|renumber --project <id> --prefix <PREFIX> [--write]");
|
|
240
|
+
process.exitCode = 1;
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const apply = args.includes("--apply") || args.includes("--auto");
|
|
244
|
+
const result = await archiveDoneTasks(resolveWithin(oceanPath(projectDir(projectId)), "tasks"), apply);
|
|
245
|
+
console.log(JSON.stringify({ dryRun: !apply, ...result }, null, 2));
|
|
246
|
+
if (apply && result.skipped.length)
|
|
247
|
+
process.exitCode = 1;
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=tasks-command.js.map
|
package/dist/main.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import "./engine-root.js";
|
|
3
|
+
import "./node-warnings.js";
|
|
4
|
+
// Loaded dynamically so node-warnings.js is in place first: static imports would load
|
|
5
|
+
// node:sqlite, and print its warning, before any module body runs.
|
|
6
|
+
const { commandRegistry } = await import("./interfaces/cli/command-registry.js");
|
|
7
|
+
const { renderCommandHelp, renderHelp, wantsCommandHelp } = await import("./interfaces/cli/help-command.js");
|
|
8
|
+
const { onboard } = await import("./interfaces/cli/onboard-command.js");
|
|
9
|
+
const { oceanVersion } = await import("./version.js");
|
|
10
|
+
const command = process.argv[2] === "--yes" ? undefined : process.argv[2];
|
|
11
|
+
if (command === "--version" || command === "-v") {
|
|
12
|
+
console.log(await oceanVersion());
|
|
13
|
+
}
|
|
14
|
+
else if (command === "--help" || command === "-h") {
|
|
15
|
+
console.log(renderHelp());
|
|
16
|
+
}
|
|
17
|
+
else if (!command) {
|
|
18
|
+
await onboard({ yes: process.argv.includes("--yes") });
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
// Own keys only: `ocean toString` must not find Object.prototype.toString.
|
|
22
|
+
const handler = Object.hasOwn(commandRegistry, command)
|
|
23
|
+
? commandRegistry[command]
|
|
24
|
+
: undefined;
|
|
25
|
+
// `--help` never runs a command: several write files or start onboarding before they look at
|
|
26
|
+
// their arguments. setup keeps its own help (it shares SETUP_USAGE).
|
|
27
|
+
if (handler &&
|
|
28
|
+
command !== "setup" &&
|
|
29
|
+
wantsCommandHelp(process.argv.slice(3))) {
|
|
30
|
+
console.log(renderCommandHelp(command));
|
|
31
|
+
}
|
|
32
|
+
else if (handler) {
|
|
33
|
+
// A failed command prints one line; OCEAN_DEBUG=1 keeps the stack for debugging.
|
|
34
|
+
try {
|
|
35
|
+
await handler();
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
if (process.env.OCEAN_DEBUG === "1" || !(error instanceof Error))
|
|
39
|
+
throw error;
|
|
40
|
+
console.error(`Error: ${error.message}`);
|
|
41
|
+
process.exitCode = 1;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
console.error(`Unknown command: ${command}`);
|
|
46
|
+
process.exitCode = 1;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Node prints "ExperimentalWarning: SQLite is an experimental feature" on every run that loads
|
|
2
|
+
// node:sqlite, which the session store and brain index always do. Drop that one warning and
|
|
3
|
+
// pass every other through. main.ts imports this before it loads anything that reaches
|
|
4
|
+
// node:sqlite; a static import chain would load the builtin before this filter is installed.
|
|
5
|
+
const emitWarning = process.emitWarning;
|
|
6
|
+
process.emitWarning = function (warning, ...rest) {
|
|
7
|
+
const options = rest[0];
|
|
8
|
+
const type = typeof options === "string"
|
|
9
|
+
? options
|
|
10
|
+
: options?.type;
|
|
11
|
+
const message = typeof warning === "string" ? warning : warning.message;
|
|
12
|
+
if (type === "ExperimentalWarning" && message.startsWith("SQLite"))
|
|
13
|
+
return;
|
|
14
|
+
emitWarning.call(this, warning, ...rest);
|
|
15
|
+
};
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=node-warnings.js.map
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
export async function oceanVersion() {
|
|
3
|
+
const manifest = JSON.parse(await readFile(new URL("../package.json", import.meta.url), "utf8"));
|
|
4
|
+
if (typeof manifest.version !== "string" || !manifest.version.trim())
|
|
5
|
+
throw new Error("package.json must declare a non-empty version");
|
|
6
|
+
return manifest.version;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kind": "mcp",
|
|
3
|
+
"name": "dev.ocean/chrome-devtools",
|
|
4
|
+
"description": "Control the owner's real, signed-in Chrome through Chrome DevTools MCP: tabs, navigation, clicks, forms, screenshots, console and network errors. Reads every open tab and acts inside any signed-in session of the attached profile, for every client that uses the Ocean gateway. The filesystem permission is declared for consent but not enforced at runtime, and the npm package is pinned by version, not by digest.",
|
|
5
|
+
"permissions": {
|
|
6
|
+
"filesystem": { "read": ["~/Library/Application Support/Google/Chrome"] },
|
|
7
|
+
"network": ["registry.npmjs.org", "localhost", "127.0.0.1"],
|
|
8
|
+
"exec": ["npx"]
|
|
9
|
+
},
|
|
10
|
+
"server": {
|
|
11
|
+
"name": "dev.ocean/chrome-devtools",
|
|
12
|
+
"description": "Chrome DevTools MCP attached to the owner's running Chrome. Usage statistics and CrUX lookups are off, so page URLs stay on this machine.",
|
|
13
|
+
"packages": [
|
|
14
|
+
{
|
|
15
|
+
"registryType": "npm",
|
|
16
|
+
"identifier": "chrome-devtools-mcp",
|
|
17
|
+
"version": "1.12.0",
|
|
18
|
+
"transport": { "type": "stdio" },
|
|
19
|
+
"packageArguments": [
|
|
20
|
+
{ "type": "positional", "value": "--autoConnect" },
|
|
21
|
+
{ "type": "positional", "value": "--no-usage-statistics" },
|
|
22
|
+
{ "type": "positional", "value": "--no-performance-crux" }
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"_meta": { "dev.ocean": { "clientKey": "chrome-devtools" } }
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kind": "mcp",
|
|
3
|
+
"name": "dev.ocean/mcp-gateway",
|
|
4
|
+
"description": "One MCP endpoint for every registered server: Ocean's own and those installed from the marketplace.",
|
|
5
|
+
"server": {
|
|
6
|
+
"name": "dev.ocean/mcp-gateway",
|
|
7
|
+
"description": "Lists and routes the tools of every registered MCP server behind one stdio endpoint.",
|
|
8
|
+
"packages": [
|
|
9
|
+
{
|
|
10
|
+
"registryType": "ocean-engine",
|
|
11
|
+
"identifier": "ocean",
|
|
12
|
+
"transport": { "type": "stdio" },
|
|
13
|
+
"packageArguments": [
|
|
14
|
+
{ "type": "positional", "value": "mcp" },
|
|
15
|
+
{ "type": "positional", "value": "gateway" }
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"_meta": { "dev.ocean": { "clientKey": "ocean-gateway" } }
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kind": "mcp",
|
|
3
|
+
"name": "dev.ocean/obsidian",
|
|
4
|
+
"description": "Ocean's Obsidian vault bridge over MCP.",
|
|
5
|
+
"server": {
|
|
6
|
+
"name": "dev.ocean/obsidian",
|
|
7
|
+
"description": "Read and sync an Obsidian vault through Ocean.",
|
|
8
|
+
"packages": [
|
|
9
|
+
{
|
|
10
|
+
"registryType": "ocean-engine",
|
|
11
|
+
"identifier": "ocean",
|
|
12
|
+
"transport": { "type": "stdio" },
|
|
13
|
+
"packageArguments": [
|
|
14
|
+
{ "type": "positional", "value": "obsidian" },
|
|
15
|
+
{ "type": "positional", "value": "mcp" }
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"_meta": { "dev.ocean": { "clientKey": "ocean-obsidian" } }
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kind": "mcp",
|
|
3
|
+
"name": "dev.ocean/ocean",
|
|
4
|
+
"description": "Ocean's own MCP server: workspace status, tasks, handoffs, sessions and the brain.",
|
|
5
|
+
"server": {
|
|
6
|
+
"name": "dev.ocean/ocean",
|
|
7
|
+
"description": "Ocean workspace, tasks, sessions and brain over MCP.",
|
|
8
|
+
"packages": [
|
|
9
|
+
{
|
|
10
|
+
"registryType": "ocean-engine",
|
|
11
|
+
"identifier": "ocean",
|
|
12
|
+
"transport": { "type": "stdio" },
|
|
13
|
+
"packageArguments": [
|
|
14
|
+
{ "type": "positional", "value": "mcp" },
|
|
15
|
+
{ "type": "positional", "value": "serve" }
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"_meta": { "dev.ocean": { "clientKey": "ocean" } }
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kind": "mcp",
|
|
3
|
+
"name": "com.microsoft/playwright-mcp",
|
|
4
|
+
"description": "Playwright browser automation through the browser extension.",
|
|
5
|
+
"permissions": {
|
|
6
|
+
"network": ["registry.npmjs.org", "localhost", "127.0.0.1"],
|
|
7
|
+
"exec": ["npx"]
|
|
8
|
+
},
|
|
9
|
+
"server": {
|
|
10
|
+
"name": "com.microsoft/playwright-mcp",
|
|
11
|
+
"description": "Browser automation with Playwright.",
|
|
12
|
+
"packages": [
|
|
13
|
+
{
|
|
14
|
+
"registryType": "npm",
|
|
15
|
+
"identifier": "@playwright/mcp",
|
|
16
|
+
"version": "0.0.84",
|
|
17
|
+
"transport": { "type": "stdio" },
|
|
18
|
+
"packageArguments": [{ "type": "positional", "value": "--extension" }]
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"_meta": { "dev.ocean": { "clientKey": "playwright" } }
|
|
22
|
+
}
|
|
23
|
+
}
|