diff --git a/tools/wta/locales/af-ZA.yml b/tools/wta/locales/af-ZA.yml index 2626053534..3dfc95b938 100644 --- a/tools/wta/locales/af-ZA.yml +++ b/tools/wta/locales/af-ZA.yml @@ -219,3 +219,11 @@ model_picker.title: "Kies model (↑ ↓ • Enter • Esc)" # {Locked="↑"," system.no_models: "Die gekoppelde agent het geen kiesbare modelle aangekondig nie." system.model_set: "Model vir hierdie paneel gestel op %{model}." # {Locked="%{model}"} system.model_unknown: "Onbekende model %{model} — tik /model om die beskikbare lys te sien." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/am-ET.yml b/tools/wta/locales/am-ET.yml index 60ee53885c..ef89406a88 100644 --- a/tools/wta/locales/am-ET.yml +++ b/tools/wta/locales/am-ET.yml @@ -219,3 +219,11 @@ model_picker.title: "ሞዴል ይምረጡ (↑ ↓ • Enter • Esc)" # {Loc system.no_models: "የተገናኘው ኤጅንት ምንም ሊመረጥ የሚችል ሞዴል አላስታወቀም።" system.model_set: "የዚህ ፓነል ሞዴል ወደ %{model} ተቀናብሯል።" # {Locked="%{model}"} system.model_unknown: "ያልታወቀ ሞዴል %{model} — የሚገኘውን ዝርዝር ለማየት /model ይተይቡ።" # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/ar-SA.yml b/tools/wta/locales/ar-SA.yml index 7f89241ab3..47c177ac77 100644 --- a/tools/wta/locales/ar-SA.yml +++ b/tools/wta/locales/ar-SA.yml @@ -220,3 +220,11 @@ model_picker.title: "اختر النموذج (↑ ↓ • Enter • Esc)" # {Lo system.no_models: "لم يُعلن عامل الذكاء الاصطناعي المتصل عن أي نماذج قابلة للاختيار." system.model_set: "تم تعيين نموذج هذه اللوحة إلى %{model}." # {Locked="%{model}"} system.model_unknown: "نموذج غير معروف %{model} — اكتب /model لعرض القائمة المتاحة." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/as-IN.yml b/tools/wta/locales/as-IN.yml index 1065a989d2..a385f4127b 100644 --- a/tools/wta/locales/as-IN.yml +++ b/tools/wta/locales/as-IN.yml @@ -221,3 +221,11 @@ model_picker.title: "মডেল বাছনি কৰক (↑ ↓ • Enter system.no_models: "সংযুক্ত এজেণ্টে কোনো বাছনিযোগ্য মডেল ঘোষণা কৰা নাই।" system.model_set: "এই পেনৰ বাবে মডেল %{model} লৈ ছেট কৰা হ'ল।" # {Locked="%{model}"} system.model_unknown: "অজ্ঞাত মডেল %{model} — উপলব্ধ তালিকা চাবলৈ /model টাইপ কৰক।" # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/az-Latn-AZ.yml b/tools/wta/locales/az-Latn-AZ.yml index a59d8b2616..423205734a 100644 --- a/tools/wta/locales/az-Latn-AZ.yml +++ b/tools/wta/locales/az-Latn-AZ.yml @@ -220,3 +220,11 @@ model_picker.title: "Model seçin (↑ ↓ • Enter • Esc)" # {Locked="↑", system.no_models: "Qoşulmuş agent heç bir seçilə bilən model elan etmədi." system.model_set: "Bu panel üçün model %{model} olaraq təyin edildi." # {Locked="%{model}"} system.model_unknown: "Naməlum model %{model} — əlçatan siyahını görmək üçün /model yazın." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/bg-BG.yml b/tools/wta/locales/bg-BG.yml index dae846d3fc..bfa916cb2c 100644 --- a/tools/wta/locales/bg-BG.yml +++ b/tools/wta/locales/bg-BG.yml @@ -220,3 +220,11 @@ model_picker.title: "Изберете модел (↑ ↓ • Enter • Esc)" # system.no_models: "Свързаният агент не обяви никакви избираеми модели." system.model_set: "Моделът за този панел е зададен на %{model}." # {Locked="%{model}"} system.model_unknown: "Неизвестен модел %{model} — въведете /model, за да видите наличния списък." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/bn-IN.yml b/tools/wta/locales/bn-IN.yml index 1aa4477151..4625cdeba3 100644 --- a/tools/wta/locales/bn-IN.yml +++ b/tools/wta/locales/bn-IN.yml @@ -221,3 +221,11 @@ model_picker.title: "মডেল নির্বাচন করুন (↑ ↓ system.no_models: "সংযুক্ত এজেন্ট কোনো নির্বাচনযোগ্য মডেল ঘোষণা করেনি।" system.model_set: "এই পেনের জন্য মডেল %{model}-এ সেট করা হয়েছে।" # {Locked="%{model}"} system.model_unknown: "অজানা মডেল %{model} — উপলব্ধ তালিকা দেখতে /model টাইপ করুন।" # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/bs-Latn-BA.yml b/tools/wta/locales/bs-Latn-BA.yml index 8305492ba7..bf5f0b9a62 100644 --- a/tools/wta/locales/bs-Latn-BA.yml +++ b/tools/wta/locales/bs-Latn-BA.yml @@ -220,3 +220,11 @@ model_picker.title: "Izaberite model (↑ ↓ • Enter • Esc)" # {Locked=" system.no_models: "Povezani agent nije oglasio nijedan model koji se može izabrati." system.model_set: "Model za ovaj panel postavljen je na %{model}." # {Locked="%{model}"} system.model_unknown: "Nepoznat model %{model} — upišite /model da vidite dostupnu listu." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/ca-ES.yml b/tools/wta/locales/ca-ES.yml index 48af684700..bca967cd50 100644 --- a/tools/wta/locales/ca-ES.yml +++ b/tools/wta/locales/ca-ES.yml @@ -220,3 +220,11 @@ model_picker.title: "Seleccioneu el model (↑ ↓ • Enter • Esc)" # {Locke system.no_models: "L’agent connectat no ha anunciat cap model seleccionable." system.model_set: "El model d’aquest tauler s’ha establert a %{model}." # {Locked="%{model}"} system.model_unknown: "Model desconegut %{model} — escriviu /model per veure la llista disponible." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/ca-Es-VALENCIA.yml b/tools/wta/locales/ca-Es-VALENCIA.yml index 39a77f71a3..9a85c5e767 100644 --- a/tools/wta/locales/ca-Es-VALENCIA.yml +++ b/tools/wta/locales/ca-Es-VALENCIA.yml @@ -220,3 +220,11 @@ model_picker.title: "Seleccioneu el model (↑ ↓ • Enter • Esc)" # {Locke system.no_models: "L’agent connectat no ha anunciat cap model seleccionable." system.model_set: "El model d’este panell s’ha establit a %{model}." # {Locked="%{model}"} system.model_unknown: "Model desconegut %{model} — escriviu /model per a vore la llista disponible." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/cs-CZ.yml b/tools/wta/locales/cs-CZ.yml index 24f7998a04..95675c96fd 100644 --- a/tools/wta/locales/cs-CZ.yml +++ b/tools/wta/locales/cs-CZ.yml @@ -220,3 +220,11 @@ model_picker.title: "Vyberte model (↑ ↓ • Enter • Esc)" # {Locked="↑" system.no_models: "Připojený agent neohlásil žádné dostupné modely." system.model_set: "Model pro tento panel nastaven na %{model}." # {Locked="%{model}"} system.model_unknown: "Neznámý model %{model} — zadáním /model zobrazíte dostupný seznam." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/cy-GB.yml b/tools/wta/locales/cy-GB.yml index 0c136ed85a..5cbbd6888d 100644 --- a/tools/wta/locales/cy-GB.yml +++ b/tools/wta/locales/cy-GB.yml @@ -219,3 +219,11 @@ model_picker.title: "Dewiswch model (↑ ↓ • Enter • Esc)" # {Locked="↑ system.no_models: "Ni hysbysebodd yr asiant cysylltiedig unrhyw fodelau dethol." system.model_set: "Gosodwyd y model ar gyfer y paen hwn i %{model}." # {Locked="%{model}"} system.model_unknown: "Model anhysbys %{model} — teipiwch /model i weld y rhestr sydd ar gael." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/da-DK.yml b/tools/wta/locales/da-DK.yml index d6ab5bfeff..b219b6375f 100644 --- a/tools/wta/locales/da-DK.yml +++ b/tools/wta/locales/da-DK.yml @@ -220,3 +220,11 @@ model_picker.title: "Vælg model (↑ ↓ • Enter • Esc)" # {Locked="↑"," system.no_models: "Den tilsluttede agent annoncerede ingen modeller, der kan vælges." system.model_set: "Modellen til denne panel er angivet til %{model}." # {Locked="%{model}"} system.model_unknown: "Ukendt model %{model} — skriv /model for at se den tilgængelige liste." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/de-DE.yml b/tools/wta/locales/de-DE.yml index df0a196634..07f7887382 100644 --- a/tools/wta/locales/de-DE.yml +++ b/tools/wta/locales/de-DE.yml @@ -220,3 +220,11 @@ model_picker.title: "Modell auswählen (↑ ↓ • Enter • Esc)" # {Locked=" system.no_models: "Der verbundene Agent hat keine auswählbaren Modelle angekündigt." system.model_set: "Modell für diesen Bereich auf %{model} festgelegt." # {Locked="%{model}"} system.model_unknown: "Unbekanntes Modell %{model} — geben Sie /model ein, um die verfügbare Liste anzuzeigen." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/el-GR.yml b/tools/wta/locales/el-GR.yml index be0ed106d8..76ae8d6919 100644 --- a/tools/wta/locales/el-GR.yml +++ b/tools/wta/locales/el-GR.yml @@ -219,3 +219,11 @@ model_picker.title: "Επιλέξτε μοντέλο (↑ ↓ • Enter • Esc) system.no_models: "Ο συνδεδεμένος agent δεν δήλωσε κανένα επιλέξιμο μοντέλο." system.model_set: "Το μοντέλο για αυτό το πλαίσιο ορίστηκε σε %{model}." # {Locked="%{model}"} system.model_unknown: "Άγνωστο μοντέλο %{model} — πληκτρολογήστε /model για να δείτε τη διαθέσιμη λίστα." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/en-GB.yml b/tools/wta/locales/en-GB.yml index 32f20abde2..a999b13dbd 100644 --- a/tools/wta/locales/en-GB.yml +++ b/tools/wta/locales/en-GB.yml @@ -218,3 +218,11 @@ model_picker.title: "Select model (↑ ↓ • Enter • Esc)" # {Locked="↑", system.no_models: "The connected agent did not advertise any selectable models." system.model_set: "Model for this pane set to %{model}." # {Locked="%{model}"} system.model_unknown: "Unknown model %{model} — type /model to see the available list." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/en-US.yml b/tools/wta/locales/en-US.yml index 8cacbca37b..e3f036ce16 100644 --- a/tools/wta/locales/en-US.yml +++ b/tools/wta/locales/en-US.yml @@ -102,6 +102,18 @@ commands.restart.summary: "Restart agent" commands.stop.summary: "Cancel the in-flight prompt" commands.sessions.summary: "Open the historical sessions picker (Ctrl+Shift+/)" # {Locked="Ctrl+Shift+/"} commands.model.summary: "Pick the model for this pane (/model to switch directly)" # {Locked="/model",""} +# "agent" = an AI agent persona (Copilot/Claude/custom .agent.md), not a human proxy +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" # {Locked="/agent",""} + +# ── Agent picker (src/ui/agent_popup.rs) ──────────────────────────────────── +# {Locked="↑","↓","Enter","Esc"} - key names, do not translate +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +# {agent} is the selected agent's display name, inserted verbatim. Shown after +# switching this pane to a custom AI agent via /agent. +system.agent_set: "This pane is now using the %{agent} agent." +# {agent} is the unrecognized text the user typed after /agent (an AI agent name). +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." # ── Model picker (src/ui/model_popup.rs) ──────────────────────────────────── # {Locked="↑","↓","Enter","Esc"} - key names, do not translate diff --git a/tools/wta/locales/es-ES.yml b/tools/wta/locales/es-ES.yml index cc29d8dc85..01c483de15 100644 --- a/tools/wta/locales/es-ES.yml +++ b/tools/wta/locales/es-ES.yml @@ -218,3 +218,11 @@ model_picker.title: "Seleccionar modelo (↑ ↓ • Enter • Esc)" # {Locked= system.no_models: "El agente conectado no anunció ningún modelo seleccionable." system.model_set: "El modelo para este panel se ha establecido en %{model}." # {Locked="%{model}"} system.model_unknown: "Modelo desconocido %{model} — escriba /model para ver la lista disponible." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/es-MX.yml b/tools/wta/locales/es-MX.yml index a1d1941df1..dc55d1a13a 100644 --- a/tools/wta/locales/es-MX.yml +++ b/tools/wta/locales/es-MX.yml @@ -218,3 +218,11 @@ model_picker.title: "Seleccionar modelo (↑ ↓ • Enter • Esc)" # {Locked= system.no_models: "El agente conectado no anunció ningún modelo seleccionable." system.model_set: "El modelo para este panel se estableció en %{model}." # {Locked="%{model}"} system.model_unknown: "Modelo desconocido %{model} — escribe /model para ver la lista disponible." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/et-EE.yml b/tools/wta/locales/et-EE.yml index 48993c9281..4b52509e4e 100644 --- a/tools/wta/locales/et-EE.yml +++ b/tools/wta/locales/et-EE.yml @@ -218,3 +218,11 @@ model_picker.title: "Valige mudel (↑ ↓ • Enter • Esc)" # {Locked="↑", system.no_models: "Ühendatud agent ei reklaaminud ühtegi valitavat mudelit." system.model_set: "Selle paani mudeliks määrati %{model}." # {Locked="%{model}"} system.model_unknown: "Tundmatu mudel %{model} — tippige /model saadaolevate mudelite loendi nägemiseks." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/eu-ES.yml b/tools/wta/locales/eu-ES.yml index 1d652a2dc9..43a5491e43 100644 --- a/tools/wta/locales/eu-ES.yml +++ b/tools/wta/locales/eu-ES.yml @@ -218,3 +218,11 @@ model_picker.title: "Hautatu modeloa (↑ ↓ • Enter • Esc)" # {Locked=" system.no_models: "Konektatutako agenteak ez du modelo hautagarririk iragarri." system.model_set: "Panel honetarako modeloa %{model} gisa ezarri da." # {Locked="%{model}"} system.model_unknown: "%{model} modelo ezezaguna — idatzi /model erabilgarri dagoen zerrenda ikusteko." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/fa-IR.yml b/tools/wta/locales/fa-IR.yml index 3841febdf7..18a0150498 100644 --- a/tools/wta/locales/fa-IR.yml +++ b/tools/wta/locales/fa-IR.yml @@ -218,3 +218,11 @@ model_picker.title: "انتخاب مدل (↑ ↓ • Enter • Esc)" # {Locked system.no_models: "عامل هوش مصنوعی متصل هیچ مدل قابل انتخابی را اعلام نکرد." system.model_set: "مدل این پنل روی %{model} تنظیم شد." # {Locked="%{model}"} system.model_unknown: "مدل ناشناخته %{model} — برای دیدن فهرست در دسترس، /model را تایپ کنید." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/fi-FI.yml b/tools/wta/locales/fi-FI.yml index 332db89602..2043a4fe5c 100644 --- a/tools/wta/locales/fi-FI.yml +++ b/tools/wta/locales/fi-FI.yml @@ -218,3 +218,11 @@ model_picker.title: "Valitse malli (↑ ↓ • Enter • Esc)" # {Locked="↑" system.no_models: "Yhdistetty agentti ei ilmoittanut yhtään valittavissa olevaa mallia." system.model_set: "Tämän paneelin malliksi asetettiin %{model}." # {Locked="%{model}"} system.model_unknown: "Tuntematon malli %{model} — kirjoita /model nähdäksesi käytettävissä olevien mallien luettelon." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/fil-PH.yml b/tools/wta/locales/fil-PH.yml index 691ddce9b4..686b9a7488 100644 --- a/tools/wta/locales/fil-PH.yml +++ b/tools/wta/locales/fil-PH.yml @@ -218,3 +218,11 @@ model_picker.title: "Pumili ng modelo (↑ ↓ • Enter • Esc)" # {Locked=" system.no_models: "Hindi nag-advertise ang nakakonektang agent ng anumang napipiling modelo." system.model_set: "Itinakda sa %{model} ang modelo para sa pane na ito." # {Locked="%{model}"} system.model_unknown: "Hindi kilalang modelo %{model} — i-type ang /model para makita ang available na listahan." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/fr-CA.yml b/tools/wta/locales/fr-CA.yml index 173783c3ad..b73a7d262a 100644 --- a/tools/wta/locales/fr-CA.yml +++ b/tools/wta/locales/fr-CA.yml @@ -218,3 +218,11 @@ model_picker.title: "Sélectionner le modèle (↑ ↓ • Enter • Esc)" # {L system.no_models: "L'agent connecté n'a annoncé aucun modèle sélectionnable." system.model_set: "Le modèle pour ce volet est défini sur %{model}." # {Locked="%{model}"} system.model_unknown: "Modèle inconnu %{model} — tapez /model pour afficher la liste disponible." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/fr-FR.yml b/tools/wta/locales/fr-FR.yml index 56687c3984..f3830f75ce 100644 --- a/tools/wta/locales/fr-FR.yml +++ b/tools/wta/locales/fr-FR.yml @@ -218,3 +218,11 @@ model_picker.title: "Sélectionner le modèle (↑ ↓ • Enter • Esc)" # {L system.no_models: "L’agent connecté n’a annoncé aucun modèle sélectionnable." system.model_set: "Modèle de ce volet défini sur %{model}." # {Locked="%{model}"} system.model_unknown: "Modèle inconnu %{model} — tapez /model pour afficher la liste disponible." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/ga-IE.yml b/tools/wta/locales/ga-IE.yml index 5fa6b2d718..554e0bec05 100644 --- a/tools/wta/locales/ga-IE.yml +++ b/tools/wta/locales/ga-IE.yml @@ -217,3 +217,11 @@ model_picker.title: "Roghnaigh samhail (↑ ↓ • Enter • Esc)" # {Locked=" system.no_models: "Níor fhógair an gníomhaire ceangailte aon tsamhail in-roghnaithe." system.model_set: "Samhail an phána seo socraithe go %{model}." # {Locked="%{model}"} system.model_unknown: "Samhail anaithnid %{model} — clóscríobh /model chun an liosta atá ar fáil a fheiceáil." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/gd-gb.yml b/tools/wta/locales/gd-gb.yml index 5e13ed9bbf..ab3a334e4c 100644 --- a/tools/wta/locales/gd-gb.yml +++ b/tools/wta/locales/gd-gb.yml @@ -217,3 +217,11 @@ model_picker.title: "Tagh modail (↑ ↓ • Enter • Esc)" # {Locked="↑"," system.no_models: "Cha do dh'ainmich an t-àidseant ceangailte modail sam bith a ghabhas taghadh." system.model_set: "Chaidh modail a' phana seo a shuidheachadh gu %{model}." # {Locked="%{model}"} system.model_unknown: "Modail neo-aithnichte %{model} — sgrìobh /model gus an liosta a tha ri làimh fhaicinn." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/gl-ES.yml b/tools/wta/locales/gl-ES.yml index eb1daf1154..45ee310398 100644 --- a/tools/wta/locales/gl-ES.yml +++ b/tools/wta/locales/gl-ES.yml @@ -218,3 +218,11 @@ model_picker.title: "Seleccionar modelo (↑ ↓ • Enter • Esc)" # {Locked= system.no_models: "O axente conectado non anunciou ningún modelo seleccionable." system.model_set: "O modelo deste panel estableceuse en %{model}." # {Locked="%{model}"} system.model_unknown: "Modelo descoñecido %{model} — escriba /model para ver a lista dispoñible." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/gu-IN.yml b/tools/wta/locales/gu-IN.yml index 1422540d03..232c27d5d7 100644 --- a/tools/wta/locales/gu-IN.yml +++ b/tools/wta/locales/gu-IN.yml @@ -219,3 +219,11 @@ model_picker.title: "મોડેલ પસંદ કરો (↑ ↓ • Enter system.no_models: "જોડાયેલ એજન્ટે કોઈ પસંદ કરી શકાય તેવા મોડેલ જાહેર કર્યા નથી." system.model_set: "આ પેન માટેનું મોડેલ %{model} પર સેટ કર્યું." # {Locked="%{model}"} system.model_unknown: "અજ્ઞાત મોડેલ %{model} — ઉપલબ્ધ સૂચિ જોવા /model ટાઇપ કરો." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/he-IL.yml b/tools/wta/locales/he-IL.yml index 422e1171ea..5250a0b3b4 100644 --- a/tools/wta/locales/he-IL.yml +++ b/tools/wta/locales/he-IL.yml @@ -218,3 +218,11 @@ model_picker.title: "בחר מודל (↑ ↓ • Enter • Esc)" # {Locked=" system.no_models: "הסוכן המחובר לא פרסם מודלים הניתנים לבחירה." system.model_set: "המודל עבור חלונית זו הוגדר ל-%{model}." # {Locked="%{model}"} system.model_unknown: "מודל לא ידוע %{model} — הקלד /model כדי לראות את הרשימה הזמינה." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/hi-IN.yml b/tools/wta/locales/hi-IN.yml index 8869bfa6b9..8d32e41267 100644 --- a/tools/wta/locales/hi-IN.yml +++ b/tools/wta/locales/hi-IN.yml @@ -219,3 +219,11 @@ model_picker.title: "मॉडल चुनें (↑ ↓ • Enter • Esc)" system.no_models: "कनेक्टेड एजेंट ने कोई चयन योग्य मॉडल घोषित नहीं किया।" system.model_set: "इस पेन के लिए मॉडल %{model} पर सेट किया गया।" # {Locked="%{model}"} system.model_unknown: "अज्ञात मॉडल %{model} — उपलब्ध सूची देखने के लिए /model टाइप करें।" # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/hr-HR.yml b/tools/wta/locales/hr-HR.yml index 8ad98ce70d..dbb2622a0f 100644 --- a/tools/wta/locales/hr-HR.yml +++ b/tools/wta/locales/hr-HR.yml @@ -218,3 +218,11 @@ model_picker.title: "Odaberite model (↑ ↓ • Enter • Esc)" # {Locked=" system.no_models: "Povezani agent nije oglasio nijedan model koji se može odabrati." system.model_set: "Model za ovo okno postavljen je na %{model}." # {Locked="%{model}"} system.model_unknown: "Nepoznat model %{model} — upišite /model za prikaz dostupnog popisa." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/hu-HU.yml b/tools/wta/locales/hu-HU.yml index ac65bc3aac..82ea9b9ba4 100644 --- a/tools/wta/locales/hu-HU.yml +++ b/tools/wta/locales/hu-HU.yml @@ -217,3 +217,11 @@ model_picker.title: "Modell kiválasztása (↑ ↓ • Enter • Esc)" # {Lock system.no_models: "A csatlakoztatott ügynök nem hirdetett meg kiválasztható modelleket." system.model_set: "A panel modellje erre állítva: %{model}." # {Locked="%{model}"} system.model_unknown: "Ismeretlen modell: %{model} — írja be a /model parancsot az elérhető lista megtekintéséhez." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/hy-AM.yml b/tools/wta/locales/hy-AM.yml index 6a04bfc24d..1acb5437fb 100644 --- a/tools/wta/locales/hy-AM.yml +++ b/tools/wta/locales/hy-AM.yml @@ -236,3 +236,11 @@ model_picker.title: "Ընտրեք մոդելը (↑ ↓ • Enter • Esc)" # { system.no_models: "Միացված ագենտը չհայտարարեց ընտրելի մոդելների մասին։" system.model_set: "Այս վահանակի մոդելը սահմանվել է %{model}։" # {Locked="%{model}"} system.model_unknown: "Անհայտ մոդել %{model} — մուտքագրեք /model՝ հասանելի ցանկը տեսնելու համար։" # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/id-ID.yml b/tools/wta/locales/id-ID.yml index cfaff1238f..89f0f3ba2f 100644 --- a/tools/wta/locales/id-ID.yml +++ b/tools/wta/locales/id-ID.yml @@ -218,3 +218,11 @@ model_picker.title: "Pilih model (↑ ↓ • Enter • Esc)" # {Locked="↑"," system.no_models: "Agen yang terhubung tidak mengiklankan model apa pun yang dapat dipilih." system.model_set: "Model untuk panel ini diatur ke %{model}." # {Locked="%{model}"} system.model_unknown: "Model tidak dikenal %{model} — ketik /model untuk melihat daftar yang tersedia." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/is-IS.yml b/tools/wta/locales/is-IS.yml index c4fb2d71a5..ef92b88f0e 100644 --- a/tools/wta/locales/is-IS.yml +++ b/tools/wta/locales/is-IS.yml @@ -218,3 +218,11 @@ model_picker.title: "Veldu líkan (↑ ↓ • Enter • Esc)" # {Locked="↑", system.no_models: "Tengdi agentinn auglýsti engin valanleg líkön." system.model_set: "Líkan fyrir þetta spjald stillt á %{model}." # {Locked="%{model}"} system.model_unknown: "Óþekkt líkan %{model} — sláðu inn /model til að sjá tiltækan lista." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/it-IT.yml b/tools/wta/locales/it-IT.yml index da32a1c638..34ccd1bf00 100644 --- a/tools/wta/locales/it-IT.yml +++ b/tools/wta/locales/it-IT.yml @@ -218,3 +218,11 @@ model_picker.title: "Seleziona modello (↑ ↓ • Enter • Esc)" # {Locked=" system.no_models: "L'agente connesso non ha annunciato alcun modello selezionabile." system.model_set: "Modello per questo riquadro impostato su %{model}." # {Locked="%{model}"} system.model_unknown: "Modello sconosciuto %{model} — digita /model per visualizzare l'elenco disponibile." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/ja-JP.yml b/tools/wta/locales/ja-JP.yml index b72b68b8c6..c521737d08 100644 --- a/tools/wta/locales/ja-JP.yml +++ b/tools/wta/locales/ja-JP.yml @@ -213,3 +213,11 @@ model_picker.title: "モデルを選択 (↑ ↓ • Enter • Esc)" # {Locked= system.no_models: "接続中のエージェントは選択可能なモデルを通知しませんでした。" system.model_set: "このペインのモデルを %{model} に設定しました。" # {Locked="%{model}"} system.model_unknown: "不明なモデル %{model} — 利用可能な一覧を表示するには /model と入力してください。" # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/ka-GE.yml b/tools/wta/locales/ka-GE.yml index ae193bf329..f318aba8bb 100644 --- a/tools/wta/locales/ka-GE.yml +++ b/tools/wta/locales/ka-GE.yml @@ -218,3 +218,11 @@ model_picker.title: "აირჩიეთ მოდელი (↑ ↓ • Enter system.no_models: "დაკავშირებულმა აგენტმა არცერთი ასარჩევი მოდელი არ გამოაცხადა." system.model_set: "ამ პანელის მოდელად დაყენდა %{model}." # {Locked="%{model}"} system.model_unknown: "უცნობი მოდელი %{model} — აკრიფეთ /model ხელმისაწვდომი სიის სანახავად." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/kk-KZ.yml b/tools/wta/locales/kk-KZ.yml index ba3fe02cae..7b5724fb4d 100644 --- a/tools/wta/locales/kk-KZ.yml +++ b/tools/wta/locales/kk-KZ.yml @@ -218,3 +218,11 @@ model_picker.title: "Модельді таңдаңыз (↑ ↓ • Enter • Es system.no_models: "Қосылған агент таңдауға болатын ешбір модельді жарияламады." system.model_set: "Осы панельдің моделі %{model} етіп орнатылды." # {Locked="%{model}"} system.model_unknown: "Белгісіз модель %{model} — қолжетімді тізімді көру үшін /model теріңіз." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/km-KH.yml b/tools/wta/locales/km-KH.yml index e6dfae5feb..b38c90d8ec 100644 --- a/tools/wta/locales/km-KH.yml +++ b/tools/wta/locales/km-KH.yml @@ -236,3 +236,11 @@ model_picker.title: "ជ្រើសរើសម៉ូដែល (↑ ↓ • Ent system.no_models: "AI អេជេន្ត់ដែលបានភ្ជាប់មិនបានប្រកាសម៉ូដែលណាមួយដែលអាចជ្រើសរើសបានទេ។" system.model_set: "ម៉ូដែលសម្រាប់ផ្តាំងនេះត្រូវបានកំណត់ទៅ %{model}។" # {Locked="%{model}"} system.model_unknown: "មិនស្គាល់ម៉ូដែល %{model} — វាយ /model ដើម្បីមើលបញ្ជីដែលមាន។" # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/kn-IN.yml b/tools/wta/locales/kn-IN.yml index e429aae42c..ae4be043e7 100644 --- a/tools/wta/locales/kn-IN.yml +++ b/tools/wta/locales/kn-IN.yml @@ -219,3 +219,11 @@ model_picker.title: "ಮಾದರಿ ಆಯ್ಕೆಮಾಡಿ (↑ ↓ • En system.no_models: "ಸಂಪರ್ಕಿತ ಏಜೆಂಟ್ ಯಾವುದೇ ಆಯ್ಕೆ ಮಾಡಬಹುದಾದ ಮಾದರಿಗಳನ್ನು ಪ್ರಕಟಿಸಲಿಲ್ಲ." system.model_set: "ಈ ಪೇನ್‌ಗಾಗಿ ಮಾದರಿಯನ್ನು %{model} ಗೆ ಹೊಂದಿಸಲಾಗಿದೆ." # {Locked="%{model}"} system.model_unknown: "ಅಪರಿಚಿತ ಮಾದರಿ %{model} — ಲಭ್ಯವಿರುವ ಪಟ್ಟಿಯನ್ನು ನೋಡಲು /model ಟೈಪ್ ಮಾಡಿ." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/ko-KR.yml b/tools/wta/locales/ko-KR.yml index b9f085fd74..4d2db0b2d5 100644 --- a/tools/wta/locales/ko-KR.yml +++ b/tools/wta/locales/ko-KR.yml @@ -213,3 +213,11 @@ model_picker.title: "모델 선택 (↑ ↓ • Enter • Esc)" # {Locked="↑" system.no_models: "연결된 에이전트가 선택 가능한 모델을 알리지 않았습니다." system.model_set: "이 창의 모델이 %{model}(으)로 설정되었습니다." # {Locked="%{model}"} system.model_unknown: "알 수 없는 모델 %{model} — 사용 가능한 목록을 보려면 /model을 입력하세요." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/kok-IN.yml b/tools/wta/locales/kok-IN.yml index 92574260c2..a6f41fcb2e 100644 --- a/tools/wta/locales/kok-IN.yml +++ b/tools/wta/locales/kok-IN.yml @@ -219,3 +219,11 @@ model_picker.title: "मॉडेल निवडात (↑ ↓ • Enter • E system.no_models: "जोडिल्ल्या एजंटान कसलेच निवडपायोग्य मॉडेल जाहीर केलें ना." system.model_set: "ह्या पेना खातीर मॉडेल %{model} चेर सेट केलें." # {Locked="%{model}"} system.model_unknown: "अज्ञात मॉडेल %{model} — उपलब्ध वळेरी पळोवपाक /model टायप करात." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/lb-LU.yml b/tools/wta/locales/lb-LU.yml index 36f6b75a39..2a0eb30689 100644 --- a/tools/wta/locales/lb-LU.yml +++ b/tools/wta/locales/lb-LU.yml @@ -218,3 +218,11 @@ model_picker.title: "Modell auswielen (↑ ↓ • Enter • Esc)" # {Locked=" system.no_models: "Den ugeschlossenen Agent huet keng auswielbar Modeller ugekënnegt." system.model_set: "De Modell fir dës Panell gouf op %{model} gesat." # {Locked="%{model}"} system.model_unknown: "Onbekannte Modell %{model} — tippt /model fir d'verfügbar Lëscht ze gesinn." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/lo-LA.yml b/tools/wta/locales/lo-LA.yml index 82dfe2b755..98377120e2 100644 --- a/tools/wta/locales/lo-LA.yml +++ b/tools/wta/locales/lo-LA.yml @@ -218,3 +218,11 @@ model_picker.title: "ເລືອກແບບຈຳລອງ (↑ ↓ • Enter system.no_models: "agent ທີ່ເຊື່ອມຕໍ່ບໍ່ໄດ້ປະກາດແບບຈຳລອງທີ່ສາມາດເລືອກໄດ້ໃດໆ." system.model_set: "ແບບຈຳລອງສຳລັບ pane ນີ້ຖືກຕັ້ງເປັນ %{model}." # {Locked="%{model}"} system.model_unknown: "ບໍ່ຮູ້ຈັກແບບຈຳລອງ %{model} — ພິມ /model ເພື່ອເບິ່ງລາຍການທີ່ມີ." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/lt-LT.yml b/tools/wta/locales/lt-LT.yml index a58d2d6a8d..419ce807a8 100644 --- a/tools/wta/locales/lt-LT.yml +++ b/tools/wta/locales/lt-LT.yml @@ -218,3 +218,11 @@ model_picker.title: "Pasirinkite modelį (↑ ↓ • Enter • Esc)" # {Locked system.no_models: "Prijungtas agentas nepaskelbė jokių pasirenkamų modelių." system.model_set: "Šios srities modelis nustatytas į %{model}." # {Locked="%{model}"} system.model_unknown: "Nežinomas modelis %{model} — įveskite /model, kad pamatytumėte galimų sąrašą." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/lv-LV.yml b/tools/wta/locales/lv-LV.yml index 3c9da55cbf..38654222a6 100644 --- a/tools/wta/locales/lv-LV.yml +++ b/tools/wta/locales/lv-LV.yml @@ -218,3 +218,11 @@ model_picker.title: "Izvēlieties modeli (↑ ↓ • Enter • Esc)" # {Locked system.no_models: "Pievienotais aģents nepaziņoja nevienu atlasāmu modeli." system.model_set: "Šīs rūts modelis iestatīts uz %{model}." # {Locked="%{model}"} system.model_unknown: "Nezināms modelis %{model} — ierakstiet /model, lai redzētu pieejamo sarakstu." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/mi-NZ.yml b/tools/wta/locales/mi-NZ.yml index a1b4a4675a..c2e1264b4b 100644 --- a/tools/wta/locales/mi-NZ.yml +++ b/tools/wta/locales/mi-NZ.yml @@ -217,3 +217,11 @@ model_picker.title: "Kōwhiria te tauira (↑ ↓ • Enter • Esc)" # {Locked system.no_models: "Kāore te agent kua hono i pānui i tētahi tauira ka taea te kōwhiri." system.model_set: "Kua whakaritea te tauira mō tēnei papa ki %{model}." # {Locked="%{model}"} system.model_unknown: "Tauira kāore e mōhiotia %{model} — patohia /model kia kite i te rārangi e wātea ana." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/mk-MK.yml b/tools/wta/locales/mk-MK.yml index a0b773d6e0..35a4062f6d 100644 --- a/tools/wta/locales/mk-MK.yml +++ b/tools/wta/locales/mk-MK.yml @@ -218,3 +218,11 @@ model_picker.title: "Изберете модел (↑ ↓ • Enter • Esc)" # system.no_models: "Поврзаниот агент не објави ниту еден модел што може да се избере." system.model_set: "Моделот за овој панел е поставен на %{model}." # {Locked="%{model}"} system.model_unknown: "Непознат модел %{model} — внесете /model за да ја видите достапната листа." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/ml-IN.yml b/tools/wta/locales/ml-IN.yml index b5f42c51f5..f78c7dd758 100644 --- a/tools/wta/locales/ml-IN.yml +++ b/tools/wta/locales/ml-IN.yml @@ -219,3 +219,11 @@ model_picker.title: "മോഡൽ തിരഞ്ഞെടുക്കുക ( system.no_models: "കണക്റ്റുചെയ്‌ത agent തിരഞ്ഞെടുക്കാവുന്ന ഒരു മോഡലും പ്രഖ്യാപിച്ചില്ല." system.model_set: "ഈ പേനിനായുള്ള മോഡൽ %{model} ആയി സജ്ജമാക്കി." # {Locked="%{model}"} system.model_unknown: "അറിയാത്ത മോഡൽ %{model} — ലഭ്യമായ പട്ടിക കാണാൻ /model ടൈപ്പ് ചെയ്യുക." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/mr-IN.yml b/tools/wta/locales/mr-IN.yml index 364cbf189b..3a7b65fc8e 100644 --- a/tools/wta/locales/mr-IN.yml +++ b/tools/wta/locales/mr-IN.yml @@ -219,3 +219,11 @@ model_picker.title: "मॉडेल निवडा (↑ ↓ • Enter • Esc) system.no_models: "कनेक्ट केलेल्या agent ने कोणतेही निवडण्यायोग्य मॉडेल जाहीर केले नाही." system.model_set: "या पेनसाठी मॉडेल %{model} वर सेट केले." # {Locked="%{model}"} system.model_unknown: "अज्ञात मॉडेल %{model} — उपलब्ध यादी पाहण्यासाठी /model टाइप करा." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/ms-MY.yml b/tools/wta/locales/ms-MY.yml index 2336accdde..d16ead091b 100644 --- a/tools/wta/locales/ms-MY.yml +++ b/tools/wta/locales/ms-MY.yml @@ -218,3 +218,11 @@ model_picker.title: "Pilih model (↑ ↓ • Enter • Esc)" # {Locked="↑"," system.no_models: "Ejen yang disambungkan tidak mengiklankan sebarang model yang boleh dipilih." system.model_set: "Model untuk anak tetingkap ini ditetapkan kepada %{model}." # {Locked="%{model}"} system.model_unknown: "Model tidak diketahui %{model} — taip /model untuk melihat senarai yang tersedia." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/mt-MT.yml b/tools/wta/locales/mt-MT.yml index 51b9204a42..2a93e132f7 100644 --- a/tools/wta/locales/mt-MT.yml +++ b/tools/wta/locales/mt-MT.yml @@ -217,3 +217,11 @@ model_picker.title: "Agħżel mudell (↑ ↓ • Enter • Esc)" # {Locked=" system.no_models: "L-aġent konness ma rreklama l-ebda mudell li jista' jintgħażel." system.model_set: "Il-mudell għal dan il-pannell ġie ssettjat għal %{model}." # {Locked="%{model}"} system.model_unknown: "Mudell mhux magħruf %{model} — ittajpja /model biex tara l-lista disponibbli." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/nb-NO.yml b/tools/wta/locales/nb-NO.yml index 408b23cb17..c7e7097f1a 100644 --- a/tools/wta/locales/nb-NO.yml +++ b/tools/wta/locales/nb-NO.yml @@ -218,3 +218,11 @@ model_picker.title: "Velg modell (↑ ↓ • Enter • Esc)" # {Locked="↑"," system.no_models: "Den tilkoblede agenten annonserte ingen valgbare modeller." system.model_set: "Modellen for dette panelet er satt til %{model}." # {Locked="%{model}"} system.model_unknown: "Ukjent modell %{model} — skriv /model for å se den tilgjengelige listen." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/ne-NP.yml b/tools/wta/locales/ne-NP.yml index 8ee82fcd28..b1c690f3e8 100644 --- a/tools/wta/locales/ne-NP.yml +++ b/tools/wta/locales/ne-NP.yml @@ -219,3 +219,11 @@ model_picker.title: "मोडेल छान्नुहोस् (↑ ↓ • system.no_models: "जोडिएको agent ले कुनै पनि छान्न मिल्ने मोडेल घोषणा गरेन।" system.model_set: "यो पेनका लागि मोडेल %{model} मा सेट गरियो।" # {Locked="%{model}"} system.model_unknown: "अज्ञात मोडेल %{model} — उपलब्ध सूची हेर्न /model टाइप गर्नुहोस्।" # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/nl-NL.yml b/tools/wta/locales/nl-NL.yml index 7123a50dd3..be9e0f1901 100644 --- a/tools/wta/locales/nl-NL.yml +++ b/tools/wta/locales/nl-NL.yml @@ -218,3 +218,11 @@ model_picker.title: "Model selecteren (↑ ↓ • Enter • Esc)" # {Locked=" system.no_models: "De verbonden agent heeft geen selecteerbare modellen aangekondigd." system.model_set: "Model voor dit deelvenster ingesteld op %{model}." # {Locked="%{model}"} system.model_unknown: "Onbekend model %{model} — typ /model om de beschikbare lijst te zien." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/nn-NO.yml b/tools/wta/locales/nn-NO.yml index 17754001bd..e41b2774ec 100644 --- a/tools/wta/locales/nn-NO.yml +++ b/tools/wta/locales/nn-NO.yml @@ -218,3 +218,11 @@ model_picker.title: "Vel modell (↑ ↓ • Enter • Esc)" # {Locked="↑"," system.no_models: "Den tilkopla agenten annonserte ingen modellar som kan veljast." system.model_set: "Modell for dette panelet sett til %{model}." # {Locked="%{model}"} system.model_unknown: "Ukjend modell %{model} — skriv /model for å sjå lista over tilgjengelege." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/or-IN.yml b/tools/wta/locales/or-IN.yml index 80672dd4cc..14db94ee9f 100644 --- a/tools/wta/locales/or-IN.yml +++ b/tools/wta/locales/or-IN.yml @@ -219,3 +219,11 @@ model_picker.title: "ମଡେଲ ବାଛନ୍ତୁ (↑ ↓ • Enter • E system.no_models: "ସଂଯୁକ୍ତ ଏଜେଣ୍ଟ କୌଣସି ଚୟନଯୋଗ୍ୟ ମଡେଲ ଘୋଷଣା କଲା ନାହିଁ।" system.model_set: "ଏହି ପେନ୍ ପାଇଁ ମଡେଲ %{model} କୁ ସେଟ୍ କରାଗଲା।" # {Locked="%{model}"} system.model_unknown: "ଅଜଣା ମଡେଲ %{model} — ଉପଲବ୍ଧ ତାଲିକା ଦେଖିବାକୁ /model ଟାଇପ୍ କରନ୍ତୁ।" # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/pa-IN.yml b/tools/wta/locales/pa-IN.yml index 21892a0de5..b2d864ccd4 100644 --- a/tools/wta/locales/pa-IN.yml +++ b/tools/wta/locales/pa-IN.yml @@ -219,3 +219,11 @@ model_picker.title: "ਮਾਡਲ ਚੁਣੋ (↑ ↓ • Enter • Esc)" # { system.no_models: "ਜੁੜੇ ਏਜੰਟ ਨੇ ਕੋਈ ਚੁਣਨਯੋਗ ਮਾਡਲ ਦਾ ਐਲਾਨ ਨਹੀਂ ਕੀਤਾ।" system.model_set: "ਇਸ ਪੈਨ ਲਈ ਮਾਡਲ %{model} 'ਤੇ ਸੈੱਟ ਕੀਤਾ ਗਿਆ।" # {Locked="%{model}"} system.model_unknown: "ਅਣਜਾਣ ਮਾਡਲ %{model} — ਉਪਲਬਧ ਸੂਚੀ ਵੇਖਣ ਲਈ /model ਟਾਈਪ ਕਰੋ।" # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/pl-PL.yml b/tools/wta/locales/pl-PL.yml index 3470ac0ab2..f21c897b46 100644 --- a/tools/wta/locales/pl-PL.yml +++ b/tools/wta/locales/pl-PL.yml @@ -218,3 +218,11 @@ model_picker.title: "Wybierz model (↑ ↓ • Enter • Esc)" # {Locked="↑" system.no_models: "Połączony agent nie ogłosił żadnych modeli do wyboru." system.model_set: "Model dla tego panelu ustawiono na %{model}." # {Locked="%{model}"} system.model_unknown: "Nieznany model %{model} — wpisz /model, aby zobaczyć dostępną listę." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/pt-BR.yml b/tools/wta/locales/pt-BR.yml index 00e99281fd..ff23d0a17f 100644 --- a/tools/wta/locales/pt-BR.yml +++ b/tools/wta/locales/pt-BR.yml @@ -218,3 +218,11 @@ model_picker.title: "Selecionar modelo (↑ ↓ • Enter • Esc)" # {Locked=" system.no_models: "O agente conectado não anunciou nenhum modelo selecionável." system.model_set: "Modelo para este painel definido como %{model}." # {Locked="%{model}"} system.model_unknown: "Modelo desconhecido %{model} — digite /model para ver a lista disponível." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/pt-PT.yml b/tools/wta/locales/pt-PT.yml index ceaf15b7e6..b981d07098 100644 --- a/tools/wta/locales/pt-PT.yml +++ b/tools/wta/locales/pt-PT.yml @@ -218,3 +218,11 @@ model_picker.title: "Selecionar modelo (↑ ↓ • Enter • Esc)" # {Locked=" system.no_models: "O agente ligado não anunciou nenhum modelo selecionável." system.model_set: "Modelo para este painel definido como %{model}." # {Locked="%{model}"} system.model_unknown: "Modelo desconhecido %{model} — escreva /model para ver a lista disponível." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/qps-ploc.yml b/tools/wta/locales/qps-ploc.yml index d5f1fde9db..fd954a5dd4 100644 --- a/tools/wta/locales/qps-ploc.yml +++ b/tools/wta/locales/qps-ploc.yml @@ -219,3 +219,11 @@ model_picker.title: "[Ŝéĺéçţ ḿöďéĺ (↑ ↓ • Enter • Esc)!!!! ! system.no_models: "[Ţĥé çöññéçţéď åğéñţ ďïď ñöţ åďṽéŕţïśé åñÿ śéĺéçţåƀĺé ḿöďéĺś.!!!! !!!! !!!! !!!!]" system.model_set: "[Ḿöďéĺ ƒöŕ ţĥïś ṗåñé śéţ ţö %{model}.!!!! !!!! !!!!]" # {Locked="%{model}"} system.model_unknown: "[Ûñķñöŵñ ḿöďéĺ %{model} — ţÿṗé /model ţö śéé ţĥé åṽåïĺåƀĺé ĺïśţ.!!!! !!!! !!!! !!!!]" # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/qps-ploca.yml b/tools/wta/locales/qps-ploca.yml index 3011850a6e..3b1dbdcce2 100644 --- a/tools/wta/locales/qps-ploca.yml +++ b/tools/wta/locales/qps-ploca.yml @@ -216,3 +216,11 @@ model_picker.title: "[!!_Select model (↑ ↓ • Enter • Esc)_!!]" # {Locke system.no_models: "[!!_The connected agent did not advertise any selectable models._!!]" system.model_set: "[!!_Model for this pane set to %{model}._!!]" # {Locked="%{model}"} system.model_unknown: "[!!_Unknown model %{model} — type /model to see the available list._!!]" # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/qps-plocm.yml b/tools/wta/locales/qps-plocm.yml index 971e55e647..da3d855b9b 100644 --- a/tools/wta/locales/qps-plocm.yml +++ b/tools/wta/locales/qps-plocm.yml @@ -216,3 +216,11 @@ model_picker.title: "[!! Sel_ect model (↑ ↓ • Enter • Esc) !!]" # {Lock system.no_models: "[!! The_ connected agent did not advertise any selectable models. !!]" system.model_set: "[!! Mod_el for this pane set to %{model}. !!]" # {Locked="%{model}"} system.model_unknown: "[!! Unk_nown model %{model} — type /model to see the available list. !!]" # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/quz-PE.yml b/tools/wta/locales/quz-PE.yml index 871e14c093..320b7bf706 100644 --- a/tools/wta/locales/quz-PE.yml +++ b/tools/wta/locales/quz-PE.yml @@ -217,3 +217,11 @@ model_picker.title: "Modelo akllay (↑ ↓ • Enter • Esc)" # {Locked="↑" system.no_models: "Tinkisqa agente mana ima akllana modelotapas willarqachu." system.model_set: "Kay k'itipaq modelo %{model} nisqaman churasqa." # {Locked="%{model}"} system.model_unknown: "Mana riqsisqa modelo %{model} — akllana lista rikunaykipaq /model qillqay." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/ro-RO.yml b/tools/wta/locales/ro-RO.yml index 945b1cc535..b3ec61ba77 100644 --- a/tools/wta/locales/ro-RO.yml +++ b/tools/wta/locales/ro-RO.yml @@ -217,3 +217,11 @@ model_picker.title: "Selectați modelul (↑ ↓ • Enter • Esc)" # {Locked= system.no_models: "Agentul conectat nu a anunțat niciun model selectabil." system.model_set: "Modelul pentru acest panou a fost setat la %{model}." # {Locked="%{model}"} system.model_unknown: "Model necunoscut %{model} — tastați /model pentru a vedea lista disponibilă." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/ru-RU.yml b/tools/wta/locales/ru-RU.yml index 77c351e3eb..477da3f03b 100644 --- a/tools/wta/locales/ru-RU.yml +++ b/tools/wta/locales/ru-RU.yml @@ -218,3 +218,11 @@ model_picker.title: "Выбор модели (↑ ↓ • Enter • Esc)" # {Lo system.no_models: "Подключённый агент не объявил ни одной доступной для выбора модели." system.model_set: "Модель для этой панели установлена на %{model}." # {Locked="%{model}"} system.model_unknown: "Неизвестная модель %{model} — введите /model, чтобы увидеть доступный список." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/sk-SK.yml b/tools/wta/locales/sk-SK.yml index 1d04667f72..3fdb15f50f 100644 --- a/tools/wta/locales/sk-SK.yml +++ b/tools/wta/locales/sk-SK.yml @@ -218,3 +218,11 @@ model_picker.title: "Vybrať model (↑ ↓ • Enter • Esc)" # {Locked="↑" system.no_models: "Pripojený agent neohlásil žiadne vybrateľné modely." system.model_set: "Model pre túto tablu je nastavený na %{model}." # {Locked="%{model}"} system.model_unknown: "Neznámy model %{model} — zadaním /model zobrazíte dostupný zoznam." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/sl-SI.yml b/tools/wta/locales/sl-SI.yml index f49098d79d..821e619a20 100644 --- a/tools/wta/locales/sl-SI.yml +++ b/tools/wta/locales/sl-SI.yml @@ -218,3 +218,11 @@ model_picker.title: "Izberi model (↑ ↓ • Enter • Esc)" # {Locked="↑", system.no_models: "Povezani agent ni oglaševal nobenega izbirljivega modela." system.model_set: "Model za to podokno je nastavljen na %{model}." # {Locked="%{model}"} system.model_unknown: "Neznan model %{model} — vnesite /model za prikaz razpoložljivega seznama." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/sq-AL.yml b/tools/wta/locales/sq-AL.yml index fdd1c8f314..c4e244cfa5 100644 --- a/tools/wta/locales/sq-AL.yml +++ b/tools/wta/locales/sq-AL.yml @@ -217,3 +217,11 @@ model_picker.title: "Zgjidhni modelin (↑ ↓ • Enter • Esc)" # {Locked=" system.no_models: "Agjenti i lidhur nuk shpalli asnjë model të zgjedhshëm." system.model_set: "Modeli për këtë panel u caktua në %{model}." # {Locked="%{model}"} system.model_unknown: "Model i panjohur %{model} — shkruani /model për të parë listën e disponueshme." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/sr-Cyrl-BA.yml b/tools/wta/locales/sr-Cyrl-BA.yml index f624f27f21..29d38ce620 100644 --- a/tools/wta/locales/sr-Cyrl-BA.yml +++ b/tools/wta/locales/sr-Cyrl-BA.yml @@ -218,3 +218,11 @@ model_picker.title: "Изаберите модел (↑ ↓ • Enter • Esc)" system.no_models: "Повезани агент није огласио ниједан модел који се може изабрати." system.model_set: "Модел за ово окно је подешен на %{model}." # {Locked="%{model}"} system.model_unknown: "Непознат модел %{model} — унесите /model да видите доступну листу." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/sr-Cyrl-RS.yml b/tools/wta/locales/sr-Cyrl-RS.yml index 02eec9e72b..e42ce20555 100644 --- a/tools/wta/locales/sr-Cyrl-RS.yml +++ b/tools/wta/locales/sr-Cyrl-RS.yml @@ -218,3 +218,11 @@ model_picker.title: "Изаберите модел (↑ ↓ • Enter • Esc)" system.no_models: "Повезани агент није огласио ниједан модел који се може изабрати." system.model_set: "Модел за ово окно је подешен на %{model}." # {Locked="%{model}"} system.model_unknown: "Непознат модел %{model} — унесите /model да видите доступну листу." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/sr-Latn-RS.yml b/tools/wta/locales/sr-Latn-RS.yml index dd022cb462..804d925ebd 100644 --- a/tools/wta/locales/sr-Latn-RS.yml +++ b/tools/wta/locales/sr-Latn-RS.yml @@ -218,3 +218,11 @@ model_picker.title: "Izaberite model (↑ ↓ • Enter • Esc)" # {Locked=" system.no_models: "Povezani agent nije oglasio nijedan model koji se može izabrati." system.model_set: "Model za ovo okno je podešen na %{model}." # {Locked="%{model}"} system.model_unknown: "Nepoznat model %{model} — unesite /model da vidite dostupnu listu." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/sv-SE.yml b/tools/wta/locales/sv-SE.yml index 2e1d669856..e03318d5e9 100644 --- a/tools/wta/locales/sv-SE.yml +++ b/tools/wta/locales/sv-SE.yml @@ -218,3 +218,11 @@ model_picker.title: "Välj modell (↑ ↓ • Enter • Esc)" # {Locked="↑", system.no_models: "Den anslutna agenten annonserade inga valbara modeller." system.model_set: "Modellen för den här panelen är inställd på %{model}." # {Locked="%{model}"} system.model_unknown: "Okänd modell %{model} — skriv /model för att se den tillgängliga listan." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/ta-IN.yml b/tools/wta/locales/ta-IN.yml index 7889593679..9f55b3b4ce 100644 --- a/tools/wta/locales/ta-IN.yml +++ b/tools/wta/locales/ta-IN.yml @@ -219,3 +219,11 @@ model_picker.title: "மாதிரியைத் தேர்ந்தெட system.no_models: "இணைக்கப்பட்ட ஏஜெண்ட் தேர்ந்தெடுக்கக்கூடிய எந்த மாதிரியையும் அறிவிக்கவில்லை." system.model_set: "இந்தப் பலகத்திற்கான மாதிரி %{model} ஆக அமைக்கப்பட்டது." # {Locked="%{model}"} system.model_unknown: "அறியப்படாத மாதிரி %{model} — கிடைக்கும் பட்டியலைக் காண /model எனத் தட்டச்சு செய்யவும்." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/te-IN.yml b/tools/wta/locales/te-IN.yml index a9df7bd1a3..40d02efdda 100644 --- a/tools/wta/locales/te-IN.yml +++ b/tools/wta/locales/te-IN.yml @@ -219,3 +219,11 @@ model_picker.title: "మోడల్‌ను ఎంచుకోండి (↑ system.no_models: "కనెక్ట్ అయిన ఏజెంట్ ఎంచుకోదగిన ఏ మోడల్‌ను కూడా ప్రకటించలేదు." system.model_set: "ఈ పేన్ కోసం మోడల్ %{model} గా సెట్ చేయబడింది." # {Locked="%{model}"} system.model_unknown: "తెలియని మోడల్ %{model} — అందుబాటులో ఉన్న జాబితాను చూడటానికి /model టైప్ చేయండి." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/th-TH.yml b/tools/wta/locales/th-TH.yml index eb12f37155..b38cb7a367 100644 --- a/tools/wta/locales/th-TH.yml +++ b/tools/wta/locales/th-TH.yml @@ -218,3 +218,11 @@ model_picker.title: "เลือกโมเดล (↑ ↓ • Enter • Esc)" system.no_models: "เอเจนต์ที่เชื่อมต่ออยู่ไม่ได้ประกาศโมเดลที่เลือกได้" system.model_set: "ตั้งค่าโมเดลสำหรับแผงนี้เป็น %{model} แล้ว" # {Locked="%{model}"} system.model_unknown: "ไม่รู้จักโมเดล %{model} — พิมพ์ /model เพื่อดูรายการที่มีอยู่" # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/tr-TR.yml b/tools/wta/locales/tr-TR.yml index 8e9cf05850..0354490dd4 100644 --- a/tools/wta/locales/tr-TR.yml +++ b/tools/wta/locales/tr-TR.yml @@ -218,3 +218,11 @@ model_picker.title: "Model seçin (↑ ↓ • Enter • Esc)" # {Locked="↑", system.no_models: "Bağlı aracı seçilebilir hiçbir model duyurmadı." system.model_set: "Bu panel için model %{model} olarak ayarlandı." # {Locked="%{model}"} system.model_unknown: "Bilinmeyen model %{model} — kullanılabilir listeyi görmek için /model yazın." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/tt-RU.yml b/tools/wta/locales/tt-RU.yml index a24cc029c9..d16ecbb864 100644 --- a/tools/wta/locales/tt-RU.yml +++ b/tools/wta/locales/tt-RU.yml @@ -218,3 +218,11 @@ model_picker.title: "Модель сайлагыз (↑ ↓ • Enter • Esc)" system.no_models: "Тоташкан агент бер дә сайлап була торган модель игълан итмәде." system.model_set: "Бу панель өчен модель %{model} итеп билгеләнде." # {Locked="%{model}"} system.model_unknown: "Билгесез модель %{model} — мөмкин булган исемлекне күрү өчен /model языгыз." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/ug-CN.yml b/tools/wta/locales/ug-CN.yml index c2e2611ddc..bb35db5940 100644 --- a/tools/wta/locales/ug-CN.yml +++ b/tools/wta/locales/ug-CN.yml @@ -227,3 +227,11 @@ model_picker.title: "مودېل تاللاڭ (↑ ↓ • Enter • Esc)" # {Lo system.no_models: "ئۇلانغان AI ئاگېنتى تاللىغىلى بولىدىغان ھېچقانداق مودېل ئېلان قىلمىدى." system.model_set: "بۇ تاختا ئۈچۈن مودېل %{model} قىلىپ بەلگىلەندى." # {Locked="%{model}"} system.model_unknown: "نامەلۇم مودېل %{model} — ئىشلەتكىلى بولىدىغان تىزىملىكنى كۆرۈش ئۈچۈن /model نى كىرگۈزۈڭ." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/uk-UA.yml b/tools/wta/locales/uk-UA.yml index c3da567326..f0bb833011 100644 --- a/tools/wta/locales/uk-UA.yml +++ b/tools/wta/locales/uk-UA.yml @@ -218,3 +218,11 @@ model_picker.title: "Виберіть модель (↑ ↓ • Enter • Esc)" system.no_models: "Підключений агент не оголосив жодної моделі, яку можна вибрати." system.model_set: "Модель для цієї панелі встановлено на %{model}." # {Locked="%{model}"} system.model_unknown: "Невідома модель %{model} — введіть /model, щоб переглянути доступний список." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/ur-PK.yml b/tools/wta/locales/ur-PK.yml index 8ccca2be6e..f77902e7f1 100644 --- a/tools/wta/locales/ur-PK.yml +++ b/tools/wta/locales/ur-PK.yml @@ -219,3 +219,11 @@ model_picker.title: "ماڈل منتخب کریں (↑ ↓ • Enter • Esc)" system.no_models: "منسلک ایجنٹ نے کوئی قابلِ انتخاب ماڈل ظاہر نہیں کیا۔" system.model_set: "اس پین کے لیے ماڈل %{model} پر سیٹ کر دیا گیا۔" # {Locked="%{model}"} system.model_unknown: "نامعلوم ماڈل %{model} — دستیاب فہرست دیکھنے کے لیے /model ٹائپ کریں۔" # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/uz-Latn-UZ.yml b/tools/wta/locales/uz-Latn-UZ.yml index 0105abb11b..ecf658d121 100644 --- a/tools/wta/locales/uz-Latn-UZ.yml +++ b/tools/wta/locales/uz-Latn-UZ.yml @@ -218,3 +218,11 @@ model_picker.title: "Modelni tanlang (↑ ↓ • Enter • Esc)" # {Locked=" system.no_models: "Ulangan agent hech qanday tanlanadigan modelni eʼlon qilmadi." system.model_set: "Bu panel uchun model %{model} ga oʻrnatildi." # {Locked="%{model}"} system.model_unknown: "Nomaʼlum model %{model} — mavjud roʻyxatni koʻrish uchun /model yozing." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/vi-VN.yml b/tools/wta/locales/vi-VN.yml index 5ac0adda5a..c3270534a8 100644 --- a/tools/wta/locales/vi-VN.yml +++ b/tools/wta/locales/vi-VN.yml @@ -218,3 +218,11 @@ model_picker.title: "Chọn mô hình (↑ ↓ • Enter • Esc)" # {Locked=" system.no_models: "Tác nhân AI đã kết nối không quảng bá bất kỳ mô hình nào có thể chọn." system.model_set: "Mô hình cho bảng này được đặt thành %{model}." # {Locked="%{model}"} system.model_unknown: "Mô hình không xác định %{model} — nhập /model để xem danh sách khả dụng." # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/zh-CN.yml b/tools/wta/locales/zh-CN.yml index 4018b10637..0e9e7c9aa8 100644 --- a/tools/wta/locales/zh-CN.yml +++ b/tools/wta/locales/zh-CN.yml @@ -213,3 +213,11 @@ model_picker.title: "选择模型(↑ ↓ • Enter • Esc)" # {Locked=" system.no_models: "已连接的智能体未公布任何可选模型。" system.model_set: "此窗格的模型已设置为 %{model}。" # {Locked="%{model}"} system.model_unknown: "未知模型 %{model} — 键入 /model 查看可用列表。" # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/locales/zh-TW.yml b/tools/wta/locales/zh-TW.yml index 02aecbc30d..829cf74c70 100644 --- a/tools/wta/locales/zh-TW.yml +++ b/tools/wta/locales/zh-TW.yml @@ -213,3 +213,11 @@ model_picker.title: "選擇模型(↑ ↓ • Enter • Esc)" # {Locked=" system.no_models: "已連線的智能體未公布任何可選取的模型。" system.model_set: "此窗格的模型已設定為 %{model}。" # {Locked="%{model}"} system.model_unknown: "未知模型 %{model} — 輸入 /model 查看可用清單。" # {Locked="%{model}","/model"} + +# ── /agent custom-agent picker (seeded EN; pending translation) ────────────── +# {Locked="/agent","","↑","↓","Enter","Esc"} +# "agent" = an AI agent persona (e.g. Copilot, Claude, a custom .agent.md), not a human representative +commands.agent.summary: "Pick the custom agent for this pane (/agent to switch directly)" +agent_picker.title: "Select agent (↑ ↓ • Enter • Esc)" +system.agent_set: "This pane is now using the %{agent} agent." +system.agent_unknown: "Unknown agent %{agent} — type /agent to see the available list." diff --git a/tools/wta/src/app.rs b/tools/wta/src/app.rs index cc5cb4b864..cbc8d3afd1 100644 --- a/tools/wta/src/app.rs +++ b/tools/wta/src/app.rs @@ -92,8 +92,8 @@ use crate::coordinator::{ use crate::pane_context::PaneContext; use crate::protocol::acp::client::{ - prompt_timing_log, CancelRequest, DropSessionRequest, LoadSessionForTab, NewSessionForTab, - PromptSubmission, RenameSessionRequest, RestartRequest, + prompt_timing_log, AgentPromptOverride, CancelRequest, DropSessionRequest, LoadSessionForTab, + NewSessionForTab, PromptSubmission, RenameSessionRequest, RestartRequest, }; use crate::ui; use crate::ui_trace; @@ -1491,6 +1491,21 @@ pub struct TabSession { /// advertised `App::available_models`. Clamped on open. pub model_picker_selected: usize, + /// The custom agent selected for this tab via `/agent`. `None` = the + /// built-in default `terminal-agent`. When set to a non-built-in agent, + /// each planner prompt on this tab ships the agent's `.agent.md` body as + /// the system prompt (see `App::active_agent_prompt_override`). + pub active_agent: Option, + /// True while the `/agent` picker modal is up for this tab. Drives both the + /// key-event intercept in `handle_key` and the popup render. + pub agent_picker_open: bool, + /// Highlighted row in the open agent picker — an index into + /// `agent_picker_items`. Clamped on open. + pub agent_picker_selected: usize, + /// Snapshot of discoverable agents taken when the picker opened, so the + /// list stays stable while the user navigates even if files change on disk. + pub agent_picker_items: Vec, + // agent session view (`/sessions`) — per-tab so each WT tab keeps // its own open/closed state and selected row across tab switches. pub current_view: View, @@ -2751,6 +2766,165 @@ impl App { self.publish_agent_status(); } + // ─── `/agent` custom-agent picker ──────────────────────────────────────── + + /// The active tab's custom-agent override for planner prompts, or `None` + /// when the tab is on the built-in default `terminal-agent`. Attached to + /// each user prompt so `build_prompt_text` ships the agent's `.agent.md` + /// body as the system prompt. + fn active_agent_prompt_override(&self) -> Option { + self.current_tab() + .active_agent + .as_ref() + .filter(|a| !a.is_builtin()) + .map(|a| AgentPromptOverride { + display_name: a.display_name.clone(), + body: a.body.clone(), + }) + } + + fn agent_picker_visible(&self) -> bool { + self.current_tab().agent_picker_open + } + + /// `/agent [name]` — switch this tab's custom agent. Bare `/agent` opens the + /// interactive picker; with an argument, match it against the discovered + /// agents (id then display name, case-insensitive) and switch directly. + fn cmd_agent(&mut self, arg: String, in_flight: bool) { + let arg = arg.trim().to_string(); + if arg.is_empty() { + self.open_agent_picker(); + return; + } + let agents = crate::custom_agents::discover_agents_default(); + let matched = crate::custom_agents::find_agent_by_id(&agents, &arg) + .cloned() + .or_else(|| { + agents + .iter() + .find(|a| a.display_name.eq_ignore_ascii_case(&arg)) + .cloned() + }); + match matched { + Some(agent) => self.apply_agent_pick(agent, in_flight), + None => { + let tab = self.current_tab_mut(); + tab.messages.push(ChatMessage::System( + t!("system.agent_unknown", agent = arg.as_str()).into_owned(), + )); + tab.scroll_to_bottom(); + } + } + } + + /// Open the picker on the active tab, snapshotting the discoverable agents + /// and pre-selecting the one the tab is currently on (built-in when none). + fn open_agent_picker(&mut self) { + let agents = crate::custom_agents::discover_agents_default(); + let current_id = self + .current_tab() + .active_agent + .as_ref() + .map(|a| a.id.clone()) + .unwrap_or_else(|| crate::custom_agents::BUILTIN_AGENT_ID.to_string()); + let selected = agents + .iter() + .position(|a| a.id.eq_ignore_ascii_case(¤t_id)) + .unwrap_or(0); + let tab = self.current_tab_mut(); + tab.agent_picker_items = agents; + tab.agent_picker_open = true; + tab.agent_picker_selected = selected; + } + + fn close_agent_picker(&mut self) { + self.current_tab_mut().agent_picker_open = false; + } + + fn agent_picker_up(&mut self) { + let tab = self.current_tab_mut(); + if tab.agent_picker_selected > 0 { + tab.agent_picker_selected -= 1; + } + } + + fn agent_picker_down(&mut self) { + let last = self.current_tab().agent_picker_items.len().saturating_sub(1); + let tab = self.current_tab_mut(); + if tab.agent_picker_selected < last { + tab.agent_picker_selected += 1; + } + } + + /// Commit the highlighted row in the open agent picker. + fn commit_agent_pick(&mut self) { + let agent = { + let tab = self.current_tab(); + tab.agent_picker_items + .get(tab.agent_picker_selected) + .cloned() + }; + self.close_agent_picker(); + if let Some(agent) = agent { + let in_flight = self.current_tab().turn.is_in_flight(); + self.apply_agent_pick(agent, in_flight); + } + } + + /// Switch the active tab to `agent` and start a fresh session bound to it + /// (mirrors `/new`: clean context, the switch takes effect immediately + /// because the agent's body becomes the system prompt on the new session's + /// first turn). Refuses while a turn is in flight — the user should `/stop` + /// first. Selecting the built-in agent reverts to the default prompt. + fn apply_agent_pick(&mut self, agent: crate::custom_agents::CustomAgent, in_flight: bool) { + if in_flight { + let tab = self.current_tab_mut(); + tab.messages.push(ChatMessage::System( + t!("system.busy_use_stop").into_owned(), + )); + tab.scroll_to_bottom(); + return; + } + let tab_id = self + .tab_id + .clone() + .unwrap_or_else(|| DEFAULT_TAB_ID.to_string()); + let display = agent.display_name.clone(); + // Proactively start a fresh session so the new agent is live at once. + let _ = self + .new_session_tx + .send(NewSessionForTab { tab_id, cwd: None }); + let tab = self.current_tab_mut(); + tab.active_agent = if agent.is_builtin() { None } else { Some(agent) }; + tab.clear_chat_history(); + tab.completed_turns.clear(); + tab.selected_completed_turn_idx = None; + tab.session_id = None; + tab.messages.push(ChatMessage::System( + t!("system.agent_set", agent = display.as_str()).into_owned(), + )); + tab.scroll_to_bottom(); + } + + /// Per-frame state for the `/agent` picker modal, or `None` when it's not + /// open on the active tab. + pub fn agent_popup_state(&self) -> Option> { + let tab = self.current_tab(); + if !tab.agent_picker_open { + return None; + } + let current_id = tab + .active_agent + .as_ref() + .map(|a| a.id.as_str()) + .unwrap_or(crate::custom_agents::BUILTIN_AGENT_ID); + Some(crate::ui::AgentPopupState { + agents: &tab.agent_picker_items, + selected: tab.agent_picker_selected, + current_id: Some(current_id), + }) + } + /// Rebuild the shared delegate runtime table from a settings change. /// `delegate_agent` / `delegate_model` are the new effective values /// (empty string = unset → fall back to deriving from the base agent @@ -6810,6 +6984,20 @@ impl App { return; } + // Agent picker modal (`/agent`): same modal key contract as the model + // picker above — arrows move, Enter commits (which starts a fresh + // session bound to the chosen agent), Esc dismisses. + if self.agent_picker_visible() { + match key.code { + KeyCode::Up => self.agent_picker_up(), + KeyCode::Down => self.agent_picker_down(), + KeyCode::Enter => self.commit_agent_pick(), + KeyCode::Esc => self.close_agent_picker(), + _ => {} + } + return; + } + match key.code { KeyCode::Up if self.current_tab().turn.recommendations().is_some() => { @@ -7157,8 +7345,9 @@ impl App { format!("{text}\n{marker}") } }; - let prompt = - PromptSubmission::new(text.clone(), Some(pane_context)).with_images(images); + let prompt = PromptSubmission::new(text.clone(), Some(pane_context)) + .with_agent_override(self.active_agent_prompt_override()) + .with_images(images); prompt_timing_log( prompt.id, prompt.submitted_at_unix_s, @@ -7576,6 +7765,7 @@ impl App { CommandKind::Sessions => self.cmd_sessions(), CommandKind::Restart => self.cmd_restart(), CommandKind::Model => self.cmd_model(cmd.rest), + CommandKind::Agent => self.cmd_agent(cmd.rest, in_flight), } } diff --git a/tools/wta/src/commands.rs b/tools/wta/src/commands.rs index 3176c8cc20..c7993f8396 100644 --- a/tools/wta/src/commands.rs +++ b/tools/wta/src/commands.rs @@ -45,6 +45,14 @@ pub enum CommandKind { /// the life of the pane but is reset by a global `acpModel` settings /// change — see `App::apply_global_acp_model`. Model, + /// Pick the custom agent for *this* agent pane. + /// + /// Bare `/agent` opens an interactive picker listing the custom agents + /// discovered from `.github/agents/` (project) and `~/.github/agents/` + /// (user), plus the built-in default; `/agent ` switches directly. + /// Selecting an agent starts a fresh session bound to that agent's + /// `.agent.md` system prompt — see `App::apply_agent_pick`. + Agent, } #[derive(Debug, Clone, Copy)] @@ -124,6 +132,13 @@ pub const REGISTRY: &[CommandSpec] = &[ kind: CommandKind::Model, takes_args: true, }, + CommandSpec { + name: "agent", + summary_key: "commands.agent.summary", + // `/agent ` switches directly; bare `/agent` opens the picker. + kind: CommandKind::Agent, + takes_args: true, + }, ]; #[derive(Debug, Clone)] @@ -299,6 +314,19 @@ mod tests { assert!(lookup("fix").unwrap().takes_args); } + #[test] + fn agent_parses_with_optional_name() { + // Bare /agent opens the picker (no arg). + let bare = parse("/agent").unwrap(); + assert_eq!(bare.kind, CommandKind::Agent); + assert_eq!(bare.rest, ""); + // /agent : the trailing text is captured verbatim for a direct switch. + let named = parse("/agent devops-helper").unwrap(); + assert_eq!(named.kind, CommandKind::Agent); + assert_eq!(named.rest, "devops-helper"); + assert!(lookup("agent").unwrap().takes_args); + } + #[test] fn rest_is_captured() { let p = parse("/help me please").unwrap(); diff --git a/tools/wta/src/custom_agents.rs b/tools/wta/src/custom_agents.rs new file mode 100644 index 0000000000..1f7b4e9e35 --- /dev/null +++ b/tools/wta/src/custom_agents.rs @@ -0,0 +1,838 @@ +//! Custom agent discovery + parsing (`.agent.md` files). +//! +//! A *custom agent* is a `.agent.md` Markdown file with YAML frontmatter that +//! overrides the built-in `terminal-agent` system prompt for a single agent +//! pane / tab. The file format deliberately mirrors GitHub Copilot's +//! `.agent.md` so definitions are portable across the ecosystem: +//! +//! ```text +//! --- +//! name: devops-helper +//! description: 'Diagnoses failing CI/build commands and proposes fixes.' +//! model: claude-haiku-4.5 +//! --- +//! You are a DevOps specialist focused on build/CI failures... +//! ``` +//! +//! Discovery scopes, highest priority first (later scope wins on id collision): +//! 1. Project: `/.intelligent-terminal/agents/*.md` (walked up) +//! 2. User: `~/.intelligent-terminal/agents/*.md` +//! 3. Built-in `terminal-agent` (always present, lowest priority) +//! +//! The IT-neutral dirs above are backend-agnostic (Intelligent Terminal's own +//! home dotdir, like `~/.claude` / `~/.copilot`). Phase B adds *provider-native* +//! sources selected by the active backend CLI (Copilot `.github/agents`, Claude +//! `.claude/agents`, …) so `/agent` also surfaces the agents you already defined +//! for whatever CLI the pane is running. +//! +//! The list is re-scanned every time the `/agent` picker opens, so adding, +//! editing, or deleting a `.agent.md` file takes effect with no restart — the +//! file on disk is the single source of truth (Copilot-CLI style). There is no +//! registry. +//! +//! This module only *discovers and parses* agents. Applying a selected agent's +//! system prompt (`body`) / `model` to an ACP session is handled elsewhere +//! (`protocol::acp::prompt` + the helper session flow). + +use std::fs; +use std::path::{Path, PathBuf}; + +/// Stable id of the built-in default agent (the embedded `terminal-agent` +/// prompt). Selecting it reverts a tab to the default behavior. +pub const BUILTIN_AGENT_ID: &str = "terminal-agent"; + +/// Where a discovered agent came from. Higher variants win on id collision. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum AgentScope { + /// The embedded default `terminal-agent`. + BuiltIn, + /// `~/.github/agents/`. + User, + /// `/.github/agents/`. + Project, +} + +/// A custom agent definition parsed from a `.agent.md` file (or the built-in). +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CustomAgent { + /// Stable identifier used by `/agent` selection and the helper flag. + /// Derived from frontmatter `name` (trimmed) or, when absent, the file + /// stem with any trailing `.agent` removed. Compared case-insensitively. + pub id: String, + /// Human-friendly name shown in the picker. Frontmatter `name` verbatim, + /// else the id. + pub display_name: String, + /// Frontmatter `description` — the routing/discovery hint shown in the UI. + pub description: String, + /// Frontmatter `model`, applied only when the running CLI supports a model + /// flag. `None` = inherit the session's current model. + pub model: Option, + /// Frontmatter `agent` (a CLI switch such as `claude`/`copilot`). Parsed + /// for forward-compat but IGNORED in the MVP — master stays single-CLI. + pub agent_cli: Option, + /// Frontmatter `tools` restriction. Parsed but not yet enforced. + pub tools: Vec, + /// Markdown body after the frontmatter — used as the ACP system prompt. + /// Empty for the built-in (the default loader supplies its prompt). + pub body: String, + /// Discovery scope this agent came from. + pub scope: AgentScope, + /// Absolute path of the source file (`None` for the built-in). + pub source_path: Option, +} + +impl CustomAgent { + /// True for the built-in default agent. + pub fn is_builtin(&self) -> bool { + self.scope == AgentScope::BuiltIn + } +} + +/// The built-in default agent entry. Its `body` is intentionally empty: when +/// this agent is active, the default embedded `terminal-agent` prompt is used +/// via the existing prompt loader rather than a body carried here. +pub fn builtin_agent() -> CustomAgent { + CustomAgent { + id: BUILTIN_AGENT_ID.to_string(), + display_name: "Terminal Agent".to_string(), + description: "Default Intelligent Terminal assistant.".to_string(), + model: None, + agent_cli: None, + tools: Vec::new(), + body: String::new(), + scope: AgentScope::BuiltIn, + source_path: None, + } +} + +/// A discovery source: a set of home-relative user dirs and repo-relative +/// project dirs (scanned per level while walking up when `walk_up`). Phase A +/// ships only the IT-neutral source; Phase B appends provider-native sources +/// (Copilot `.github/agents`, Claude `.claude/agents`, …) selected by the +/// active backend. +struct AgentSource { + /// Dirs relative to the user's home directory, e.g. + /// `.intelligent-terminal/agents`. + user_rel: &'static [&'static str], + /// Dirs relative to each project level, e.g. `.intelligent-terminal/agents`. + project_rel: &'static [&'static str], + /// When true, `project_rel` is scanned at every directory from the cwd up + /// to (and including) the git root; otherwise only at the cwd. + walk_up: bool, +} + +/// The always-on, backend-agnostic IT source. Branded to Intelligent Terminal +/// (its own home dotdir, like `~/.claude` / `~/.copilot`) — deliberately NOT +/// `.github`, which is Copilot's provider convention (added in Phase B). +fn neutral_sources() -> Vec { + vec![AgentSource { + user_rel: &[".intelligent-terminal/agents"], + project_rel: &[".intelligent-terminal/agents"], + walk_up: true, + }] +} + +/// Discover all custom agents visible from `project_dir` (walked up to the git +/// root for a project agents folder) and `user_home` (the IT-neutral user +/// dir), plus the always-present built-in. +/// +/// Priority (later wins on id collision): **Project > User > BuiltIn**, and the +/// override keeps the earlier display slot. Within the project scope, a level +/// closer to the cwd wins over an ancestor. +/// +/// Both roots are optional so this is unit-testable with temp directories and +/// so a missing `$HOME` / cwd degrades gracefully to fewer agents. +pub fn discover_agents(project_dir: Option<&Path>, user_home: Option<&Path>) -> Vec { + let mut agents = vec![builtin_agent()]; + let sources = neutral_sources(); + + // USER scope first so PROJECT upserts over it. (When Phase B adds provider + // sources, they are appended after neutral within each scope, so + // provider-native wins over IT-neutral at the same scope.) + if let Some(home) = user_home { + for source in &sources { + for rel in source.user_rel { + collect_from_dir(&join_rel(home, rel), AgentScope::User, &mut agents); + } + } + } + + // PROJECT scope: scan each level from the git root down to the cwd, so the + // level closest to the cwd is processed last and wins on collision. + if let Some(cwd) = project_dir { + for source in &sources { + let levels = if source.walk_up { + project_levels(cwd) + } else { + vec![cwd.to_path_buf()] + }; + for level in &levels { + for rel in source.project_rel { + collect_from_dir(&join_rel(level, rel), AgentScope::Project, &mut agents); + } + } + } + } + + agents +} + +/// Join a `/`-separated relative path onto `base`, one segment at a time (so it +/// works regardless of the platform path separator). +fn join_rel(base: &Path, rel: &str) -> PathBuf { + let mut p = base.to_path_buf(); + for seg in rel.split('/').filter(|s| !s.is_empty()) { + p.push(seg); + } + p +} + +/// The project directory levels to scan, ordered **git-root-first, cwd-last**, +/// so callers that upsert (last-wins) let the cwd-closest definition win. +/// +/// The repo root is the nearest ancestor (including `cwd`) that contains a +/// `.git` entry. When no git root is found we scan only the cwd (matching +/// Codex: "if it cannot find a project root, it only checks the current +/// directory") rather than walking to the filesystem root. +fn project_levels(cwd: &Path) -> Vec { + let git_root = cwd.ancestors().find(|a| a.join(".git").exists()); + match git_root { + Some(root) => { + let mut levels: Vec = Vec::new(); + for anc in cwd.ancestors() { + levels.push(anc.to_path_buf()); + if anc == root { + break; + } + } + levels.reverse(); // root-first, cwd-last + levels + } + None => vec![cwd.to_path_buf()], + } +} + +/// Convenience wrapper over [`discover_agents`] using the real current +/// directory and user home directory. +pub fn discover_agents_default() -> Vec { + let cwd = std::env::current_dir().ok(); + let home = user_home_dir(); + discover_agents(cwd.as_deref(), home.as_deref()) +} + +/// Find a discovered agent by id (case-insensitive). +pub fn find_agent_by_id<'a>(agents: &'a [CustomAgent], id: &str) -> Option<&'a CustomAgent> { + agents.iter().find(|a| a.id.eq_ignore_ascii_case(id)) +} + +/// Resolve the user's home directory without pulling in the `dirs`/`home` +/// crates (avoids a new dependency + third-party-notice regeneration). On +/// Windows `USERPROFILE` is authoritative; `HOME` is the cross-platform / test +/// fallback. +fn user_home_dir() -> Option { + std::env::var_os("USERPROFILE") + .filter(|v| !v.is_empty()) + .or_else(|| std::env::var_os("HOME").filter(|v| !v.is_empty())) + .map(PathBuf::from) +} + +/// Scan `dir` for `*.md` agent files and upsert each into `agents`. +/// +/// Files are processed in sorted filename order for deterministic results. +/// Unreadable or unparsable files are skipped silently — a broken agent file +/// must never take down the picker. +fn collect_from_dir(dir: &Path, scope: AgentScope, agents: &mut Vec) { + let mut entries: Vec = match fs::read_dir(dir) { + Ok(read) => read + .flatten() + .map(|e| e.path()) + .filter(|p| is_agent_file(p)) + .collect(), + Err(_) => return, + }; + entries.sort(); + + for path in entries { + let Ok(text) = fs::read_to_string(&path) else { + continue; + }; + if let Some(agent) = parse_agent(&text, &path, scope) { + upsert(agents, agent); + } + } +} + +/// True for files that VS Code / Copilot treat as agent definitions: any `.md` +/// file in the agents directory (including the `*.agent.md` convention). +fn is_agent_file(path: &Path) -> bool { + path.is_file() + && path + .extension() + .and_then(|e| e.to_str()) + .is_some_and(|e| e.eq_ignore_ascii_case("md")) +} + +/// Insert `agent`, or replace an existing same-id entry in place (so a +/// higher-priority scope wins while keeping the earlier display slot). +fn upsert(agents: &mut Vec, agent: CustomAgent) { + if let Some(existing) = agents.iter_mut().find(|a| a.id.eq_ignore_ascii_case(&agent.id)) { + *existing = agent; + } else { + agents.push(agent); + } +} + +/// Parse one `.agent.md` file into a [`CustomAgent`]. Returns `None` only when +/// the file yields no usable id (should not happen — the file stem is always a +/// fallback), so parsing is otherwise infallible and tolerant of missing +/// fields. +fn parse_agent(text: &str, path: &Path, scope: AgentScope) -> Option { + let (frontmatter, body) = split_frontmatter(text); + + let name = frontmatter + .as_ref() + .and_then(|fm| fm.scalar("name")) + .map(str::to_string); + + let id = name + .clone() + .map(|n| n.trim().to_string()) + .filter(|n| !n.is_empty()) + .or_else(|| file_stem_id(path))?; + + let display_name = name + .as_deref() + .map(str::trim) + .filter(|n| !n.is_empty()) + .unwrap_or(&id) + .to_string(); + + let description = frontmatter + .as_ref() + .and_then(|fm| fm.scalar("description")) + .unwrap_or("") + .trim() + .to_string(); + + let model = frontmatter + .as_ref() + .and_then(|fm| fm.scalar("model")) + .map(str::trim) + .filter(|m| !m.is_empty()) + .map(str::to_string); + + let agent_cli = frontmatter + .as_ref() + .and_then(|fm| fm.scalar("agent")) + .map(str::trim) + .filter(|a| !a.is_empty()) + .map(str::to_string); + + let tools = frontmatter + .as_ref() + .map(|fm| fm.list("tools")) + .unwrap_or_default(); + + Some(CustomAgent { + id, + display_name, + description, + model, + agent_cli, + tools, + body: body.trim().to_string(), + scope, + source_path: Some(path.to_path_buf()), + }) +} + +/// Derive an id from a file path: the stem with any trailing `.agent` removed +/// (so `devops-helper.agent.md` → `devops-helper`). +fn file_stem_id(path: &Path) -> Option { + let stem = path.file_stem().and_then(|s| s.to_str())?; + let stem = stem.strip_suffix(".agent").unwrap_or(stem); + let stem = stem.trim(); + (!stem.is_empty()).then(|| stem.to_string()) +} + +// ─── Minimal YAML-frontmatter parser ───────────────────────────────────────── +// +// We deliberately avoid a YAML crate (serde_yaml is unmaintained and any new +// dependency forces a third-party-notice regeneration — see +// `rust-wta.instructions.md`). Agent frontmatter only uses a tiny subset: +// `key: scalar`, single/double-quoted scalars, inline arrays `[a, b]`, and +// block lists (`-` items). This parser covers exactly that and treats anything +// it doesn't understand as absent rather than erroring. + +/// Parsed frontmatter: an ordered set of `key -> value` where a value is either +/// a scalar string or a list of strings. +struct Frontmatter { + entries: Vec<(String, FmValue)>, +} + +enum FmValue { + Scalar(String), + List(Vec), +} + +impl Frontmatter { + fn scalar(&self, key: &str) -> Option<&str> { + self.entries.iter().find_map(|(k, v)| match v { + FmValue::Scalar(s) if k == key => Some(s.as_str()), + _ => None, + }) + } + + fn list(&self, key: &str) -> Vec { + self.entries + .iter() + .find_map(|(k, v)| match v { + FmValue::List(items) if k == key => Some(items.clone()), + FmValue::Scalar(s) if k == key => Some(parse_inline_array(s)), + _ => None, + }) + .unwrap_or_default() + } +} + +/// Split a document into `(frontmatter, body)`. When the text does not begin +/// with a `---` fence, the whole document is the body and there is no +/// frontmatter. +fn split_frontmatter(text: &str) -> (Option, String) { + // Tolerate a UTF-8 BOM and leading blank lines before the opening fence. + let trimmed = text.trim_start_matches('\u{feff}'); + let mut lines = trimmed.lines(); + + // The first non-empty line must be exactly `---` to start frontmatter. + let mut consumed_leading = 0usize; + let first = loop { + match lines.next() { + Some(l) if l.trim().is_empty() => { + consumed_leading += l.len() + 1; + continue; + } + other => break other, + } + }; + if first.map(|l| l.trim()) != Some("---") { + return (None, text.to_string()); + } + + let mut fm_lines: Vec<&str> = Vec::new(); + let mut closed = false; + for line in lines.by_ref() { + if line.trim() == "---" { + closed = true; + break; + } + fm_lines.push(line); + } + if !closed { + // Unterminated frontmatter — treat the whole file as body. + return (None, text.to_string()); + } + + let body: String = lines.collect::>().join("\n"); + let _ = consumed_leading; + (Some(parse_frontmatter_lines(&fm_lines)), body) +} + +fn parse_frontmatter_lines(lines: &[&str]) -> Frontmatter { + let mut entries: Vec<(String, FmValue)> = Vec::new(); + let mut i = 0; + + while i < lines.len() { + let raw = lines[i]; + i += 1; + + let line = strip_comment(raw); + if line.trim().is_empty() { + continue; + } + // Only treat top-level (non-indented) `key:` lines as new keys; block + // list items (` - x`) are consumed by the look-ahead below. + let Some(colon) = line.find(':') else { + continue; + }; + let key = line[..colon].trim(); + if key.is_empty() || key.starts_with('-') { + continue; + } + let value = line[colon + 1..].trim(); + + if value.is_empty() { + // Possible block list on following indented `-` lines. + let mut items = Vec::new(); + while i < lines.len() { + let peek = strip_comment(lines[i]); + let peek_trim = peek.trim(); + if peek_trim.is_empty() { + i += 1; + continue; + } + if let Some(item) = peek_trim.strip_prefix('-') { + items.push(unquote(item.trim())); + i += 1; + } else { + break; + } + } + if items.is_empty() { + entries.push((key.to_string(), FmValue::Scalar(String::new()))); + } else { + entries.push((key.to_string(), FmValue::List(items))); + } + } else if value.starts_with('[') { + entries.push((key.to_string(), FmValue::List(parse_inline_array(value)))); + } else { + entries.push((key.to_string(), FmValue::Scalar(unquote(value)))); + } + } + + Frontmatter { entries } +} + +/// Strip a trailing ` # comment` from a frontmatter line, but not a `#` inside +/// a quoted scalar. Cheap heuristic: only strip when the `#` is preceded by +/// whitespace and is outside quotes. +fn strip_comment(line: &str) -> &str { + let bytes = line.as_bytes(); + let mut in_single = false; + let mut in_double = false; + let mut prev_ws = true; + for (idx, &b) in bytes.iter().enumerate() { + match b { + b'\'' if !in_double => in_single = !in_single, + b'"' if !in_single => in_double = !in_double, + b'#' if !in_single && !in_double && prev_ws => return &line[..idx], + _ => {} + } + prev_ws = b == b' ' || b == b'\t'; + } + line +} + +/// Remove matching surrounding single or double quotes from a scalar. +fn unquote(s: &str) -> String { + let s = s.trim(); + if s.len() >= 2 { + let bytes = s.as_bytes(); + let first = bytes[0]; + let last = bytes[s.len() - 1]; + if (first == b'\'' && last == b'\'') || (first == b'"' && last == b'"') { + return s[1..s.len() - 1].to_string(); + } + } + s.to_string() +} + +/// Parse an inline YAML array like `['read', "edit", search]` into items. +fn parse_inline_array(value: &str) -> Vec { + let value = value.trim(); + let inner = value + .strip_prefix('[') + .and_then(|v| v.strip_suffix(']')) + .unwrap_or(value); + inner + .split(',') + .map(|item| unquote(item.trim())) + .filter(|item| !item.is_empty()) + .collect() +} + +#[cfg(test)] +mod tests { + use super::*; + use std::sync::atomic::{AtomicU32, Ordering}; + + /// A throwaway temp directory that cleans itself up on drop. Avoids adding + /// the `tempfile` crate (dependency + notice regeneration). + struct TempDir { + path: PathBuf, + } + + impl TempDir { + fn new() -> Self { + static COUNTER: AtomicU32 = AtomicU32::new(0); + let n = COUNTER.fetch_add(1, Ordering::Relaxed); + let nanos = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .map(|d| d.as_nanos()) + .unwrap_or(0); + let path = std::env::temp_dir().join(format!( + "wta-ca-test-{}-{}-{}", + std::process::id(), + n, + nanos + )); + fs::create_dir_all(&path).unwrap(); + TempDir { path } + } + + fn write_agent(&self, rel: &str, contents: &str) { + self.write_agent_in(".", rel, contents); + } + + /// Write an agent file under `//.intelligent-terminal/agents/`. + /// `level` is a `/`-separated subpath (use "." for the root). + fn write_agent_in(&self, level: &str, rel: &str, contents: &str) { + let mut dir = self.path.clone(); + if level != "." { + for seg in level.split('/') { + dir.push(seg); + } + } + dir.push(".intelligent-terminal"); + dir.push("agents"); + fs::create_dir_all(&dir).unwrap(); + fs::write(dir.join(rel), contents).unwrap(); + } + + /// Mark a subdirectory (or the root, ".") as a git repo root so + /// `project_levels` walk-up stops there. + fn make_git_root(&self, level: &str) { + let mut dir = self.path.clone(); + if level != "." { + for seg in level.split('/') { + dir.push(seg); + } + } + fs::create_dir_all(dir.join(".git")).unwrap(); + } + + /// Absolute path to a `/`-separated subdirectory of this temp dir. + fn sub(&self, level: &str) -> PathBuf { + let mut dir = self.path.clone(); + for seg in level.split('/') { + dir.push(seg); + } + dir + } + } + + impl Drop for TempDir { + fn drop(&mut self) { + let _ = fs::remove_dir_all(&self.path); + } + } + + #[test] + fn builtin_is_always_present_and_first() { + let agents = discover_agents(None, None); + assert_eq!(agents.len(), 1); + assert!(agents[0].is_builtin()); + assert_eq!(agents[0].id, BUILTIN_AGENT_ID); + } + + #[test] + fn parses_frontmatter_and_body() { + let project = TempDir::new(); + project.write_agent( + "devops-helper.agent.md", + "---\nname: devops-helper\ndescription: 'Fixes failing builds.'\nmodel: claude-haiku-4.5\n---\nYou are a DevOps specialist.\nHelp fix CI failures.\n", + ); + + let agents = discover_agents(Some(&project.path), None); + let agent = find_agent_by_id(&agents, "devops-helper").expect("found"); + assert_eq!(agent.id, "devops-helper"); + assert_eq!(agent.display_name, "devops-helper"); + assert_eq!(agent.description, "Fixes failing builds."); + assert_eq!(agent.model.as_deref(), Some("claude-haiku-4.5")); + assert_eq!(agent.scope, AgentScope::Project); + assert_eq!( + agent.body, + "You are a DevOps specialist.\nHelp fix CI failures." + ); + } + + #[test] + fn id_falls_back_to_file_stem_without_name() { + let project = TempDir::new(); + // No `name` in frontmatter → id derives from stem minus `.agent`. + project.write_agent( + "reviewer.agent.md", + "---\ndescription: 'Reviews code.'\n---\nBe a strict reviewer.\n", + ); + + let agents = discover_agents(Some(&project.path), None); + let agent = find_agent_by_id(&agents, "reviewer").expect("found"); + assert_eq!(agent.id, "reviewer"); + assert_eq!(agent.display_name, "reviewer"); + assert_eq!(agent.description, "Reviews code."); + } + + #[test] + fn project_scope_overrides_user_scope_by_id() { + let user = TempDir::new(); + // Reuse write_agent layout under the "home" temp dir. + let user_dir = user.path.join(".intelligent-terminal").join("agents"); + fs::create_dir_all(&user_dir).unwrap(); + fs::write( + user_dir.join("shared.agent.md"), + "---\nname: shared\ndescription: 'User version.'\n---\nUser body.\n", + ) + .unwrap(); + + let project = TempDir::new(); + project.write_agent( + "shared.agent.md", + "---\nname: shared\ndescription: 'Project version.'\n---\nProject body.\n", + ); + + let agents = discover_agents(Some(&project.path), Some(&user.path)); + let shared = find_agent_by_id(&agents, "shared").expect("found"); + // Project wins on collision. + assert_eq!(shared.description, "Project version."); + assert_eq!(shared.scope, AgentScope::Project); + assert_eq!(shared.body, "Project body."); + // Only one `shared` entry (deduped), plus the built-in. + assert_eq!(agents.iter().filter(|a| a.id == "shared").count(), 1); + } + + #[test] + fn custom_agent_can_override_builtin_and_keeps_first_slot() { + let project = TempDir::new(); + project.write_agent( + "terminal-agent.agent.md", + "---\nname: terminal-agent\ndescription: 'Custom default.'\n---\nCustom default body.\n", + ); + + let agents = discover_agents(Some(&project.path), None); + assert_eq!(agents[0].id, BUILTIN_AGENT_ID); + // Overridden in place: scope + description come from the file now. + assert_eq!(agents[0].scope, AgentScope::Project); + assert_eq!(agents[0].description, "Custom default."); + } + + #[test] + fn parses_inline_and_block_tool_lists() { + let project = TempDir::new(); + project.write_agent( + "inline.agent.md", + "---\nname: inline\ntools: ['read', \"edit\", search]\n---\nbody\n", + ); + project.write_agent( + "block.agent.md", + "---\nname: block\ntools:\n - read\n - edit\n---\nbody\n", + ); + + let agents = discover_agents(Some(&project.path), None); + let inline = find_agent_by_id(&agents, "inline").unwrap(); + assert_eq!(inline.tools, vec!["read", "edit", "search"]); + let block = find_agent_by_id(&agents, "block").unwrap(); + assert_eq!(block.tools, vec!["read", "edit"]); + } + + #[test] + fn agent_frontmatter_field_is_parsed_but_marked_for_the_caller() { + let project = TempDir::new(); + project.write_agent( + "switcher.agent.md", + "---\nname: switcher\nagent: claude\ndescription: 'x'\n---\nbody\n", + ); + let agents = discover_agents(Some(&project.path), None); + let a = find_agent_by_id(&agents, "switcher").unwrap(); + assert_eq!(a.agent_cli.as_deref(), Some("claude")); + } + + #[test] + fn file_without_frontmatter_uses_stem_and_whole_body() { + let project = TempDir::new(); + project.write_agent("plain.md", "Just a system prompt with no frontmatter.\n"); + let agents = discover_agents(Some(&project.path), None); + let a = find_agent_by_id(&agents, "plain").expect("found"); + assert_eq!(a.description, ""); + assert_eq!(a.body, "Just a system prompt with no frontmatter."); + } + + #[test] + fn unterminated_frontmatter_is_treated_as_body() { + let project = TempDir::new(); + project.write_agent("broken.md", "---\nname: broken\nno closing fence\n"); + let agents = discover_agents(Some(&project.path), None); + let a = find_agent_by_id(&agents, "broken").expect("found"); + // The unterminated block is not parsed as frontmatter. + assert_eq!(a.id, "broken"); // from file stem + assert!(a.body.contains("no closing fence")); + } + + #[test] + fn strips_trailing_comment_but_not_inside_quotes() { + assert_eq!(strip_comment("name: foo # a comment").trim(), "name: foo"); + assert_eq!( + strip_comment("description: 'has # inside'").trim(), + "description: 'has # inside'" + ); + } + + #[test] + fn discovery_is_deterministic_and_sorted() { + let project = TempDir::new(); + project.write_agent("zeta.agent.md", "---\nname: zeta\n---\nz\n"); + project.write_agent("alpha.agent.md", "---\nname: alpha\n---\na\n"); + + let ids: Vec = discover_agents(Some(&project.path), None) + .into_iter() + .map(|a| a.id) + .collect(); + // built-in first, then sorted-by-filename order (alpha before zeta). + assert_eq!(ids, vec!["terminal-agent", "alpha", "zeta"]); + } + + #[test] + fn walks_up_to_git_root_finds_ancestor_agent() { + let repo = TempDir::new(); + repo.make_git_root("."); + // Agent defined at the repo root's neutral dir… + repo.write_agent_in(".", "root-agent.agent.md", "---\nname: root-agent\n---\nr\n"); + // …discovered even when the cwd is a nested subdirectory. + let cwd = repo.sub("a/b/c"); + fs::create_dir_all(&cwd).unwrap(); + + let agents = discover_agents(Some(&cwd), None); + assert!( + find_agent_by_id(&agents, "root-agent").is_some(), + "walk-up must find an agent defined at the git root from a nested cwd" + ); + } + + #[test] + fn cwd_level_wins_over_ancestor_on_collision() { + let repo = TempDir::new(); + repo.make_git_root("."); + repo.write_agent_in( + ".", + "dup.agent.md", + "---\nname: dup\ndescription: 'Root version.'\n---\nroot\n", + ); + repo.write_agent_in( + "a/b", + "dup.agent.md", + "---\nname: dup\ndescription: 'Nested version.'\n---\nnested\n", + ); + let cwd = repo.sub("a/b"); + + let agents = discover_agents(Some(&cwd), None); + let dup = find_agent_by_id(&agents, "dup").expect("found"); + assert_eq!( + dup.description, "Nested version.", + "the level closest to the cwd must win over an ancestor" + ); + assert_eq!(agents.iter().filter(|a| a.id == "dup").count(), 1); + } + + #[test] + fn no_git_root_scans_only_cwd_not_ancestors() { + // No `.git` anywhere under the temp root → ancestors are NOT scanned. + let root = TempDir::new(); + root.write_agent_in(".", "ancestor.agent.md", "---\nname: ancestor\n---\na\n"); + let cwd = root.sub("x/y"); + fs::create_dir_all(&cwd).unwrap(); + + let agents = discover_agents(Some(&cwd), None); + assert!( + find_agent_by_id(&agents, "ancestor").is_none(), + "without a git root, discovery must scan only the cwd, not ancestors" + ); + } +} diff --git a/tools/wta/src/main.rs b/tools/wta/src/main.rs index b728ba35ee..0f30fbbb69 100644 --- a/tools/wta/src/main.rs +++ b/tools/wta/src/main.rs @@ -11,6 +11,7 @@ mod clipboard_image; mod command_recall; mod commands; mod coordinator; +mod custom_agents; mod cwd_util; mod event; mod helper; diff --git a/tools/wta/src/protocol/acp/client.rs b/tools/wta/src/protocol/acp/client.rs index 9f3d49b094..e30a04840d 100644 --- a/tools/wta/src/protocol/acp/client.rs +++ b/tools/wta/src/protocol/acp/client.rs @@ -79,12 +79,31 @@ impl TemplateMemo { } } +/// A custom-agent system-prompt override carried with a planner prompt. +/// +/// When a tab has a non-built-in custom agent selected (via `/agent`), each +/// user prompt on that tab carries the agent's `.agent.md` body here so +/// [`build_prompt_text`] uses it as the planner template instead of the +/// default `terminal-agent` prompt. `None`/absent = the built-in default. +#[derive(Debug, Clone)] +pub struct AgentPromptOverride { + /// The agent's display name (for prompt-source telemetry / the loaded-name + /// event), mirroring `PlannerPromptTemplate::display_name`. + pub display_name: String, + /// The agent's system-prompt body (the `.agent.md` markdown after the + /// frontmatter), used verbatim as the planner template. + pub body: String, +} + #[derive(Debug, Clone)] pub struct PromptSubmission { pub id: u64, pub text: String, pub pane_context: Option, pub submitted_at_unix_s: f64, + /// Custom-agent override for this prompt's planner template (`/agent` + /// selection). `None` for autofix prompts and for the built-in agent. + pub agent_override: Option, /// True when this prompt was synthesized by the auto-fix flow rather /// than typed by a human. The host uses this to skip broadcasting it /// as a User message (the client already shows the error line), and @@ -235,10 +254,19 @@ impl PromptSubmission { pane_context, submitted_at_unix_s: now_unix_s(), is_autofix, + agent_override: None, images: Vec::new(), } } + /// Attach a custom-agent system-prompt override (from a `/agent` + /// selection) to a human-entered planner prompt. No-op semantics for the + /// built-in agent — callers pass `None` there. + pub fn with_agent_override(mut self, agent_override: Option) -> Self { + self.agent_override = agent_override; + self + } + /// Attach pasted images (Alt+V) to a human-entered prompt. pub fn with_images(mut self, images: Vec) -> Self { self.images = images; @@ -1160,6 +1188,7 @@ async fn build_prompt_text( shell_mgr: &ShellManager, wt_connected: bool, pane_context: Option<&PaneContext>, + agent_override: Option<&AgentPromptOverride>, ) -> (String, String, String, Option) { let total_started = std::time::Instant::now(); let mut runtime_sections = Vec::new(); @@ -1172,6 +1201,10 @@ async fn build_prompt_text( let template_started = std::time::Instant::now(); let planner_template = if is_autofix { prompt::load_autofix_prompt_template() + } else if let Some(agent) = agent_override { + // A custom agent is selected on this tab: use its `.agent.md` body as + // the planner template instead of the default `terminal-agent` prompt. + prompt::planner_template_from_agent_override(&agent.display_name, &agent.body) } else { prompt::load_planner_prompt_template() }; @@ -3522,6 +3555,7 @@ async fn dispatch_prompt_body( &shell_mgr_task, wt_connected, prompt.pane_context.as_ref(), + prompt.agent_override.as_ref(), ) .await; // A manual `/fix` resolved its working pane in build_prompt_text (it had no @@ -4167,7 +4201,7 @@ mod tests { let mgr = crate::shell::ShellManager::new(); let expected = super::prompt::load_planner_prompt_template(); let (prompt, _source, display_name, fix_pane) = - super::build_prompt_text(1, 0.0, "list files", false, true, &mgr, false, None).await; + super::build_prompt_text(1, 0.0, "list files", false, true, &mgr, false, None, None).await; assert_eq!(display_name, expected.display_name); assert!( prompt.contains("### Supported Delegate Agents"), @@ -4180,15 +4214,41 @@ mod tests { assert!(fix_pane.is_none(), "planner turns never resolve a fix pane"); } - /// An autofix turn loads the *autofix* persona (not the planner), appends a - /// non-empty hint as a User Request, and omits planner-only sections. + /// A planner turn with a custom-agent override ships the agent's `.agent.md` + /// body as the template instead of the default `terminal-agent` prompt, and + /// still appends the user request. + #[tokio::test] + async fn build_prompt_text_planner_uses_agent_override_body() { + let mgr = crate::shell::ShellManager::new(); + let default_tpl = super::prompt::load_planner_prompt_template(); + let over = super::AgentPromptOverride { + display_name: "DevOps Helper".to_string(), + body: "You are a DevOps specialist. Fix CI failures.".to_string(), + }; + let (prompt, _source, display_name, _fix) = + super::build_prompt_text(8, 0.0, "why is my build red", false, true, &mgr, false, None, Some(&over)) + .await; + assert_eq!(display_name, "DevOps Helper"); + assert_ne!( + display_name, default_tpl.display_name, + "override must not reuse the default planner persona name" + ); + assert!( + prompt.contains("You are a DevOps specialist."), + "override body must be shipped as the template" + ); + assert!( + prompt.contains("## User Request\nwhy is my build red"), + "override turns still append the user text" + ); + } #[tokio::test] async fn build_prompt_text_autofix_appends_hint_and_omits_planner_sections() { let mgr = crate::shell::ShellManager::new(); let planner = super::prompt::load_planner_prompt_template(); let autofix = super::prompt::load_autofix_prompt_template(); let (prompt, _s, display_name, fix_pane) = - super::build_prompt_text(2, 0.0, "fix the build", true, true, &mgr, false, None).await; + super::build_prompt_text(2, 0.0, "fix the build", true, true, &mgr, false, None, None).await; assert_eq!(display_name, autofix.display_name); assert_ne!( display_name, planner.display_name, @@ -4211,7 +4271,7 @@ mod tests { async fn build_prompt_text_autofix_blank_hint_has_no_user_request() { let mgr = crate::shell::ShellManager::new(); let (prompt, _s, _d, _f) = - super::build_prompt_text(3, 0.0, " ", true, true, &mgr, false, None).await; + super::build_prompt_text(3, 0.0, " ", true, true, &mgr, false, None, None).await; assert!( !prompt.contains("## User Request"), "blank autofix hint must not add a User Request section" @@ -4230,7 +4290,7 @@ mod tests { "test precondition: planner template body is non-empty" ); let (prompt, _s, _d, _f) = - super::build_prompt_text(4, 0.0, "hi", false, false, &mgr, false, None).await; + super::build_prompt_text(4, 0.0, "hi", false, false, &mgr, false, None, None).await; assert!( !prompt.contains(planner.content.trim()), "include_template=false must omit the template body" @@ -4251,7 +4311,7 @@ mod tests { "is_agent_pane": false, })); let (prompt, _s, _d, fix_pane) = - super::build_prompt_text(5, 0.0, "", true, true, &mgr, true, None).await; + super::build_prompt_text(5, 0.0, "", true, true, &mgr, true, None, None).await; assert_eq!( fix_pane.as_deref(), Some("work-pane"), @@ -4278,7 +4338,7 @@ mod tests { ..Default::default() }; let (_p, _s, _d, fix_pane) = - super::build_prompt_text(6, 0.0, "", true, true, &mgr, true, Some(&ctx)).await; + super::build_prompt_text(6, 0.0, "", true, true, &mgr, true, Some(&ctx), None).await; assert!( fix_pane.is_none(), "error-triggered autofix carries its source; resolved_fix_pane stays None" @@ -4318,7 +4378,7 @@ mod tests { ..Default::default() }; let (prompt, _s, _d, _f) = - super::build_prompt_text(7, 0.0, "", true, true, &mgr, true, Some(&ctx)).await; + super::build_prompt_text(7, 0.0, "", true, true, &mgr, true, Some(&ctx), None).await; assert!(prompt.contains("### Shell Context"), "got: {prompt}"); // The shell-context JSON must carry the SOURCE pane's shell + cwd… assert!( diff --git a/tools/wta/src/protocol/acp/mock_agent_tests.rs b/tools/wta/src/protocol/acp/mock_agent_tests.rs index 6c1c6b750c..939d0eb34f 100644 --- a/tools/wta/src/protocol/acp/mock_agent_tests.rs +++ b/tools/wta/src/protocol/acp/mock_agent_tests.rs @@ -614,6 +614,7 @@ fn test_prompt(id: u64, text: &str, is_autofix: bool) -> PromptSubmission { pane_context: None, submitted_at_unix_s: 0.0, is_autofix, + agent_override: None, images: Vec::new(), } } diff --git a/tools/wta/src/protocol/acp/prompt.rs b/tools/wta/src/protocol/acp/prompt.rs index c897a31a4b..20784e1da0 100644 --- a/tools/wta/src/protocol/acp/prompt.rs +++ b/tools/wta/src/protocol/acp/prompt.rs @@ -38,6 +38,37 @@ pub(crate) fn load_planner_prompt_template() -> PlannerPromptTemplate { ) } +/// Build the planner template for a specific selected custom agent. +/// +/// The built-in `terminal-agent` falls back to the default file/embedded +/// loader (so a user override of `terminal-agent.md` still applies). Any other +/// agent uses its `.agent.md` body verbatim as the template — the runtime +/// context block is merged in later by [`merge_runtime_sections`] (the body +/// need not contain the [`RUNTIME_CONTEXT_MARKER`]; the merge appends when it +/// is absent). +pub(crate) fn load_planner_prompt_template_for_agent( + agent: &crate::custom_agents::CustomAgent, +) -> PlannerPromptTemplate { + if agent.is_builtin() { + return load_planner_prompt_template(); + } + planner_template_from_agent_override(&agent.display_name, &agent.body) +} + +/// Build a planner template from a custom agent's display name + system-prompt +/// body directly (without a [`CustomAgent`]). Used on the prompt hot path where +/// the override travels with the prompt as `(display_name, body)`. +pub(crate) fn planner_template_from_agent_override( + display_name: &str, + body: &str, +) -> PlannerPromptTemplate { + PlannerPromptTemplate { + display_name: display_name.to_string(), + content: body.to_string(), + source_label: format!("agent:{display_name}"), + } +} + pub(crate) fn merge_runtime_sections(template: &str, runtime_sections: &[String]) -> String { let runtime_block = runtime_sections .iter() @@ -264,6 +295,38 @@ mod tests { assert_eq!(merged, "before\n\nfirst\n\nsecond"); } + #[test] + fn agent_template_uses_custom_body_and_display_name() { + use crate::custom_agents::{AgentScope, CustomAgent}; + + let agent = CustomAgent { + id: "devops-helper".to_string(), + display_name: "DevOps Helper".to_string(), + description: "Fixes builds.".to_string(), + model: Some("claude-haiku-4.5".to_string()), + agent_cli: None, + tools: Vec::new(), + body: "You are a DevOps specialist.".to_string(), + scope: AgentScope::Project, + source_path: Some(PathBuf::from("C:/x/.github/agents/devops-helper.agent.md")), + }; + + let template = super::load_planner_prompt_template_for_agent(&agent); + assert_eq!(template.content, "You are a DevOps specialist."); + assert_eq!(template.display_name, "DevOps Helper"); + assert!(template.source_label.starts_with("agent:")); + } + + #[test] + fn agent_template_for_builtin_falls_back_to_default_loader() { + use crate::custom_agents::builtin_agent; + + // The built-in must NOT use its (empty) body; it delegates to the + // default embedded/file loader so a user override still applies. + let template = super::load_planner_prompt_template_for_agent(&builtin_agent()); + assert!(!template.content.is_empty()); + } + #[test] fn loader_seeds_prompt_files_and_prefers_user_prompt() { let prompt_root = temp_prompt_root("prefers-user"); diff --git a/tools/wta/src/slash_command_tests.rs b/tools/wta/src/slash_command_tests.rs index 338c782530..c3312f35bd 100644 --- a/tools/wta/src/slash_command_tests.rs +++ b/tools/wta/src/slash_command_tests.rs @@ -274,6 +274,69 @@ fn slash_model_direct_switch_sets_override() { ); } +// ---- /agent custom-agent picker ---- + +#[test] +fn slash_agent_bare_opens_picker() { + let mut app = test_app(); + // The built-in `terminal-agent` is always discoverable, so the picker + // always has at least one row to show. + run_slash(&mut app, "agent"); + assert!( + app.current_tab().agent_picker_open, + "bare /agent must open the agent picker" + ); +} + +#[test] +fn slash_agent_direct_builtin_selects_default() { + let mut app = test_app(); + app.current_tab_mut().session_id = Some("sid-1".into()); + + run_slash_args(&mut app, "agent", "terminal-agent"); + + assert!( + app.current_tab().active_agent.is_none(), + "selecting the built-in agent leaves the tab on the default (None)" + ); + assert!( + !app.current_tab().agent_picker_open, + "a direct /agent switch must not leave the picker open" + ); + assert!( + app.current_tab().session_id.is_none(), + "switching agent starts a fresh session (session_id cleared)" + ); +} + +#[test] +fn slash_agent_unknown_notes_system_and_keeps_default() { + let mut app = test_app(); + run_slash_args(&mut app, "agent", "no-such-agent-xyz"); + + assert!( + app.current_tab().active_agent.is_none(), + "an unknown /agent name must not change the active agent" + ); + assert!(matches!( + app.current_tab().messages.last(), + Some(ChatMessage::System(_)) + )); +} + +#[test] +fn degraded_blocks_agent_command_too() { + let mut app = test_app(); + app.transport_lost = true; + + run_slash(&mut app, "agent"); + + assert!( + !app.current_tab().agent_picker_open, + "/agent must be refused while the transport is lost" + ); +} + // ---- Degraded (transport-lost) gating: only /restart runs ---- #[test] diff --git a/tools/wta/src/ui/agent_popup.rs b/tools/wta/src/ui/agent_popup.rs new file mode 100644 index 0000000000..d99f387a61 --- /dev/null +++ b/tools/wta/src/ui/agent_popup.rs @@ -0,0 +1,76 @@ +//! `/agent` custom-agent picker modal. +//! +//! Opened by the `/agent` slash command (`App::cmd_agent`), this overlay lists +//! the custom agents discovered from `.github/agents/` (project) and +//! `~/.github/agents/` (user), plus the built-in default `terminal-agent`, and +//! lets the user switch *this pane* to one of them. Selecting an agent starts a +//! fresh session bound to that agent's `.agent.md` system prompt. Modeled on +//! the `/model` picker (`model_popup.rs`): anchored above the input box, arrow +//! keys move the highlight, Enter commits, Esc dismisses (all handled in +//! `App::handle_key`). + +use ratatui::prelude::*; +use ratatui::widgets::{Clear, List, ListItem, ListState}; + +use super::popup; +use crate::custom_agents::CustomAgent; +use crate::theme; + +const POPUP_MAX_VISIBLE: usize = 8; +/// Marker drawn next to the agent the pane is currently on. +const CURRENT_MARKER: &str = "● "; +const CURRENT_PAD: &str = " "; + +/// Per-frame state captured from the [`App`](crate::app::App). +pub struct AgentPopupState<'a> { + pub agents: &'a [CustomAgent], + pub selected: usize, + /// Id of the agent the pane is currently on, drawn with a leading marker. + pub current_id: Option<&'a str>, +} + +/// Render the agent picker just above `input_area`, falling back to below when +/// there isn't room. No-op on an empty list (never happens — the built-in is +/// always present — but guarded for safety). +pub fn render_popup(frame: &mut Frame, state: AgentPopupState<'_>, input_area: Rect) { + if state.agents.is_empty() { + return; + } + + let visible = state.agents.len().min(POPUP_MAX_VISIBLE) as u16; + let area = popup::anchored_above(frame, input_area, visible); + + frame.render_widget(Clear, area); + + let items: Vec = state + .agents + .iter() + .map(|a| { + let is_current = state.current_id == Some(a.id.as_str()); + let marker = if is_current { CURRENT_MARKER } else { CURRENT_PAD }; + let mut spans = vec![Span::styled( + format!(" {}{}", marker, a.display_name), + theme::INPUT_TEXT, + )]; + // Show the raw id when it differs from the display name, plus the + // optional one-line description, both dimmed. + if !a.id.eq_ignore_ascii_case(&a.display_name) { + spans.push(Span::styled(format!(" ({})", a.id), theme::DIM)); + } + if !a.description.is_empty() { + spans.push(Span::styled(format!(" — {}", a.description), theme::DIM)); + } + ListItem::new(Line::from(spans)) + }) + .collect(); + + let list = List::new(items) + .block(popup::block(t!("agent_picker.title").into_owned())) + .highlight_style(theme::SELECTED) + .highlight_symbol("> "); + + let mut list_state = ListState::default(); + list_state.select(Some(state.selected.min(state.agents.len() - 1))); + + frame.render_stateful_widget(list, area, &mut list_state); +} diff --git a/tools/wta/src/ui/layout.rs b/tools/wta/src/ui/layout.rs index 658d83f15a..6528f2e2fd 100644 --- a/tools/wta/src/ui/layout.rs +++ b/tools/wta/src/ui/layout.rs @@ -2,8 +2,8 @@ use crate::app::{App, AppMode, View, DEFAULT_TAB_ID}; use ratatui::prelude::*; use super::{ - agents_view, auth, chat, command_popup, debug_panel, input, model_popup, permission, - recommendations, setup, + agent_popup, agents_view, auth, chat, command_popup, debug_panel, input, model_popup, + permission, recommendations, setup, }; pub fn render(frame: &mut Frame, app: &mut App) { @@ -229,6 +229,11 @@ pub fn render(frame: &mut Frame, app: &mut App) { model_popup::render_popup(frame, model_state, chunks[6]); } + // `/agent` picker modal: same anchor and mutual-exclusion as `/model`. + if let Some(agent_state) = app.agent_popup_state() { + agent_popup::render_popup(frame, agent_state, chunks[6]); + } + // `/help` overlay sits on top of everything so the user can always // dismiss it with Esc. command_popup::render_help_overlay(frame, app, area); diff --git a/tools/wta/src/ui/mod.rs b/tools/wta/src/ui/mod.rs index 0609a906c8..76e8ea7c2b 100644 --- a/tools/wta/src/ui/mod.rs +++ b/tools/wta/src/ui/mod.rs @@ -1,6 +1,7 @@ mod auth; pub(crate) mod card; pub(crate) mod chat; +mod agent_popup; mod command_popup; mod debug_panel; mod input; @@ -17,3 +18,4 @@ pub use shimmer::CYCLE_FRAMES as ACTIVITY_CYCLE_FRAMES; pub use command_popup::PopupState; pub use layout::render; pub use model_popup::ModelPopupState; +pub use agent_popup::AgentPopupState;