synabun 2.0.7 → 2.0.10
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 +67 -0
- package/README.md +1 -1
- package/THIRD-PARTY-LICENSES.md +46 -4
- package/hooks/claude-code/post-plan.mjs +6 -30
- package/hooks/claude-code/session-start.mjs +1 -4
- package/hooks/claude-code/shared.mjs +106 -72
- package/launcher.mjs +9 -3
- package/lib/package-processes.js +670 -0
- package/lib/runtime-dependencies.js +225 -0
- package/lib/start-launcher.js +6 -1
- package/mcp-server/dist/services/browser-bench.d.ts +1 -1
- package/mcp-server/dist/services/browser-bench.d.ts.map +1 -1
- package/mcp-server/dist/services/browser-bench.js +1 -1
- package/mcp-server/dist/services/browser-bench.js.map +1 -1
- package/mcp-server/dist/services/categories.d.ts +35 -2
- package/mcp-server/dist/services/categories.d.ts.map +1 -1
- package/mcp-server/dist/services/categories.js +77 -33
- package/mcp-server/dist/services/categories.js.map +1 -1
- package/mcp-server/dist/services/desktop-bench.d.ts +7 -7
- package/mcp-server/dist/services/desktop-bench.d.ts.map +1 -1
- package/mcp-server/dist/services/desktop-bench.js +1 -1
- package/mcp-server/dist/services/desktop-bench.js.map +1 -1
- package/mcp-server/dist/tools/agents.d.ts +1 -1
- package/mcp-server/dist/tools/agents.d.ts.map +1 -1
- package/mcp-server/dist/tools/agents.js +1 -1
- package/mcp-server/dist/tools/agents.js.map +1 -1
- package/mcp-server/dist/tools/bluesky.js +1 -1
- package/mcp-server/dist/tools/bluesky.js.map +1 -1
- package/mcp-server/dist/tools/browser-advanced.d.ts +1 -1
- package/mcp-server/dist/tools/browser-advanced.d.ts.map +1 -1
- package/mcp-server/dist/tools/browser-advanced.js +1 -1
- package/mcp-server/dist/tools/browser-advanced.js.map +1 -1
- package/mcp-server/dist/tools/browser-batch.d.ts +1 -1
- package/mcp-server/dist/tools/browser-batch.d.ts.map +1 -1
- package/mcp-server/dist/tools/browser-batch.js +1 -1
- package/mcp-server/dist/tools/browser-batch.js.map +1 -1
- package/mcp-server/dist/tools/browser-cheatsheet.d.ts +1 -1
- package/mcp-server/dist/tools/browser-cheatsheet.d.ts.map +1 -1
- package/mcp-server/dist/tools/browser-cheatsheet.js +1 -1
- package/mcp-server/dist/tools/browser-cheatsheet.js.map +1 -1
- package/mcp-server/dist/tools/browser-interact.d.ts +1 -1
- package/mcp-server/dist/tools/browser-interact.d.ts.map +1 -1
- package/mcp-server/dist/tools/browser-interact.js +1 -1
- package/mcp-server/dist/tools/browser-interact.js.map +1 -1
- package/mcp-server/dist/tools/browser-navigate.d.ts +1 -1
- package/mcp-server/dist/tools/browser-navigate.d.ts.map +1 -1
- package/mcp-server/dist/tools/browser-navigate.js +1 -1
- package/mcp-server/dist/tools/browser-navigate.js.map +1 -1
- package/mcp-server/dist/tools/browser-observe.d.ts +1 -1
- package/mcp-server/dist/tools/browser-observe.d.ts.map +1 -1
- package/mcp-server/dist/tools/browser-observe.js +1 -1
- package/mcp-server/dist/tools/browser-observe.js.map +1 -1
- package/mcp-server/dist/tools/card-tools.d.ts +1 -1
- package/mcp-server/dist/tools/card-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/card-tools.js +1 -1
- package/mcp-server/dist/tools/card-tools.js.map +1 -1
- package/mcp-server/dist/tools/category.d.ts +1 -1
- package/mcp-server/dist/tools/category.d.ts.map +1 -1
- package/mcp-server/dist/tools/category.js +5 -1
- package/mcp-server/dist/tools/category.js.map +1 -1
- package/mcp-server/dist/tools/choice.d.ts +1 -1
- package/mcp-server/dist/tools/choice.d.ts.map +1 -1
- package/mcp-server/dist/tools/choice.js +1 -1
- package/mcp-server/dist/tools/choice.js.map +1 -1
- package/mcp-server/dist/tools/computer.d.ts +1 -1
- package/mcp-server/dist/tools/computer.d.ts.map +1 -1
- package/mcp-server/dist/tools/computer.js +1 -1
- package/mcp-server/dist/tools/computer.js.map +1 -1
- package/mcp-server/dist/tools/discord-channel.d.ts +1 -1
- package/mcp-server/dist/tools/discord-channel.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-channel.js +1 -1
- package/mcp-server/dist/tools/discord-channel.js.map +1 -1
- package/mcp-server/dist/tools/discord-guild.d.ts +1 -1
- package/mcp-server/dist/tools/discord-guild.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-guild.js +1 -1
- package/mcp-server/dist/tools/discord-guild.js.map +1 -1
- package/mcp-server/dist/tools/discord-member.d.ts +1 -1
- package/mcp-server/dist/tools/discord-member.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-member.js +1 -1
- package/mcp-server/dist/tools/discord-member.js.map +1 -1
- package/mcp-server/dist/tools/discord-message.d.ts +1 -1
- package/mcp-server/dist/tools/discord-message.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-message.js +1 -1
- package/mcp-server/dist/tools/discord-message.js.map +1 -1
- package/mcp-server/dist/tools/discord-onboarding.d.ts +1 -1
- package/mcp-server/dist/tools/discord-onboarding.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-onboarding.js +1 -1
- package/mcp-server/dist/tools/discord-onboarding.js.map +1 -1
- package/mcp-server/dist/tools/discord-role.d.ts +1 -1
- package/mcp-server/dist/tools/discord-role.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-role.js +1 -1
- package/mcp-server/dist/tools/discord-role.js.map +1 -1
- package/mcp-server/dist/tools/discord-thread.d.ts +1 -1
- package/mcp-server/dist/tools/discord-thread.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-thread.js +1 -1
- package/mcp-server/dist/tools/discord-thread.js.map +1 -1
- package/mcp-server/dist/tools/discord-webhook.d.ts +1 -1
- package/mcp-server/dist/tools/discord-webhook.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-webhook.js +1 -1
- package/mcp-server/dist/tools/discord-webhook.js.map +1 -1
- package/mcp-server/dist/tools/fb-groups.d.ts +1 -1
- package/mcp-server/dist/tools/fb-groups.d.ts.map +1 -1
- package/mcp-server/dist/tools/fb-groups.js +1 -1
- package/mcp-server/dist/tools/fb-groups.js.map +1 -1
- package/mcp-server/dist/tools/forget.d.ts +1 -1
- package/mcp-server/dist/tools/forget.d.ts.map +1 -1
- package/mcp-server/dist/tools/forget.js +1 -1
- package/mcp-server/dist/tools/forget.js.map +1 -1
- package/mcp-server/dist/tools/git-tools.d.ts +1 -1
- package/mcp-server/dist/tools/git-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/git-tools.js +1 -1
- package/mcp-server/dist/tools/git-tools.js.map +1 -1
- package/mcp-server/dist/tools/gsc/experience.d.ts +1 -1
- package/mcp-server/dist/tools/gsc/experience.d.ts.map +1 -1
- package/mcp-server/dist/tools/gsc/experience.js +1 -1
- package/mcp-server/dist/tools/gsc/experience.js.map +1 -1
- package/mcp-server/dist/tools/gsc/indexing.d.ts +1 -1
- package/mcp-server/dist/tools/gsc/indexing.d.ts.map +1 -1
- package/mcp-server/dist/tools/gsc/indexing.js +1 -1
- package/mcp-server/dist/tools/gsc/indexing.js.map +1 -1
- package/mcp-server/dist/tools/gsc/inspect.d.ts +1 -1
- package/mcp-server/dist/tools/gsc/inspect.d.ts.map +1 -1
- package/mcp-server/dist/tools/gsc/inspect.js +1 -1
- package/mcp-server/dist/tools/gsc/inspect.js.map +1 -1
- package/mcp-server/dist/tools/gsc/navigate.d.ts +1 -1
- package/mcp-server/dist/tools/gsc/navigate.d.ts.map +1 -1
- package/mcp-server/dist/tools/gsc/navigate.js +1 -1
- package/mcp-server/dist/tools/gsc/navigate.js.map +1 -1
- package/mcp-server/dist/tools/gsc/performance.d.ts +1 -1
- package/mcp-server/dist/tools/gsc/performance.d.ts.map +1 -1
- package/mcp-server/dist/tools/gsc/performance.js +1 -1
- package/mcp-server/dist/tools/gsc/performance.js.map +1 -1
- package/mcp-server/dist/tools/gsc/settings.d.ts +1 -1
- package/mcp-server/dist/tools/gsc/settings.d.ts.map +1 -1
- package/mcp-server/dist/tools/gsc/settings.js +1 -1
- package/mcp-server/dist/tools/gsc/settings.js.map +1 -1
- package/mcp-server/dist/tools/image-tools.d.ts +1 -1
- package/mcp-server/dist/tools/image-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/image-tools.js +1 -1
- package/mcp-server/dist/tools/image-tools.js.map +1 -1
- package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +1 -1
- package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/leonardo-browser-tools.js +1 -1
- package/mcp-server/dist/tools/leonardo-browser-tools.js.map +1 -1
- package/mcp-server/dist/tools/loop.d.ts +1 -1
- package/mcp-server/dist/tools/loop.d.ts.map +1 -1
- package/mcp-server/dist/tools/loop.js +1 -1
- package/mcp-server/dist/tools/loop.js.map +1 -1
- package/mcp-server/dist/tools/memories.d.ts +1 -1
- package/mcp-server/dist/tools/memories.d.ts.map +1 -1
- package/mcp-server/dist/tools/memories.js +1 -1
- package/mcp-server/dist/tools/memories.js.map +1 -1
- package/mcp-server/dist/tools/morelogin.d.ts +1 -1
- package/mcp-server/dist/tools/morelogin.d.ts.map +1 -1
- package/mcp-server/dist/tools/morelogin.js +1 -1
- package/mcp-server/dist/tools/morelogin.js.map +1 -1
- package/mcp-server/dist/tools/profile.d.ts +1 -1
- package/mcp-server/dist/tools/profile.d.ts.map +1 -1
- package/mcp-server/dist/tools/profile.js +1 -1
- package/mcp-server/dist/tools/profile.js.map +1 -1
- package/mcp-server/dist/tools/recall.d.ts +1 -1
- package/mcp-server/dist/tools/recall.d.ts.map +1 -1
- package/mcp-server/dist/tools/recall.js +1 -1
- package/mcp-server/dist/tools/recall.js.map +1 -1
- package/mcp-server/dist/tools/reflect.d.ts +1 -1
- package/mcp-server/dist/tools/reflect.d.ts.map +1 -1
- package/mcp-server/dist/tools/reflect.js +1 -1
- package/mcp-server/dist/tools/reflect.js.map +1 -1
- package/mcp-server/dist/tools/remember.d.ts +1 -1
- package/mcp-server/dist/tools/remember.d.ts.map +1 -1
- package/mcp-server/dist/tools/remember.js +13 -11
- package/mcp-server/dist/tools/remember.js.map +1 -1
- package/mcp-server/dist/tools/restore.d.ts +1 -1
- package/mcp-server/dist/tools/restore.d.ts.map +1 -1
- package/mcp-server/dist/tools/restore.js +1 -1
- package/mcp-server/dist/tools/restore.js.map +1 -1
- package/mcp-server/dist/tools/style-guide-tools.d.ts +1 -1
- package/mcp-server/dist/tools/style-guide-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/style-guide-tools.js +1 -1
- package/mcp-server/dist/tools/style-guide-tools.js.map +1 -1
- package/mcp-server/dist/tools/sync.d.ts +1 -1
- package/mcp-server/dist/tools/sync.d.ts.map +1 -1
- package/mcp-server/dist/tools/sync.js +1 -1
- package/mcp-server/dist/tools/sync.js.map +1 -1
- package/mcp-server/dist/tools/tictactoe-tools.d.ts +1 -1
- package/mcp-server/dist/tools/tictactoe-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/tictactoe-tools.js +1 -1
- package/mcp-server/dist/tools/tictactoe-tools.js.map +1 -1
- package/mcp-server/dist/tools/utils.d.ts +1 -1
- package/mcp-server/dist/tools/utils.d.ts.map +1 -1
- package/mcp-server/dist/tools/utils.js +1 -1
- package/mcp-server/dist/tools/utils.js.map +1 -1
- package/mcp-server/dist/tools/whatsapp-send-file.d.ts +1 -1
- package/mcp-server/dist/tools/whatsapp-send-file.d.ts.map +1 -1
- package/mcp-server/dist/tools/whatsapp-send-file.js +1 -1
- package/mcp-server/dist/tools/whatsapp-send-file.js.map +1 -1
- package/mcp-server/dist/tools/whiteboard-tools.d.ts +3 -3
- package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/whiteboard-tools.js +1 -1
- package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -1
- package/mcp-server/dist/tools/youtube/analytics.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/analytics.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/analytics.js +1 -1
- package/mcp-server/dist/tools/youtube/analytics.js.map +1 -1
- package/mcp-server/dist/tools/youtube/download.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/download.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/download.js +1 -1
- package/mcp-server/dist/tools/youtube/download.js.map +1 -1
- package/mcp-server/dist/tools/youtube/media.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/media.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/media.js +1 -1
- package/mcp-server/dist/tools/youtube/media.js.map +1 -1
- package/mcp-server/dist/tools/youtube/metadata.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/metadata.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/metadata.js +1 -1
- package/mcp-server/dist/tools/youtube/metadata.js.map +1 -1
- package/mcp-server/dist/tools/youtube/navigate.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/navigate.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/navigate.js +1 -1
- package/mcp-server/dist/tools/youtube/navigate.js.map +1 -1
- package/mcp-server/dist/tools/youtube/playlist.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/playlist.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/playlist.js +1 -1
- package/mcp-server/dist/tools/youtube/playlist.js.map +1 -1
- package/mcp-server/dist/tools/youtube/schedule.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/schedule.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/schedule.js +1 -1
- package/mcp-server/dist/tools/youtube/schedule.js.map +1 -1
- package/mcp-server/dist/tools/youtube/source.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/source.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/source.js +1 -1
- package/mcp-server/dist/tools/youtube/source.js.map +1 -1
- package/mcp-server/dist/tools/youtube/upload.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/upload.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/upload.js +4 -9
- package/mcp-server/dist/tools/youtube/upload.js.map +1 -1
- package/mcp-server/dist/tui.js +16 -4
- package/mcp-server/dist/tui.js.map +1 -1
- package/mcp-server/package-lock.json +3 -3
- package/mcp-server/package.json +3 -3
- package/mcp-server/src/services/browser-bench.ts +1 -1
- package/mcp-server/src/services/categories.ts +77 -32
- package/mcp-server/src/services/desktop-bench.ts +1 -1
- package/mcp-server/src/tools/agents.ts +1 -1
- package/mcp-server/src/tools/bluesky.ts +1 -1
- package/mcp-server/src/tools/browser-advanced.ts +1 -1
- package/mcp-server/src/tools/browser-batch.ts +1 -1
- package/mcp-server/src/tools/browser-cheatsheet.ts +1 -1
- package/mcp-server/src/tools/browser-interact.ts +1 -1
- package/mcp-server/src/tools/browser-navigate.ts +1 -1
- package/mcp-server/src/tools/browser-observe.ts +1 -1
- package/mcp-server/src/tools/card-tools.ts +1 -1
- package/mcp-server/src/tools/category.ts +6 -1
- package/mcp-server/src/tools/choice.ts +1 -1
- package/mcp-server/src/tools/computer.ts +1 -1
- package/mcp-server/src/tools/discord-channel.ts +1 -1
- package/mcp-server/src/tools/discord-guild.ts +1 -1
- package/mcp-server/src/tools/discord-member.ts +1 -1
- package/mcp-server/src/tools/discord-message.ts +1 -1
- package/mcp-server/src/tools/discord-onboarding.ts +1 -1
- package/mcp-server/src/tools/discord-role.ts +1 -1
- package/mcp-server/src/tools/discord-thread.ts +1 -1
- package/mcp-server/src/tools/discord-webhook.ts +1 -1
- package/mcp-server/src/tools/fb-groups.ts +1 -1
- package/mcp-server/src/tools/forget.ts +1 -1
- package/mcp-server/src/tools/git-tools.ts +1 -1
- package/mcp-server/src/tools/gsc/experience.ts +1 -1
- package/mcp-server/src/tools/gsc/indexing.ts +1 -1
- package/mcp-server/src/tools/gsc/inspect.ts +1 -1
- package/mcp-server/src/tools/gsc/navigate.ts +1 -1
- package/mcp-server/src/tools/gsc/performance.ts +1 -1
- package/mcp-server/src/tools/gsc/settings.ts +1 -1
- package/mcp-server/src/tools/image-tools.ts +1 -1
- package/mcp-server/src/tools/leonardo-browser-tools.ts +1 -1
- package/mcp-server/src/tools/loop.ts +1 -1
- package/mcp-server/src/tools/memories.ts +1 -1
- package/mcp-server/src/tools/morelogin.ts +1 -1
- package/mcp-server/src/tools/profile.ts +1 -1
- package/mcp-server/src/tools/recall.ts +1 -1
- package/mcp-server/src/tools/reflect.ts +1 -1
- package/mcp-server/src/tools/remember.ts +13 -12
- package/mcp-server/src/tools/restore.ts +1 -1
- package/mcp-server/src/tools/style-guide-tools.ts +1 -1
- package/mcp-server/src/tools/sync.ts +1 -1
- package/mcp-server/src/tools/tictactoe-tools.ts +1 -1
- package/mcp-server/src/tools/utils.ts +1 -1
- package/mcp-server/src/tools/whatsapp-send-file.ts +1 -1
- package/mcp-server/src/tools/whiteboard-tools.ts +1 -1
- package/mcp-server/src/tools/youtube/analytics.ts +1 -1
- package/mcp-server/src/tools/youtube/download.ts +1 -1
- package/mcp-server/src/tools/youtube/media.ts +1 -1
- package/mcp-server/src/tools/youtube/metadata.ts +1 -1
- package/mcp-server/src/tools/youtube/navigate.ts +1 -1
- package/mcp-server/src/tools/youtube/playlist.ts +1 -1
- package/mcp-server/src/tools/youtube/schedule.ts +1 -1
- package/mcp-server/src/tools/youtube/source.ts +1 -1
- package/mcp-server/src/tools/youtube/upload.ts +4 -12
- package/mcp-server/src/tui.ts +22 -9
- package/neural-interface/i18n/en.json +236 -7
- package/neural-interface/i18n/pt-BR.json +238 -9
- package/neural-interface/lib/account-usage.js +5 -3
- package/neural-interface/lib/agent-sandbox-elevation.js +102 -0
- package/neural-interface/lib/agent-sandbox-setting.js +57 -0
- package/neural-interface/lib/app-controls-api.js +161 -0
- package/neural-interface/lib/assistant-api.js +40 -7
- package/neural-interface/lib/assistant-brains/opencode.js +13 -1
- package/neural-interface/lib/assistant-brains/opencode2-browser-policy/index.js +44 -0
- package/neural-interface/lib/assistant-brains/opencode2-route-gate/index.js +57 -0
- package/neural-interface/lib/assistant-catalog.js +17 -2
- package/neural-interface/lib/assistant-dispatch.js +3 -0
- package/neural-interface/lib/assistant-envelope.js +19 -1
- package/neural-interface/lib/assistant-route-gate-codex.js +3 -1
- package/neural-interface/lib/assistant-runtime.js +131 -8
- package/neural-interface/lib/claude-model-catalog.js +64 -14
- package/neural-interface/lib/codex-account-auth.js +4 -2
- package/neural-interface/lib/codex-accounts.js +14 -1
- package/neural-interface/lib/codex-settings-schema.js +111 -47
- package/neural-interface/lib/editor-completion-opencode.js +132 -35
- package/neural-interface/lib/exec-loop-command.js +11 -2
- package/neural-interface/lib/install-details.js +23 -5
- package/neural-interface/lib/launch-cache.js +293 -0
- package/neural-interface/lib/login-start.js +524 -0
- package/neural-interface/lib/native-loop-providers.js +24 -4
- package/neural-interface/lib/native-loop-runtime.js +19 -0
- package/neural-interface/lib/opencode-db-schema.js +75 -0
- package/neural-interface/lib/opencode-history.js +16 -1
- package/neural-interface/lib/opencode-protocol.js +173 -0
- package/neural-interface/lib/opencode-provider-view.js +81 -0
- package/neural-interface/lib/opencode-runtime-config.js +10 -3
- package/neural-interface/lib/opencode-serve-records.js +606 -0
- package/neural-interface/lib/opencode-v2-client.js +33 -6
- package/neural-interface/lib/opencode-v2-ws-requests.js +19 -5
- package/neural-interface/lib/opencode-worker-activity.js +229 -0
- package/neural-interface/lib/opencode2-client.js +760 -0
- package/neural-interface/lib/opencode2-proxy.js +116 -0
- package/neural-interface/lib/opencode2-translate.js +1008 -0
- package/neural-interface/lib/process-identity.js +361 -0
- package/neural-interface/lib/provider-panel-terminal-auth.js +3 -2
- package/neural-interface/lib/session-cache-builder.js +26 -5
- package/neural-interface/lib/session-indexer.js +3 -1
- package/neural-interface/lib/session-title-generator.js +20 -0
- package/neural-interface/lib/style-guide/api.js +4 -3
- package/neural-interface/lib/untrusted-file-headers.js +27 -0
- package/neural-interface/package-lock.json +1342 -44
- package/neural-interface/package.json +5 -1
- package/neural-interface/public/index.html +2 -2
- package/neural-interface/public/shared/account-menu.js +4 -1
- package/neural-interface/public/shared/account-usage.js +62 -2
- package/neural-interface/public/shared/account-view.js +2 -1
- package/neural-interface/public/shared/agent-runtime-options.js +55 -11
- package/neural-interface/public/shared/assistant/asst-account-menu.js +298 -0
- package/neural-interface/public/shared/assistant/asst-agents-dock.js +172 -17
- package/neural-interface/public/shared/assistant/asst-api.js +18 -3
- package/neural-interface/public/shared/assistant/asst-brain-picker.js +424 -152
- package/neural-interface/public/shared/assistant/asst-composer.js +1 -1
- package/neural-interface/public/shared/assistant/asst-hosts.js +49 -2
- package/neural-interface/public/shared/assistant/asst-menu.js +275 -77
- package/neural-interface/public/shared/assistant/asst-model-chip.js +135 -0
- package/neural-interface/public/shared/assistant/asst-panel.js +236 -35
- package/neural-interface/public/shared/assistant/asst-rack-styles.js +28 -10
- package/neural-interface/public/shared/assistant/asst-redact.js +186 -0
- package/neural-interface/public/shared/assistant/asst-render.js +382 -36
- package/neural-interface/public/shared/assistant/asst-run-stage.js +231 -0
- package/neural-interface/public/shared/assistant/asst-sanitize.js +193 -3
- package/neural-interface/public/shared/assistant/asst-scene-styles.js +273 -0
- package/neural-interface/public/shared/assistant/asst-scenes.js +528 -0
- package/neural-interface/public/shared/assistant/asst-sidepanel-styles.js +3 -15
- package/neural-interface/public/shared/assistant/asst-state.js +14 -0
- package/neural-interface/public/shared/assistant/asst-styles.js +109 -17
- package/neural-interface/public/shared/assistant/asst-tool-kinds.js +13 -1
- package/neural-interface/public/shared/cc-dropdown.js +480 -0
- package/neural-interface/public/shared/cdx/cdx-panel.js +14 -2
- package/neural-interface/public/shared/cdx/cdx-render.js +15 -3
- package/neural-interface/public/shared/cdx/cdx-styles.js +49 -5
- package/neural-interface/public/shared/cdx/cdx-tabs.js +152 -35
- package/neural-interface/public/shared/cp/cp-markdown.js +4 -57
- package/neural-interface/public/shared/data-cache.js +223 -0
- package/neural-interface/public/shared/desktop-bridge.js +11 -0
- package/neural-interface/public/shared/desktop-titlebar-view.js +78 -1
- package/neural-interface/public/shared/desktop-titlebar.js +214 -28
- package/neural-interface/public/shared/desktop-update-view.js +15 -5
- package/neural-interface/public/shared/file-links.js +73 -8
- package/neural-interface/public/shared/html-shell.js +74 -80
- package/neural-interface/public/shared/launch-prefetch.js +59 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-caps.js +3 -2
- package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +11 -3
- package/neural-interface/public/shared/ocp-v2/ocp-v2-modelpicker.js +54 -17
- package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +97 -3
- package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +3 -2
- package/neural-interface/public/shared/ocp-v2/ocp-v2-providers.js +11 -9
- package/neural-interface/public/shared/ocp-v2/ocp-v2-rehydrate.js +15 -4
- package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +1 -1
- package/neural-interface/public/shared/ocp-v2/ocp-v2-send-logic.js +401 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +16 -9
- package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +60 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +83 -5
- package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +195 -19
- package/neural-interface/public/shared/opencode-providers.js +39 -0
- package/neural-interface/public/shared/schedules-view.js +318 -0
- package/neural-interface/public/shared/settings/settings-app-pane.js +335 -0
- package/neural-interface/public/shared/settings/settings-app.js +243 -0
- package/neural-interface/public/shared/settings/settings-data.js +88 -0
- package/neural-interface/public/shared/settings/settings-ia.js +17 -0
- package/neural-interface/public/shared/showcase-privacy.js +2 -1
- package/neural-interface/public/shared/sidepanel-session-status.js +49 -0
- package/neural-interface/public/shared/styles.css +543 -372
- package/neural-interface/public/shared/ui-assistant.js +27 -5
- package/neural-interface/public/shared/ui-automation-studio.js +67 -27
- package/neural-interface/public/shared/ui-bookmarks.js +2 -1
- package/neural-interface/public/shared/ui-claude-panel.js +126 -12
- package/neural-interface/public/shared/ui-codex-panel.js +1 -0
- package/neural-interface/public/shared/ui-detail.js +6 -6
- package/neural-interface/public/shared/ui-explorer.js +2 -0
- package/neural-interface/public/shared/ui-file-links.js +1 -0
- package/neural-interface/public/shared/ui-image-gallery.js +6 -5
- package/neural-interface/public/shared/ui-invite.js +18 -2
- package/neural-interface/public/shared/ui-link.js +9 -9
- package/neural-interface/public/shared/ui-menubar.js +232 -33
- package/neural-interface/public/shared/ui-native-loop-router.js +2 -0
- package/neural-interface/public/shared/ui-opencode-panel-v2.js +1 -0
- package/neural-interface/public/shared/ui-schedules-studio.js +2099 -869
- package/neural-interface/public/shared/ui-sessions.js +15 -4
- package/neural-interface/public/shared/ui-settings.js +87 -36
- package/neural-interface/public/shared/ui-sidebar.js +4 -4
- package/neural-interface/public/shared/ui-sidepanel-session-entry.js +13 -0
- package/neural-interface/public/shared/ui-sidepanel-sessions.js +55 -4
- package/neural-interface/public/shared/ui-sidepanel-tray.js +84 -8
- package/neural-interface/public/shared/ui-skills.js +70 -12
- package/neural-interface/public/shared/ui-sync.js +9 -0
- package/neural-interface/public/shared/ui-terminal.js +36 -20
- package/neural-interface/public/shared/ui-trash.js +8 -1
- package/neural-interface/public/shared/ui-tutorial-steps.js +7 -3
- package/neural-interface/public/shared/ui-tutorial.js +15 -5
- package/neural-interface/public/shared/ui-update.js +87 -16
- package/neural-interface/public/shared/ui-whiteboard.js +2 -1
- package/neural-interface/public/variant/2d/main.js +4 -1
- package/neural-interface/public/variant/3d/main.js +3 -0
- package/neural-interface/public/vendor/highlight/LICENSE +29 -0
- package/neural-interface/public/vendor/highlight/github-dark-dimmed-11.12.0.min.css +9 -0
- package/neural-interface/public/vendor/highlight/highlight-11.12.0.min.js +1262 -0
- package/neural-interface/public/vendor/highlight/manifest.json +5 -0
- package/neural-interface/public/vendor/html2canvas/LICENSE +22 -0
- package/neural-interface/public/vendor/html2canvas/html2canvas-1.4.1.min.js +20 -0
- package/neural-interface/public/vendor/html2canvas/manifest.json +4 -0
- package/neural-interface/public/vendor/marked/LICENSE.md +44 -0
- package/neural-interface/public/vendor/marked/manifest.json +4 -0
- package/neural-interface/public/vendor/marked/marked-14.1.4.esm.js +2502 -0
- package/neural-interface/public/vendor/mermaid/LICENSE +21 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/abnfDiagram-PAR5IXJI.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/architecture-7GRP2DOG-M7G3SWCO.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/architectureDiagram-2PNWDENW.mjs +36 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/blockDiagram-PUWGUBOA.mjs +129 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/c4Diagram-3NLNHZP5.mjs +38 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-2NMSUPJH.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-32MCUW2P.mjs +206 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-3NPNU5GP.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-3SMGFRGC.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-4CAJECRU.mjs +14 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-4OADUZ5Q.mjs +10 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5IMINLNL.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5IQCK5RY.mjs +3 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5MVFYWFU.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-AQ6EADP3.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-AZZRMDJM.mjs +15 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-CLS4B6BI.mjs +168 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-DZP67EKU.mjs +70 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-EICP7K5X.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-GDY2UAB4.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-H7VHZCWX.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-IJBDOHL6.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JFFVMJIA.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JQRUD6KW.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JZGDI5JK.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-KD6SPIPN.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-NF366YI6.mjs +231 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-NUDPKBEF.mjs +32 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-OJINMHTS.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-Q6NGPIAH.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-QJSWEUOL.mjs +132 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-R7JDMUKV.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-RCXAM2GK.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-RT4MAWR3.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-SFMINX4W.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-SLDQ463B.mjs +88 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-STOV2HOB.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-T5OCTHI4.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-TCEHX7R3.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VQC2EELJ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VRZKL3EH.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VTHDQ7BV.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VY2OSTJR.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-WUBWJARI.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-YBMQ5JGJ.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-YDMLL4PJ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-Z6V44ARX.mjs +62 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZJJ7VQJP.mjs +339 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZNLK7HRR.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZQN7UHIL.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZS6VBONO.mjs +174 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZUNWM646.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/classDiagram-FGAMPOII.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/classDiagram-v2-AI5RJEK4.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cose-bilkent-Q72C2OJ3.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cynefin-OW5HDTMX-6OCTWOGG.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cynefinDiagram-2OOWUY4M.mjs +62 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/dagre-MPVFI544.mjs +4 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-AE4NWXFW.mjs +24 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-BUJID5UG.mjs +41 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-C44CZ5NI.mjs +24 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-EYOLEXXS.mjs +30 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-P7B6PWOJ.mjs +3 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ebnfDiagram-FTPZ3PV6.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/erDiagram-H3ERR26V.mjs +99 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/eventmodeling-NTZA5JFV-WKSWQHFS.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/flowDiagram-YHGXBVSY.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ganttDiagram-RWFTB7ED.mjs +292 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/gitGraph-4MIJSDKK-JH2HKYUO.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/gitGraphDiagram-MAR6GKOP.mjs +106 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/info-A6RAGUB7-3TX3OFWW.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/infoDiagram-LV547AFH.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ishikawaDiagram-PUJQGNDS.mjs +70 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/journeyDiagram-EW5QJT4W.mjs +139 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/kanban-definition-JSQERAZB.mjs +89 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/katex-CZ4GXH2S.mjs +257 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/mindmap-definition-VBJCLQLM.mjs +96 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/packet-AYTQ26CC-MKII6P3Y.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pegDiagram-7WILOQTJ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pie-WAS4IAKB-6B4OPMJ5.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pieDiagram-EFA7CBSB.mjs +39 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/quadrantDiagram-WARVYA7P.mjs +7 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/radar-RG4KPBEZ-UPTR3XUL.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-74A4TZTK-MEFUPFMS.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-abnf-HS5TGJTU-R5YG2S5D.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-ebnf-LZEXJU2U-G5QEX2L6.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-peg-WCYAUIDC-H5I2ZRY2.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroadDiagram-5NIQVNLQ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/requirementDiagram-SXREGOKZ.mjs +84 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sankeyDiagram-VV74M2VP.mjs +40 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sequenceDiagram-52ZFIFDL.mjs +162 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sizeCapture-FGA5AGYP.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/stateDiagram-3QAKPIVI.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/stateDiagram-v2-HN2P4RDZ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/swimlanes-QLVP42QD.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/swimlanesDiagram-JKPDBFCN.mjs +8 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/timeline-definition-GS45XAXW.mjs +120 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/treeView-Q6P3EWNA-ZRJGANNQ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/treemap-WGGIJYW6-K64VN5AS.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/vennDiagram-QIQU2ZRJ.mjs +34 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/wardley-WFR3VGLG-D67OWCCH.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/wardleyDiagram-U6YNM66N.mjs +78 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/xychartDiagram-XJAZEDNM.mjs +7 -0
- package/neural-interface/public/vendor/mermaid/manifest.json +4 -0
- package/neural-interface/public/vendor/mermaid/mermaid-11.17.2.esm.min.mjs +14 -0
- package/neural-interface/scripts/build-vendor.mjs +84 -3
- package/neural-interface/scripts/rebuild-pty.js +14 -2
- package/neural-interface/server.js +1279 -372
- package/npm-shrinkwrap.json +4424 -0
- package/package.json +54 -2
- package/postinstall.js +61 -47
- package/preuninstall.js +8 -35
- package/setup.js +76 -44
- package/skills/synabun/modules/idea.md +1 -1
- package/skills/synabun/modules/schedule.md +2 -2
- package/updater.cmd +2 -2
- package/updater.mjs +97 -3
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════
|
|
2
|
+
// SynaBun Assistant — what the composer's model chip says
|
|
3
|
+
// ═══════════════════════════════════════════
|
|
4
|
+
// The model as a short human name from its catalog label ("Opus 5.5 (1M
|
|
5
|
+
// context)" → "Opus 5.5", "Default (recommended) — Opus 5.5" → "Opus 5.5"),
|
|
6
|
+
// a context tag for a "[1m]" / "[extended]" variant ("1M"), and the forms the
|
|
7
|
+
// chip falls back to when the composer row has no room, longest first: the tag
|
|
8
|
+
// goes first, then the account cue, then the API badge, then the name shortens
|
|
9
|
+
// by whole words, to a form that still names this model alone when there is one
|
|
10
|
+
// ("Opus 5.5" → "Opus", "GPT-6-Luna" → "Luna"). Never a cut word.
|
|
11
|
+
// asst-brain-picker.js draws the first form that fits. DOM-free: node --test loads it.
|
|
12
|
+
|
|
13
|
+
const VARIANT = /\[(1m|extended)\]$/i;
|
|
14
|
+
const VERSION = /^v?\d+(?:\.\d+)*[a-z]?$/i;
|
|
15
|
+
|
|
16
|
+
function str(v) {
|
|
17
|
+
return v == null ? '' : String(v).trim();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** The id without its provider ("anthropic/…"), legacy ":<window>" and variant suffix. */
|
|
21
|
+
function bareId(id) {
|
|
22
|
+
const tail = str(id).split('/').pop() || '';
|
|
23
|
+
return tail.replace(/:\d+$/, '').replace(VARIANT, '');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The model's short name: { name, raw }. The label's own words without what the
|
|
28
|
+
* chip says otherwise (parentheses: the context, "recommended"); after a dash, the
|
|
29
|
+
* model it runs as. No label (or the id itself): the bare id, `raw` (shown mono).
|
|
30
|
+
*/
|
|
31
|
+
export function modelChipName(label, id) {
|
|
32
|
+
let text = str(label);
|
|
33
|
+
if (text && text !== str(id)) {
|
|
34
|
+
const runsAs = text.split(/\s+[—–]\s+/).pop();
|
|
35
|
+
text = str(runsAs.replace(/\s*\([^)]*\)/g, '').replace(/\s+/g, ' '));
|
|
36
|
+
if (text) return { name: text, raw: false };
|
|
37
|
+
}
|
|
38
|
+
const name = bareId(id) || str(id);
|
|
39
|
+
return { name, raw: true };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** "1M", "400K": a context window in tokens, never rounded up. */
|
|
43
|
+
function compactTokens(n) {
|
|
44
|
+
const v = Number(n);
|
|
45
|
+
if (!Number.isFinite(v) || v <= 0) return '';
|
|
46
|
+
if (v >= 1e6) return `${Math.floor(v / 1e5) / 10}M`;
|
|
47
|
+
if (v >= 1e3) return `${Math.floor(v / 1e3)}K`;
|
|
48
|
+
return String(v);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* What tells a context variant from its model ("opus[1m]" → "1M"): its window when
|
|
53
|
+
* the catalog knows it, else "1M" for "[1m]", else the label's own word ("extended").
|
|
54
|
+
* '' for a model that is not a variant.
|
|
55
|
+
*/
|
|
56
|
+
export function modelChipTag(id, { contextWindow = null, label = '' } = {}) {
|
|
57
|
+
const m = str(id).match(VARIANT);
|
|
58
|
+
if (!m) return '';
|
|
59
|
+
const tokens = compactTokens(contextWindow);
|
|
60
|
+
if (tokens) return tokens;
|
|
61
|
+
if (m[1].toLowerCase() === '1m') return '1M';
|
|
62
|
+
const note = str(label).match(/\(([^)]*)\)\s*$/);
|
|
63
|
+
return note ? str(note[1].replace(/\bcontext\b/i, '')) : '';
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// "GPT-6.1-Sol" → ['GPT', '6.1', 'Sol'] with the separators kept: whole words in, whole words out.
|
|
67
|
+
function parts(name) {
|
|
68
|
+
return str(name).match(/[^\s-]+|[\s-]+/g) || [];
|
|
69
|
+
}
|
|
70
|
+
const isSep = (p) => /^[\s-]+$/.test(p);
|
|
71
|
+
const wordsOf = (name) => parts(name).filter(p => !isSep(p)).map(w => w.toLowerCase());
|
|
72
|
+
|
|
73
|
+
/** Whether `words` run in that order, whole, somewhere in `other` ("opus" in "Opus 5.5"). */
|
|
74
|
+
function within(words, other) {
|
|
75
|
+
for (let i = 0; i + words.length <= other.length; i += 1) {
|
|
76
|
+
if (words.every((w, j) => other[i + j] === w)) return true;
|
|
77
|
+
}
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The name's shorter forms, whole words only, longest first: `unique` still names this
|
|
83
|
+
* model alone among `names` (the short names of every model the provider lists: "Opus"
|
|
84
|
+
* for "Opus 5.5", "GPT-6.1" for "GPT-6.1-Sol", "Luna" for "GPT-6-Luna" when every
|
|
85
|
+
* "GPT-6" is another model too), `other` drops trailing words whatever they lose
|
|
86
|
+
* ("Sonnet" for "Sonnet 5.5" beside "Sonnet 5"; "GPT-6"). A form never starts with a
|
|
87
|
+
* version ("5.5"), and a suffix is tried only when no shorter prefix is unique.
|
|
88
|
+
*/
|
|
89
|
+
export function modelChipShortNames(name, names = []) {
|
|
90
|
+
const all = parts(name);
|
|
91
|
+
const own = wordsOf(name);
|
|
92
|
+
const others = [...new Set((Array.isArray(names) ? names : []).map(str).filter(n => n && n.toLowerCase() !== str(name).toLowerCase()))].map(wordsOf);
|
|
93
|
+
const unique = (form) => { const w = wordsOf(form); return !others.some(o => within(w, o)); };
|
|
94
|
+
const prefixes = [];
|
|
95
|
+
const suffixes = [];
|
|
96
|
+
for (let n = own.length - 1; n >= 1; n -= 1) {
|
|
97
|
+
let seen = 0;
|
|
98
|
+
const cut = all.findIndex(p => !isSep(p) && ++seen > n);
|
|
99
|
+
prefixes.push(all.slice(0, cut).join('').replace(/[\s-]+$/, ''));
|
|
100
|
+
let skip = own.length - n;
|
|
101
|
+
const from = all.findIndex(p => !isSep(p) && skip-- === 0);
|
|
102
|
+
if (!VERSION.test(all[from])) suffixes.push(all.slice(from).join(''));
|
|
103
|
+
}
|
|
104
|
+
const lossless = prefixes.filter(unique);
|
|
105
|
+
const picked = lossless.length ? lossless : suffixes.filter(unique);
|
|
106
|
+
return { unique: picked, other: prefixes.filter(p => !picked.includes(p)) };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* The chip's forms, longest first: [{ name, tag, cue, api }] (tag / cue / api: shown
|
|
111
|
+
* or not). `tag`, `cue` and `api` say whether the chip has one at all; `names` are the
|
|
112
|
+
* provider's models (modelChipShortNames). What goes, in order: the tag, the account
|
|
113
|
+
* cue, the API badge, then the name. A shorter name that still names this model alone
|
|
114
|
+
* loses nothing, so it is tried before the cue and before the badge go; one that
|
|
115
|
+
* loses something only after.
|
|
116
|
+
*/
|
|
117
|
+
export function modelChipForms({ name, names = [], tag = false, cue = false, api = false } = {}) {
|
|
118
|
+
const full = str(name);
|
|
119
|
+
const out = [];
|
|
120
|
+
const seen = new Set();
|
|
121
|
+
const add = (n, t, c, a) => {
|
|
122
|
+
const form = { name: n, tag: !!(t && tag), cue: !!(c && cue), api: !!(a && api) };
|
|
123
|
+
const key = JSON.stringify(form);
|
|
124
|
+
if (!seen.has(key)) { seen.add(key); out.push(form); }
|
|
125
|
+
};
|
|
126
|
+
const short = full ? modelChipShortNames(full, names) : { unique: [], other: [] };
|
|
127
|
+
add(full, true, true, true);
|
|
128
|
+
add(full, false, true, true);
|
|
129
|
+
for (const u of short.unique) add(u, false, true, true);
|
|
130
|
+
add(full, false, false, true);
|
|
131
|
+
for (const u of short.unique) add(u, false, false, true);
|
|
132
|
+
add(full, false, false, false);
|
|
133
|
+
for (const n of [...short.unique, ...short.other]) add(n, false, false, false);
|
|
134
|
+
return out;
|
|
135
|
+
}
|
|
@@ -51,20 +51,21 @@ import { cachedProjects, createBrainPicker, testDensityLabel } from './asst-brai
|
|
|
51
51
|
import { createRovingToolbar } from './asst-roving.js';
|
|
52
52
|
import { openAccountsManager } from './asst-accounts.js';
|
|
53
53
|
import { createAgentsDock } from './asst-agents-dock.js';
|
|
54
|
+
import { activityOf } from './asst-scenes.js';
|
|
54
55
|
import { createUsageGauge } from './asst-usage.js';
|
|
55
|
-
import { closeMenu, isMenuOpen, openMenu } from './asst-menu.js';
|
|
56
|
+
import { closeMenu, currentMenuAnchor, isMenuOpen, openMenu } from './asst-menu.js';
|
|
56
57
|
import { createRouteModeControl, openModelsManager, openRoutesEditor, refreshModelsManager, renderRouteCard, routeModeLabel } from './asst-route.js';
|
|
57
58
|
import { budgetChipText, budgetSpendText, budgetTone, closeBudgetEditor, createBudgetController, mountBudgetChip, openBudgetEditor } from './asst-budget.js';
|
|
58
59
|
import { computerRemoteView, createComputerPanel, createComputerToggle, normalizeComputerRemote, openFrameLightbox, closeFrameLightbox, requestDesktopStop } from './asst-computer.js';
|
|
59
60
|
import {
|
|
60
61
|
applyLimit, applyLimitPacket, applyUsagePacket, brainLabel, createRenameWriter, createTabState, DEFAULT_ROUTE_MODE, deserializeTabState, fmtCost, fmtRunLine, limitExpiresIn, limitNoticeText, modelShortName,
|
|
61
62
|
brainModePatch, normalizeBrain, normalizeComputerMode, permissionModeLabel, normalizeRouteMode, normalizeTestDensity, projectLabel, providerShortLabel, readStoredBrain, runFromPayload,
|
|
62
|
-
serializeTabState, tabStorageKey, userSessionTitle,
|
|
63
|
+
serializeTabState, sessionStatus, tabStorageKey, userSessionTitle,
|
|
63
64
|
} from './asst-state.js';
|
|
64
65
|
import {
|
|
65
66
|
closeAssistantSession, dispatchAssistantRun, escalateAssistantRun, focusAssistantRun, getAssistantRun,
|
|
66
67
|
fetchManageCatalog, getAssistantRunResult, getAssistantSession, getAssistantSessionUsage, getDesktopStatus, getRouting, killAllAssistantRuns, removeAssistantRun, clearFinishedAssistantRuns,
|
|
67
|
-
listAssistantSessions, patchAssistantSession, patchHiddenModels, stopAssistantRun, uploadAssistantAttachment,
|
|
68
|
+
listAssistantSessions, patchAssistantSession, patchHiddenModels, setAdminSandbox, stopAssistantRun, uploadAssistantAttachment,
|
|
68
69
|
} from './asst-api.js';
|
|
69
70
|
|
|
70
71
|
const ICON_SESSIONS = '<svg viewBox="0 0 24 24"><path d="M3 6h18M3 12h18M3 18h12"/></svg>';
|
|
@@ -74,6 +75,7 @@ const ICON_COG = '<svg viewBox="0 0 24 24"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v
|
|
|
74
75
|
const ICON_ROUTE = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7h13l-3-3M20 17H7l3 3"/></svg>';
|
|
75
76
|
const ICON_COMPUTER = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="12" rx="2"/><path d="M8 20h8M12 16v4"/></svg>';
|
|
76
77
|
const ICON_CLOSE = '<svg viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>';
|
|
78
|
+
const ICON_TRASH = '<svg viewBox="0 0 24 24"><path d="M3 6h18M8 6V4.5A1.5 1.5 0 0 1 9.5 3h5A1.5 1.5 0 0 1 16 4.5V6M18.5 6l-.8 13a2 2 0 0 1-2 1.9H8.3a2 2 0 0 1-2-1.9L5.5 6M10 11v6M14 11v6"/></svg>';
|
|
77
79
|
const REPLAY_WAIT_MS = 1500; // a replay that stops short of its count is drawn after this long
|
|
78
80
|
|
|
79
81
|
function el(tag, className, text) {
|
|
@@ -148,14 +150,17 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
148
150
|
usageView: saved?.usageView || null,
|
|
149
151
|
});
|
|
150
152
|
Object.assign(st, {
|
|
151
|
-
status: 'idle',
|
|
153
|
+
status: 'idle', // the brain's own: its turn, its cards (setStatus)
|
|
154
|
+
workers: { working: 0, waiting: 0 }, // its dispatched agents, from the agents tray (sessionStatus)
|
|
155
|
+
shownStatus: 'idle', // what the host shows: both together (pushStatus)
|
|
152
156
|
dispatchUsd: 0,
|
|
153
157
|
serverCost: false,
|
|
154
158
|
engine: '',
|
|
155
159
|
sdkVersion: '',
|
|
156
160
|
routing: null, // server view { mode, effectiveMode, defaultMode, askBelow }
|
|
157
|
-
features: { routing: null, computer: null, testDensity: null, rename: null }, // null = unknown yet
|
|
161
|
+
features: { routing: null, computer: null, testDensity: null, rename: null, adminSandbox: null }, // null = unknown yet
|
|
158
162
|
testDensityEffective: null, // server view: the level in effect
|
|
163
|
+
adminSandbox: null, // server view: the global Admin sandbox setting (every agent)
|
|
159
164
|
brainCapabilities: null,
|
|
160
165
|
computerEffective: st.computerUse === true,
|
|
161
166
|
desktopSupported: null,
|
|
@@ -164,6 +169,9 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
164
169
|
desktopProbe: false,
|
|
165
170
|
routingProbe: false,
|
|
166
171
|
sessionTitle: String(session?.title || ''), // the server's name (the user's rename, else the first prompt): history + notifications
|
|
172
|
+
// Whether this session holds a chat (a prompt was sent): until then the server keeps it as a draft,
|
|
173
|
+
// New reuses it, and leaving it for another session closes it (nothing of it is stored).
|
|
174
|
+
chatStarted: !!session?.chatStartedAt || Number(session?.turns) > 0,
|
|
167
175
|
});
|
|
168
176
|
let recordName = userSessionTitle(session); // the name the session record holds as the user's ('' = never renamed)
|
|
169
177
|
const controls = new Map(); // requestId → { card, origin, kind }
|
|
@@ -314,18 +322,33 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
314
322
|
notify(host.notifySource || 'cli', type, notifyLabel(), { sessionId, provider: 'assistant', panel: 'assistant' });
|
|
315
323
|
}
|
|
316
324
|
|
|
317
|
-
/** root[data-status] and data-computer drive status styling (the live dot, the Computer switch). */
|
|
325
|
+
/** root[data-status] (the session's status, sessionStatus) and data-computer drive status styling (the live dot, the Computer switch). */
|
|
318
326
|
function renderStatus() {
|
|
319
|
-
root.dataset.status = st.
|
|
327
|
+
root.dataset.status = st.shownStatus || 'idle';
|
|
320
328
|
if (st.desktopActive) root.dataset.computer = 'active';
|
|
321
329
|
else delete root.dataset.computer;
|
|
322
330
|
}
|
|
323
331
|
|
|
332
|
+
/** The brain's own status: its turn ('working', 'done', 'idle') and its cards ('action'). */
|
|
324
333
|
function setStatus(status) {
|
|
325
334
|
st.status = status || 'idle';
|
|
326
|
-
|
|
335
|
+
pushStatus(true);
|
|
327
336
|
syncBlocked();
|
|
328
|
-
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* What the host shows (tray pill, header, terminal badge) is the session's status: the brain's own and
|
|
341
|
+
* its dispatched agents' together (asst-state.js sessionStatus), so the gold stays while a worker works
|
|
342
|
+
* after the turn that dispatched it ended, and a worker that waits on you makes the session need you.
|
|
343
|
+
* The brain's own changes always reach the host; a change of the agents' counts only when the status moved.
|
|
344
|
+
*/
|
|
345
|
+
function pushStatus(always = false) {
|
|
346
|
+
if (destroyed) return;
|
|
347
|
+
const next = sessionStatus(st.status, st.workers);
|
|
348
|
+
if (!always && next === st.shownStatus) return;
|
|
349
|
+
st.shownStatus = next;
|
|
350
|
+
renderStatus();
|
|
351
|
+
try { host.setStatus?.(next); } catch { /* ignore */ }
|
|
329
352
|
}
|
|
330
353
|
|
|
331
354
|
/**
|
|
@@ -583,6 +606,9 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
583
606
|
// Test density sits right after the permission mode; hidden on a server that does not know it.
|
|
584
607
|
getTestDensity: () => testDensityView(),
|
|
585
608
|
onTestDensity: (level) => setTestDensity(level),
|
|
609
|
+
// The global Admin sandbox switch, in the permission menu; hidden on a server that does not serve it.
|
|
610
|
+
getAdminSandbox: () => adminSandboxView(),
|
|
611
|
+
onAdminSandbox: (enabled) => changeAdminSandbox(enabled),
|
|
586
612
|
// The registered projects arrived: their labels name the project in the fields and the "Fix … in" suggestion.
|
|
587
613
|
onProjects: () => { picker.render(); renderer.refreshEmpty(); },
|
|
588
614
|
});
|
|
@@ -628,13 +654,24 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
628
654
|
onStopAll: () => stopAll(),
|
|
629
655
|
onRemove: (runId) => removeRun(runId),
|
|
630
656
|
onClearFinished: () => clearFinished(),
|
|
657
|
+
// A mini scene or a lane: that run's card in the transcript (drawn first when this window never got it).
|
|
658
|
+
onReveal: (runId) => {
|
|
659
|
+
if (renderer.revealRun(runId)) return;
|
|
660
|
+
const run = dock.getRun(runId);
|
|
661
|
+
if (run) { renderer.restoreRuns([run]); renderer.revealRun(runId); }
|
|
662
|
+
},
|
|
663
|
+
// Whatever told the tray (the sync bus, its fetch), the transcript's card and route line follow.
|
|
664
|
+
onRunChange: (run) => renderer.syncRun(run),
|
|
631
665
|
onToggle: (open) => { st.dockOpen = open; agentsBtn.setAttribute('aria-pressed', open ? 'true' : 'false'); persist(); },
|
|
632
666
|
onShowAllChange: (showAll) => { st.dockShowAll = showAll; persist(); },
|
|
633
|
-
onCountChange: ({ total, active, attention, visible: shown }) => {
|
|
667
|
+
onCountChange: ({ total, active, attention, working = 0, waiting = 0, visible: shown }) => {
|
|
634
668
|
agentsCount.textContent = String(active || total);
|
|
635
669
|
agentsCount.classList.toggle('attention', attention > 0);
|
|
636
670
|
agentsBtn.hidden = !shown;
|
|
637
671
|
agentsBtn.classList.toggle('attention', attention > 0);
|
|
672
|
+
// Whatever told the tray (this socket, the sync bus, its fetch after a reload): the session's status follows.
|
|
673
|
+
st.workers = { working, waiting };
|
|
674
|
+
pushStatus();
|
|
638
675
|
},
|
|
639
676
|
});
|
|
640
677
|
agentsBtn.setAttribute('aria-pressed', st.dockOpen ? 'true' : 'false');
|
|
@@ -773,6 +810,8 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
773
810
|
lockControl(packet.request_id, resolvedLabel(packet.origin, tt('assistant.control.state.answered', 'Answered')));
|
|
774
811
|
return;
|
|
775
812
|
case 'reattach_result':
|
|
813
|
+
// Whether a turn runs now: a route the journal left open is that turn's, or nobody's.
|
|
814
|
+
renderer.reattached(!!(packet.ok && packet.running));
|
|
776
815
|
if (packet.ok) {
|
|
777
816
|
if (packet.sessionId) st.providerSessionId = packet.sessionId;
|
|
778
817
|
if (packet.resynced) rehydrate({ force: true });
|
|
@@ -801,6 +840,8 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
801
840
|
finishTurn({ aborted: true });
|
|
802
841
|
return;
|
|
803
842
|
case 'error': {
|
|
843
|
+
// The server no longer has this session: no error row and no retry loop; the host closes the tab.
|
|
844
|
+
if (packet.code === 'SESSION_NOT_FOUND') { sessionGone(); return; }
|
|
804
845
|
// A rejected route answer keeps its card open with the message.
|
|
805
846
|
const routeCard = packet.request_id ? routeCardByRequest(packet.request_id) : null;
|
|
806
847
|
if (routeCard) { routeCard.fail(packet.message); return; }
|
|
@@ -926,6 +967,7 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
926
967
|
if (meta.id && meta.id !== sessionId) return;
|
|
927
968
|
// The server's title names the conversation (history, notifications); the tab's name is the host's.
|
|
928
969
|
applyRecordName(meta);
|
|
970
|
+
if (meta.chatStartedAt || Number(meta.turns) > 0) st.chatStarted = true;
|
|
929
971
|
if (meta.brain && typeof meta.brain === 'object') {
|
|
930
972
|
const next = normalizeBrain({ ...st.brain, ...meta.brain, provider: meta.brain.provider || meta.brain.brain || st.brain.provider });
|
|
931
973
|
if (JSON.stringify(next) !== JSON.stringify(st.brain)) { st.brain = next; picker.render(); host.setBrain?.(next); persist(); }
|
|
@@ -950,7 +992,9 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
950
992
|
if (typeof meta.features.computer === 'boolean') st.features.computer = meta.features.computer;
|
|
951
993
|
if (typeof meta.features.testDensity === 'boolean') st.features.testDensity = meta.features.testDensity;
|
|
952
994
|
if (typeof meta.features.rename === 'boolean') st.features.rename = meta.features.rename;
|
|
995
|
+
if (typeof meta.features.adminSandbox === 'boolean') st.features.adminSandbox = meta.features.adminSandbox;
|
|
953
996
|
}
|
|
997
|
+
if (typeof meta.adminSandbox === 'boolean') st.adminSandbox = meta.adminSandbox;
|
|
954
998
|
if ('testDensityExplicit' in meta) st.testDensity = normalizeTestDensity(meta.testDensityExplicit, null);
|
|
955
999
|
if (meta.testDensity) st.testDensityEffective = normalizeTestDensity(meta.testDensity);
|
|
956
1000
|
if (typeof meta.computerUse === 'boolean') st.computerEffective = meta.computerUse;
|
|
@@ -1066,6 +1110,31 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1066
1110
|
if (!quiet) renderer.appendStatus(tt('assistant.status.testDensity', 'Test density: {level}', { level: testDensityLabel(next, t) }));
|
|
1067
1111
|
}
|
|
1068
1112
|
|
|
1113
|
+
/** The global Admin sandbox setting (true / false), or null while the server does not serve it. */
|
|
1114
|
+
function adminSandboxView() {
|
|
1115
|
+
if (st.features.adminSandbox !== true || typeof st.adminSandbox !== 'boolean') return null;
|
|
1116
|
+
return st.adminSandbox;
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
/** Every agent SynaBun starts follows it; every window hears the change (sync:agents:admin-sandbox-changed). */
|
|
1120
|
+
async function changeAdminSandbox(enabled) {
|
|
1121
|
+
const before = st.adminSandbox;
|
|
1122
|
+
st.adminSandbox = enabled === true;
|
|
1123
|
+
picker.render();
|
|
1124
|
+
try {
|
|
1125
|
+
const view = await setAdminSandbox(st.adminSandbox);
|
|
1126
|
+
if (typeof view?.adminSandbox === 'boolean') st.adminSandbox = view.adminSandbox;
|
|
1127
|
+
picker.render();
|
|
1128
|
+
renderer.appendStatus(st.adminSandbox
|
|
1129
|
+
? tt('assistant.adminSandbox.statusOn', 'Admin sandbox: on. On Windows, Codex may ask for administrator approval once per account to set up its sandbox.')
|
|
1130
|
+
: tt('assistant.adminSandbox.statusOff', 'Admin sandbox: off. No agent SynaBun starts asks for administrator approval for a sandbox.'));
|
|
1131
|
+
} catch (err) {
|
|
1132
|
+
st.adminSandbox = before;
|
|
1133
|
+
picker.render();
|
|
1134
|
+
toast(err?.message || String(err));
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1069
1138
|
/** Fresh tabs inherit the last-used test density (like the route mode). */
|
|
1070
1139
|
function applyLastUsedTestDensity() {
|
|
1071
1140
|
if (saved || st.features.testDensity !== true || st.testDensity != null) return;
|
|
@@ -1312,6 +1381,7 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1312
1381
|
st.turnStartedAt = Date.now();
|
|
1313
1382
|
setRunning(true);
|
|
1314
1383
|
sock.send(msg);
|
|
1384
|
+
st.chatStarted = true; // the server stores the session with this prompt
|
|
1315
1385
|
// Name the conversation like the server will (its first prompt) — not the tab.
|
|
1316
1386
|
if (!st.userRenamed && (!st.sessionTitle || /^(?:SynaBun|Assistant(?: \d+)?)$/.test(st.sessionTitle))) {
|
|
1317
1387
|
const guess = String(payload.text || '').split('\n')[0].trim().slice(0, 60);
|
|
@@ -1473,15 +1543,34 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1473
1543
|
if (!st.running) setRunning(true, { label: tt('assistant.compacting', 'compacting…') });
|
|
1474
1544
|
}
|
|
1475
1545
|
|
|
1546
|
+
/** Nobody chatted in this session yet (and nothing runs in it): New reuses it, leaving it closes it. */
|
|
1547
|
+
function unused() {
|
|
1548
|
+
return !st.chatStarted && !st.running;
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1476
1551
|
function newSession(provider) {
|
|
1477
1552
|
const b = provider ? normalizeBrain({ ...st.brain, provider, model: '', effort: null, agent: null, accountId: null }) : st.brain;
|
|
1553
|
+
// This one is still empty: it is the new session (the server keeps one draft, not a pile of them).
|
|
1554
|
+
// /new <provider> switches its brain as the picker does; what only this page showed (/help) is cleared.
|
|
1555
|
+
if (unused() && !destroyed) {
|
|
1556
|
+
if (provider && provider !== st.brain.provider) applyBrain(b, { requiresSwitch: true, field: 'provider' });
|
|
1557
|
+
if (!renderer.isEmpty()) clearTranscript();
|
|
1558
|
+
composer.focus();
|
|
1559
|
+
return;
|
|
1560
|
+
}
|
|
1478
1561
|
emit('assistant:new', { brain: b, host: hostId });
|
|
1479
1562
|
}
|
|
1480
1563
|
|
|
1564
|
+
/** Open another assistant session; this one goes with it when nobody chatted in it (`replaces`). */
|
|
1565
|
+
function openOther(id) {
|
|
1566
|
+
emit('assistant:resume', { sessionId: id, host: hostId, replaces: unused() ? sessionId : null });
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1481
1569
|
function resume(id) {
|
|
1482
1570
|
if (!id) return;
|
|
1483
|
-
if (String(id).startsWith('assistant-')) {
|
|
1571
|
+
if (String(id).startsWith('assistant-')) { if (id !== sessionId) openOther(id); return; }
|
|
1484
1572
|
sock.send({ type: 'resume', providerSessionId: id });
|
|
1573
|
+
st.chatStarted = true; // a provider conversation: the server stores the session with it
|
|
1485
1574
|
renderer.appendDivider(tt('assistant.status.resuming', 'resuming {id}', { id: String(id).slice(0, 8) }));
|
|
1486
1575
|
}
|
|
1487
1576
|
|
|
@@ -1603,35 +1692,109 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1603
1692
|
}
|
|
1604
1693
|
|
|
1605
1694
|
// ── Menus ──
|
|
1695
|
+
/**
|
|
1696
|
+
* The Sessions menu: New, then every session that holds a chat (the server lists no other). Each row
|
|
1697
|
+
* opens its session; its Remove (hover / focus, → from the row, Delete) asks in the row itself, then
|
|
1698
|
+
* removes the session for good: its running turn and agents stop (the question says so), every host
|
|
1699
|
+
* drops its tab, and the session showing here is replaced by a fresh one, as New does.
|
|
1700
|
+
*/
|
|
1606
1701
|
function showSessionsMenu(list) {
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1702
|
+
let sessions = (Array.isArray(list) ? list : []).filter(s => s?.id);
|
|
1703
|
+
let asking = null; // the id of the row that asks "Remove …?"
|
|
1704
|
+
const nameOf = (s) => s.title || s.label || s.id;
|
|
1705
|
+
const build = () => {
|
|
1706
|
+
const items = [
|
|
1707
|
+
{ id: 'new', label: tt('assistant.topbar.new', 'New assistant session'), desc: brainLabel(st.brain), icon: ICON_NEW, onSelect: () => newSession(null) },
|
|
1708
|
+
{ kind: 'separator' },
|
|
1709
|
+
];
|
|
1710
|
+
if (!sessions.length) items.push({ kind: 'info', label: tt('assistant.sessions.empty', 'No other sessions') });
|
|
1711
|
+
else items.push({ kind: 'header', label: tt('assistant.sessions.recent', 'Recent') });
|
|
1712
|
+
for (const s of sessions.slice(0, 30)) {
|
|
1713
|
+
const isCurrent = s.id === sessionId;
|
|
1714
|
+
const name = nameOf(s);
|
|
1715
|
+
if (s.id === asking) { items.push(removeQuestion(s, name, isCurrent)); continue; }
|
|
1716
|
+
const b = s.brain && typeof s.brain === 'object' ? s.brain : { provider: s.brain, model: s.model, effort: s.effort };
|
|
1717
|
+
items.push({
|
|
1718
|
+
kind: 'radio',
|
|
1719
|
+
id: s.id,
|
|
1720
|
+
label: name,
|
|
1721
|
+
desc: [brainLabel(b), relativeTime(s.updatedAt || s.createdAt), s.status].filter(Boolean).join(' · '),
|
|
1722
|
+
selected: isCurrent,
|
|
1723
|
+
onSelect: () => { if (!isCurrent) openOther(s.id); },
|
|
1724
|
+
action: {
|
|
1725
|
+
id: `remove:${s.id}`,
|
|
1726
|
+
icon: ICON_TRASH,
|
|
1727
|
+
label: tt('assistant.sessions.removeNamed', 'Remove “{title}”', { title: name }),
|
|
1728
|
+
tooltip: tt('assistant.sessions.remove', 'Remove session'),
|
|
1729
|
+
onSelect: () => ask(s.id),
|
|
1730
|
+
},
|
|
1731
|
+
});
|
|
1732
|
+
}
|
|
1733
|
+
return items;
|
|
1734
|
+
};
|
|
1735
|
+
/** "Remove “name”? …" with Remove and Cancel, in place of the row (it still matches the filter by name). */
|
|
1736
|
+
const removeQuestion = (s, name, isCurrent) => {
|
|
1737
|
+
const runs = Math.max(0, Number(s.activeRuns) || 0);
|
|
1738
|
+
const running = isCurrent ? st.running : s.running === true;
|
|
1739
|
+
const question = [
|
|
1740
|
+
tt('assistant.sessions.removeAsk', 'Remove “{title}” for good?', { title: name }),
|
|
1741
|
+
running ? tt('assistant.sessions.removeStopsTurn', 'Its running turn stops.') : '',
|
|
1742
|
+
runs ? tt('assistant.sessions.removeStopsAgents', 'Its running agents stop ({count}).', { count: runs }) : '',
|
|
1743
|
+
].filter(Boolean).join(' ');
|
|
1744
|
+
return {
|
|
1745
|
+
kind: 'buttons',
|
|
1746
|
+
id: `ask:${s.id}`,
|
|
1747
|
+
className: 'asst-dd-confirm',
|
|
1748
|
+
label: question,
|
|
1749
|
+
buttons: [
|
|
1750
|
+
{ id: `remove-yes:${s.id}`, label: tt('assistant.sessions.removeConfirm', 'Remove'), danger: true, keywords: name, keepOpen: true, onSelect: () => confirmRemove(s, isCurrent) },
|
|
1751
|
+
{ id: `remove-no:${s.id}`, label: tt('common.cancel', 'Cancel'), keywords: name, keepOpen: true, onSelect: () => cancel() },
|
|
1752
|
+
],
|
|
1753
|
+
};
|
|
1754
|
+
};
|
|
1755
|
+
const handle = openMenu(sessionsBtn, {
|
|
1627
1756
|
title: tt('assistant.topbar.sessions', 'Sessions'),
|
|
1628
|
-
items,
|
|
1757
|
+
items: build(),
|
|
1629
1758
|
role: 'menu',
|
|
1630
1759
|
placement: 'below',
|
|
1631
1760
|
width: 300,
|
|
1632
1761
|
filter: sessions.length > 8,
|
|
1633
1762
|
filterPlaceholder: tt('assistant.sessions.filter', 'Filter sessions…'),
|
|
1763
|
+
// Esc while a row asks: back to the row, the menu stays open.
|
|
1764
|
+
onEscape: () => { if (!asking) return false; cancel(); return true; },
|
|
1634
1765
|
});
|
|
1766
|
+
function ask(id) {
|
|
1767
|
+
asking = id;
|
|
1768
|
+
handle?.update({ items: build(), focus: `remove-no:${id}` });
|
|
1769
|
+
}
|
|
1770
|
+
function cancel() {
|
|
1771
|
+
const id = asking;
|
|
1772
|
+
asking = null;
|
|
1773
|
+
handle?.update({ items: build(), focus: id });
|
|
1774
|
+
}
|
|
1775
|
+
function confirmRemove(s, isCurrent) {
|
|
1776
|
+
asking = null;
|
|
1777
|
+
const name = nameOf(s);
|
|
1778
|
+
const done = (result) => {
|
|
1779
|
+
if (result?.ok) return;
|
|
1780
|
+
const text = tt('assistant.sessions.removeFailed', 'Could not remove “{title}”: {error}', { title: name, error: result?.error || tt('assistant.errorGeneric', 'Something went wrong') });
|
|
1781
|
+
if (destroyed) return;
|
|
1782
|
+
renderer.appendError(text);
|
|
1783
|
+
announce(text);
|
|
1784
|
+
};
|
|
1785
|
+
if (isCurrent) {
|
|
1786
|
+
// This panel's own session: a fresh one takes its place (as New), then this one goes.
|
|
1787
|
+
closeMenu();
|
|
1788
|
+
emit('assistant:remove', { sessionId: s.id, fresh: true, brain: st.brain, done });
|
|
1789
|
+
return;
|
|
1790
|
+
}
|
|
1791
|
+
// Another session (open elsewhere or not): its row goes now, and focus stays in the list.
|
|
1792
|
+
const at = sessions.findIndex((row) => row.id === s.id);
|
|
1793
|
+
sessions = sessions.filter((row) => row.id !== s.id);
|
|
1794
|
+
const next = sessions[Math.min(at, sessions.length - 1)];
|
|
1795
|
+
handle?.update({ items: build(), focus: next ? next.id : 'new' });
|
|
1796
|
+
emit('assistant:remove', { sessionId: s.id, fresh: false, done });
|
|
1797
|
+
}
|
|
1635
1798
|
}
|
|
1636
1799
|
|
|
1637
1800
|
function engineText() {
|
|
@@ -1867,6 +2030,18 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1867
2030
|
const requestId = msg?.request_id || msg?.requestId;
|
|
1868
2031
|
if (requestId) lockControl(requestId, resolvedLabel(msg.resolvedBy));
|
|
1869
2032
|
}));
|
|
2033
|
+
// What this session's workers do right now (Claude and Codex workers stream their events to the page,
|
|
2034
|
+
// OpenCode workers a compact copy of their tool calls: lib/opencode-worker-activity.js):
|
|
2035
|
+
// their stages and the tray's scenes follow the current call.
|
|
2036
|
+
unsubs.push(on('sync:sidepanel:provider-event', (msg) => {
|
|
2037
|
+
const runId = msg?.run?.runId;
|
|
2038
|
+
if (!runId || !dock.getRun(runId)) return;
|
|
2039
|
+
const activity = activityOf(msg.event);
|
|
2040
|
+
if (!activity) return;
|
|
2041
|
+
const stamped = { ...activity, at: Date.now() };
|
|
2042
|
+
renderer.setRunActivity(runId, stamped);
|
|
2043
|
+
dock.setRunActivity(runId, stamped);
|
|
2044
|
+
}));
|
|
1870
2045
|
unsubs.push(on('sync:assistant:desktop', (msg) => computerPanel.applyDesktop(msg)));
|
|
1871
2046
|
unsubs.push(on('sync:assistant:desktop-setup', (msg) => computerPanel.applySetup(msg)));
|
|
1872
2047
|
// Models switched on/off elsewhere: the open Models manager reloads (the menus drop their cache on their own).
|
|
@@ -1879,6 +2054,12 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1879
2054
|
st.routing = { ...(st.routing || {}), defaultMode: def, effectiveMode: st.routeMode || def };
|
|
1880
2055
|
routeChip.render();
|
|
1881
2056
|
}));
|
|
2057
|
+
// The global Admin sandbox setting changed in some window (this one included): every panel shows it.
|
|
2058
|
+
unsubs.push(on('sync:agents:admin-sandbox-changed', (msg) => {
|
|
2059
|
+
if (typeof msg?.adminSandbox !== 'boolean' || msg.adminSandbox === st.adminSandbox) return;
|
|
2060
|
+
st.adminSandbox = msg.adminSandbox;
|
|
2061
|
+
picker.render();
|
|
2062
|
+
}));
|
|
1882
2063
|
unsubs.push(on('session:info', () => updateGuest()));
|
|
1883
2064
|
unsubs.push(on('permissions:changed', () => updateGuest()));
|
|
1884
2065
|
|
|
@@ -1887,6 +2068,19 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1887
2068
|
}
|
|
1888
2069
|
|
|
1889
2070
|
// ── Rehydration ──
|
|
2071
|
+
/**
|
|
2072
|
+
* The server no longer has this session: a draft it dropped (a restart before its first prompt, a
|
|
2073
|
+
* page away too long) or one removed while this page missed the broadcast. The tab closes; one that
|
|
2074
|
+
* was showing with no chat in it is replaced by a fresh session (asst-hosts.js gone), never left dead.
|
|
2075
|
+
*/
|
|
2076
|
+
let gone = false;
|
|
2077
|
+
function sessionGone() {
|
|
2078
|
+
if (gone || destroyed) return;
|
|
2079
|
+
gone = true;
|
|
2080
|
+
sock.close();
|
|
2081
|
+
emit('assistant:gone', { sessionId, fresh: visible() && unused(), brain: st.brain });
|
|
2082
|
+
}
|
|
2083
|
+
|
|
1890
2084
|
async function rehydrate({ force = false } = {}) {
|
|
1891
2085
|
try {
|
|
1892
2086
|
const data = await getAssistantSession(sessionId);
|
|
@@ -1899,7 +2093,11 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1899
2093
|
// A conversation with nothing in it yet may be greeted; a restored one never is.
|
|
1900
2094
|
if (Array.isArray(transcript) && !transcript.length && !(Number(meta?.turns) > 0)) renderer.offerGreeting();
|
|
1901
2095
|
for (const run of (Array.isArray(data?.runs) ? data.runs : [])) dock.upsertRun(run);
|
|
2096
|
+
// Run cards are not journaled: the runs the tray fetched come back into the transcript, next to the
|
|
2097
|
+
// calls that dispatched them, and a worker that still works is live at once (its stage, its route line).
|
|
2098
|
+
dock.ready.then(() => { if (!destroyed) renderer.restoreRuns(dock.getRuns()); });
|
|
1902
2099
|
} catch (err) {
|
|
2100
|
+
if (err?.status === 404) { sessionGone(); return; }
|
|
1903
2101
|
console.warn('[assistant] could not restore the conversation', err);
|
|
1904
2102
|
renderer.showEmpty();
|
|
1905
2103
|
}
|
|
@@ -1914,7 +2112,7 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1914
2112
|
if (session && typeof session === 'object') applySessionMeta(session);
|
|
1915
2113
|
else applyFeatures();
|
|
1916
2114
|
rehydrate().finally(() => {
|
|
1917
|
-
if (destroyed) return;
|
|
2115
|
+
if (destroyed || gone) return;
|
|
1918
2116
|
probeFeatures();
|
|
1919
2117
|
applyLastUsedRouteMode();
|
|
1920
2118
|
applyLastUsedTestDensity();
|
|
@@ -1954,7 +2152,8 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1954
2152
|
attachPath: (path) => { if (path) { composer.insertText(`\`${path}\` `); composer.focus(); } },
|
|
1955
2153
|
/** The server's name for the conversation (the user's rename, else the first prompt): tooltips. */
|
|
1956
2154
|
getConversationTitle: () => st.sessionTitle || '',
|
|
1957
|
-
|
|
2155
|
+
/** The session's status as its host shows it: the brain's own with its dispatched agents' (sessionStatus). */
|
|
2156
|
+
getStatus: () => st.shownStatus || 'idle',
|
|
1958
2157
|
focus: () => composer.focus(),
|
|
1959
2158
|
onShown: () => { syncTabLabel(); renderer.scrollEnd(true); if (visible()) composer.focus(); director.touch(); },
|
|
1960
2159
|
onHidden: () => { closeMenu(); picker.close(); director.stopTyping(); },
|
|
@@ -1975,7 +2174,9 @@ export function mountAssistant(viewport, { sessionId, brain, host = {}, session
|
|
|
1975
2174
|
unsubs.forEach(off => { try { off(); } catch { /* ignore */ } });
|
|
1976
2175
|
document.removeEventListener('keydown', onEscCapture, true);
|
|
1977
2176
|
surfaces.forEach((node) => { node.removeEventListener('keydown', onRootKey); node.removeEventListener('focusin', onFocusIn); });
|
|
1978
|
-
|
|
2177
|
+
// Its own menu closes; another panel's stays open (its Sessions menu may be what removed this session).
|
|
2178
|
+
const menuAnchor = currentMenuAnchor();
|
|
2179
|
+
if (!menuAnchor || !menuAnchor.isConnected || root.contains(menuAnchor) || barEl.contains(menuAnchor)) closeMenu();
|
|
1979
2180
|
closeFrameLightbox();
|
|
1980
2181
|
if (helpModal) { helpModal.remove(); helpModal = null; }
|
|
1981
2182
|
for (const card of routeCards.values()) card.destroy();
|