@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,105 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { atomicWrite } from "@ocean/core/shared/fs-utils.js";
|
|
6
|
+
import { liveEngineEntry, oceanPath, repoRoot, SYSTEM_DIR, } from "@ocean/core/shared/paths.js";
|
|
7
|
+
// Client configs that may launch Ocean by an absolute path into the kernel (an MCP server entry).
|
|
8
|
+
// When the engine's entry moved (packages/core → packages/harness), an entry written earlier kept
|
|
9
|
+
// the old path and the client's Ocean server failed to start without a word (T-293). Only the
|
|
10
|
+
// engine entry's former locations are rewritten, and only while they no longer exist — another
|
|
11
|
+
// kernel package's server that is merely not built yet is never touched; the files are otherwise
|
|
12
|
+
// left byte for byte. The release build's entry (T-294, removed in T-306) is repointed to the
|
|
13
|
+
// checkout even while it still exists, so no client keeps running a release.
|
|
14
|
+
// Where the engine's `dist/main.js` lived before it moved to packages/harness.
|
|
15
|
+
const FORMER_ENGINE_PACKAGES = ["core"];
|
|
16
|
+
const CLIENT_CONFIGS = [
|
|
17
|
+
".gemini/settings.json",
|
|
18
|
+
".hermes/config.yaml",
|
|
19
|
+
".codex/config.toml",
|
|
20
|
+
".claude.json",
|
|
21
|
+
".cursor/mcp.json",
|
|
22
|
+
".gemini/antigravity/mcp_config.json",
|
|
23
|
+
// Claude Desktop: macOS, then Windows.
|
|
24
|
+
"Library/Application Support/Claude/claude_desktop_config.json",
|
|
25
|
+
"AppData/Roaming/Claude/claude_desktop_config.json",
|
|
26
|
+
];
|
|
27
|
+
// The always-on service's start files as `ocean setup` writes them (macOS, Linux, Windows). An
|
|
28
|
+
// updated one needs the service restarted to take effect (T-305).
|
|
29
|
+
const SERVICE_FILES = [
|
|
30
|
+
"Library/LaunchAgents/com.ocean.runtime.plist",
|
|
31
|
+
".config/systemd/user/ocean.service",
|
|
32
|
+
"AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup/ocean.cmd",
|
|
33
|
+
];
|
|
34
|
+
function escapeRegExp(value) {
|
|
35
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
36
|
+
}
|
|
37
|
+
// A JSON config stores a Windows path with every backslash escaped, so a path is searched in
|
|
38
|
+
// both spellings and replaced in the spelling it was found in. On POSIX the two are the same.
|
|
39
|
+
function asJson(value) {
|
|
40
|
+
return JSON.stringify(value).slice(1, -1);
|
|
41
|
+
}
|
|
42
|
+
export async function repairEngineEntries(home = os.homedir()) {
|
|
43
|
+
const entry = liveEngineEntry();
|
|
44
|
+
const results = [];
|
|
45
|
+
// Without a built entry there is nothing correct to point at.
|
|
46
|
+
if (!existsSync(entry))
|
|
47
|
+
return results;
|
|
48
|
+
const releaseEntry = oceanPath(SYSTEM_DIR, "runtime", "release", "current", "packages", "harness", "dist", "main.js");
|
|
49
|
+
const targets = [
|
|
50
|
+
...FORMER_ENGINE_PACKAGES.map((name) => path.join(repoRoot(), "packages", name, "dist", "main.js")),
|
|
51
|
+
releaseEntry,
|
|
52
|
+
];
|
|
53
|
+
const stale = new RegExp([...new Set(targets.flatMap((target) => [target, asJson(target)]))]
|
|
54
|
+
.map(escapeRegExp)
|
|
55
|
+
.join("|"), "g");
|
|
56
|
+
const pathOf = (found) => targets.find((target) => target === found || asJson(target) === found) ??
|
|
57
|
+
found;
|
|
58
|
+
const files = [
|
|
59
|
+
...CLIENT_CONFIGS.map((relative) => ({
|
|
60
|
+
relative,
|
|
61
|
+
kind: "client",
|
|
62
|
+
})),
|
|
63
|
+
...SERVICE_FILES.map((relative) => ({
|
|
64
|
+
relative,
|
|
65
|
+
kind: "service",
|
|
66
|
+
})),
|
|
67
|
+
];
|
|
68
|
+
for (const { relative, kind } of files) {
|
|
69
|
+
const file = path.join(home, relative);
|
|
70
|
+
const display = `~/${relative}`;
|
|
71
|
+
let text;
|
|
72
|
+
try {
|
|
73
|
+
text = await readFile(file, "utf8");
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
// A config that exists but cannot be read is said so, never passed off as absent.
|
|
77
|
+
const missing = error.code === "ENOENT";
|
|
78
|
+
results.push({
|
|
79
|
+
file: display,
|
|
80
|
+
kind,
|
|
81
|
+
status: missing ? "missing" : "unreadable",
|
|
82
|
+
replaced: [],
|
|
83
|
+
});
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const hits = [
|
|
87
|
+
...new Set([...text.matchAll(stale)].map((match) => match[0])),
|
|
88
|
+
].filter((found) => {
|
|
89
|
+
const target = pathOf(found);
|
|
90
|
+
return (target !== entry && (target === releaseEntry || !existsSync(target)));
|
|
91
|
+
});
|
|
92
|
+
const replaced = [...new Set(hits.map(pathOf))];
|
|
93
|
+
if (!replaced.length) {
|
|
94
|
+
results.push({ file: display, kind, status: "current", replaced });
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
let next = text;
|
|
98
|
+
for (const found of hits)
|
|
99
|
+
next = next.replaceAll(found, found === pathOf(found) ? entry : asJson(entry));
|
|
100
|
+
await atomicWrite(file, next);
|
|
101
|
+
results.push({ file: display, kind, status: "updated", replaced });
|
|
102
|
+
}
|
|
103
|
+
return results;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=engine-entry-repair.js.map
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { mkdir, readdir, readFile } from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { claudeHiddenSkills, readHermesDisabled, } from "@ocean/context/context/context-cost.js";
|
|
5
|
+
import { atomicWrite } from "@ocean/core/shared/fs-utils.js";
|
|
6
|
+
import { oceanPath, SYSTEM_DIR } from "@ocean/core/shared/paths.js";
|
|
7
|
+
// The owner hides skills from Claude's model with `skillOverrides` (`off`,
|
|
8
|
+
// `user-invocable-only`). Codex, Gemini and Hermes have no such setting and load every installed
|
|
9
|
+
// skill's description on every request, so `ocean client sync` disables the same skills there:
|
|
10
|
+
// a generated block of `[[skills.config]] enabled = false` entries in ~/.codex/config.toml, and
|
|
11
|
+
// names in `skills.disabled` of ~/.gemini/settings.json and ~/.hermes/config.yaml. None of them
|
|
12
|
+
// can then use the skill at all, even explicitly; un-hiding it in Claude re-enables it on the
|
|
13
|
+
// next sync.
|
|
14
|
+
const BEGIN = "# ocean:skill-filter:begin — generated by `ocean client sync` from Claude's skillOverrides; edit those, not this";
|
|
15
|
+
const END = "# ocean:skill-filter:end";
|
|
16
|
+
// SKILL.md files directly under `root/<dir>/`, plus one category level deeper when `nested`.
|
|
17
|
+
async function installedSkills(root, nested) {
|
|
18
|
+
const found = [];
|
|
19
|
+
let entries;
|
|
20
|
+
try {
|
|
21
|
+
entries = (await readdir(root)).sort();
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return found;
|
|
25
|
+
}
|
|
26
|
+
for (const entry of entries) {
|
|
27
|
+
if (entry.startsWith(".") && !nested)
|
|
28
|
+
continue;
|
|
29
|
+
const file = path.join(root, entry, "SKILL.md");
|
|
30
|
+
let text;
|
|
31
|
+
try {
|
|
32
|
+
text = await readFile(file, "utf8");
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
if (nested)
|
|
36
|
+
found.push(...(await installedSkills(path.join(root, entry), false)));
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const name = /^name:[ \t]*["']?([^"'\r\n]+?)["']?[ \t]*$/m.exec(text.split(/\r?\n---/)[0] ?? "")?.[1] ?? entry;
|
|
40
|
+
found.push({ name, file });
|
|
41
|
+
}
|
|
42
|
+
return found;
|
|
43
|
+
}
|
|
44
|
+
function codexBlock(files) {
|
|
45
|
+
const entries = files.map((file) => `[[skills.config]]\npath = ${JSON.stringify(file)}\nenabled = false\n`);
|
|
46
|
+
return `${BEGIN}\n${entries.join("\n")}${END}\n`;
|
|
47
|
+
}
|
|
48
|
+
async function syncCodex(home, hidden) {
|
|
49
|
+
const file = path.join(home, ".codex", "config.toml");
|
|
50
|
+
const display = "~/.codex/config.toml";
|
|
51
|
+
let text;
|
|
52
|
+
try {
|
|
53
|
+
text = await readFile(file, "utf8");
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return { client: "codex", file: display, status: "missing", disabled: 0 };
|
|
57
|
+
}
|
|
58
|
+
const skills = [
|
|
59
|
+
...(await installedSkills(path.join(home, ".codex", "skills"), true)),
|
|
60
|
+
...(await installedSkills(path.join(home, ".agents", "skills"), false)),
|
|
61
|
+
];
|
|
62
|
+
const files = skills
|
|
63
|
+
.filter((skill) => hidden.has(skill.name))
|
|
64
|
+
.map((skill) => skill.file);
|
|
65
|
+
const start = text.indexOf(BEGIN);
|
|
66
|
+
const end = start === -1 ? -1 : text.indexOf(END, start);
|
|
67
|
+
const hasBlock = start !== -1 && end > start;
|
|
68
|
+
const block = files.length ? codexBlock(files) : "";
|
|
69
|
+
let next;
|
|
70
|
+
if (hasBlock) {
|
|
71
|
+
const after = text.slice(end + END.length).replace(/^\r?\n/, "");
|
|
72
|
+
next = `${text.slice(0, start)}${block}${after}`;
|
|
73
|
+
}
|
|
74
|
+
else if (block) {
|
|
75
|
+
next = `${text}${text.endsWith("\n") || !text ? "" : "\n"}\n${block}`;
|
|
76
|
+
}
|
|
77
|
+
else
|
|
78
|
+
next = text;
|
|
79
|
+
if (next === text)
|
|
80
|
+
return {
|
|
81
|
+
client: "codex",
|
|
82
|
+
file: display,
|
|
83
|
+
status: "current",
|
|
84
|
+
disabled: files.length,
|
|
85
|
+
};
|
|
86
|
+
await atomicWrite(file, next);
|
|
87
|
+
return {
|
|
88
|
+
client: "codex",
|
|
89
|
+
file: display,
|
|
90
|
+
status: "updated",
|
|
91
|
+
disabled: files.length,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function statePath() {
|
|
95
|
+
return oceanPath(SYSTEM_DIR, "state", "skill-filter.json");
|
|
96
|
+
}
|
|
97
|
+
async function readState() {
|
|
98
|
+
try {
|
|
99
|
+
const parsed = JSON.parse(await readFile(statePath(), "utf8"));
|
|
100
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return {};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Names Ocean put into a client's list, so un-hiding a skill in Claude takes it back out without
|
|
107
|
+
// touching the ones the owner disabled himself.
|
|
108
|
+
async function readAdded(client) {
|
|
109
|
+
const list = (await readState())[client];
|
|
110
|
+
return new Set(Array.isArray(list)
|
|
111
|
+
? list.filter((name) => typeof name === "string")
|
|
112
|
+
: []);
|
|
113
|
+
}
|
|
114
|
+
// Records one client's added names, keeping the other clients' entries.
|
|
115
|
+
async function recordAdded(client, added, previous) {
|
|
116
|
+
if (JSON.stringify(added) === JSON.stringify([...previous].sort()))
|
|
117
|
+
return;
|
|
118
|
+
await mkdir(path.dirname(statePath()), { recursive: true });
|
|
119
|
+
await atomicWrite(statePath(), `${JSON.stringify({ ...(await readState()), [client]: added }, null, 2)}\n`);
|
|
120
|
+
}
|
|
121
|
+
// The owner's own entries first, then the hidden skills Ocean adds (never twice).
|
|
122
|
+
function mergeDisabled(current, previous, wanted) {
|
|
123
|
+
const owners = current.filter((name) => !previous.has(name));
|
|
124
|
+
const added = wanted.filter((name) => !owners.includes(name));
|
|
125
|
+
return { next: [...owners, ...added], added };
|
|
126
|
+
}
|
|
127
|
+
async function syncGemini(home, hidden) {
|
|
128
|
+
const file = path.join(home, ".gemini", "settings.json");
|
|
129
|
+
const display = "~/.gemini/settings.json";
|
|
130
|
+
let text;
|
|
131
|
+
try {
|
|
132
|
+
text = await readFile(file, "utf8");
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
return { client: "gemini", file: display, status: "missing", disabled: 0 };
|
|
136
|
+
}
|
|
137
|
+
let settings;
|
|
138
|
+
try {
|
|
139
|
+
const parsed = JSON.parse(text);
|
|
140
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
141
|
+
throw new Error("not an object");
|
|
142
|
+
settings = parsed;
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
return {
|
|
146
|
+
client: "gemini",
|
|
147
|
+
file: display,
|
|
148
|
+
status: "unparseable",
|
|
149
|
+
disabled: 0,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
const installed = new Set([
|
|
153
|
+
...(await installedSkills(path.join(home, ".gemini", "skills"), false)),
|
|
154
|
+
...(await installedSkills(path.join(home, ".agents", "skills"), false)),
|
|
155
|
+
].map((skill) => skill.name));
|
|
156
|
+
const wanted = [...hidden].filter((name) => installed.has(name)).sort();
|
|
157
|
+
const skills = settings.skills && typeof settings.skills === "object"
|
|
158
|
+
? settings.skills
|
|
159
|
+
: {};
|
|
160
|
+
const current = Array.isArray(skills.disabled)
|
|
161
|
+
? skills.disabled.filter((name) => typeof name === "string")
|
|
162
|
+
: [];
|
|
163
|
+
const previous = await readAdded("gemini");
|
|
164
|
+
const { next, added } = mergeDisabled(current, previous, wanted);
|
|
165
|
+
const record = () => recordAdded("gemini", added, previous);
|
|
166
|
+
if (JSON.stringify(next) === JSON.stringify(current)) {
|
|
167
|
+
await record();
|
|
168
|
+
return {
|
|
169
|
+
client: "gemini",
|
|
170
|
+
file: display,
|
|
171
|
+
status: "current",
|
|
172
|
+
disabled: wanted.length,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
const updated = { ...settings, skills: { ...skills, disabled: next } };
|
|
176
|
+
await atomicWrite(file, `${JSON.stringify(updated, null, 2)}\n`);
|
|
177
|
+
await record();
|
|
178
|
+
return {
|
|
179
|
+
client: "gemini",
|
|
180
|
+
file: display,
|
|
181
|
+
status: "updated",
|
|
182
|
+
disabled: wanted.length,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
export async function syncSkillFilter(home = os.homedir()) {
|
|
186
|
+
const hidden = await claudeHiddenSkills(home);
|
|
187
|
+
return [
|
|
188
|
+
await syncCodex(home, hidden),
|
|
189
|
+
await syncGemini(home, hidden),
|
|
190
|
+
await syncHermes(home, hidden),
|
|
191
|
+
];
|
|
192
|
+
}
|
|
193
|
+
// Hermes reads `skills.disabled` from ~/.hermes/config.yaml. Only that key is rewritten, line by
|
|
194
|
+
// line; a shape the reader does not understand is reported, never rewritten.
|
|
195
|
+
async function syncHermes(home, hidden) {
|
|
196
|
+
const file = path.join(home, ".hermes", "config.yaml");
|
|
197
|
+
const display = "~/.hermes/config.yaml";
|
|
198
|
+
let text;
|
|
199
|
+
try {
|
|
200
|
+
text = await readFile(file, "utf8");
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
return { client: "hermes", file: display, status: "missing", disabled: 0 };
|
|
204
|
+
}
|
|
205
|
+
const parsed = readHermesDisabled(text);
|
|
206
|
+
if (!parsed)
|
|
207
|
+
return {
|
|
208
|
+
client: "hermes",
|
|
209
|
+
file: display,
|
|
210
|
+
status: "unparseable",
|
|
211
|
+
disabled: 0,
|
|
212
|
+
};
|
|
213
|
+
const installed = new Set((await installedSkills(path.join(home, ".hermes", "skills"), true)).map((skill) => skill.name));
|
|
214
|
+
const wanted = [...hidden].filter((name) => installed.has(name)).sort();
|
|
215
|
+
const previous = await readAdded("hermes");
|
|
216
|
+
const { next, added } = mergeDisabled(parsed.names, previous, wanted);
|
|
217
|
+
const record = () => recordAdded("hermes", added, previous);
|
|
218
|
+
const result = (status) => ({
|
|
219
|
+
client: "hermes",
|
|
220
|
+
file: display,
|
|
221
|
+
status,
|
|
222
|
+
disabled: wanted.length,
|
|
223
|
+
});
|
|
224
|
+
// Same names in another order is not a change: the owner's file is left as written.
|
|
225
|
+
if (next.length === parsed.names.length &&
|
|
226
|
+
next.every((name) => parsed.names.includes(name))) {
|
|
227
|
+
await record();
|
|
228
|
+
return result("current");
|
|
229
|
+
}
|
|
230
|
+
const { indent, lines } = parsed;
|
|
231
|
+
const quote = (name) => /^[\w.-]+$/.test(name) ? name : JSON.stringify(name);
|
|
232
|
+
const block = next.length
|
|
233
|
+
? [`${indent}disabled:`, ...next.map((name) => `${indent}- ${quote(name)}`)]
|
|
234
|
+
: [`${indent}disabled: []`];
|
|
235
|
+
let updated;
|
|
236
|
+
if (parsed.disabled) {
|
|
237
|
+
const [from, to] = parsed.disabled;
|
|
238
|
+
updated = [...lines.slice(0, from), ...block, ...lines.slice(to)];
|
|
239
|
+
}
|
|
240
|
+
else if (parsed.skills >= 0)
|
|
241
|
+
updated = [
|
|
242
|
+
...lines.slice(0, parsed.skills + 1),
|
|
243
|
+
...block,
|
|
244
|
+
...lines.slice(parsed.skills + 1),
|
|
245
|
+
];
|
|
246
|
+
else {
|
|
247
|
+
const body = lines.at(-1) === "" ? lines.slice(0, -1) : lines;
|
|
248
|
+
updated = [...body, "skills:", ...block, ""];
|
|
249
|
+
}
|
|
250
|
+
await atomicWrite(file, updated.join("\n"));
|
|
251
|
+
await record();
|
|
252
|
+
return result("updated");
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=skill-filter.js.map
|