mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 06:40:44 +00:00
UI: localize command palette labels (#72378)
This commit is contained in:
@@ -31,6 +31,7 @@ Docs: https://docs.openclaw.ai
|
||||
- WhatsApp/Web: keep quiet but healthy linked-device sessions connected by basing the watchdog on WhatsApp Web transport activity, while retaining a longer app-silence cap so frame activity cannot mask a stuck session forever. Fixes #70678; carries forward the focused #71466 approach and keeps #63939 as related configurable-timeout follow-up. Thanks @vincentkoc and @oromeis.
|
||||
- Discord/gateway: count failed health-monitor restart attempts toward cooldown and hourly caps, and evict stale account lifecycle state during channel reloads so repeated Discord gateway recovery cannot loop on old status. Fixes #38596. (#40413) Thanks @jellyAI-dev and @vashquez.
|
||||
- Cron/context engine: run isolated cron jobs under run-scoped context-engine session keys so prior runs of the same job are not inherited unless the job is explicitly session-bound. (#72292) Thanks @jalehman.
|
||||
- Control UI: localize command palette labels, categories, skill shortcuts, footer hints, and connect-command copy labels while preserving localized command palette search matching. (#61130, #61119) Thanks @rubensfox20.
|
||||
|
||||
## 2026.4.26
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"fallbackKeys": [],
|
||||
"generatedAt": "2026-04-25T07:56:05.494Z",
|
||||
"generatedAt": "2026-04-26T21:47:11.631Z",
|
||||
"locale": "de",
|
||||
"model": "gpt-5.5",
|
||||
"provider": "openai",
|
||||
"sourceHash": "2af900ae253948aab69216e38e0fce2dfde89801d178dee0ebb8dd28df2e11ef",
|
||||
"totalKeys": 734,
|
||||
"translatedKeys": 734,
|
||||
"sourceHash": "0b1690213c6431759bd87ed8a231c4f523c79bac42dfac74028698fb18e7ebba",
|
||||
"totalKeys": 752,
|
||||
"translatedKeys": 752,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"fallbackKeys": [],
|
||||
"generatedAt": "2026-04-25T07:56:33.676Z",
|
||||
"generatedAt": "2026-04-26T21:47:11.941Z",
|
||||
"locale": "es",
|
||||
"model": "gpt-5.5",
|
||||
"provider": "openai",
|
||||
"sourceHash": "2af900ae253948aab69216e38e0fce2dfde89801d178dee0ebb8dd28df2e11ef",
|
||||
"totalKeys": 734,
|
||||
"translatedKeys": 734,
|
||||
"sourceHash": "0b1690213c6431759bd87ed8a231c4f523c79bac42dfac74028698fb18e7ebba",
|
||||
"totalKeys": 752,
|
||||
"translatedKeys": 752,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"fallbackKeys": [],
|
||||
"generatedAt": "2026-04-25T07:56:45.086Z",
|
||||
"generatedAt": "2026-04-26T21:47:12.883Z",
|
||||
"locale": "fr",
|
||||
"model": "gpt-5.5",
|
||||
"provider": "openai",
|
||||
"sourceHash": "2af900ae253948aab69216e38e0fce2dfde89801d178dee0ebb8dd28df2e11ef",
|
||||
"totalKeys": 734,
|
||||
"translatedKeys": 734,
|
||||
"sourceHash": "0b1690213c6431759bd87ed8a231c4f523c79bac42dfac74028698fb18e7ebba",
|
||||
"totalKeys": 752,
|
||||
"translatedKeys": 752,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"fallbackKeys": [],
|
||||
"generatedAt": "2026-04-25T07:57:25.463Z",
|
||||
"generatedAt": "2026-04-26T21:47:13.865Z",
|
||||
"locale": "id",
|
||||
"model": "gpt-5.5",
|
||||
"provider": "openai",
|
||||
"sourceHash": "2af900ae253948aab69216e38e0fce2dfde89801d178dee0ebb8dd28df2e11ef",
|
||||
"totalKeys": 734,
|
||||
"translatedKeys": 734,
|
||||
"sourceHash": "0b1690213c6431759bd87ed8a231c4f523c79bac42dfac74028698fb18e7ebba",
|
||||
"totalKeys": 752,
|
||||
"translatedKeys": 752,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"fallbackKeys": [],
|
||||
"generatedAt": "2026-04-25T07:56:47.425Z",
|
||||
"generatedAt": "2026-04-26T21:47:12.252Z",
|
||||
"locale": "ja-JP",
|
||||
"model": "gpt-5.5",
|
||||
"provider": "openai",
|
||||
"sourceHash": "2af900ae253948aab69216e38e0fce2dfde89801d178dee0ebb8dd28df2e11ef",
|
||||
"totalKeys": 734,
|
||||
"translatedKeys": 734,
|
||||
"sourceHash": "0b1690213c6431759bd87ed8a231c4f523c79bac42dfac74028698fb18e7ebba",
|
||||
"totalKeys": 752,
|
||||
"translatedKeys": 752,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"fallbackKeys": [],
|
||||
"generatedAt": "2026-04-25T07:56:44.197Z",
|
||||
"generatedAt": "2026-04-26T21:47:12.563Z",
|
||||
"locale": "ko",
|
||||
"model": "gpt-5.5",
|
||||
"provider": "openai",
|
||||
"sourceHash": "2af900ae253948aab69216e38e0fce2dfde89801d178dee0ebb8dd28df2e11ef",
|
||||
"totalKeys": 734,
|
||||
"translatedKeys": 734,
|
||||
"sourceHash": "0b1690213c6431759bd87ed8a231c4f523c79bac42dfac74028698fb18e7ebba",
|
||||
"totalKeys": 752,
|
||||
"translatedKeys": 752,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"fallbackKeys": [],
|
||||
"generatedAt": "2026-04-25T07:57:26.422Z",
|
||||
"generatedAt": "2026-04-26T21:47:14.204Z",
|
||||
"locale": "pl",
|
||||
"model": "gpt-5.5",
|
||||
"provider": "openai",
|
||||
"sourceHash": "2af900ae253948aab69216e38e0fce2dfde89801d178dee0ebb8dd28df2e11ef",
|
||||
"totalKeys": 734,
|
||||
"translatedKeys": 734,
|
||||
"sourceHash": "0b1690213c6431759bd87ed8a231c4f523c79bac42dfac74028698fb18e7ebba",
|
||||
"totalKeys": 752,
|
||||
"translatedKeys": 752,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"fallbackKeys": [],
|
||||
"generatedAt": "2026-04-25T07:56:04.004Z",
|
||||
"generatedAt": "2026-04-26T21:47:11.305Z",
|
||||
"locale": "pt-BR",
|
||||
"model": "gpt-5.5",
|
||||
"provider": "openai",
|
||||
"sourceHash": "2af900ae253948aab69216e38e0fce2dfde89801d178dee0ebb8dd28df2e11ef",
|
||||
"totalKeys": 734,
|
||||
"translatedKeys": 734,
|
||||
"sourceHash": "0b1690213c6431759bd87ed8a231c4f523c79bac42dfac74028698fb18e7ebba",
|
||||
"totalKeys": 752,
|
||||
"translatedKeys": 752,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"fallbackKeys": [],
|
||||
"generatedAt": "2026-04-25T07:57:38.352Z",
|
||||
"generatedAt": "2026-04-26T21:47:14.524Z",
|
||||
"locale": "th",
|
||||
"model": "gpt-5.5",
|
||||
"provider": "openai",
|
||||
"sourceHash": "2af900ae253948aab69216e38e0fce2dfde89801d178dee0ebb8dd28df2e11ef",
|
||||
"totalKeys": 734,
|
||||
"translatedKeys": 734,
|
||||
"sourceHash": "0b1690213c6431759bd87ed8a231c4f523c79bac42dfac74028698fb18e7ebba",
|
||||
"totalKeys": 752,
|
||||
"translatedKeys": 752,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"fallbackKeys": [],
|
||||
"generatedAt": "2026-04-25T07:57:03.203Z",
|
||||
"generatedAt": "2026-04-26T21:47:13.204Z",
|
||||
"locale": "tr",
|
||||
"model": "gpt-5.5",
|
||||
"provider": "openai",
|
||||
"sourceHash": "2af900ae253948aab69216e38e0fce2dfde89801d178dee0ebb8dd28df2e11ef",
|
||||
"totalKeys": 734,
|
||||
"translatedKeys": 734,
|
||||
"sourceHash": "0b1690213c6431759bd87ed8a231c4f523c79bac42dfac74028698fb18e7ebba",
|
||||
"totalKeys": 752,
|
||||
"translatedKeys": 752,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"fallbackKeys": [],
|
||||
"generatedAt": "2026-04-25T07:57:11.008Z",
|
||||
"generatedAt": "2026-04-26T21:47:13.531Z",
|
||||
"locale": "uk",
|
||||
"model": "gpt-5.5",
|
||||
"provider": "openai",
|
||||
"sourceHash": "2af900ae253948aab69216e38e0fce2dfde89801d178dee0ebb8dd28df2e11ef",
|
||||
"totalKeys": 734,
|
||||
"translatedKeys": 734,
|
||||
"sourceHash": "0b1690213c6431759bd87ed8a231c4f523c79bac42dfac74028698fb18e7ebba",
|
||||
"totalKeys": 752,
|
||||
"translatedKeys": 752,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"fallbackKeys": [],
|
||||
"generatedAt": "2026-04-25T07:56:08.786Z",
|
||||
"generatedAt": "2026-04-26T21:47:10.673Z",
|
||||
"locale": "zh-CN",
|
||||
"model": "gpt-5.5",
|
||||
"provider": "openai",
|
||||
"sourceHash": "2af900ae253948aab69216e38e0fce2dfde89801d178dee0ebb8dd28df2e11ef",
|
||||
"totalKeys": 734,
|
||||
"translatedKeys": 734,
|
||||
"sourceHash": "0b1690213c6431759bd87ed8a231c4f523c79bac42dfac74028698fb18e7ebba",
|
||||
"totalKeys": 752,
|
||||
"translatedKeys": 752,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"fallbackKeys": [],
|
||||
"generatedAt": "2026-04-25T07:56:00.104Z",
|
||||
"generatedAt": "2026-04-26T21:47:10.990Z",
|
||||
"locale": "zh-TW",
|
||||
"model": "gpt-5.5",
|
||||
"provider": "openai",
|
||||
"sourceHash": "2af900ae253948aab69216e38e0fce2dfde89801d178dee0ebb8dd28df2e11ef",
|
||||
"totalKeys": 734,
|
||||
"translatedKeys": 734,
|
||||
"sourceHash": "0b1690213c6431759bd87ed8a231c4f523c79bac42dfac74028698fb18e7ebba",
|
||||
"totalKeys": 752,
|
||||
"translatedKeys": 752,
|
||||
"workflow": 1
|
||||
}
|
||||
|
||||
@@ -280,6 +280,8 @@ export const de: TranslationMap = {
|
||||
tailscaleDocsLink: "Docs: Tailscale Serve",
|
||||
insecureHttpDocsTitle: "Dokumentation zu unsicherem HTTP (öffnet sich in neuem Tab)",
|
||||
insecureHttpDocsLink: "Docs: Unsicheres HTTP",
|
||||
copyCommand: "Befehl kopieren",
|
||||
copyCommandAria: "Befehl kopieren: {command}",
|
||||
},
|
||||
cards: {
|
||||
cost: "Kosten",
|
||||
@@ -316,6 +318,30 @@ export const de: TranslationMap = {
|
||||
palette: {
|
||||
placeholder: "Befehl eingeben…",
|
||||
noResults: "Keine Ergebnisse",
|
||||
categories: {
|
||||
search: "Suchen",
|
||||
navigation: "Navigation",
|
||||
skills: "Skills",
|
||||
},
|
||||
items: {
|
||||
overview: "Übersicht",
|
||||
sessions: "Sitzungen",
|
||||
scheduled: "Geplant",
|
||||
skills: "Skills",
|
||||
settings: "Einstellungen",
|
||||
agents: "Agenten",
|
||||
shellCommand: "Shell-Befehl",
|
||||
debugMode: "Debug-Modus",
|
||||
},
|
||||
descriptions: {
|
||||
shellCommand: "Shell ausführen",
|
||||
debugMode: "Debug umschalten",
|
||||
},
|
||||
footer: {
|
||||
navigate: "navigieren",
|
||||
select: "auswählen",
|
||||
close: "schließen",
|
||||
},
|
||||
},
|
||||
},
|
||||
dreaming: {
|
||||
|
||||
@@ -271,6 +271,8 @@ export const en: TranslationMap = {
|
||||
tailscaleDocsLink: "Docs: Tailscale Serve",
|
||||
insecureHttpDocsTitle: "Insecure HTTP docs (opens in new tab)",
|
||||
insecureHttpDocsLink: "Docs: Insecure HTTP",
|
||||
copyCommand: "Copy command",
|
||||
copyCommandAria: "Copy command: {command}",
|
||||
},
|
||||
cards: {
|
||||
cost: "Cost",
|
||||
@@ -306,6 +308,30 @@ export const en: TranslationMap = {
|
||||
palette: {
|
||||
placeholder: "Type a command…",
|
||||
noResults: "No results",
|
||||
categories: {
|
||||
search: "Search",
|
||||
navigation: "Navigation",
|
||||
skills: "Skills",
|
||||
},
|
||||
items: {
|
||||
overview: "Overview",
|
||||
sessions: "Sessions",
|
||||
scheduled: "Scheduled",
|
||||
skills: "Skills",
|
||||
settings: "Settings",
|
||||
agents: "Agents",
|
||||
shellCommand: "Shell Command",
|
||||
debugMode: "Debug Mode",
|
||||
},
|
||||
descriptions: {
|
||||
shellCommand: "Run shell",
|
||||
debugMode: "Toggle debug",
|
||||
},
|
||||
footer: {
|
||||
navigate: "navigate",
|
||||
select: "select",
|
||||
close: "close",
|
||||
},
|
||||
},
|
||||
},
|
||||
dreaming: {
|
||||
|
||||
@@ -275,6 +275,8 @@ export const es: TranslationMap = {
|
||||
tailscaleDocsLink: "Documentación: Tailscale Serve",
|
||||
insecureHttpDocsTitle: "Documentación de HTTP inseguro (se abre en una pestaña nueva)",
|
||||
insecureHttpDocsLink: "Documentación: HTTP inseguro",
|
||||
copyCommand: "Copiar comando",
|
||||
copyCommandAria: "Copiar comando: {command}",
|
||||
},
|
||||
cards: {
|
||||
cost: "Costo",
|
||||
@@ -310,6 +312,30 @@ export const es: TranslationMap = {
|
||||
palette: {
|
||||
placeholder: "Escribe un comando…",
|
||||
noResults: "Sin resultados",
|
||||
categories: {
|
||||
search: "Buscar",
|
||||
navigation: "Navegación",
|
||||
skills: "Skills",
|
||||
},
|
||||
items: {
|
||||
overview: "Resumen",
|
||||
sessions: "Sesiones",
|
||||
scheduled: "Programado",
|
||||
skills: "Skills",
|
||||
settings: "Configuración",
|
||||
agents: "Agentes",
|
||||
shellCommand: "Comando de shell",
|
||||
debugMode: "Modo de depuración",
|
||||
},
|
||||
descriptions: {
|
||||
shellCommand: "Ejecutar shell",
|
||||
debugMode: "Alternar depuración",
|
||||
},
|
||||
footer: {
|
||||
navigate: "navegar",
|
||||
select: "seleccionar",
|
||||
close: "cerrar",
|
||||
},
|
||||
},
|
||||
},
|
||||
dreaming: {
|
||||
|
||||
@@ -279,6 +279,8 @@ export const fr: TranslationMap = {
|
||||
tailscaleDocsLink: "Documentation : Tailscale Serve",
|
||||
insecureHttpDocsTitle: "Documentation sur HTTP non sécurisé (s’ouvre dans un nouvel onglet)",
|
||||
insecureHttpDocsLink: "Documentation : HTTP non sécurisé",
|
||||
copyCommand: "Copier la commande",
|
||||
copyCommandAria: "Copier la commande : {command}",
|
||||
},
|
||||
cards: {
|
||||
cost: "Coût",
|
||||
@@ -314,6 +316,30 @@ export const fr: TranslationMap = {
|
||||
palette: {
|
||||
placeholder: "Saisissez une commande…",
|
||||
noResults: "Aucun résultat",
|
||||
categories: {
|
||||
search: "Recherche",
|
||||
navigation: "Navigation",
|
||||
skills: "Skills",
|
||||
},
|
||||
items: {
|
||||
overview: "Vue d’ensemble",
|
||||
sessions: "Sessions",
|
||||
scheduled: "Planifié",
|
||||
skills: "Skills",
|
||||
settings: "Paramètres",
|
||||
agents: "Agents",
|
||||
shellCommand: "Commande shell",
|
||||
debugMode: "Mode débogage",
|
||||
},
|
||||
descriptions: {
|
||||
shellCommand: "Exécuter le shell",
|
||||
debugMode: "Basculer le débogage",
|
||||
},
|
||||
footer: {
|
||||
navigate: "naviguer",
|
||||
select: "sélectionner",
|
||||
close: "fermer",
|
||||
},
|
||||
},
|
||||
},
|
||||
dreaming: {
|
||||
|
||||
@@ -275,6 +275,8 @@ export const id: TranslationMap = {
|
||||
tailscaleDocsLink: "Dokumentasi: Tailscale Serve",
|
||||
insecureHttpDocsTitle: "Dokumentasi HTTP tidak aman (dibuka di tab baru)",
|
||||
insecureHttpDocsLink: "Dokumentasi: HTTP tidak aman",
|
||||
copyCommand: "Salin perintah",
|
||||
copyCommandAria: "Salin perintah: {command}",
|
||||
},
|
||||
cards: {
|
||||
cost: "Biaya",
|
||||
@@ -310,6 +312,30 @@ export const id: TranslationMap = {
|
||||
palette: {
|
||||
placeholder: "Ketik perintah…",
|
||||
noResults: "Tidak ada hasil",
|
||||
categories: {
|
||||
search: "Cari",
|
||||
navigation: "Navigasi",
|
||||
skills: "Skills",
|
||||
},
|
||||
items: {
|
||||
overview: "Ikhtisar",
|
||||
sessions: "Sesi",
|
||||
scheduled: "Terjadwal",
|
||||
skills: "Skills",
|
||||
settings: "Pengaturan",
|
||||
agents: "Agen",
|
||||
shellCommand: "Perintah shell",
|
||||
debugMode: "Mode debug",
|
||||
},
|
||||
descriptions: {
|
||||
shellCommand: "Jalankan shell",
|
||||
debugMode: "Alihkan debug",
|
||||
},
|
||||
footer: {
|
||||
navigate: "navigasi",
|
||||
select: "pilih",
|
||||
close: "tutup",
|
||||
},
|
||||
},
|
||||
},
|
||||
dreaming: {
|
||||
|
||||
@@ -279,6 +279,8 @@ export const ja_JP: TranslationMap = {
|
||||
tailscaleDocsLink: "ドキュメント: Tailscale Serve",
|
||||
insecureHttpDocsTitle: "安全でない HTTP に関するドキュメント(新しいタブで開きます)",
|
||||
insecureHttpDocsLink: "ドキュメント: 安全でない HTTP",
|
||||
copyCommand: "コマンドをコピー",
|
||||
copyCommandAria: "コマンドをコピー: {command}",
|
||||
},
|
||||
cards: {
|
||||
cost: "コスト",
|
||||
@@ -314,6 +316,30 @@ export const ja_JP: TranslationMap = {
|
||||
palette: {
|
||||
placeholder: "コマンドを入力…",
|
||||
noResults: "結果がありません",
|
||||
categories: {
|
||||
search: "検索",
|
||||
navigation: "ナビゲーション",
|
||||
skills: "Skills",
|
||||
},
|
||||
items: {
|
||||
overview: "概要",
|
||||
sessions: "セッション",
|
||||
scheduled: "スケジュール済み",
|
||||
skills: "Skills",
|
||||
settings: "設定",
|
||||
agents: "エージェント",
|
||||
shellCommand: "シェルコマンド",
|
||||
debugMode: "デバッグモード",
|
||||
},
|
||||
descriptions: {
|
||||
shellCommand: "シェルを実行",
|
||||
debugMode: "デバッグを切り替え",
|
||||
},
|
||||
footer: {
|
||||
navigate: "移動",
|
||||
select: "選択",
|
||||
close: "閉じる",
|
||||
},
|
||||
},
|
||||
},
|
||||
dreaming: {
|
||||
|
||||
@@ -274,6 +274,8 @@ export const ko: TranslationMap = {
|
||||
tailscaleDocsLink: "문서: Tailscale Serve",
|
||||
insecureHttpDocsTitle: "안전하지 않은 HTTP 문서(새 탭에서 열림)",
|
||||
insecureHttpDocsLink: "문서: 안전하지 않은 HTTP",
|
||||
copyCommand: "명령 복사",
|
||||
copyCommandAria: "명령 복사: {command}",
|
||||
},
|
||||
cards: {
|
||||
cost: "비용",
|
||||
@@ -309,6 +311,30 @@ export const ko: TranslationMap = {
|
||||
palette: {
|
||||
placeholder: "명령을 입력하세요…",
|
||||
noResults: "결과 없음",
|
||||
categories: {
|
||||
search: "검색",
|
||||
navigation: "탐색",
|
||||
skills: "Skills",
|
||||
},
|
||||
items: {
|
||||
overview: "개요",
|
||||
sessions: "세션",
|
||||
scheduled: "예약됨",
|
||||
skills: "Skills",
|
||||
settings: "설정",
|
||||
agents: "에이전트",
|
||||
shellCommand: "셸 명령",
|
||||
debugMode: "디버그 모드",
|
||||
},
|
||||
descriptions: {
|
||||
shellCommand: "셸 실행",
|
||||
debugMode: "디버그 전환",
|
||||
},
|
||||
footer: {
|
||||
navigate: "탐색",
|
||||
select: "선택",
|
||||
close: "닫기",
|
||||
},
|
||||
},
|
||||
},
|
||||
dreaming: {
|
||||
|
||||
@@ -276,6 +276,8 @@ export const pl: TranslationMap = {
|
||||
tailscaleDocsLink: "Dokumentacja: Tailscale Serve",
|
||||
insecureHttpDocsTitle: "Dokumentacja niezabezpieczonego HTTP (otwiera się w nowej karcie)",
|
||||
insecureHttpDocsLink: "Dokumentacja: Niezabezpieczone HTTP",
|
||||
copyCommand: "Kopiuj polecenie",
|
||||
copyCommandAria: "Kopiuj polecenie: {command}",
|
||||
},
|
||||
cards: {
|
||||
cost: "Koszt",
|
||||
@@ -312,6 +314,30 @@ export const pl: TranslationMap = {
|
||||
palette: {
|
||||
placeholder: "Wpisz polecenie…",
|
||||
noResults: "Brak wyników",
|
||||
categories: {
|
||||
search: "Szukaj",
|
||||
navigation: "Nawigacja",
|
||||
skills: "Skills",
|
||||
},
|
||||
items: {
|
||||
overview: "Przegląd",
|
||||
sessions: "Sesje",
|
||||
scheduled: "Zaplanowane",
|
||||
skills: "Skills",
|
||||
settings: "Ustawienia",
|
||||
agents: "Agenci",
|
||||
shellCommand: "Polecenie powłoki",
|
||||
debugMode: "Tryb debugowania",
|
||||
},
|
||||
descriptions: {
|
||||
shellCommand: "Uruchom powłokę",
|
||||
debugMode: "Przełącz debugowanie",
|
||||
},
|
||||
footer: {
|
||||
navigate: "nawiguj",
|
||||
select: "wybierz",
|
||||
close: "zamknij",
|
||||
},
|
||||
},
|
||||
},
|
||||
dreaming: {
|
||||
|
||||
@@ -275,6 +275,8 @@ export const pt_BR: TranslationMap = {
|
||||
tailscaleDocsLink: "Docs: Tailscale Serve",
|
||||
insecureHttpDocsTitle: "Documentação de HTTP inseguro (abre em nova aba)",
|
||||
insecureHttpDocsLink: "Docs: HTTP inseguro",
|
||||
copyCommand: "Copiar comando",
|
||||
copyCommandAria: "Copiar comando: {command}",
|
||||
},
|
||||
cards: {
|
||||
cost: "Custo",
|
||||
@@ -310,6 +312,30 @@ export const pt_BR: TranslationMap = {
|
||||
palette: {
|
||||
placeholder: "Digite um comando…",
|
||||
noResults: "Sem resultados",
|
||||
categories: {
|
||||
search: "Pesquisar",
|
||||
navigation: "Navegação",
|
||||
skills: "Skills",
|
||||
},
|
||||
items: {
|
||||
overview: "Visão geral",
|
||||
sessions: "Sessões",
|
||||
scheduled: "Agendado",
|
||||
skills: "Skills",
|
||||
settings: "Configurações",
|
||||
agents: "Agentes",
|
||||
shellCommand: "Comando de shell",
|
||||
debugMode: "Modo de depuração",
|
||||
},
|
||||
descriptions: {
|
||||
shellCommand: "Executar shell",
|
||||
debugMode: "Alternar depuração",
|
||||
},
|
||||
footer: {
|
||||
navigate: "navegar",
|
||||
select: "selecionar",
|
||||
close: "fechar",
|
||||
},
|
||||
},
|
||||
},
|
||||
dreaming: {
|
||||
|
||||
@@ -268,6 +268,8 @@ export const th: TranslationMap = {
|
||||
tailscaleDocsLink: "เอกสาร: Tailscale Serve",
|
||||
insecureHttpDocsTitle: "เอกสาร HTTP ที่ไม่ปลอดภัย (เปิดในแท็บใหม่)",
|
||||
insecureHttpDocsLink: "เอกสาร: HTTP ที่ไม่ปลอดภัย",
|
||||
copyCommand: "คัดลอกคำสั่ง",
|
||||
copyCommandAria: "คัดลอกคำสั่ง: {command}",
|
||||
},
|
||||
cards: {
|
||||
cost: "ค่าใช้จ่าย",
|
||||
@@ -303,6 +305,30 @@ export const th: TranslationMap = {
|
||||
palette: {
|
||||
placeholder: "พิมพ์คำสั่ง…",
|
||||
noResults: "ไม่พบผลลัพธ์",
|
||||
categories: {
|
||||
search: "ค้นหา",
|
||||
navigation: "การนำทาง",
|
||||
skills: "ทักษะ",
|
||||
},
|
||||
items: {
|
||||
overview: "ภาพรวม",
|
||||
sessions: "เซสชัน",
|
||||
scheduled: "กำหนดเวลาแล้ว",
|
||||
skills: "ทักษะ",
|
||||
settings: "การตั้งค่า",
|
||||
agents: "เอเจนต์",
|
||||
shellCommand: "คำสั่งเชลล์",
|
||||
debugMode: "โหมดดีบัก",
|
||||
},
|
||||
descriptions: {
|
||||
shellCommand: "เรียกใช้เชลล์",
|
||||
debugMode: "สลับดีบัก",
|
||||
},
|
||||
footer: {
|
||||
navigate: "นำทาง",
|
||||
select: "เลือก",
|
||||
close: "ปิด",
|
||||
},
|
||||
},
|
||||
},
|
||||
dreaming: {
|
||||
|
||||
@@ -279,6 +279,8 @@ export const tr: TranslationMap = {
|
||||
tailscaleDocsLink: "Belgeler: Tailscale Serve",
|
||||
insecureHttpDocsTitle: "Güvenli olmayan HTTP belgeleri (yeni sekmede açılır)",
|
||||
insecureHttpDocsLink: "Belgeler: Güvenli olmayan HTTP",
|
||||
copyCommand: "Komutu kopyala",
|
||||
copyCommandAria: "Komutu kopyala: {command}",
|
||||
},
|
||||
cards: {
|
||||
cost: "Maliyet",
|
||||
@@ -315,6 +317,30 @@ export const tr: TranslationMap = {
|
||||
palette: {
|
||||
placeholder: "Bir komut yazın…",
|
||||
noResults: "Sonuç yok",
|
||||
categories: {
|
||||
search: "Arama",
|
||||
navigation: "Navigation",
|
||||
skills: "Skills",
|
||||
},
|
||||
items: {
|
||||
overview: "Genel Bakış",
|
||||
sessions: "Oturumlar",
|
||||
scheduled: "Zamanlanmış",
|
||||
skills: "Skills",
|
||||
settings: "Ayarlar",
|
||||
agents: "Ajanlar",
|
||||
shellCommand: "Shell Komutu",
|
||||
debugMode: "Hata Ayıklama Modu",
|
||||
},
|
||||
descriptions: {
|
||||
shellCommand: "Shell çalıştır",
|
||||
debugMode: "Hata ayıklamayı değiştir",
|
||||
},
|
||||
footer: {
|
||||
navigate: "gezin",
|
||||
select: "seç",
|
||||
close: "kapat",
|
||||
},
|
||||
},
|
||||
},
|
||||
dreaming: {
|
||||
|
||||
@@ -277,6 +277,8 @@ export const uk: TranslationMap = {
|
||||
tailscaleDocsLink: "Документація: Tailscale Serve",
|
||||
insecureHttpDocsTitle: "Документація щодо незахищеного HTTP (відкривається в новій вкладці)",
|
||||
insecureHttpDocsLink: "Документація: незахищений HTTP",
|
||||
copyCommand: "Копіювати команду",
|
||||
copyCommandAria: "Копіювати команду: {command}",
|
||||
},
|
||||
cards: {
|
||||
cost: "Вартість",
|
||||
@@ -313,6 +315,30 @@ export const uk: TranslationMap = {
|
||||
palette: {
|
||||
placeholder: "Введіть команду…",
|
||||
noResults: "Немає результатів",
|
||||
categories: {
|
||||
search: "Пошук",
|
||||
navigation: "Навігація",
|
||||
skills: "Навички",
|
||||
},
|
||||
items: {
|
||||
overview: "Огляд",
|
||||
sessions: "Сеанси",
|
||||
scheduled: "Заплановано",
|
||||
skills: "Навички",
|
||||
settings: "Налаштування",
|
||||
agents: "Агенти",
|
||||
shellCommand: "Команда оболонки",
|
||||
debugMode: "Режим налагодження",
|
||||
},
|
||||
descriptions: {
|
||||
shellCommand: "Запустити оболонку",
|
||||
debugMode: "Перемкнути налагодження",
|
||||
},
|
||||
footer: {
|
||||
navigate: "навігація",
|
||||
select: "вибрати",
|
||||
close: "закрити",
|
||||
},
|
||||
},
|
||||
},
|
||||
dreaming: {
|
||||
|
||||
@@ -268,6 +268,8 @@ export const zh_CN: TranslationMap = {
|
||||
tailscaleDocsLink: "文档:Tailscale Serve",
|
||||
insecureHttpDocsTitle: "不安全 HTTP 文档(在新标签页中打开)",
|
||||
insecureHttpDocsLink: "文档:不安全 HTTP",
|
||||
copyCommand: "复制命令",
|
||||
copyCommandAria: "复制命令:{command}",
|
||||
},
|
||||
cards: {
|
||||
cost: "费用",
|
||||
@@ -303,6 +305,30 @@ export const zh_CN: TranslationMap = {
|
||||
palette: {
|
||||
placeholder: "输入命令…",
|
||||
noResults: "无结果",
|
||||
categories: {
|
||||
search: "搜索",
|
||||
navigation: "导航",
|
||||
skills: "技能",
|
||||
},
|
||||
items: {
|
||||
overview: "概览",
|
||||
sessions: "会话",
|
||||
scheduled: "已计划",
|
||||
skills: "技能",
|
||||
settings: "设置",
|
||||
agents: "代理",
|
||||
shellCommand: "Shell 命令",
|
||||
debugMode: "调试模式",
|
||||
},
|
||||
descriptions: {
|
||||
shellCommand: "运行 shell",
|
||||
debugMode: "切换调试",
|
||||
},
|
||||
footer: {
|
||||
navigate: "导航",
|
||||
select: "选择",
|
||||
close: "关闭",
|
||||
},
|
||||
},
|
||||
},
|
||||
dreaming: {
|
||||
|
||||
@@ -268,6 +268,8 @@ export const zh_TW: TranslationMap = {
|
||||
tailscaleDocsLink: "文件:Tailscale Serve",
|
||||
insecureHttpDocsTitle: "不安全 HTTP 文件(在新分頁中開啟)",
|
||||
insecureHttpDocsLink: "文件:不安全 HTTP",
|
||||
copyCommand: "複製指令",
|
||||
copyCommandAria: "複製指令:{command}",
|
||||
},
|
||||
cards: {
|
||||
cost: "費用",
|
||||
@@ -303,6 +305,30 @@ export const zh_TW: TranslationMap = {
|
||||
palette: {
|
||||
placeholder: "輸入指令…",
|
||||
noResults: "無結果",
|
||||
categories: {
|
||||
search: "搜尋",
|
||||
navigation: "導覽",
|
||||
skills: "技能",
|
||||
},
|
||||
items: {
|
||||
overview: "概覽",
|
||||
sessions: "工作階段",
|
||||
scheduled: "已排程",
|
||||
skills: "技能",
|
||||
settings: "設定",
|
||||
agents: "代理",
|
||||
shellCommand: "Shell 指令",
|
||||
debugMode: "偵錯模式",
|
||||
},
|
||||
descriptions: {
|
||||
shellCommand: "執行 shell",
|
||||
debugMode: "切換偵錯",
|
||||
},
|
||||
footer: {
|
||||
navigate: "導覽",
|
||||
select: "選取",
|
||||
close: "關閉",
|
||||
},
|
||||
},
|
||||
},
|
||||
dreaming: {
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { i18n } from "../../i18n/index.ts";
|
||||
import { refreshSlashCommands, resetSlashCommandsForTest } from "../chat/slash-commands.ts";
|
||||
import { getPaletteItems } from "./command-palette.ts";
|
||||
import { getFilteredPaletteItems, getPaletteItems } from "./command-palette.ts";
|
||||
|
||||
afterEach(() => {
|
||||
afterEach(async () => {
|
||||
resetSlashCommandsForTest();
|
||||
await i18n.setLocale("en");
|
||||
});
|
||||
|
||||
describe("command palette", () => {
|
||||
@@ -51,4 +53,20 @@ describe("command palette", () => {
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("matches localized base item labels and descriptions", async () => {
|
||||
await i18n.setLocale("zh-CN");
|
||||
|
||||
expect(getPaletteItems()).toContainEqual(
|
||||
expect.objectContaining({
|
||||
id: "nav-config",
|
||||
label: "设置",
|
||||
}),
|
||||
);
|
||||
expect(getFilteredPaletteItems("切换调试")).toContainEqual(
|
||||
expect.objectContaining({
|
||||
id: "skill-debug",
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -29,61 +29,61 @@ function getPaletteBaseItems(): PaletteItem[] {
|
||||
return [
|
||||
{
|
||||
id: "nav-overview",
|
||||
label: "Overview",
|
||||
label: t("overview.palette.items.overview"),
|
||||
icon: "barChart",
|
||||
category: "navigation",
|
||||
action: "nav:overview",
|
||||
},
|
||||
{
|
||||
id: "nav-sessions",
|
||||
label: "Sessions",
|
||||
label: t("overview.palette.items.sessions"),
|
||||
icon: "fileText",
|
||||
category: "navigation",
|
||||
action: "nav:sessions",
|
||||
},
|
||||
{
|
||||
id: "nav-cron",
|
||||
label: "Scheduled",
|
||||
label: t("overview.palette.items.scheduled"),
|
||||
icon: "scrollText",
|
||||
category: "navigation",
|
||||
action: "nav:cron",
|
||||
},
|
||||
{
|
||||
id: "nav-skills",
|
||||
label: "Skills",
|
||||
label: t("overview.palette.items.skills"),
|
||||
icon: "zap",
|
||||
category: "navigation",
|
||||
action: "nav:skills",
|
||||
},
|
||||
{
|
||||
id: "nav-config",
|
||||
label: "Settings",
|
||||
label: t("overview.palette.items.settings"),
|
||||
icon: "settings",
|
||||
category: "navigation",
|
||||
action: "nav:config",
|
||||
},
|
||||
{
|
||||
id: "nav-agents",
|
||||
label: "Agents",
|
||||
label: t("overview.palette.items.agents"),
|
||||
icon: "folder",
|
||||
category: "navigation",
|
||||
action: "nav:agents",
|
||||
},
|
||||
{
|
||||
id: "skill-shell",
|
||||
label: "Shell Command",
|
||||
label: t("overview.palette.items.shellCommand"),
|
||||
icon: "monitor",
|
||||
category: "skills",
|
||||
action: "/skill shell",
|
||||
description: "Run shell",
|
||||
description: t("overview.palette.descriptions.shellCommand"),
|
||||
},
|
||||
{
|
||||
id: "skill-debug",
|
||||
label: "Debug Mode",
|
||||
label: t("overview.palette.items.debugMode"),
|
||||
icon: "bug",
|
||||
category: "skills",
|
||||
action: "/verbose full",
|
||||
description: "Toggle debug",
|
||||
description: t("overview.palette.descriptions.debugMode"),
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -120,6 +120,10 @@ function filteredItems(query: string): PaletteItem[] {
|
||||
);
|
||||
}
|
||||
|
||||
export function getFilteredPaletteItems(query: string): readonly PaletteItem[] {
|
||||
return filteredItems(query);
|
||||
}
|
||||
|
||||
function groupItems(items: PaletteItem[]): Array<[string, PaletteItem[]]> {
|
||||
const map = new Map<string, PaletteItem[]>();
|
||||
for (const item of items) {
|
||||
@@ -190,11 +194,18 @@ function handleKeydown(e: KeyboardEvent, props: CommandPaletteProps) {
|
||||
}
|
||||
}
|
||||
|
||||
const CATEGORY_LABELS: Record<string, string> = {
|
||||
search: "Search",
|
||||
navigation: "Navigation",
|
||||
skills: "Skills",
|
||||
};
|
||||
function getCategoryLabel(category: string): string {
|
||||
switch (category) {
|
||||
case "search":
|
||||
return t("overview.palette.categories.search");
|
||||
case "navigation":
|
||||
return t("overview.palette.categories.navigation");
|
||||
case "skills":
|
||||
return t("overview.palette.categories.skills");
|
||||
default:
|
||||
return category;
|
||||
}
|
||||
}
|
||||
|
||||
function focusInput(el: Element | undefined) {
|
||||
if (el) {
|
||||
@@ -244,9 +255,7 @@ export function renderCommandPalette(props: CommandPaletteProps) {
|
||||
</div>`
|
||||
: grouped.map(
|
||||
([category, groupedItems]) => html`
|
||||
<div class="cmd-palette__group-label">
|
||||
${CATEGORY_LABELS[category] ?? category}
|
||||
</div>
|
||||
<div class="cmd-palette__group-label">${getCategoryLabel(category)}</div>
|
||||
${groupedItems.map((item) => {
|
||||
const globalIndex = items.indexOf(item);
|
||||
const isActive = globalIndex === props.activeIndex;
|
||||
@@ -273,9 +282,9 @@ export function renderCommandPalette(props: CommandPaletteProps) {
|
||||
)}
|
||||
</div>
|
||||
<div class="cmd-palette__footer">
|
||||
<span><kbd>↑↓</kbd> navigate</span>
|
||||
<span><kbd>↵</kbd> select</span>
|
||||
<span><kbd>esc</kbd> close</span>
|
||||
<span><kbd>↑↓</kbd> ${t("overview.palette.footer.navigate")}</span>
|
||||
<span><kbd>↵</kbd> ${t("overview.palette.footer.select")}</span>
|
||||
<span><kbd>esc</kbd> ${t("overview.palette.footer.close")}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { html } from "lit";
|
||||
import { t } from "../../i18n/index.ts";
|
||||
import { renderCopyButton } from "../chat/copy-as-markdown.ts";
|
||||
|
||||
async function copyCommand(command: string) {
|
||||
@@ -10,13 +11,14 @@ async function copyCommand(command: string) {
|
||||
}
|
||||
|
||||
export function renderConnectCommand(command: string) {
|
||||
const copyLabel = t("overview.connection.copyCommand");
|
||||
return html`
|
||||
<div
|
||||
class="login-gate__command"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
title="Copy command"
|
||||
aria-label=${`Copy command: ${command}`}
|
||||
title=${copyLabel}
|
||||
aria-label=${t("overview.connection.copyCommandAria", { command })}
|
||||
@click=${async (e: Event) => {
|
||||
if ((e.target as HTMLElement | null)?.closest(".chat-copy-btn")) {
|
||||
return;
|
||||
@@ -32,7 +34,7 @@ export function renderConnectCommand(command: string) {
|
||||
}}
|
||||
>
|
||||
<code>${command}</code>
|
||||
${renderCopyButton(command, "Copy command")}
|
||||
${renderCopyButton(command, copyLabel)}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user