synabun 2.0.9 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +115 -0
- package/README.md +25 -2
- package/THIRD-PARTY-LICENSES.md +68 -4
- package/bin/synabun.js +71 -24
- package/docs/whatsapp.md +2 -2
- 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/launcher.mjs +9 -3
- package/lib/claude-hooks.js +172 -18
- package/lib/client-config-repair.js +17 -8
- package/lib/desktop-app.js +7 -1
- package/lib/external-tools.js +1 -1
- 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 +43 -5
- package/lib/tools-cli.js +45 -0
- package/lib/update-snapshot.js +228 -0
- package/lib/virustotal.mjs +192 -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/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/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/neural-interface.d.ts +16 -10
- 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 +20 -62
- 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/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 +10 -10
- package/mcp-server/dist/tools/agents.d.ts.map +1 -1
- package/mcp-server/dist/tools/agents.js +22 -13
- 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/image-tools.d.ts +1 -1
- package/mcp-server/dist/tools/image-tools.js +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 +639 -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/codex-config-heal.ts +80 -29
- package/mcp-server/src/services/memory-judge-backfill.ts +7 -1
- package/mcp-server/src/services/neural-interface.ts +79 -20
- package/mcp-server/src/services/server-instructions.ts +27 -63
- 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/whiteboard-geometry.ts +94 -9
- package/mcp-server/src/tools/agents.ts +22 -14
- package/mcp-server/src/tools/image-tools.ts +1 -1
- package/mcp-server/src/tools/skill-tools.ts +589 -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 +3680 -206
- package/neural-interface/i18n/pt-BR.json +3628 -157
- package/neural-interface/lib/account-usage.js +5 -3
- package/neural-interface/lib/app-controls-api.js +161 -0
- package/neural-interface/lib/assistant-api.js +148 -35
- 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 +122 -44
- package/neural-interface/lib/assistant-brains/opencode2-browser-policy/index.js +59 -0
- package/neural-interface/lib/assistant-brains/opencode2-route-gate/index.js +97 -0
- package/neural-interface/lib/assistant-catalog.js +23 -9
- package/neural-interface/lib/assistant-dispatch.js +874 -156
- package/neural-interface/lib/assistant-envelope.js +22 -2
- package/neural-interface/lib/assistant-persona.js +80 -11
- package/neural-interface/lib/assistant-plan-permissions.js +10 -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 +13 -8
- package/neural-interface/lib/assistant-runtime.js +183 -26
- package/neural-interface/lib/assistant-task-prompt.js +78 -14
- package/neural-interface/lib/assistant-tools.js +51 -0
- package/neural-interface/lib/backup-service.js +620 -3
- 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 +83 -0
- package/neural-interface/lib/browser-network-guard.js +284 -0
- package/neural-interface/lib/browser-policy-roots.js +64 -0
- package/neural-interface/lib/browser-tool-policy.js +186 -31
- package/neural-interface/lib/claude-agent-bridge.js +4 -2
- package/neural-interface/lib/claude-hooks-status.js +103 -0
- package/neural-interface/lib/claude-model-catalog.js +64 -14
- package/neural-interface/lib/claude-temporary.js +5 -11
- package/neural-interface/lib/cli-install.js +18 -138
- package/neural-interface/lib/cli-resolver.js +4 -1
- package/neural-interface/lib/cli-update-planner.js +32 -31
- package/neural-interface/lib/cloudflared/tunnel.js +42 -2
- package/neural-interface/lib/codex-mcp-approvals.js +11 -0
- package/neural-interface/lib/codex-settings-schema.js +109 -47
- package/neural-interface/lib/codex-worker-app-server.js +172 -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 +164 -67
- package/neural-interface/lib/exec-loop-command.js +4 -1
- package/neural-interface/lib/http-guards.js +8 -2
- package/neural-interface/lib/install-details.js +4 -1
- package/neural-interface/lib/launch-cache.js +293 -0
- package/neural-interface/lib/login-start.js +524 -0
- package/neural-interface/lib/mcp-agent-servers.js +67 -0
- package/neural-interface/lib/mcp-client-config.js +0 -29
- package/neural-interface/lib/mcp-external-servers.js +323 -0
- package/neural-interface/lib/{mcp-profile-refresh-coordinator.js → mcp-tools-refresh-coordinator.js} +4 -4
- package/neural-interface/lib/morelogin.js +30 -0
- package/neural-interface/lib/native-loop-providers.js +565 -50
- package/neural-interface/lib/native-loop-runtime.js +287 -41
- package/neural-interface/lib/opencode-config.js +557 -0
- package/neural-interface/lib/opencode-db-schema.js +58 -0
- package/neural-interface/lib/opencode-history.js +49 -204
- package/neural-interface/lib/opencode-mcp-ready.js +108 -0
- package/neural-interface/lib/opencode-native-boundary.js +44 -0
- package/neural-interface/lib/opencode-protocol.js +310 -0
- package/neural-interface/lib/opencode-provider-view.js +81 -0
- package/neural-interface/lib/opencode-runtime-config.js +32 -15
- package/neural-interface/lib/opencode-serve-records.js +624 -0
- package/neural-interface/lib/opencode-v2-client.js +53 -131
- package/neural-interface/lib/opencode-v2-ws-requests.js +35 -195
- package/neural-interface/lib/opencode-worker-activity.js +229 -0
- package/neural-interface/lib/opencode-worker-data.js +27 -0
- package/neural-interface/lib/opencode2-client.js +796 -0
- package/neural-interface/lib/opencode2-proxy.js +76 -0
- package/neural-interface/lib/opencode2-translate.js +1057 -0
- package/neural-interface/lib/owner-authority.js +249 -0
- package/neural-interface/lib/page-session.js +275 -0
- package/neural-interface/lib/peer-identity.js +763 -0
- package/neural-interface/lib/process-identity.js +361 -0
- package/neural-interface/lib/request-gate.js +17 -2
- package/neural-interface/lib/rulesets/api.js +1 -1
- package/neural-interface/lib/rulesets/fs-safe.js +1 -1
- package/neural-interface/lib/rulesets/installer.js +92 -27
- package/neural-interface/lib/rulesets/json-edit.js +1 -1
- package/neural-interface/lib/session-cache-builder.js +18 -10
- package/neural-interface/lib/session-title-generator.js +58 -18
- 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 +294 -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 +267 -0
- package/neural-interface/lib/skills/creation.js +843 -0
- package/neural-interface/lib/skills/deploy.js +564 -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 +214 -0
- package/neural-interface/lib/skills/eval-confinement.js +397 -0
- package/neural-interface/lib/skills/eval-sandbox.js +280 -0
- package/neural-interface/lib/skills/eval-trace.js +119 -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 +200 -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 +387 -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 +262 -0
- package/neural-interface/lib/skills/runtime-checks.js +355 -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 +522 -0
- package/neural-interface/lib/skills/telemetry.js +113 -0
- package/neural-interface/lib/sqlite-integrity-worker.js +22 -0
- package/neural-interface/lib/style-guide/api.js +4 -3
- package/neural-interface/lib/tool-lists.js +124 -0
- package/neural-interface/lib/untrusted-file-headers.js +27 -0
- package/neural-interface/lib/whatsapp/bridge.js +6 -3
- package/neural-interface/lib/worker-confinement.js +1192 -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-relay-ports.js +227 -0
- package/neural-interface/lib/worker-resume.js +229 -0
- package/neural-interface/lib/worker-sandbox.js +299 -0
- package/neural-interface/package-lock.json +1354 -50
- package/neural-interface/package.json +6 -2
- package/neural-interface/public/index.html +5 -3
- package/neural-interface/public/index2d.html +19 -11
- package/neural-interface/public/onboarding.html +2 -2
- package/neural-interface/public/shared/account-menu.js +8 -5
- package/neural-interface/public/shared/agent-runtime-options.js +76 -16
- 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 +205 -19
- package/neural-interface/public/shared/assistant/asst-api.js +11 -3
- 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 +241 -112
- package/neural-interface/public/shared/assistant/asst-composer.js +1 -1
- package/neural-interface/public/shared/assistant/asst-control.js +157 -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 +49 -2
- package/neural-interface/public/shared/assistant/asst-limit-dock.js +40 -0
- package/neural-interface/public/shared/assistant/asst-limit-wait.js +294 -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 +84 -12
- package/neural-interface/public/shared/assistant/asst-panel.js +303 -44
- package/neural-interface/public/shared/assistant/asst-rack-styles.js +93 -58
- package/neural-interface/public/shared/assistant/asst-redact.js +186 -0
- package/neural-interface/public/shared/assistant/asst-render.js +770 -100
- package/neural-interface/public/shared/assistant/asst-route.js +83 -12
- package/neural-interface/public/shared/assistant/asst-run-stage.js +231 -0
- package/neural-interface/public/shared/assistant/asst-sanitize.js +193 -3
- package/neural-interface/public/shared/assistant/asst-scene-styles.js +273 -0
- package/neural-interface/public/shared/assistant/asst-scenes.js +530 -0
- package/neural-interface/public/shared/assistant/asst-sidepanel-styles.js +3 -15
- package/neural-interface/public/shared/assistant/asst-sidepanel.js +67 -4
- package/neural-interface/public/shared/assistant/asst-slash.js +9 -7
- package/neural-interface/public/shared/assistant/asst-state.js +25 -15
- package/neural-interface/public/shared/assistant/asst-stop.js +127 -0
- package/neural-interface/public/shared/assistant/asst-styles.js +102 -21
- package/neural-interface/public/shared/assistant/asst-tool-kinds.js +165 -13
- package/neural-interface/public/shared/automation-context.js +5 -2
- package/neural-interface/public/shared/cc-dropdown.js +550 -0
- 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 +8 -7
- package/neural-interface/public/shared/cdx/cdx-panel.js +58 -150
- package/neural-interface/public/shared/cdx/cdx-protocol.js +28 -1
- package/neural-interface/public/shared/cdx/cdx-render.js +62 -32
- package/neural-interface/public/shared/cdx/cdx-requests.js +3 -3
- 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 +201 -74
- package/neural-interface/public/shared/cdx/cdx-ws.js +0 -1
- package/neural-interface/public/shared/cli-install-view.js +4 -8
- package/neural-interface/public/shared/cli-status.js +2 -2
- package/neural-interface/public/shared/constants.js +2 -2
- 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 +366 -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-markdown.js +4 -57
- package/neural-interface/public/shared/crash-notice-view.js +168 -0
- package/neural-interface/public/shared/data-cache.js +223 -0
- package/neural-interface/public/shared/desktop-bridge.js +11 -0
- package/neural-interface/public/shared/desktop-titlebar-view.js +78 -1
- package/neural-interface/public/shared/desktop-titlebar.js +214 -28
- package/neural-interface/public/shared/desktop-update-view.js +35 -5
- package/neural-interface/public/shared/editor/editor-panel-logic.js +2 -2
- package/neural-interface/public/shared/file-links.js +73 -8
- package/neural-interface/public/shared/html-shell.js +78 -86
- package/neural-interface/public/shared/i18n.js +2 -0
- package/neural-interface/public/shared/launch-prefetch.js +59 -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-caps.js +3 -2
- 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 +9 -2
- 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-modelpicker.js +54 -17
- 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 +140 -254
- package/neural-interface/public/shared/ocp-v2/ocp-v2-plan.js +1 -2
- package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +97 -203
- package/neural-interface/public/shared/ocp-v2/ocp-v2-providers.js +11 -9
- package/neural-interface/public/shared/ocp-v2/ocp-v2-rehydrate.js +15 -4
- package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +7 -22
- package/neural-interface/public/shared/ocp-v2/ocp-v2-send-logic.js +401 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +20 -13
- 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 +53 -82
- 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 +48 -40
- 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 +205 -62
- package/neural-interface/public/shared/opencode-providers.js +39 -0
- package/neural-interface/public/shared/page-session.js +96 -0
- 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 +452 -0
- package/neural-interface/public/shared/settings/settings-app-pane.js +335 -0
- package/neural-interface/public/shared/settings/settings-app.js +243 -0
- package/neural-interface/public/shared/settings/settings-claude-hooks.js +135 -0
- package/neural-interface/public/shared/settings/settings-data.js +90 -0
- package/neural-interface/public/shared/settings/settings-ia.js +23 -6
- package/neural-interface/public/shared/settings/settings-opencode.js +89 -0
- 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/sidepanel-session-status.js +49 -0
- package/neural-interface/public/shared/skills/ss-args.js +96 -0
- package/neural-interface/public/shared/skills/ss-creation.js +219 -0
- package/neural-interface/public/shared/skills/ss-dialog.js +130 -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 +141 -0
- package/neural-interface/public/shared/skills/ss-presets.js +117 -0
- package/neural-interface/public/shared/skills/ss-profiles.js +475 -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 +236 -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 +229 -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-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 +279 -0
- package/neural-interface/public/shared/skills/studio/sx-install.js +296 -0
- package/neural-interface/public/shared/skills/studio/sx-library-view.js +639 -0
- package/neural-interface/public/shared/skills/studio/sx-library.js +475 -0
- package/neural-interface/public/shared/skills/studio/sx-main.js +681 -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 +248 -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 +425 -0
- package/neural-interface/public/shared/styleguide/sg-panel.js +4 -2
- package/neural-interface/public/shared/styles.css +2065 -2150
- package/neural-interface/public/shared/synabun-mascot.js +1115 -9
- 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/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-assistant.js +27 -5
- package/neural-interface/public/shared/ui-automation-studio.js +155 -152
- package/neural-interface/public/shared/ui-bookmarks.js +2 -1
- package/neural-interface/public/shared/ui-claude-panel.js +153 -13
- package/neural-interface/public/shared/ui-codex-panel.js +1 -0
- 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 +21 -9
- package/neural-interface/public/shared/ui-file-links.js +1 -0
- package/neural-interface/public/shared/ui-image-gallery.js +56 -52
- package/neural-interface/public/shared/ui-invite.js +18 -2
- package/neural-interface/public/shared/ui-keybinds.js +26 -1
- package/neural-interface/public/shared/ui-link.js +9 -9
- package/neural-interface/public/shared/ui-menubar.js +229 -40
- package/neural-interface/public/shared/ui-native-loop-router-state.js +5 -0
- package/neural-interface/public/shared/ui-native-loop-router.js +9 -1
- package/neural-interface/public/shared/ui-navbar.js +4 -24
- package/neural-interface/public/shared/ui-opencode-panel-v2.js +1 -0
- package/neural-interface/public/shared/ui-panels.js +96 -65
- package/neural-interface/public/shared/ui-schedules-studio.js +2267 -953
- package/neural-interface/public/shared/ui-sessions.js +20 -7
- package/neural-interface/public/shared/ui-settings.js +679 -496
- package/neural-interface/public/shared/ui-sidebar.js +4 -4
- package/neural-interface/public/shared/ui-sidepanel-session-entry.js +13 -0
- package/neural-interface/public/shared/ui-sidepanel-sessions.js +56 -5
- package/neural-interface/public/shared/ui-sidepanel-state.js +23 -12
- package/neural-interface/public/shared/ui-sidepanel-tray.js +84 -8
- package/neural-interface/public/shared/ui-sidepanel-windows.js +16 -11
- package/neural-interface/public/shared/ui-skills.js +42 -2781
- package/neural-interface/public/shared/ui-styleguide.js +5 -2
- package/neural-interface/public/shared/ui-sync.js +22 -5
- package/neural-interface/public/shared/ui-terminal.js +159 -199
- package/neural-interface/public/shared/ui-tool-updates.js +3 -1
- package/neural-interface/public/shared/ui-tooltip.js +10 -5
- package/neural-interface/public/shared/ui-trash.js +14 -5
- 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 -61
- package/neural-interface/public/shared/ui-tutorial.css +47 -100
- package/neural-interface/public/shared/ui-tutorial.js +285 -499
- package/neural-interface/public/shared/ui-update.js +121 -16
- package/neural-interface/public/shared/ui-whiteboard.js +313 -59
- package/neural-interface/public/shared/ui-worker-end.js +4 -0
- 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 +1 -1
- 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-restart.js +12 -0
- package/neural-interface/public/sidepanel-session.html +1 -1
- 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 +36 -2
- package/neural-interface/public/variant/2d/minimap.js +11 -13
- package/neural-interface/public/variant/3d/main.js +72 -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/highlight/LICENSE +29 -0
- package/neural-interface/public/vendor/highlight/github-dark-dimmed-11.12.0.min.css +9 -0
- package/neural-interface/public/vendor/highlight/highlight-11.12.0.min.js +1262 -0
- package/neural-interface/public/vendor/highlight/manifest.json +5 -0
- package/neural-interface/public/vendor/html2canvas/LICENSE +22 -0
- package/neural-interface/public/vendor/html2canvas/html2canvas-1.4.1.min.js +20 -0
- package/neural-interface/public/vendor/html2canvas/manifest.json +4 -0
- package/neural-interface/public/vendor/marked/LICENSE.md +44 -0
- package/neural-interface/public/vendor/marked/manifest.json +4 -0
- package/neural-interface/public/vendor/marked/marked-14.1.4.esm.js +2502 -0
- package/neural-interface/public/vendor/mermaid/LICENSE +21 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/abnfDiagram-PAR5IXJI.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/architecture-7GRP2DOG-M7G3SWCO.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/architectureDiagram-2PNWDENW.mjs +36 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/blockDiagram-PUWGUBOA.mjs +129 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/c4Diagram-3NLNHZP5.mjs +38 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-2NMSUPJH.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-32MCUW2P.mjs +206 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-3NPNU5GP.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-3SMGFRGC.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-4CAJECRU.mjs +14 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-4OADUZ5Q.mjs +10 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5IMINLNL.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5IQCK5RY.mjs +3 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5MVFYWFU.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-AQ6EADP3.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-AZZRMDJM.mjs +15 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-CLS4B6BI.mjs +168 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-DZP67EKU.mjs +70 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-EICP7K5X.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-GDY2UAB4.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-H7VHZCWX.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-IJBDOHL6.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JFFVMJIA.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JQRUD6KW.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JZGDI5JK.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-KD6SPIPN.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-NF366YI6.mjs +231 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-NUDPKBEF.mjs +32 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-OJINMHTS.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-Q6NGPIAH.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-QJSWEUOL.mjs +132 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-R7JDMUKV.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-RCXAM2GK.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-RT4MAWR3.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-SFMINX4W.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-SLDQ463B.mjs +88 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-STOV2HOB.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-T5OCTHI4.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-TCEHX7R3.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VQC2EELJ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VRZKL3EH.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VTHDQ7BV.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VY2OSTJR.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-WUBWJARI.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-YBMQ5JGJ.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-YDMLL4PJ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-Z6V44ARX.mjs +62 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZJJ7VQJP.mjs +339 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZNLK7HRR.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZQN7UHIL.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZS6VBONO.mjs +174 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZUNWM646.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/classDiagram-FGAMPOII.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/classDiagram-v2-AI5RJEK4.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cose-bilkent-Q72C2OJ3.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cynefin-OW5HDTMX-6OCTWOGG.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cynefinDiagram-2OOWUY4M.mjs +62 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/dagre-MPVFI544.mjs +4 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-AE4NWXFW.mjs +24 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-BUJID5UG.mjs +41 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-C44CZ5NI.mjs +24 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-EYOLEXXS.mjs +30 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-P7B6PWOJ.mjs +3 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ebnfDiagram-FTPZ3PV6.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/erDiagram-H3ERR26V.mjs +99 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/eventmodeling-NTZA5JFV-WKSWQHFS.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/flowDiagram-YHGXBVSY.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ganttDiagram-RWFTB7ED.mjs +292 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/gitGraph-4MIJSDKK-JH2HKYUO.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/gitGraphDiagram-MAR6GKOP.mjs +106 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/info-A6RAGUB7-3TX3OFWW.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/infoDiagram-LV547AFH.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ishikawaDiagram-PUJQGNDS.mjs +70 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/journeyDiagram-EW5QJT4W.mjs +139 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/kanban-definition-JSQERAZB.mjs +89 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/katex-CZ4GXH2S.mjs +257 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/mindmap-definition-VBJCLQLM.mjs +96 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/packet-AYTQ26CC-MKII6P3Y.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pegDiagram-7WILOQTJ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pie-WAS4IAKB-6B4OPMJ5.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pieDiagram-EFA7CBSB.mjs +39 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/quadrantDiagram-WARVYA7P.mjs +7 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/radar-RG4KPBEZ-UPTR3XUL.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-74A4TZTK-MEFUPFMS.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-abnf-HS5TGJTU-R5YG2S5D.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-ebnf-LZEXJU2U-G5QEX2L6.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-peg-WCYAUIDC-H5I2ZRY2.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroadDiagram-5NIQVNLQ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/requirementDiagram-SXREGOKZ.mjs +84 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sankeyDiagram-VV74M2VP.mjs +40 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sequenceDiagram-52ZFIFDL.mjs +162 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sizeCapture-FGA5AGYP.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/stateDiagram-3QAKPIVI.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/stateDiagram-v2-HN2P4RDZ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/swimlanes-QLVP42QD.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/swimlanesDiagram-JKPDBFCN.mjs +8 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/timeline-definition-GS45XAXW.mjs +120 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/treeView-Q6P3EWNA-ZRJGANNQ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/treemap-WGGIJYW6-K64VN5AS.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/vennDiagram-QIQU2ZRJ.mjs +34 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/wardley-WFR3VGLG-D67OWCCH.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/wardleyDiagram-U6YNM66N.mjs +78 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/xychartDiagram-XJAZEDNM.mjs +7 -0
- package/neural-interface/public/vendor/mermaid/manifest.json +4 -0
- package/neural-interface/public/vendor/mermaid/mermaid-11.17.2.esm.min.mjs +14 -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 +116 -3
- package/neural-interface/server.js +4834 -2541
- package/neural-interface/templates/rulesets/core.md +1 -1
- package/neural-interface/templates/rulesets/legacy-hashes.json +18 -0
- package/neural-interface/templates/rulesets/manifest.json +8 -8
- package/npm-shrinkwrap.json +18 -12
- package/package.json +16 -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 +5 -5
- 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/lib/claude-hooks.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { accessSync, constants, statSync } from 'node:fs';
|
|
2
|
+
import { homedir, tmpdir } from 'node:os';
|
|
3
|
+
import { isAbsolute, join, resolve, sep } from 'node:path';
|
|
2
4
|
import { PACKAGE_ROOT } from './paths.js';
|
|
3
|
-
import { durableEntry, packagedRuntime } from './packaged-runtime.js';
|
|
5
|
+
import { durableEntry, isReadOnlyVolumePath, isTransientPath, packagedRuntime } from './packaged-runtime.js';
|
|
4
6
|
|
|
5
7
|
// Handler identity must be byte-for-byte identical across settings scopes.
|
|
6
8
|
// Claude Code deduplicates matching settings handlers before executing them.
|
|
@@ -27,10 +29,10 @@ export function hookDefinitionsForEvent(event) {
|
|
|
27
29
|
return HOOK_SCRIPTS.filter(def => events.includes(def.event));
|
|
28
30
|
}
|
|
29
31
|
|
|
30
|
-
// No
|
|
31
|
-
//
|
|
32
|
-
//
|
|
33
|
-
//
|
|
32
|
+
// No install paths or downloads. Walk up from the project/cwd for checkout-only
|
|
33
|
+
// installs, then use the installed root. Single quotes inside JS work inside
|
|
34
|
+
// the command's double quotes on both cmd.exe and POSIX shells. Keep this
|
|
35
|
+
// versioned literal stable.
|
|
34
36
|
const BOOTSTRAP = "const f=require('node:fs'),p=require('node:path'),u=require('node:url'),s=process.argv[1];let r;const ok=d=>{try{return JSON.parse(f.readFileSync(p.join(d,'package.json'),'utf8')).name==='synabun'&&f.existsSync(p.join(d,'hooks','claude-code',s))}catch{return false}};for(let d=p.resolve(process.env.CLAUDE_PROJECT_DIR||process.cwd());;d=p.dirname(d)){if(ok(d)){r=d;break}if(d===p.dirname(d))break}if(!r&&process.env.SYNABUN_HOOK_ROOT&&ok(process.env.SYNABUN_HOOK_ROOT))r=process.env.SYNABUN_HOOK_ROOT;if(!r)throw Error('SynaBun hook root unavailable; repair the hook installation');import(u.pathToFileURL(p.join(r,'hooks','claude-code',s)).href)";
|
|
35
37
|
|
|
36
38
|
/**
|
|
@@ -49,23 +51,48 @@ function quoteHookEntry(entry) {
|
|
|
49
51
|
return `"${entry.replace(/[\\"$`]/g, '\\$&')}"`;
|
|
50
52
|
}
|
|
51
53
|
|
|
54
|
+
// Windows: cmd.exe, PowerShell and Git Bash all run this, and a Windows program
|
|
55
|
+
// gets the user's PATH from the registry whoever starts it.
|
|
52
56
|
const nodeHookCommand = scriptName => `node -e "${BOOTSTRAP}" ${scriptName}`;
|
|
53
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Where a hook started without the login PATH looks for Node after `node` on
|
|
60
|
+
* PATH: the official installer's and Homebrew's folders and Volta's shim (the
|
|
61
|
+
* Node a terminal finds, as a rule), then SYNABUN_NODE. The same names on every
|
|
62
|
+
* machine.
|
|
63
|
+
*/
|
|
64
|
+
export const HOOK_NODE_FOLDERS = Object.freeze(['/usr/local/bin/node', '/opt/homebrew/bin/node', '$HOME/.volta/bin/node']);
|
|
65
|
+
|
|
66
|
+
// macOS and Linux: Claude Code runs a settings hook with /bin/sh in its own
|
|
67
|
+
// environment. Started from a terminal that has the login PATH; started from
|
|
68
|
+
// the Dock, Finder, a desktop app or launchd it is /usr/bin:/bin:/usr/sbin:/sbin,
|
|
69
|
+
// where `node` is not found and every hook exits 127. So: `node` on PATH, as a
|
|
70
|
+
// terminal finds it, then the usual folders, then the Node the installer named
|
|
71
|
+
// in the user's settings (SYNABUN_NODE: nvm and the like have no usual folder).
|
|
72
|
+
// Nothing in it names this machine, so the tracked template and the projects'
|
|
73
|
+
// settings carry it as they are.
|
|
74
|
+
const POSIX_NODE_FINDER = `n=$(command -v node) || for n in ${HOOK_NODE_FOLDERS.map(p => (p.startsWith('$') ? `"${p}"` : p)).join(' ')} "$SYNABUN_NODE"; do [ -f "$n" ] && [ -x "$n" ] && break; n=node; done; `;
|
|
75
|
+
const posixHookCommand = scriptName => `${POSIX_NODE_FINDER}exec "$n" -e "${BOOTSTRAP}" ${scriptName}`;
|
|
76
|
+
|
|
54
77
|
// Whatever entry wrote it: an application that moved must still find, and
|
|
55
78
|
// repair, its own handlers.
|
|
56
79
|
const PACKAGED_HOOK_COMMAND = new RegExp(`^"(?:[^"\\\\]|\\\\.)+"\\s+${PACKAGED_HOOK_MODE}\\s+(\\S+)$`);
|
|
57
80
|
|
|
58
|
-
export function hookCommandString(scriptName, _targetProjectPath, runtime = packagedRuntime()) {
|
|
81
|
+
export function hookCommandString(scriptName, _targetProjectPath, runtime = packagedRuntime(), platform = process.platform) {
|
|
59
82
|
if (!HOOK_SCRIPTS.some(h => h.script === scriptName)) throw new Error('Unknown SynaBun hook');
|
|
60
83
|
const entry = durableEntry(runtime);
|
|
61
|
-
|
|
84
|
+
if (entry) return `${quoteHookEntry(entry)} ${PACKAGED_HOOK_MODE} ${scriptName}`;
|
|
85
|
+
return platform === 'win32' ? nodeHookCommand(scriptName) : posixHookCommand(scriptName);
|
|
62
86
|
}
|
|
63
87
|
|
|
64
88
|
export function isSynaBunHookCommand(command, scriptName) {
|
|
65
89
|
if (typeof command !== 'string') return false;
|
|
66
|
-
//
|
|
67
|
-
// an npm install and the application
|
|
68
|
-
|
|
90
|
+
// Every canonical form, whichever kind of install and system is reading:
|
|
91
|
+
// moving between an npm install and the application, or a settings file
|
|
92
|
+
// shared between Windows and macOS, must not leave two handlers behind.
|
|
93
|
+
if (command === nodeHookCommand(scriptName) || command === posixHookCommand(scriptName)) return true;
|
|
94
|
+
// Any version of the POSIX finder in front of the same bootstrap.
|
|
95
|
+
if (command.startsWith('n=$(command -v node)') && command.endsWith(` -e "${BOOTSTRAP}" ${scriptName}`)) return true;
|
|
69
96
|
const packaged = command.trim().match(PACKAGED_HOOK_COMMAND);
|
|
70
97
|
if (packaged) return packaged[1] === scriptName;
|
|
71
98
|
// Recognize only the old direct-node path forms, including cross-OS installs.
|
|
@@ -98,25 +125,47 @@ export function hookInstallPlan({ target, registered = false, hook } = {}, runti
|
|
|
98
125
|
return target === 'project' && !registered && !hook ? 'register-only' : 'refuse';
|
|
99
126
|
}
|
|
100
127
|
|
|
101
|
-
|
|
128
|
+
/**
|
|
129
|
+
* The Node a hook falls back to when Claude Code was started without the login
|
|
130
|
+
* PATH (SYNABUN_NODE): the one running SynaBun, which is known to run its hooks,
|
|
131
|
+
* when its path outlives this run. null on Windows (its programs get the user's
|
|
132
|
+
* PATH) and for a Node in a temporary place.
|
|
133
|
+
*/
|
|
134
|
+
export function hookNodePin({ execPath = process.execPath, platform = process.platform, env = process.env, writable } = {}) {
|
|
135
|
+
if (platform === 'win32' || typeof execPath !== 'string' || !isAbsolute(execPath)) return null;
|
|
136
|
+
if (isTransientPath(execPath, env) || isReadOnlyVolumePath(execPath, { platform, writable })) return null;
|
|
137
|
+
const temporary = [tmpdir(), '/tmp', '/private/tmp', '/private/var/folders', '/var/folders'];
|
|
138
|
+
if (temporary.some(dir => resolve(execPath).startsWith(`${resolve(dir)}${sep}`))) return null;
|
|
139
|
+
return execPath;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export function ensureHookRoot(settings, targetProjectPath, packageRoot = PACKAGE_ROOT, runtime = packagedRuntime(), { node = hookNodePin() } = {}) {
|
|
102
143
|
// A packaged application's command finds its own handlers, and its package
|
|
103
144
|
// root can be a mount that ends with the run.
|
|
104
145
|
if (runtime) return false;
|
|
105
146
|
// The checked-in template must not acquire a machine-specific env path.
|
|
106
147
|
if (targetProjectPath && resolve(targetProjectPath) === resolve(packageRoot)) return false;
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
148
|
+
let changed = false;
|
|
149
|
+
if (settings.env?.SYNABUN_HOOK_ROOT !== resolve(packageRoot)) {
|
|
150
|
+
settings.env = { ...settings.env, SYNABUN_HOOK_ROOT: resolve(packageRoot) };
|
|
151
|
+
changed = true;
|
|
152
|
+
}
|
|
153
|
+
// The user's own settings only (this machine's file): every session gets its env.
|
|
154
|
+
if (!targetProjectPath && node && settings.env?.SYNABUN_NODE !== node) {
|
|
155
|
+
settings.env = { ...settings.env, SYNABUN_NODE: node };
|
|
156
|
+
changed = true;
|
|
157
|
+
}
|
|
158
|
+
return changed;
|
|
110
159
|
}
|
|
111
160
|
|
|
112
|
-
export function sweepSettingsHooks(settings, targetProjectPath, stats = {}, packageRoot = PACKAGE_ROOT, runtime = packagedRuntime()) {
|
|
161
|
+
export function sweepSettingsHooks(settings, targetProjectPath, stats = {}, packageRoot = PACKAGE_ROOT, runtime = packagedRuntime(), { platform = process.platform, node = hookNodePin({ platform }) } = {}) {
|
|
113
162
|
if (!settings?.hooks || hookInstallBlocker(runtime)) return false;
|
|
114
163
|
let changed = false;
|
|
115
164
|
let ownsHooks = false;
|
|
116
165
|
for (const def of HOOK_SCRIPTS) {
|
|
117
166
|
const entries = settings.hooks[def.event];
|
|
118
167
|
if (!Array.isArray(entries)) continue;
|
|
119
|
-
const command = hookCommandString(def.script, targetProjectPath, runtime);
|
|
168
|
+
const command = hookCommandString(def.script, targetProjectPath, runtime, platform);
|
|
120
169
|
const matches = entries.flatMap(e => (e.hooks || []).filter(h => isSynaBunHookCommand(h.command, def.script)).map(h => ({ entry: e, hook: h })));
|
|
121
170
|
if (!matches.length) continue;
|
|
122
171
|
ownsHooks = true;
|
|
@@ -133,6 +182,111 @@ export function sweepSettingsHooks(settings, targetProjectPath, stats = {}, pack
|
|
|
133
182
|
settings.hooks[def.event] = [...rest, { matcher: def.matcher || '', hooks: [{ type: 'command', command, timeout: def.timeout }] }];
|
|
134
183
|
changed = true;
|
|
135
184
|
}
|
|
136
|
-
if (ownsHooks && ensureHookRoot(settings, targetProjectPath, packageRoot, runtime)) changed = true;
|
|
185
|
+
if (ownsHooks && ensureHookRoot(settings, targetProjectPath, packageRoot, runtime, { node })) changed = true;
|
|
137
186
|
return changed;
|
|
138
187
|
}
|
|
188
|
+
|
|
189
|
+
// ── What is really installed (Settings → Automations → Claude Code hooks) ────
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* What one settings file holds of SynaBun's handlers. `handlers`: one per
|
|
193
|
+
* HOOK_SCRIPTS entry, with `copies` (SynaBun handlers for that script in any
|
|
194
|
+
* form) and `current` (one of them is this machine's command, matcher and
|
|
195
|
+
* timeout); `events`: every handler of the event present; `installed` /
|
|
196
|
+
* `current` / `total` count handlers, `duplicates` the extra copies (each runs).
|
|
197
|
+
*/
|
|
198
|
+
export function hookInstallState(settings, { targetProjectPath, runtime = packagedRuntime(), platform = process.platform } = {}) {
|
|
199
|
+
const handlers = HOOK_SCRIPTS.map((def) => {
|
|
200
|
+
const entries = Array.isArray(settings?.hooks?.[def.event]) ? settings.hooks[def.event] : [];
|
|
201
|
+
const owned = entries.flatMap(entry => (Array.isArray(entry?.hooks) ? entry.hooks : [])
|
|
202
|
+
.filter(hook => isSynaBunHookCommand(hook?.command, def.script)).map(hook => ({ entry, hook })));
|
|
203
|
+
const command = hookCommandString(def.script, targetProjectPath, runtime, platform);
|
|
204
|
+
const current = owned.some(({ entry, hook }) => hook.command === command && (entry.matcher || '') === (def.matcher || '') && hook.timeout === def.timeout);
|
|
205
|
+
return { event: def.event, script: def.script, copies: owned.length, current };
|
|
206
|
+
});
|
|
207
|
+
const events = {};
|
|
208
|
+
for (const h of handlers) events[h.event] = (events[h.event] ?? true) && h.copies > 0;
|
|
209
|
+
return {
|
|
210
|
+
handlers,
|
|
211
|
+
events,
|
|
212
|
+
installed: handlers.filter(h => h.copies > 0).length,
|
|
213
|
+
current: handlers.filter(h => h.current).length,
|
|
214
|
+
duplicates: handlers.reduce((sum, h) => sum + Math.max(0, h.copies - 1), 0),
|
|
215
|
+
total: handlers.length,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/** The commands of SynaBun's handlers in a settings file, script by script (to compare two scopes). */
|
|
220
|
+
export function hookCommandsOf(settings) {
|
|
221
|
+
const out = {};
|
|
222
|
+
for (const def of HOOK_SCRIPTS) {
|
|
223
|
+
const entries = Array.isArray(settings?.hooks?.[def.event]) ? settings.hooks[def.event] : [];
|
|
224
|
+
const commands = entries.flatMap(entry => (Array.isArray(entry?.hooks) ? entry.hooks : []))
|
|
225
|
+
.map(hook => hook?.command).filter(command => isSynaBunHookCommand(command, def.script));
|
|
226
|
+
out[`${def.event}:${def.script}`] = [...new Set(commands)].sort();
|
|
227
|
+
}
|
|
228
|
+
return out;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Whether a project's SynaBun handlers run once next to the user's: Claude Code
|
|
233
|
+
* runs one copy of identical handlers from both files, and both of different
|
|
234
|
+
* ones. 'same' (nothing of SynaBun's there, or the same commands), 'different'.
|
|
235
|
+
*/
|
|
236
|
+
export function projectHooksAgree(userSettings, projectSettings) {
|
|
237
|
+
const user = hookCommandsOf(userSettings);
|
|
238
|
+
const project = hookCommandsOf(projectSettings);
|
|
239
|
+
for (const [key, commands] of Object.entries(project)) {
|
|
240
|
+
if (!commands.length) continue;
|
|
241
|
+
const mine = user[key] || [];
|
|
242
|
+
if (!mine.length) continue; // only the project runs it: once
|
|
243
|
+
if (commands.some(command => !mine.includes(command))) return 'different';
|
|
244
|
+
}
|
|
245
|
+
return 'same';
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/** Claude Code's own switches that stop SynaBun's handlers, in one settings file: the first that applies, or null. */
|
|
249
|
+
export function hooksSwitchedOff(settings, { managed = false } = {}) {
|
|
250
|
+
if (!settings || typeof settings !== 'object') return null;
|
|
251
|
+
if (settings.disableAllHooks === true) return 'disableAllHooks';
|
|
252
|
+
// Only managed settings can keep user and project hooks from running.
|
|
253
|
+
if (managed && settings.allowManagedHooksOnly === true) return 'allowManagedHooksOnly';
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/** Where Claude Code reads managed (organization) settings on this system. */
|
|
258
|
+
export function managedClaudeSettingsPath(platform = process.platform) {
|
|
259
|
+
if (platform === 'darwin') return '/Library/Application Support/ClaudeCode/managed-settings.json';
|
|
260
|
+
if (platform === 'win32') return 'C:\\Program Files\\ClaudeCode\\managed-settings.json';
|
|
261
|
+
return '/etc/claude-code/managed-settings.json';
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/** The PATH macOS gives a program it starts from the Dock, Finder or launchd. */
|
|
265
|
+
export const LAUNCHD_PATH = Object.freeze(['/usr/bin', '/bin', '/usr/sbin', '/sbin']);
|
|
266
|
+
|
|
267
|
+
function runnableFile(path) {
|
|
268
|
+
try {
|
|
269
|
+
if (!statSync(path).isFile()) return false;
|
|
270
|
+
accessSync(path, constants.X_OK);
|
|
271
|
+
return true;
|
|
272
|
+
} catch { return false; }
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* The Node a SynaBun hook would run with in a Claude Code started without the
|
|
277
|
+
* login PATH (the Dock, Finder, a desktop app, launchd): what the POSIX command
|
|
278
|
+
* tries after PATH, in its order. { path, via: 'SYNABUN_NODE' | 'folder' } or
|
|
279
|
+
* null (such a session would fail every hook). Windows: not asked (null).
|
|
280
|
+
*/
|
|
281
|
+
export function hookNodeWithoutPath({ env = {}, home = homedir(), platform = process.platform, runnable = runnableFile } = {}) {
|
|
282
|
+
if (platform === 'win32') return null;
|
|
283
|
+
// `command -v node` on the PATH such a launch has (a Linux distribution's own Node).
|
|
284
|
+
for (const dir of LAUNCHD_PATH) if (runnable(`${dir}/node`)) return { path: `${dir}/node`, via: 'PATH' };
|
|
285
|
+
for (const folder of HOOK_NODE_FOLDERS) {
|
|
286
|
+
const path = folder.startsWith('$HOME/') ? join(home, folder.slice('$HOME/'.length)) : folder;
|
|
287
|
+
if (runnable(path)) return { path, via: 'folder' };
|
|
288
|
+
}
|
|
289
|
+
const pinned = typeof env.SYNABUN_NODE === 'string' ? env.SYNABUN_NODE : '';
|
|
290
|
+
if (pinned && runnable(pinned)) return { path: pinned, via: 'SYNABUN_NODE' };
|
|
291
|
+
return null;
|
|
292
|
+
}
|
|
@@ -16,11 +16,18 @@ import { dirname, join, resolve } from 'node:path';
|
|
|
16
16
|
import { homedir } from 'node:os';
|
|
17
17
|
import {
|
|
18
18
|
mergeGeminiMcpConfig,
|
|
19
|
-
mergeOpenCodeMcpConfig,
|
|
20
19
|
} from '../neural-interface/lib/mcp-client-config.js';
|
|
20
|
+
import {
|
|
21
|
+
mcpServersOf,
|
|
22
|
+
opencodeConfigDir,
|
|
23
|
+
opencodeConfigFilePath,
|
|
24
|
+
opencodeMcpServerEntry,
|
|
25
|
+
setMcpServer,
|
|
26
|
+
} from '../neural-interface/lib/opencode-config.js';
|
|
21
27
|
import {
|
|
22
28
|
inspectCodexConfig,
|
|
23
29
|
upsertCodexMcpConfig,
|
|
30
|
+
upsertCodexMcpContent,
|
|
24
31
|
} from '../mcp-server/dist/services/codex-config-heal.js';
|
|
25
32
|
import { mcpStdioCommand } from './packaged-runtime.js';
|
|
26
33
|
|
|
@@ -60,11 +67,12 @@ export function auditAndRepairClientConfigs({
|
|
|
60
67
|
} = {}) {
|
|
61
68
|
if (!dataHome || !packageRoot) throw new Error('dataHome and packageRoot are required');
|
|
62
69
|
const definition = buildCanonicalMcpDefinition({ dataHome, packageRoot });
|
|
70
|
+
// Codex loads every SynaBun tool (its deferred catalog); a Codex runtime's own list is only its focus.
|
|
63
71
|
const codexDefinition = {
|
|
64
72
|
...definition,
|
|
65
73
|
env: {
|
|
66
74
|
...definition.env,
|
|
67
|
-
|
|
75
|
+
SYNABUN_TOOLS: 'all',
|
|
68
76
|
SYNABUN_TOOL_CATALOG_MODE: 'deferred',
|
|
69
77
|
},
|
|
70
78
|
};
|
|
@@ -105,11 +113,12 @@ export function auditAndRepairClientConfigs({
|
|
|
105
113
|
results.gemini = { exists: existsSync(geminiPath), connected: false, changed: false, path: geminiPath };
|
|
106
114
|
}
|
|
107
115
|
|
|
108
|
-
|
|
109
|
-
|
|
116
|
+
// OpenCode 2's global opencode.json (it never reads the config.json of OpenCode 1), its mcp.servers.SynaBun:
|
|
117
|
+
// the folder the rest of SynaBun writes (OPENCODE_CONFIG_DIR, else XDG_CONFIG_HOME's, else ~/.config/opencode).
|
|
118
|
+
const openCodePath = opencodeConfigFilePath(opencodeConfigDir({ home }));
|
|
110
119
|
const openCode = readJson(openCodePath);
|
|
111
|
-
if (openCode
|
|
112
|
-
const next =
|
|
120
|
+
if (mcpServersOf(openCode).SynaBun) {
|
|
121
|
+
const next = setMcpServer(structuredClone(openCode), 'SynaBun', opencodeMcpServerEntry(definition));
|
|
113
122
|
const changed = jsonChanged(openCode, next);
|
|
114
123
|
if (apply && changed) writeJsonAtomic(openCodePath, next);
|
|
115
124
|
results.opencode = { exists: true, connected: true, changed, path: openCodePath };
|
|
@@ -126,9 +135,9 @@ export function auditAndRepairClientConfigs({
|
|
|
126
135
|
upsertCodexMcpConfig(codexPath, codexDefinition);
|
|
127
136
|
changed = before !== readFileSync(codexPath, 'utf-8');
|
|
128
137
|
} else {
|
|
138
|
+
// What the repair would write, compared with what is there: a value like "all" is in most files anyway.
|
|
129
139
|
const content = readFileSync(codexPath, 'utf-8');
|
|
130
|
-
changed =
|
|
131
|
-
|| !Object.values(codexDefinition.env).every(value => content.includes(value));
|
|
140
|
+
changed = upsertCodexMcpContent(content, codexDefinition) !== content;
|
|
132
141
|
}
|
|
133
142
|
results.codex = { exists: true, connected: true, changed, path: codexPath, health: codexHealth };
|
|
134
143
|
} else {
|
package/lib/desktop-app.js
CHANGED
|
@@ -193,9 +193,15 @@ export async function runAppBackend({
|
|
|
193
193
|
// 3. Start, through the launcher (lock, supervisor record, background start).
|
|
194
194
|
let launcherPid = null;
|
|
195
195
|
let lastPhase = null;
|
|
196
|
+
let lastStep = null;
|
|
197
|
+
// A phase is said when it begins; the snapshot also says how far it is (its step, the bytes done), for the
|
|
198
|
+
// window's progress bar.
|
|
196
199
|
const reportPhase = (current) => {
|
|
197
|
-
if (!current?.phase
|
|
200
|
+
if (!current?.phase) return;
|
|
201
|
+
const step = current.phase === 'snapshot' ? `${current.detail?.step ?? ''}:${current.detail?.done ?? ''}:${current.detail?.state ?? ''}` : null;
|
|
202
|
+
if (current.phase === lastPhase && step === lastStep) return;
|
|
198
203
|
lastPhase = current.phase;
|
|
204
|
+
lastStep = step;
|
|
199
205
|
emit({ type: 'supervisor', phase: current.phase, detail: current.detail || null });
|
|
200
206
|
};
|
|
201
207
|
const reporter = () => ({
|
package/lib/external-tools.js
CHANGED
|
@@ -66,7 +66,7 @@ export const EXTERNAL_TOOLS = Object.freeze([
|
|
|
66
66
|
label: 'OpenCode',
|
|
67
67
|
command: 'opencode',
|
|
68
68
|
packages: Object.freeze(['opencode-ai']),
|
|
69
|
-
// (
|
|
69
|
+
// (No OpenCode client package ships: SynaBun speaks to OpenCode 2's serve itself, neural-interface/lib/opencode2-client.js.)
|
|
70
70
|
patterns: Object.freeze([new RegExp(`^opencode-${PLATFORMS}-`)]),
|
|
71
71
|
}),
|
|
72
72
|
Object.freeze({
|
|
@@ -11,6 +11,16 @@
|
|
|
11
11
|
// The launcher also leaves its stop message in the server's stderr log
|
|
12
12
|
// (recordLauncherFailure), because a detached launch has no terminal: the
|
|
13
13
|
// updater's relaunch reads it back to tell the user why SynaBun did not start.
|
|
14
|
+
//
|
|
15
|
+
// The snapshot is the backup service's upgrade snapshot (createUpgradeSnapshot):
|
|
16
|
+
// a consistent copy of each database (a clone where the file system clones)
|
|
17
|
+
// that passed SQLite's integrity check, stored uncompressed, checksummed as it
|
|
18
|
+
// is written and read back once. The desktop app takes it itself before it
|
|
19
|
+
// replaces its own files (lib/update-snapshot.js) and hands it over; this start
|
|
20
|
+
// uses it only when the data home is still what it was taken from
|
|
21
|
+
// (checkUpgradeSnapshotFreshness), whatever process wrote since: an AI tool's
|
|
22
|
+
// own MCP server may have saved a memory while the app swapped itself. Then it
|
|
23
|
+
// takes a new one, here, before the server and so any migration runs.
|
|
14
24
|
|
|
15
25
|
import { appendFileSync, existsSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
16
26
|
import { resolve } from 'node:path';
|
|
@@ -31,19 +41,41 @@ function readJson(path, fallback) {
|
|
|
31
41
|
/**
|
|
32
42
|
* Why the snapshot an in-app update handed over cannot stand in for a fresh
|
|
33
43
|
* one, or null when it can. It can only when the updater recorded that it
|
|
34
|
-
* installed exactly the version now launching,
|
|
35
|
-
*
|
|
36
|
-
*
|
|
44
|
+
* installed exactly the version now launching, the archive passes verification
|
|
45
|
+
* and its database copy passed SQLite's integrity check, and (the desktop app's
|
|
46
|
+
* snapshot, which records what it was taken from) nothing it protects changed
|
|
47
|
+
* since it was taken. A `prepared` update is not enough: its updater may never
|
|
48
|
+
* have run while the old server went on changing data.
|
|
37
49
|
*/
|
|
38
|
-
async function handoffSnapshotProblem({ handoff, version, backupService }) {
|
|
50
|
+
async function handoffSnapshotProblem({ handoff, version, backupService, dataHome }) {
|
|
39
51
|
if (handoff.status !== 'installed') return 'that update was prepared but never recorded as installed';
|
|
40
52
|
if (typeof handoff.target !== 'string' || handoff.target !== version) return 'it belongs to an update to another version';
|
|
41
53
|
if (typeof handoff.snapshotPath !== 'string' || !handoff.snapshotPath) return 'it names no snapshot';
|
|
42
54
|
if (!existsSync(handoff.snapshotPath)) return 'its snapshot file is gone';
|
|
43
55
|
try {
|
|
44
56
|
const service = await backupService();
|
|
45
|
-
|
|
46
|
-
|
|
57
|
+
let manifest;
|
|
58
|
+
// The desktop app read its snapshot back once, right after writing it, and
|
|
59
|
+
// recorded which file that was. The very same file, untouched since (device,
|
|
60
|
+
// inode, size, modification time), is not read a second time: only its
|
|
61
|
+
// manifest. Any other file is read in full.
|
|
62
|
+
if (handoff.verifiedStamp && typeof service.sameBackupFile === 'function' && typeof service.readBackupArchiveManifest === 'function'
|
|
63
|
+
&& service.sameBackupFile(handoff.snapshotPath, handoff.verifiedStamp)) {
|
|
64
|
+
manifest = await service.readBackupArchiveManifest(handoff.snapshotPath);
|
|
65
|
+
if (manifest?.verified !== true) return 'its file is not a verified snapshot';
|
|
66
|
+
} else {
|
|
67
|
+
manifest = await service.verifyBackupArchive(handoff.snapshotPath);
|
|
68
|
+
}
|
|
69
|
+
if (manifest?.kind !== 'pre-update') return 'its file is not a pre-update snapshot';
|
|
70
|
+
// The restore runs SQLite's integrity check on the database it puts back: a copy that never passed it is no copy.
|
|
71
|
+
if (manifest.database && manifest.database.integrity !== 'ok') return 'its database copy was not checked with SQLite\'s integrity check';
|
|
72
|
+
// The data as it is now, before anything of this version touches it. The desktop app's snapshot says what it was
|
|
73
|
+
// taken from; the npm updater's (taken by the old server right before it stopped) does not, and is used as before.
|
|
74
|
+
if (handoff.source === 'desktop' || manifest.inputs) {
|
|
75
|
+
if (typeof service.checkUpgradeSnapshotFreshness !== 'function') return 'this version cannot tell whether the data changed since';
|
|
76
|
+
const freshness = await service.checkUpgradeSnapshotFreshness({ dataHome, manifest, databasePath: resolve(dataHome, 'mcp-data', 'memory.db') });
|
|
77
|
+
if (!freshness?.fresh) return `the data changed after it was taken (${freshness?.reason || 'unknown'})`;
|
|
78
|
+
}
|
|
47
79
|
} catch (error) {
|
|
48
80
|
return `its snapshot did not pass verification (${error?.message || error})`;
|
|
49
81
|
}
|
|
@@ -94,7 +126,10 @@ export async function protectFirstLaunchAfterUpdate({
|
|
|
94
126
|
let snapshotPath = null;
|
|
95
127
|
if (pendingHandoff) {
|
|
96
128
|
info('Checking the snapshot taken by the updater...');
|
|
97
|
-
|
|
129
|
+
// The desktop app's splash says it: the copy made before the update is compared with the data (supervisor phase
|
|
130
|
+
// `snapshot`, step `check`).
|
|
131
|
+
progress({ step: 'check' });
|
|
132
|
+
const problem = await handoffSnapshotProblem({ handoff, version, backupService, dataHome });
|
|
98
133
|
if (problem) info(`The updater's snapshot is not used: ${problem}. Taking a new one.`);
|
|
99
134
|
else {
|
|
100
135
|
snapshotPath = handoff.snapshotPath;
|
|
@@ -106,11 +141,16 @@ export async function protectFirstLaunchAfterUpdate({
|
|
|
106
141
|
if (!snapshotPath) {
|
|
107
142
|
const folderPath = resolve(dataHome, 'backups', 'updates');
|
|
108
143
|
let service;
|
|
144
|
+
let lastPhase = null;
|
|
109
145
|
try {
|
|
110
146
|
info(`Protecting user state before first launch of v${version}...`);
|
|
111
147
|
progress({});
|
|
112
148
|
service = await backupService();
|
|
113
|
-
|
|
149
|
+
// The upgrade snapshot where the service has it (every SynaBun since 2026-10-21); the full backup otherwise.
|
|
150
|
+
const takeSnapshot = typeof service.createUpgradeSnapshot === 'function'
|
|
151
|
+
? options => service.createUpgradeSnapshot(options)
|
|
152
|
+
: options => service.createVerifiedBackup(options);
|
|
153
|
+
const snapshot = await takeSnapshot({
|
|
114
154
|
dataHome,
|
|
115
155
|
databasePath: resolve(dataHome, 'mcp-data', 'memory.db'),
|
|
116
156
|
folderPath,
|
|
@@ -118,17 +158,22 @@ export async function protectFirstLaunchAfterUpdate({
|
|
|
118
158
|
appVersion: manifest.lastAppVersion || null,
|
|
119
159
|
// Without this the checksum and archive phases run silently for minutes
|
|
120
160
|
// on a large data home, which users read as a hang and kill.
|
|
121
|
-
onProgress: ({ phase, files, bytes, skippedFiles, skippedBytes }) => {
|
|
122
|
-
progress({ step: phase, files, bytes, skippedFiles });
|
|
161
|
+
onProgress: ({ phase, files, bytes, skippedFiles, skippedBytes, done, total, method, state }) => {
|
|
162
|
+
progress({ step: phase, files, bytes, skippedFiles, done, total, ...(state ? { state } : {}) });
|
|
163
|
+
// Each phase is said once, when it begins; the steps within it only reach the progress bar.
|
|
164
|
+
if (phase === lastPhase) return;
|
|
165
|
+
lastPhase = phase;
|
|
123
166
|
const size = bytes ? ` (${(bytes / 1024 / 1024).toFixed(0)} MB)` : '';
|
|
124
167
|
if (phase === 'collect') {
|
|
125
168
|
info(` ${files} files to protect${size}`);
|
|
126
169
|
if (skippedFiles) {
|
|
127
170
|
info(` Skipping ${skippedFiles} generated media files (${(skippedBytes / 1024 / 1024).toFixed(0)} MB) — an upgrade never touches them`);
|
|
128
171
|
}
|
|
129
|
-
} else if (phase === '
|
|
130
|
-
else if (phase === '
|
|
172
|
+
} else if (phase === 'copy') info(` Copying the databases${method === 'clone' ? ' (a file system clone)' : ''}...`);
|
|
173
|
+
else if (phase === 'checksum') info(` Checksumming ${files} files...`);
|
|
174
|
+
else if (phase === 'archive') info(total ? ` Writing the archive (${(total / 1024 / 1024).toFixed(0)} MB)...` : ` Compressing${size}...`);
|
|
131
175
|
else if (phase === 'verify') info(' Verifying archive integrity...');
|
|
176
|
+
else if (phase === 'integrity') info(' Finishing SQLite\'s integrity check of the database copies...');
|
|
132
177
|
},
|
|
133
178
|
});
|
|
134
179
|
snapshotPath = snapshot.path;
|
package/lib/mcp-dist.js
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// What "the MCP server is built" means, in one place: mcp-server/dist/index.js and every module it imports by a
|
|
2
|
+
// relative path, transitively, are on disk. mcp-server/dist/ is build output that git ignores, yet a checkout can
|
|
3
|
+
// hold a tracked dist/index.js whose newer imports were never committed (they are ignored too): a server started
|
|
4
|
+
// from it fails to load /mcp. postinstall.js and setup.js build when this says no; the Neural Interface's restore,
|
|
5
|
+
// onboarding status and build route, the install details, the release and the packaged app's checks ask it too.
|
|
6
|
+
//
|
|
7
|
+
// The imports are read from the code itself, never from a comment or a string: a light tokenizer skips comments,
|
|
8
|
+
// strings, template literals and regular expressions, so a word "import" in a text cannot ask for a module that is
|
|
9
|
+
// not loaded (a packaged app has no compiler: a false "missing" there would stop it). Only plain fs and path:
|
|
10
|
+
// postinstall.js and setup.js import this on any Node.
|
|
11
|
+
|
|
12
|
+
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
13
|
+
import { dirname, join, relative, resolve, sep } from 'node:path';
|
|
14
|
+
|
|
15
|
+
const MAX_MODULES = 5000;
|
|
16
|
+
const MAX_MODULE_BYTES = 8 * 1024 * 1024;
|
|
17
|
+
const CODE_EXT = /\.(?:m?js|cjs)$/i;
|
|
18
|
+
// After one of these a `/` starts a regular expression, after anything else it divides.
|
|
19
|
+
const REGEX_AFTER_PUNCT = new Set(['(', ',', '=', ':', '[', '!', '&', '|', '?', '{', '}', ';', '+', '-', '*', '%', '<', '>', '~', '^']);
|
|
20
|
+
const REGEX_AFTER_WORD = new Set(['return', 'typeof', 'instanceof', 'in', 'of', 'new', 'delete', 'void', 'throw', 'case', 'do', 'else', 'yield', 'await']);
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The tokens of a module that matter for its imports: words, punctuation and string literals (their values), with
|
|
24
|
+
* comments, template literal text and regular expressions left out.
|
|
25
|
+
* @returns {{ t: 'word'|'punct'|'string', v: string }[]}
|
|
26
|
+
*/
|
|
27
|
+
export function codeTokens(text) {
|
|
28
|
+
const src = String(text ?? '');
|
|
29
|
+
const out = [];
|
|
30
|
+
const frames = []; // one per open `${` of a template literal: the brace depth that closes it
|
|
31
|
+
let depth = 0;
|
|
32
|
+
let i = 0;
|
|
33
|
+
const last = () => out[out.length - 1];
|
|
34
|
+
const regexAllowed = () => {
|
|
35
|
+
const p = last();
|
|
36
|
+
if (!p) return true;
|
|
37
|
+
if (p.t === 'punct') return REGEX_AFTER_PUNCT.has(p.v);
|
|
38
|
+
if (p.t === 'word') return REGEX_AFTER_WORD.has(p.v);
|
|
39
|
+
return false;
|
|
40
|
+
};
|
|
41
|
+
const template = () => {
|
|
42
|
+
// From just after a backtick (or a closing `}` of a `${`): to the closing backtick or the next `${`.
|
|
43
|
+
while (i < src.length) {
|
|
44
|
+
const c = src[i];
|
|
45
|
+
if (c === '\\') { i += 2; continue; }
|
|
46
|
+
if (c === '`') { i += 1; out.push({ t: 'string', v: '' }); return; }
|
|
47
|
+
if (c === '$' && src[i + 1] === '{') { i += 2; frames.push(depth); depth += 1; return; }
|
|
48
|
+
i += 1;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
while (i < src.length) {
|
|
52
|
+
const c = src[i];
|
|
53
|
+
if (c === '/' && src[i + 1] === '/') { const nl = src.indexOf('\n', i); i = nl < 0 ? src.length : nl; continue; }
|
|
54
|
+
if (c === '/' && src[i + 1] === '*') { const end = src.indexOf('*/', i + 2); i = end < 0 ? src.length : end + 2; continue; }
|
|
55
|
+
if (c === '\'' || c === '"') {
|
|
56
|
+
let j = i + 1; let v = '';
|
|
57
|
+
while (j < src.length && src[j] !== c && src[j] !== '\n') { if (src[j] === '\\') { v += src[j + 1] ?? ''; j += 2; continue; } v += src[j]; j += 1; }
|
|
58
|
+
out.push({ t: 'string', v });
|
|
59
|
+
i = j + 1;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (c === '`') { i += 1; template(); continue; }
|
|
63
|
+
if (c === '/' && regexAllowed()) {
|
|
64
|
+
let j = i + 1; let inClass = false;
|
|
65
|
+
while (j < src.length && src[j] !== '\n') {
|
|
66
|
+
const d = src[j];
|
|
67
|
+
if (d === '\\') { j += 2; continue; }
|
|
68
|
+
if (d === '[') inClass = true;
|
|
69
|
+
else if (d === ']') inClass = false;
|
|
70
|
+
else if (d === '/' && !inClass) break;
|
|
71
|
+
j += 1;
|
|
72
|
+
}
|
|
73
|
+
i = j + 1;
|
|
74
|
+
while (i < src.length && /[a-z]/i.test(src[i])) i += 1;
|
|
75
|
+
out.push({ t: 'punct', v: ')' }); // a value, as far as a following `/` is concerned
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (/[A-Za-z_$]/.test(c)) {
|
|
79
|
+
let j = i + 1;
|
|
80
|
+
while (j < src.length && /[\w$]/.test(src[j])) j += 1;
|
|
81
|
+
out.push({ t: 'word', v: src.slice(i, j) });
|
|
82
|
+
i = j;
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
if (/\s/.test(c)) { i += 1; continue; }
|
|
86
|
+
if (/[0-9]/.test(c)) { let j = i + 1; while (j < src.length && /[\w.]/.test(src[j])) j += 1; out.push({ t: 'word', v: src.slice(i, j) }); i = j; continue; }
|
|
87
|
+
if (c === '{') depth += 1;
|
|
88
|
+
if (c === '}') {
|
|
89
|
+
if (frames.length && depth - 1 === frames[frames.length - 1]) { depth -= 1; frames.pop(); i += 1; template(); continue; }
|
|
90
|
+
depth = Math.max(0, depth - 1);
|
|
91
|
+
}
|
|
92
|
+
out.push({ t: 'punct', v: c });
|
|
93
|
+
i += 1;
|
|
94
|
+
}
|
|
95
|
+
return out;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** The module specifiers a module loads: static imports, `export … from`, side-effect imports, `import('…')`. */
|
|
99
|
+
export function importSpecifiers(text) {
|
|
100
|
+
const tokens = codeTokens(text);
|
|
101
|
+
const found = [];
|
|
102
|
+
const at = (k) => tokens[k] || { t: 'end', v: '' };
|
|
103
|
+
for (let k = 0; k < tokens.length; k++) {
|
|
104
|
+
const tok = tokens[k];
|
|
105
|
+
if (tok.t !== 'word' || (tok.v !== 'import' && tok.v !== 'export')) continue;
|
|
106
|
+
if (k > 0 && at(k - 1).t === 'punct' && at(k - 1).v === '.') continue; // obj.import
|
|
107
|
+
const next = at(k + 1);
|
|
108
|
+
if (tok.v === 'import') {
|
|
109
|
+
if (next.t === 'punct' && next.v === '.') continue; // import.meta
|
|
110
|
+
if (next.t === 'punct' && next.v === '(') { if (at(k + 2).t === 'string' && at(k + 3).v === ')') found.push(at(k + 2).v); continue; }
|
|
111
|
+
if (next.t === 'string') { found.push(next.v); continue; }
|
|
112
|
+
}
|
|
113
|
+
// import a, { b as c } from '…'; import * as d from '…'; export { e } from '…'; export * from '…'
|
|
114
|
+
let j = k + 1;
|
|
115
|
+
while (j < tokens.length) {
|
|
116
|
+
const x = at(j);
|
|
117
|
+
if (x.t === 'word' && x.v === 'from') break;
|
|
118
|
+
if (x.t === 'word' || (x.t === 'punct' && (x.v === ',' || x.v === '{' || x.v === '}' || x.v === '*'))) { j += 1; continue; }
|
|
119
|
+
j = -1;
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
if (j > k + 1 && at(j).v === 'from' && at(j + 1).t === 'string') {
|
|
123
|
+
if (tok.v === 'export' && !(next.v === '*' || next.v === '{')) continue;
|
|
124
|
+
found.push(at(j + 1).v);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return found;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const posix = (p) => p.split(sep).join('/');
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Every module dist/index.js needs that is not on disk (or cannot be read), as paths from the package root.
|
|
134
|
+
* Modules inside mcp-server/dist are followed; one outside it (the package's lib/) is only looked for.
|
|
135
|
+
* @param {string} packageRoot
|
|
136
|
+
* @param {{ exists?: (p: string) => boolean, readText?: (p: string) => string, entry?: string }} [o]
|
|
137
|
+
* @returns {{ complete: boolean, missing: string[], checked: number }}
|
|
138
|
+
*/
|
|
139
|
+
export function mcpDistMissing(packageRoot, { exists = existsSync, readText = null, entry = 'index.js' } = {}) {
|
|
140
|
+
const root = resolve(packageRoot);
|
|
141
|
+
const dist = join(root, 'mcp-server', 'dist');
|
|
142
|
+
const read = readText || ((p) => {
|
|
143
|
+
const st = statSync(p);
|
|
144
|
+
if (!st.isFile()) throw new Error('not a regular file');
|
|
145
|
+
if (st.size > MAX_MODULE_BYTES) return null;
|
|
146
|
+
return readFileSync(p, 'utf8');
|
|
147
|
+
});
|
|
148
|
+
const missing = new Set();
|
|
149
|
+
const seen = new Set();
|
|
150
|
+
const queue = [join(dist, entry)];
|
|
151
|
+
let checked = 0;
|
|
152
|
+
while (queue.length && checked < MAX_MODULES) {
|
|
153
|
+
const file = queue.shift();
|
|
154
|
+
if (seen.has(file)) continue;
|
|
155
|
+
seen.add(file);
|
|
156
|
+
if (!exists(file)) { missing.add(posix(relative(root, file))); continue; }
|
|
157
|
+
const inside = file.startsWith(dist + sep);
|
|
158
|
+
if (!inside || !CODE_EXT.test(file)) continue;
|
|
159
|
+
let text;
|
|
160
|
+
try { text = read(file); } catch { missing.add(posix(relative(root, file))); continue; }
|
|
161
|
+
checked += 1;
|
|
162
|
+
if (text === null) continue; // too large to read here: present, not followed
|
|
163
|
+
for (const spec of importSpecifiers(text)) {
|
|
164
|
+
if (!spec.startsWith('./') && !spec.startsWith('../')) continue;
|
|
165
|
+
const target = resolve(dirname(file), spec.split(/[?#]/)[0]);
|
|
166
|
+
if (!seen.has(target)) queue.push(target);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const list = [...missing].sort();
|
|
170
|
+
return { complete: list.length === 0, missing: list, checked };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/** Whether the MCP server is built: dist/index.js and everything it imports are there. */
|
|
174
|
+
export function mcpDistBuilt(packageRoot, options) {
|
|
175
|
+
return mcpDistMissing(packageRoot, options).complete;
|
|
176
|
+
}
|