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
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { fetchToolCatalog } from '../agent-runtime-options.js';
|
|
1
2
|
// ═══════════════════════════════════════════
|
|
2
3
|
// SynaBun Assistant — panel (mount / lifecycle)
|
|
3
4
|
// ═══════════════════════════════════════════
|
|
@@ -40,6 +41,7 @@ import { getWhiteboardElementById } from '../ui-whiteboard.js';
|
|
|
40
41
|
import { focusNativeLoopRun } from '../ui-native-loop-router.js';
|
|
41
42
|
import { wireFileLinks } from '../ui-file-links.js';
|
|
42
43
|
import { injectAssistantStyles } from './asst-styles.js';
|
|
44
|
+
import { tipsSeen, tourOffered } from '../tour/tour-state.js';
|
|
43
45
|
import { createAssistantSocket } from './asst-ws.js';
|
|
44
46
|
import { createRenderer, ICON_ASSISTANT, mdInto } from './asst-render.js';
|
|
45
47
|
import { createMascotDirector, MASCOT_TIMING, turnEndPose } from './asst-mascot.js';
|
|
@@ -47,6 +49,8 @@ import { lastInputAt, onKey, onPointer } from '../synabun-ticker.js';
|
|
|
47
49
|
import { buildControlResponse, closedControlState, normalizeControlRequest, renderControlCard } from './asst-control.js';
|
|
48
50
|
import { buildPromptText, createComposer } from './asst-composer.js';
|
|
49
51
|
import { buildDispatchSpec, parseSlashCommand, slashHelpMarkdown } from './asst-slash.js';
|
|
52
|
+
import { resolveStopTarget } from './asst-stop.js';
|
|
53
|
+
import { plural } from './asst-tool-kinds.js';
|
|
50
54
|
import { cachedProjects, createBrainPicker, testDensityLabel } from './asst-brain-picker.js';
|
|
51
55
|
import { createRovingToolbar } from './asst-roving.js';
|
|
52
56
|
import { openAccountsManager } from './asst-accounts.js';
|
|
@@ -243,6 +247,23 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
243
247
|
const providerIcon = (p) => getProviderMeta(p).icon;
|
|
244
248
|
const providerColor = (p) => getProviderMeta(p).color;
|
|
245
249
|
const visible = () => { try { return host.isVisible ? !!host.isVisible() : true; } catch { return true; } };
|
|
250
|
+
|
|
251
|
+
// ── Just-in-time tips (../tour/tour-tips.js): once each, ever; never in a replay or while the tour runs ──
|
|
252
|
+
function tip(id, targetOf) {
|
|
253
|
+
if (destroyed || replaying || !visible() || guestBlocked() || tipsSeen(storage).has(id)) return;
|
|
254
|
+
requestAnimationFrame(() => {
|
|
255
|
+
if (destroyed) return;
|
|
256
|
+
let target = null;
|
|
257
|
+
try { target = targetOf(); } catch { target = null; }
|
|
258
|
+
if (!target?.isConnected) return;
|
|
259
|
+
import('../tour/tour-tips.js')
|
|
260
|
+
.then(async ({ ensureTourStyles, showTip }) => {
|
|
261
|
+
await ensureTourStyles();
|
|
262
|
+
if (!destroyed && target.isConnected) showTip(id, { storage, tr: (key) => t(key), root, target, renderer, reduced: () => matchMedia('(prefers-reduced-motion: reduce)').matches });
|
|
263
|
+
})
|
|
264
|
+
.catch(() => { /* a tip is never worth an error */ });
|
|
265
|
+
});
|
|
266
|
+
}
|
|
246
267
|
const hostId = host.id || null; // routing only (assistant:new / resume / focused) — never a feature switch
|
|
247
268
|
|
|
248
269
|
function persist() {
|
|
@@ -506,7 +527,18 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
506
527
|
emptyBudgetChip?.destroy();
|
|
507
528
|
emptyBudgetChip = null;
|
|
508
529
|
},
|
|
509
|
-
|
|
530
|
+
// The first-visit row asks for the Workspace tour on this panel (ui-tutorial.js); the others fill the composer.
|
|
531
|
+
onSuggestion: (template, s) => {
|
|
532
|
+
if (s?.action === 'tour') { emit('tour:open', { host: controller.tourHost(), from: 'starter' }); return; }
|
|
533
|
+
composer.fillTemplate(template);
|
|
534
|
+
},
|
|
535
|
+
// A follow-up under a finished message, or Retry now on a usage-limit card: sent as the user's next
|
|
536
|
+
// message (queued while a turn runs, like a typed one). "Something else…" is the composer.
|
|
537
|
+
onFollowup: (text) => { submit(clickPayload(text)); },
|
|
538
|
+
onFollowupOther: () => composer.focus(),
|
|
539
|
+
onLimitRetry: (text) => { submit(clickPayload(text)); },
|
|
540
|
+
limitInfo: () => st.limit,
|
|
541
|
+
brainProvider: () => st.brain.provider,
|
|
510
542
|
heroOrigin: () => { try { return host.takeHeroOrigin?.() || null; } catch { return null; } },
|
|
511
543
|
onMascotChange: () => director?.retarget(),
|
|
512
544
|
onInit: (ev) => {
|
|
@@ -536,12 +568,20 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
536
568
|
},
|
|
537
569
|
});
|
|
538
570
|
|
|
571
|
+
/** What a click sends: the text alone, shaped like a typed message with nothing attached. */
|
|
572
|
+
function clickPayload(text) {
|
|
573
|
+
return { text: String(text ?? ''), images: [], files: [], uploads: [], memories: [] };
|
|
574
|
+
}
|
|
575
|
+
|
|
539
576
|
function emptySuggestions() {
|
|
540
577
|
const project = projectLabel(st.brain.project, cachedProjects()) || tt('assistant.empty.thisProject', 'this project');
|
|
541
578
|
const list = [];
|
|
579
|
+
// Until the Workspace tour is completed or skipped, its starter comes first. It never opens by itself.
|
|
580
|
+
if (tourOffered(storage) && !guestBlocked()) list.push({ id: 'tour', action: 'tour', kind: 'ask', label: tt('tour.starter', 'Show me the workspace'), meta: tt('tour.starterTime', '2 min') });
|
|
542
581
|
if (computerAvailable()) list.push({ id: 'computer', label: tt('assistant.empty.suggestComputer', 'Use my Mac to…'), template: tt('assistant.empty.templateComputer', 'Use my Mac to {caret}') });
|
|
543
582
|
list.push({ id: 'web', label: tt('assistant.empty.suggestWeb', 'Look up … on the web'), template: tt('assistant.empty.templateWeb', 'Look up {caret} on the web') });
|
|
544
583
|
list.push({ id: 'fix', label: tt('assistant.empty.suggestFix', 'Fix … in {project}', { project }), template: tt('assistant.empty.templateFix', 'Fix {caret} in {project}', { project }) });
|
|
584
|
+
list.push({ id: 'skill', label: tt('assistant.empty.suggestSkill', 'Create Skill'), template: tt('assistant.empty.templateSkill', 'Create a skill that {caret}') });
|
|
545
585
|
list.push({ id: 'schedule', label: tt('assistant.empty.suggestSchedule', 'Schedule …'), template: tt('assistant.empty.templateSchedule', 'Schedule {caret}') });
|
|
546
586
|
list.push({ id: 'remember', label: tt('assistant.empty.suggestRemember', 'Remember …'), template: tt('assistant.empty.templateRemember', 'Remember {caret}') });
|
|
547
587
|
return list;
|
|
@@ -553,7 +593,7 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
553
593
|
describeSlash: (cmd) => tt(cmd.descKey, cmd.desc),
|
|
554
594
|
resolveMemory: (id) => appState.allNodes?.find(n => n.id === id) || null,
|
|
555
595
|
resolveWhiteboardImage: (id) => { const wb = getWhiteboardElementById(id); return wb?.type === 'image' && wb.dataUrl ? { dataUrl: wb.dataUrl } : null; },
|
|
556
|
-
onDraftChange: (text) => { st.draft = text; persist(); director?.type(!!String(text || '').trim()); },
|
|
596
|
+
onDraftChange: (text) => { st.draft = text; persist(); director?.type(!!String(text || '').trim()); renderer.setDrafting?.(!!String(text || '').trim()); },
|
|
557
597
|
onFocusChange: (focused) => { if (focused) director?.touch(); else director?.stopTyping(); },
|
|
558
598
|
onAbort: () => abort(),
|
|
559
599
|
onToast: toast,
|
|
@@ -591,6 +631,7 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
591
631
|
const accountHooks = () => ({ t, onChanged: () => picker.refresh(true), onSelect: (id) => applyBrain({ ...st.brain, accountId: id }, { requiresSwitch: true, field: 'account' }) });
|
|
592
632
|
// Model · effort · permission mode · account sit in the composer row next to attach; project and MCP in the toolbar.
|
|
593
633
|
const picker = createBrainPicker({ brain: composer.el.querySelector('.asst-composer-brain'), context: barGroups.context }, {
|
|
634
|
+
getSessionId: () => st.sessionId,
|
|
594
635
|
t,
|
|
595
636
|
mascot: () => director,
|
|
596
637
|
getBrain: () => st.brain,
|
|
@@ -677,6 +718,17 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
677
718
|
agentsBtn.setAttribute('aria-pressed', st.dockOpen ? 'true' : 'false');
|
|
678
719
|
|
|
679
720
|
const usage = createUsageGauge(root.querySelector('.asst-usage-host'), { t, sessionId });
|
|
721
|
+
// The first usage strip on screen gets its tip (once, ever).
|
|
722
|
+
const usageHostEl = root.querySelector('.asst-usage-host');
|
|
723
|
+
if (typeof MutationObserver === 'function' && !tipsSeen(storage).has('usage')) {
|
|
724
|
+
const usageTipWatch = new MutationObserver(() => {
|
|
725
|
+
if (usageHostEl.hidden) return;
|
|
726
|
+
usageTipWatch.disconnect();
|
|
727
|
+
tip('usage', () => usageHostEl.querySelector('.asst-usage-strip') || usageHostEl);
|
|
728
|
+
});
|
|
729
|
+
usageTipWatch.observe(usageHostEl, { attributes: true, attributeFilter: ['hidden'] });
|
|
730
|
+
unsubs.push(() => usageTipWatch.disconnect());
|
|
731
|
+
}
|
|
680
732
|
if (st.usageView) { usage.apply({ type: 'assistant:usage', ...st.usageView }); usage.setConnection('reconnecting'); }
|
|
681
733
|
let usageFetchSeq = 0;
|
|
682
734
|
let usageSocketOpened = false;
|
|
@@ -721,6 +773,7 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
721
773
|
clearTimeout(limitTimer);
|
|
722
774
|
limitTimer = null;
|
|
723
775
|
const limit = st.limit;
|
|
776
|
+
renderer.noteLimit(limit); // the waiting card of this turn's limit error counts to the reported reset
|
|
724
777
|
limitEl.hidden = !limit;
|
|
725
778
|
limitEl.dataset.status = limit?.status || '';
|
|
726
779
|
const text = limitNoticeText(limit, tt);
|
|
@@ -870,7 +923,7 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
870
923
|
return;
|
|
871
924
|
case 'assistant:dispatch': {
|
|
872
925
|
const run = runFromPayload(packet);
|
|
873
|
-
if (run) { dock.upsertRun(run); renderer.upsertRunCard(dock.getRun(run.runId) || run); }
|
|
926
|
+
if (run) { dock.upsertRun(run); renderer.upsertRunCard(dock.getRun(run.runId) || run); tip('run', () => renderer.getRunCard(run.runId)); }
|
|
874
927
|
return;
|
|
875
928
|
}
|
|
876
929
|
case 'assistant:permission-request':
|
|
@@ -914,7 +967,7 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
914
967
|
switch (ev.type) {
|
|
915
968
|
case 'synabun.dispatch': {
|
|
916
969
|
const run = runFromPayload(ev);
|
|
917
|
-
if (run) { dock.upsertRun(run); renderer.upsertRunCard(dock.getRun(run.runId) || run); }
|
|
970
|
+
if (run) { dock.upsertRun(run); renderer.upsertRunCard(dock.getRun(run.runId) || run); tip('run', () => renderer.getRunCard(run.runId)); }
|
|
918
971
|
return;
|
|
919
972
|
}
|
|
920
973
|
case 'synabun.dispatch_result': {
|
|
@@ -972,7 +1025,7 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
972
1025
|
const next = normalizeBrain({ ...st.brain, ...meta.brain, provider: meta.brain.provider || meta.brain.brain || st.brain.provider });
|
|
973
1026
|
if (JSON.stringify(next) !== JSON.stringify(st.brain)) { st.brain = next; picker.render(); host.setBrain?.(next); persist(); }
|
|
974
1027
|
} else if (typeof meta.brain === 'string') {
|
|
975
|
-
const next = normalizeBrain({ ...st.brain, provider: meta.brain, model: meta.model ?? st.brain.model, effort: meta.effort ?? st.brain.effort, accountId: meta.accountId ?? st.brain.accountId,
|
|
1028
|
+
const next = normalizeBrain({ ...st.brain, provider: meta.brain, model: meta.model ?? st.brain.model, effort: meta.effort ?? st.brain.effort, accountId: meta.accountId ?? st.brain.accountId, tools: meta.tools ?? st.brain.tools, project: meta.cwd ?? st.brain.project });
|
|
976
1029
|
if (JSON.stringify(next) !== JSON.stringify(st.brain)) { st.brain = next; picker.render(); host.setBrain?.(next); persist(); }
|
|
977
1030
|
}
|
|
978
1031
|
if (meta.budget && typeof meta.budget === 'object') budgetController.receiveSession(meta.budget);
|
|
@@ -1156,6 +1209,7 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1156
1209
|
if (st.computerRemote) { explainRemoteComputer(); return; }
|
|
1157
1210
|
const next = enabled === true;
|
|
1158
1211
|
const wasActive = st.desktopActive;
|
|
1212
|
+
if (next && !st.computerEffective) tip('computer', () => (isRendered(computerToggle.el) ? computerToggle.el : moreBtn));
|
|
1159
1213
|
st.computerUse = next;
|
|
1160
1214
|
st.computerEffective = next;
|
|
1161
1215
|
persist();
|
|
@@ -1181,7 +1235,7 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1181
1235
|
elapsedMs: st.turnStartedAt ? Date.now() - st.turnStartedAt : 0,
|
|
1182
1236
|
}) : null;
|
|
1183
1237
|
const answer = wasRunning && !aborted ? renderer.turnAnswer() : '';
|
|
1184
|
-
renderer.finishTurn({ holdMs: pose ? MASCOT_TIMING.oneShotMs[pose] : 0 });
|
|
1238
|
+
renderer.finishTurn({ holdMs: pose ? MASCOT_TIMING.oneShotMs[pose] : 0, guess: !aborted && !errored });
|
|
1185
1239
|
if (wasRunning) director.turnEnded(pose);
|
|
1186
1240
|
if (answer && !silent) announce(tt('assistant.announce.replied', 'SynaBun replied: {text}', { text: answer }));
|
|
1187
1241
|
st.running = false;
|
|
@@ -1221,6 +1275,8 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1221
1275
|
providerIcon,
|
|
1222
1276
|
scrollEnd: () => renderer.scrollEnd(),
|
|
1223
1277
|
onRespond: (n, decision) => respondControl(n, decision),
|
|
1278
|
+
// A question card's Esc, and its answer when focus was in it: back to the message box.
|
|
1279
|
+
focusComposer: () => composer.focus(),
|
|
1224
1280
|
renderRoute: (_container, n) => mountRouteCard(n),
|
|
1225
1281
|
});
|
|
1226
1282
|
if (!entry) return;
|
|
@@ -1262,6 +1318,7 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1262
1318
|
renderer.appendNode(card.el);
|
|
1263
1319
|
routeCards.set(card.routeId, card);
|
|
1264
1320
|
routeChip.render();
|
|
1321
|
+
tip('route', () => card.el);
|
|
1265
1322
|
requestAnimationFrame(() => { if (!destroyed && !card.collapsed) card.focusIfIdle(); });
|
|
1266
1323
|
return card;
|
|
1267
1324
|
}
|
|
@@ -1430,8 +1487,9 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1430
1487
|
else renames.settled().then(() => { if (!destroyed) sock.send({ type: 'list_sessions' }); }); // a rename on its way is in the list
|
|
1431
1488
|
return true;
|
|
1432
1489
|
case 'stop':
|
|
1490
|
+
// /stop all: every run of the session, at once. /stop <target>: the one run it names, or nothing.
|
|
1433
1491
|
if (parsed.all) await stopAll();
|
|
1434
|
-
else if (parsed.target) await
|
|
1492
|
+
else if (parsed.target) await stopNamedRun(parsed.target);
|
|
1435
1493
|
else abort();
|
|
1436
1494
|
return true;
|
|
1437
1495
|
case 'agents': {
|
|
@@ -1514,7 +1572,7 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1514
1572
|
}
|
|
1515
1573
|
|
|
1516
1574
|
async function dispatch(parsed, payload) {
|
|
1517
|
-
const spec = buildDispatchSpec(parsed, st.brain, { assistantSessionId: sessionId });
|
|
1575
|
+
const spec = buildDispatchSpec(parsed, st.brain, { assistantSessionId: sessionId, toolCatalog: await fetchToolCatalog() });
|
|
1518
1576
|
renderer.appendUser(payload.text);
|
|
1519
1577
|
try {
|
|
1520
1578
|
const res = await dispatchAssistantRun(spec);
|
|
@@ -1585,7 +1643,7 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1585
1643
|
if (meta.silent) return;
|
|
1586
1644
|
if (meta.requiresSwitch) {
|
|
1587
1645
|
const b = st.brain;
|
|
1588
|
-
if (!meta.restartBrain) sock.send({ type: 'switch_brain', brain: b.provider, model: b.model || undefined, effort: b.effort || undefined, accountId: b.accountId || undefined,
|
|
1646
|
+
if (!meta.restartBrain) sock.send({ type: 'switch_brain', brain: b.provider, model: b.model || undefined, effort: b.effort || undefined, accountId: b.accountId || undefined, tools: b.tools ?? undefined, cwd: b.project || undefined, agent: b.agent || undefined, permissionMode: b.permissionMode, planMode: b.planMode === true });
|
|
1589
1647
|
renderer.appendDivider(`${tt('assistant.status.brain', 'brain')} → ${brainLabel(b)}`);
|
|
1590
1648
|
renderer.forgetSeen(); // the new brain's ids start over
|
|
1591
1649
|
} else if (before.permissionMode !== st.brain.permissionMode || !!before.planMode !== !!st.brain.planMode) {
|
|
@@ -1638,9 +1696,29 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1638
1696
|
}
|
|
1639
1697
|
}
|
|
1640
1698
|
|
|
1699
|
+
/**
|
|
1700
|
+
* /stop <target>: the run of this session it names (its id or the start of it, its title, the words
|
|
1701
|
+
* of its title: asst-stop.js), and only that one. A target that fits none, or more than one, stops nothing.
|
|
1702
|
+
*/
|
|
1703
|
+
async function stopNamedRun(target) {
|
|
1704
|
+
const found = resolveStopTarget(target, dock.getRuns());
|
|
1705
|
+
if (found.run && !found.error) return stopRun(found.run.runId);
|
|
1706
|
+
if (found.passthrough) return stopRun(found.passthrough); // a full id the tray has not loaded: the server knows
|
|
1707
|
+
const name = (run) => `${run.title || run.runId}${run.title ? ` (${String(run.runId).slice(0, 8)})` : ''}`;
|
|
1708
|
+
const message = found.error === 'ambiguous'
|
|
1709
|
+
? tt('assistant.slash.stopAmbiguous', '"{target}" matches {count} agents: {list}. Nothing was stopped; name one of them.', { target, count: found.matches.length, list: found.matches.map(name).join(', ') })
|
|
1710
|
+
: found.error === 'finished'
|
|
1711
|
+
? tt('assistant.slash.stopFinished', '{name} has already finished.', { name: name(found.run) })
|
|
1712
|
+
: tt('assistant.slash.stopNoMatch', 'No agent of this session matches "{target}". Nothing was stopped; /agents lists them.', { target });
|
|
1713
|
+
renderer.appendStatus(message);
|
|
1714
|
+
}
|
|
1715
|
+
|
|
1641
1716
|
async function stopAll() {
|
|
1642
|
-
try {
|
|
1643
|
-
|
|
1717
|
+
try {
|
|
1718
|
+
const res = await killAllAssistantRuns(sessionId);
|
|
1719
|
+
const count = Array.isArray(res?.stopped) ? res.stopped.length : null;
|
|
1720
|
+
toast(count === null ? tt('assistant.status.stopAllRequested', 'Stopping all dispatched agents…') : plural(tt, 'assistant.status.stopAllDone', count, 'Stopped {count} agent.', 'Stopped {count} agents.'));
|
|
1721
|
+
} catch (err) { renderer.appendError(`${tt('assistant.status.stopFailed', 'Stop failed')}: ${err?.message || err}`); }
|
|
1644
1722
|
}
|
|
1645
1723
|
|
|
1646
1724
|
async function escalateRun(runId, target) {
|
|
@@ -1852,6 +1930,7 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1852
1930
|
items.push({ kind: 'info', label: tt('assistant.topbar.cost', 'Session cost'), value: fmtCost(totalCost()) || '$0.00' });
|
|
1853
1931
|
if (Number(st.dispatchUsd) > 0) items.push({ kind: 'info', label: tt('assistant.topbar.agentsCost', 'Agents'), value: fmtCost(st.dispatchUsd) });
|
|
1854
1932
|
openMenu(moreBtn, { label: tt('assistant.toolbar.more', 'More options'), items, role: 'menu', placement: 'below', width: 280 });
|
|
1933
|
+
tip('more', () => document.querySelector('.asst-dd-menu'));
|
|
1855
1934
|
}
|
|
1856
1935
|
|
|
1857
1936
|
// Assistant → Models: switch models off (hidden from routing, dispatch and every model menu).
|
|
@@ -2145,6 +2224,22 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
2145
2224
|
resume,
|
|
2146
2225
|
setRouteMode: (mode) => setRouteMode(mode),
|
|
2147
2226
|
setComputerUse: (enabled) => setComputerUse(enabled),
|
|
2227
|
+
/**
|
|
2228
|
+
* What the Workspace tour presents on (public/shared/tour/): this panel's own board,
|
|
2229
|
+
* its controls and its director, while the empty state shows its character and nothing
|
|
2230
|
+
* runs. null otherwise (the tour then uses a session-free preview).
|
|
2231
|
+
*/
|
|
2232
|
+
tourHost() {
|
|
2233
|
+
const hero = renderer.mascot();
|
|
2234
|
+
if (destroyed || st.running || hero?.kind !== 'hero' || hero.parked?.()) return null;
|
|
2235
|
+
return {
|
|
2236
|
+
root, transcript: transcriptEl, announcer, bar: barEl, renderer, director, composer,
|
|
2237
|
+
live: true,
|
|
2238
|
+
computer: computerAvailable(),
|
|
2239
|
+
refreshStarters: () => renderer.refreshEmpty(),
|
|
2240
|
+
focusComposer: () => composer.focus(),
|
|
2241
|
+
};
|
|
2242
|
+
},
|
|
2148
2243
|
attachMemory: (node) => composer.addMemory(node),
|
|
2149
2244
|
attachImageDataUrl: (dataUrl, name) => composer.addImageDataUrl(dataUrl, name),
|
|
2150
2245
|
insertText: (text) => composer.insertText(text),
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
// mascot stands over its task class's scene (asst-scenes.js; the motion is
|
|
9
9
|
// asst-scene-styles.js): one column, as wide as the scene.
|
|
10
10
|
//
|
|
11
|
-
// Rules: gold only means live (the awake row's ring and tick, the
|
|
12
|
-
// sweep); a rack a card holds (data-state="waiting") drops its gold:
|
|
13
|
-
// for you" in the warn tone with ◆,
|
|
11
|
+
// Rules: gold only means live (the awake row's ring and tick, the bubble's
|
|
12
|
+
// verb, the sweep); a rack a card holds (data-state="waiting") drops its gold:
|
|
13
|
+
// "Waiting for you" in the warn tone with ◆, stopped clocks. Motion answers
|
|
14
14
|
// events and stays under 300 ms; infinite animations run only on the live
|
|
15
15
|
// rack, pause while the UI is dragged (body.ui-interacting) and everything is
|
|
16
16
|
// static under prefers-reduced-motion (the sweep is not drawn at all). No
|
|
@@ -117,6 +117,7 @@ export const RACK_CSS = `
|
|
|
117
117
|
grid-area: caption;
|
|
118
118
|
align-self: end;
|
|
119
119
|
min-width: 0;
|
|
120
|
+
margin-left: 8px; /* flush with the bubble's body (its notch takes the first 8px) */
|
|
120
121
|
margin-bottom: 6px; /* the gap over the bubble: an empty caption takes no room */
|
|
121
122
|
overflow: hidden;
|
|
122
123
|
display: -webkit-box;
|
|
@@ -128,95 +129,107 @@ export const RACK_CSS = `
|
|
|
128
129
|
}
|
|
129
130
|
.asst-rack-caption:empty { display: none; }
|
|
130
131
|
|
|
132
|
+
/* ── The bubble: one 18px line (verb · subject · clock), 32px tall at one line, the ledger row's height.
|
|
133
|
+
The verb is gold only while the call runs; the mascot (and the sweep) carry the motion, the bubble
|
|
134
|
+
carries the words and, at the end of the line in the quietest tone, the numbers. Opaque fill (the
|
|
135
|
+
card under the panel tint), so the notch can cover the ring where it meets the edge: no seam. */
|
|
131
136
|
.asst-bubble {
|
|
137
|
+
--rk-bubble-bg: linear-gradient(var(--rk-fill-1), var(--rk-fill-1)), var(--rk-card);
|
|
132
138
|
grid-area: bubble;
|
|
133
139
|
position: relative;
|
|
134
140
|
justify-self: start;
|
|
135
141
|
align-self: start;
|
|
136
|
-
display:
|
|
137
|
-
grid-template-columns: auto minmax(0, 1fr);
|
|
138
|
-
align-items: baseline;
|
|
139
|
-
column-gap: 7px;
|
|
140
|
-
row-gap: 1px;
|
|
142
|
+
display: block; /* a block, not a flex column: a flex item's -webkit-box is blockified and loses its line clamp */
|
|
141
143
|
max-width: calc(100% - 8px);
|
|
142
144
|
min-width: 0;
|
|
143
145
|
margin-left: 8px;
|
|
144
|
-
padding:
|
|
145
|
-
border-radius: 3px
|
|
146
|
-
background: var(--rk-
|
|
146
|
+
padding: 7px 10px;
|
|
147
|
+
border-radius: 3px 10px 10px 10px;
|
|
148
|
+
background: var(--rk-bubble-bg);
|
|
147
149
|
box-shadow: inset 0 0 0 1px var(--rk-line);
|
|
148
150
|
}
|
|
149
|
-
/* The tail:
|
|
151
|
+
/* The tail: a 7px notch pointing at the mascot (left beside it, up under it), centred on the first line and
|
|
152
|
+
on the mascot's eyes. An 11px square turned 45° and cut to a triangle, 1px into the bubble so it paints
|
|
153
|
+
over the ring: the ring stops at the notch's legs, no double edge. */
|
|
150
154
|
.asst-bubble::before {
|
|
151
155
|
content: '';
|
|
152
156
|
position: absolute;
|
|
153
|
-
left: -
|
|
154
|
-
top:
|
|
157
|
+
left: -4.5px;
|
|
158
|
+
top: 10.5px;
|
|
155
159
|
width: 11px;
|
|
156
160
|
height: 11px;
|
|
157
|
-
background: var(--rk-
|
|
161
|
+
background: var(--rk-bubble-bg);
|
|
158
162
|
box-shadow: inset 1px -1px 0 var(--rk-line);
|
|
159
163
|
clip-path: polygon(0 0, 0 100%, 100% 100%);
|
|
160
164
|
transform: rotate(45deg);
|
|
161
165
|
pointer-events: none;
|
|
162
166
|
}
|
|
163
|
-
|
|
167
|
+
/* The line: one text flow, two lines at most (six opened), of the verb, the subject (cut by asst-render.js
|
|
168
|
+
until nothing is clamped) and the numbers, which take the end of the subject's last line and wrap
|
|
169
|
+
under it as a unit when they are long (a computer action and its clock). 2px of room around it for
|
|
170
|
+
the subject's focus ring. */
|
|
171
|
+
.asst-bubble-line {
|
|
172
|
+
display: -webkit-box;
|
|
173
|
+
-webkit-box-orient: vertical;
|
|
174
|
+
-webkit-line-clamp: 2;
|
|
175
|
+
min-width: 0;
|
|
176
|
+
margin: -2px -3px;
|
|
177
|
+
padding: 2px 3px;
|
|
178
|
+
overflow: hidden;
|
|
179
|
+
/* The strut sets the 18px pitch; the words inside sit at line-height 1, so no mix of sizes or fonts grows a line. */
|
|
180
|
+
font-size: 12px;
|
|
181
|
+
line-height: 18px;
|
|
182
|
+
overflow-wrap: anywhere;
|
|
183
|
+
}
|
|
184
|
+
.asst-bubble-line:has(> .asst-bubble-subject[aria-expanded="true"]) { -webkit-line-clamp: 6; }
|
|
185
|
+
.asst-bubble-verb { color: var(--rk-text-2); font-size: 12px; font-weight: 500; line-height: 1; white-space: nowrap; }
|
|
186
|
+
.asst-bubble-verb:not(:empty) { margin-right: 7px; }
|
|
164
187
|
.asst-bubble[data-state="running"] .asst-bubble-verb { color: var(--rk-gold); }
|
|
165
|
-
/* A card holds the call: no gold,
|
|
188
|
+
/* A card holds the call: no gold, the clock stopped (asst-render.js), "◆ Waiting for you". */
|
|
166
189
|
.asst-bubble[data-state="waiting"] .asst-bubble-verb { color: var(--rk-warn); }
|
|
167
190
|
.asst-bubble[data-state="waiting"] .asst-bubble-verb::before { content: '◆'; margin-right: 5px; font-size: 9px; vertical-align: 1px; }
|
|
168
191
|
.asst-bubble-subject {
|
|
169
192
|
--rk-cut: middle; /* where asst-render.js cuts a long subject: the middle; the head on a narrow stage */
|
|
170
193
|
position: relative;
|
|
171
|
-
min-width: 0;
|
|
172
|
-
overflow: hidden;
|
|
173
|
-
display: -webkit-box;
|
|
174
|
-
-webkit-box-orient: vertical;
|
|
175
|
-
-webkit-line-clamp: 2;
|
|
176
194
|
border-radius: 4px;
|
|
177
195
|
color: var(--rk-text);
|
|
178
196
|
font-size: 12px;
|
|
179
|
-
line-height: 1
|
|
180
|
-
overflow-wrap: anywhere;
|
|
197
|
+
line-height: 1;
|
|
181
198
|
cursor: pointer;
|
|
182
199
|
}
|
|
183
200
|
.asst-bubble-subject.is-mono { font-family: var(--rk-mono); font-size: 11.5px; }
|
|
184
201
|
.asst-bubble-subject.is-muted { color: var(--rk-text-3); }
|
|
185
|
-
.asst-bubble-subject[aria-expanded="true"] {
|
|
202
|
+
.asst-bubble-subject[aria-expanded="true"] { cursor: text; user-select: text; }
|
|
186
203
|
.asst-bubble-subject .is-dim { color: var(--rk-text-3); }
|
|
187
204
|
.asst-bubble-subject .is-strong { color: var(--rk-text); font-weight: 600; }
|
|
188
|
-
/*
|
|
189
|
-
|
|
205
|
+
/* A URL or path: one piece per span, a <wbr> between them (asst-render.js writeSubject), so it wraps after "/"
|
|
206
|
+
and at its other separators, never mid-word; a piece wider than its line is cut instead (fitSubject). The
|
|
207
|
+
rest of the subject wraps as the line says. Opened, the whole literal shows: a piece may break again. */
|
|
208
|
+
.asst-bubble-piece { white-space: nowrap; }
|
|
209
|
+
.asst-bubble-subject[aria-expanded="true"] .asst-bubble-piece { white-space: normal; }
|
|
210
|
+
/* Streaming thinking cut from its head ("…the end of the thought") fades in from the cut; whole text is left alone. */
|
|
211
|
+
.asst-bubble[data-kind="think"][data-state="running"] .asst-bubble-subject.is-cut {
|
|
190
212
|
-webkit-mask-image: linear-gradient(90deg, transparent, #000 12px);
|
|
191
213
|
mask-image: linear-gradient(90deg, transparent, #000 12px);
|
|
192
214
|
}
|
|
193
|
-
.asst-bubble-caret {
|
|
194
|
-
display: none;
|
|
195
|
-
width: 6px;
|
|
196
|
-
height: 12px;
|
|
197
|
-
margin-left: 3px;
|
|
198
|
-
vertical-align: -2px;
|
|
199
|
-
background: var(--rk-gold);
|
|
200
|
-
}
|
|
201
|
-
.asst-bubble[data-state="running"] .asst-bubble-caret { display: inline-block; animation: asst-rk-caret 1.06s steps(1) infinite; }
|
|
202
215
|
.asst-bubble-meta {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
gap: 2px 12px;
|
|
216
|
+
display: inline-flex;
|
|
217
|
+
gap: 0 8px;
|
|
218
|
+
margin-left: 7px;
|
|
207
219
|
color: var(--rk-text-3);
|
|
208
220
|
font-size: 11px;
|
|
209
|
-
line-height: 1
|
|
221
|
+
line-height: 1; /* inside the 18px strut: the smaller type never grows the line */
|
|
222
|
+
white-space: nowrap;
|
|
210
223
|
font-variant-numeric: tabular-nums;
|
|
211
224
|
}
|
|
212
225
|
.asst-bubble-meta:empty { display: none; }
|
|
213
226
|
.asst-bubble-num { white-space: nowrap; }
|
|
214
227
|
.asst-bubble-err {
|
|
215
|
-
grid-column: 1 / -1;
|
|
216
228
|
display: -webkit-box;
|
|
217
229
|
-webkit-box-orient: vertical;
|
|
218
230
|
-webkit-line-clamp: 2;
|
|
219
231
|
min-width: 0;
|
|
232
|
+
margin-top: 2px;
|
|
220
233
|
overflow: hidden;
|
|
221
234
|
color: var(--rk-red);
|
|
222
235
|
font-family: var(--rk-mono);
|
|
@@ -228,8 +241,8 @@ export const RACK_CSS = `
|
|
|
228
241
|
.asst-bubble-copy {
|
|
229
242
|
position: relative;
|
|
230
243
|
isolation: isolate;
|
|
231
|
-
|
|
232
|
-
|
|
244
|
+
display: inline-flex;
|
|
245
|
+
align-items: center;
|
|
233
246
|
height: var(--rk-pill-h);
|
|
234
247
|
margin-top: 4px;
|
|
235
248
|
padding: 0 var(--rk-pill-px);
|
|
@@ -242,7 +255,9 @@ export const RACK_CSS = `
|
|
|
242
255
|
cursor: pointer;
|
|
243
256
|
}
|
|
244
257
|
.asst-bubble-copy:hover { color: var(--rk-text); }
|
|
245
|
-
|
|
258
|
+
/* The clock: tabular digits that roll in place (asst-render.js); its cell keeps "59 s" of room, right-aligned, so
|
|
259
|
+
"9 s" → "10 s" moves nothing. */
|
|
260
|
+
.asst-odo { display: inline-flex; justify-content: flex-end; min-width: 2.4em; font-variant-numeric: tabular-nums; white-space: pre; }
|
|
246
261
|
.asst-odo-d { display: inline-block; }
|
|
247
262
|
|
|
248
263
|
.asst-rack-sweep { position: absolute; left: 0; right: 0; bottom: 0; height: 1.5px; overflow: hidden; pointer-events: none; }
|
|
@@ -553,9 +568,9 @@ export const RACK_CSS = `
|
|
|
553
568
|
.asst-rack-stage { grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "face caption" "bubble bubble"; column-gap: 8px; row-gap: 6px; }
|
|
554
569
|
.asst-rack-set { align-self: center; flex-direction: row; }
|
|
555
570
|
.asst-rack.is-staged > .asst-rack-stage { padding: 10px 10px 10px; }
|
|
556
|
-
.asst-rack-caption { align-self: center; margin-bottom: 0; }
|
|
557
|
-
.asst-bubble { justify-self: stretch; max-width: 100%; margin: 4px 0 0; border-radius: 3px
|
|
558
|
-
.asst-bubble::before { left: 30px; top: -
|
|
571
|
+
.asst-rack-caption { align-self: center; margin-left: 0; margin-bottom: 0; }
|
|
572
|
+
.asst-bubble { justify-self: stretch; max-width: 100%; margin: 4px 0 0; border-radius: 3px 10px 10px 10px; }
|
|
573
|
+
.asst-bubble::before { left: 30px; top: -4.5px; box-shadow: inset 1px 1px 0 var(--rk-line); clip-path: polygon(0 100%, 0 0, 100% 0); }
|
|
559
574
|
.asst-station-hdr { gap: 8px; padding: 0 6px; }
|
|
560
575
|
.asst-station-time { display: none; }
|
|
561
576
|
.asst-tick.is-old { display: none; }
|
|
@@ -565,7 +580,8 @@ export const RACK_CSS = `
|
|
|
565
580
|
.asst-station-sub { margin-left: 12px; }
|
|
566
581
|
}
|
|
567
582
|
@container asst (max-width: 320px) {
|
|
568
|
-
.asst-bubble { padding:
|
|
583
|
+
.asst-bubble { padding: 6px 9px; }
|
|
584
|
+
.asst-bubble::before { top: -4.5px; }
|
|
569
585
|
.asst-bubble-subject { --rk-cut: head; }
|
|
570
586
|
.asst-bubble-meta { display: none; }
|
|
571
587
|
}
|
|
@@ -576,6 +592,7 @@ export const RACK_CSS = `
|
|
|
576
592
|
}
|
|
577
593
|
|
|
578
594
|
/* ── Motion ─────────────────────────────────────────────────────── */
|
|
595
|
+
/* The caret blink belongs to the scenes' code caret (asst-scene-styles.js); the bubble has none. */
|
|
579
596
|
@keyframes asst-rk-caret { 0% { opacity: 1; } 50% { opacity: 0; } }
|
|
580
597
|
@keyframes asst-rk-sweep { from { transform: translateX(-100%); } to { transform: translateX(270%); } }
|
|
581
598
|
@keyframes asst-rk-tick { 0%, 100% { opacity: 1; } 50% { opacity: .4; } }
|