synabun 2.0.10 → 2.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/CHANGELOG.md +207 -0
- package/README.md +25 -2
- package/THIRD-PARTY-LICENSES.md +22 -0
- package/bin/synabun.js +71 -24
- package/docs/whatsapp.md +13 -13
- package/hooks/claude-code/pre-websearch.mjs +12 -1
- package/hooks/claude-code/shared.mjs +5 -0
- package/hooks/claude-code/stop.mjs +1 -1
- package/lib/claude-hooks.js +172 -18
- package/lib/client-config-repair.js +30 -17
- package/lib/desktop-app.js +7 -1
- package/lib/external-tools.js +7 -6
- package/lib/first-launch-protection.js +57 -12
- package/lib/mcp-dist.js +176 -0
- package/lib/release-npm-ci.mjs +138 -0
- package/lib/release-publish.mjs +91 -0
- package/lib/release-scan.mjs +50 -0
- package/lib/server-crash-record.js +123 -0
- package/lib/server-exit.js +318 -0
- package/lib/server-supervisor.js +508 -0
- package/lib/start-launcher.js +37 -4
- package/lib/tools-cli.js +45 -0
- package/lib/update-snapshot.js +302 -0
- package/lib/virustotal.mjs +203 -0
- package/lib/windows-crash-event.js +269 -0
- package/mcp-server/dist/http.d.ts +20 -1
- package/mcp-server/dist/http.d.ts.map +1 -1
- package/mcp-server/dist/http.js +59 -12
- package/mcp-server/dist/http.js.map +1 -1
- package/mcp-server/dist/index.d.ts +33 -27
- package/mcp-server/dist/index.d.ts.map +1 -1
- package/mcp-server/dist/index.js +128 -143
- package/mcp-server/dist/index.js.map +1 -1
- package/mcp-server/dist/preload.js +1 -1
- package/mcp-server/dist/preload.js.map +1 -1
- package/mcp-server/dist/services/budget-judgments.d.ts +1 -1
- package/mcp-server/dist/services/budget-judgments.d.ts.map +1 -1
- package/mcp-server/dist/services/budget-judgments.js +5 -3
- package/mcp-server/dist/services/budget-judgments.js.map +1 -1
- package/mcp-server/dist/services/codex-config-heal.d.ts +6 -2
- package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -1
- package/mcp-server/dist/services/codex-config-heal.js +81 -28
- package/mcp-server/dist/services/codex-config-heal.js.map +1 -1
- package/mcp-server/dist/services/identity.d.ts +2 -2
- package/mcp-server/dist/services/identity.js +2 -2
- package/mcp-server/dist/services/memory-judge-backfill.d.ts +6 -0
- package/mcp-server/dist/services/memory-judge-backfill.d.ts.map +1 -1
- package/mcp-server/dist/services/memory-judge-backfill.js +7 -1
- package/mcp-server/dist/services/memory-judge-backfill.js.map +1 -1
- package/mcp-server/dist/services/memory-sessions.d.ts +1 -1
- package/mcp-server/dist/services/memory-sessions.d.ts.map +1 -1
- package/mcp-server/dist/services/memory-sessions.js +28 -2
- package/mcp-server/dist/services/memory-sessions.js.map +1 -1
- package/mcp-server/dist/services/neural-interface.d.ts +18 -11
- package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
- package/mcp-server/dist/services/neural-interface.js +67 -11
- package/mcp-server/dist/services/neural-interface.js.map +1 -1
- package/mcp-server/dist/services/server-instructions.d.ts +7 -2
- package/mcp-server/dist/services/server-instructions.d.ts.map +1 -1
- package/mcp-server/dist/services/server-instructions.js +22 -63
- package/mcp-server/dist/services/server-instructions.js.map +1 -1
- package/mcp-server/dist/services/tool-catalog.d.ts +120 -0
- package/mcp-server/dist/services/tool-catalog.d.ts.map +1 -0
- package/mcp-server/dist/services/tool-catalog.js +339 -0
- package/mcp-server/dist/services/tool-catalog.js.map +1 -0
- package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts +12 -0
- package/mcp-server/dist/services/tool-list-refresh-barrier.d.ts.map +1 -0
- package/mcp-server/dist/services/tool-list-refresh-barrier.js +40 -0
- package/mcp-server/dist/services/tool-list-refresh-barrier.js.map +1 -0
- package/mcp-server/dist/services/tool-list.d.ts +108 -0
- package/mcp-server/dist/services/tool-list.d.ts.map +1 -0
- package/mcp-server/dist/services/tool-list.js +334 -0
- package/mcp-server/dist/services/tool-list.js.map +1 -0
- package/mcp-server/dist/services/tool-runtime.d.ts +161 -0
- package/mcp-server/dist/services/tool-runtime.d.ts.map +1 -0
- package/mcp-server/dist/services/tool-runtime.js +400 -0
- package/mcp-server/dist/services/tool-runtime.js.map +1 -0
- package/mcp-server/dist/services/typesafe-config.js +1 -1
- package/mcp-server/dist/services/typesafe-config.js.map +1 -1
- package/mcp-server/dist/services/whiteboard-geometry.d.ts +26 -2
- package/mcp-server/dist/services/whiteboard-geometry.d.ts.map +1 -1
- package/mcp-server/dist/services/whiteboard-geometry.js +91 -8
- package/mcp-server/dist/services/whiteboard-geometry.js.map +1 -1
- package/mcp-server/dist/tools/agents.d.ts +14 -14
- package/mcp-server/dist/tools/agents.d.ts.map +1 -1
- package/mcp-server/dist/tools/agents.js +29 -19
- package/mcp-server/dist/tools/agents.js.map +1 -1
- package/mcp-server/dist/tools/browser-batch.d.ts +3 -3
- package/mcp-server/dist/tools/choice.d.ts +6 -0
- package/mcp-server/dist/tools/choice.d.ts.map +1 -1
- package/mcp-server/dist/tools/choice.js +18 -13
- package/mcp-server/dist/tools/choice.js.map +1 -1
- package/mcp-server/dist/tools/git-tools.js +2 -2
- package/mcp-server/dist/tools/git-tools.js.map +1 -1
- package/mcp-server/dist/tools/image-tools.d.ts +1 -1
- package/mcp-server/dist/tools/image-tools.js +1 -1
- package/mcp-server/dist/tools/morelogin.d.ts.map +1 -1
- package/mcp-server/dist/tools/morelogin.js +9 -6
- package/mcp-server/dist/tools/morelogin.js.map +1 -1
- package/mcp-server/dist/tools/skill-tools.d.ts +505 -0
- package/mcp-server/dist/tools/skill-tools.d.ts.map +1 -0
- package/mcp-server/dist/tools/skill-tools.js +642 -0
- package/mcp-server/dist/tools/skill-tools.js.map +1 -0
- package/mcp-server/dist/tools/skill.d.ts +7 -0
- package/mcp-server/dist/tools/skill.d.ts.map +1 -0
- package/mcp-server/dist/tools/skill.js +11 -0
- package/mcp-server/dist/tools/skill.js.map +1 -0
- package/mcp-server/dist/tools/tool-groups.d.ts +68 -0
- package/mcp-server/dist/tools/tool-groups.d.ts.map +1 -0
- package/mcp-server/dist/tools/tool-groups.js +147 -0
- package/mcp-server/dist/tools/tool-groups.js.map +1 -0
- package/mcp-server/dist/tools/whiteboard-format.d.ts.map +1 -1
- package/mcp-server/dist/tools/whiteboard-format.js +7 -4
- package/mcp-server/dist/tools/whiteboard-format.js.map +1 -1
- package/mcp-server/dist/tools/whiteboard-tools.d.ts +64 -13
- package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/whiteboard-tools.js +30 -5
- package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -1
- package/mcp-server/package-lock.json +2 -2
- package/mcp-server/package.json +1 -1
- package/mcp-server/src/http.ts +75 -12
- package/mcp-server/src/index.ts +147 -154
- package/mcp-server/src/preload.ts +12 -12
- package/mcp-server/src/services/budget-judgments.ts +5 -3
- package/mcp-server/src/services/codex-config-heal.ts +80 -29
- package/mcp-server/src/services/identity.ts +2 -2
- package/mcp-server/src/services/memory-judge-backfill.ts +7 -1
- package/mcp-server/src/services/memory-sessions.ts +24 -3
- package/mcp-server/src/services/neural-interface.ts +81 -21
- package/mcp-server/src/services/server-instructions.ts +29 -64
- package/mcp-server/src/services/tool-catalog.ts +403 -0
- package/mcp-server/src/services/tool-list-refresh-barrier.ts +33 -0
- package/mcp-server/src/services/tool-list.ts +410 -0
- package/mcp-server/src/services/tool-runtime.ts +457 -0
- package/mcp-server/src/services/typesafe-config.ts +1 -1
- package/mcp-server/src/services/whiteboard-geometry.ts +94 -9
- package/mcp-server/src/tools/agents.ts +29 -20
- package/mcp-server/src/tools/choice.ts +17 -12
- package/mcp-server/src/tools/git-tools.ts +2 -2
- package/mcp-server/src/tools/image-tools.ts +1 -1
- package/mcp-server/src/tools/morelogin.ts +6 -4
- package/mcp-server/src/tools/skill-tools.ts +592 -0
- package/mcp-server/src/tools/skill.ts +13 -0
- package/mcp-server/src/tools/tool-groups.ts +164 -0
- package/mcp-server/src/tools/whiteboard-format.ts +9 -3
- package/mcp-server/src/tools/whiteboard-tools.ts +39 -5
- package/neural-interface/i18n/en.json +3953 -228
- package/neural-interface/i18n/pt-BR.json +3901 -179
- package/neural-interface/lib/agent-sandbox-elevation.js +6 -0
- package/neural-interface/lib/antigravity/acp-client-host.js +554 -0
- package/neural-interface/lib/antigravity/acp-connection.js +299 -0
- package/neural-interface/lib/antigravity/bypass.js +100 -0
- package/neural-interface/lib/antigravity/catalog.js +273 -0
- package/neural-interface/lib/antigravity/home.js +260 -0
- package/neural-interface/lib/antigravity/migrate-gemini.js +139 -0
- package/neural-interface/lib/antigravity/panel-bridge.js +1058 -0
- package/neural-interface/lib/antigravity/policy-hook.mjs +78 -0
- package/neural-interface/lib/antigravity/policy.js +74 -0
- package/neural-interface/lib/antigravity/tool-call.js +178 -0
- package/neural-interface/lib/antigravity/transcripts.js +252 -0
- package/neural-interface/lib/antigravity/usage.js +43 -0
- package/neural-interface/lib/assistant-api.js +128 -28
- package/neural-interface/lib/assistant-brains/antigravity.js +423 -0
- package/neural-interface/lib/assistant-brains/claude.js +4 -3
- package/neural-interface/lib/assistant-brains/codex-browser-policy-hook.mjs +12 -2
- package/neural-interface/lib/assistant-brains/codex-route-gate-hook.mjs +32 -9
- package/neural-interface/lib/assistant-brains/codex.js +9 -5
- package/neural-interface/lib/assistant-brains/opencode.js +120 -54
- package/neural-interface/lib/assistant-brains/opencode2-browser-policy/index.js +28 -13
- package/neural-interface/lib/assistant-brains/opencode2-route-gate/index.js +59 -19
- package/neural-interface/lib/assistant-budget-planner.js +7 -3
- package/neural-interface/lib/assistant-budget-split.js +42 -15
- package/neural-interface/lib/assistant-catalog.js +81 -15
- package/neural-interface/lib/assistant-config.js +6 -3
- package/neural-interface/lib/assistant-dispatch.js +1073 -200
- package/neural-interface/lib/assistant-envelope.js +156 -2
- package/neural-interface/lib/assistant-evidence.js +80 -0
- package/neural-interface/lib/assistant-hidden-models.js +7 -5
- package/neural-interface/lib/assistant-persona.js +93 -19
- package/neural-interface/lib/assistant-plan-permissions.js +25 -9
- package/neural-interface/lib/assistant-route-gate-codex.js +3 -0
- package/neural-interface/lib/assistant-route-gate.js +6 -4
- package/neural-interface/lib/assistant-router.js +245 -38
- package/neural-interface/lib/assistant-runtime.js +214 -30
- package/neural-interface/lib/assistant-task-prompt.js +87 -21
- package/neural-interface/lib/assistant-tools.js +51 -0
- package/neural-interface/lib/assistant-usage.js +29 -0
- package/neural-interface/lib/backup-service.js +626 -4
- package/neural-interface/lib/backup-zip-reader.js +10 -5
- package/neural-interface/lib/backup-zip-writer.js +257 -0
- package/neural-interface/lib/browser-execution.js +10 -2
- package/neural-interface/lib/browser-guard-cdp.js +84 -0
- package/neural-interface/lib/browser-network-guard.js +476 -0
- package/neural-interface/lib/browser-policy-roots.js +64 -0
- package/neural-interface/lib/browser-tool-policy.js +198 -38
- package/neural-interface/lib/claude-agent-bridge.js +11 -2
- package/neural-interface/lib/claude-history-cache.js +210 -0
- package/neural-interface/lib/claude-hooks-status.js +103 -0
- package/neural-interface/lib/claude-model-catalog.js +5 -1
- package/neural-interface/lib/claude-temporary.js +5 -11
- package/neural-interface/lib/cli-install-api.js +1 -1
- package/neural-interface/lib/cli-install.js +163 -154
- package/neural-interface/lib/cli-resolver.js +13 -3
- package/neural-interface/lib/cli-update-planner.js +52 -41
- package/neural-interface/lib/cloudflared/tunnel.js +42 -2
- package/neural-interface/lib/codex-mcp-approvals.js +11 -0
- package/neural-interface/lib/codex-rollout-reader.js +52 -0
- package/neural-interface/lib/codex-worker-app-server.js +191 -0
- package/neural-interface/lib/confined-fs.js +30 -3
- package/neural-interface/lib/crash-notice-api.js +98 -0
- package/neural-interface/lib/editor-completion-opencode.js +68 -68
- package/neural-interface/lib/editor-git-api.js +3 -20
- package/neural-interface/lib/exec-loop-command.js +13 -10
- package/neural-interface/lib/file-explorer-api.js +74 -40
- package/neural-interface/lib/file-explorer-watch.js +9 -3
- package/neural-interface/lib/git-bash/install.js +52 -6
- package/neural-interface/lib/git-bash/manager.js +59 -17
- package/neural-interface/lib/git-bash/pins.js +12 -0
- package/neural-interface/lib/git-read.js +2 -2
- package/neural-interface/lib/git-status-runner.js +390 -0
- package/neural-interface/lib/git-status-watchdog.js +40 -0
- package/neural-interface/lib/greeting/budgets.js +1 -0
- package/neural-interface/lib/greeting/engine.js +2 -2
- package/neural-interface/lib/greeting/sources.js +10 -12
- package/neural-interface/lib/greeting/writer.js +1 -1
- package/neural-interface/lib/http-guards.js +8 -2
- package/neural-interface/lib/install-details.js +4 -1
- package/neural-interface/lib/mcp-agent-servers.js +67 -0
- package/neural-interface/lib/mcp-client-config.js +35 -33
- package/neural-interface/lib/mcp-external-servers.js +332 -0
- package/neural-interface/lib/mcp-installer.js +2 -1
- package/neural-interface/lib/{mcp-profile-refresh-coordinator.js → mcp-tools-refresh-coordinator.js} +4 -4
- package/neural-interface/lib/memory-session-capture.js +17 -3
- package/neural-interface/lib/morelogin.js +177 -25
- package/neural-interface/lib/native-loop-providers.js +965 -66
- package/neural-interface/lib/native-loop-runtime.js +290 -42
- package/neural-interface/lib/opencode-config.js +557 -0
- package/neural-interface/lib/opencode-db-schema.js +17 -34
- package/neural-interface/lib/opencode-history.js +48 -218
- package/neural-interface/lib/opencode-mcp-ready.js +108 -0
- package/neural-interface/lib/opencode-native-boundary.js +53 -0
- package/neural-interface/lib/opencode-protocol.js +249 -112
- package/neural-interface/lib/opencode-runtime-config.js +32 -22
- package/neural-interface/lib/opencode-serve-records.js +39 -21
- package/neural-interface/lib/opencode-v2-client.js +48 -153
- package/neural-interface/lib/opencode-v2-ws-requests.js +36 -210
- package/neural-interface/lib/opencode-worker-data.js +27 -0
- package/neural-interface/lib/opencode2-client.js +73 -37
- package/neural-interface/lib/opencode2-proxy.js +23 -63
- package/neural-interface/lib/opencode2-translate.js +51 -2
- package/neural-interface/lib/owner-authority.js +249 -0
- package/neural-interface/lib/page-session.js +275 -0
- package/neural-interface/lib/path-confine.js +12 -9
- package/neural-interface/lib/peer-identity.js +793 -0
- package/neural-interface/lib/pty-host/core.js +28 -1
- package/neural-interface/lib/pty-host/lifetime.js +12 -0
- package/neural-interface/lib/pty-host/manager.js +12 -1
- package/neural-interface/lib/remote-policy.js +1 -1
- package/neural-interface/lib/request-gate.js +20 -2
- package/neural-interface/lib/rulesets/api.js +7 -6
- package/neural-interface/lib/rulesets/fs-safe.js +1 -1
- package/neural-interface/lib/rulesets/installer.js +180 -36
- package/neural-interface/lib/rulesets/json-edit.js +1 -1
- package/neural-interface/lib/rulesets/render.js +1 -1
- package/neural-interface/lib/session-cache-builder.js +81 -31
- package/neural-interface/lib/session-title-generator.js +58 -36
- package/neural-interface/lib/skills/api-v2.js +495 -0
- package/neural-interface/lib/skills/bundle.js +418 -0
- package/neural-interface/lib/skills/catalog.js +298 -0
- package/neural-interface/lib/skills/creation-api.js +191 -0
- package/neural-interface/lib/skills/creation-brief.js +247 -0
- package/neural-interface/lib/skills/creation-sources.js +285 -0
- package/neural-interface/lib/skills/creation.js +843 -0
- package/neural-interface/lib/skills/deploy.js +569 -0
- package/neural-interface/lib/skills/digest.js +119 -0
- package/neural-interface/lib/skills/discover.js +111 -0
- package/neural-interface/lib/skills/draft-confinement.js +216 -0
- package/neural-interface/lib/skills/eval-confinement.js +399 -0
- package/neural-interface/lib/skills/eval-sandbox.js +280 -0
- package/neural-interface/lib/skills/eval-trace.js +135 -0
- package/neural-interface/lib/skills/evals-api.js +212 -0
- package/neural-interface/lib/skills/evals.js +1573 -0
- package/neural-interface/lib/skills/export.js +203 -0
- package/neural-interface/lib/skills/frontmatter.js +64 -0
- package/neural-interface/lib/skills/health.js +75 -0
- package/neural-interface/lib/skills/json-edit.js +165 -0
- package/neural-interface/lib/skills/known-bridge-digests.json +441 -0
- package/neural-interface/lib/skills/known-bridges.js +96 -0
- package/neural-interface/lib/skills/library.js +823 -0
- package/neural-interface/lib/skills/local-store.js +21 -0
- package/neural-interface/lib/skills/migration.js +433 -0
- package/neural-interface/lib/skills/operations.js +45 -0
- package/neural-interface/lib/skills/ownership.js +427 -0
- package/neural-interface/lib/skills/packages.js +88 -0
- package/neural-interface/lib/skills/reviews.js +212 -0
- package/neural-interface/lib/skills/revision.js +80 -0
- package/neural-interface/lib/skills/roots.js +269 -0
- package/neural-interface/lib/skills/runtime-checks.js +358 -0
- package/neural-interface/lib/skills/scan-assets.js +252 -0
- package/neural-interface/lib/skills/scan-context.js +26 -0
- package/neural-interface/lib/skills/scan-shell.js +324 -0
- package/neural-interface/lib/skills/scan.js +364 -0
- package/neural-interface/lib/skills/scanners.js +54 -0
- package/neural-interface/lib/skills/service.js +530 -0
- package/neural-interface/lib/skills/telemetry.js +119 -0
- package/neural-interface/lib/sqlite-integrity-worker.js +22 -0
- package/neural-interface/lib/synabun-version.js +1 -1
- package/neural-interface/lib/system-activity.js +1 -1
- package/neural-interface/lib/tool-lists.js +124 -0
- package/neural-interface/lib/whatsapp/brain.js +7 -3
- package/neural-interface/lib/whatsapp/bridge.js +6 -3
- package/neural-interface/lib/whatsapp/cards.js +22 -9
- package/neural-interface/lib/whatsapp/config.js +1 -1
- package/neural-interface/lib/worker-confinement.js +1268 -0
- package/neural-interface/lib/worker-guard-setting.js +56 -0
- package/neural-interface/lib/worker-mcp-channel.js +175 -0
- package/neural-interface/lib/worker-question.js +74 -0
- package/neural-interface/lib/worker-relay-ports.js +227 -0
- package/neural-interface/lib/worker-resume.js +238 -0
- package/neural-interface/lib/worker-sandbox.js +329 -0
- package/neural-interface/package-lock.json +34 -12
- package/neural-interface/package.json +3 -2
- package/neural-interface/public/index.html +3 -1
- package/neural-interface/public/index2d.html +19 -11
- package/neural-interface/public/onboarding.html +3 -3
- package/neural-interface/public/shared/account-menu.js +8 -5
- package/neural-interface/public/shared/agent-runtime-options.js +125 -31
- package/neural-interface/public/shared/agy/agy-bypass.js +47 -0
- package/neural-interface/public/shared/agy/agy-client.js +266 -0
- package/neural-interface/public/shared/agy/agy-commands.js +120 -0
- package/neural-interface/public/shared/agy/agy-copy.js +326 -0
- package/neural-interface/public/shared/agy/agy-diff.js +161 -0
- package/neural-interface/public/shared/agy/agy-events.js +469 -0
- package/neural-interface/public/shared/agy/agy-greeting.js +26 -0
- package/neural-interface/public/shared/agy/agy-options.js +232 -0
- package/neural-interface/public/shared/agy/agy-panel.js +2543 -0
- package/neural-interface/public/shared/agy/agy-render.js +392 -0
- package/neural-interface/public/shared/agy/agy-setup.js +149 -0
- package/neural-interface/public/shared/agy/agy-styles.js +604 -0
- package/neural-interface/public/shared/agy/agy-tabs-logic.js +181 -0
- package/neural-interface/public/shared/api.js +1527 -1336
- package/neural-interface/public/shared/app-frame.js +192 -0
- package/neural-interface/public/shared/assistant/asst-agents-dock.js +36 -6
- package/neural-interface/public/shared/assistant/asst-api.js +1 -1
- package/neural-interface/public/shared/assistant/asst-ask-styles.js +270 -0
- package/neural-interface/public/shared/assistant/asst-ask-tail.js +118 -0
- package/neural-interface/public/shared/assistant/asst-ask.js +397 -0
- package/neural-interface/public/shared/assistant/asst-brain-picker.js +105 -44
- package/neural-interface/public/shared/assistant/asst-budget.js +5 -4
- package/neural-interface/public/shared/assistant/asst-control.js +205 -26
- package/neural-interface/public/shared/assistant/asst-followups-card.js +383 -0
- package/neural-interface/public/shared/assistant/asst-followups.js +417 -0
- package/neural-interface/public/shared/assistant/asst-hosts.js +16 -7
- package/neural-interface/public/shared/assistant/asst-limit-dock.js +45 -0
- package/neural-interface/public/shared/assistant/asst-limit-wait.js +327 -0
- package/neural-interface/public/shared/assistant/asst-limit.js +168 -0
- package/neural-interface/public/shared/assistant/asst-mascot.js +49 -12
- package/neural-interface/public/shared/assistant/asst-menu.js +7 -6
- package/neural-interface/public/shared/assistant/asst-panel.js +151 -19
- package/neural-interface/public/shared/assistant/asst-rack-styles.js +66 -49
- package/neural-interface/public/shared/assistant/asst-render.js +445 -82
- package/neural-interface/public/shared/assistant/asst-route.js +304 -53
- package/neural-interface/public/shared/assistant/asst-routes-editor.js +9 -8
- package/neural-interface/public/shared/assistant/asst-scenes.js +56 -1
- package/neural-interface/public/shared/assistant/asst-sidepanel.js +117 -10
- package/neural-interface/public/shared/assistant/asst-slash.js +17 -9
- package/neural-interface/public/shared/assistant/asst-state.js +87 -24
- package/neural-interface/public/shared/assistant/asst-stop.js +127 -0
- package/neural-interface/public/shared/assistant/asst-styles.js +93 -21
- package/neural-interface/public/shared/assistant/asst-tool-kinds.js +190 -23
- package/neural-interface/public/shared/assistant/asst-usage.js +2 -1
- package/neural-interface/public/shared/automation-context.js +5 -2
- package/neural-interface/public/shared/cc-dropdown.js +89 -19
- package/neural-interface/public/shared/cdx/cdx-context-menu.js +10 -9
- package/neural-interface/public/shared/cdx/cdx-copy.js +16 -0
- package/neural-interface/public/shared/cdx/cdx-output-model.js +22 -1
- package/neural-interface/public/shared/cdx/cdx-output.js +34 -10
- package/neural-interface/public/shared/cdx/cdx-panel.js +59 -151
- package/neural-interface/public/shared/cdx/cdx-preview.js +12 -0
- package/neural-interface/public/shared/cdx/cdx-protocol.js +39 -11
- package/neural-interface/public/shared/cdx/cdx-render.js +57 -38
- package/neural-interface/public/shared/cdx/cdx-requests.js +14 -4
- package/neural-interface/public/shared/cdx/cdx-skill-hints.js +54 -0
- package/neural-interface/public/shared/cdx/cdx-styles.js +15 -3
- package/neural-interface/public/shared/cdx/cdx-tabs.js +127 -44
- package/neural-interface/public/shared/cdx/cdx-ws.js +0 -1
- package/neural-interface/public/shared/cli-install-controller.js +218 -0
- package/neural-interface/public/shared/cli-install-view.js +11 -12
- package/neural-interface/public/shared/cli-status.js +11 -10
- package/neural-interface/public/shared/constants.js +5 -4
- package/neural-interface/public/shared/context-menu-areas.js +34 -0
- package/neural-interface/public/shared/context-menu-logic.js +243 -0
- package/neural-interface/public/shared/context-menu-model.js +367 -0
- package/neural-interface/public/shared/context-menu.js +372 -0
- package/neural-interface/public/shared/cp/cp-context-menu.js +10 -9
- package/neural-interface/public/shared/cp/cp-restore.js +162 -0
- package/neural-interface/public/shared/cp/cp-tool-cards.js +10 -3
- package/neural-interface/public/shared/crash-notice-view.js +168 -0
- package/neural-interface/public/shared/desktop-bridge.js +17 -0
- package/neural-interface/public/shared/desktop-titlebar-view.js +12 -0
- package/neural-interface/public/shared/desktop-titlebar.js +13 -4
- package/neural-interface/public/shared/desktop-update-view.js +21 -0
- package/neural-interface/public/shared/editor/editor-panel-logic.js +2 -2
- package/neural-interface/public/shared/explorer/fx-api.js +4 -4
- package/neural-interface/public/shared/explorer/fx-links.js +3 -3
- package/neural-interface/public/shared/explorer/fx-logic.js +1 -1
- package/neural-interface/public/shared/explorer/fx-main.js +48 -16
- package/neural-interface/public/shared/explorer/fx-tree.js +1 -0
- package/neural-interface/public/shared/greeting/greeting-card.js +2 -2
- package/neural-interface/public/shared/greeting/greeting-view.js +1 -0
- package/neural-interface/public/shared/html-shell.js +30 -15
- package/neural-interface/public/shared/i18n.js +2 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-approvals.js +7 -7
- package/neural-interface/public/shared/ocp-v2/ocp-v2-binding.js +4 -4
- package/neural-interface/public/shared/ocp-v2/ocp-v2-changes-logic.js +3 -101
- package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +2 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-compact-button.js +1 -3
- package/neural-interface/public/shared/ocp-v2/ocp-v2-composer-logic.js +2 -6
- package/neural-interface/public/shared/ocp-v2/ocp-v2-context-menu.js +11 -11
- package/neural-interface/public/shared/ocp-v2/ocp-v2-context-model.js +0 -3
- package/neural-interface/public/shared/ocp-v2/ocp-v2-events.js +8 -4
- package/neural-interface/public/shared/ocp-v2/ocp-v2-manager.js +7 -7
- package/neural-interface/public/shared/ocp-v2/ocp-v2-outcome-notifications.js +16 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +74 -259
- package/neural-interface/public/shared/ocp-v2/ocp-v2-plan.js +1 -2
- package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +95 -202
- package/neural-interface/public/shared/ocp-v2/ocp-v2-rehydrate.js +13 -4
- package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +13 -22
- package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +4 -4
- package/neural-interface/public/shared/ocp-v2/ocp-v2-session-actions.js +8 -61
- package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +2 -91
- package/neural-interface/public/shared/ocp-v2/ocp-v2-slash-hints.js +16 -15
- package/neural-interface/public/shared/ocp-v2/ocp-v2-state.js +8 -21
- package/neural-interface/public/shared/ocp-v2/ocp-v2-status-logic.js +1 -99
- package/neural-interface/public/shared/ocp-v2/ocp-v2-status.js +5 -35
- package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +17 -21
- package/neural-interface/public/shared/ocp-v2/{ocp-v2-profile-inheritance.js → ocp-v2-tools-inheritance.js} +16 -16
- package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +60 -50
- package/neural-interface/public/shared/page-session.js +96 -0
- package/neural-interface/public/shared/provider-icons.js +4 -2
- package/neural-interface/public/shared/registry.js +5 -3
- package/neural-interface/public/shared/retired-2d.js +3 -0
- package/neural-interface/public/shared/schedules-view.js +195 -61
- package/neural-interface/public/shared/settings/settings-claude-hooks.js +135 -0
- package/neural-interface/public/shared/settings/settings-data.js +3 -1
- package/neural-interface/public/shared/settings/settings-ia.js +6 -6
- package/neural-interface/public/shared/settings/settings-opencode.js +89 -0
- package/neural-interface/public/shared/settings/settings-rules.js +2 -2
- package/neural-interface/public/shared/settings/settings-skill-folders-pane.js +265 -0
- package/neural-interface/public/shared/settings/settings-skill-folders.js +130 -0
- package/neural-interface/public/shared/settings/settings-worker-guard.js +72 -0
- package/neural-interface/public/shared/showcase-privacy.js +6 -1
- package/neural-interface/public/shared/sidepanel-session-status.js +3 -3
- package/neural-interface/public/shared/skills/ss-args.js +96 -0
- package/neural-interface/public/shared/skills/ss-creation.js +222 -0
- package/neural-interface/public/shared/skills/ss-dialog.js +133 -0
- package/neural-interface/public/shared/skills/ss-doc.js +173 -0
- package/neural-interface/public/shared/skills/ss-eval-adapters.js +269 -0
- package/neural-interface/public/shared/skills/ss-eval-grade.js +359 -0
- package/neural-interface/public/shared/skills/ss-eval-optimise.js +153 -0
- package/neural-interface/public/shared/skills/ss-eval-plan.js +315 -0
- package/neural-interface/public/shared/skills/ss-evals.js +417 -0
- package/neural-interface/public/shared/skills/ss-form.js +159 -0
- package/neural-interface/public/shared/skills/ss-frontmatter.js +376 -0
- package/neural-interface/public/shared/skills/ss-ids.js +32 -0
- package/neural-interface/public/shared/skills/ss-lint.js +149 -0
- package/neural-interface/public/shared/skills/ss-presets.js +117 -0
- package/neural-interface/public/shared/skills/ss-profiles.js +513 -0
- package/neural-interface/public/shared/skills/ss-resources.js +165 -0
- package/neural-interface/public/shared/skills/ss-review-view.js +190 -0
- package/neural-interface/public/shared/skills/ss-tabs.js +79 -0
- package/neural-interface/public/shared/skills/ss-unicode.js +135 -0
- package/neural-interface/public/shared/skills/studio/sx-actions.js +222 -0
- package/neural-interface/public/shared/skills/studio/sx-cm.js +101 -0
- package/neural-interface/public/shared/skills/studio/sx-create-ai-view.js +749 -0
- package/neural-interface/public/shared/skills/studio/sx-create-ai.js +237 -0
- package/neural-interface/public/shared/skills/studio/sx-create-view.js +254 -0
- package/neural-interface/public/shared/skills/studio/sx-create.js +126 -0
- package/neural-interface/public/shared/skills/studio/sx-diff-view.js +43 -0
- package/neural-interface/public/shared/skills/studio/sx-diff.js +133 -0
- package/neural-interface/public/shared/skills/studio/sx-docs.js +480 -0
- package/neural-interface/public/shared/skills/studio/sx-dom.js +230 -0
- package/neural-interface/public/shared/skills/studio/sx-edit-view.js +848 -0
- package/neural-interface/public/shared/skills/studio/sx-editor-model.js +193 -0
- package/neural-interface/public/shared/skills/studio/sx-errors.js +22 -0
- package/neural-interface/public/shared/skills/studio/sx-fixes-view.js +359 -0
- package/neural-interface/public/shared/skills/studio/sx-fixes.js +327 -0
- package/neural-interface/public/shared/skills/studio/sx-geometry.js +82 -0
- package/neural-interface/public/shared/skills/studio/sx-import.js +262 -0
- package/neural-interface/public/shared/skills/studio/sx-inspector.js +308 -0
- package/neural-interface/public/shared/skills/studio/sx-install-flow.js +282 -0
- package/neural-interface/public/shared/skills/studio/sx-install.js +313 -0
- package/neural-interface/public/shared/skills/studio/sx-library-view.js +748 -0
- package/neural-interface/public/shared/skills/studio/sx-library.js +479 -0
- package/neural-interface/public/shared/skills/studio/sx-main.js +690 -0
- package/neural-interface/public/shared/skills/studio/sx-operations-view.js +98 -0
- package/neural-interface/public/shared/skills/studio/sx-operations.js +11 -0
- package/neural-interface/public/shared/skills/studio/sx-plan.js +158 -0
- package/neural-interface/public/shared/skills/studio/sx-publish-view.js +621 -0
- package/neural-interface/public/shared/skills/studio/sx-review-view.js +369 -0
- package/neural-interface/public/shared/skills/studio/sx-review.js +148 -0
- package/neural-interface/public/shared/skills/studio/sx-scan.js +35 -0
- package/neural-interface/public/shared/skills/studio/sx-snippets.js +96 -0
- package/neural-interface/public/shared/skills/studio/sx-subject.js +249 -0
- package/neural-interface/public/shared/skills/studio/sx-test-view.js +994 -0
- package/neural-interface/public/shared/skills/studio/sx-test.js +328 -0
- package/neural-interface/public/shared/skills/studio/sx-versions-view.js +241 -0
- package/neural-interface/public/shared/skills/studio/sx-workspace-view.js +426 -0
- package/neural-interface/public/shared/state.js +1 -1
- package/neural-interface/public/shared/streaming-markdown.js +58 -0
- package/neural-interface/public/shared/styleguide/sg-panel.js +4 -2
- package/neural-interface/public/shared/styles.css +1822 -1756
- package/neural-interface/public/shared/synabun-mascot.js +1115 -9
- package/neural-interface/public/shared/text-cache.js +29 -0
- package/neural-interface/public/shared/tool-list-picker.js +55 -0
- package/neural-interface/public/shared/tool-list-storage.js +24 -0
- package/neural-interface/public/shared/tool-list-view.js +112 -0
- package/neural-interface/public/shared/topright-overflow-logic.js +54 -0
- package/neural-interface/public/shared/tour/tour-actor.js +268 -0
- package/neural-interface/public/shared/tour/tour-beats.js +336 -0
- package/neural-interface/public/shared/tour/tour-engine.js +884 -0
- package/neural-interface/public/shared/tour/tour-ink.js +390 -0
- package/neural-interface/public/shared/tour/tour-stage.js +440 -0
- package/neural-interface/public/shared/tour/tour-state.js +40 -0
- package/neural-interface/public/shared/tour/tour-tips.js +99 -0
- package/neural-interface/public/shared/tour/tour.css +144 -0
- package/neural-interface/public/shared/ui-antigravity-panel.js +19 -0
- package/neural-interface/public/shared/ui-assistant.js +2 -0
- package/neural-interface/public/shared/ui-automation-studio.js +111 -140
- package/neural-interface/public/shared/ui-claude-panel.js +376 -82
- package/neural-interface/public/shared/ui-cli-banner.js +23 -167
- package/neural-interface/public/shared/ui-command-runner.js +6 -3
- package/neural-interface/public/shared/ui-context-menu.js +295 -0
- package/neural-interface/public/shared/ui-cost-widget.js +57 -59
- package/neural-interface/public/shared/ui-crash-notice.js +187 -0
- package/neural-interface/public/shared/ui-detail.js +15 -3
- package/neural-interface/public/shared/ui-file-explorer.js +48 -6
- package/neural-interface/public/shared/ui-file-links.js +2 -2
- package/neural-interface/public/shared/ui-games.js +2 -2
- package/neural-interface/public/shared/ui-image-gallery.js +50 -47
- package/neural-interface/public/shared/ui-judgments.js +1 -1
- package/neural-interface/public/shared/ui-keybinds.js +33 -2
- package/neural-interface/public/shared/ui-link.js +3 -3
- package/neural-interface/public/shared/ui-menubar.js +10 -20
- package/neural-interface/public/shared/ui-native-loop-router-state.js +5 -0
- package/neural-interface/public/shared/ui-native-loop-router.js +11 -1
- package/neural-interface/public/shared/ui-navbar.js +49 -24
- package/neural-interface/public/shared/ui-notifications.js +1 -0
- package/neural-interface/public/shared/ui-panels.js +96 -65
- package/neural-interface/public/shared/ui-resume.js +9 -7
- package/neural-interface/public/shared/ui-schedules-studio.js +546 -431
- package/neural-interface/public/shared/ui-scroll-follow.js +16 -5
- package/neural-interface/public/shared/ui-sessions.js +27 -15
- package/neural-interface/public/shared/ui-settings.js +683 -526
- package/neural-interface/public/shared/ui-sidepanel-session-entry.js +9 -2
- package/neural-interface/public/shared/ui-sidepanel-sessions.js +4 -4
- package/neural-interface/public/shared/ui-sidepanel-state.js +23 -12
- package/neural-interface/public/shared/ui-sidepanel-tray.js +48 -7
- package/neural-interface/public/shared/ui-sidepanel-windows.js +18 -13
- package/neural-interface/public/shared/ui-skills.js +33 -2830
- package/neural-interface/public/shared/ui-styleguide.js +5 -2
- package/neural-interface/public/shared/ui-sync.js +15 -5
- package/neural-interface/public/shared/ui-terminal.js +270 -190
- package/neural-interface/public/shared/ui-tool-updates.js +6 -4
- package/neural-interface/public/shared/ui-tooltip.js +81 -51
- package/neural-interface/public/shared/ui-topright-overflow.js +233 -0
- package/neural-interface/public/shared/ui-trash.js +6 -4
- package/neural-interface/public/shared/ui-tutorial-layout.js +3 -117
- package/neural-interface/public/shared/ui-tutorial-preview.js +103 -0
- package/neural-interface/public/shared/ui-tutorial-steps.js +3 -65
- package/neural-interface/public/shared/ui-tutorial.css +47 -100
- package/neural-interface/public/shared/ui-tutorial.js +285 -509
- package/neural-interface/public/shared/ui-update.js +38 -2
- package/neural-interface/public/shared/ui-whiteboard.js +312 -59
- package/neural-interface/public/shared/ui-worker-end.js +5 -1
- package/neural-interface/public/shared/ui-workspaces.js +3 -2
- package/neural-interface/public/shared/view-variant.js +66 -0
- package/neural-interface/public/shared/whatsapp/wa-view.js +3 -3
- package/neural-interface/public/shared/whiteboard-list.js +172 -0
- package/neural-interface/public/shared/worker-end.js +10 -3
- package/neural-interface/public/shared/worker-questions.js +34 -0
- package/neural-interface/public/shared/worker-restart.js +12 -0
- package/neural-interface/public/sidepanel-session.html +2 -2
- package/neural-interface/public/variant/2d/background.js +2 -1
- package/neural-interface/public/variant/2d/context-menu.js +8 -2
- package/neural-interface/public/variant/2d/graph.js +42 -20
- package/neural-interface/public/variant/2d/hulls.js +14 -9
- package/neural-interface/public/variant/2d/lasso.js +11 -7
- package/neural-interface/public/variant/2d/main.js +32 -1
- package/neural-interface/public/variant/2d/minimap.js +11 -13
- package/neural-interface/public/variant/3d/main.js +69 -6
- package/neural-interface/public/variant/3d/map-controls.js +24 -9
- package/neural-interface/public/vendor/caveat/OFL.txt +93 -0
- package/neural-interface/public/vendor/caveat/caveat-latin-400-normal.woff2 +0 -0
- package/neural-interface/public/vendor/caveat/caveat-latin-700-normal.woff2 +0 -0
- package/neural-interface/public/vendor/caveat/caveat.css +17 -0
- package/neural-interface/public/vendor/caveat/manifest.json +12 -0
- package/neural-interface/public/vendor/yaml/LICENSE +13 -0
- package/neural-interface/public/vendor/yaml/manifest.json +4 -0
- package/neural-interface/public/vendor/yaml/yaml-2.9.1.min.js +137 -0
- package/neural-interface/scripts/build-vendor.mjs +32 -0
- package/neural-interface/server.js +4553 -2855
- package/neural-interface/templates/rulesets/README.md +1 -1
- package/neural-interface/templates/rulesets/core.md +1 -1
- package/neural-interface/templates/rulesets/legacy-hashes.json +23 -5
- package/neural-interface/templates/rulesets/manifest.json +8 -8
- package/npm-shrinkwrap.json +34 -12
- package/package.json +17 -3
- package/postinstall.js +9 -4
- package/preuninstall.js +1 -1
- package/setup.js +97 -322
- package/skills/skill-forge/SKILL.md +177 -0
- package/skills/skill-forge/evals/evals.json +54 -0
- package/skills/skill-forge/references/package.md +105 -0
- package/skills/skill-forge/references/review-and-recovery.md +63 -0
- package/skills/skill-forge/references/runtime-profiles.md +20 -0
- package/skills/skill-forge/references/sources-and-capabilities.md +51 -0
- package/skills/synabun/SKILL.md +10 -7
- package/skills/synabun/modules/audit.md +1 -5
- package/skills/synabun/modules/changelog.md +1 -5
- package/skills/synabun/modules/idea.md +1 -1
- package/skills/synabun/modules/memorize.md +6 -9
- package/skills/synabun/modules/schedule.md +6 -6
- package/mcp-server/dist/services/profiles.d.ts +0 -120
- package/mcp-server/dist/services/profiles.d.ts.map +0 -1
- package/mcp-server/dist/services/profiles.js +0 -387
- package/mcp-server/dist/services/profiles.js.map +0 -1
- package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +0 -97
- package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +0 -1
- package/mcp-server/dist/tools/leonardo-browser-tools.js +0 -228
- package/mcp-server/dist/tools/leonardo-browser-tools.js.map +0 -1
- package/mcp-server/dist/tools/leonardo.d.ts +0 -13
- package/mcp-server/dist/tools/leonardo.d.ts.map +0 -1
- package/mcp-server/dist/tools/leonardo.js +0 -21
- package/mcp-server/dist/tools/leonardo.js.map +0 -1
- package/mcp-server/dist/tools/profile.d.ts +0 -17
- package/mcp-server/dist/tools/profile.d.ts.map +0 -1
- package/mcp-server/dist/tools/profile.js +0 -114
- package/mcp-server/dist/tools/profile.js.map +0 -1
- package/mcp-server/src/services/profiles.ts +0 -428
- package/mcp-server/src/tools/leonardo-browser-tools.ts +0 -291
- package/mcp-server/src/tools/leonardo.ts +0 -30
- package/mcp-server/src/tools/profile.ts +0 -122
- package/neural-interface/lib/assistant-brains/opencode-browser-policy.js +0 -47
- package/neural-interface/lib/assistant-brains/opencode-route-gate.js +0 -62
- package/neural-interface/lib/mcp-profile-servers.js +0 -120
- package/neural-interface/public/shared/ui-tutorial-draw.js +0 -311
- package/skills/leonardo/SKILL.md +0 -168
- package/skills/leonardo/icon.svg +0 -1
- package/skills/leonardo/modules/browser-guide.md +0 -378
- package/skills/leonardo/modules/image-prompter.md +0 -283
- package/skills/leonardo/modules/model-advisor.md +0 -100
- package/skills/leonardo/modules/prompt-library.md +0 -110
- package/skills/leonardo/modules/style-guide.md +0 -186
- package/skills/leonardo/modules/video-prompter.md +0 -317
- /package/neural-interface/templates/rulesets/{gemini.md → antigravity.md} +0 -0
|
@@ -1,78 +1,210 @@
|
|
|
1
1
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
2
2
|
// Which OpenCode SynaBun talks to, and how to know it is really there.
|
|
3
3
|
//
|
|
4
|
-
// OpenCode
|
|
5
|
-
// `opencode
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
// only when
|
|
4
|
+
// SynaBun drives OpenCode 2 and nothing else (OpenCode 1 support was removed
|
|
5
|
+
// on 2026-10-24). OpenCode 2 (`opencode --version` → "opencode v2.1.4") serves
|
|
6
|
+
// its API under /api/*, behind HTTP Basic auth (user `opencode`) with a
|
|
7
|
+
// password set per launch. Production serves generate it privately on stdout
|
|
8
|
+
// (serveSpecFor passwordFrom 'stdout'); an environment password would remain
|
|
9
|
+
// readable in the process and its shell's programs. The low-level 'env' mode
|
|
10
|
+
// remains for explicit callers/fixtures. Every other path is its web app, an HTML page with
|
|
11
|
+
// status 200. SynaBun reads the version of the binary it is about to start
|
|
12
|
+
// (the CLI resolver's cached `--version`, keyed by the file, so an upgrade in
|
|
13
|
+
// place is read again), refuses an OpenCode it does not drive with one
|
|
14
|
+
// sentence that says what was found and how to get OpenCode 2, and calls a
|
|
15
|
+
// serve healthy only when OpenCode 2's API answers JSON: an HTML page never
|
|
16
|
+
// passes.
|
|
17
|
+
//
|
|
18
|
+
// OPENCODE_MIN_VERSION is the oldest OpenCode 2 SynaBun's OpenCode layer was
|
|
19
|
+
// built and checked against (the recorded events of tests/fixtures/
|
|
20
|
+
// opencode2-events.json, the plugin hook of the route gate and the browser
|
|
21
|
+
// policy, the live smoke test). npm's `opencode-ai` package is still OpenCode
|
|
22
|
+
// 1; OpenCode 2 comes from its own installer (https://opencode.ai/v2/install),
|
|
23
|
+
// Homebrew (anomalyco/tap/opencode-v2) or WinGet (Anomaly.OpenCode).
|
|
16
24
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
17
25
|
|
|
18
26
|
import { randomBytes } from 'node:crypto';
|
|
27
|
+
import { request as httpRequest } from 'node:http';
|
|
19
28
|
|
|
20
|
-
|
|
21
|
-
export const
|
|
22
|
-
export const OPENCODE2_USERNAME = 'opencode';
|
|
29
|
+
export const OPENCODE_MIN_VERSION = '2.0.32';
|
|
30
|
+
export const OPENCODE_USERNAME = 'opencode';
|
|
23
31
|
|
|
24
|
-
/** "1.
|
|
25
|
-
export function
|
|
32
|
+
/** "2.1.4", "opencode v2.1.4", "v1.19.3" → { major, minor, patch }; null when no version can be read. */
|
|
33
|
+
export function opencodeVersionOf(version) {
|
|
26
34
|
const match = String(version ?? '').match(/(\d+)\.(\d+)\.(\d+)/);
|
|
27
35
|
if (!match) return null;
|
|
28
|
-
const major =
|
|
29
|
-
return Number.isFinite
|
|
36
|
+
const [major, minor, patch] = match.slice(1, 4).map(Number);
|
|
37
|
+
return [major, minor, patch].every(Number.isFinite) ? { major, minor, patch } : null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const MINIMUM = opencodeVersionOf(OPENCODE_MIN_VERSION);
|
|
41
|
+
|
|
42
|
+
function olderThanMinimum(v) {
|
|
43
|
+
if (v.major !== MINIMUM.major) return v.major < MINIMUM.major;
|
|
44
|
+
if (v.minor !== MINIMUM.minor) return v.minor < MINIMUM.minor;
|
|
45
|
+
return v.patch < MINIMUM.patch;
|
|
30
46
|
}
|
|
31
47
|
|
|
32
48
|
/**
|
|
33
|
-
* The
|
|
34
|
-
*
|
|
35
|
-
* speaks it; a major SynaBun does not know is refused with a sentence, never
|
|
36
|
-
* guessed at.
|
|
49
|
+
* The commands that install OpenCode 2 on a system, the first one first: OpenCode's own installer
|
|
50
|
+
* (https://opencode.ai/v2/install, the one `opencode upgrade` runs), its Homebrew tap, WinGet on Windows.
|
|
37
51
|
*/
|
|
38
|
-
export function
|
|
39
|
-
|
|
52
|
+
export function opencodeInstallCommands(platform = process.platform) {
|
|
53
|
+
if (platform === 'win32') return ['winget install --id Anomaly.OpenCode --exact'];
|
|
54
|
+
if (platform === 'darwin') return ['brew install anomalyco/tap/opencode-v2', 'curl -fsSL https://opencode.ai/v2/install | bash'];
|
|
55
|
+
return ['curl -fsSL https://opencode.ai/v2/install | bash'];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** How to get OpenCode 2 on a system, as words of a sentence ("run: …, or: …"). */
|
|
59
|
+
export function opencodeInstallRoute(platform = process.platform) {
|
|
60
|
+
return opencodeInstallCommands(platform).map((command, index) => `${index ? 'or: ' : 'run: '}${command}`).join(', ');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Whether SynaBun drives the OpenCode of a version string: `{ supported,
|
|
65
|
+
* version, major, reason, code }`. `reason` is the one sentence a person reads
|
|
66
|
+
* when it does not: what was found (`path`, when known) and how to get OpenCode
|
|
67
|
+
* 2; `code` says which case it is ('unreadable' | 'opencode1' | 'newer' |
|
|
68
|
+
* 'outdated'), for a page that words it in its own language.
|
|
69
|
+
*/
|
|
70
|
+
export function opencodeSupportFor(version, { path = null, platform = process.platform } = {}) {
|
|
40
71
|
const text = version ? String(version).trim() : '';
|
|
41
|
-
|
|
42
|
-
|
|
72
|
+
const parsed = opencodeVersionOf(text);
|
|
73
|
+
const where = path ? ` (${path})` : '';
|
|
74
|
+
// What every refusal but an outdated OpenCode 2's ends with: how to get OpenCode 2, or where to pick one.
|
|
75
|
+
const getOpencode2 = `install OpenCode 2 (${opencodeInstallRoute(platform)}), or choose an OpenCode 2 under Settings → Executable paths`;
|
|
76
|
+
if (!parsed) {
|
|
77
|
+
const found = text ? `SynaBun cannot read the OpenCode version "${text}"${where}` : `SynaBun could not read the version of the OpenCode it found${where}`;
|
|
78
|
+
return { supported: false, version: text || null, major: null, code: 'unreadable', reason: `${found}, and it needs OpenCode 2 (${OPENCODE_MIN_VERSION} or newer): ${getOpencode2}.` };
|
|
79
|
+
}
|
|
80
|
+
const { major } = parsed;
|
|
81
|
+
// The version as OpenCode prints it, without its name ("opencode v2.1.4" → "2.1.4", a prerelease kept whole).
|
|
82
|
+
const shown = text.replace(/^opencode\s+/i, '').replace(/^v(?=\d)/i, '') || `${parsed.major}.${parsed.minor}.${parsed.patch}`;
|
|
83
|
+
if (major <= 1) {
|
|
84
|
+
return { supported: false, version: text, major, code: 'opencode1', reason: `SynaBun works with OpenCode 2 only, and the OpenCode it found${where} is version ${shown}: install OpenCode 2 (${opencodeInstallRoute(platform)}; npm's opencode-ai package is still OpenCode 1), or choose an OpenCode 2 under Settings → Executable paths.` };
|
|
85
|
+
}
|
|
86
|
+
if (major >= 3) {
|
|
87
|
+
return { supported: false, version: text, major, code: 'newer', reason: `OpenCode ${shown}${where} is newer than SynaBun supports: SynaBun works with OpenCode 2 only, so ${getOpencode2}.` };
|
|
88
|
+
}
|
|
89
|
+
if (olderThanMinimum(parsed)) {
|
|
90
|
+
return { supported: false, version: text, major, code: 'outdated', reason: `SynaBun needs OpenCode ${OPENCODE_MIN_VERSION} or newer, and the OpenCode it found${where} is version ${shown}: update it (run: opencode upgrade).` };
|
|
43
91
|
}
|
|
44
|
-
|
|
45
|
-
if (major === 2) return { protocol: 2, major, version: text, supported: true, reason: null };
|
|
46
|
-
return { protocol: null, major, version: text, supported: false, reason: `OpenCode ${major} (${text}) is newer than SynaBun supports: SynaBun works with OpenCode 1 and OpenCode 2.` };
|
|
92
|
+
return { supported: true, version: text, major, code: null, reason: null };
|
|
47
93
|
}
|
|
48
94
|
|
|
49
|
-
/** A fresh password for one
|
|
95
|
+
/** A fresh password for one serve launch. */
|
|
50
96
|
export function newServePassword() {
|
|
51
97
|
return randomBytes(24).toString('base64url');
|
|
52
98
|
}
|
|
53
99
|
|
|
54
|
-
/** The Authorization header for
|
|
55
|
-
export function basicAuthHeader(password, username =
|
|
100
|
+
/** The Authorization header for a serve. */
|
|
101
|
+
export function basicAuthHeader(password, username = OPENCODE_USERNAME) {
|
|
56
102
|
return `Basic ${Buffer.from(`${username}:${password}`).toString('base64')}`;
|
|
57
103
|
}
|
|
58
104
|
|
|
105
|
+
/** The environment variables OpenCode 2 takes its serve password from (OPENCODE_PASSWORD first). */
|
|
106
|
+
export const SERVE_PASSWORD_ENV = Object.freeze(['OPENCODE_PASSWORD', 'OPENCODE_SERVER_PASSWORD']);
|
|
107
|
+
|
|
59
108
|
/**
|
|
60
|
-
* The arguments and environment of `opencode serve` on `port
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
* password SynaBun holds is the one the serve checks).
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
109
|
+
* The arguments and environment of `opencode serve` on `port`: its loopback
|
|
110
|
+
* host name and the launch's password. `passwordFrom`:
|
|
111
|
+
* 'env' (default) the password is OPENCODE_PASSWORD (any
|
|
112
|
+
* OPENCODE_SERVER_PASSWORD the environment carries is dropped, so
|
|
113
|
+
* the password SynaBun holds is the one the serve checks). OpenCode
|
|
114
|
+
* 2 keeps it in its own environment, so every program its shell
|
|
115
|
+
* starts inherits it, and a process of the same user can read it
|
|
116
|
+
* in the serve's start-up environment (ps eww).
|
|
117
|
+
* 'stdout' no password variable at all: OpenCode 2 makes one up and prints
|
|
118
|
+
* it once on its standard output ("server password <it>", after
|
|
119
|
+
* "server listening on …"), which SynaBun reads
|
|
120
|
+
* (servePasswordReader) and keeps out of its logs
|
|
121
|
+
* (redactServeOutput). The password is in no environment: not the
|
|
122
|
+
* serve's, not its shell's. `password` is null until it is read.
|
|
123
|
+
* A launch through a login shell removes both variables after the
|
|
124
|
+
* profile ran (`unset`, serveUnsetCommand), so a profile that
|
|
125
|
+
* exports one cannot put it back.
|
|
68
126
|
*/
|
|
69
|
-
export function serveSpecFor(
|
|
70
|
-
const args = ['serve', '--port', String(port)];
|
|
71
|
-
|
|
127
|
+
export function serveSpecFor(port, { env = process.env, password = null, passwordFrom = 'env' } = {}) {
|
|
128
|
+
const args = ['serve', '--port', String(port), '--hostname', '127.0.0.1'];
|
|
129
|
+
const next = { ...env };
|
|
130
|
+
for (const key of SERVE_PASSWORD_ENV) delete next[key];
|
|
131
|
+
if (passwordFrom === 'stdout') return { args, env: next, password: null, passwordFrom: 'stdout' };
|
|
72
132
|
const pass = password || newServePassword();
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
133
|
+
next.OPENCODE_PASSWORD = pass;
|
|
134
|
+
return { args, env: next, password: pass, passwordFrom: 'env' };
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** What a POSIX shell runs before `exec opencode serve` of a 'stdout' launch: the password variables gone. */
|
|
138
|
+
export function serveUnsetCommand() {
|
|
139
|
+
return `unset ${SERVE_PASSWORD_ENV.join(' ')}`;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const SERVE_PASSWORD_LINE = /(?:^|\n)server password (\S+)[ \t]*\r?\n/;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* A reader of a 'stdout' serve's output: feed it each chunk of standard output; it answers the password once its
|
|
146
|
+
* line is complete ("server password <it>" and a line end), else null. Chunks may split the line anywhere.
|
|
147
|
+
*/
|
|
148
|
+
export function servePasswordReader() {
|
|
149
|
+
let buffered = '';
|
|
150
|
+
let found = null;
|
|
151
|
+
return (chunk) => {
|
|
152
|
+
if (found) return found;
|
|
153
|
+
buffered = `${buffered}${String(chunk ?? '')}`.slice(-4096);
|
|
154
|
+
const m = SERVE_PASSWORD_LINE.exec(buffered);
|
|
155
|
+
if (m) found = m[1];
|
|
156
|
+
return found;
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** Serve output with its password line taken out (what a log may hold). */
|
|
161
|
+
export function redactServeOutput(text) {
|
|
162
|
+
return String(text ?? '').replace(/server password \S+/g, 'server password <hidden>');
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* A line-buffering redactor for either of a serve's output streams. redactServeOutput runs on whole lines only: a chunk of a
|
|
167
|
+
* stream may split the "server password <x>" line anywhere (the token across two reads), and redacting each chunk on
|
|
168
|
+
* its own would let a fragment of the password through to the log. Feed every chunk to `push`; it assembles complete
|
|
169
|
+
* lines, redacts each and hands it to `emit` (the trailing newline kept). Call `flush` once the stream ends to emit a
|
|
170
|
+
* last line that never got its newline. A partial line that grows past `maxLine` without a newline is redacted and
|
|
171
|
+
* emitted so the buffer cannot grow without bound (the password line is short and newline-terminated, so this cap is
|
|
172
|
+
* never reached mid-password).
|
|
173
|
+
*/
|
|
174
|
+
export function createServeLogRedactor(emit, { maxLine = 65536 } = {}) {
|
|
175
|
+
let buf = '';
|
|
176
|
+
const drain = (final) => {
|
|
177
|
+
let nl;
|
|
178
|
+
while ((nl = buf.indexOf('\n')) >= 0) {
|
|
179
|
+
const line = buf.slice(0, nl + 1);
|
|
180
|
+
buf = buf.slice(nl + 1);
|
|
181
|
+
emit(redactServeOutput(line));
|
|
182
|
+
}
|
|
183
|
+
if ((final || buf.length > maxLine) && buf) { emit(redactServeOutput(buf)); buf = ''; }
|
|
184
|
+
};
|
|
185
|
+
return {
|
|
186
|
+
push: (chunk) => { buf += String(chunk ?? ''); drain(false); },
|
|
187
|
+
flush: () => drain(true),
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* A serve's environment with a run's own settings on top: a string value is set, null (or undefined) removes the
|
|
193
|
+
* variable, anything else is ignored. `GIT_*: null` clears every inherited git variable BEFORE the explicit
|
|
194
|
+
* settings are applied, so SynaBun's own git safety settings survive. The marker never reaches the child.
|
|
195
|
+
* A new object; `env` is not changed. Also used for evaluation runtimes, whose whole process tree needs this policy.
|
|
196
|
+
*/
|
|
197
|
+
export function withServeEnv(env, extra) {
|
|
198
|
+
const next = { ...(env || {}) };
|
|
199
|
+
if (extra && typeof extra === 'object') {
|
|
200
|
+
if (extra['GIT_*'] === null) for (const key of Object.keys(next)) if (key.startsWith('GIT_')) delete next[key];
|
|
201
|
+
for (const [key, value] of Object.entries(extra)) {
|
|
202
|
+
if (key === 'GIT_*') continue;
|
|
203
|
+
if (typeof value === 'string') next[key] = value;
|
|
204
|
+
else if (value === null || value === undefined) delete next[key];
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return next;
|
|
76
208
|
}
|
|
77
209
|
|
|
78
210
|
function isJsonResponse(res) {
|
|
@@ -85,89 +217,94 @@ async function readJson(res) {
|
|
|
85
217
|
}
|
|
86
218
|
|
|
87
219
|
/**
|
|
88
|
-
* Is
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
* 'locked'
|
|
94
|
-
* '
|
|
95
|
-
* '
|
|
96
|
-
* '
|
|
97
|
-
* 'error' something answered, but not an OpenCode API
|
|
220
|
+
* Is OpenCode 2's API answering on `port`? Asks /api/info with `password`.
|
|
221
|
+
* Resolves `{ ok, version, state, error }`, where `state` is
|
|
222
|
+
* 'healthy' OpenCode 2's API answered JSON, from a version SynaBun drives
|
|
223
|
+
* 'unsupported' OpenCode's API answered, from a version SynaBun does not drive
|
|
224
|
+
* (`error` is opencodeSupportFor's sentence)
|
|
225
|
+
* 'locked' an OpenCode 2 serve whose password SynaBun does not hold
|
|
226
|
+
* 'html' a web page — never healthy
|
|
227
|
+
* 'down' nothing answered
|
|
228
|
+
* 'error' something answered, but not OpenCode 2's API
|
|
98
229
|
* Never throws.
|
|
99
230
|
*/
|
|
100
|
-
export async function checkOpencodeServer({ port,
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const asV1 = async () => {
|
|
110
|
-
const res = await get('/global/health');
|
|
111
|
-
if (res.failed) return { ok: false, protocol: 1, version: null, state: 'down', error: String(res.error?.message || res.error) };
|
|
112
|
-
const { json, html } = await readJson(res);
|
|
113
|
-
if (res.ok && json && (json.healthy === true || typeof json.version === 'string')) {
|
|
114
|
-
return { ok: true, protocol: 1, version: typeof json.version === 'string' ? json.version : null, state: 'healthy', error: null };
|
|
115
|
-
}
|
|
116
|
-
return { ok: false, protocol: 1, version: null, state: html ? 'html' : 'error', error: html ? 'answered with a web page, not the OpenCode 1 API' : `GET /global/health answered ${res.status}` };
|
|
117
|
-
};
|
|
118
|
-
const asV2 = async () => {
|
|
119
|
-
const res = await get('/api/info', password ? { authorization: basicAuthHeader(password) } : {});
|
|
120
|
-
if (res.failed) return { ok: false, protocol: 2, version: null, state: 'down', error: String(res.error?.message || res.error) };
|
|
121
|
-
const { json, html } = await readJson(res);
|
|
122
|
-
if (res.ok && json && typeof json.version === 'string' && Array.isArray(json.urls)) {
|
|
123
|
-
return { ok: true, protocol: 2, version: json.version, state: 'healthy', error: null };
|
|
124
|
-
}
|
|
125
|
-
if (res.status === 401 && json && /unauthori[sz]ed/i.test(String(json._tag || json.name || ''))) {
|
|
126
|
-
return { ok: false, protocol: 2, version: null, state: 'locked', error: password ? 'the OpenCode 2 serve refused SynaBun\'s password' : 'an OpenCode 2 serve SynaBun did not start (it needs that serve\'s password)' };
|
|
127
|
-
}
|
|
128
|
-
return { ok: false, protocol: 2, version: null, state: html ? 'html' : 'error', error: html ? 'answered with a web page, not the OpenCode 2 API' : `GET /api/info answered ${res.status}` };
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
if (protocol === 1) {
|
|
132
|
-
const v1 = await asV1();
|
|
133
|
-
if (v1.ok || v1.state === 'down') return v1;
|
|
134
|
-
// A web page where OpenCode 1 was expected: is it an OpenCode 2?
|
|
135
|
-
const v2 = await asV2();
|
|
136
|
-
if (v2.ok || v2.state === 'locked') return { ...v2, ok: false, state: 'mismatch', error: 'an OpenCode 2 serve answered where SynaBun expected OpenCode 1' };
|
|
137
|
-
return v1;
|
|
231
|
+
export async function checkOpencodeServer({ port, password = null, fetchImpl = globalThis.fetch, timeoutMs = 2000, host = '127.0.0.1' } = {}) {
|
|
232
|
+
let res;
|
|
233
|
+
try {
|
|
234
|
+
res = await fetchImpl(`http://${host}:${port}/api/info`, {
|
|
235
|
+
headers: { accept: 'application/json', ...(password ? { authorization: basicAuthHeader(password) } : {}) },
|
|
236
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
237
|
+
});
|
|
238
|
+
} catch (error) {
|
|
239
|
+
return { ok: false, version: null, state: 'down', error: String(error?.message || error) };
|
|
138
240
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
return v2;
|
|
241
|
+
const { json, html } = await readJson(res);
|
|
242
|
+
if (res.ok && json && typeof json.version === 'string' && Array.isArray(json.urls)) {
|
|
243
|
+
const support = opencodeSupportFor(json.version);
|
|
244
|
+
if (!support.supported) return { ok: false, version: json.version, state: 'unsupported', error: support.reason };
|
|
245
|
+
return { ok: true, version: json.version, state: 'healthy', error: null };
|
|
145
246
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
return
|
|
247
|
+
if (res.status === 401 && json && /unauthori[sz]ed/i.test(String(json._tag || json.name || ''))) {
|
|
248
|
+
return { ok: false, version: null, state: 'locked', error: password ? 'the OpenCode serve refused SynaBun\'s password' : 'an OpenCode serve SynaBun did not start (it needs that serve\'s password)' };
|
|
249
|
+
}
|
|
250
|
+
return { ok: false, version: null, state: html ? 'html' : 'error', error: html ? 'answered with a web page, not the OpenCode 2 API' : `GET /api/info answered ${res.status}` };
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// An upgrade must be rejected before PTY/resource lookup, even for an Origin
|
|
254
|
+
// that OpenCode permits. Never place a real credential in a URL or this probe.
|
|
255
|
+
export function probeUnauthenticatedUpgrade({ port, timeoutMs = 2000 } = {}) {
|
|
256
|
+
return new Promise(resolve => {
|
|
257
|
+
const req = httpRequest({ hostname: '127.0.0.1', port,
|
|
258
|
+
path: '/api/pty/synabun-auth-probe/connect',
|
|
259
|
+
headers: { connection: 'Upgrade', upgrade: 'websocket', 'sec-websocket-version': '13',
|
|
260
|
+
'sec-websocket-key': randomBytes(16).toString('base64'), origin: 'http://localhost:1' },
|
|
261
|
+
});
|
|
262
|
+
req.on('response', res => { res.resume(); resolve(res.statusCode); });
|
|
263
|
+
req.on('upgrade', (_res, socket) => { socket.destroy(); resolve(101); });
|
|
264
|
+
req.on('error', () => resolve(null));
|
|
265
|
+
req.setTimeout(timeoutMs, () => { req.destroy(); resolve(null); });
|
|
266
|
+
req.end();
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/** Readiness for private serves: valid client + denied anonymous HTTP AND WS.
|
|
271
|
+
* An unmanaged, passwordless API is never adopted. Errors contain no secrets.
|
|
272
|
+
*/
|
|
273
|
+
export async function checkPrivateOpencodeServer(options = {}) {
|
|
274
|
+
const check = await checkOpencodeServer(options);
|
|
275
|
+
if (!check.ok) return check;
|
|
276
|
+
const refused = () => ({ ok: false, version: check.version, state: 'unsecured',
|
|
277
|
+
error: 'OpenCode did not prove private HTTP and WebSocket authentication; it will not be used.' });
|
|
278
|
+
if (!options.password) return refused();
|
|
279
|
+
try {
|
|
280
|
+
const response = await (options.fetchImpl || globalThis.fetch)(`http://127.0.0.1:${options.port}/api/info`, {
|
|
281
|
+
headers: { accept: 'application/json' }, signal: AbortSignal.timeout(options.timeoutMs || 2000), redirect: 'error',
|
|
282
|
+
});
|
|
283
|
+
await response.body?.cancel();
|
|
284
|
+
if (response.status !== 401 || await probeUnauthenticatedUpgrade(options) !== 401) return refused();
|
|
285
|
+
} catch { return refused(); }
|
|
286
|
+
return check;
|
|
150
287
|
}
|
|
151
288
|
|
|
152
289
|
/**
|
|
153
290
|
* The sentence a person reads when OpenCode cannot be used: what was found and
|
|
154
|
-
* what to do. `check` is a checkOpencodeServer answer, `detected`
|
|
155
|
-
*
|
|
291
|
+
* what to do. `check` is a checkOpencodeServer answer, `detected` an
|
|
292
|
+
* opencodeSupportFor answer.
|
|
156
293
|
*/
|
|
157
294
|
export function opencodeProblemText({ check = null, detected = null, port = null } = {}) {
|
|
158
295
|
if (detected && !detected.supported) return detected.reason;
|
|
159
296
|
if (!check || check.ok) return '';
|
|
160
297
|
const where = port ? ` on port ${port}` : '';
|
|
161
298
|
switch (check.state) {
|
|
299
|
+
case 'unsupported':
|
|
300
|
+
return check.error || `The OpenCode server${where} is a version SynaBun does not drive.`;
|
|
162
301
|
case 'locked':
|
|
163
|
-
return `An OpenCode
|
|
164
|
-
case 'mismatch':
|
|
165
|
-
return `The OpenCode server${where} is not the version SynaBun found on this computer (${check.error}). Stop it and start OpenCode again from SynaBun.`;
|
|
302
|
+
return `An OpenCode server SynaBun did not start is already running${where}, and SynaBun does not have its password. Stop that server (or free the port) and start OpenCode again from SynaBun.`;
|
|
166
303
|
case 'html':
|
|
167
|
-
return `Something${where} answers with a web page instead of the OpenCode API (${check.error}).`;
|
|
304
|
+
return `Something${where} answers with a web page instead of the OpenCode 2 API (${check.error}).`;
|
|
168
305
|
case 'down':
|
|
169
306
|
return `OpenCode is not answering${where}.`;
|
|
170
307
|
default:
|
|
171
|
-
return `OpenCode${where} did not answer as
|
|
308
|
+
return `OpenCode${where} did not answer as OpenCode 2: ${check.error || 'unknown error'}.`;
|
|
172
309
|
}
|
|
173
310
|
}
|
|
@@ -1,35 +1,33 @@
|
|
|
1
1
|
import { dirname, resolve } from 'node:path';
|
|
2
2
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
3
|
+
import { mcpServersOf, normalizeMcpServers, parseJsonc, setMcpServer, withPlugin } from './opencode-config.js';
|
|
3
4
|
|
|
4
|
-
/** The browser-policy plugin (assistant-brains/
|
|
5
|
-
export const OPENCODE_BROWSER_POLICY_PLUGIN = pathToFileURL(resolve(dirname(fileURLToPath(import.meta.url)), 'assistant-brains', '
|
|
6
|
-
/** Its OpenCode 2 form: a plugin folder, listed under `plugins` (OpenCode 1 ignores that key). */
|
|
7
|
-
export const OPENCODE2_BROWSER_POLICY_PLUGIN = pathToFileURL(resolve(dirname(fileURLToPath(import.meta.url)), 'assistant-brains', 'opencode2-browser-policy')).href;
|
|
5
|
+
/** The browser-policy plugin (assistant-brains/opencode2-browser-policy/, a plugin folder) as a file URL a serve can load. */
|
|
6
|
+
export const OPENCODE_BROWSER_POLICY_PLUGIN = pathToFileURL(resolve(dirname(fileURLToPath(import.meta.url)), 'assistant-brains', 'opencode2-browser-policy')).href;
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* An Assistant task run's serve config gets SynaBun's browser policy as a
|
|
11
|
-
* plugin (`cwd`: the run's project, for the scripts it reads
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* plugin (`cwd`: the run's project, for the scripts it reads; `roots`: the
|
|
11
|
+
* registered code projects its test runners may also run in, as the run
|
|
12
|
+
* starts), listed under `plugins`. The user's own plugins stay; an earlier
|
|
13
|
+
* entry of ours is replaced. Returns `config`.
|
|
14
14
|
*/
|
|
15
|
-
export function withOpenCodeBrowserPolicy(config, { cwd = null } = {}) {
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
plugins.push([OPENCODE_BROWSER_POLICY_PLUGIN, options]);
|
|
19
|
-
config.plugin = plugins;
|
|
20
|
-
const plugins2 = (Array.isArray(config.plugins) ? config.plugins : []).filter((entry) => (entry && typeof entry === 'object' ? entry.package : entry) !== OPENCODE2_BROWSER_POLICY_PLUGIN);
|
|
21
|
-
plugins2.push({ package: OPENCODE2_BROWSER_POLICY_PLUGIN, options });
|
|
22
|
-
config.plugins = plugins2;
|
|
23
|
-
return config;
|
|
15
|
+
export function withOpenCodeBrowserPolicy(config, { cwd = null, roots = [] } = {}) {
|
|
16
|
+
const list = (Array.isArray(roots) ? roots : []).filter((path) => typeof path === 'string' && path);
|
|
17
|
+
return withPlugin(config, OPENCODE_BROWSER_POLICY_PLUGIN, { ...(cwd ? { cwd: String(cwd) } : {}), ...(list.length ? { roots: list } : {}) });
|
|
24
18
|
}
|
|
25
19
|
|
|
26
20
|
/**
|
|
27
|
-
* Build the SynaBun MCP entry used by managed OpenCode runtimes
|
|
21
|
+
* Build the SynaBun MCP entry used by managed OpenCode runtimes, in OpenCode
|
|
22
|
+
* 2's shape (`mcp.servers.SynaBun`: type local, the command as an array, its
|
|
23
|
+
* `environment`).
|
|
28
24
|
*
|
|
29
25
|
* Managed sidepanels/automations must always use a local MCP child. Reusing a
|
|
30
26
|
* user's remote entry would ignore process environment pins and collapse all
|
|
31
|
-
* sessions onto the shared HTTP server. Preserve harmless local options
|
|
32
|
-
* remove remote-only transport fields and
|
|
27
|
+
* sessions onto the shared HTTP server. Preserve harmless local options (its
|
|
28
|
+
* timeout, its working folder), but remove remote-only transport fields and a
|
|
29
|
+
* switch that turned it off, and canonicalize command/environment. SynaBun tools are always direct calls;
|
|
30
|
+
* OpenCode 2.1 otherwise hides them behind Code Mode (`execute`). Other servers keep their own settings.
|
|
33
31
|
*/
|
|
34
32
|
export function buildManagedOpenCodeSynabunEntry(existing, {
|
|
35
33
|
command,
|
|
@@ -45,7 +43,10 @@ export function buildManagedOpenCodeSynabunEntry(existing, {
|
|
|
45
43
|
environment: _environment,
|
|
46
44
|
env: _env,
|
|
47
45
|
command: _command,
|
|
46
|
+
args: _args,
|
|
48
47
|
type: _type,
|
|
48
|
+
enabled: _enabled,
|
|
49
|
+
disabled: _disabled,
|
|
49
50
|
...safeOptions
|
|
50
51
|
} = source;
|
|
51
52
|
const environment = {
|
|
@@ -57,9 +58,18 @@ export function buildManagedOpenCodeSynabunEntry(existing, {
|
|
|
57
58
|
return {
|
|
58
59
|
...safeOptions,
|
|
59
60
|
type: 'local',
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
codemode: false,
|
|
62
|
+
command: Array.isArray(command) ? [...command] : [command],
|
|
62
63
|
environment,
|
|
63
|
-
env: { ...environment },
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
|
+
|
|
67
|
+
/** Pin only SynaBun on the shared serve, preserving an inherited overlay and the owner's other servers. */
|
|
68
|
+
export function buildSharedOpenCodeConfigOverlay(config, content) {
|
|
69
|
+
const overlay = normalizeMcpServers(parseJsonc(content || '{}'));
|
|
70
|
+
const synabun = mcpServersOf(config).SynaBun;
|
|
71
|
+
const inherited = mcpServersOf(overlay).SynaBun;
|
|
72
|
+
if (!synabun && !inherited) return content;
|
|
73
|
+
setMcpServer(overlay, 'SynaBun', { ...synabun, ...inherited, codemode: false });
|
|
74
|
+
return JSON.stringify(overlay);
|
|
75
|
+
}
|