synabun 2.0.5 → 2.0.9
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 +78 -0
- package/README.md +2 -1
- package/THIRD-PARTY-LICENSES.md +13 -0
- package/docs/whatsapp.md +151 -16
- package/hooks/claude-code/post-plan.mjs +6 -30
- package/hooks/claude-code/session-start.mjs +1 -4
- package/hooks/claude-code/shared.mjs +112 -75
- package/lib/child-path.js +303 -0
- package/lib/claude-hooks.js +2 -1
- package/lib/data-home-migration.js +2 -0
- package/lib/desktop-app.js +265 -0
- package/lib/external-tools.js +7 -3
- package/lib/log-redact.js +102 -0
- package/lib/package-processes.js +670 -0
- package/lib/packaged-runtime.js +138 -11
- package/lib/runtime-dependencies.js +225 -0
- package/mcp-server/dist/http.d.ts +3 -1
- package/mcp-server/dist/http.d.ts.map +1 -1
- package/mcp-server/dist/http.js +15 -4
- package/mcp-server/dist/http.js.map +1 -1
- package/mcp-server/dist/index.d.ts.map +1 -1
- package/mcp-server/dist/index.js +9 -6
- package/mcp-server/dist/index.js.map +1 -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/budget-judgments.d.ts +108 -0
- package/mcp-server/dist/services/budget-judgments.d.ts.map +1 -0
- package/mcp-server/dist/services/budget-judgments.js +153 -0
- package/mcp-server/dist/services/budget-judgments.js.map +1 -0
- 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/codex-config-heal.d.ts +5 -1
- package/mcp-server/dist/services/codex-config-heal.d.ts.map +1 -1
- package/mcp-server/dist/services/codex-config-heal.js +41 -4
- package/mcp-server/dist/services/codex-config-heal.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/services/identity.d.ts +11 -0
- package/mcp-server/dist/services/identity.d.ts.map +1 -1
- package/mcp-server/dist/services/identity.js +24 -0
- package/mcp-server/dist/services/identity.js.map +1 -1
- package/mcp-server/dist/services/neural-interface.d.ts +13 -0
- package/mcp-server/dist/services/neural-interface.d.ts.map +1 -1
- package/mcp-server/dist/services/neural-interface.js +34 -2
- package/mcp-server/dist/services/neural-interface.js.map +1 -1
- package/mcp-server/dist/services/typesafe-config.d.ts +1 -1
- package/mcp-server/dist/services/typesafe-config.d.ts.map +1 -1
- package/mcp-server/dist/services/typesafe-config.js +4 -1
- package/mcp-server/dist/services/typesafe-config.js.map +1 -1
- package/mcp-server/dist/tools/agents.d.ts +11 -8
- package/mcp-server/dist/tools/agents.d.ts.map +1 -1
- package/mcp-server/dist/tools/agents.js +35 -14
- 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 +17 -0
- package/mcp-server/dist/tools/whatsapp-send-file.d.ts.map +1 -0
- package/mcp-server/dist/tools/whatsapp-send-file.js +44 -0
- package/mcp-server/dist/tools/whatsapp-send-file.js.map +1 -0
- 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 +18 -5
- package/mcp-server/dist/tui.js.map +1 -1
- package/mcp-server/dist/version.d.ts +5 -0
- package/mcp-server/dist/version.d.ts.map +1 -0
- package/mcp-server/dist/version.js +21 -0
- package/mcp-server/dist/version.js.map +1 -0
- package/mcp-server/package-lock.json +3 -3
- package/mcp-server/package.json +3 -3
- package/mcp-server/run.mjs +15 -9
- package/mcp-server/src/http.ts +18 -3
- package/mcp-server/src/index.ts +9 -6
- package/mcp-server/src/services/browser-bench.ts +1 -1
- package/mcp-server/src/services/budget-judgments.ts +183 -0
- package/mcp-server/src/services/categories.ts +77 -32
- package/mcp-server/src/services/codex-config-heal.ts +35 -4
- package/mcp-server/src/services/desktop-bench.ts +1 -1
- package/mcp-server/src/services/identity.ts +27 -0
- package/mcp-server/src/services/neural-interface.ts +34 -2
- package/mcp-server/src/services/typesafe-config.ts +4 -1
- package/mcp-server/src/tools/agents.ts +34 -15
- 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 +51 -0
- 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 +24 -10
- package/mcp-server/src/version.ts +22 -0
- package/neural-interface/i18n/en.json +645 -57
- package/neural-interface/i18n/pt-BR.json +644 -56
- package/neural-interface/lib/account-usage.js +163 -0
- package/neural-interface/lib/agent-sandbox-elevation.js +102 -0
- package/neural-interface/lib/agent-sandbox-setting.js +57 -0
- package/neural-interface/lib/assistant-api.js +274 -52
- package/neural-interface/lib/assistant-brains/claude.js +15 -2
- package/neural-interface/lib/assistant-brains/codex.js +3 -0
- package/neural-interface/lib/assistant-brains/opencode.js +17 -4
- package/neural-interface/lib/assistant-budget-planner.js +390 -0
- package/neural-interface/lib/assistant-budget-split.js +408 -0
- package/neural-interface/lib/assistant-budget.js +94 -95
- package/neural-interface/lib/assistant-config.js +62 -14
- package/neural-interface/lib/assistant-dispatch.js +432 -125
- package/neural-interface/lib/assistant-jev.js +26 -3
- package/neural-interface/lib/assistant-persona.js +68 -11
- package/neural-interface/lib/assistant-plan-permissions.js +8 -1
- package/neural-interface/lib/assistant-route-accounts.js +14 -0
- package/neural-interface/lib/assistant-route-gate-codex.js +3 -1
- package/neural-interface/lib/assistant-route-gate.js +19 -3
- package/neural-interface/lib/assistant-router.js +373 -42
- package/neural-interface/lib/assistant-runtime.js +312 -48
- package/neural-interface/lib/assistant-user-writer.js +4 -2
- package/neural-interface/lib/augmented-path.js +317 -53
- package/neural-interface/lib/claude-accounts.js +342 -31
- package/neural-interface/lib/claude-agent-bridge.js +90 -3
- package/neural-interface/lib/claude-executable.js +6 -1
- package/neural-interface/lib/claude-model-catalog.js +3 -3
- package/neural-interface/lib/claude-panel-auth.js +221 -0
- package/neural-interface/lib/claude-profile-api-key.js +62 -0
- package/neural-interface/lib/cli-install-api.js +137 -0
- package/neural-interface/lib/cli-install.js +797 -0
- package/neural-interface/lib/cli-path.js +130 -0
- package/neural-interface/lib/cli-resolver.js +744 -0
- package/neural-interface/lib/cli-update-planner.js +143 -7
- package/neural-interface/lib/codex-account-auth.js +180 -0
- package/neural-interface/lib/codex-accounts.js +502 -0
- package/neural-interface/lib/codex-capabilities.js +2 -1
- package/neural-interface/lib/codex-compat-rpc.js +8 -2
- package/neural-interface/lib/codex-mcp-approvals.js +5 -1
- package/neural-interface/lib/codex-panel-auth.js +62 -0
- package/neural-interface/lib/codex-session-settings.js +1 -1
- package/neural-interface/lib/codex-settings-schema.js +122 -0
- package/neural-interface/lib/desktop/config.js +3 -0
- package/neural-interface/lib/exec-loop-command.js +3 -1
- package/neural-interface/lib/git-bash/bzip2.js +339 -0
- package/neural-interface/lib/git-bash/claude-settings.js +73 -0
- package/neural-interface/lib/git-bash/extract-worker.js +34 -0
- package/neural-interface/lib/git-bash/install.js +529 -0
- package/neural-interface/lib/git-bash/licenses/COPYING +360 -0
- package/neural-interface/lib/git-bash/licenses/LGPL-2.1 +511 -0
- package/neural-interface/lib/git-bash/manager.js +268 -0
- package/neural-interface/lib/git-bash/pins.js +206 -0
- package/neural-interface/lib/git-bash/pins.json +34 -0
- package/neural-interface/lib/git-bash/resolver.js +194 -0
- package/neural-interface/lib/git-read.js +34 -2
- package/neural-interface/lib/install-details.js +163 -0
- package/neural-interface/lib/mcp-installer.js +14 -2
- package/neural-interface/lib/native-loop-providers.js +22 -4
- package/neural-interface/lib/native-loop-runtime.js +9 -4
- package/neural-interface/lib/os-path.js +319 -0
- package/neural-interface/lib/provider-panel-api-key-auth.js +92 -0
- package/neural-interface/lib/provider-panel-terminal-auth.js +96 -0
- package/neural-interface/lib/pty-host/core.js +2 -1
- package/neural-interface/lib/pty-host/manager.js +27 -2
- package/neural-interface/lib/remote-policy.js +20 -11
- package/neural-interface/lib/session-indexer.js +3 -1
- package/neural-interface/lib/session-title-generator.js +6 -3
- package/neural-interface/lib/system-about.js +340 -0
- package/neural-interface/lib/system-activity.js +66 -0
- package/neural-interface/lib/terminal-env.js +11 -3
- package/neural-interface/lib/terminal-path.js +55 -0
- package/neural-interface/lib/virtual-socket.js +12 -1
- package/neural-interface/lib/whatsapp/baileys-adapter.js +165 -45
- package/neural-interface/lib/whatsapp/bridge.js +78 -34
- package/neural-interface/lib/whatsapp/commands.js +13 -14
- package/neural-interface/lib/whatsapp/config.js +134 -20
- package/neural-interface/lib/whatsapp/fake-baileys.js +99 -14
- package/neural-interface/lib/whatsapp/host-core.js +168 -35
- package/neural-interface/lib/whatsapp/inbound.js +5 -3
- package/neural-interface/lib/whatsapp/local-file.js +524 -0
- package/neural-interface/lib/whatsapp/manager.js +92 -32
- package/neural-interface/lib/whatsapp/paths.js +11 -1
- package/neural-interface/lib/whatsapp/protocol.js +65 -5
- package/neural-interface/lib/whatsapp/redact.js +63 -0
- package/neural-interface/lib/whatsapp/service.js +343 -91
- package/neural-interface/lib/whatsapp/transcription.js +463 -0
- package/neural-interface/package-lock.json +2 -2
- package/neural-interface/package.json +1 -1
- package/neural-interface/public/index.html +2 -0
- package/neural-interface/public/index2d.html +2 -0
- package/neural-interface/public/offline.html +16 -1
- package/neural-interface/public/onboarding.html +96 -2
- package/neural-interface/public/shared/account-i18n.js +7 -0
- package/neural-interface/public/shared/account-menu.js +542 -0
- package/neural-interface/public/shared/account-usage.js +79 -0
- package/neural-interface/public/shared/account-view.js +336 -0
- package/neural-interface/public/shared/agent-runtime-options.js +28 -8
- package/neural-interface/public/shared/assistant/asst-account-menu.js +298 -0
- package/neural-interface/public/shared/assistant/asst-accounts.js +182 -184
- package/neural-interface/public/shared/assistant/asst-api.js +39 -2
- package/neural-interface/public/shared/assistant/asst-brain-picker.js +288 -32
- package/neural-interface/public/shared/assistant/asst-budget.js +259 -303
- package/neural-interface/public/shared/assistant/asst-mascot.js +126 -7
- package/neural-interface/public/shared/assistant/asst-menu.js +219 -80
- package/neural-interface/public/shared/assistant/asst-model-chip.js +135 -0
- package/neural-interface/public/shared/assistant/asst-panel.js +87 -16
- package/neural-interface/public/shared/assistant/asst-render.js +38 -7
- package/neural-interface/public/shared/assistant/asst-route.js +72 -14
- package/neural-interface/public/shared/assistant/asst-routes-editor.js +45 -6
- package/neural-interface/public/shared/assistant/asst-slash.js +1 -1
- package/neural-interface/public/shared/assistant/asst-state.js +1 -1
- package/neural-interface/public/shared/assistant/asst-styles.js +160 -29
- package/neural-interface/public/shared/cdx/cdx-commands.js +4 -1
- package/neural-interface/public/shared/cdx/cdx-features.js +22 -14
- package/neural-interface/public/shared/cdx/cdx-icons.js +2 -0
- package/neural-interface/public/shared/cdx/cdx-panel.js +49 -108
- package/neural-interface/public/shared/cdx/cdx-settings.js +231 -0
- package/neural-interface/public/shared/cdx/cdx-styles.js +172 -111
- package/neural-interface/public/shared/cdx/cdx-tabs.js +264 -664
- package/neural-interface/public/shared/cdx/cdx-ws.js +2 -0
- package/neural-interface/public/shared/claude-account-view.js +3 -0
- package/neural-interface/public/shared/cli-install-view.js +392 -0
- package/neural-interface/public/shared/cli-status.js +282 -22
- package/neural-interface/public/shared/cp/cp-events.js +2 -1
- package/neural-interface/public/shared/cp/cp-styles.js +46 -0
- package/neural-interface/public/shared/desktop-bridge.js +39 -0
- package/neural-interface/public/shared/desktop-titlebar-page.js +59 -0
- package/neural-interface/public/shared/desktop-titlebar-view.js +122 -0
- package/neural-interface/public/shared/desktop-titlebar.js +153 -0
- package/neural-interface/public/shared/desktop-update-view.js +462 -0
- package/neural-interface/public/shared/editor/editor-panel.js +1 -1
- package/neural-interface/public/shared/explorer/fx-main.js +1 -1
- package/neural-interface/public/shared/git-bash-view.js +145 -0
- package/neural-interface/public/shared/html-shell.js +1 -0
- package/neural-interface/public/shared/i18n.js +19 -1
- package/neural-interface/public/shared/install-details-view.js +86 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +4 -1
- package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +36 -1
- package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +17 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +169 -2
- package/neural-interface/public/shared/pwa-install-page.js +3 -1
- package/neural-interface/public/shared/settings/settings-about-pane.js +271 -0
- package/neural-interface/public/shared/settings/settings-about.js +254 -0
- package/neural-interface/public/shared/settings/settings-ia.js +15 -0
- package/neural-interface/public/shared/showcase-privacy.js +490 -0
- package/neural-interface/public/shared/storage.js +30 -3
- package/neural-interface/public/shared/styles.css +281 -32
- package/neural-interface/public/shared/synabun-mascot.js +48 -2
- package/neural-interface/public/shared/ui-claude-panel.js +262 -217
- package/neural-interface/public/shared/ui-cli-banner.js +355 -0
- package/neural-interface/public/shared/ui-explorer.js +2 -0
- package/neural-interface/public/shared/ui-git-bash.js +124 -0
- package/neural-interface/public/shared/ui-judgments.js +10 -1
- package/neural-interface/public/shared/ui-loading.js +30 -6
- package/neural-interface/public/shared/ui-menubar.js +13 -3
- package/neural-interface/public/shared/ui-navbar.js +3 -1
- package/neural-interface/public/shared/ui-provider-auth.js +104 -0
- package/neural-interface/public/shared/ui-provider-terminal-auth.js +223 -0
- package/neural-interface/public/shared/ui-sessions.js +9 -3
- package/neural-interface/public/shared/ui-settings.js +55 -3
- package/neural-interface/public/shared/ui-sidepanel-sessions.js +3 -1
- package/neural-interface/public/shared/ui-sync.js +8 -0
- package/neural-interface/public/shared/ui-terminal.js +17 -0
- package/neural-interface/public/shared/ui-tool-updates.js +5 -0
- package/neural-interface/public/shared/ui-update.js +598 -7
- package/neural-interface/public/shared/ui-whatsapp.js +21 -6
- package/neural-interface/public/shared/whatsapp/wa-view.js +51 -8
- package/neural-interface/public/shared/worker-end.js +2 -0
- package/neural-interface/public/sw.js +1 -1
- package/neural-interface/public/variant/2d/main.js +10 -1
- package/neural-interface/public/variant/3d/main.js +10 -1
- package/neural-interface/scripts/rebuild-pty.js +14 -2
- package/neural-interface/server.js +1384 -679
- package/npm-shrinkwrap.json +4424 -0
- package/package.json +57 -2
- package/postinstall.js +61 -47
- package/preuninstall.js +8 -35
- package/setup.js +80 -47
- package/skills/synabun/modules/idea.md +1 -1
- package/skills/synabun/modules/schedule.md +1 -1
- package/updater.cmd +2 -2
- package/updater.mjs +97 -3
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// Model routes: draft-only editor. All model data comes through asst-route-models.
|
|
2
2
|
// The global default and saved preferences are written together only on Save.
|
|
3
|
-
import { clampEffortId, getEffortLevelsForModel, modelEffortIds } from '../agent-runtime-options.js';
|
|
3
|
+
import { clampEffortId, getEffortLevelsForModel, modelEffortIds, fetchClaudeAccounts, fetchCodexAccounts, getCachedClaudeAccounts, getCachedCodexAccounts, getClaudeWorkerAccountId, getCodexWorkerAccountId } from '../agent-runtime-options.js';
|
|
4
|
+
import { accountSummary, accountName, accountBadge, accountIdentity } from '../account-view.js';
|
|
5
|
+
import { accountUsageText, autoAccountLabel } from '../account-usage.js';
|
|
4
6
|
import { getProviderMeta } from '../provider-icons.js';
|
|
5
7
|
import { getRouting, putRouting } from './asst-api.js';
|
|
6
8
|
import { catalogModelRow, hiddenModelFor, ICON_CARET, openModelMenu } from './asst-brain-picker.js';
|
|
@@ -30,7 +32,33 @@ function translator(t) {
|
|
|
30
32
|
return typeof text === 'string' && text !== key ? text : String(fallback).replace(/\{(\w+)\}/g, (_, k) => params?.[k] ?? `{${k}}`);
|
|
31
33
|
};
|
|
32
34
|
}
|
|
33
|
-
function choiceKey(p) { return p ? JSON.stringify([p.kind || 'direct', p.provider || '', p.model || '', p.effort || '']) : ''; }
|
|
35
|
+
function choiceKey(p) { return p ? JSON.stringify([p.kind || 'direct', p.provider || '', p.model || '', p.effort || '', p.accountId || '']) : ''; }
|
|
36
|
+
|
|
37
|
+
export function routeAccountView(pref, task, brain, accounts, workers = {}, t = null) {
|
|
38
|
+
const tr = translator(t);
|
|
39
|
+
const empty = { label: tr('assistant.routes.editorUnusedValue', '—'), readOnly: true, options: [], hint: '' };
|
|
40
|
+
if (!pref || pref.provider === 'opencode') return empty;
|
|
41
|
+
const direct = task.id === 'chat' || routeExecutionKind(pref, task, brain) === 'direct';
|
|
42
|
+
const provider = task.id === 'chat' ? brain.provider : pref.provider;
|
|
43
|
+
if (!['claude-code', 'codex'].includes(provider)) return empty;
|
|
44
|
+
const rows = accounts[provider] || [];
|
|
45
|
+
const providerView = provider === 'codex' ? 'codex' : 'claude';
|
|
46
|
+
const id = task.id === 'chat' ? brain.accountId || 'default' : pref.accountId || (direct ? brain.accountId || 'default' : null);
|
|
47
|
+
const selected = rows.find(a => a.id === id);
|
|
48
|
+
const missing = id && id !== 'auto' && !selected;
|
|
49
|
+
const removed = tr('assistant.routes.account.removed', '{id} · account removed', { id });
|
|
50
|
+
const warning = missing ? tr('assistant.routes.account.removedHint', 'Account removed. Save another account choice before running this route.') : selected?.signedIn === false ? tr('assistant.routes.account.signedOut', 'Signed out. Sign in from the provider account menu before running this route.') : '';
|
|
51
|
+
const worker = rows.find(a => a.id === (workers[provider] || 'default'));
|
|
52
|
+
const label = id === 'auto' ? autoAccountLabel(t) : selected ? accountSummary(selected, providerView) : missing ? removed : tr('assistant.routes.account.workersDefault', 'Workers default');
|
|
53
|
+
const options = [
|
|
54
|
+
{ id: '', label: direct ? tr('assistant.routes.editorInConversation', 'This conversation') : tr('assistant.routes.account.workersDefault', 'Workers default'), desc: worker ? accountSummary(worker, providerView) : '', selected: !pref.accountId },
|
|
55
|
+
{ id: 'auto', label: autoAccountLabel(t), desc: tr('assistant.accountUsage.autoHint', 'Signed-in subscriptions only. Another account runs on a worker.'), selected: id === 'auto' },
|
|
56
|
+
...rows.map(a => ({ id: a.id, label: accountName(a, providerView), tag: accountBadge(a, providerView).text, desc: a.signedIn === false ? tr('assistant.routes.account.signedOut', 'Signed out. Sign in from the provider account menu before running this route.') : [accountIdentity(a), accountUsageText(a, t)].filter(Boolean).join(' · '), selected: !!pref.accountId && a.id === id })),
|
|
57
|
+
];
|
|
58
|
+
return { label, readOnly: task.id === 'chat', options, warning, hint: warning || (selected ? `${label} · ${accountUsageText(selected, t)}` : label) };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function routeModelAccount(pref, provider) { return pref?.provider === provider ? pref.accountId || null : null; }
|
|
34
62
|
|
|
35
63
|
/** Only actual choices change the draft. Catalog label/by updates are not user edits. */
|
|
36
64
|
export function routeEditorPatch(mode, initialMode, prefs, edits) {
|
|
@@ -307,7 +335,7 @@ export async function openRoutesEditor(hooks = {}) {
|
|
|
307
335
|
const note = el('div', 'asst-routes-catalog-note'); note.setAttribute('role', 'status'); note.append(el('span', '', tr('assistant.routes.editorState.modelsFailed', 'Could not refresh the model list. Showing provider lists where available. Reload models to verify your choices.'))); table.append(note);
|
|
308
336
|
} else if (!rowsOf(state.catalog).length) table.append(el('div', 'asst-routes-catalog-note', tr('assistant.routes.editorState.modelsEmpty', 'No models are available. Check Models or connect a provider, then reload.')));
|
|
309
337
|
const columns = el('div', 'asst-routes-columns'); columns.setAttribute('aria-hidden', 'true');
|
|
310
|
-
for (const key of ['task', 'model', 'effort', 'run', 'reset']) columns.append(el('span', '', tr(`assistant.routes.columns.${key}`, key)));
|
|
338
|
+
for (const key of ['task', 'model', 'effort', 'run', 'account', 'reset']) columns.append(el('span', '', tr(`assistant.routes.columns.${key}`, key)));
|
|
311
339
|
table.append(columns);
|
|
312
340
|
const list = el('div', 'asst-routes-list');
|
|
313
341
|
const taskList = tasks();
|
|
@@ -363,7 +391,7 @@ export async function openRoutesEditor(hooks = {}) {
|
|
|
363
391
|
else if (target?.model) {
|
|
364
392
|
const levels = modelEffortIds(catalogModelRow(target.provider, target.model, state.catalog));
|
|
365
393
|
const effort = !pref?.effort ? null : levels ? clampEffortId(pref.effort, levels) : pref.provider === target.provider ? pref.effort : null;
|
|
366
|
-
setChoice(task.id, { kind: task.dispatchOnly ? 'dispatch' : pref?.kind || task.defaultKind || 'direct', provider: target.provider, model: target.model, effort, label: target.label || target.model }, modelBtn.dataset.focusKey);
|
|
394
|
+
setChoice(task.id, { kind: task.dispatchOnly ? 'dispatch' : pref?.kind || task.defaultKind || 'direct', provider: target.provider, model: target.model, effort, accountId: routeModelAccount(pref, target.provider), label: target.label || target.model }, modelBtn.dataset.focusKey);
|
|
367
395
|
}
|
|
368
396
|
},
|
|
369
397
|
});
|
|
@@ -420,9 +448,20 @@ export async function openRoutesEditor(hooks = {}) {
|
|
|
420
448
|
if (task.dispatchOnly) run.title = tr('assistant.routes.workerOnly', 'Worker only');
|
|
421
449
|
else if (pref && pref.provider !== brain().provider && task.id !== 'chat') run.title = tr('assistant.routes.otherProviderWorker', 'A model from another provider runs on a worker.');
|
|
422
450
|
const runCell = el('div', 'asst-routes-cell asst-routes-run-cell'); runCell.append(el('span', 'asst-routes-cell-label', tr('assistant.routes.columns.run', 'Runs in')), run); node.append(runCell);
|
|
451
|
+
const account = routeAccountView(pref, task, brain(), { 'claude-code': getCachedClaudeAccounts(), codex: getCachedCodexAccounts() }, { 'claude-code': getClaudeWorkerAccountId(), codex: getCodexWorkerAccountId() }, hooks.t);
|
|
452
|
+
const accountCell = el('div', 'asst-routes-cell asst-routes-account-cell');
|
|
453
|
+
const accountBtn = fieldButton('asst-routes-account', task, tr('assistant.routes.columns.account', 'Account'), account.label, () => {
|
|
454
|
+
state.menuFocus = `${task.id}-account`;
|
|
455
|
+
openMenuFor(accountBtn, tr('assistant.routes.columns.account', 'Account'), account.options.map(o => ({ ...o, kind: 'radio', onSelect: () => setChoice(task.id, { ...pref, accountId: o.id || null }, `${task.id}-account`) })));
|
|
456
|
+
});
|
|
457
|
+
accountBtn.dataset.focusKey = `${task.id}-account`; accountBtn.disabled = account.readOnly; accountBtn.title = account.hint;
|
|
458
|
+
if (!account.readOnly) caret(accountBtn);
|
|
459
|
+
if (account.warning) accountBtn.classList.add('asst-dd-warn');
|
|
460
|
+
accountCell.append(el('span', 'asst-routes-cell-label', tr('assistant.routes.columns.account', 'Account')), accountBtn); node.append(accountCell);
|
|
423
461
|
const resetCell = el('div', 'asst-routes-reset-cell');
|
|
424
462
|
if (pref) { const reset = button('asst-iconbtn asst-routes-reset', tr('assistant.routes.reset', 'Reset {taskClass}', { taskClass: task.label }), () => setChoice(task.id, null, `${task.id}-model`)); reset.dataset.focusKey = `${task.id}-reset`; reset.title = reset.getAttribute('aria-label'); reset.innerHTML = ICON_RESET; resetCell.append(reset); }
|
|
425
463
|
node.append(resetCell);
|
|
464
|
+
if (account.warning) { const note = el('div', 'asst-routes-row-warning', account.warning); note.id = `${nameId}-account-warning`; accountBtn.setAttribute('aria-describedby', note.id); node.append(note); }
|
|
426
465
|
if (capabilityNote) node.append(capabilityNote);
|
|
427
466
|
if (issue) { description.hidden = true; node.querySelector('.asst-routes-row-note')?.remove(); const note = el('div', 'asst-routes-row-warning', issueText(issue, task)); note.title = note.textContent; note.id = `${nameId}-issue`; modelBtn.setAttribute('aria-describedby', `${source.id} ${note.id}`); modelBtn.title = `${label} — ${note.textContent}`; node.append(note); }
|
|
428
467
|
if (task.id === 'chat' || task.id === 'vision') {
|
|
@@ -453,7 +492,7 @@ export async function openRoutesEditor(hooks = {}) {
|
|
|
453
492
|
const pending = preserve ? changes() : {};
|
|
454
493
|
state.loading = true; state.error = ''; state.modelsLoading = true; render();
|
|
455
494
|
try {
|
|
456
|
-
const [data, result] = await Promise.all([getRouting(), loadRouteModels().then(catalog => ({ catalog })).catch(() => ({ catalog: state.catalog, error: true }))]);
|
|
495
|
+
const [data, result] = await Promise.all([getRouting(), loadRouteModels().then(catalog => ({ catalog })).catch(() => ({ catalog: state.catalog, error: true })), Promise.allSettled([fetchClaudeAccounts(true), fetchCodexAccounts(true)])]);
|
|
457
496
|
if (!overlay.isConnected) return;
|
|
458
497
|
state.data = data; state.version = data.version ?? null; state.initialMode = normalizeRouteMode(data.routing?.defaultMode, DEFAULT_ROUTE_MODE);
|
|
459
498
|
state.mode = pending.defaultMode || state.initialMode; state.prefs = { ...(data.routing?.preferences || {}) }; state.patch = pending.preferences || {};
|
|
@@ -485,7 +524,7 @@ export async function openRoutesEditor(hooks = {}) {
|
|
|
485
524
|
import { openMenu } from './asst-menu.js';
|
|
486
525
|
function openMenuFor(anchor, title, items) {
|
|
487
526
|
if (currentMenu()) { closeMenu({ restoreFocus: true }); return null; }
|
|
488
|
-
const menu = openMenu(anchor, { title, items, className:
|
|
527
|
+
const menu = openMenu(anchor, { title, items, className: `asst-route-field-menu${anchor.classList.contains('asst-routes-account') ? ' asst-route-account-menu' : ''}`, role: 'menu' });
|
|
489
528
|
const overlay = anchor.closest('.asst-routes-overlay'); if (overlay) adoptMenu(menu, overlay); return menu;
|
|
490
529
|
}
|
|
491
530
|
function adoptMenu(menu, overlay) {
|
|
@@ -15,7 +15,7 @@ export const SLASH_COMMANDS = [
|
|
|
15
15
|
{ name: 'project', usage: '/project <path>', descKey: 'assistant.slash.project', desc: 'Set the working project' },
|
|
16
16
|
{ name: 'routes', usage: '/routes [always|unsure|never]', descKey: 'assistant.slash.routes', desc: 'Set when to ask before routing (or open the model routes)' },
|
|
17
17
|
{ name: 'models', usage: '/models [list | archived | hide <id…> | show <id…>]', descKey: 'assistant.slash.models', desc: 'Switch models off or on for the Assistant (or open the Models list)' },
|
|
18
|
-
{ name: 'budget', usage: '/budget', descKey: 'assistant.slash.budget', desc: 'Set the
|
|
18
|
+
{ name: 'budget', usage: '/budget', descKey: 'assistant.slash.budget', desc: 'Set the session budget and view provider shares' },
|
|
19
19
|
{ name: 'computer', usage: '/computer [on|off]', descKey: 'assistant.slash.computer', desc: 'Let the assistant use your Mac' },
|
|
20
20
|
{ name: 'stop', usage: '/stop [runId|all]', descKey: 'assistant.slash.stop', desc: 'Stop a run, everything, or the current turn' },
|
|
21
21
|
{ name: 'new', usage: '/new [provider]', descKey: 'assistant.slash.new', desc: 'Start a fresh session' },
|
|
@@ -181,7 +181,7 @@ export function resolveBrainDefaults(brain, catalog = {}) {
|
|
|
181
181
|
|
|
182
182
|
if (ACCOUNT_PROVIDERS.has(b.provider)) {
|
|
183
183
|
const accounts = catalog.accounts?.[b.provider] || [];
|
|
184
|
-
if (!b.accountId || (accounts.length && !accounts.some(a => a?.id === b.accountId))) {
|
|
184
|
+
if (!b.accountId || (b.accountId !== 'auto' && accounts.length && !accounts.some(a => a?.id === b.accountId))) {
|
|
185
185
|
b.accountId = accounts.find(a => a?.isDefault)?.id || accounts[0]?.id || 'default';
|
|
186
186
|
}
|
|
187
187
|
} else {
|
|
@@ -367,10 +367,10 @@ export function injectAssistantStyles() {
|
|
|
367
367
|
.asst-chip.asst-suggestion > .asst-icon svg { width: 20px; height: 14px; }
|
|
368
368
|
.asst-chip.asst-suggestion > .asst-icon { color: var(--asst-text-3); }
|
|
369
369
|
.asst-chip.asst-suggestion:is(:hover, :focus-visible) > .asst-icon { color: var(--asst-text); }
|
|
370
|
-
/*
|
|
371
|
-
.asst-empty-project { display: flex; justify-content: center; max-width: 100%; }
|
|
372
|
-
.asst-dd.asst-empty-
|
|
373
|
-
.asst-empty-
|
|
370
|
+
/* Project and Budget: shared md capsules under the lead, like the suggestions. */
|
|
371
|
+
.asst-empty-project { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; max-width: 100%; }
|
|
372
|
+
.asst-dd.asst-empty-control-btn { max-width: min(100%, 360px); }
|
|
373
|
+
.asst-empty-control-btn .asst-dd-label { max-width: 30ch; }
|
|
374
374
|
.asst-empty-project-key { flex-shrink: 0; color: var(--asst-text-3); font-weight: 400; }
|
|
375
375
|
|
|
376
376
|
/* ── Messages ───────────────────────────────────────────────────── */
|
|
@@ -578,32 +578,61 @@ export function injectAssistantStyles() {
|
|
|
578
578
|
color: var(--asst-text-2);
|
|
579
579
|
}
|
|
580
580
|
|
|
581
|
-
/* ── Route lines
|
|
581
|
+
/* ── Route lines ────────────────────────────────────────────────────
|
|
582
|
+
One line at any width, in the cards' column (the rack's 560px, no
|
|
583
|
+
hang): the glyph, arrow, kind and mark hold; the rest (model ·
|
|
584
|
+
account · usage, or the state) takes only the room left (flex-basis 0)
|
|
585
|
+
and ellipsizes first; the class gives way once the rest is down to
|
|
586
|
+
its "…". The head's title carries the whole text. */
|
|
582
587
|
.asst-route-line { font-size: 12.5px; }
|
|
583
588
|
.asst-route-line-head {
|
|
584
|
-
|
|
589
|
+
position: relative;
|
|
590
|
+
display: flex;
|
|
585
591
|
align-items: center;
|
|
586
592
|
gap: 6px;
|
|
587
|
-
|
|
593
|
+
width: fit-content;
|
|
594
|
+
max-width: min(100%, 560px);
|
|
595
|
+
min-width: 0;
|
|
588
596
|
min-height: 26px;
|
|
589
|
-
margin-left: -8px;
|
|
590
597
|
padding: 3px 8px;
|
|
598
|
+
overflow: hidden;
|
|
591
599
|
border: 0;
|
|
592
600
|
border-radius: var(--asst-r-ctl);
|
|
593
601
|
background: transparent;
|
|
594
602
|
color: var(--asst-text-2);
|
|
595
603
|
font: inherit;
|
|
604
|
+
white-space: nowrap;
|
|
596
605
|
text-align: left;
|
|
597
606
|
cursor: pointer;
|
|
598
607
|
}
|
|
599
608
|
.asst-route-line-head:hover { background: var(--asst-fill-1); }
|
|
600
609
|
.asst-route-glyph { color: var(--asst-brand); }
|
|
610
|
+
.asst-route-glyph svg, .asst-route-icon svg { width: 12px; height: 12px; }
|
|
611
|
+
.asst-route-glyph, .asst-route-arrow, .asst-route-kind, .asst-route-icon, .asst-route-chev { flex: none; }
|
|
601
612
|
.asst-route-arrow, .asst-route-chev { color: var(--asst-text-4); }
|
|
602
613
|
.asst-route-kind { color: var(--asst-text-3); font-size: 11.5px; }
|
|
603
|
-
.asst-route-
|
|
604
|
-
.asst-route-
|
|
614
|
+
.asst-route-class { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
|
615
|
+
.asst-route-rest { flex: 1 1 0; min-width: 1.2em; overflow: hidden; text-overflow: ellipsis; color: var(--asst-text-3); }
|
|
616
|
+
.asst-route-target { color: var(--asst-text); font-weight: 500; }
|
|
605
617
|
.asst-route-meta, .asst-route-state { flex-shrink: 0; color: var(--asst-text-3); white-space: nowrap; }
|
|
618
|
+
.asst-route-meta:not([hidden]) + .asst-route-state::before { content: '· '; color: var(--asst-text-3); }
|
|
606
619
|
.asst-route-line.pending .asst-route-state { color: var(--asst-warn); }
|
|
620
|
+
/* Live: the rack's sweep (asst-rk-sweep, asst-rack-styles.js) on the row's bottom edge, gold while
|
|
621
|
+
a run it dispatched works (the mark ticks like the rack's running tick), the warn tone while it
|
|
622
|
+
waits for your choice. Settled rows hold still. */
|
|
623
|
+
.asst-route-sweep { position: absolute; left: 0; right: 0; bottom: 0; height: 1.5px; overflow: hidden; pointer-events: none; }
|
|
624
|
+
.asst-route-line[data-live] .asst-route-sweep::after {
|
|
625
|
+
content: '';
|
|
626
|
+
position: absolute;
|
|
627
|
+
top: 0;
|
|
628
|
+
bottom: 0;
|
|
629
|
+
left: 0;
|
|
630
|
+
width: 38%;
|
|
631
|
+
background: linear-gradient(90deg, transparent, var(--asst-brand), transparent);
|
|
632
|
+
animation: asst-rk-sweep 1.8s cubic-bezier(.45, 0, .55, 1) infinite;
|
|
633
|
+
}
|
|
634
|
+
.asst-route-line[data-live="waiting"] .asst-route-sweep::after { background: linear-gradient(90deg, transparent, var(--asst-warn), transparent); }
|
|
635
|
+
.asst-route-line[data-live="working"] .asst-route-icon { animation: asst-rk-tick 1.1s ease-in-out infinite; }
|
|
607
636
|
.asst-route-line.muted .asst-route-glyph { color: var(--asst-text-4); }
|
|
608
637
|
.asst-route-line.muted .asst-route-class { color: var(--asst-text-3); }
|
|
609
638
|
.asst-route-chev { transition: transform var(--asst-dur-base) var(--asst-ease-standard); }
|
|
@@ -1079,8 +1108,21 @@ export function injectAssistantStyles() {
|
|
|
1079
1108
|
/* Fields (toolbar and composer): glyph · seam · value ▾ */
|
|
1080
1109
|
.asst-dd { flex: 0 1 auto; justify-content: flex-start; max-width: calc(18ch + 60px); }
|
|
1081
1110
|
.asst-dd .asst-dd-label { min-width: 0; max-width: 18ch; overflow: hidden; text-overflow: ellipsis; }
|
|
1082
|
-
/*
|
|
1083
|
-
|
|
1111
|
+
/* The model chip: name · context tag · account cue · API (asst-model-chip.js). The picker
|
|
1112
|
+
draws the longest form that fits the row, so no part shrinks or ends in an ellipsis; the
|
|
1113
|
+
cue and the API badge are the account menu's avatar and badge at the row's xs size. */
|
|
1114
|
+
.asst-dd.asst-dd-model { max-width: calc(30ch + 60px); }
|
|
1115
|
+
.asst-dd-model .asst-dd-label.asst-model-label { display: inline-flex; align-items: center; gap: 4px; max-width: none; }
|
|
1116
|
+
.asst-model-label > * { flex: none; }
|
|
1117
|
+
.asst-model-label > [hidden] { display: none; }
|
|
1118
|
+
.asst-model-tag { color: var(--asst-text-3); font-family: var(--asst-mono); font-size: 10.5px; font-weight: 400; }
|
|
1119
|
+
.asst-model-label > .asst-acct-avatar { flex: 0 0 auto; min-width: 16px; width: auto; height: 16px; padding: 0 4px; font-size: 10px; }
|
|
1120
|
+
.asst-model-label > .asst-acct-avatar[data-tone="warn"] { box-shadow: inset 0 0 0 1px var(--asst-pill-warn-ring); color: var(--asst-warn); }
|
|
1121
|
+
.asst-model-label > .asst-acct-badge { margin: 0; }
|
|
1122
|
+
/* Even the shortest form does not fit (a row narrower than 320px that cannot wrap): the name gives. */
|
|
1123
|
+
.asst-dd-model[data-squeezed] .asst-model-name { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
|
1124
|
+
/* A display name ("Sonnet 5", a project) is sans; a raw model id (opus) is mono. */
|
|
1125
|
+
.asst-dd.asst-dd-model[data-raw] .asst-model-name { font-family: var(--asst-mono); font-weight: 400; }
|
|
1084
1126
|
.asst-dd-caret {
|
|
1085
1127
|
display: inline-flex;
|
|
1086
1128
|
flex-shrink: 0;
|
|
@@ -1386,8 +1428,9 @@ export function injectAssistantStyles() {
|
|
|
1386
1428
|
z-index: 100030; /* above modals (100020): the routes editor opens model menus */
|
|
1387
1429
|
display: flex;
|
|
1388
1430
|
flex-direction: column;
|
|
1389
|
-
|
|
1390
|
-
|
|
1431
|
+
/* --asst-dd-room: the width of the box the menu stays inside, less its margins (asst-menu.js positionMenu). */
|
|
1432
|
+
min-width: min(200px, var(--asst-dd-room, 200px));
|
|
1433
|
+
max-width: min(380px, calc(100vw - 16px), var(--asst-dd-room, 100vw));
|
|
1391
1434
|
max-height: 380px;
|
|
1392
1435
|
overflow: hidden;
|
|
1393
1436
|
padding: 4px;
|
|
@@ -1434,6 +1477,8 @@ export function injectAssistantStyles() {
|
|
|
1434
1477
|
.asst-dd-item-desc { color: var(--asst-text-3); font-size: 11px; }
|
|
1435
1478
|
/* Test density: each level's description is a sentence, so it wraps instead of truncating. */
|
|
1436
1479
|
.asst-tests-menu .asst-dd-item-desc { white-space: normal; }
|
|
1480
|
+
/* Admin sandbox (permission menu): its note is a sentence too. */
|
|
1481
|
+
.asst-dd-item.asst-admin-sandbox-item .asst-dd-item-desc { white-space: normal; }
|
|
1437
1482
|
.asst-dd-item-tag { flex-shrink: 0; margin-left: auto; color: var(--asst-text-3); font-size: 11px; }
|
|
1438
1483
|
.asst-dd-kbd { flex-shrink: 0; margin-left: auto; color: var(--asst-text-3); font-family: var(--asst-mono); font-size: 10.5px; }
|
|
1439
1484
|
.asst-dd-sep { flex-shrink: 0; height: 1px; margin: 4px 6px; background: var(--asst-line); }
|
|
@@ -1463,6 +1508,45 @@ export function injectAssistantStyles() {
|
|
|
1463
1508
|
.asst-dd-input::placeholder { color: var(--asst-text-3); }
|
|
1464
1509
|
.asst-dd-filter { margin: 2px 0 4px; }
|
|
1465
1510
|
.asst-dd-empty { padding: 8px 10px; color: var(--asst-text-3); }
|
|
1511
|
+
/* A footer stays under a scrolling list; a button row is one line of compact items. */
|
|
1512
|
+
.asst-dd-foot { flex-shrink: 0; margin-top: 4px; padding-top: 4px; border-top: 1px solid var(--asst-line); }
|
|
1513
|
+
.asst-dd-btnrow { display: flex; flex-wrap: wrap; align-items: center; gap: 2px; }
|
|
1514
|
+
.asst-dd-btnrow-label { flex: 1 1 auto; min-width: 0; padding: 5px 10px; color: var(--asst-text-2); overflow-wrap: anywhere; }
|
|
1515
|
+
.asst-dd-btnrow .asst-dd-item { flex: 0 1 auto; width: auto; }
|
|
1516
|
+
|
|
1517
|
+
/* ── Account menu (asst-account-menu.js) ────────────────────────
|
|
1518
|
+
Every account once: initial · name ✓ · plan or credential badge, then who it is and its
|
|
1519
|
+
usage in full (lines wrap, nothing is cut). Kept inside the panel by asst-menu.js. The
|
|
1520
|
+
composer's Model menu lists the same rows: the rules follow the rows' own classes. */
|
|
1521
|
+
.asst-dd-item.asst-acct-item { gap: 8px; padding: 6px 8px; }
|
|
1522
|
+
:is(.asst-account-menu .asst-dd-item, .asst-dd-item:is(.asst-acct-item, .asst-acct-choice))[data-checked="1"] { background: var(--asst-fill-1); }
|
|
1523
|
+
:is(.asst-account-menu .asst-dd-item, .asst-dd-item:is(.asst-acct-item, .asst-acct-choice)):is(:hover, .focused) { background: var(--asst-fill-2); }
|
|
1524
|
+
.asst-acct-avatar { display: inline-flex; flex: 0 0 24px; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: var(--asst-pill-r-xs); background: var(--asst-fill-2); color: var(--asst-text-2); font-size: 11px; font-weight: 600; line-height: 1; }
|
|
1525
|
+
.asst-acct-avatar svg { width: 14px; height: 14px; }
|
|
1526
|
+
.asst-acct-main { display: flex; flex: 1 1 auto; flex-direction: column; gap: 1px; min-width: 0; }
|
|
1527
|
+
/* A long name wraps; its check and badge stay on its first line. */
|
|
1528
|
+
.asst-acct-head { display: flex; align-items: flex-start; gap: 6px; min-width: 0; }
|
|
1529
|
+
.asst-acct-name { min-width: 0; font-weight: 500; overflow-wrap: anywhere; }
|
|
1530
|
+
.asst-acct-check { display: inline-flex; flex: none; margin-top: 3px; color: var(--asst-text); }
|
|
1531
|
+
.asst-acct-check svg { width: 12px; height: 12px; }
|
|
1532
|
+
.asst-acct-badge { flex: none; margin: 1px 0 0 auto; padding: 0 var(--asst-pill-px-xs); border-radius: var(--asst-pill-r-xs); background: var(--asst-fill-1); box-shadow: inset 0 0 0 1px var(--asst-line); color: var(--asst-text-2); font-size: 10.5px; font-weight: 500; line-height: 16px; white-space: nowrap; }
|
|
1533
|
+
.asst-acct-line { color: var(--asst-text-3); font-size: 11px; line-height: 1.35; overflow-wrap: anywhere; }
|
|
1534
|
+
.asst-dd-item:is(:hover, .focused) .asst-acct-line:not([data-tone="warn"]) { color: var(--asst-text-2); }
|
|
1535
|
+
:is(.asst-acct-badge, .asst-acct-line, .asst-acct-value-text)[data-tone="warn"] { color: var(--asst-warn); }
|
|
1536
|
+
/* The note under the accounts lines up with their names. */
|
|
1537
|
+
.asst-dd-info.asst-acct-note { padding: 3px 8px 5px 40px; font-size: 11px; }
|
|
1538
|
+
.asst-dd-item.asst-acct-value { gap: 6px; }
|
|
1539
|
+
/* Footer rows read "label … value": the label muted, as the button row's. */
|
|
1540
|
+
.asst-acct-value-label { flex: 1 1 auto; min-width: 0; color: var(--asst-text-2); overflow-wrap: anywhere; }
|
|
1541
|
+
.asst-acct-value-text { flex: 0 1 auto; min-width: 0; text-align: right; overflow-wrap: anywhere; }
|
|
1542
|
+
.asst-acct-next { display: inline-flex; flex: none; color: var(--asst-text-3); }
|
|
1543
|
+
.asst-acct-next svg { width: 12px; height: 12px; }
|
|
1544
|
+
.asst-dd-item.asst-acct-back { gap: 6px; color: var(--asst-text-2); }
|
|
1545
|
+
.asst-dd-item.asst-acct-choice { gap: 4px; padding: 5px 8px; }
|
|
1546
|
+
.asst-dd-btnrow[data-id="manage-row"] .asst-dd-item { flex: 1 1 0; }
|
|
1547
|
+
@media (pointer: coarse) {
|
|
1548
|
+
:is(.asst-account-menu .asst-dd-item, .asst-dd-item:is(.asst-acct-item, .asst-acct-choice), .asst-dd-btnrow[data-id="manage-row"] .asst-dd-item) { min-height: 44px; }
|
|
1549
|
+
}
|
|
1466
1550
|
|
|
1467
1551
|
/* ── Modals (help, accounts, model routes) ──────────────────────── */
|
|
1468
1552
|
.asst-modal-overlay {
|
|
@@ -1503,11 +1587,50 @@ export function injectAssistantStyles() {
|
|
|
1503
1587
|
.asst-account-label { color: var(--asst-text); }
|
|
1504
1588
|
.asst-account-sub { color: var(--asst-text-3); font-size: 11px; }
|
|
1505
1589
|
.asst-account-row input.asst-dd-input { margin: 0; }
|
|
1590
|
+
/* Claude accounts (claude-account-view.js): what each runs on, its credentials and their actions. */
|
|
1591
|
+
.asst-account-row.claude { flex-wrap: wrap; align-items: flex-start; }
|
|
1592
|
+
.asst-account-row.claude .asst-account-main { flex-basis: 60%; }
|
|
1593
|
+
.asst-account-head { display: flex; align-items: center; gap: 6px; min-width: 0; }
|
|
1594
|
+
.asst-account-badge { flex-shrink: 0; padding: 1px 6px; border-radius: var(--asst-pill-r-xs); color: var(--asst-text-2); font-size: 10.5px; box-shadow: inset 0 0 0 1px var(--asst-line-2); }
|
|
1595
|
+
.asst-account-badge[data-tone="ok"] { color: var(--asst-text); box-shadow: inset 0 0 0 1px var(--asst-pill-on-ring); }
|
|
1596
|
+
.asst-account-badge[data-tone="warn"] { color: var(--asst-warn); box-shadow: inset 0 0 0 1px var(--asst-pill-warn-ring); }
|
|
1597
|
+
.asst-account-creds { display: flex; flex-direction: column; gap: 2px; margin-top: 4px; color: var(--asst-text-3); font-size: 11px; }
|
|
1598
|
+
.asst-account-cred { display: flex; align-items: center; gap: 6px; }
|
|
1599
|
+
.asst-account-cred-k { min-width: 120px; }
|
|
1600
|
+
.asst-account-actions { display: flex; flex-wrap: wrap; flex-basis: 100%; gap: 6px; margin-top: 6px; }
|
|
1601
|
+
.asst-account-form { display: flex; flex-basis: 100%; gap: 6px; margin-top: 6px; }
|
|
1602
|
+
.asst-account-form input { flex: 1; min-width: 0; }
|
|
1603
|
+
.asst-account-msg { flex-basis: 100%; margin-top: 4px; color: var(--asst-text-3); font-size: 11px; }
|
|
1604
|
+
.asst-dd.asst-dd-warn { color: var(--asst-warn); box-shadow: inset 0 0 0 1px var(--asst-pill-warn-ring); }
|
|
1506
1605
|
.asst-login-box { display: flex; flex-direction: column; gap: 8px; padding: 10px 12px; border-radius: var(--asst-r-field); box-shadow: inset 0 0 0 1px var(--asst-line-2); }
|
|
1507
1606
|
.asst-login-code { color: var(--asst-text); font-family: var(--asst-mono); font-size: 15px; letter-spacing: .1em; }
|
|
1508
1607
|
|
|
1509
1608
|
.asst-routes-modal { width: min(660px, 100%); }
|
|
1510
|
-
.asst-budget-
|
|
1609
|
+
.asst-budget-modal { width: min(560px, calc(100vw - 24px)); }
|
|
1610
|
+
.asst-budget-controls { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; align-items: center; min-width: 0; }
|
|
1611
|
+
.asst-budget-controls > :is(.asst-modal-note, .asst-budget-field-error, .asst-budget-switch-label) { grid-column: 1 / -1; }
|
|
1612
|
+
.asst-budget-controls > .asst-btn { justify-self: start; }
|
|
1613
|
+
.asst-budget-controls .asst-budget-input { width: 96px; min-width: 0; box-sizing: border-box; }
|
|
1614
|
+
.asst-budget-switch-label { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--asst-text); cursor: pointer; }
|
|
1615
|
+
.asst-budget-switch { appearance: none; position: relative; width: 30px; height: 18px; margin: 0; border: 0; border-radius: var(--asst-pill-r-xs); background: var(--asst-fill-3); box-shadow: inset 0 0 0 1px var(--asst-line-2); cursor: pointer; }
|
|
1616
|
+
.asst-budget-switch::before { content: ''; position: absolute; width: 12px; height: 12px; top: 3px; left: 3px; border-radius: var(--asst-pill-r-xs); background: var(--asst-text-3); transition: transform var(--asst-dur-fast) var(--asst-ease-standard); }
|
|
1617
|
+
.asst-budget-switch:checked { background: var(--asst-brand); }
|
|
1618
|
+
.asst-budget-switch:checked::before { background: var(--asst-ink); transform: translateX(12px); }
|
|
1619
|
+
.asst-budget-controls :is(input, button):focus-visible { outline: 2px solid var(--asst-focus); outline-offset: 2px; }
|
|
1620
|
+
.asst-budget-controls input:disabled { opacity: .5; }
|
|
1621
|
+
.asst-budget-popover .asst-dd-list { padding: 8px; }
|
|
1622
|
+
.asst-budget-session { display: flex; flex-direction: column; gap: 12px; margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--asst-line); }
|
|
1623
|
+
.asst-budget-total { font-family: var(--asst-mono); }
|
|
1624
|
+
.asst-budget-session[data-tone="warn"] .asst-budget-total, .asst-budget-dry { color: var(--asst-warn); }
|
|
1625
|
+
.asst-budget-session[data-tone="over"] .asst-budget-total { color: var(--asst-live); }
|
|
1626
|
+
.asst-budget-providers { display: flex; flex-direction: column; gap: 8px; }
|
|
1627
|
+
.asst-budget-provider { padding: 8px; border-radius: var(--asst-r-field); background: var(--asst-fill-1); overflow-wrap: anywhere; }
|
|
1628
|
+
.asst-budget-provider[data-eligible="false"] { color: var(--asst-text-3); }
|
|
1629
|
+
.asst-budget-provider-name { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
|
|
1630
|
+
.asst-budget-provider-money { margin-top: 4px; font: 12px/1.5 var(--asst-mono); }
|
|
1631
|
+
.asst-budget-brain { padding: 0 6px; border-radius: var(--asst-pill-r-xs); background: var(--asst-fill-2); font-size: 11.5px; }
|
|
1632
|
+
.asst-budget-dry { font-size: 12px; }
|
|
1633
|
+
.asst-budget-meter { width: 100%; accent-color: var(--asst-brand); }
|
|
1511
1634
|
.asst-budget-desc, .asst-budget-meta { color: var(--asst-text-3); font-size: 11.5px; line-height: 1.4; }
|
|
1512
1635
|
.asst-budget-meta { font-variant-numeric: tabular-nums; }
|
|
1513
1636
|
.asst-budget-field-error { color: var(--asst-live); font-size: 11.5px; line-height: 1.4; }
|
|
@@ -1592,7 +1715,7 @@ export function injectAssistantStyles() {
|
|
|
1592
1715
|
/* Model routes editor: Settings density on a desktop pointer. Scoped here
|
|
1593
1716
|
so route cards, the model manager and other Assistant menus keep their UI. */
|
|
1594
1717
|
.asst-routes-overlay { font-family: var(--stg-font, -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", Inter, sans-serif); }
|
|
1595
|
-
.asst-routes-overlay .asst-routes-modal { width: min(
|
|
1718
|
+
.asst-routes-overlay .asst-routes-modal { width: min(1040px, 100%); max-height: calc(100dvh - 32px); border-radius: var(--asst-r-card); line-height: 1.4; }
|
|
1596
1719
|
.asst-routes-modal :is(.asst-btn, .asst-dd, .asst-iconbtn) { --cap-h: var(--asst-pill-h-sm); --cap-r: var(--asst-pill-r-xs); --cap-px: var(--asst-pill-px-sm); --cap-icon: 12px; --cap-gap: 4px; }
|
|
1597
1720
|
.asst-routes-modal .asst-modal-head { min-height: 40px; padding: 8px 14px 8px 22px; font-size: 13px; }
|
|
1598
1721
|
.asst-routes-modal .asst-modal-head .asst-icon { color: var(--asst-text-2); }
|
|
@@ -1616,7 +1739,7 @@ export function injectAssistantStyles() {
|
|
|
1616
1739
|
.asst-routes-modal .asst-routes-list-actions .asst-btn:hover:not(:disabled) { color: var(--asst-text); background: var(--asst-fill-1); }
|
|
1617
1740
|
/* Reserve the widths the current model names, effort words and destinations
|
|
1618
1741
|
need; give all remaining space to task descriptions instead of a share. */
|
|
1619
|
-
.asst-routes-modal .asst-routes-columns, .asst-routes-modal .asst-routes-row { display: grid; grid-template-columns: minmax(
|
|
1742
|
+
.asst-routes-modal .asst-routes-columns, .asst-routes-modal .asst-routes-row { display: grid; grid-template-columns: minmax(100px, 1fr) minmax(120px, 200px) 70px 116px minmax(120px, 190px) var(--asst-pill-h-sm); column-gap: 6px; }
|
|
1620
1743
|
.asst-routes-columns { position: sticky; top: -14px; z-index: 1; padding: 4px 8px; color: var(--asst-text-3); font-size: 11.5px; background: var(--asst-popover); }
|
|
1621
1744
|
.asst-routes-columns span:last-child { visibility: hidden; }
|
|
1622
1745
|
.asst-routes-modal .asst-routes-list { padding: 0 8px; border: 1px solid var(--asst-line); border-radius: var(--radius-group, 9px); background: var(--asst-field); }
|
|
@@ -1650,11 +1773,16 @@ export function injectAssistantStyles() {
|
|
|
1650
1773
|
.asst-routes-catalog-note { padding: 8px; color: var(--asst-warn); font-size: 12px; line-height: 1.45; background: var(--asst-fill-1); border-radius: var(--asst-pill-r-xs); }
|
|
1651
1774
|
.asst-routes-modal .asst-routes-error { flex-wrap: wrap; }
|
|
1652
1775
|
.asst-routes-modal .asst-routes-error span { min-width: 0; overflow-wrap: anywhere; }
|
|
1653
|
-
.asst-routes-overlay :is(.asst-route-model-menu, .asst-route-field-menu) { max-width: min(440px, calc(100vw - 16px)); font-family: inherit; font-size: 12px; }
|
|
1776
|
+
.asst-routes-overlay :is(.asst-route-model-menu, .asst-route-field-menu) { max-width: min(440px, calc(100vw - 16px), var(--asst-dd-room, 100vw)); font-family: inherit; font-size: 12px; }
|
|
1654
1777
|
.asst-routes-overlay :is(.asst-route-model-menu, .asst-route-field-menu) .asst-dd-item { height: var(--asst-pill-h-sm); min-height: var(--asst-pill-h-sm); padding: 0 8px; border-radius: var(--asst-pill-r-xs); }
|
|
1655
1778
|
.asst-routes-overlay :is(.asst-route-model-menu, .asst-route-field-menu) .asst-dd-item-main { flex-direction: row; align-items: center; gap: 8px; }
|
|
1656
1779
|
.asst-routes-overlay :is(.asst-route-model-menu, .asst-route-field-menu) .asst-dd-item-label { flex-shrink: 0; max-width: 60%; }
|
|
1657
1780
|
.asst-routes-overlay :is(.asst-route-model-menu, .asst-route-field-menu) .asst-dd-item-desc { flex: 1; text-align: end; }
|
|
1781
|
+
/* Account identities and quota windows need a second line in their menu. */
|
|
1782
|
+
.asst-routes-overlay .asst-route-account-menu .asst-dd-item { height: auto; min-height: var(--asst-pill-h-sm); padding: 4px 8px; }
|
|
1783
|
+
.asst-routes-overlay .asst-route-account-menu .asst-dd-item-main { flex-direction: column; align-items: stretch; gap: 2px; }
|
|
1784
|
+
.asst-routes-overlay .asst-route-account-menu :is(.asst-dd-item-label, .asst-dd-item-desc) { white-space: normal; max-width: none; text-align: start; overflow-wrap: anywhere; }
|
|
1785
|
+
.asst-model-menu .asst-dd-item[data-kind="radio"]:not([data-id*=":"]) .asst-dd-item-desc { white-space: normal; overflow-wrap: anywhere; }
|
|
1658
1786
|
.asst-routes-overlay .asst-route-model-menu .asst-dd-input { height: var(--asst-pill-h-sm); min-height: var(--asst-pill-h-sm); font-size: 12px; border-radius: var(--asst-pill-r-xs); }
|
|
1659
1787
|
.asst-routes-overlay .asst-route-model-menu .asst-dd-input:focus-visible { outline: 2px solid var(--asst-focus); outline-offset: -2px; }
|
|
1660
1788
|
.asst-route-menu-foot { flex-shrink: 0; display: flex; flex-wrap: wrap; align-items: center; border-top: 1px solid var(--asst-line-2); padding-top: 4px; }
|
|
@@ -1665,7 +1793,7 @@ export function injectAssistantStyles() {
|
|
|
1665
1793
|
.asst-routes-modal :is(.asst-btn, .asst-dd, .asst-iconbtn) { --cap-h: 44px; }
|
|
1666
1794
|
.asst-routes-modal .asst-routes-mode { height: auto; min-height: 44px; }
|
|
1667
1795
|
.asst-routes-modal .asst-routes-mode-label { white-space: normal; }
|
|
1668
|
-
.asst-routes-modal .asst-routes-columns, .asst-routes-modal .asst-routes-row { grid-template-columns: minmax(0,
|
|
1796
|
+
.asst-routes-modal .asst-routes-columns, .asst-routes-modal .asst-routes-row { grid-template-columns: minmax(0, 1fr) minmax(0, 1.5fr) minmax(0, .7fr) minmax(0, .9fr) minmax(0, 1.4fr) 44px; }
|
|
1669
1797
|
.asst-routes-overlay :is(.asst-route-model-menu, .asst-route-field-menu) :is(.asst-dd-item, .asst-dd-input) { min-height: 44px; height: auto; padding: 8px; }
|
|
1670
1798
|
.asst-routes-overlay :is(.asst-route-model-menu, .asst-route-field-menu) .asst-dd-item-main { flex-direction: column; align-items: stretch; gap: 2px; }
|
|
1671
1799
|
.asst-routes-overlay :is(.asst-route-model-menu, .asst-route-field-menu) :is(.asst-dd-item-label, .asst-dd-item-desc) { white-space: normal; max-width: none; text-align: start; overflow-wrap: anywhere; }
|
|
@@ -1678,7 +1806,7 @@ export function injectAssistantStyles() {
|
|
|
1678
1806
|
.asst-routes-modal .asst-routes-modes { grid-template-columns: 1fr; }
|
|
1679
1807
|
.asst-routes-modal .asst-routes-columns { display: none; }
|
|
1680
1808
|
.asst-routes-modal .asst-routes-row { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 44px; gap: 8px; padding: 12px 0; }
|
|
1681
|
-
.asst-routes-modal .asst-routes-row-main, .asst-routes-modal .asst-routes-model-cell { grid-column: 1 / -1; }
|
|
1809
|
+
.asst-routes-modal .asst-routes-row-main, .asst-routes-modal .asst-routes-model-cell, .asst-routes-modal .asst-routes-account-cell { grid-column: 1 / -1; }
|
|
1682
1810
|
.asst-routes-cell { flex-direction: column; gap: 4px; }
|
|
1683
1811
|
.asst-routes-cell-label { display: block; color: var(--asst-text-3); font-size: 11.5px; }
|
|
1684
1812
|
.asst-routes-reset-cell { align-self: end; }
|
|
@@ -1749,8 +1877,9 @@ export function injectAssistantStyles() {
|
|
|
1749
1877
|
density is its gauge alone. A capsule that runs out of
|
|
1750
1878
|
room drops its label half first and stays a glyph (its words remain in
|
|
1751
1879
|
aria-label and the tooltip): route mode and Computer ≤960px, the mode
|
|
1752
|
-
≤540px, every composer field but the model ≤440px
|
|
1753
|
-
and
|
|
1880
|
+
≤540px, every composer field but the model ≤440px, where the model
|
|
1881
|
+
drops its caret and keeps its name (its form fits the row: see the
|
|
1882
|
+
model chip above). Model, history, new and "⋯" never hide; whatever hides stays in "⋯". A toolbar placed
|
|
1754
1883
|
outside the root (the sidepanel header) is out of reach of these rules:
|
|
1755
1884
|
its host sizes it (asst-sidepanel-styles.js).
|
|
1756
1885
|
Glyph only is the same three rules everywhere (see Capsules): the
|
|
@@ -1776,13 +1905,13 @@ export function injectAssistantStyles() {
|
|
|
1776
1905
|
.asst-composer-brain .asst-dd.asst-dd-mode { display: grid; place-content: center; place-items: center; padding: 0; }
|
|
1777
1906
|
.asst-composer-brain .asst-dd.asst-dd-mode > :is(.asst-dd-label, .asst-dd-caret) { display: none; }
|
|
1778
1907
|
.asst-composer-brain .asst-dd.asst-dd-mode > .asst-icon:not([hidden]) { margin: 0; padding: 0 var(--cap-glyph-pad); box-shadow: none; }
|
|
1779
|
-
.asst-dd-model .asst-dd-label { max-width: 14ch; }
|
|
1780
1908
|
.asst-route-badge { display: none; }
|
|
1781
1909
|
}
|
|
1782
1910
|
@container asst (max-width: 440px) {
|
|
1783
1911
|
.asst-composer-brain .asst-dd:is(.asst-dd-effort, .asst-dd-variant, .asst-dd-mode, .asst-dd-account) { display: grid; place-content: center; place-items: center; padding: 0; }
|
|
1784
1912
|
.asst-composer-brain .asst-dd:is(.asst-dd-effort, .asst-dd-variant, .asst-dd-mode, .asst-dd-account) > :is(.asst-dd-label, .asst-dd-caret) { display: none; }
|
|
1785
1913
|
.asst-composer-brain .asst-dd:is(.asst-dd-effort, .asst-dd-variant, .asst-dd-mode, .asst-dd-account) > .asst-icon:not([hidden]) { margin: 0; padding: 0 var(--cap-glyph-pad); box-shadow: none; }
|
|
1914
|
+
.asst-composer-brain .asst-dd.asst-dd-model > .asst-dd-caret { display: none; }
|
|
1786
1915
|
}
|
|
1787
1916
|
@container asst (max-width: 400px) {
|
|
1788
1917
|
.asst-root > * { --asst-inline: 6px; }
|
|
@@ -1790,19 +1919,17 @@ export function injectAssistantStyles() {
|
|
|
1790
1919
|
.asst-suggestions { flex-direction: column; align-items: stretch; width: 100%; }
|
|
1791
1920
|
.asst-chip.asst-suggestion { justify-content: flex-start; max-width: none; }
|
|
1792
1921
|
.asst-empty-project { width: 100%; }
|
|
1793
|
-
.asst-dd.asst-empty-
|
|
1794
|
-
.asst-empty-
|
|
1922
|
+
.asst-dd.asst-empty-control-btn { flex: 1 1 auto; justify-content: flex-start; max-width: none; }
|
|
1923
|
+
.asst-empty-control-btn .asst-dd-label { flex: 1 1 auto; max-width: none; text-align: start; }
|
|
1795
1924
|
.asst-msg.msg-user .asst-msg-content { max-width: 92%; }
|
|
1796
|
-
.asst-dd-model .asst-dd-label { max-width: 9ch; }
|
|
1797
1925
|
.asst-route-opt-sub { display: none; }
|
|
1798
1926
|
.asst-run-main { flex-wrap: wrap; row-gap: 2px; }
|
|
1799
1927
|
.asst-run-title { flex-basis: 100%; }
|
|
1800
1928
|
}
|
|
1801
1929
|
@container asst (max-width: 320px) {
|
|
1802
1930
|
.asst-bar-group[data-group="computer"] { display: none !important; }
|
|
1803
|
-
/*
|
|
1804
|
-
|
|
1805
|
-
/* A tighter gap keeps attach · model · effort · variant · mode · tests · send on one row at 320px. */
|
|
1931
|
+
/* A tighter gap keeps attach · model · effort · variant · mode · tests · send on one row at 320px;
|
|
1932
|
+
narrower, the row wraps rather than cut the model chip. */
|
|
1806
1933
|
.asst-composer-actions { flex-wrap: wrap; gap: 6px 4px; }
|
|
1807
1934
|
.asst-composer-brain { flex-wrap: wrap; gap: 6px 4px; }
|
|
1808
1935
|
}
|
|
@@ -1825,6 +1952,8 @@ export function injectAssistantStyles() {
|
|
|
1825
1952
|
@keyframes asst-spin { to { transform: rotate(360deg); } }
|
|
1826
1953
|
|
|
1827
1954
|
body.ui-interacting :is(.asst-live-dot, .asst-spinner, .asst-computer-dot, .syna-cameo-eye) { animation-play-state: paused !important; }
|
|
1955
|
+
body.ui-interacting .asst-route-line[data-live] .asst-route-icon,
|
|
1956
|
+
body.ui-interacting .asst-route-line[data-live] .asst-route-sweep::after { animation-play-state: paused !important; }
|
|
1828
1957
|
|
|
1829
1958
|
@media (prefers-reduced-motion: reduce) {
|
|
1830
1959
|
.asst-transcript { scroll-behavior: auto; }
|
|
@@ -1834,6 +1963,8 @@ export function injectAssistantStyles() {
|
|
|
1834
1963
|
.term-minimized-pill,
|
|
1835
1964
|
.term-minimized-pill::before,
|
|
1836
1965
|
.term-minimized-pill::after { animation: none !important; transition: none !important; }
|
|
1966
|
+
/* A frozen sweep would be a stray stub: the route row draws none (its run card and state words remain). */
|
|
1967
|
+
.asst-route-sweep { display: none; }
|
|
1837
1968
|
}
|
|
1838
1969
|
`;
|
|
1839
1970
|
document.head.appendChild(style);
|
|
@@ -20,6 +20,8 @@ const definitions = [
|
|
|
20
20
|
['hooks', 'Inspect configured hooks', 'hooks_list'],
|
|
21
21
|
['init', 'Create or update AGENTS.md guidance', null, true],
|
|
22
22
|
['logout', 'Sign out of Codex', 'account_logout'],
|
|
23
|
+
['login', 'Sign in with ChatGPT'],
|
|
24
|
+
['account', 'Choose an account or sign in'],
|
|
23
25
|
['mcp', 'Search MCP servers and tools', 'mcp_status'],
|
|
24
26
|
['mention', 'Add a structured file mention', null, true],
|
|
25
27
|
['model', 'Choose model'],
|
|
@@ -146,10 +148,11 @@ export function configChanges(definitions, inputs, original) {
|
|
|
146
148
|
export const SESSION_CONFIG_FIELDS = Object.freeze({
|
|
147
149
|
model: 'model', model_reasoning_effort: 'effort', model_reasoning_summary: 'summary',
|
|
148
150
|
personality: 'personality', service_tier: 'serviceTier', approval_policy: 'approvalPolicy',
|
|
151
|
+
sandbox_mode: 'sandboxPolicy',
|
|
149
152
|
});
|
|
150
153
|
|
|
151
154
|
export function sessionSettings(config) {
|
|
152
|
-
return Object.fromEntries(Object.entries(config).filter(([key]) => SESSION_CONFIG_FIELDS[key]).map(([key, value]) => [SESSION_CONFIG_FIELDS[key], value]));
|
|
155
|
+
return Object.fromEntries(Object.entries(config).filter(([key]) => SESSION_CONFIG_FIELDS[key]).map(([key, value]) => [key === 'sandbox_mode' ? 'sandboxMode' : SESSION_CONFIG_FIELDS[key], value]));
|
|
153
156
|
}
|
|
154
157
|
|
|
155
158
|
export function modelServiceTiers(model) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { capabilityAvailability, flattenNativeCatalog, reviewTarget } from './cdx-commands.js';
|
|
2
|
+
import { t } from '../i18n.js';
|
|
2
3
|
import { knownCodexCapabilities } from './cdx-capabilities.js';
|
|
3
4
|
import { codexReadableValue, parseCodexAttachmentPayload, codexGatewayState, codexVerificationState, codexHttpsHandoff } from './cdx-protocol.js';
|
|
4
5
|
|
|
@@ -333,23 +334,27 @@ export function updateCodexGateway(tab, value) {
|
|
|
333
334
|
accountSecurityViews.get(tab)?.();
|
|
334
335
|
}
|
|
335
336
|
|
|
336
|
-
export async function mountCodexAccountSecurity({ host, request, tab, capabilities }) {
|
|
337
|
+
export async function mountCodexAccountSecurity({ host, experimentalHost = host, request, tab, capabilities }) {
|
|
338
|
+
const tr = (key, params) => t(`codexSettings.${key}`, params);
|
|
337
339
|
const view = { error: message => { error.textContent = message; } };
|
|
338
340
|
const error = element('div', 'cxp-settings-hint'); error.setAttribute('role', 'alert');
|
|
339
341
|
const gateway = element('div', 'cxp-settings-section');
|
|
340
342
|
const verification = element('div', 'cxp-settings-section');
|
|
341
|
-
host.append(gateway,
|
|
343
|
+
host.append(gateway, error);
|
|
344
|
+
experimentalHost.append(verification);
|
|
342
345
|
const available = name => capabilityAvailability(knownCodexCapabilities(tab) || capabilities, name);
|
|
343
346
|
const renderGateway = () => {
|
|
344
347
|
if (!host.isConnected || tab.closed) { accountSecurityViews.delete(tab); return; }
|
|
345
348
|
gateway.replaceChildren();
|
|
346
349
|
if (!available('gateway_oauth_read').supported) return;
|
|
347
350
|
const value = tab.gatewayOAuth || {};
|
|
351
|
+
gateway.hidden = !value.required;
|
|
352
|
+
if (!value.required) return;
|
|
348
353
|
const state = codexGatewayState(value);
|
|
349
|
-
gateway.append(element('div', 'cxp-settings-section-title', '
|
|
350
|
-
gateway.append(element('div', 'cxp-settings-hint', `${value.providerName || value.providerId || '
|
|
354
|
+
gateway.append(element('div', 'cxp-settings-section-title', tr('gateway')));
|
|
355
|
+
gateway.append(element('div', 'cxp-settings-hint', `${value.providerName || value.providerId || tr('provider')} · ${tr(`gatewayStates.${value.status || 'notReady'}`)}`));
|
|
351
356
|
const action = state.pending ? 'gateway_oauth_cancel' : 'gateway_oauth_login';
|
|
352
|
-
gateway.append(button(state.pending ? '
|
|
357
|
+
gateway.append(button(tr(state.pending ? 'cancel' : 'signIn'), async () => {
|
|
353
358
|
if (!available(action).supported) throw new Error(available(action).reason);
|
|
354
359
|
await request(action, {});
|
|
355
360
|
// Notification is authoritative; do not overwrite a completed login with a stale optimistic state.
|
|
@@ -360,10 +365,10 @@ export async function mountCodexAccountSecurity({ host, request, tab, capabiliti
|
|
|
360
365
|
}, view, available(action)));
|
|
361
366
|
if (!available(action).supported) gateway.append(element('div', 'cxp-settings-hint', available(action).reason));
|
|
362
367
|
const handoff = codexHttpsHandoff(value.authUrl);
|
|
363
|
-
if (value.authUrl && !handoff) gateway.append(element('div', 'cxp-settings-hint', '
|
|
368
|
+
if (value.authUrl && !handoff) gateway.append(element('div', 'cxp-settings-hint', tr('httpsRequired')));
|
|
364
369
|
if (handoff && state.pending) {
|
|
365
|
-
gateway.append(element('div', 'cxp-settings-hint',
|
|
366
|
-
gateway.append(button(
|
|
370
|
+
gateway.append(element('div', 'cxp-settings-hint', tr('continueAt', { host: handoff.host })));
|
|
371
|
+
gateway.append(button(tr('openHost', { host: handoff.host }), () => {
|
|
367
372
|
window.open(handoff.url, '_blank', 'noopener,noreferrer');
|
|
368
373
|
}, view));
|
|
369
374
|
}
|
|
@@ -386,12 +391,15 @@ export async function mountCodexAccountSecurity({ host, request, tab, capabiliti
|
|
|
386
391
|
const response = await request('verification_status', {});
|
|
387
392
|
if (!host.isConnected || tab.closed) return;
|
|
388
393
|
const state = codexVerificationState(response.verification);
|
|
389
|
-
|
|
390
|
-
verification.
|
|
391
|
-
verification.
|
|
394
|
+
const reason = response.verification?.unavailableReason;
|
|
395
|
+
verification.hidden = !!reason && reason !== 'credentialMissing';
|
|
396
|
+
if (verification.hidden) return;
|
|
397
|
+
verification.append(element('div', 'cxp-settings-section-title', tr('verification')));
|
|
398
|
+
verification.append(element('div', 'cxp-settings-hint', tr(state.enrolled ? 'credentialReady' : 'credentialMissing')));
|
|
399
|
+
verification.append(element('div', 'cxp-settings-hint', tr('localCredential')));
|
|
392
400
|
const action = state.enrolled ? 'verification_delete' : 'verification_enroll';
|
|
393
|
-
const control = button(state.enrolled ? '
|
|
394
|
-
if (state.enrolled && !window.confirm('
|
|
401
|
+
const control = button(tr(state.enrolled ? 'remove' : 'enroll'), async () => {
|
|
402
|
+
if (state.enrolled && !window.confirm(tr('removeCredential'))) return;
|
|
395
403
|
await request(action, {}); await readVerification();
|
|
396
404
|
}, view, available(action));
|
|
397
405
|
if (state.enrolled) control.style.color = 'var(--cxp-danger)';
|
|
@@ -399,7 +407,7 @@ export async function mountCodexAccountSecurity({ host, request, tab, capabiliti
|
|
|
399
407
|
if (!available(action).supported) verification.append(element('div', 'cxp-settings-hint', available(action).reason));
|
|
400
408
|
} catch (failure) {
|
|
401
409
|
if (available('verification_status').supported) {
|
|
402
|
-
verification.append(element('div', 'cxp-settings-hint',
|
|
410
|
+
verification.append(element('div', 'cxp-settings-hint', tr('error', { message: failure.message })));
|
|
403
411
|
}
|
|
404
412
|
}
|
|
405
413
|
}
|
|
@@ -41,6 +41,8 @@ export let windowId = hostedSidepanelId || sessionStorage.getItem('cxp-window-id
|
|
|
41
41
|
// ── Storage Keys ──
|
|
42
42
|
export const STOR = {
|
|
43
43
|
threadId: 'synabun-codex-panel-thread',
|
|
44
|
+
// The account that thread belongs to (its rollout lives in that account's CODEX_HOME).
|
|
45
|
+
threadAccount: 'synabun-codex-panel-thread-account',
|
|
44
46
|
title: 'synabun-codex-panel-title',
|
|
45
47
|
project: 'synabun-codex-panel-project',
|
|
46
48
|
projectThreads: 'synabun-codex-panel-project-threads',
|