synabun 2.0.10 → 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 +86 -0
- package/README.md +25 -2
- package/THIRD-PARTY-LICENSES.md +22 -0
- 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/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 +37 -4
- 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 +3463 -200
- package/neural-interface/i18n/pt-BR.json +3411 -151
- package/neural-interface/lib/assistant-api.js +127 -28
- 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-catalog.js +6 -7
- package/neural-interface/lib/assistant-dispatch.js +871 -156
- package/neural-interface/lib/assistant-envelope.js +3 -1
- 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 +56 -18
- 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-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-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 +68 -68
- package/neural-interface/lib/exec-loop-command.js +4 -8
- 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 +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 +547 -47
- package/neural-interface/lib/native-loop-runtime.js +268 -41
- 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 +44 -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/peer-identity.js +763 -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 +17 -30
- 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 +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/tool-lists.js +124 -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 +18 -12
- package/neural-interface/package.json +2 -2
- package/neural-interface/public/index.html +3 -1
- 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 +35 -19
- 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 +33 -2
- 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 +49 -35
- 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-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 +7 -6
- package/neural-interface/public/shared/assistant/asst-panel.js +106 -11
- package/neural-interface/public/shared/assistant/asst-rack-styles.js +66 -49
- package/neural-interface/public/shared/assistant/asst-render.js +401 -77
- package/neural-interface/public/shared/assistant/asst-route.js +83 -12
- package/neural-interface/public/shared/assistant/asst-scenes.js +2 -0
- 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 +11 -15
- package/neural-interface/public/shared/assistant/asst-stop.js +127 -0
- package/neural-interface/public/shared/assistant/asst-styles.js +59 -21
- package/neural-interface/public/shared/assistant/asst-tool-kinds.js +156 -16
- 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 +8 -7
- package/neural-interface/public/shared/cdx/cdx-panel.js +45 -149
- package/neural-interface/public/shared/cdx/cdx-protocol.js +28 -1
- package/neural-interface/public/shared/cdx/cdx-render.js +47 -29
- 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 +11 -3
- package/neural-interface/public/shared/cdx/cdx-tabs.js +52 -39
- 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/crash-notice-view.js +168 -0
- package/neural-interface/public/shared/desktop-update-view.js +20 -0
- package/neural-interface/public/shared/editor/editor-panel-logic.js +2 -2
- package/neural-interface/public/shared/html-shell.js +9 -11
- 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 +47 -252
- 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-render.js +6 -21
- 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 +0 -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 +14 -47
- 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 +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-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/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 +1525 -1779
- 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-automation-studio.js +91 -128
- package/neural-interface/public/shared/ui-claude-panel.js +77 -5
- 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-image-gallery.js +50 -47
- package/neural-interface/public/shared/ui-keybinds.js +26 -1
- package/neural-interface/public/shared/ui-menubar.js +8 -18
- package/neural-interface/public/shared/ui-native-loop-router-state.js +5 -0
- package/neural-interface/public/shared/ui-native-loop-router.js +7 -1
- package/neural-interface/public/shared/ui-navbar.js +4 -24
- package/neural-interface/public/shared/ui-panels.js +96 -65
- package/neural-interface/public/shared/ui-schedules-studio.js +507 -423
- package/neural-interface/public/shared/ui-sessions.js +5 -3
- package/neural-interface/public/shared/ui-settings.js +594 -462
- package/neural-interface/public/shared/ui-sidepanel-sessions.js +1 -1
- package/neural-interface/public/shared/ui-sidepanel-state.js +23 -12
- package/neural-interface/public/shared/ui-sidepanel-windows.js +16 -11
- 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 +124 -180
- 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 +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 +311 -58
- 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 +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 +3934 -2454
- 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 +4 -4
- 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
|
@@ -3,6 +3,7 @@ import { on } from './state.js';
|
|
|
3
3
|
import { initI18n, isReady, t } from './i18n.js';
|
|
4
4
|
import { isGuest, hasPermission, showGuestToast } from './ui-sync.js';
|
|
5
5
|
import { createPanel } from './styleguide/sg-panel.js';
|
|
6
|
+
import { centeredInFrame } from './app-frame.js';
|
|
6
7
|
let current = null, opening = false;
|
|
7
8
|
export function initStyleGuide() { on('styleguide:open', options => openPanel(options)); }
|
|
8
9
|
async function openPanel(options = {}) {
|
|
@@ -25,8 +26,10 @@ async function openPanel(options = {}) {
|
|
|
25
26
|
document.body.append(backdrop);
|
|
26
27
|
current = createPanel({ projectPath: options?.projectPath, onClosed: () => { backdrop.remove(); current = null; } });
|
|
27
28
|
document.body.append(current.panel);
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
// Centred in the app frame (its CSS size: 1180 × 720 at most, the window less 16 / 32px)
|
|
30
|
+
const at = centeredInFrame(Math.min(1180, window.innerWidth - 16), Math.min(720, window.innerHeight - 32));
|
|
31
|
+
current.panel.style.left = at.left + 'px';
|
|
32
|
+
current.panel.style.top = at.top + 'px';
|
|
30
33
|
await current.ready;
|
|
31
34
|
}
|
|
32
35
|
finally {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { updateCachedToolDefault, invalidateToolCatalog } from './agent-runtime-options.js';
|
|
1
2
|
// ═══════════════════════════════════════════
|
|
2
3
|
// SynaBun Neural Interface — Real-time Sync
|
|
3
4
|
// ═══════════════════════════════════════════
|
|
@@ -24,7 +25,7 @@ function clearOpenCodeHistoryClientState(message) {
|
|
|
24
25
|
'opencode-v2-windows',
|
|
25
26
|
'synabun-ocp-windows',
|
|
26
27
|
'synabun-ocp-session-snapshots',
|
|
27
|
-
'synabun-opencode-session-
|
|
28
|
+
'synabun-opencode-session-tools',
|
|
28
29
|
]);
|
|
29
30
|
const prefixes = [
|
|
30
31
|
'opencode-v2-tabs-',
|
|
@@ -138,6 +139,9 @@ const SYNC_HANDLERS = {
|
|
|
138
139
|
'assistant:routing-changed': (msg) => emit('sync:assistant:routing-changed', msg),
|
|
139
140
|
// Admin sandbox (lib/agent-sandbox-setting.js): the one global value changed in some window
|
|
140
141
|
'agents:admin-sandbox-changed': (msg) => emit('sync:agents:admin-sandbox-changed', msg),
|
|
142
|
+
// Skills Service (lib/skills/service.js): a skill, a revision, a review or an installation changed (owner only) —
|
|
143
|
+
// the Studio reads its library again, Settings its chips, the Codex panel its skill hints
|
|
144
|
+
'skills:changed': (msg) => emit('sync:skills:changed', msg),
|
|
141
145
|
|
|
142
146
|
// WhatsApp Link — states and counters only (never a QR, code, number or text); Settings → WhatsApp re-reads /api/whatsapp/status
|
|
143
147
|
'whatsapp:status': (msg) => emit('sync:whatsapp:status', msg),
|
|
@@ -154,10 +158,12 @@ const SYNC_HANDLERS = {
|
|
|
154
158
|
// Browser auto-open (triggered by menu/keybind manual open)
|
|
155
159
|
'browser:open': (msg) => emit('browser:open', msg),
|
|
156
160
|
|
|
157
|
-
//
|
|
158
|
-
'mcp:
|
|
159
|
-
|
|
160
|
-
|
|
161
|
+
// Default tools sync
|
|
162
|
+
'mcp:servers-changed': (msg) => { invalidateToolCatalog(msg); emit('mcp:servers-changed', msg); },
|
|
163
|
+
'mcp:tools-default-changed': (msg) => {
|
|
164
|
+
updateCachedToolDefault(msg.tools);
|
|
165
|
+
emit('mcp:tools-default-changed', msg);
|
|
166
|
+
emit('sync:mcp:tools-default-changed', msg);
|
|
161
167
|
},
|
|
162
168
|
|
|
163
169
|
// Terminal link events
|
|
@@ -209,6 +215,10 @@ const SYNC_HANDLERS = {
|
|
|
209
215
|
// restart, not only the one that asked for it (ui-loading.js).
|
|
210
216
|
'server:restarting': (msg) => emit('server:restarting', msg),
|
|
211
217
|
|
|
218
|
+
// The notice after an automatic restart was dismissed in some window: every
|
|
219
|
+
// other one drops it too (ui-crash-notice.js).
|
|
220
|
+
'crash-notice:changed': (msg) => emit('sync:crash-notice:changed', msg),
|
|
221
|
+
|
|
212
222
|
// Session indexing progress
|
|
213
223
|
'indexing:started': (msg) => emit('ws:message', msg),
|
|
214
224
|
'indexing:session-started': (msg) => emit('ws:message', msg),
|
|
@@ -14,6 +14,7 @@ import { registerAction } from './ui-keybinds.js';
|
|
|
14
14
|
import { isGuest, hasPermission } from './ui-sync.js';
|
|
15
15
|
import { getWhiteboardElementById } from './ui-whiteboard.js';
|
|
16
16
|
import { createFrameRenderer } from './utils.js';
|
|
17
|
+
import { frameRect, onFrameChange, clampBox, clampBoxLoose } from './app-frame.js';
|
|
17
18
|
import { notify, NOTIF_TYPE } from './ui-notifications.js';
|
|
18
19
|
import { getProviderMeta } from './provider-icons.js';
|
|
19
20
|
import { readinessKind, typeWhenReady } from './term-ready.js';
|
|
@@ -27,7 +28,6 @@ import { initAssistant, registerAssistantHost, openAssistant, assistantOwnerOf,
|
|
|
27
28
|
const $ = (id) => document.getElementById(id);
|
|
28
29
|
const CLI_PROFILES = new Set(['claude-code', 'codex', 'gemini', 'opencode']);
|
|
29
30
|
const NOTIF_TRACKED_CLI_PROFILES = new Set(['claude-code', 'codex', 'gemini', 'opencode']);
|
|
30
|
-
const CLI_PROFILES_NEED_PROFILER = new Set(['codex', 'gemini']); // Claude Code has tool search — no profiler needed
|
|
31
31
|
const CLI_PROFILES_NEED_RECALL = new Set(['claude-code', 'codex', 'gemini', 'opencode']);
|
|
32
32
|
|
|
33
33
|
// ── Platform ──
|
|
@@ -617,79 +617,6 @@ function _cliBadgeHtml(sessionId) {
|
|
|
617
617
|
: '';
|
|
618
618
|
}
|
|
619
619
|
|
|
620
|
-
// ── Floating terminal MCP profile dropdown ──
|
|
621
|
-
|
|
622
|
-
let _floatProfileCache = null;
|
|
623
|
-
let _floatProfileCacheTime = 0;
|
|
624
|
-
|
|
625
|
-
async function _fetchFloatProfiles() {
|
|
626
|
-
const now = Date.now();
|
|
627
|
-
if (_floatProfileCache && now - _floatProfileCacheTime < 60000) return _floatProfileCache;
|
|
628
|
-
try {
|
|
629
|
-
const resp = await fetch('/api/mcp/profile');
|
|
630
|
-
const data = await resp.json();
|
|
631
|
-
if (data.ok) {
|
|
632
|
-
_floatProfileCache = { current: data.profile || 'full', presets: data.presets || {} };
|
|
633
|
-
_floatProfileCacheTime = now;
|
|
634
|
-
}
|
|
635
|
-
} catch {}
|
|
636
|
-
return _floatProfileCache || { current: 'full', presets: {} };
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
function _initFloatProfileDropdown(dd) {
|
|
640
|
-
const btn = dd.querySelector('.term-float-profile-btn');
|
|
641
|
-
const menu = dd.querySelector('.term-float-profile-menu');
|
|
642
|
-
const label = dd.querySelector('.term-float-profile-label');
|
|
643
|
-
|
|
644
|
-
// Load current profile label
|
|
645
|
-
_fetchFloatProfiles().then(data => {
|
|
646
|
-
const p = data.presets[data.current];
|
|
647
|
-
label.textContent = p?.label || data.current;
|
|
648
|
-
});
|
|
649
|
-
|
|
650
|
-
btn.addEventListener('click', async (e) => {
|
|
651
|
-
e.stopPropagation();
|
|
652
|
-
const wasOpen = menu.classList.contains('open');
|
|
653
|
-
// Close all other open profile menus
|
|
654
|
-
document.querySelectorAll('.term-float-profile-menu.open').forEach(m => m.classList.remove('open'));
|
|
655
|
-
if (wasOpen) return;
|
|
656
|
-
|
|
657
|
-
const data = await _fetchFloatProfiles();
|
|
658
|
-
menu.innerHTML = '';
|
|
659
|
-
for (const [id, preset] of Object.entries(data.presets)) {
|
|
660
|
-
const opt = document.createElement('div');
|
|
661
|
-
opt.className = 'term-float-profile-option' + (id === data.current ? ' selected' : '');
|
|
662
|
-
opt.innerHTML = `<span class="tfp-name">${_escHtml(String(preset.label || id))}</span><span class="tfp-hint">${_escHtml(String(preset.tools))} tools</span>`;
|
|
663
|
-
opt.addEventListener('click', async (ev) => {
|
|
664
|
-
ev.stopPropagation();
|
|
665
|
-
menu.classList.remove('open');
|
|
666
|
-
if (id === data.current) return;
|
|
667
|
-
label.textContent = preset.label || id;
|
|
668
|
-
try {
|
|
669
|
-
await fetch('/api/mcp/profile', {
|
|
670
|
-
method: 'POST',
|
|
671
|
-
headers: { 'Content-Type': 'application/json' },
|
|
672
|
-
body: JSON.stringify({ profile: id }),
|
|
673
|
-
});
|
|
674
|
-
_floatProfileCache = null; // bust cache
|
|
675
|
-
// Update all other floating profile dropdowns
|
|
676
|
-
document.querySelectorAll('.term-float-profile-label').forEach(lbl => {
|
|
677
|
-
lbl.textContent = preset.label || id;
|
|
678
|
-
});
|
|
679
|
-
} catch {}
|
|
680
|
-
});
|
|
681
|
-
menu.appendChild(opt);
|
|
682
|
-
}
|
|
683
|
-
menu.classList.add('open');
|
|
684
|
-
|
|
685
|
-
// Close on outside click
|
|
686
|
-
const close = (ev) => {
|
|
687
|
-
if (!dd.contains(ev.target)) { menu.classList.remove('open'); document.removeEventListener('mousedown', close); }
|
|
688
|
-
};
|
|
689
|
-
setTimeout(() => document.addEventListener('mousedown', close), 0);
|
|
690
|
-
});
|
|
691
|
-
}
|
|
692
|
-
|
|
693
620
|
// ── Floating terminal Recall profile dropdown ──
|
|
694
621
|
|
|
695
622
|
const FLOAT_RECALL_META = [
|
|
@@ -2322,24 +2249,22 @@ function detachPanel() {
|
|
|
2322
2249
|
// so left margin matches right margin — accounts for left sidebars and right sidepanel)
|
|
2323
2250
|
let pos;
|
|
2324
2251
|
try { pos = JSON.parse(storage.getItem(KEYS.TERMINAL_FLOAT_POS)); } catch {}
|
|
2252
|
+
const f = frameRect();
|
|
2325
2253
|
if (!pos) {
|
|
2326
|
-
const
|
|
2327
|
-
const leftEdge = (parseFloat(cs.getPropertyValue('--explorer-width')) || 0)
|
|
2328
|
-
+ (parseFloat(cs.getPropertyValue('--file-explorer-width')) || 0);
|
|
2329
|
-
const rightEdge = window.innerWidth - getRightPanelReservedWidth(cs);
|
|
2254
|
+
const { left: leftEdge, right: rightEdge } = _usableArea(f);
|
|
2330
2255
|
const usableW = Math.max(0, rightEdge - leftEdge);
|
|
2331
2256
|
const w = Math.min(800, usableW * 0.6);
|
|
2332
2257
|
const h = Math.min(500, dockedH);
|
|
2333
2258
|
pos = {
|
|
2334
2259
|
left: leftEdge + (usableW - w) / 2,
|
|
2335
|
-
top: Math.max(
|
|
2260
|
+
top: Math.max(f.top, f.top + (f.height - h) / 2),
|
|
2336
2261
|
width: w, height: h,
|
|
2337
2262
|
};
|
|
2338
2263
|
}
|
|
2339
2264
|
|
|
2340
2265
|
_panel.classList.add('detached');
|
|
2341
|
-
_panel.style.left = pos.left + 'px';
|
|
2342
|
-
_panel.style.top = Math.max(
|
|
2266
|
+
_panel.style.left = Math.max(f.left, Math.min(pos.left, f.right - 80)) + 'px';
|
|
2267
|
+
_panel.style.top = Math.max(f.top, Math.min(pos.top, f.bottom - 80)) + 'px';
|
|
2343
2268
|
_panel.style.width = pos.width + 'px';
|
|
2344
2269
|
_panel.style.height = pos.height + 'px';
|
|
2345
2270
|
|
|
@@ -2436,7 +2361,7 @@ function initFloatDrag() {
|
|
|
2436
2361
|
// Header drag for floating mode
|
|
2437
2362
|
function _startPanelDrag(x, y) {
|
|
2438
2363
|
const rect = _panel.getBoundingClientRect();
|
|
2439
|
-
_floatDrag = { startX: x, startY: y, startL: rect.left, startT: rect.top };
|
|
2364
|
+
_floatDrag = { startX: x, startY: y, startL: rect.left, startT: rect.top, w: rect.width, h: rect.height, frame: frameRect() };
|
|
2440
2365
|
pendingPanelDrag = null;
|
|
2441
2366
|
_panel.classList.add('float-dragging');
|
|
2442
2367
|
document.body.classList.add('ui-interacting');
|
|
@@ -2452,7 +2377,10 @@ function initFloatDrag() {
|
|
|
2452
2377
|
finalL = Math.round(finalL / gs) * gs;
|
|
2453
2378
|
finalT = Math.round(finalT / gs) * gs;
|
|
2454
2379
|
}
|
|
2455
|
-
|
|
2380
|
+
// Inside the app frame: the header stays below the bar, 80px of the window stays in reach
|
|
2381
|
+
const f = _floatDrag.frame || (_floatDrag.frame = frameRect());
|
|
2382
|
+
const w = _floatDrag.w || 0, h = _floatDrag.h || 0;
|
|
2383
|
+
({ x: finalL, y: finalT } = clampBoxLoose(finalL, finalT, w, h, f, 80));
|
|
2456
2384
|
// Transform during drag (composited, no layout); committed on dragend
|
|
2457
2385
|
_floatDrag.lastL = finalL;
|
|
2458
2386
|
_floatDrag.lastT = finalT;
|
|
@@ -2546,7 +2474,11 @@ function initFloatResize() {
|
|
|
2546
2474
|
nl = Math.round(nl / gs) * gs; nt = Math.round(nt / gs) * gs;
|
|
2547
2475
|
nw = Math.round(nw / gs) * gs; nh = Math.round(nh / gs) * gs;
|
|
2548
2476
|
}
|
|
2549
|
-
|
|
2477
|
+
const f = frameRect();
|
|
2478
|
+
if (nt < f.top) { if (dir.includes('n')) nh -= f.top - nt; nt = f.top; }
|
|
2479
|
+
if (nl < f.left) { if (dir.includes('w')) nw -= f.left - nl; nl = f.left; }
|
|
2480
|
+
nw = Math.max(MIN_W, Math.min(nw, f.right - nl));
|
|
2481
|
+
nh = Math.max(MIN_H, Math.min(nh, f.bottom - nt));
|
|
2550
2482
|
_panel.style.left = nl + 'px';
|
|
2551
2483
|
_panel.style.top = nt + 'px';
|
|
2552
2484
|
_panel.style.width = nw + 'px';
|
|
@@ -2653,10 +2585,12 @@ function initResizeHandle() {
|
|
|
2653
2585
|
_draggingResize = true;
|
|
2654
2586
|
document.body.classList.add('ui-interacting');
|
|
2655
2587
|
graphLayers = [$('graph-container'), $('static-bg')].filter(Boolean);
|
|
2588
|
+
// Up to 80% of the window, and never past the top of the app frame (its 12px inner padding kept)
|
|
2589
|
+
const dockBottom = _panel.getBoundingClientRect().bottom;
|
|
2590
|
+
const maxH = Math.max(MIN_HEIGHT, Math.min(window.innerHeight * 0.8, dockBottom - frameRect().top - 12));
|
|
2656
2591
|
|
|
2657
2592
|
const onMove = (e) => {
|
|
2658
2593
|
const dy = startY - e.clientY;
|
|
2659
|
-
const maxH = window.innerHeight * 0.8;
|
|
2660
2594
|
const newH = Math.max(MIN_HEIGHT, Math.min(maxH, startH + dy));
|
|
2661
2595
|
scheduleHeight(newH);
|
|
2662
2596
|
};
|
|
@@ -4180,12 +4114,13 @@ function initContextMenu(viewport, term, getWs) {
|
|
|
4180
4114
|
menu.style.top = '0px';
|
|
4181
4115
|
menu.classList.add('open');
|
|
4182
4116
|
const rect = menu.getBoundingClientRect();
|
|
4117
|
+
const f = frameRect();
|
|
4183
4118
|
let x = e.clientX;
|
|
4184
4119
|
let y = e.clientY;
|
|
4185
|
-
if (x + rect.width >
|
|
4186
|
-
if (y + rect.height >
|
|
4187
|
-
if (x <
|
|
4188
|
-
if (y <
|
|
4120
|
+
if (x + rect.width > f.right) x = f.right - rect.width - 4;
|
|
4121
|
+
if (y + rect.height > f.bottom) y = e.clientY - rect.height;
|
|
4122
|
+
if (x < f.left) x = f.left + 4;
|
|
4123
|
+
if (y < f.top) y = f.top + 4;
|
|
4189
4124
|
menu.style.left = x + 'px';
|
|
4190
4125
|
menu.style.top = y + 'px';
|
|
4191
4126
|
|
|
@@ -4415,7 +4350,8 @@ function sendMemoryDrop(node, ws) {
|
|
|
4415
4350
|
ws.send(JSON.stringify({ type: 'memory_drop', content, title }));
|
|
4416
4351
|
}
|
|
4417
4352
|
|
|
4418
|
-
|
|
4353
|
+
// Also what the context menu sends to the AI panel (ui-context-menu.js).
|
|
4354
|
+
export function formatMemoryForCLI(node) {
|
|
4419
4355
|
const p = node.payload;
|
|
4420
4356
|
const parts = [];
|
|
4421
4357
|
|
|
@@ -4551,10 +4487,11 @@ function _placeFloatColorPicker(picker, colorBtn) {
|
|
|
4551
4487
|
const inset = first ? first.left + first.width / 2 - box.left : 0;
|
|
4552
4488
|
const margin = 8, gap = 6;
|
|
4553
4489
|
const left = btn.left + btn.width / 2 - inset;
|
|
4490
|
+
const f = frameRect();
|
|
4554
4491
|
let top = btn.top - gap - box.height;
|
|
4555
|
-
if (top < margin) top = btn.bottom + gap;
|
|
4556
|
-
picker.style.left = Math.max(margin, Math.min(left,
|
|
4557
|
-
picker.style.top = Math.max(margin, Math.min(top,
|
|
4492
|
+
if (top < f.top + margin) top = btn.bottom + gap;
|
|
4493
|
+
picker.style.left = Math.max(f.left + margin, Math.min(left, f.right - box.width - margin)) + 'px';
|
|
4494
|
+
picker.style.top = Math.max(f.top + margin, Math.min(top, f.bottom - box.height - margin)) + 'px';
|
|
4558
4495
|
}
|
|
4559
4496
|
|
|
4560
4497
|
function getRightPanelReservedWidth(cs = getComputedStyle(document.documentElement)) {
|
|
@@ -4563,17 +4500,24 @@ function getRightPanelReservedWidth(cs = getComputedStyle(document.documentEleme
|
|
|
4563
4500
|
|| 0;
|
|
4564
4501
|
}
|
|
4565
4502
|
|
|
4503
|
+
/** The app frame's area left for the floats: right of the explorers, left of a docked right sidepanel (its reserved
|
|
4504
|
+
* width counts from the window's right edge), below the bar. */
|
|
4505
|
+
function _usableArea(f = frameRect(), cs = getComputedStyle(document.documentElement)) {
|
|
4506
|
+
const reserved = getRightPanelReservedWidth(cs);
|
|
4507
|
+
return { left: f.left, top: f.top, right: Math.max(f.left, Math.min(f.right, window.innerWidth - reserved)), bottom: f.bottom };
|
|
4508
|
+
}
|
|
4509
|
+
|
|
4566
4510
|
/** Update snapped-edge classes on all floating tabs based on adjacency */
|
|
4567
|
-
/** Compute
|
|
4511
|
+
/** Compute frame/panel snap boundaries (getComputedStyle reads — cache during drag) */
|
|
4568
4512
|
function _snapEnv() {
|
|
4569
|
-
const
|
|
4570
|
-
const
|
|
4571
|
-
const fileExplorerW = parseFloat(cs.getPropertyValue('--file-explorer-width')) || 0;
|
|
4513
|
+
const f = frameRect();
|
|
4514
|
+
const area = _usableArea(f);
|
|
4572
4515
|
return {
|
|
4573
|
-
leftPanelEdge:
|
|
4574
|
-
rightPanelEdge:
|
|
4575
|
-
|
|
4576
|
-
|
|
4516
|
+
leftPanelEdge: f.left,
|
|
4517
|
+
rightPanelEdge: area.right,
|
|
4518
|
+
frameRight: f.right,
|
|
4519
|
+
topEdge: f.top,
|
|
4520
|
+
bottomEdge: f.bottom,
|
|
4577
4521
|
};
|
|
4578
4522
|
}
|
|
4579
4523
|
|
|
@@ -4591,7 +4535,7 @@ function _updateSnappedEdges(rectsOverride, envOverride) {
|
|
|
4591
4535
|
}
|
|
4592
4536
|
}
|
|
4593
4537
|
|
|
4594
|
-
const { leftPanelEdge, rightPanelEdge, topEdge, bottomEdge } = envOverride || _snapEnv();
|
|
4538
|
+
const { leftPanelEdge, rightPanelEdge, frameRight, topEdge, bottomEdge } = envOverride || _snapEnv();
|
|
4595
4539
|
|
|
4596
4540
|
for (const [sid, dt] of _detachedTabs) {
|
|
4597
4541
|
if (!dt.el || dt.minimized) continue;
|
|
@@ -4611,8 +4555,8 @@ function _updateSnappedEdges(rectsOverride, envOverride) {
|
|
|
4611
4555
|
}
|
|
4612
4556
|
|
|
4613
4557
|
// Check adjacency to viewport / panel edges
|
|
4614
|
-
if (Math.abs(me.left - leftPanelEdge) < TOLERANCE
|
|
4615
|
-
if (Math.abs(me.right - rightPanelEdge) < TOLERANCE || Math.abs(me.right -
|
|
4558
|
+
if (Math.abs(me.left - leftPanelEdge) < TOLERANCE) edges.left = true;
|
|
4559
|
+
if (Math.abs(me.right - rightPanelEdge) < TOLERANCE || Math.abs(me.right - frameRight) < TOLERANCE) edges.right = true;
|
|
4616
4560
|
if (Math.abs(me.top - topEdge) < TOLERANCE) edges.top = true;
|
|
4617
4561
|
if (Math.abs(me.bottom - bottomEdge) < TOLERANCE) edges.bottom = true;
|
|
4618
4562
|
|
|
@@ -4668,20 +4612,16 @@ export function tileFloatingTerminals() {
|
|
|
4668
4612
|
}
|
|
4669
4613
|
if (entries.length === 0) return;
|
|
4670
4614
|
|
|
4671
|
-
// Compute available
|
|
4672
|
-
|
|
4673
|
-
const
|
|
4674
|
-
const fileExplorerW = parseFloat(cs.getPropertyValue('--file-explorer-width')) || 0;
|
|
4675
|
-
const sidebarW = explorerW + fileExplorerW;
|
|
4676
|
-
const rightPanelW = getRightPanelReservedWidth(cs);
|
|
4615
|
+
// Compute the available area: the app frame, minus a docked right sidepanel and the docked terminal (which sits
|
|
4616
|
+
// 12px inside the frame's bottom: the tiles stop at its top)
|
|
4617
|
+
const area = _usableArea();
|
|
4677
4618
|
const termPanel = document.getElementById('terminal-panel');
|
|
4678
|
-
const
|
|
4679
|
-
? termPanel.getBoundingClientRect().
|
|
4680
|
-
const
|
|
4681
|
-
const
|
|
4682
|
-
const
|
|
4683
|
-
const
|
|
4684
|
-
const areaH = window.innerHeight - TOP_PAD - termH;
|
|
4619
|
+
const termTop = (termPanel && !termPanel.classList.contains('hidden') && !termPanel.classList.contains('detached'))
|
|
4620
|
+
? termPanel.getBoundingClientRect().top : area.bottom;
|
|
4621
|
+
const areaL = area.left;
|
|
4622
|
+
const areaT = area.top;
|
|
4623
|
+
const areaW = Math.max(0, area.right - area.left);
|
|
4624
|
+
const areaH = Math.max(0, Math.min(area.bottom, termTop) - area.top);
|
|
4685
4625
|
|
|
4686
4626
|
// Calculate grid: find best cols/rows to fill the space
|
|
4687
4627
|
const n = entries.length;
|
|
@@ -4732,17 +4672,16 @@ function _defaultFloatRect(kind = {}) {
|
|
|
4732
4672
|
const offset = _detachedTabs.size * 30;
|
|
4733
4673
|
const isBrowser = kind.profile === 'browser';
|
|
4734
4674
|
const isAssistant = !!kind._isAssistant || kind.profile === 'assistant';
|
|
4735
|
-
const
|
|
4736
|
-
const leftEdge = (
|
|
4737
|
-
+ (parseFloat(cs.getPropertyValue('--file-explorer-width')) || 0);
|
|
4738
|
-
const rightEdge = window.innerWidth - getRightPanelReservedWidth(cs);
|
|
4675
|
+
const f = frameRect();
|
|
4676
|
+
const { left: leftEdge, right: rightEdge } = _usableArea(f);
|
|
4739
4677
|
const usableW = Math.max(0, rightEdge - leftEdge);
|
|
4740
4678
|
// Assistant floats default to 780×560 (chat + agents dock need more room than a TUI)
|
|
4741
4679
|
const w = Math.round(Math.min(isBrowser ? 960 : (isAssistant ? 780 : 700), usableW * (isBrowser ? 0.65 : (isAssistant ? 0.6 : 0.5))));
|
|
4742
|
-
const h = Math.round(Math.min(isBrowser ? 640 : (isAssistant ? 560 : 420),
|
|
4680
|
+
const h = Math.round(Math.min(isBrowser ? 640 : (isAssistant ? 560 : 420), f.height * (isBrowser ? 0.6 : (isAssistant ? 0.7 : 0.5))));
|
|
4681
|
+
const at = clampBox(leftEdge + (usableW - w) / 2 + offset, f.top + (f.height - h) / 2 + offset, w, h, f);
|
|
4743
4682
|
return {
|
|
4744
|
-
left: Math.round(
|
|
4745
|
-
top: Math.round(
|
|
4683
|
+
left: Math.round(at.x),
|
|
4684
|
+
top: Math.round(at.y),
|
|
4746
4685
|
width: w,
|
|
4747
4686
|
height: h,
|
|
4748
4687
|
};
|
|
@@ -4792,10 +4731,6 @@ function detachTab(idx, opts = {}) {
|
|
|
4792
4731
|
<span class="term-float-tab-icon">${prof?.svg || SVG_SHELL}</span>
|
|
4793
4732
|
<button class="term-float-color-strip" data-tooltip="Change color"></button>
|
|
4794
4733
|
<span class="term-float-tab-title">${_escHtml(_displayLabel(session))}</span>${session._isAssistant ? '<span class="term-float-brain-chip" data-tooltip="Brain" hidden></span>' : ''}${_cliBadgeHtml(session.id)}
|
|
4795
|
-
${CLI_PROFILES_NEED_PROFILER.has(session.profile) ? `<div class="term-float-profile-dd" data-tooltip="Tool profile">
|
|
4796
|
-
<button class="term-float-profile-btn"><span class="term-float-profile-label">...</span><span class="term-float-profile-arrow">▾</span></button>
|
|
4797
|
-
<div class="term-float-profile-menu"></div>
|
|
4798
|
-
</div>` : ''}
|
|
4799
4734
|
${CLI_PROFILES_NEED_RECALL.has(session.profile) ? `<div class="term-float-recall-dd" data-tooltip="Recall profile">
|
|
4800
4735
|
<button class="term-float-recall-btn"><span class="term-float-recall-label">...</span><span class="term-float-recall-arrow">▾</span></button>
|
|
4801
4736
|
<div class="term-float-recall-menu"></div>
|
|
@@ -5018,11 +4953,6 @@ function detachTab(idx, opts = {}) {
|
|
|
5018
4953
|
});
|
|
5019
4954
|
}
|
|
5020
4955
|
|
|
5021
|
-
// Wire MCP profile dropdown (CLI profiles only)
|
|
5022
|
-
const profileDd = win.querySelector('.term-float-profile-dd');
|
|
5023
|
-
if (profileDd) {
|
|
5024
|
-
_initFloatProfileDropdown(profileDd);
|
|
5025
|
-
}
|
|
5026
4956
|
|
|
5027
4957
|
// Wire recall profile dropdown
|
|
5028
4958
|
const recallDd = win.querySelector('.term-float-recall-dd');
|
|
@@ -5306,7 +5236,7 @@ function initTabFloatDrag(win, sessionId) {
|
|
|
5306
5236
|
|
|
5307
5237
|
function _checkHeader(target) {
|
|
5308
5238
|
const header = target.closest('.term-float-tab-header');
|
|
5309
|
-
if (!header || target.closest('button
|
|
5239
|
+
if (!header || target.closest('button')) return false;
|
|
5310
5240
|
const session = _sessions.find(s => s.id === sessionId);
|
|
5311
5241
|
return !session?.pinned;
|
|
5312
5242
|
}
|
|
@@ -5343,8 +5273,9 @@ function initTabFloatDrag(win, sessionId) {
|
|
|
5343
5273
|
const KEEP = 80;
|
|
5344
5274
|
const w = drag.startW || parseFloat(win.style.width) || 700;
|
|
5345
5275
|
const h = drag.startH || parseFloat(win.style.height) || 420;
|
|
5346
|
-
|
|
5347
|
-
|
|
5276
|
+
const env = drag.snapEnv;
|
|
5277
|
+
const frame = { left: env.leftPanelEdge, top: env.topEdge, right: env.frameRight, bottom: env.bottomEdge };
|
|
5278
|
+
({ x: finalL, y: finalT } = clampBoxLoose(finalL, finalT, w, h, frame, KEEP));
|
|
5348
5279
|
|
|
5349
5280
|
// Snap to other floating windows (rects cached at drag start)
|
|
5350
5281
|
const SNAP_DIST = 12;
|
|
@@ -5375,11 +5306,12 @@ function initTabFloatDrag(win, sessionId) {
|
|
|
5375
5306
|
else if (Math.abs(myB - or.bottom) < SNAP_DIST) { finalT = or.bottom - h; snapped = true; }
|
|
5376
5307
|
}
|
|
5377
5308
|
}
|
|
5378
|
-
// Also snap to
|
|
5379
|
-
if (Math.abs(finalL) < SNAP_DIST) { finalL =
|
|
5380
|
-
if (Math.abs(finalT -
|
|
5381
|
-
if (Math.abs(myR -
|
|
5382
|
-
if (Math.abs(
|
|
5309
|
+
// Also snap to the app frame's edges (and a docked right sidepanel's)
|
|
5310
|
+
if (Math.abs(finalL - frame.left) < SNAP_DIST) { finalL = frame.left; snapped = true; }
|
|
5311
|
+
if (Math.abs(finalT - frame.top) < SNAP_DIST) { finalT = frame.top; snapped = true; }
|
|
5312
|
+
if (Math.abs(myR - frame.right) < SNAP_DIST) { finalL = frame.right - w; snapped = true; }
|
|
5313
|
+
else if (Math.abs(myR - env.rightPanelEdge) < SNAP_DIST) { finalL = env.rightPanelEdge - w; snapped = true; }
|
|
5314
|
+
if (Math.abs(myB - frame.bottom) < SNAP_DIST) { finalT = frame.bottom - h; snapped = true; }
|
|
5383
5315
|
|
|
5384
5316
|
win.classList.toggle('float-snapping', snapped);
|
|
5385
5317
|
// Transform-based positioning: left/top force layout every frame; a
|
|
@@ -5498,7 +5430,9 @@ function initTabFloatResize(win, sessionId) {
|
|
|
5498
5430
|
nl = Math.round(nl / gs) * gs; nt = Math.round(nt / gs) * gs;
|
|
5499
5431
|
nw = Math.round(nw / gs) * gs; nh = Math.round(nh / gs) * gs;
|
|
5500
5432
|
}
|
|
5501
|
-
|
|
5433
|
+
// The header never goes above the app frame's top (a top edge stops there, the bottom edge stays put)
|
|
5434
|
+
const frameTop = frameRect().top;
|
|
5435
|
+
if (nt < frameTop) { if (dir.includes('n')) nh = Math.max(MIN_H, nh - (frameTop - nt)); nt = frameTop; }
|
|
5502
5436
|
win.style.left = nl + 'px';
|
|
5503
5437
|
win.style.top = nt + 'px';
|
|
5504
5438
|
win.style.width = nw + 'px';
|
|
@@ -5841,41 +5775,48 @@ export async function initTerminal() {
|
|
|
5841
5775
|
}
|
|
5842
5776
|
});
|
|
5843
5777
|
|
|
5844
|
-
// ── Window resize —
|
|
5778
|
+
// ── Window resize, an explorer opening or closing — keep the floats in the app frame, refit all terminals ──
|
|
5779
|
+
const clampFloatsToFrame = () => {
|
|
5780
|
+
const f = frameRect();
|
|
5781
|
+
const KEEP = 80; // min px of tab that must remain visible
|
|
5782
|
+
const floats = [..._detachedTabs.values()].filter(tabState => !tabState.minimized).map(tabState => tabState.el);
|
|
5783
|
+
if (_detached && _panel && !_panel.classList.contains('hidden')) floats.push(_panel);
|
|
5784
|
+
|
|
5785
|
+
for (const el of floats) {
|
|
5786
|
+
if (!el) continue;
|
|
5787
|
+
let l = parseFloat(el.style.left) || 0;
|
|
5788
|
+
let t = parseFloat(el.style.top) || 0;
|
|
5789
|
+
let w = parseFloat(el.style.width) || 700;
|
|
5790
|
+
let h = parseFloat(el.style.height) || 420;
|
|
5791
|
+
|
|
5792
|
+
// Clamp dimensions to the frame
|
|
5793
|
+
w = Math.min(w, f.width);
|
|
5794
|
+
h = Math.min(h, f.height);
|
|
5795
|
+
|
|
5796
|
+
// Clamp position so the header stays reachable, below the title bar and right of the explorers
|
|
5797
|
+
({ x: l, y: t } = clampBoxLoose(l, t, w, h, f, KEEP));
|
|
5798
|
+
|
|
5799
|
+
el.style.left = l + 'px';
|
|
5800
|
+
el.style.top = t + 'px';
|
|
5801
|
+
el.style.width = w + 'px';
|
|
5802
|
+
el.style.height = h + 'px';
|
|
5803
|
+
}
|
|
5804
|
+
|
|
5805
|
+
// Refit all terminals to new dimensions
|
|
5806
|
+
_sessions.forEach(s => _scheduleFit(s));
|
|
5807
|
+
};
|
|
5845
5808
|
window.addEventListener('resize', () => {
|
|
5846
5809
|
if (_windowResizeTimer) clearTimeout(_windowResizeTimer);
|
|
5847
5810
|
_windowResizeTimer = setTimeout(() => {
|
|
5848
5811
|
_windowResizeTimer = null;
|
|
5849
|
-
|
|
5850
|
-
const vh = window.innerHeight;
|
|
5851
|
-
const KEEP = 80; // min px of tab that must remain visible
|
|
5852
|
-
|
|
5853
|
-
for (const [, tabState] of _detachedTabs) {
|
|
5854
|
-
if (tabState.minimized) continue;
|
|
5855
|
-
const el = tabState.el;
|
|
5856
|
-
let l = parseFloat(el.style.left) || 0;
|
|
5857
|
-
let t = parseFloat(el.style.top) || 0;
|
|
5858
|
-
let w = parseFloat(el.style.width) || 700;
|
|
5859
|
-
let h = parseFloat(el.style.height) || 420;
|
|
5860
|
-
|
|
5861
|
-
// Clamp dimensions to viewport
|
|
5862
|
-
w = Math.min(w, vw);
|
|
5863
|
-
h = Math.min(h, vh);
|
|
5864
|
-
|
|
5865
|
-
// Clamp position so header stays reachable and below title bar
|
|
5866
|
-
l = Math.max(KEEP - w, Math.min(l, vw - KEEP));
|
|
5867
|
-
t = Math.max(48, Math.min(t, vh - KEEP));
|
|
5868
|
-
|
|
5869
|
-
el.style.left = l + 'px';
|
|
5870
|
-
el.style.top = t + 'px';
|
|
5871
|
-
el.style.width = w + 'px';
|
|
5872
|
-
el.style.height = h + 'px';
|
|
5873
|
-
}
|
|
5874
|
-
|
|
5875
|
-
// Refit all terminals to new dimensions
|
|
5876
|
-
_sessions.forEach(s => _scheduleFit(s));
|
|
5812
|
+
clampFloatsToFrame();
|
|
5877
5813
|
}, 150);
|
|
5878
5814
|
});
|
|
5815
|
+
onFrameChange(() => {
|
|
5816
|
+
if (_windowResizeTimer) return; // the resize pass runs shortly
|
|
5817
|
+
clampFloatsToFrame();
|
|
5818
|
+
_updateSnappedEdges();
|
|
5819
|
+
});
|
|
5879
5820
|
|
|
5880
5821
|
// ── Visibility change — flow control, warm renderers, one focus target ──
|
|
5881
5822
|
document.addEventListener('visibilitychange', () => {
|
|
@@ -6482,11 +6423,13 @@ async function attachDetached(terminalSessionId, profile, initialMessage, autoSu
|
|
|
6482
6423
|
if (dt?.el) {
|
|
6483
6424
|
const panelWidth = getRightPanelReservedWidth();
|
|
6484
6425
|
if (panelWidth > 0) {
|
|
6485
|
-
|
|
6486
|
-
const
|
|
6487
|
-
const
|
|
6488
|
-
|
|
6489
|
-
|
|
6426
|
+
// Beside the panel, 24px from its slot, at the top of the app frame
|
|
6427
|
+
const f = frameRect();
|
|
6428
|
+
const area = _usableArea(f);
|
|
6429
|
+
const w = Math.min(700, Math.max(0, area.right - area.left - 16) * 0.6);
|
|
6430
|
+
const h = Math.min(500, f.height - 40);
|
|
6431
|
+
dt.el.style.left = Math.max(f.left, area.right - w - 24) + 'px';
|
|
6432
|
+
dt.el.style.top = f.top + 'px';
|
|
6490
6433
|
dt.el.style.width = w + 'px';
|
|
6491
6434
|
dt.el.style.height = h + 'px';
|
|
6492
6435
|
}
|
|
@@ -6669,10 +6612,11 @@ function applyTerminalLayout(snap) {
|
|
|
6669
6612
|
const minW = 280, minH = 160;
|
|
6670
6613
|
const w = Math.max(minW, dt.width || minW);
|
|
6671
6614
|
const h = Math.max(minH, dt.height || minH);
|
|
6672
|
-
const
|
|
6673
|
-
const
|
|
6674
|
-
const
|
|
6675
|
-
const
|
|
6615
|
+
const f = frameRect();
|
|
6616
|
+
const maxL = f.right - 80;
|
|
6617
|
+
const maxT = f.bottom - 40;
|
|
6618
|
+
const l = Math.max(f.left, Math.min(dt.left || 0, maxL));
|
|
6619
|
+
const t = Math.max(f.top, Math.min(dt.top || 0, maxT));
|
|
6676
6620
|
|
|
6677
6621
|
tabState.el.style.left = l + 'px';
|
|
6678
6622
|
tabState.el.style.top = t + 'px';
|
|
@@ -239,7 +239,9 @@ function _toastEsc(s) {
|
|
|
239
239
|
}
|
|
240
240
|
|
|
241
241
|
export function showUpdateToast({ updates, errors, onClick } = {}) {
|
|
242
|
-
|
|
242
|
+
// One update toast at a time; the notice after an automatic restart (ui-crash-notice.js) wears the same toast
|
|
243
|
+
// and stays until it is dismissed.
|
|
244
|
+
document.querySelectorAll('.update-check-toast').forEach(el => { if (!el.classList.contains('crash-notice')) el.remove(); });
|
|
243
245
|
|
|
244
246
|
const toast = document.createElement('div');
|
|
245
247
|
toast.className = 'update-check-toast';
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
// Body-appended, overflow-proof tooltip for data-tooltip attributes
|
|
4
4
|
// ═══════════════════════════════════════════
|
|
5
5
|
|
|
6
|
+
import { boundsForPoint, frameRect } from './app-frame.js';
|
|
7
|
+
|
|
6
8
|
/**
|
|
7
9
|
* Initialize the tooltip system.
|
|
8
10
|
* Creates a body-appended tooltip element and delegates
|
|
@@ -41,13 +43,16 @@ export function initTooltip() {
|
|
|
41
43
|
const th = tip.offsetHeight;
|
|
42
44
|
const gap = 8;
|
|
43
45
|
const preferred = el.getAttribute('data-tooltip-pos');
|
|
46
|
+
// Kept inside the app frame for a control in it; one on the bar or an explorer keeps the window.
|
|
47
|
+
const b = boundsForPoint(frameRect(), r.left + r.width / 2, r.top + r.height / 2)
|
|
48
|
+
|| { left: 0, top: 0, right: window.innerWidth, bottom: window.innerHeight };
|
|
44
49
|
|
|
45
50
|
// Left-side placement (session dropdowns in sidepanels)
|
|
46
51
|
// Anchor to the left edge of the containing sidepanel so tooltip always appears fully outside
|
|
47
52
|
if (preferred === 'left') {
|
|
48
53
|
const panel = el.closest('.claude-panel, .codex-panel, .ocp-panel, .assistant-panel, .menubar-dropdown--resume');
|
|
49
54
|
const anchorLeft = panel ? panel.getBoundingClientRect().left : r.left;
|
|
50
|
-
if (anchorLeft - gap - tw > 4) {
|
|
55
|
+
if (anchorLeft - gap - tw > b.left + 4) {
|
|
51
56
|
setPlacement('left');
|
|
52
57
|
tip.style.top = (r.top + r.height / 2 - th / 2) + 'px';
|
|
53
58
|
tip.style.left = (anchorLeft - gap - tw) + 'px';
|
|
@@ -60,7 +65,7 @@ export function initTooltip() {
|
|
|
60
65
|
const inWbToolbar = !!el.closest('#wb-toolbar');
|
|
61
66
|
const rightAnchor = el.closest('.menubar-dropdown--resume');
|
|
62
67
|
const anchorRight = rightAnchor ? rightAnchor.getBoundingClientRect().right : r.right;
|
|
63
|
-
if ((preferred === 'right' || inWbToolbar) && anchorRight + gap + tw <
|
|
68
|
+
if ((preferred === 'right' || inWbToolbar) && anchorRight + gap + tw < b.right - 4) {
|
|
64
69
|
setPlacement('right');
|
|
65
70
|
tip.style.top = (r.top + r.height / 2 - th / 2) + 'px';
|
|
66
71
|
tip.style.left = (anchorRight + gap) + 'px';
|
|
@@ -72,13 +77,13 @@ export function initTooltip() {
|
|
|
72
77
|
const forceBelow = preferred === 'below' || el.closest('#title-bar');
|
|
73
78
|
let top = forceBelow ? r.bottom + gap : r.top - th - gap;
|
|
74
79
|
let placement = forceBelow ? 'below' : 'above';
|
|
75
|
-
if (!forceBelow && top < 4) {
|
|
80
|
+
if (!forceBelow && top < b.top + 4) {
|
|
76
81
|
top = r.bottom + gap;
|
|
77
82
|
placement = 'below';
|
|
78
83
|
}
|
|
79
84
|
let left = r.left + r.width / 2 - tw / 2;
|
|
80
|
-
if (left
|
|
81
|
-
if (left
|
|
85
|
+
if (left + tw > b.right - 4) left = b.right - 4 - tw;
|
|
86
|
+
if (left < b.left + 4) left = b.left + 4;
|
|
82
87
|
setPlacement(placement);
|
|
83
88
|
tip.style.top = top + 'px';
|
|
84
89
|
tip.style.left = left + 'px';
|