diff --git a/README.md b/README.md index 634eb884..1cb24db3 100644 --- a/README.md +++ b/README.md @@ -295,7 +295,7 @@ Need help with `PATH`, API keys, provider/model matching, or JSON errors? See th ## 🌐 WebUI -The WebUI ships **inside the published wheel** — no extra build step. It is the browser workbench for chat sessions, workspace controls, Apps, Skills, Automations, and settings. For the full user guide, see [`docs/webui.md`](./docs/webui.md). +The WebUI ships **inside the published wheel** — no extra build step. It is the browser workbench for topics, workspace controls, Apps, Skills, Automations, and settings. For the full user guide, see [`docs/webui.md`](./docs/webui.md).

nanobot webui preview diff --git a/docs/automations.md b/docs/automations.md index 9ca0dedd..56d779bd 100644 --- a/docs/automations.md +++ b/docs/automations.md @@ -2,21 +2,21 @@ -Automations are agent turns that run later in a linked chat/session. Use them +Automations are agent turns that run later in a linked topic. Use them when nanobot should do work without someone actively typing: reminders, recurring checks, nightly summaries, CI follow-ups, local script reports, or webhook-driven events. -Create automations from the chat, channel, or WebUI session where the result -should appear. That lets nanobot keep the right session history, workspace, and -reply target. +Create automations from the chat channel or WebUI topic where the +result should appear. That lets nanobot keep the right session history, +workspace, and reply target. ## Choose an Automation Type | Type | Starts from | Best for | Created with | |---|---|---|---| -| Scheduled automation | Time, interval, or cron expression | Recurring reminders, scheduled summaries, one-time future tasks | Ask nanobot in the target session to schedule it with the `cron` tool | -| Local trigger | A local `nanobot trigger ...` command | CI jobs, webhooks, shell scripts, generated reports | `/trigger ` in the target session | +| Scheduled automation | Time, interval, or cron expression | Recurring reminders, scheduled summaries, one-time future tasks | Ask nanobot in the target topic to schedule it with the `cron` tool | +| Local trigger | A local `nanobot trigger ...` command | CI jobs, webhooks, shell scripts, generated reports | `/trigger ` in the target topic | | Heartbeat | Protected system schedule | Quiet recurring checks that should only report useful results | Edit `/HEARTBEAT.md` | The two user-created automation types are scheduled automations and local @@ -26,21 +26,21 @@ protected from normal automation edits. ## Before You Create One Keep `nanobot gateway` running. The gateway owns background delivery for chat -apps, WebUI sessions, scheduled automations, local triggers, heartbeat, and +apps, WebUI topics, scheduled automations, local triggers, heartbeat, and Dream jobs. Use the same workspace and config for the gateway and any process that sends local trigger messages. If you run multiple nanobot instances, pass the matching `--config` or `--workspace` option to `nanobot trigger`. -Create each automation from the target session. An automation without a linked -chat/session cannot be enabled or run from the WebUI because nanobot would not -know where to deliver the turn. +Create each automation from the target topic. An automation without a linked +topic cannot be enabled or run from the WebUI because nanobot would not know +where to deliver the turn. ## Scheduled Automations Scheduled automations are created by the agent's `cron` tool. In practice, ask -nanobot from the target chat or WebUI session: +nanobot from the target chat or WebUI topic: ```text Every weekday at 9am, check open pull requests and summarize blockers here. @@ -68,7 +68,7 @@ report, use heartbeat instead of a user-created scheduled automation. Local triggers let a local script or external service send a message into a specific nanobot session later. -Create the trigger from the chat or WebUI session where future messages should +Create the trigger from the chat or WebUI topic where future messages should arrive: ```text @@ -120,7 +120,7 @@ Heartbeat is enabled by default when `nanobot gateway` starts. Configure it in Use the WebUI Automations view to: - filter by all, active, paused, needs-attention, or system jobs; -- search by task name, message, trigger command, linked chat, schedule, or +- search by task name, message, trigger command, linked topic, schedule, or status; - sort by next run, last run, updated time, or name; - run scheduled automations now; @@ -138,7 +138,7 @@ Automation delivery is workspace-local. Scheduled jobs and local trigger deliveries use the same workspace as the gateway. Local trigger messages are written to a durable queue. If the gateway is not -running yet, the message waits in that workspace. If the linked session is +running yet, the message waits in that workspace. If the linked topic is already running a turn, the trigger waits until the session becomes idle instead of being injected into the active turn. @@ -154,7 +154,7 @@ queue is not a distributed multi-consumer queue. ## Common Patterns -For a nightly report, ask from the target session: +For a nightly report, ask from the target topic: ```text Every night at 9pm, review today's workspace changes and summarize anything I should handle tomorrow. @@ -181,7 +181,7 @@ generate-report | nanobot trigger ## Troubleshooting If an automation does not run, check that `nanobot gateway` is running, the -automation is enabled, and it was created from a linked chat/session. +automation is enabled, and it was created from a linked topic. If a local trigger waits forever, confirm the command uses the same workspace or config as the gateway. diff --git a/docs/webui.md b/docs/webui.md index ef3ce74a..f6efd3e0 100644 --- a/docs/webui.md +++ b/docs/webui.md @@ -1,8 +1,8 @@ # Nanobot WebUI: Browser Workbench for Self-Hosted AI Agents - + -The WebUI is nanobot's browser workbench for persistent chat sessions, visible +The WebUI is nanobot's browser workbench for persistent topics, visible agent activity, workspace controls, Apps, Skills, settings, and Automations in one place. @@ -57,9 +57,9 @@ gateway health endpoint, `18790` by default, is not the browser UI. Use the WebUI as the primary setup surface after Quick Start: -1. Send `Hello!` in a new chat to prove the selected model works. +1. Send `Hello!` in a new topic to prove the selected model works. 2. Open **Settings → Models** and confirm the active model preset. -3. Start a separate chat before project work, then choose the intended workspace and access mode. +3. Start a separate topic before project work, then choose the intended workspace and access mode. 4. Add only one capability next: a chat channel in **Settings → Channels**, a web/voice/image provider in **Settings**, or an App/MCP integration in **Apps**. 5. Restart when the WebUI shows a restart requirement, then test that capability with the smallest possible request. @@ -69,7 +69,7 @@ This path avoids hand-editing `config.json` for normal setup. Use the reference | Area | Use it for | |---|---| -| Chat | Start, switch, search, fork, and delete browser sessions | +| Topics | Start, switch, search, fork, and delete browser topics | | Agent activity | See thinking, tool calls, file edits with diffs, command output, and generated artifacts in context | | Workspace | Pick the project workspace before asking for file or shell work | | Access | Choose the access mode for local capabilities allowed by your gateway configuration | @@ -80,10 +80,10 @@ This path avoids hand-editing `config.json` for normal setup. Use the reference | Automations | Review, search, run, pause, edit, and delete scheduled and local-trigger agent turns | | Settings | Adjust models, providers, image generation, voice, web tools, runtime, and safety options | -## Chat Workspace +## Topic Workspace -The sidebar is the session switcher. A session keeps its own history, title, -workspace metadata, and linked automations. Use a new session when you want a +The sidebar is the topic switcher. Each topic keeps its own history, title, +workspace selection, and linked automations. Use a new topic when you want a separate context; use fork when you want to continue from an existing point without changing the original thread. @@ -123,7 +123,7 @@ directory. The access control in the composer controls the local capability level for the chat. It does not bypass your gateway, provider, shell sandbox, or operating system configuration; it only selects among the capabilities that are already -available to this WebUI session. +available to the current topic. In Restricted mode, ordinary file and shell work stays inside the selected project. To preserve agent continuity, filesystem/search tools receive narrow, @@ -133,7 +133,7 @@ neighboring memory or profile files, and it does not allow writes outside the selected project. These tool exceptions do not broaden the browser's file preview boundary. -Remote WebUI sessions may reduce access for the current workspace. Selecting a +Remote WebUI connections may reduce access for the current workspace. Selecting a different workspace or enabling Full Access remains limited to local and native clients. @@ -199,10 +199,10 @@ to perform that task. ## Automations -Automations are agent turns that run later in a linked chat/session. They should -be created from the chat, channel, or session where they are supposed to run so -nanobot keeps the correct target context. When an automation runs, it normally -delivers the result back to that linked chat. +Automations are agent turns that run later in a linked topic. Create them from +the topic or channel where they are supposed to run so nanobot keeps the +correct target context. When an automation runs, it normally delivers the +result back to that topic. For the full automation model, creation flow, trigger CLI usage, and delivery semantics, see [`automations.md`](./automations.md). @@ -221,7 +221,7 @@ instead of creating a chat automation. Use the Automations view to: - Filter by all, active, paused, needs-attention, or system jobs. -- Search by task name, message, trigger command, linked chat, schedule, or status. +- Search by task name, message, trigger command, linked topic, schedule, or status. - Sort by next run, last run, updated time, or name. - Run scheduled automations now. - Pause or resume, rename, or delete user-created automations. @@ -232,9 +232,9 @@ Search accepts plain text and field filters such as `name:backup`, `chat:WeChat`, `schedule:09:30`, `cron:"0 23 * * *"`, `trigger`, and `status:paused`. -An automation without a linked chat cannot be enabled or run from the WebUI, +An automation without a linked topic cannot be enabled or run from the WebUI, because nanobot would not know where to deliver the scheduled turn. Recreate it -from the target chat or channel so the automation has complete context. +from the target topic or channel so the automation has complete context. Local triggers do not have a WebUI "Run now" action because each run needs a message. Use the copied `nanobot trigger ...` command and replace `"message"` diff --git a/webui/src/components/ChatList.tsx b/webui/src/components/ChatList.tsx index 644876b4..37899986 100644 --- a/webui/src/components/ChatList.tsx +++ b/webui/src/components/ChatList.tsx @@ -516,7 +516,7 @@ function ChatsFoldFooter({ const { t, i18n } = useTranslation(); const collapsedFallback = i18n.resolvedLanguage?.startsWith("zh") ? `已折叠 ${hiddenCount} 个对话` - : `${hiddenCount} hidden chats`; + : `${hiddenCount} hidden topics`; return (

