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
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// The Neural Interface offers only the 3D memory map. The 2D implementation is deprecated, kept on disk.
|
|
2
|
+
import { KEYS } from './constants.js';
|
|
3
|
+
|
|
4
|
+
export function resolveViewVariant(_requested) { return '3d'; }
|
|
5
|
+
|
|
6
|
+
/** Preserve other URL state, including memory anchors, when retiring a 2D address. Shared with the server. */
|
|
7
|
+
export function normalizeViewUrl(input) {
|
|
8
|
+
const url = new URL(input, 'http://localhost');
|
|
9
|
+
if (url.pathname.toLowerCase() === '/index2d.html') url.pathname = '/';
|
|
10
|
+
if (url.searchParams.has('variant')) url.searchParams.set('variant', resolveViewVariant(url.searchParams.get('variant')));
|
|
11
|
+
const hash = url.hash.slice(1);
|
|
12
|
+
if (hash === '2d') url.hash = '3d';
|
|
13
|
+
else {
|
|
14
|
+
const start = hash.includes('?') ? hash.indexOf('?') + 1 : 0;
|
|
15
|
+
const params = new URLSearchParams(hash.slice(start));
|
|
16
|
+
if (params.has('variant')) {
|
|
17
|
+
params.set('variant', resolveViewVariant(params.get('variant')));
|
|
18
|
+
url.hash = hash.slice(0, start) + params.toString();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return url.pathname + url.search + url.hash;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Optional legacy config fields are normalized without changing Focus Mode, glass or accent settings. */
|
|
25
|
+
export function normalizeViewConfig(config) {
|
|
26
|
+
if (!config || typeof config !== 'object' || Array.isArray(config)) return config;
|
|
27
|
+
const next = { ...config };
|
|
28
|
+
for (const key of ['variant', 'viewVariant']) {
|
|
29
|
+
if (Object.hasOwn(next, key)) next[key] = resolveViewVariant(next[key]);
|
|
30
|
+
}
|
|
31
|
+
return next;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Retain archived 2D coordinates, but never reinterpret their x/y positions as 3D positions. */
|
|
35
|
+
export function normalizeWorkspaceVariant(workspace) {
|
|
36
|
+
if (workspace?.variant !== '2d') return workspace;
|
|
37
|
+
return {
|
|
38
|
+
...workspace,
|
|
39
|
+
variant: '3d',
|
|
40
|
+
nodePositions2d: workspace.nodePositions2d || workspace.nodePositions || {},
|
|
41
|
+
nodePositions3d: workspace.nodePositions3d || {},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Rewrite persisted preferences at boot, in both the hydrated server store and any browser-local copy. */
|
|
46
|
+
export function migrateViewPreferences(...stores) {
|
|
47
|
+
for (const store of new Set(stores.filter(Boolean))) {
|
|
48
|
+
// A refused read/write or malformed old value must not stop the supported view from booting.
|
|
49
|
+
try {
|
|
50
|
+
if (store.getItem(KEYS.VIEW_VARIANT) !== '3d') store.setItem(KEYS.VIEW_VARIANT, '3d');
|
|
51
|
+
} catch {}
|
|
52
|
+
for (const [key, normalize] of [
|
|
53
|
+
[KEYS.INTERFACE_CONFIG, normalizeViewConfig],
|
|
54
|
+
[KEYS.WORKSPACES, (list) => Array.isArray(list) ? list.map(normalizeWorkspaceVariant) : list],
|
|
55
|
+
]) {
|
|
56
|
+
try {
|
|
57
|
+
const raw = store.getItem(key);
|
|
58
|
+
if (!raw) continue;
|
|
59
|
+
const value = JSON.parse(raw);
|
|
60
|
+
const next = normalize(value);
|
|
61
|
+
if (JSON.stringify(next) !== JSON.stringify(value)) store.setItem(key, JSON.stringify(next));
|
|
62
|
+
} catch {}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return resolveViewVariant();
|
|
66
|
+
}
|
|
@@ -89,7 +89,7 @@ export const BRAIN_COPY = Object.freeze({
|
|
|
89
89
|
effortDefault: 'Default effort',
|
|
90
90
|
saved: 'WhatsApp model saved. It applies from your next message.',
|
|
91
91
|
});
|
|
92
|
-
const BRAIN_PROVIDER_LABELS = Object.freeze({ 'claude-code': 'Claude', codex: 'Codex', opencode: 'OpenCode' });
|
|
92
|
+
const BRAIN_PROVIDER_LABELS = Object.freeze({ 'claude-code': 'Claude', codex: 'Codex', opencode: 'OpenCode', antigravity: 'Antigravity' });
|
|
93
93
|
export function brainProviderLabel(provider) { return BRAIN_PROVIDER_LABELS[provider] || String(provider || ''); }
|
|
94
94
|
/**
|
|
95
95
|
* The stored choice of a status: { provider, model, effort } or null (same as
|
|
@@ -242,7 +242,7 @@ export const HELP = Object.freeze({
|
|
|
242
242
|
'Stuck on "Reconnecting"? Check this computer\'s internet connection, then press Reconnect now.',
|
|
243
243
|
'Voice notes not transcribed? This computer needs whisper.cpp, its speech model and FFmpeg, which you install yourself; the line under "Transcribe voice notes" says what is missing.',
|
|
244
244
|
],
|
|
245
|
-
browserTools: 'Not the same as the WhatsApp browser tools. The
|
|
245
|
+
browserTools: 'Not the same as the WhatsApp browser tools. The browser_whatsapp tool group lets agents read WhatsApp Web in SynaBun\'s browser; this tab is you chatting with SynaBun from your phone. They do not share a session.',
|
|
246
246
|
uninstall: 'Uninstalling SynaBun does not unlink WhatsApp. Use Unlink or Remove here first, or log SynaBun out under WhatsApp → Settings → Linked devices.',
|
|
247
247
|
});
|
|
248
248
|
|
|
@@ -399,7 +399,7 @@ export function waView(status, { now = Date.now() } = {}) {
|
|
|
399
399
|
}
|
|
400
400
|
case 'connected': {
|
|
401
401
|
const who = accountLine(s);
|
|
402
|
-
// A Codex / OpenCode brain holds the conversation at read-only whatever the level.
|
|
402
|
+
// A Codex / OpenCode / Antigravity brain holds the conversation at read-only whatever the level.
|
|
403
403
|
const applies = s.brainLimit?.provider ? say('view.connected.readOnlyBrain', 'Read-only ({brain} brain)', { brain: s.brainLimit.label || s.brainLimit.provider }) : level;
|
|
404
404
|
return view('ok', say('view.connected.title', 'Connected'), [mode, who, applies].filter(Boolean).join(' · '), { primary: button('open-conversation', say('button.openConversation', 'Open conversation')), secondary: button('test', say('button.test', 'Send a test message')), step: 'done', pane: 'connected', nav: 'connected' });
|
|
405
405
|
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════
|
|
2
|
+
// WHITEBOARD-LIST — nesting levels of a list card (DOM-free)
|
|
3
|
+
// ═══════════════════════════════════════════
|
|
4
|
+
//
|
|
5
|
+
// A list element keeps its bullets as `items: string[]`, as every board always has, and, only while some bullet
|
|
6
|
+
// is nested, `levels: number[]` beside them: levels[i] is how deep items[i] sits, 0 = top level. A list without
|
|
7
|
+
// `levels` (every board saved before nesting existed) reads as all level 0, and a reader that does not know
|
|
8
|
+
// `levels` still shows every bullet, flat. Callers may also hand items over as { text, level } objects; they are
|
|
9
|
+
// stored as the two arrays. Every writer keeps three rules: the first item is level 0, an item sits at most one
|
|
10
|
+
// level deeper than the item above it, and no item is deeper than WB_LIST_MAX_LEVEL.
|
|
11
|
+
//
|
|
12
|
+
// No imports: ui-whiteboard.js (the board), server.js (whiteboard_add / whiteboard_update) and node --test load it.
|
|
13
|
+
// mcp-server/src/services/whiteboard-geometry.ts reads the same format for the MCP tools.
|
|
14
|
+
|
|
15
|
+
export const WB_LIST_MAX_LEVEL = 4;
|
|
16
|
+
|
|
17
|
+
/** Level of one value: a whole number from 0 to WB_LIST_MAX_LEVEL (anything else is 0, more is the maximum). */
|
|
18
|
+
function levelOf(value) {
|
|
19
|
+
const n = Math.floor(Number(value));
|
|
20
|
+
return Number.isFinite(n) && n > 0 ? Math.min(n, WB_LIST_MAX_LEVEL) : 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Text of one stored entry: a string, or the { text, level } form. */
|
|
24
|
+
export function listItemText(item) {
|
|
25
|
+
if (typeof item === 'string') return item;
|
|
26
|
+
if (item && typeof item === 'object') return item.text == null ? '' : String(item.text);
|
|
27
|
+
return item == null ? '' : String(item);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** `count` levels that keep the rules, read from `levels` (missing entries are 0). */
|
|
31
|
+
export function fitListLevels(levels, count) {
|
|
32
|
+
const out = [];
|
|
33
|
+
let above = -1;
|
|
34
|
+
for (let i = 0; i < count; i++) {
|
|
35
|
+
const level = Math.min(levelOf(Array.isArray(levels) ? levels[i] : 0), above + 1);
|
|
36
|
+
out.push(level);
|
|
37
|
+
above = level;
|
|
38
|
+
}
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* A list's items in either form → { items: string[], levels: number[] } (levels always as long as items, keeping
|
|
44
|
+
* the rules). A plain string is level `levels[i]` (0 when there is no such entry); a { text, level } object's own
|
|
45
|
+
* level wins over `levels[i]`.
|
|
46
|
+
*/
|
|
47
|
+
export function readListItems(items, levels) {
|
|
48
|
+
const list = Array.isArray(items) ? items : [];
|
|
49
|
+
const texts = list.map(listItemText);
|
|
50
|
+
const wanted = list.map((item, i) => (item && typeof item === 'object' && item.level !== undefined
|
|
51
|
+
? item.level
|
|
52
|
+
: (Array.isArray(levels) ? levels[i] : 0)));
|
|
53
|
+
return { items: texts, levels: fitListLevels(wanted, texts.length) };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** True when some level is above 0 (only then is `levels` stored). */
|
|
57
|
+
export function hasNestedLevels(levels) {
|
|
58
|
+
return Array.isArray(levels) && levels.some(level => level > 0);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Store items + levels on a list element: `items` always, `levels` only while something is nested (removed
|
|
63
|
+
* otherwise, so a flat list is stored exactly as before). Always new arrays, never an edit in place: copies of
|
|
64
|
+
* an element (undo entries, the clipboard, a duplicate) share the arrays of the original.
|
|
65
|
+
*/
|
|
66
|
+
export function writeListItems(el, items, levels) {
|
|
67
|
+
const read = readListItems(items, levels);
|
|
68
|
+
el.items = read.items;
|
|
69
|
+
if (hasNestedLevels(read.levels)) el.levels = read.levels;
|
|
70
|
+
else delete el.levels;
|
|
71
|
+
return el;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The `items` / `levels` fields of an update to a list, made to keep the rules. Items sent without levels are
|
|
76
|
+
* read in their own form (a plain string is level 0, an object carries its level): replacing the items of a
|
|
77
|
+
* nested list with plain strings flattens it. Levels sent alone apply to the items the list already has.
|
|
78
|
+
* `levels` comes back as null when nothing is nested (the update then removes it).
|
|
79
|
+
*/
|
|
80
|
+
export function normalizeListUpdate(currentItems, patch) {
|
|
81
|
+
if (!patch || typeof patch !== 'object') return patch;
|
|
82
|
+
const hasItems = Object.hasOwn(patch, 'items');
|
|
83
|
+
const hasLevels = Object.hasOwn(patch, 'levels');
|
|
84
|
+
if (!hasItems && !hasLevels) return patch;
|
|
85
|
+
const read = hasItems ? readListItems(patch.items, patch.levels) : readListItems(currentItems, patch.levels);
|
|
86
|
+
const out = { ...patch, levels: hasNestedLevels(read.levels) ? read.levels : null };
|
|
87
|
+
if (hasItems) out.items = read.items;
|
|
88
|
+
return out;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** End (exclusive) of the item at `index` and its sub-items: the items right after it that sit deeper. */
|
|
92
|
+
export function listSubtreeEnd(levels, index) {
|
|
93
|
+
let end = index + 1;
|
|
94
|
+
while (end < levels.length && levels[end] > levels[index]) end++;
|
|
95
|
+
return end;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Whether the item at `index` can go one level deeper: never the first, never more than one level deeper than
|
|
99
|
+
* the item above it, and neither it nor a sub-item of it past the maximum. */
|
|
100
|
+
export function canIndentListItem(levels, index) {
|
|
101
|
+
if (!Array.isArray(levels) || index <= 0 || index >= levels.length) return false;
|
|
102
|
+
if (levels[index] > levels[index - 1]) return false;
|
|
103
|
+
const deepest = Math.max(...levels.slice(index, listSubtreeEnd(levels, index)));
|
|
104
|
+
return deepest < WB_LIST_MAX_LEVEL;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Levels with the item at `index` one level deeper, its sub-items with it (they stay its sub-items), or null
|
|
108
|
+
* when it cannot go deeper. */
|
|
109
|
+
export function indentListItem(levels, index) {
|
|
110
|
+
if (!canIndentListItem(levels, index)) return null;
|
|
111
|
+
const next = levels.slice();
|
|
112
|
+
for (let i = index, end = listSubtreeEnd(levels, index); i < end; i++) next[i] += 1;
|
|
113
|
+
return fitListLevels(next, next.length);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Levels with the item at `index` one level shallower, its sub-items with it, or null when it is at the top
|
|
117
|
+
* level. The items after them keep their level (one that was its sibling becomes its sub-item, as in a flat
|
|
118
|
+
* outline nothing is reordered). */
|
|
119
|
+
export function outdentListItem(levels, index) {
|
|
120
|
+
if (!Array.isArray(levels) || index < 0 || index >= levels.length || levels[index] <= 0) return null;
|
|
121
|
+
const next = levels.slice();
|
|
122
|
+
for (let i = index, end = listSubtreeEnd(levels, index); i < end; i++) next[i] -= 1;
|
|
123
|
+
return fitListLevels(next, next.length);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Bullet and number styles per level, in the order browsers nest them: the level-0 style is what a flat list
|
|
127
|
+
// always showed (a disc, a decimal number); deeper levels cycle.
|
|
128
|
+
export const UNORDERED_STYLES = ['disc', 'circle', 'square'];
|
|
129
|
+
export const ORDERED_STYLES = ['decimal', 'lower-alpha', 'lower-roman'];
|
|
130
|
+
const BULLET_GLYPHS = { disc: '•', circle: '◦', square: '▪' };
|
|
131
|
+
|
|
132
|
+
/** The list-style name of a level (the CSS in styles.css uses the same cycle). */
|
|
133
|
+
export function listStyleForLevel(level, ordered) {
|
|
134
|
+
const styles = ordered ? ORDERED_STYLES : UNORDERED_STYLES;
|
|
135
|
+
return styles[levelOf(level) % styles.length];
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function toRoman(n) {
|
|
139
|
+
const table = [[1000, 'm'], [900, 'cm'], [500, 'd'], [400, 'cd'], [100, 'c'], [90, 'xc'], [50, 'l'], [40, 'xl'], [10, 'x'], [9, 'ix'], [5, 'v'], [4, 'iv'], [1, 'i']];
|
|
140
|
+
let out = '';
|
|
141
|
+
for (const [value, digits] of table) while (n >= value) { out += digits; n -= value; }
|
|
142
|
+
return out;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function toAlpha(n) {
|
|
146
|
+
let out = '';
|
|
147
|
+
while (n > 0) { n -= 1; out = String.fromCharCode(97 + (n % 26)) + out; n = Math.floor(n / 26); }
|
|
148
|
+
return out;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** A counter value in one of the ordered styles: 1 → "1", "a", "i". */
|
|
152
|
+
export function formatListCounter(n, style) {
|
|
153
|
+
if (style === 'lower-alpha') return toAlpha(n);
|
|
154
|
+
if (style === 'lower-roman') return toRoman(n);
|
|
155
|
+
return String(n);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* The marker drawn before each item: a bullet glyph per level, or the item's number in its level's style followed
|
|
160
|
+
* by "." (numbering restarts under every item above, as nested ordered lists do).
|
|
161
|
+
*/
|
|
162
|
+
export function listMarkers(levels, ordered) {
|
|
163
|
+
const counters = [];
|
|
164
|
+
return (Array.isArray(levels) ? levels : []).map((raw) => {
|
|
165
|
+
const level = levelOf(raw);
|
|
166
|
+
const style = listStyleForLevel(level, ordered);
|
|
167
|
+
if (!ordered) return BULLET_GLYPHS[style];
|
|
168
|
+
counters.length = level + 1;
|
|
169
|
+
counters[level] = (counters[level] || 0) + 1;
|
|
170
|
+
return `${formatListCounter(counters[level], style)}.`;
|
|
171
|
+
});
|
|
172
|
+
}
|
|
@@ -47,6 +47,7 @@ export const WORKER_END_COPY = Object.freeze({
|
|
|
47
47
|
reasonMaxTurns: 'The run reached its turn limit.',
|
|
48
48
|
reasonIdle: 'The worker waited for a follow-up that did not come, and closed.',
|
|
49
49
|
reasonRestart: 'The server restarted while the run was open.',
|
|
50
|
+
reasonRestartNotResumed: 'The server restarted while the run was open, and it could not continue: {reason}',
|
|
50
51
|
reasonKillAll: 'Stopped together with every other run.',
|
|
51
52
|
reasonCleared: 'The run\'s state was removed.',
|
|
52
53
|
reasonOther: 'Stopped ({reason}).',
|
|
@@ -61,8 +62,9 @@ export const WORKER_END_CLASS = 'worker-end-card';
|
|
|
61
62
|
/** The run states (runtime and dispatcher alike) after which nothing more happens. */
|
|
62
63
|
export const TERMINAL_STATES = new Set(['completed', 'failed', 'stopped', 'interrupted']);
|
|
63
64
|
const TERMINAL = TERMINAL_STATES;
|
|
64
|
-
// Dispatcher states in which a turn is in progress (or about to be): the card waits.
|
|
65
|
-
|
|
65
|
+
// Dispatcher states in which a turn is in progress (or about to be): the card waits. A run a server restart cut off
|
|
66
|
+
// (suspended) and one the next start resumes (resuming) are not over either.
|
|
67
|
+
const WORKING = new Set(['queued', 'awaiting_route', 'starting', 'running', 'awaiting_permission', 'suspended', 'resuming']);
|
|
66
68
|
const SUMMARY_CHARS = 320;
|
|
67
69
|
|
|
68
70
|
/** A WORKER_END_COPY sentence with its `{params}` filled in: the translator when the page gives none. */
|
|
@@ -85,6 +87,7 @@ export function isRunWorking(run, dispatch = null) {
|
|
|
85
87
|
if (TERMINAL.has(state) || TERMINAL.has(String(run?.status || ''))) return false;
|
|
86
88
|
if (state) return WORKING.has(state);
|
|
87
89
|
const status = String(run?.status || '');
|
|
90
|
+
if (status === 'suspended') return true;
|
|
88
91
|
if (status !== 'starting' && status !== 'running') return false;
|
|
89
92
|
return run?.turnState !== 'idle' && run?.turnState !== 'terminal';
|
|
90
93
|
}
|
|
@@ -159,7 +162,7 @@ function stopReason(reason, t) {
|
|
|
159
162
|
case 'budget_share': return t('reasonBudgetShare');
|
|
160
163
|
case 'max_turns': return t('reasonMaxTurns');
|
|
161
164
|
case 'idle_timeout': return t('reasonIdle');
|
|
162
|
-
case 'server_restart': case 'server_shutdown': return t('reasonRestart');
|
|
165
|
+
case 'server_restart': case 'server_shutdown': case 'resume_failed': return t('reasonRestart');
|
|
163
166
|
case 'kill_all': return t('reasonKillAll');
|
|
164
167
|
case 'state_removed': case 'state_inactive': return t('reasonCleared');
|
|
165
168
|
case '': return '';
|
|
@@ -226,6 +229,10 @@ export function workerEndView(run, dispatch = null, { t = fillWorkerEndCopy, bus
|
|
|
226
229
|
} else {
|
|
227
230
|
kind = endState === 'interrupted' ? 'interrupted' : 'stopped';
|
|
228
231
|
detail = stopReason(dispatch?.completionReason || run?.stoppedReason || '', t);
|
|
232
|
+
// A Claude Code worker the server could not resume after a restart says why (lib/worker-resume.js; a resume that
|
|
233
|
+
// failed to start has the reason resume_failed and the error).
|
|
234
|
+
const notResumed = dispatch?.resumeRefused || (dispatch?.completionReason === 'resume_failed' ? (dispatch?.error || run?.error || '') : '');
|
|
235
|
+
if (kind === 'interrupted' && notResumed) detail = t('reasonRestartNotResumed', { reason: plain(notResumed, 200) });
|
|
229
236
|
}
|
|
230
237
|
|
|
231
238
|
if (kind === 'complete' || kind === 'blocked') detail = plain(result?.summary || '');
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Bridge run state to each provider's existing question card. No card markup lives here.
|
|
2
|
+
import { t } from './i18n.js';
|
|
3
|
+
|
|
4
|
+
export function syncWorkerQuestions(holder, run, { open, close }) {
|
|
5
|
+
const previous = holder._workerQuestions || new Map();
|
|
6
|
+
const next = new Map((run.pending || []).filter((p) => p.kind === 'question' || p.protocol?.provider === 'codex').map((p) => [p.requestId, p]));
|
|
7
|
+
// Set before rendering: callbacks can synchronously read the current request.
|
|
8
|
+
holder._workerQuestions = next;
|
|
9
|
+
for (const [id, pending] of previous) if (!next.has(id)) close(id, pending);
|
|
10
|
+
for (const [id, pending] of next) if (!previous.has(id)) open(id, pending);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export async function answerWorkerQuestion(runId, requestId, response) {
|
|
14
|
+
const res = await fetch(`/api/assistant/runs/${encodeURIComponent(runId)}/permission`, {
|
|
15
|
+
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
16
|
+
body: JSON.stringify({ ...response, requestId, origin: 'user' }),
|
|
17
|
+
});
|
|
18
|
+
const body = await res.json().catch(() => ({}));
|
|
19
|
+
// Another surface or Stop consumed it first. This card must clear too.
|
|
20
|
+
if (res.status === 409 && ['PERMISSION_ALREADY_RESOLVED', 'NO_PENDING_REQUEST'].includes(body.code)) return { stale: true };
|
|
21
|
+
if (!res.ok || body.ok === false) throw new Error(body.error || t('workerQuestion.deliveryFailed'));
|
|
22
|
+
return body;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Claude's native card shows one tool call at a time (each call may contain several questions). */
|
|
26
|
+
export function syncWorkerQuestionQueue(holder, run, hooks) {
|
|
27
|
+
syncWorkerQuestions(holder, run, { open() {}, close() {} });
|
|
28
|
+
const next = holder._workerQuestions.keys().next().value || null;
|
|
29
|
+
const previous = holder._workerQuestionActiveId || null;
|
|
30
|
+
if (next === previous) return;
|
|
31
|
+
holder._workerQuestionActiveId = next;
|
|
32
|
+
if (previous) hooks.close(previous);
|
|
33
|
+
if (next) hooks.open(next, holder._workerQuestions.get(next));
|
|
34
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Shared provider-panel status. A suspension still owns the tab, but is not working. */
|
|
2
|
+
export function workerRestart(run) {
|
|
3
|
+
const suspended = run?.status === 'suspended';
|
|
4
|
+
const resumes = Number(run?.resumes) || 0;
|
|
5
|
+
return {
|
|
6
|
+
suspended,
|
|
7
|
+
active: suspended || ['starting', 'running'].includes(run?.status),
|
|
8
|
+
key: suspended ? 'workerRestart.suspended' : resumes ? 'workerRestart.resumed' : null,
|
|
9
|
+
stamp: suspended ? `suspended:${run.suspendedAt || ''}` : `resumed:${resumes}`,
|
|
10
|
+
resumes,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
html .sp-sidepanel { position:fixed; inset:0 !important; width:100% !important; height:100% !important;
|
|
11
11
|
min-width:0 !important; max-width:none !important; transform:none !important; border:0; border-radius:0; box-shadow:none; }
|
|
12
12
|
.sp-window-toggle, .sp-window-move, .sp-window-resize, .sp-dock-resize { display:none !important; }
|
|
13
|
-
.cp-header-actions, .cxp-actions, .ocpv2-actions { display:none !important; }
|
|
13
|
+
.cp-header-actions, .cxp-actions, .ocpv2-actions, .agy-actions { display:none !important; }
|
|
14
14
|
#term-minimized-tray { position:fixed; right:8px; top:45px; z-index:20000; }
|
|
15
15
|
</style>
|
|
16
16
|
</head>
|
|
17
|
-
<body><div id="term-minimized-tray"></div><script type="module" src="/shared/ui-sidepanel-session-entry.js"></script></body>
|
|
17
|
+
<body><div id="term-minimized-tray"></div><script type="module" src="/shared/page-session.js"></script><script type="module" src="/shared/ui-sidepanel-session-entry.js"></script></body>
|
|
18
18
|
</html>
|
|
@@ -58,7 +58,8 @@ export function drawBackground(ctx, time, w, h) {
|
|
|
58
58
|
const maxDim = Math.max(w, h);
|
|
59
59
|
_bgGrad = ctx.createRadialGradient(w / 2, h / 2, 0, w / 2, h / 2, maxDim * 0.7);
|
|
60
60
|
_bgGrad.addColorStop(0, '#0e1218');
|
|
61
|
-
|
|
61
|
+
// The app frame's interior (styles.css --frame-surface): the card's edge reads as one surface with the 3D map's
|
|
62
|
+
_bgGrad.addColorStop(1, '#07080b');
|
|
62
63
|
_bgGradW = w;
|
|
63
64
|
_bgGradH = h;
|
|
64
65
|
}
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
import { state, emit, on } from '../../shared/state.js';
|
|
9
9
|
import { getAllCards } from './graph.js';
|
|
10
|
+
import { frameRect } from '../../shared/app-frame.js';
|
|
11
|
+
import { placeMenu } from '../../shared/context-menu-logic.js';
|
|
10
12
|
|
|
11
13
|
const $ = (id) => document.getElementById(id);
|
|
12
14
|
|
|
@@ -51,9 +53,13 @@ export function showContextMenu(node, event) {
|
|
|
51
53
|
if (!_contextMenu) return;
|
|
52
54
|
|
|
53
55
|
_contextMenuNode = node;
|
|
54
|
-
_contextMenu.style.left = event.clientX + 'px';
|
|
55
|
-
_contextMenu.style.top = event.clientY + 'px';
|
|
56
56
|
_contextMenu.classList.add('open');
|
|
57
|
+
// At the pointer, flipped and kept inside the app frame (the card is in it)
|
|
58
|
+
const box = _contextMenu.getBoundingClientRect();
|
|
59
|
+
const at = placeMenu({ x: event.clientX, y: event.clientY, width: box.width, height: box.height,
|
|
60
|
+
viewportWidth: window.innerWidth, viewportHeight: window.innerHeight, bounds: frameRect() });
|
|
61
|
+
_contextMenu.style.left = at.left + 'px';
|
|
62
|
+
_contextMenu.style.top = at.top + 'px';
|
|
57
63
|
|
|
58
64
|
// Update pin text based on card pinned state
|
|
59
65
|
const pinItem = _contextMenu.querySelector('[data-action="pin"]');
|
|
@@ -131,17 +131,24 @@ const _panInertia = {
|
|
|
131
131
|
// COORDINATE TRANSFORMS
|
|
132
132
|
// ═══════════════════════════════════════════
|
|
133
133
|
|
|
134
|
+
// The canvas fills the app frame (index2d.html #canvas-main), not the window: a pointer's client coordinates are
|
|
135
|
+
// turned into the canvas's own by its box (kept from the last resize: the canvas moves only when it is resized).
|
|
136
|
+
let _box = { left: 0, top: 0 };
|
|
137
|
+
let _boxMeasured = false;
|
|
138
|
+
|
|
139
|
+
/** Client (viewport) coordinates → world. */
|
|
134
140
|
export function screenToWorld(sx, sy) {
|
|
135
141
|
return {
|
|
136
|
-
x: (sx * _dpr - _viewport.offsetX) / _viewport.scale,
|
|
137
|
-
y: (sy * _dpr - _viewport.offsetY) / _viewport.scale,
|
|
142
|
+
x: ((sx - _box.left) * _dpr - _viewport.offsetX) / _viewport.scale,
|
|
143
|
+
y: ((sy - _box.top) * _dpr - _viewport.offsetY) / _viewport.scale,
|
|
138
144
|
};
|
|
139
145
|
}
|
|
140
146
|
|
|
147
|
+
/** World → client (viewport) coordinates. */
|
|
141
148
|
export function worldToScreen(wx, wy) {
|
|
142
149
|
return {
|
|
143
|
-
x: (wx * _viewport.scale + _viewport.offsetX) / _dpr,
|
|
144
|
-
y: (wy * _viewport.scale + _viewport.offsetY) / _dpr,
|
|
150
|
+
x: (wx * _viewport.scale + _viewport.offsetX) / _dpr + _box.left,
|
|
151
|
+
y: (wy * _viewport.scale + _viewport.offsetY) / _dpr + _box.top,
|
|
145
152
|
};
|
|
146
153
|
}
|
|
147
154
|
|
|
@@ -163,7 +170,10 @@ function _getVisibleBounds(margin = 0) {
|
|
|
163
170
|
// PUBLIC API: Viewport accessors
|
|
164
171
|
// ═══════════════════════════════════════════
|
|
165
172
|
|
|
166
|
-
export function getViewport() {
|
|
173
|
+
export function getViewport() {
|
|
174
|
+
// width / height: the canvas buffer (device pixels, like the offsets)
|
|
175
|
+
return { ..._viewport, dpr: _dpr, width: _canvas?.width || 0, height: _canvas?.height || 0 };
|
|
176
|
+
}
|
|
167
177
|
export function getAllCards() { return _cards; }
|
|
168
178
|
export function getRegions() { return _regions; }
|
|
169
179
|
|
|
@@ -187,7 +197,7 @@ export function initGraph(container, callbacks = {}) {
|
|
|
187
197
|
if (!_canvas) {
|
|
188
198
|
_canvas = document.createElement('canvas');
|
|
189
199
|
_canvas.id = 'canvas-main';
|
|
190
|
-
_canvas.style.cssText = 'position:fixed;top:
|
|
200
|
+
_canvas.style.cssText = 'position:fixed;top:var(--frame-top);left:var(--frame-left);width:calc(100% - var(--sidebar-total-width, 0px) - 2 * var(--frame-gap));height:calc(100dvh - var(--frame-top) - var(--frame-gap));border-radius:var(--frame-radius);z-index:1;';
|
|
191
201
|
container.appendChild(_canvas);
|
|
192
202
|
}
|
|
193
203
|
_ctx = _canvas.getContext('2d');
|
|
@@ -210,6 +220,8 @@ export function initGraph(container, callbacks = {}) {
|
|
|
210
220
|
_canvas.addEventListener('dblclick', _onDblClick);
|
|
211
221
|
_canvas.addEventListener('contextmenu', _onContextMenu);
|
|
212
222
|
window.addEventListener('resize', _scheduleCanvasResize);
|
|
223
|
+
// The frame changes the canvas's box without a window resize (an explorer opening, the bar's height)
|
|
224
|
+
if (typeof ResizeObserver === 'function') new ResizeObserver(_scheduleCanvasResize).observe(_canvas);
|
|
213
225
|
|
|
214
226
|
// Hidden tab → stop the loop entirely; resume on return unless externally stopped
|
|
215
227
|
document.addEventListener('visibilitychange', () => {
|
|
@@ -1397,7 +1409,7 @@ const _scheduleHover2D = rafThrottle(() => {
|
|
|
1397
1409
|
if (newHoverId !== state.hoveredNodeId) {
|
|
1398
1410
|
state.hoveredNodeId = newHoverId;
|
|
1399
1411
|
}
|
|
1400
|
-
_canvas.style.cursor = hit ? 'pointer' : '
|
|
1412
|
+
_canvas.style.cursor = hit ? 'pointer' : 'move';
|
|
1401
1413
|
if (newHoverId) emit('node-hover', hit.node);
|
|
1402
1414
|
else if (!hit) emit('node-hover', null);
|
|
1403
1415
|
});
|
|
@@ -1469,7 +1481,7 @@ function _onPointerLeave() {
|
|
|
1469
1481
|
if (_focusPaused) return;
|
|
1470
1482
|
if (state.hoveredNodeId) {
|
|
1471
1483
|
state.hoveredNodeId = null;
|
|
1472
|
-
_canvas.style.cursor = '
|
|
1484
|
+
_canvas.style.cursor = 'move';
|
|
1473
1485
|
emit('node-hover', null);
|
|
1474
1486
|
}
|
|
1475
1487
|
}
|
|
@@ -1483,9 +1495,9 @@ function _onWheel(e) {
|
|
|
1483
1495
|
_viewport.minScale,
|
|
1484
1496
|
Math.min(_viewport.maxScale, (_smoothZoom.active ? _smoothZoom.targetScale : _viewport.scale) * zoomFactor)
|
|
1485
1497
|
);
|
|
1486
|
-
// Update anchor to cursor position (buffer coords)
|
|
1487
|
-
_smoothZoom.anchorX = e.clientX * _dpr;
|
|
1488
|
-
_smoothZoom.anchorY = e.clientY * _dpr;
|
|
1498
|
+
// Update anchor to cursor position (buffer coords, from the canvas's own corner)
|
|
1499
|
+
_smoothZoom.anchorX = (e.clientX - _box.left) * _dpr;
|
|
1500
|
+
_smoothZoom.anchorY = (e.clientY - _box.top) * _dpr;
|
|
1489
1501
|
_smoothZoom.active = true;
|
|
1490
1502
|
}
|
|
1491
1503
|
|
|
@@ -1502,11 +1514,14 @@ function _onDblClick(e) {
|
|
|
1502
1514
|
}
|
|
1503
1515
|
}
|
|
1504
1516
|
|
|
1517
|
+
// A card has its own menu (context-menu.js): the event is taken only then. Anywhere else on the graph (its empty
|
|
1518
|
+
// space, a region, while focus mode pauses it) it is left to the app's right-click menu, which adds the graph's
|
|
1519
|
+
// own rows (main.js registers that area): taking it there would leave the user with no menu at all.
|
|
1505
1520
|
function _onContextMenu(e) {
|
|
1506
|
-
if (_focusPaused)
|
|
1507
|
-
e.preventDefault();
|
|
1521
|
+
if (_focusPaused) return;
|
|
1508
1522
|
const hit = _hitTest(e.clientX, e.clientY);
|
|
1509
1523
|
if (hit && hit.type === 'card') {
|
|
1524
|
+
e.preventDefault();
|
|
1510
1525
|
emit('node-context-menu', { node: hit.node, event: e });
|
|
1511
1526
|
}
|
|
1512
1527
|
}
|
|
@@ -1622,14 +1637,20 @@ function _resizeCanvas() {
|
|
|
1622
1637
|
if (!_canvas) return;
|
|
1623
1638
|
_resizePending = false;
|
|
1624
1639
|
_dpr = Math.min(window.devicePixelRatio || 1, MAX_DPR);
|
|
1625
|
-
|
|
1626
|
-
const
|
|
1640
|
+
// The CSS box is the app frame's (index2d.html); the buffer follows it. Hidden (no box): the window's size.
|
|
1641
|
+
const box = _canvas.getBoundingClientRect();
|
|
1642
|
+
const w = box.width || window.innerWidth;
|
|
1643
|
+
const h = box.height || window.innerHeight;
|
|
1644
|
+
// The world stays where it was on screen when the canvas's corner moves (an explorer opening or closing):
|
|
1645
|
+
// what was under the pointer is still under it, as when the canvas was the whole window.
|
|
1646
|
+
if (box.width && box.height && _boxMeasured) {
|
|
1647
|
+
_viewport.offsetX -= (box.left - _box.left) * _dpr;
|
|
1648
|
+
_viewport.offsetY -= (box.top - _box.top) * _dpr;
|
|
1649
|
+
}
|
|
1650
|
+
if (box.width && box.height) { _box = { left: box.left, top: box.top }; _boxMeasured = true; }
|
|
1627
1651
|
// Set canvas buffer size to DPR-scaled resolution for crisp rendering
|
|
1628
1652
|
_canvas.width = Math.round(w * _dpr);
|
|
1629
1653
|
_canvas.height = Math.round(h * _dpr);
|
|
1630
|
-
// CSS display size stays at viewport dimensions
|
|
1631
|
-
_canvas.style.width = w + 'px';
|
|
1632
|
-
_canvas.style.height = h + 'px';
|
|
1633
1654
|
}
|
|
1634
1655
|
|
|
1635
1656
|
// Window resizes arrive many times per frame while a window or sidepanel is
|
|
@@ -1692,12 +1713,13 @@ function _getPublicAPI() {
|
|
|
1692
1713
|
})),
|
|
1693
1714
|
links: state.allLinks,
|
|
1694
1715
|
}),
|
|
1716
|
+
// The canvas's size is the app frame's (CSS): a value given here only measures it again.
|
|
1695
1717
|
width: (w) => {
|
|
1696
|
-
if (w != null)
|
|
1718
|
+
if (w != null) _resizeCanvas();
|
|
1697
1719
|
return _canvas ? Math.round(_canvas.width / _dpr) : 0;
|
|
1698
1720
|
},
|
|
1699
1721
|
height: (h) => {
|
|
1700
|
-
if (h != null)
|
|
1722
|
+
if (h != null) _resizeCanvas();
|
|
1701
1723
|
return _canvas ? Math.round(_canvas.height / _dpr) : 0;
|
|
1702
1724
|
},
|
|
1703
1725
|
// No-ops for compatibility
|
|
@@ -31,8 +31,7 @@ export function initHulls(graphInstance) {
|
|
|
31
31
|
if (!_hullCanvas) return;
|
|
32
32
|
_hullCtx = _hullCanvas.getContext('2d');
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
_hullCanvas.height = window.innerHeight;
|
|
34
|
+
_sizeHullCanvas();
|
|
36
35
|
|
|
37
36
|
// Toggle button
|
|
38
37
|
const toggleBtn = $('hull-toggle-btn');
|
|
@@ -68,8 +67,7 @@ export function drawHulls() {
|
|
|
68
67
|
|
|
69
68
|
if (!_hullCanvas || !_hullCtx) return;
|
|
70
69
|
|
|
71
|
-
|
|
72
|
-
_hullCanvas.height = window.innerHeight;
|
|
70
|
+
_sizeHullCanvas();
|
|
73
71
|
const ctx = _hullCtx;
|
|
74
72
|
ctx.clearRect(0, 0, _hullCanvas.width, _hullCanvas.height);
|
|
75
73
|
|
|
@@ -86,11 +84,12 @@ export function drawHulls() {
|
|
|
86
84
|
catGroups[cat].push(n);
|
|
87
85
|
});
|
|
88
86
|
|
|
89
|
-
// Convert graph coords to
|
|
87
|
+
// Convert graph coords to the overlay's own (it covers the graph's box, centred on the same point)
|
|
88
|
+
const halfW = _hullCanvas.width / 2, halfH = _hullCanvas.height / 2;
|
|
90
89
|
function toScreen(gx, gy) {
|
|
91
90
|
return {
|
|
92
|
-
x: (gx - center.x) * zoom +
|
|
93
|
-
y: (gy - center.y) * zoom +
|
|
91
|
+
x: (gx - center.x) * zoom + halfW,
|
|
92
|
+
y: (gy - center.y) * zoom + halfH,
|
|
94
93
|
};
|
|
95
94
|
}
|
|
96
95
|
|
|
@@ -186,8 +185,14 @@ export function isHullsVisible() {
|
|
|
186
185
|
|
|
187
186
|
function _onResize() {
|
|
188
187
|
if (!_hullCanvas) return;
|
|
189
|
-
|
|
190
|
-
|
|
188
|
+
_sizeHullCanvas();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/** The overlay's buffer follows its CSS box (the graph's, inside the app frame); no box: the window's size. */
|
|
192
|
+
function _sizeHullCanvas() {
|
|
193
|
+
const box = _hullCanvas.getBoundingClientRect();
|
|
194
|
+
_hullCanvas.width = Math.round(box.width || window.innerWidth);
|
|
195
|
+
_hullCanvas.height = Math.round(box.height || window.innerHeight);
|
|
191
196
|
}
|
|
192
197
|
|
|
193
198
|
/**
|