diff --git a/webui/src/i18n/locales/en/common.json b/webui/src/i18n/locales/en/common.json index 75e1b808..bf3260be 100644 --- a/webui/src/i18n/locales/en/common.json +++ b/webui/src/i18n/locales/en/common.json @@ -43,12 +43,12 @@ "sidebar": { "navigation": "Sidebar navigation", "collapse": "Collapse sidebar", - "newChat": "New chat", + "newChat": "New topic", "searchAria": "Search", "searchPlaceholder": "Search", "searchResults": "Results", - "noSearchResults": "No matching chats.", - "recent": "Recent", + "noSearchResults": "No matching topics.", + "recent": "Recent topics", "settings": "Settings", "language": { "label": "Language", @@ -819,15 +819,15 @@ } }, "chat": { - "fallbackTitle": "Chat {{id}}", + "fallbackTitle": "Topic {{id}}", "forkTitle": "Fork: {{title}}", "loading": "Loading…", "noSessions": "No sessions yet.", "showMore": "Show {{count}} more", - "collapsed": "{{count}} hidden chats", + "collapsed": "{{count}} hidden topics", "showLess": "Show less", - "actions": "Chat actions for {{title}}", - "newInProject": "Start a new chat in {{project}}", + "actions": "Topic actions for {{title}}", + "newInProject": "Start a new topic in {{project}}", "activity": { "running": "Agent running", "complete": "Agent finished", @@ -836,9 +836,9 @@ "pin": "Pin", "unpin": "Unpin", "rename": "Rename", - "renameTitle": "Rename chat", - "renameDescription": "Choose a local sidebar name for this chat.", - "renamePlaceholder": "Chat name", + "renameTitle": "Rename topic", + "renameDescription": "Choose a local sidebar name for this topic.", + "renamePlaceholder": "Topic name", "renameProjectTitle": "Rename project", "renameProjectDescription": "Choose a local sidebar name for this project.", "renameProjectPlaceholder": "Project name", @@ -848,10 +848,10 @@ "showArchived": "Show archived", "hideArchived": "Hide archived", "delete": "Delete", - "newChat": "New chat", + "newChat": "New topic", "groups": { "pinned": "Pinned", - "all": "Chats", + "all": "Topics", "projects": "Projects", "today": "Today", "yesterday": "Yesterday", @@ -860,7 +860,7 @@ } }, "deleteConfirm": { - "title": "Delete this chat?", + "title": "Delete this topic?", "description": "This action cannot be undone.", "cancel": "Cancel", "confirm": "Delete", @@ -954,14 +954,14 @@ }, "header": { "toggleSidebar": "Toggle sidebar", - "newChat": "Start a new chat", + "newChat": "Start a new topic", "toggleTheme": "Toggle theme from header", "settings": "Open settings", "sessionInfo": "Session details" }, "sessionInfo": { "title": "Session", - "untitled": "Untitled chat", + "untitled": "Untitled topic", "automations": "Automations", "count": "{{count}}", "loading": "Loading automations...", @@ -987,7 +987,7 @@ "composer": { "placeholderThread": "Type your message…", "placeholderHero": "Ask anything...", - "placeholderOpening": "Opening a new chat…", + "placeholderOpening": "Opening a new topic…", "placeholderStreaming": "Model is responding…", "inputAria": "Message input", "sendHint": "Enter to send · Shift+Enter for newline", diff --git a/webui/src/i18n/locales/es/common.json b/webui/src/i18n/locales/es/common.json index 210ede8b..b86bcda5 100644 --- a/webui/src/i18n/locales/es/common.json +++ b/webui/src/i18n/locales/es/common.json @@ -43,12 +43,12 @@ "sidebar": { "navigation": "Navegación de la barra lateral", "collapse": "Contraer barra lateral", - "newChat": "Nuevo chat", + "newChat": "Nuevo tema", "searchAria": "Buscar", "searchPlaceholder": "Buscar", "searchResults": "Resultados", - "noSearchResults": "No hay chats coincidentes.", - "recent": "Recientes", + "noSearchResults": "No hay temas coincidentes.", + "recent": "Temas recientes", "settings": "Configuración", "language": { "label": "Idioma", @@ -806,15 +806,15 @@ } }, "chat": { - "fallbackTitle": "Chat {{id}}", + "fallbackTitle": "Tema {{id}}", "forkTitle": "Bifurcación: {{title}}", "loading": "Cargando…", "noSessions": "Todavía no hay sesiones.", "showMore": "Mostrar {{count}} más", - "collapsed": "{{count}} chats ocultos", + "collapsed": "{{count}} temas ocultos", "showLess": "Mostrar menos", - "actions": "Acciones del chat {{title}}", - "newInProject": "Iniciar un chat nuevo en {{project}}", + "actions": "Acciones del tema {{title}}", + "newInProject": "Iniciar un tema nuevo en {{project}}", "activity": { "running": "Agent running", "complete": "Agent finished", @@ -823,9 +823,9 @@ "pin": "Pin", "unpin": "Unpin", "rename": "Rename", - "renameTitle": "Rename chat", - "renameDescription": "Choose a local sidebar name for this chat.", - "renamePlaceholder": "Chat name", + "renameTitle": "Renombrar tema", + "renameDescription": "Elige un nombre local de la barra lateral para este tema.", + "renamePlaceholder": "Nombre del tema", "renameProjectTitle": "Rename project", "renameProjectDescription": "Choose a local sidebar name for this project.", "renameProjectPlaceholder": "Project name", @@ -835,10 +835,10 @@ "showArchived": "Show archived", "hideArchived": "Hide archived", "delete": "Eliminar", - "newChat": "Nuevo chat", + "newChat": "Nuevo tema", "groups": { "pinned": "Pinned", - "all": "Chats", + "all": "Temas", "projects": "Projects", "today": "Today", "yesterday": "Yesterday", @@ -941,14 +941,14 @@ }, "header": { "toggleSidebar": "Mostrar u ocultar la barra lateral", - "newChat": "Iniciar un chat nuevo", + "newChat": "Iniciar un tema nuevo", "toggleTheme": "Cambiar tema desde el encabezado", "settings": "Abrir configuración", "sessionInfo": "Detalles de la sesión" }, "sessionInfo": { "title": "Sesión", - "untitled": "Chat sin título", + "untitled": "Tema sin título", "automations": "Automatizaciones", "count": "{{count}}", "loading": "Cargando automatizaciones...", @@ -974,7 +974,7 @@ "composer": { "placeholderThread": "Escribe tu mensaje…", "placeholderHero": "¿Qué tienes en mente?", - "placeholderOpening": "Abriendo un nuevo chat…", + "placeholderOpening": "Abriendo un nuevo tema…", "placeholderStreaming": "El modelo está respondiendo…", "inputAria": "Entrada de mensaje", "sendHint": "Enter para enviar · Shift+Enter para nueva línea", diff --git a/webui/src/i18n/locales/fr/common.json b/webui/src/i18n/locales/fr/common.json index 332940fe..0cc55a48 100644 --- a/webui/src/i18n/locales/fr/common.json +++ b/webui/src/i18n/locales/fr/common.json @@ -43,12 +43,12 @@ "sidebar": { "navigation": "Navigation de la barre latérale", "collapse": "Réduire la barre latérale", - "newChat": "Nouvelle discussion", + "newChat": "Nouveau sujet", "searchAria": "Rechercher", "searchPlaceholder": "Rechercher", "searchResults": "Résultats", - "noSearchResults": "Aucun chat correspondant.", - "recent": "Récentes", + "noSearchResults": "Aucun sujet correspondant.", + "recent": "Sujets récents", "settings": "Paramètres", "language": { "label": "Langue", @@ -805,15 +805,15 @@ } }, "chat": { - "fallbackTitle": "Discussion {{id}}", + "fallbackTitle": "Sujet {{id}}", "forkTitle": "Branche : {{title}}", "loading": "Chargement…", "noSessions": "Aucune session pour le moment.", "showMore": "Afficher {{count}} de plus", - "collapsed": "{{count}} discussions masquées", + "collapsed": "{{count}} sujets masqués", "showLess": "Afficher moins", - "actions": "Actions de la discussion {{title}}", - "newInProject": "Démarrer une nouvelle discussion dans {{project}}", + "actions": "Actions du sujet {{title}}", + "newInProject": "Démarrer un nouveau sujet dans {{project}}", "activity": { "running": "Agent running", "complete": "Agent finished", @@ -822,9 +822,9 @@ "pin": "Pin", "unpin": "Unpin", "rename": "Rename", - "renameTitle": "Rename chat", - "renameDescription": "Choose a local sidebar name for this chat.", - "renamePlaceholder": "Chat name", + "renameTitle": "Renommer le sujet", + "renameDescription": "Choisissez un nom local dans la barre latérale pour ce sujet.", + "renamePlaceholder": "Nom du sujet", "renameProjectTitle": "Rename project", "renameProjectDescription": "Choose a local sidebar name for this project.", "renameProjectPlaceholder": "Project name", @@ -834,10 +834,10 @@ "showArchived": "Show archived", "hideArchived": "Hide archived", "delete": "Supprimer", - "newChat": "Nouvelle discussion", + "newChat": "Nouveau sujet", "groups": { "pinned": "Pinned", - "all": "Chats", + "all": "Sujets", "projects": "Projects", "today": "Today", "yesterday": "Yesterday", @@ -940,14 +940,14 @@ }, "header": { "toggleSidebar": "Afficher ou masquer la barre latérale", - "newChat": "Démarrer un nouveau chat", + "newChat": "Démarrer un nouveau sujet", "toggleTheme": "Changer le thème depuis l’en-tête", "settings": "Ouvrir les paramètres", "sessionInfo": "Détails de la session" }, "sessionInfo": { "title": "Session", - "untitled": "Chat sans titre", + "untitled": "Sujet sans titre", "automations": "Automatisations", "count": "{{count}}", "loading": "Chargement des automatisations...", @@ -973,7 +973,7 @@ "composer": { "placeholderThread": "Saisissez votre message…", "placeholderHero": "Qu’avez-vous en tête ?", - "placeholderOpening": "Ouverture d’une nouvelle discussion…", + "placeholderOpening": "Ouverture d’un nouveau sujet…", "placeholderStreaming": "Le modèle est en train de répondre…", "inputAria": "Champ de message", "sendHint": "Entrée pour envoyer · Maj+Entrée pour un retour à la ligne", diff --git a/webui/src/i18n/locales/id/common.json b/webui/src/i18n/locales/id/common.json index 30441b29..21d75275 100644 --- a/webui/src/i18n/locales/id/common.json +++ b/webui/src/i18n/locales/id/common.json @@ -43,12 +43,12 @@ "sidebar": { "navigation": "Navigasi bilah samping", "collapse": "Ciutkan sidebar", - "newChat": "Obrolan baru", + "newChat": "Topik baru", "searchAria": "Cari", "searchPlaceholder": "Cari", "searchResults": "Hasil", - "noSearchResults": "Tidak ada chat yang cocok.", - "recent": "Terbaru", + "noSearchResults": "Tidak ada topik yang cocok.", + "recent": "Topik terbaru", "settings": "Pengaturan", "language": { "label": "Bahasa", @@ -805,15 +805,15 @@ } }, "chat": { - "fallbackTitle": "Obrolan {{id}}", + "fallbackTitle": "Topik {{id}}", "forkTitle": "Cabang: {{title}}", "loading": "Memuat…", "noSessions": "Belum ada sesi.", "showMore": "Tampilkan {{count}} lagi", - "collapsed": "{{count}} obrolan diciutkan", + "collapsed": "{{count}} topik diciutkan", "showLess": "Tampilkan lebih sedikit", - "actions": "Aksi obrolan untuk {{title}}", - "newInProject": "Mulai obrolan baru di {{project}}", + "actions": "Aksi topik untuk {{title}}", + "newInProject": "Mulai topik baru di {{project}}", "activity": { "running": "Agent running", "complete": "Agent finished", @@ -822,9 +822,9 @@ "pin": "Pin", "unpin": "Unpin", "rename": "Rename", - "renameTitle": "Rename chat", - "renameDescription": "Choose a local sidebar name for this chat.", - "renamePlaceholder": "Chat name", + "renameTitle": "Ganti nama topik", + "renameDescription": "Pilih nama lokal di bilah sisi untuk topik ini.", + "renamePlaceholder": "Nama topik", "renameProjectTitle": "Rename project", "renameProjectDescription": "Choose a local sidebar name for this project.", "renameProjectPlaceholder": "Project name", @@ -834,10 +834,10 @@ "showArchived": "Show archived", "hideArchived": "Hide archived", "delete": "Hapus", - "newChat": "Obrolan baru", + "newChat": "Topik baru", "groups": { "pinned": "Pinned", - "all": "Chats", + "all": "Topik", "projects": "Projects", "today": "Today", "yesterday": "Yesterday", @@ -940,14 +940,14 @@ }, "header": { "toggleSidebar": "Tampilkan atau sembunyikan sidebar", - "newChat": "Mulai chat baru", + "newChat": "Mulai topik baru", "toggleTheme": "Alihkan tema dari header", "settings": "Buka pengaturan", "sessionInfo": "Detail sesi" }, "sessionInfo": { "title": "Sesi", - "untitled": "Chat tanpa judul", + "untitled": "Topik tanpa judul", "automations": "Otomasi", "count": "{{count}}", "loading": "Memuat otomasi...", @@ -973,7 +973,7 @@ "composer": { "placeholderThread": "Ketik pesan Anda…", "placeholderHero": "Apa yang sedang Anda pikirkan?", - "placeholderOpening": "Membuka obrolan baru…", + "placeholderOpening": "Membuka topik baru…", "placeholderStreaming": "Model sedang merespons…", "inputAria": "Input pesan", "sendHint": "Enter untuk kirim · Shift+Enter untuk baris baru", diff --git a/webui/src/i18n/locales/ja/common.json b/webui/src/i18n/locales/ja/common.json index ed9cd239..901bc9d1 100644 --- a/webui/src/i18n/locales/ja/common.json +++ b/webui/src/i18n/locales/ja/common.json @@ -43,12 +43,12 @@ "sidebar": { "navigation": "サイドバーのナビゲーション", "collapse": "サイドバーを閉じる", - "newChat": "新しいチャット", + "newChat": "新しいトピック", "searchAria": "検索", "searchPlaceholder": "検索", "searchResults": "検索結果", - "noSearchResults": "一致するチャットはありません。", - "recent": "最近のチャット", + "noSearchResults": "一致するトピックはありません。", + "recent": "最近のトピック", "settings": "設定", "language": { "label": "言語", @@ -805,15 +805,15 @@ } }, "chat": { - "fallbackTitle": "チャット {{id}}", + "fallbackTitle": "トピック {{id}}", "forkTitle": "分岐:{{title}}", "loading": "読み込み中…", "noSessions": "まだセッションがありません。", "showMore": "さらに {{count}} 件表示", - "collapsed": "{{count}} 件のチャットを折りたたみ中", + "collapsed": "{{count}} 件のトピックを折りたたみ中", "showLess": "折りたたむ", - "actions": "「{{title}}」のチャット操作", - "newInProject": "「{{project}}」で新しいチャットを開始", + "actions": "「{{title}}」のトピック操作", + "newInProject": "「{{project}}」で新しいトピックを開始", "activity": { "running": "Agent running", "complete": "Agent finished", @@ -822,9 +822,9 @@ "pin": "Pin", "unpin": "Unpin", "rename": "Rename", - "renameTitle": "Rename chat", - "renameDescription": "Choose a local sidebar name for this chat.", - "renamePlaceholder": "Chat name", + "renameTitle": "トピック名を変更", + "renameDescription": "このトピックのサイドバー表示名を選択します。", + "renamePlaceholder": "トピック名", "renameProjectTitle": "Rename project", "renameProjectDescription": "Choose a local sidebar name for this project.", "renameProjectPlaceholder": "Project name", @@ -834,10 +834,10 @@ "showArchived": "Show archived", "hideArchived": "Hide archived", "delete": "削除", - "newChat": "新しいチャット", + "newChat": "新しいトピック", "groups": { "pinned": "Pinned", - "all": "Chats", + "all": "トピック", "projects": "Projects", "today": "Today", "yesterday": "Yesterday", @@ -940,14 +940,14 @@ }, "header": { "toggleSidebar": "サイドバーを切り替える", - "newChat": "新しいチャットを開始", + "newChat": "新しいトピックを開始", "toggleTheme": "ヘッダーからテーマを切り替える", "settings": "設定を開く", "sessionInfo": "セッション詳細" }, "sessionInfo": { "title": "セッション", - "untitled": "無題のチャット", + "untitled": "無題のトピック", "automations": "自動タスク", "count": "{{count}}", "loading": "自動タスクを読み込み中...", @@ -973,7 +973,7 @@ "composer": { "placeholderThread": "メッセージを入力…", "placeholderHero": "何を考えていますか?", - "placeholderOpening": "新しいチャットを開いています…", + "placeholderOpening": "新しいトピックを開いています…", "placeholderStreaming": "モデルが応答しています…", "inputAria": "メッセージ入力欄", "sendHint": "Enter で送信 · Shift+Enter で改行", diff --git a/webui/src/i18n/locales/ko/common.json b/webui/src/i18n/locales/ko/common.json index 44f1f544..dd2ad5de 100644 --- a/webui/src/i18n/locales/ko/common.json +++ b/webui/src/i18n/locales/ko/common.json @@ -43,12 +43,12 @@ "sidebar": { "navigation": "사이드바 탐색", "collapse": "사이드바 접기", - "newChat": "새 채팅", + "newChat": "새 주제", "searchAria": "검색", "searchPlaceholder": "검색", "searchResults": "결과", - "noSearchResults": "일치하는 채팅이 없습니다.", - "recent": "최근 대화", + "noSearchResults": "일치하는 주제가 없습니다.", + "recent": "최근 주제", "settings": "설정", "language": { "label": "언어", @@ -805,15 +805,15 @@ } }, "chat": { - "fallbackTitle": "채팅 {{id}}", + "fallbackTitle": "주제 {{id}}", "forkTitle": "분기: {{title}}", "loading": "불러오는 중…", "noSessions": "아직 세션이 없습니다.", "showMore": "{{count}}개 더 보기", - "collapsed": "{{count}}개 채팅 접힘", + "collapsed": "{{count}}개 주제 접힘", "showLess": "접기", - "actions": "{{title}} 채팅 작업", - "newInProject": "{{project}}에서 새 채팅 시작", + "actions": "{{title}} 주제 작업", + "newInProject": "{{project}}에서 새 주제 시작", "activity": { "running": "Agent running", "complete": "Agent finished", @@ -822,9 +822,9 @@ "pin": "Pin", "unpin": "Unpin", "rename": "Rename", - "renameTitle": "Rename chat", - "renameDescription": "Choose a local sidebar name for this chat.", - "renamePlaceholder": "Chat name", + "renameTitle": "주제 이름 변경", + "renameDescription": "이 주제에 사용할 사이드바 이름을 선택하세요.", + "renamePlaceholder": "주제 이름", "renameProjectTitle": "Rename project", "renameProjectDescription": "Choose a local sidebar name for this project.", "renameProjectPlaceholder": "Project name", @@ -834,10 +834,10 @@ "showArchived": "Show archived", "hideArchived": "Hide archived", "delete": "삭제", - "newChat": "새 채팅", + "newChat": "새 주제", "groups": { "pinned": "Pinned", - "all": "Chats", + "all": "주제", "projects": "Projects", "today": "Today", "yesterday": "Yesterday", @@ -940,14 +940,14 @@ }, "header": { "toggleSidebar": "사이드바 전환", - "newChat": "새 채팅 시작", + "newChat": "새 주제 시작", "toggleTheme": "헤더에서 테마 전환", "settings": "설정 열기", "sessionInfo": "세션 세부 정보" }, "sessionInfo": { "title": "세션", - "untitled": "제목 없는 채팅", + "untitled": "제목 없는 주제", "automations": "자동화", "count": "{{count}}", "loading": "자동화를 불러오는 중...", @@ -973,7 +973,7 @@ "composer": { "placeholderThread": "메시지를 입력하세요…", "placeholderHero": "무슨 생각을 하고 있나요?", - "placeholderOpening": "새 채팅을 여는 중…", + "placeholderOpening": "새 주제를 여는 중…", "placeholderStreaming": "모델이 응답 중입니다…", "inputAria": "메시지 입력", "sendHint": "Enter로 전송 · Shift+Enter로 줄바꿈", diff --git a/webui/src/i18n/locales/pt-BR/common.json b/webui/src/i18n/locales/pt-BR/common.json index 5a33d082..0692324e 100644 --- a/webui/src/i18n/locales/pt-BR/common.json +++ b/webui/src/i18n/locales/pt-BR/common.json @@ -43,12 +43,12 @@ "sidebar": { "navigation": "Navegação da barra lateral", "collapse": "Recolher barra lateral", - "newChat": "Nova conversa", + "newChat": "Novo tópico", "searchAria": "Buscar", "searchPlaceholder": "Buscar", "searchResults": "Resultados", - "noSearchResults": "Nenhuma conversa encontrada.", - "recent": "Recentes", + "noSearchResults": "Nenhum tópico encontrado.", + "recent": "Tópicos recentes", "settings": "Configurações", "language": { "label": "Idioma", @@ -819,15 +819,15 @@ } }, "chat": { - "fallbackTitle": "Conversa {{id}}", + "fallbackTitle": "Tópico {{id}}", "forkTitle": "Fork: {{title}}", "loading": "Carregando…", "noSessions": "Nenhuma sessão ainda.", "showMore": "Mostrar mais {{count}}", - "collapsed": "{{count}} conversas ocultas", + "collapsed": "{{count}} tópicos ocultos", "showLess": "Mostrar menos", - "actions": "Ações da conversa {{title}}", - "newInProject": "Iniciar uma nova conversa em {{project}}", + "actions": "Ações do tópico {{title}}", + "newInProject": "Iniciar um novo tópico em {{project}}", "activity": { "running": "Agente em execução", "complete": "Agente finalizado", @@ -836,9 +836,9 @@ "pin": "Fixar", "unpin": "Desafixar", "rename": "Renomear", - "renameTitle": "Renomear conversa", - "renameDescription": "Escolha um nome local da barra lateral para esta conversa.", - "renamePlaceholder": "Nome da conversa", + "renameTitle": "Renomear tópico", + "renameDescription": "Escolha um nome local da barra lateral para este tópico.", + "renamePlaceholder": "Nome do tópico", "renameProjectTitle": "Renomear projeto", "renameProjectDescription": "Escolha um nome local da barra lateral para este projeto.", "renameProjectPlaceholder": "Nome do projeto", @@ -848,10 +848,10 @@ "showArchived": "Mostrar arquivadas", "hideArchived": "Ocultar arquivadas", "delete": "Excluir", - "newChat": "Nova conversa", + "newChat": "Novo tópico", "groups": { "pinned": "Fixadas", - "all": "Conversas", + "all": "Tópicos", "projects": "Projetos", "today": "Hoje", "yesterday": "Ontem", @@ -954,14 +954,14 @@ }, "header": { "toggleSidebar": "Alternar barra lateral", - "newChat": "Iniciar uma nova conversa", + "newChat": "Iniciar um novo tópico", "toggleTheme": "Alternar tema pelo cabeçalho", "settings": "Abrir configurações", "sessionInfo": "Detalhes da sessão" }, "sessionInfo": { "title": "Sessão", - "untitled": "Conversa sem título", + "untitled": "Tópico sem título", "automations": "Automações", "count": "{{count}}", "loading": "Carregando automações...", @@ -987,7 +987,7 @@ "composer": { "placeholderThread": "Digite sua mensagem…", "placeholderHero": "Pergunte qualquer coisa...", - "placeholderOpening": "Abrindo uma nova conversa…", + "placeholderOpening": "Abrindo um novo tópico…", "placeholderStreaming": "O modelo está respondendo…", "inputAria": "Campo de mensagem", "sendHint": "Enter para enviar · Shift+Enter para nova linha", diff --git a/webui/src/i18n/locales/vi/common.json b/webui/src/i18n/locales/vi/common.json index f62b5b03..4541861d 100644 --- a/webui/src/i18n/locales/vi/common.json +++ b/webui/src/i18n/locales/vi/common.json @@ -43,12 +43,12 @@ "sidebar": { "navigation": "Điều hướng thanh bên", "collapse": "Thu gọn thanh bên", - "newChat": "Cuộc trò chuyện mới", + "newChat": "Chủ đề mới", "searchAria": "Tìm kiếm", "searchPlaceholder": "Tìm kiếm", "searchResults": "Kết quả", - "noSearchResults": "Không có cuộc trò chuyện phù hợp.", - "recent": "Gần đây", + "noSearchResults": "Không có chủ đề phù hợp.", + "recent": "Chủ đề gần đây", "settings": "Cài đặt", "language": { "label": "Ngôn ngữ", @@ -805,15 +805,15 @@ } }, "chat": { - "fallbackTitle": "Trò chuyện {{id}}", + "fallbackTitle": "Chủ đề {{id}}", "forkTitle": "Nhánh: {{title}}", "loading": "Đang tải…", "noSessions": "Chưa có phiên nào.", "showMore": "Hiển thị thêm {{count}}", - "collapsed": "Đã thu gọn {{count}} cuộc trò chuyện", + "collapsed": "Đã thu gọn {{count}} chủ đề", "showLess": "Thu gọn", - "actions": "Tác vụ cho cuộc trò chuyện {{title}}", - "newInProject": "Bắt đầu cuộc trò chuyện mới trong {{project}}", + "actions": "Tác vụ cho chủ đề {{title}}", + "newInProject": "Bắt đầu chủ đề mới trong {{project}}", "activity": { "running": "Agent running", "complete": "Agent finished", @@ -822,9 +822,9 @@ "pin": "Pin", "unpin": "Unpin", "rename": "Rename", - "renameTitle": "Rename chat", - "renameDescription": "Choose a local sidebar name for this chat.", - "renamePlaceholder": "Chat name", + "renameTitle": "Đổi tên chủ đề", + "renameDescription": "Chọn tên hiển thị trong thanh bên cho chủ đề này.", + "renamePlaceholder": "Tên chủ đề", "renameProjectTitle": "Rename project", "renameProjectDescription": "Choose a local sidebar name for this project.", "renameProjectPlaceholder": "Project name", @@ -834,10 +834,10 @@ "showArchived": "Show archived", "hideArchived": "Hide archived", "delete": "Xóa", - "newChat": "Cuộc trò chuyện mới", + "newChat": "Chủ đề mới", "groups": { "pinned": "Pinned", - "all": "Chats", + "all": "Chủ đề", "projects": "Projects", "today": "Today", "yesterday": "Yesterday", @@ -940,14 +940,14 @@ }, "header": { "toggleSidebar": "Bật/tắt thanh bên", - "newChat": "Bắt đầu chat mới", + "newChat": "Bắt đầu chủ đề mới", "toggleTheme": "Chuyển chủ đề từ header", "settings": "Mở cài đặt", "sessionInfo": "Chi tiết phiên" }, "sessionInfo": { "title": "Phiên", - "untitled": "Chat chưa đặt tên", + "untitled": "Chủ đề chưa đặt tên", "automations": "Tự động hóa", "count": "{{count}}", "loading": "Đang tải tự động hóa...", @@ -973,7 +973,7 @@ "composer": { "placeholderThread": "Nhập tin nhắn…", "placeholderHero": "Bạn đang nghĩ gì?", - "placeholderOpening": "Đang mở cuộc trò chuyện mới…", + "placeholderOpening": "Đang mở chủ đề mới…", "placeholderStreaming": "Mô hình đang trả lời…", "inputAria": "Ô nhập tin nhắn", "sendHint": "Enter để gửi · Shift+Enter để xuống dòng", diff --git a/webui/src/i18n/locales/zh-CN/common.json b/webui/src/i18n/locales/zh-CN/common.json index 2d8230d8..1540bbff 100644 --- a/webui/src/i18n/locales/zh-CN/common.json +++ b/webui/src/i18n/locales/zh-CN/common.json @@ -43,12 +43,12 @@ "sidebar": { "navigation": "侧边栏导航", "collapse": "收起侧边栏", - "newChat": "新建对话", + "newChat": "新建话题", "searchAria": "搜索", "searchPlaceholder": "搜索", "searchResults": "搜索结果", - "noSearchResults": "没有匹配的会话。", - "recent": "最近对话", + "noSearchResults": "没有匹配的话题。", + "recent": "最近话题", "settings": "设置", "language": { "label": "语言", @@ -819,15 +819,15 @@ } }, "chat": { - "fallbackTitle": "对话 {{id}}", + "fallbackTitle": "话题 {{id}}", "forkTitle": "分叉:{{title}}", "loading": "加载中…", - "noSessions": "还没有会话。", + "noSessions": "还没有话题。", "showMore": "再显示 {{count}} 个", - "collapsed": "已折叠 {{count}} 个对话", + "collapsed": "已折叠 {{count}} 个话题", "showLess": "收起", - "actions": "“{{title}}” 的会话操作", - "newInProject": "在 {{project}} 中开始新对话", + "actions": "“{{title}}” 的话题操作", + "newInProject": "在 {{project}} 中开始新话题", "activity": { "running": "Agent 正在运行", "complete": "Agent 已完成", @@ -836,9 +836,9 @@ "pin": "置顶", "unpin": "取消置顶", "rename": "重命名", - "renameTitle": "重命名对话", - "renameDescription": "为这个对话设置一个仅用于 WebUI 侧边栏的名称。", - "renamePlaceholder": "对话名称", + "renameTitle": "重命名话题", + "renameDescription": "为这个话题设置一个仅用于 WebUI 侧边栏的名称。", + "renamePlaceholder": "话题名称", "renameProjectTitle": "重命名项目", "renameProjectDescription": "为这个项目设置一个仅用于 WebUI 侧边栏的名称。", "renameProjectPlaceholder": "项目名称", @@ -848,10 +848,10 @@ "showArchived": "显示归档", "hideArchived": "隐藏归档", "delete": "删除", - "newChat": "新建对话", + "newChat": "新建话题", "groups": { "pinned": "置顶", - "all": "对话", + "all": "话题", "projects": "项目", "today": "今天", "yesterday": "昨天", @@ -860,11 +860,11 @@ } }, "deleteConfirm": { - "title": "删除这个对话?", + "title": "删除这个话题?", "description": "此操作无法撤销。", "cancel": "取消", "confirm": "删除", - "automationsDescription": "这个对话有关联的自动任务。删除对话也会删除这些自动任务。", + "automationsDescription": "这个话题有关联的自动任务。删除话题也会删除这些自动任务。", "moreAutomations": "另有 {{count}} 个", "confirmWithAutomations": "删除", "schedule": { @@ -891,7 +891,7 @@ "error": "连接出错" }, "thread": { - "loadingConversation": "正在加载对话…", + "loadingConversation": "正在加载话题…", "empty": { "greetings": { "workOn": "我们要一起做点什么?", @@ -954,14 +954,14 @@ }, "header": { "toggleSidebar": "切换侧边栏", - "newChat": "从顶部新建对话", + "newChat": "从顶部新建话题", "toggleTheme": "从顶部切换主题", "settings": "打开设置", "sessionInfo": "会话详情" }, "sessionInfo": { "title": "会话", - "untitled": "未命名对话", + "untitled": "未命名话题", "automations": "自动任务", "count": "{{count}}", "loading": "正在加载自动任务...", @@ -987,7 +987,7 @@ "composer": { "placeholderThread": "输入消息…", "placeholderHero": "问任何问题...", - "placeholderOpening": "正在打开新对话…", + "placeholderOpening": "正在打开新话题…", "placeholderStreaming": "模型正在回复…", "inputAria": "消息输入框", "sendHint": "Enter 发送 · Shift+Enter 换行", @@ -1065,8 +1065,8 @@ }, "commands": { "new": { - "title": "新建对话", - "description": "重置当前对话,并开始一个新的对话。" + "title": "新建话题", + "description": "重置当前话题,并开始一个新的话题。" }, "stop": { "title": "停止当前任务", diff --git a/webui/src/i18n/locales/zh-TW/common.json b/webui/src/i18n/locales/zh-TW/common.json index fe179885..5dca7477 100644 --- a/webui/src/i18n/locales/zh-TW/common.json +++ b/webui/src/i18n/locales/zh-TW/common.json @@ -43,12 +43,12 @@ "sidebar": { "navigation": "側邊欄導覽", "collapse": "收合側邊欄", - "newChat": "新增對話", + "newChat": "新增話題", "searchAria": "搜尋", "searchPlaceholder": "搜尋", "searchResults": "搜尋結果", - "noSearchResults": "沒有符合的對話。", - "recent": "最近對話", + "noSearchResults": "沒有符合的話題。", + "recent": "最近話題", "settings": "設定", "language": { "label": "語言", @@ -805,15 +805,15 @@ } }, "chat": { - "fallbackTitle": "對話 {{id}}", + "fallbackTitle": "話題 {{id}}", "forkTitle": "分支:{{title}}", "loading": "載入中…", - "noSessions": "目前還沒有對話。", + "noSessions": "目前還沒有話題。", "showMore": "再顯示 {{count}} 個", - "collapsed": "已隱藏 {{count}} 個對話", + "collapsed": "已隱藏 {{count}} 個話題", "showLess": "收起", - "actions": "「{{title}}」的對話操作", - "newInProject": "在 {{project}} 中開始新對話", + "actions": "「{{title}}」的話題操作", + "newInProject": "在 {{project}} 中開始新話題", "activity": { "running": "Agent 正在執行", "complete": "Agent 已完成", @@ -822,9 +822,9 @@ "pin": "置頂", "unpin": "取消置頂", "rename": "重新命名", - "renameTitle": "重新命名對話", - "renameDescription": "為這個對話選擇僅顯示於本機側邊欄的名稱。", - "renamePlaceholder": "對話名稱", + "renameTitle": "重新命名話題", + "renameDescription": "為這個話題選擇僅顯示於本機側邊欄的名稱。", + "renamePlaceholder": "話題名稱", "renameProjectTitle": "重新命名專案", "renameProjectDescription": "為這個專案選擇僅顯示於本機側邊欄的名稱。", "renameProjectPlaceholder": "專案名稱", @@ -834,10 +834,10 @@ "showArchived": "顯示封存", "hideArchived": "隱藏封存", "delete": "刪除", - "newChat": "新增對話", + "newChat": "新增話題", "groups": { "pinned": "置頂", - "all": "對話", + "all": "話題", "projects": "專案", "today": "今天", "yesterday": "昨天", @@ -846,11 +846,11 @@ } }, "deleteConfirm": { - "title": "刪除這個對話?", + "title": "刪除這個話題?", "description": "此操作無法復原。", "cancel": "取消", "confirm": "刪除", - "automationsDescription": "這個對話含有已排程的自動任務。刪除對話時也會一併刪除這些任務。", + "automationsDescription": "這個話題含有已排程的自動任務。刪除話題時也會一併刪除這些任務。", "moreAutomations": "另有 {{count}} 個", "confirmWithAutomations": "刪除", "schedule": { @@ -877,7 +877,7 @@ "error": "連線錯誤" }, "thread": { - "loadingConversation": "正在載入對話…", + "loadingConversation": "正在載入話題…", "empty": { "greetings": { "workOn": "我們要一起做點什麼?", @@ -940,14 +940,14 @@ }, "header": { "toggleSidebar": "切換側邊欄", - "newChat": "開始新對話", + "newChat": "開始新話題", "toggleTheme": "切換佈景主題", "settings": "開啟設定", "sessionInfo": "對話詳細資料" }, "sessionInfo": { "title": "對話", - "untitled": "未命名對話", + "untitled": "未命名話題", "automations": "自動任務", "count": "{{count}}", "loading": "正在載入自動任務…", @@ -973,7 +973,7 @@ "composer": { "placeholderThread": "輸入訊息…", "placeholderHero": "任何問題都可以問…", - "placeholderOpening": "正在開啟新對話…", + "placeholderOpening": "正在開啟新話題…", "placeholderStreaming": "模型正在回覆…", "inputAria": "訊息輸入框", "sendHint": "Enter 送出 · Shift+Enter 換行", @@ -1042,8 +1042,8 @@ "closeHint": "Esc 關閉", "commands": { "new": { - "title": "新增對話", - "description": "重置目前對話,並開始新的對話。" + "title": "新增話題", + "description": "重置目前話題,並開始新的話題。" }, "stop": { "title": "停止目前任務", diff --git a/webui/src/tests/app-layout.test.tsx b/webui/src/tests/app-layout.test.tsx index 54d42bf6..f6a51356 100644 --- a/webui/src/tests/app-layout.test.tsx +++ b/webui/src/tests/app-layout.test.tsx @@ -858,13 +858,13 @@ describe("App layout", () => { ).toBeInTheDocument(), ); - fireEvent.pointerDown(screen.getByLabelText("Chat actions for First chat"), { + fireEvent.pointerDown(screen.getByLabelText("Topic actions for First chat"), { button: 0, }); fireEvent.click(await screen.findByRole("menuitem", { name: "Delete" })); await waitFor(() => - expect(screen.getByText("Delete this chat?")).toBeInTheDocument(), + expect(screen.getByText("Delete this topic?")).toBeInTheDocument(), ); fireEvent.click(screen.getByRole("button", { name: "Delete" })); @@ -876,7 +876,7 @@ describe("App layout", () => { within(sidebar).getByRole("button", { name: /^Second chat$/ }), ).toBeInTheDocument(), ); - expect(screen.queryByText("Delete this chat?")).not.toBeInTheDocument(); + expect(screen.queryByText("Delete this topic?")).not.toBeInTheDocument(); expect(document.body.style.pointerEvents).not.toBe("none"); }, 15_000); @@ -921,7 +921,7 @@ describe("App layout", () => { ).toBeInTheDocument(), ); - fireEvent.pointerDown(screen.getByLabelText(/First chat.*会话操作/), { + fireEvent.pointerDown(screen.getByLabelText(/First chat.*话题操作/), { button: 0, }); fireEvent.click(await screen.findByRole("menuitem", { name: "删除" })); @@ -931,7 +931,7 @@ describe("App layout", () => { ); expect(getSessionAutomationsSpy).toHaveBeenCalledWith("websocket:chat-a"); expect( - screen.getByText("这个对话有关联的自动任务。删除对话也会删除这些自动任务。"), + screen.getByText("这个话题有关联的自动任务。删除话题也会删除这些自动任务。"), ).toBeInTheDocument(); expect( screen.queryByText("This chat has scheduled automations. Deleting it will also delete them."), @@ -989,7 +989,7 @@ describe("App layout", () => { ); fireEvent.pointerDown( - within(mobileSidebar).getByLabelText("Chat actions for Existing chat"), + within(mobileSidebar).getByLabelText("Topic actions for Existing chat"), { button: 0 }, ); @@ -1000,7 +1000,7 @@ describe("App layout", () => { fireEvent.click(deleteItem); await waitFor(() => - expect(screen.getByText("Delete this chat?")).toBeInTheDocument(), + expect(screen.getByText("Delete this topic?")).toBeInTheDocument(), ); }, 15_000); @@ -1143,16 +1143,16 @@ describe("App layout", () => { await waitFor(() => expect(connectSpy).toHaveBeenCalled()); const sidebar = screen.getByRole("navigation", { name: "Sidebar navigation" }); await waitFor(() => - expect(within(sidebar).getByText("Chats")).toBeInTheDocument(), + expect(within(sidebar).getByText("Topics")).toBeInTheDocument(), ); - const group = within(sidebar).getByText("Chats").closest("section"); + const group = within(sidebar).getByText("Topics").closest("section"); expect(group).toBeTruthy(); const labels = within(group as HTMLElement) .getAllByRole("button") .map((button) => button.textContent?.trim()) .filter(Boolean); - expect(labels).toEqual(["Alpha plan", "New chat", "Zulu work"]); + expect(labels).toEqual(["Alpha plan", "New topic", "Zulu work"]); }); it("shows running and completed session indicators in the sidebar", async () => { @@ -1969,7 +1969,7 @@ describe("App layout", () => { await waitFor(() => expect(connectSpy).toHaveBeenCalled()); const sidebar = screen.getByRole("navigation", { name: "Sidebar navigation" }); - fireEvent.click(within(sidebar).getByRole("button", { name: "New chat" })); + fireEvent.click(within(sidebar).getByRole("button", { name: "New topic" })); await waitFor(() => expect(document.title).toBe("nanobot")); fireEvent.click(within(sidebar).getByRole("button", { name: "Settings" })); @@ -2009,7 +2009,7 @@ describe("App layout", () => { const sidebar = screen.getByRole("navigation", { name: "Sidebar navigation" }); expect(within(sidebar).getByText("Q2 roadmap")).toBeInTheDocument(); expect(within(sidebar).getByText("Travel ideas")).toBeInTheDocument(); - const newChatButton = within(sidebar).getByRole("button", { name: "New chat" }); + const newChatButton = within(sidebar).getByRole("button", { name: "New topic" }); const searchButton = within(sidebar).getByRole("button", { name: "Search" }); expect( newChatButton.compareDocumentPosition(searchButton) & @@ -2139,10 +2139,10 @@ describe("App layout", () => { await waitFor(() => expect(connectSpy).toHaveBeenCalled()); const sidebar = screen.getByRole("navigation", { name: "Sidebar navigation" }); - const newChatButton = within(sidebar).getByRole("button", { name: "New chat" }); + const newChatButton = within(sidebar).getByRole("button", { name: "New topic" }); expect(newChatButton).toHaveAttribute( "title", - "New chat (Ctrl+Shift+O)", + "New topic (Ctrl+Shift+O)", ); expect(newChatButton).toHaveAttribute( "aria-keyshortcuts", @@ -2157,9 +2157,9 @@ describe("App layout", () => { await waitFor(() => expect(connectSpy).toHaveBeenCalled()); const sidebar = screen.getByRole("navigation", { name: "Sidebar navigation" }); - expect(within(sidebar).getByRole("button", { name: "New chat" })).toHaveAttribute( + expect(within(sidebar).getByRole("button", { name: "New topic" })).toHaveAttribute( "title", - "New chat (⌘⇧O)", + "New topic (⌘⇧O)", ); }); @@ -2230,9 +2230,9 @@ describe("App layout", () => { const sidebarAside = container.querySelector("aside.lg\\:block") as HTMLElement; await waitFor(() => expect(sidebarAside.style.width).toBe("56px")); - expect(screen.queryByRole("button", { name: "Start a new chat" })).not.toBeInTheDocument(); + expect(screen.queryByRole("button", { name: "Start a new topic" })).not.toBeInTheDocument(); const rail = screen.getByRole("navigation", { name: "Sidebar navigation" }); - expect(within(rail).getByRole("button", { name: "New chat" })).toBeInTheDocument(); + expect(within(rail).getByRole("button", { name: "New topic" })).toBeInTheDocument(); expect(within(rail).getByRole("button", { name: "Search" })).toBeInTheDocument(); expect(within(rail).queryByRole("button", { name: "View" })).not.toBeInTheDocument(); expect(within(rail).queryByText("Existing chat")).not.toBeInTheDocument(); @@ -2241,10 +2241,10 @@ describe("App layout", () => { await waitFor(() => expect(sidebarAside.style.width).toBe("272px")); const sidebar = screen.getByRole("navigation", { name: "Sidebar navigation" }); - fireEvent.click(within(sidebar).getByRole("button", { name: "New chat" })); + fireEvent.click(within(sidebar).getByRole("button", { name: "New topic" })); expect(createChatSpy).not.toHaveBeenCalled(); expect(screen.getByText(HERO_GREETING_PATTERN)).toBeInTheDocument(); - expect(screen.queryByRole("button", { name: "Start a new chat" })).not.toBeInTheDocument(); + expect(screen.queryByRole("button", { name: "Start a new topic" })).not.toBeInTheDocument(); expect(screen.getByRole("button", { name: "Toggle theme from header" })).toBeInTheDocument(); expect(within(sidebar).getByRole("button", { name: "Settings" })).toBeInTheDocument(); diff --git a/webui/src/tests/chat-list.test.tsx b/webui/src/tests/chat-list.test.tsx index 88ed2dc9..50ed9f02 100644 --- a/webui/src/tests/chat-list.test.tsx +++ b/webui/src/tests/chat-list.test.tsx @@ -142,7 +142,7 @@ describe("ChatList", () => { expect(screen.queryByText("Today")).not.toBeInTheDocument(); }); - it("keeps default workspace chats in the Chats section instead of a project folder", () => { + it("keeps default workspace topics in the Topics section instead of a project folder", () => { const sessions = [ session({ chatId: "default", @@ -184,7 +184,7 @@ describe("ChatList", () => { expect(screen.getByRole("region", { name: "nanobot" })).toBeInTheDocument(); expect(screen.queryByRole("region", { name: "workspace" })).not.toBeInTheDocument(); - const chatsSection = screen.getByRole("region", { name: "Chats" }); + const chatsSection = screen.getByRole("region", { name: "Topics" }); expect(within(chatsSection).getByText("Default workspace chat")).toBeInTheDocument(); expect(within(chatsSection).queryByText("Project chat")).not.toBeInTheDocument(); }); @@ -229,13 +229,13 @@ describe("ChatList", () => { expect(within(projectSection).queryByText("Alpha task")).not.toBeInTheDocument(); fireEvent.click( - within(projectSection).getByRole("button", { name: "Start a new chat in Photos" }), + within(projectSection).getByRole("button", { name: "Start a new topic in Photos" }), ); expect(onNewChatInProject).toHaveBeenCalledWith("/Users/me/nanobot", "Photos"); expect(onToggleGroup).toHaveBeenCalledTimes(1); fireEvent.pointerDown( - within(projectSection).getByLabelText("Chat actions for Photos"), + within(projectSection).getByLabelText("Topic actions for Photos"), { button: 0 }, ); fireEvent.click(await screen.findByRole("menuitem", { name: "Rename" })); @@ -300,13 +300,13 @@ describe("ChatList", () => { }; const { rerender } = render(); - const chatsSection = screen.getByRole("region", { name: "Chats" }); + const chatsSection = screen.getByRole("region", { name: "Topics" }); expect(within(chatsSection).getByText("Chat 9")).toBeInTheDocument(); expect(within(chatsSection).getByText("Chat 2")).toBeInTheDocument(); expect(within(chatsSection).queryByText("Chat 1")).not.toBeInTheDocument(); expect(within(chatsSection).queryByRole("button", { name: "Show all" })).not.toBeInTheDocument(); - fireEvent.click(within(chatsSection).getByRole("button", { name: "2 hidden chats" })); + fireEvent.click(within(chatsSection).getByRole("button", { name: "2 hidden topics" })); expect(onToggleGroup).toHaveBeenCalledWith("workspace:chats"); @@ -321,7 +321,7 @@ describe("ChatList", () => { expect(within(chatsSection).getByRole("button", { name: "Show less" })).toBeInTheDocument(); }); - it("sorts Chats section among project groups by recency, not always last", () => { + it("sorts Topics section among project groups by recency, not always last", () => { const sessions = [ session({ chatId: "recent-chat", @@ -367,8 +367,8 @@ describe("ChatList", () => { const regionNames = allRegions.map((r) => r.getAttribute("aria-label") ?? r.textContent); // The most recently updated conversation ("Recent chat" at 12:00) must be - // in the first group — Chats should come before both projects. - const chatsIdx = regionNames.findIndex((n) => n?.includes("Chats")); + // in the first group — Topics should come before both projects. + const chatsIdx = regionNames.findIndex((n) => n?.includes("Topics")); const projAIdx = regionNames.findIndex((n) => n?.includes("project-a")); const projBIdx = regionNames.findIndex((n) => n?.includes("project-b")); @@ -377,7 +377,7 @@ describe("ChatList", () => { expect(within(allRegions[chatsIdx]).getByText("Recent chat")).toBeInTheDocument(); }); - it("keeps one Projects heading when Chats sorts between project groups", () => { + it("keeps one Projects heading when Topics sorts between project groups", () => { const sessions = [ session({ chatId: "project-a", @@ -423,11 +423,11 @@ describe("ChatList", () => { .getAllByRole("region") .map((r) => r.getAttribute("aria-label") ?? ""); - expect(regionNames).toEqual(["project-a", "Chats", "project-b"]); + expect(regionNames).toEqual(["project-a", "Topics", "project-b"]); expect(screen.getAllByText("Projects")).toHaveLength(1); }); - it("keeps Chats last when its latest conversation is older than all projects", () => { + it("keeps Topics last when its latest conversation is older than all projects", () => { const sessions = [ session({ chatId: "project-a", @@ -473,7 +473,7 @@ describe("ChatList", () => { .getAllByRole("region") .map((r) => r.getAttribute("aria-label") ?? ""); - expect(regionNames).toEqual(["project-a", "project-b", "Chats"]); + expect(regionNames).toEqual(["project-a", "project-b", "Topics"]); expect(screen.getAllByText("Projects")).toHaveLength(1); }); }); diff --git a/webui/src/tests/i18n.test.tsx b/webui/src/tests/i18n.test.tsx index 266515c8..c00c5b72 100644 --- a/webui/src/tests/i18n.test.tsx +++ b/webui/src/tests/i18n.test.tsx @@ -445,7 +445,7 @@ describe("webui i18n", () => { const chat = resources["pt-BR"].common.chat; expect(sidebar.settings).toBe("Configurações"); - expect(chat.newChat).toBe("Nova conversa"); + expect(chat.newChat).toBe("Novo tópico"); expect(settings.nav.browser).toBe("Web"); expect(settings.sections.webSearch).toBe("Busca na web"); expect(settings.byok.tabs.webSearch).toBe("Busca na web"); diff --git a/webui/src/tests/useSessions.test.tsx b/webui/src/tests/useSessions.test.tsx index 148bf462..e1f1c6d0 100644 --- a/webui/src/tests/useSessions.test.tsx +++ b/webui/src/tests/useSessions.test.tsx @@ -71,7 +71,7 @@ describe("useSessions", () => { updatedAt: "2026-04-16T10:00:00Z", title: "", preview: "hi", - })).toBe("New chat"); + })).toBe("New topic"); expect(sessionTitle({ key: "websocket:chat-work",