diff --git a/apps/desktop/README.i18n.yaml b/apps/desktop/README.i18n.yaml index f554ad3863..01b1154394 100644 --- a/apps/desktop/README.i18n.yaml +++ b/apps/desktop/README.i18n.yaml @@ -33,8 +33,8 @@ en: 372297005b57a08b zh: 074a635ac17e4362 /deepseek-harness-desktop/installation-ownership: - en: 7cbb1f9e5006bd34 - zh: 01e9e15a75a90450 + en: 160b500cdcd6a39a + zh: 6c267f1762ec3689 /deepseek-harness-desktop/installation-ownership/runtime-and-plugin-activation: en: a1a47b09f4a72ba4 zh: 7b1cf27f0b72cf31 @@ -45,8 +45,8 @@ en: faf7676ba18bbf2f zh: f1d7b75ad348c548 /deepseek-harness-desktop/develop/startup-onboarding: - en: d87d51b901b72ecd - zh: 525da1c4d56af659 + en: 67dc7ef3e293236a + zh: 1b224db684a2d1d7 /deepseek-harness-desktop/develop/welcome-window-appearance: en: 617a89aeb28131b9 zh: 4d84bd5d86501c86 diff --git a/apps/desktop/README.md b/apps/desktop/README.md index 931401ec77..1d5292c68b 100644 --- a/apps/desktop/README.md +++ b/apps/desktop/README.md @@ -152,7 +152,7 @@ The product UI retains Web actions, including "Open In..." through the shared au Update copy preserves the complete version, including prerelease suffixes, without adding v or V. When no update is available, the dialog title reports the result and the body shows the current version. -Electron chooses typed English, Chinese, or Japanese shell copy from its application locale and falls back to English. The macOS application bundle declares English, Simplified Chinese, and Japanese in `CFBundleLocalizations`, allowing macOS to match the initial application language to the user’s preferred languages. Saved Client UI language preferences still take precedence for the main interface. Windows NSIS installer resources live in one JSON file per language under `installer/locales/`; packaging generates NSIS strings and discovers the installer language list from these files. English, Simplified Chinese, and Japanese resources must have matching keys and format placeholders; `pnpm run check:i18n` validates them. The native installer test builds and exercises each configured language. Platform account pages and onboarding artwork use English for languages other than Chinese. On Windows, the main document's language updates desktop menus, recovery and update prompts. The repository Client UI i18n gate checks desktop sources. +Electron chooses typed shell copy in the eight [shipped Client languages](../../packages/client/locale/README.md) from its application locale and falls back to English. The macOS application bundle declares all eight languages in `CFBundleLocalizations`, allowing macOS to match the initial application language to the user’s preferred languages. Saved Client UI language preferences still take precedence for the main interface. Windows NSIS installer resources live in one JSON file per language under `installer/locales/`; packaging generates NSIS strings and discovers the installer language list from these files. All shipped language resources must have matching keys, format placeholders, and command examples; `pnpm run check:i18n` validates them. The native installer test builds and exercises each configured language. Platform account pages and onboarding artwork use English for languages other than Chinese. On Windows, the main document's language updates desktop menus, recovery and update prompts. The repository Client UI i18n gate checks desktop sources. Windows and macOS relay native fullscreen transitions and the state after each page load to the renderer, so overlays can adapt their caption clearance. @@ -220,7 +220,7 @@ Repeated launches and `dsh://open` keep the workspace hidden until the startup c Desktop checks configured model API-key references after the Host starts and before opening the workspace. With no configured key, the welcome window offers the API-key page. Save and continue writes through the existing credential service using the official DeepSeek provider's configured reference, then opens the workspace. Set up later opens the workspace without saving the draft or a completion setting; the next process launch checks credentials again. Back to sign in returns to the entry and clears the unsaved key and validation message. Buttons keep their labels and block competing actions while saving or opening the workspace. The Desktop preload marker suppresses the Web credential dialog, while retaining the Models settings page and the welcome notice. -The welcome window reads the shared `locale.preference` before it appears. An explicit English, Chinese, or Japanese choice wins; otherwise Desktop picks the first supported OS language and falls back to English. The main UI reads the same preference and OS language order through its isolated preload before mounting. Language changes in Settings update the shell’s current dictionary and menu; automatic selection writes no preference. The welcome window has no language selector. +The welcome window reads the shared `locale.preference` before it appears. An explicit supported language choice wins; otherwise Desktop picks the first supported OS language and falls back to English. The main UI reads the same preference and OS language order through its isolated preload before mounting. Language changes in Settings update the shell’s current dictionary and menu; automatic selection writes no preference. The welcome window has no language selector. The browser-login waiting page offers a copy-link action for the current pending authorization, a loading indicator, and cancellation. Clipboard failures leave the copy action available for retry. Copy feedback resets after two seconds; the copied state disables the link until it resets. Welcome text uses Montserrat Light with system fallbacks; large action buttons keep the system font, while text buttons use Montserrat Light. English introductory copy is 24px throughout. Chinese introductory copy is 24px with a 26px product name. Login action buttons are 240px wide with 14px labels. Authorization status headings use 20px Montserrat Regular text. The API-key page uses a 20px heading and a 14px back action, with 84px between the secondary button’s bottom edge and the window bottom. diff --git a/apps/desktop/README.zh.md b/apps/desktop/README.zh.md index 262eee3ac7..c2078e9d30 100644 --- a/apps/desktop/README.zh.md +++ b/apps/desktop/README.zh.md @@ -152,7 +152,7 @@ Electron 拥有 `$DSH_HOME/profiles/desktop`。其 `dependencies` 包含 pnpm 升级文案完整展示版本号(包括预发布后缀),不额外添加 v 或 V。无可用更新时,弹窗标题显示检查结果,正文显示当前版本。 -Electron 根据应用语言选择类型化的英文、中文或日文 shell 文案,并回退到英文。macOS 应用包通过 `CFBundleLocalizations` 声明支持英语、简体中文和日语,让 macOS 根据用户的首选语言匹配初始应用语言。主界面仍优先使用已保存的 Client UI 语言偏好。 Windows NSIS 安装器在 `installer/locales/` 下按语言保存独立 JSON 资源;打包从这些文件生成 NSIS 文案和安装器语言清单。英文、简体中文和日语资源的键与格式占位符必须一致,`pnpm run check:i18n` 负责检查。原生安装器测试逐个构建并验证配置中的语言。账户平台页面和引导插图对中文以外的语言使用英文。在 Windows 上,主文档的语言会更新桌面菜单、恢复与更新提示。仓库 Client UI i18n 检查覆盖桌面端源码。 +Electron 根据应用语言选择类型化的八种[内置 Client 语言](../../packages/client/locale/README.zh.md)的 shell 文案,并回退到英文。macOS 应用包通过 `CFBundleLocalizations` 声明支持全部八种语言,让 macOS 根据用户的首选语言匹配初始应用语言。主界面仍优先使用已保存的 Client UI 语言偏好。Windows NSIS 安装器在 `installer/locales/` 下按语言保存独立 JSON 资源;打包从这些文件生成 NSIS 文案和安装器语言清单。全部内置语言资源的键、格式占位符和命令示例必须一致,`pnpm run check:i18n` 负责检查。原生安装器测试逐个构建并验证配置中的语言。账户平台页面和引导插图对中文以外的语言使用英文。在 Windows 上,主文档的语言会更新桌面菜单、恢复与更新提示。仓库 Client UI i18n 检查覆盖桌面端源码。 Windows 和 macOS 会在原生全屏切换及每次页面加载后向渲染器同步全屏状态,让浮层调整顶栏避让距离。 @@ -220,7 +220,7 @@ API Key 输入框初始为空,并通过 `autocomplete="new-password"` 请求 C Desktop 在 Host 启动后、打开工作区前检查模型 API Key 引用是否已配置。没有已配置的密钥时,欢迎窗口提供 API Key 页面。“保存并继续”通过现有凭证服务写入 DeepSeek 官方提供方配置的引用,然后打开工作区。“稍后配置”打开工作区,但不保存草稿或完成标记;下次进程启动时会重新检查凭证。“返回登录”回到入口并清空未保存的密钥和校验提示。保存或打开工作区期间,按钮保持原文案并禁用竞争操作。Desktop preload 标记使 Web 凭证弹窗不再显示,同时保留模型设置页和欢迎须知。 -欢迎窗口在显示前读取共享的 `locale.preference`。用户明确选择的英文、中文或日文优先;否则 Desktop 按系统语言顺序匹配支持的语言,并以英文兜底。主界面在挂载前通过隔离 preload 读取同一偏好和系统语言顺序。在设置中切换语言会更新桌面壳的当前词典和菜单;自动选择不会写入偏好。欢迎窗口不提供语言切换入口。 +欢迎窗口在显示前读取共享的 `locale.preference`。用户明确选择的受支持语言优先;否则 Desktop 按系统语言顺序匹配支持的语言,并以英文兜底。主界面在挂载前通过隔离 preload 读取同一偏好和系统语言顺序。在设置中切换语言会更新桌面壳的当前词典和菜单;自动选择不会写入偏好。欢迎窗口不提供语言切换入口。 等待浏览器登录时,欢迎页提供当前待授权请求的链接复制入口、加载指示和取消操作;剪贴板写入失败后可以重试复制,复制结果提示在两秒后恢复;已复制状态下链接禁用,恢复后可再次点击。Welcome 文字使用 Montserrat Light 并回退到系统字体,底部大按钮保留系统字体,文字按钮使用 Montserrat Light。英文欢迎正文及产品名均为 24px,中文欢迎正文为 24px、产品名为 26px。登录操作按钮宽 240px,文字为 14px。授权状态标题使用 20px Montserrat Regular 字重。API Key 页的标题为 20px,返回操作为 14px,次级按钮底边距窗口底部 84px。 diff --git a/apps/desktop/installer/locales/de_DE.json b/apps/desktop/installer/locales/de_DE.json new file mode 100644 index 0000000000..faf725b88e --- /dev/null +++ b/apps/desktop/installer/locales/de_DE.json @@ -0,0 +1,40 @@ +{ + "nsisLanguage": "GERMAN", + "strings": { + "INSTALLER_INSTALL": "Jetzt installieren", + "INSTALLER_FINISH": "Fertigstellen", + "INSTALLER_NATIVE_PROGRESS": "Installation wird vorbereitet… %d%%", + "INSTALLER_PROGRESS_EXTRACT": "Dateien extrahieren… %d%%", + "INSTALLER_PROGRESS_COPY": "Dateien werden installiert… %d%%", + "INSTALLER_PROGRESS_REGISTER": "Abschluss der Installation… %d%%", + "INSTALLER_PROGRESS_CLEAN": "Bereinigen temporärer Dateien… %d%%", + "INSTALLER_CHOOSE_PATH": "Standort wählen", + "INSTALLER_BROWSE": "Durchsuchen", + "INSTALLER_LAUNCH": "Jetzt starten", + "INSTALLER_LAUNCH_FAILED": "DeepSeek Harness konnte nicht gestartet werden. Versuchen Sie es noch einmal oder deaktivieren Sie „Jetzt starten“ und schließen Sie das Installationsprogramm.", + "INSTALLER_UI_ERROR": "Das Installationsprogramm konnte sein Fenster nicht initialisieren. Schließen Sie es und versuchen Sie es erneut.", + "INSTALLER_THEME_ERROR": "Verwenden Sie /THEME=auto, /THEME=light oder /THEME=dark.", + "INSTALLER_FAILED": "Die Installation wurde nicht abgeschlossen. Schließen Sie dieses Installationsprogramm und versuchen Sie es erneut. Wenn das Problem weiterhin besteht, laden Sie das Installationsprogramm erneut herunter.", + "INSTALLER_RUNNING": "DeepSeek Harness läuft. Beenden Sie es über die Taskleiste und versuchen Sie es erneut.", + "INSTALLER_DIRECTORY_FAILED": "Das Installationsverzeichnis konnte nicht ersetzt werden.", + "INSTALLER_DIRECTORY_HINT": "Überprüfen Sie den Zugriff auf das Installationsverzeichnis und schließen Sie Programme mithilfe seiner Dateien. Führen Sie dann das Installationsprogramm erneut aus. Kopieren Sie die Fehlerdetails, wenn das Problem weiterhin besteht.", + "INSTALLER_DIRECTORY_RESTORE_HINT": "Die vorherige Installation konnte nicht wiederhergestellt werden. Behalten Sie das in den Fehlerdetails angezeigte Sicherungsverzeichnis bei und wenden Sie sich vor der erneuten Installation an den Support.", + "INSTALLER_PATH_INVALID": "Wählen Sie einen vollständigen lokalen Ordnerpfad. Laufwerksstämme, Systemordner, Links und Sonderzeichen werden nicht unterstützt.", + "INSTALLER_PATH_OWNERSHIP": "Wählen Sie einen leeren Ordner oder den registrierten DeepSeek Harness-Installationsordner.", + "INSTALLER_PATH_WRITABLE": "Dieser Ort ist nicht beschreibbar. Wählen Sie einen Ordner, der für den aktuellen Benutzer verfügbar ist.", + "INSTALLER_DISK_SPACE": "Es ist nicht genügend freier Speicherplatz vorhanden. Wählen Sie einen anderen Standort.", + "INSTALLER_PER_USER": "Dieses Installationsprogramm unterstützt nur den aktuellen Benutzer. Deinstallieren Sie zunächst die vorhandene All-User-Installation.", + "INSTALLER_EXTRACT_FAILED": "Die Anwendungsdateien konnten nicht extrahiert werden.", + "INSTALLER_EXTRACT_HINT": "Möglicherweise hat die Sicherheitssoftware eine Datei blockiert oder die Festplatte ist voll. Schließen Sie dieses Installationsprogramm und versuchen Sie es erneut. Wenn es weiterhin fehlschlägt, senden Sie uns die Fehlerdetails unten.", + "INSTALLER_EXTRACT_COPY": "Fehlerdetails kopieren", + "INSTALLER_EXTRACT_EXPAND": "Details anzeigen", + "INSTALLER_EXTRACT_COLLAPSE": "Details ausblenden", + "INSTALLER_EXTRACT_SAVED": "Der vollständige Bericht wurde unter %s gespeichert", + "INSTALLER_EXTRACT_UNSAVED": "Der vollständige Bericht konnte nicht gespeichert werden. Verwenden Sie „Fehlerdetails kopieren“, um sie beizubehalten.", + "INSTALLER_EXTRACT_COPIED": "Fehlerdetails wurden in die Zwischenablage kopiert." + }, + "uninstaller": { + "welcome": "Willkommen", + "finished": "entfernt worden" + } +} diff --git a/apps/desktop/installer/locales/es_ES.json b/apps/desktop/installer/locales/es_ES.json new file mode 100644 index 0000000000..c160a1db5a --- /dev/null +++ b/apps/desktop/installer/locales/es_ES.json @@ -0,0 +1,40 @@ +{ + "nsisLanguage": "SPANISH", + "strings": { + "INSTALLER_INSTALL": "Instalar ahora", + "INSTALLER_FINISH": "Finalizar", + "INSTALLER_NATIVE_PROGRESS": "Preparando la instalación… %d%%", + "INSTALLER_PROGRESS_EXTRACT": "Extrayendo archivos… %d%%", + "INSTALLER_PROGRESS_COPY": "Instalando archivos… %d%%", + "INSTALLER_PROGRESS_REGISTER": "Terminando la instalación… %d%%", + "INSTALLER_PROGRESS_CLEAN": "Limpieza de archivos temporales… %d%%", + "INSTALLER_CHOOSE_PATH": "Elige ubicación", + "INSTALLER_BROWSE": "Examinar", + "INSTALLER_LAUNCH": "Lanzar ahora", + "INSTALLER_LAUNCH_FAILED": "No se pudo iniciar DeepSeek Harness. Vuelva a intentarlo o desmarque Iniciar ahora y cierre el instalador.", + "INSTALLER_UI_ERROR": "El instalador no pudo inicializar su ventana. Ciérralo y vuelve a intentarlo.", + "INSTALLER_THEME_ERROR": "Utilice /THEME=auto, /THEME=light o /THEME=dark.", + "INSTALLER_FAILED": "La instalación no terminó. Cierre este instalador y vuelva a intentarlo. Si el problema persiste, descargue el instalador nuevamente.", + "INSTALLER_RUNNING": "DeepSeek Harness se está ejecutando. Salga de la bandeja del sistema y vuelva a intentarlo.", + "INSTALLER_DIRECTORY_FAILED": "No se pudo reemplazar el directorio de instalación.", + "INSTALLER_DIRECTORY_HINT": "Verifique el acceso al directorio de instalación y cierre los programas usando sus archivos, luego ejecute el instalador nuevamente. Copie los detalles del error si el problema persiste.", + "INSTALLER_DIRECTORY_RESTORE_HINT": "No se pudo restaurar la instalación anterior. Mantenga el directorio de respaldo que se muestra en los detalles del error y comuníquese con el soporte antes de volver a instalar.", + "INSTALLER_PATH_INVALID": "Elija una ruta de carpeta local completa. No se admiten raíces de unidades, carpetas del sistema, enlaces ni caracteres especiales.", + "INSTALLER_PATH_OWNERSHIP": "Elija una carpeta vacía o la carpeta de instalación registrada de DeepSeek Harness.", + "INSTALLER_PATH_WRITABLE": "Esta ubicación no se puede escribir. Elija una carpeta disponible para el usuario actual.", + "INSTALLER_DISK_SPACE": "No hay suficiente espacio libre en disco. Elija otra ubicación.", + "INSTALLER_PER_USER": "Este instalador solo admite el usuario actual. Primero desinstale la instalación existente para todos los usuarios.", + "INSTALLER_EXTRACT_FAILED": "No se pudieron extraer los archivos de la aplicación.", + "INSTALLER_EXTRACT_HINT": "Es posible que el software de seguridad haya bloqueado un archivo o que el disco esté lleno. Cierra este instalador y vuelve a intentarlo. Si sigue fallando, envíenos los detalles del error a continuación.", + "INSTALLER_EXTRACT_COPY": "Copiar detalles del error", + "INSTALLER_EXTRACT_EXPAND": "Mostrar detalles", + "INSTALLER_EXTRACT_COLLAPSE": "Ocultar detalles", + "INSTALLER_EXTRACT_SAVED": "El informe completo se guardó en %s.", + "INSTALLER_EXTRACT_UNSAVED": "No se pudo guardar el informe completo. Utilice Copiar detalles del error para conservarlo.", + "INSTALLER_EXTRACT_COPIED": "Los detalles del error se copiaron al portapapeles." + }, + "uninstaller": { + "welcome": "Bienvenido", + "finished": "ha sido desinstalado" + } +} diff --git a/apps/desktop/installer/locales/fr_FR.json b/apps/desktop/installer/locales/fr_FR.json new file mode 100644 index 0000000000..326ead62a8 --- /dev/null +++ b/apps/desktop/installer/locales/fr_FR.json @@ -0,0 +1,40 @@ +{ + "nsisLanguage": "FRENCH", + "strings": { + "INSTALLER_INSTALL": "Installer maintenant", + "INSTALLER_FINISH": "Terminer", + "INSTALLER_NATIVE_PROGRESS": "Préparation de l'installation… %d%%", + "INSTALLER_PROGRESS_EXTRACT": "Extraction de fichiers… %d%%", + "INSTALLER_PROGRESS_COPY": "Installation des fichiers… %d%%", + "INSTALLER_PROGRESS_REGISTER": "Finition de l'installation… %d%%", + "INSTALLER_PROGRESS_CLEAN": "Nettoyage des fichiers temporaires… %d%%", + "INSTALLER_CHOOSE_PATH": "Choisissez un emplacement", + "INSTALLER_BROWSE": "Parcourir", + "INSTALLER_LAUNCH": "Lancez-vous maintenant", + "INSTALLER_LAUNCH_FAILED": "DeepSeek Harness n'a pas pu être lancé. Réessayez ou désactivez Lancer maintenant et fermez le programme d'installation.", + "INSTALLER_UI_ERROR": "Le programme d'installation n'a pas pu initialiser sa fenêtre. Fermez-le et réessayez.", + "INSTALLER_THEME_ERROR": "Utilisez /THEME=auto, /THEME=light ou /THEME=dark.", + "INSTALLER_FAILED": "L'installation n'est pas terminée. Fermez ce programme d'installation et réessayez. Si le problème persiste, téléchargez à nouveau le programme d'installation.", + "INSTALLER_RUNNING": "DeepSeek Harness est en cours d'exécution. Quittez-le de la barre d'état système et réessayez.", + "INSTALLER_DIRECTORY_FAILED": "Le répertoire d'installation n'a pas pu être remplacé.", + "INSTALLER_DIRECTORY_HINT": "Vérifiez l'accès au répertoire d'installation et fermez les programmes à l'aide de ses fichiers, puis réexécutez le programme d'installation. Copiez les détails de l'erreur si le problème persiste.", + "INSTALLER_DIRECTORY_RESTORE_HINT": "L'installation précédente n'a pas pu être restaurée. Conservez le répertoire de sauvegarde indiqué dans les détails de l'erreur et contactez l'assistance avant de procéder à une nouvelle installation.", + "INSTALLER_PATH_INVALID": "Choisissez un chemin de dossier local complet. Les racines du lecteur, les dossiers système, les liens et les caractères spéciaux ne sont pas pris en charge.", + "INSTALLER_PATH_OWNERSHIP": "Choisissez un dossier vide ou le dossier d'installation DeepSeek Harness enregistré.", + "INSTALLER_PATH_WRITABLE": "Cet emplacement n'est pas accessible en écriture. Choisissez un dossier disponible pour l'utilisateur actuel.", + "INSTALLER_DISK_SPACE": "Il n'y a pas assez d'espace disque libre. Choisissez un autre emplacement.", + "INSTALLER_PER_USER": "Ce programme d'installation prend en charge uniquement l'utilisateur actuel. Désinstallez d’abord l’installation existante pour tous les utilisateurs.", + "INSTALLER_EXTRACT_FAILED": "Les fichiers de l'application n'ont pas pu être extraits.", + "INSTALLER_EXTRACT_HINT": "Un logiciel de sécurité a peut-être bloqué un fichier ou le disque est peut-être plein. Fermez ce programme d'installation et réessayez. Si l'échec persiste, envoyez-nous les détails de l'erreur ci-dessous.", + "INSTALLER_EXTRACT_COPY": "Copier les détails de l'erreur", + "INSTALLER_EXTRACT_EXPAND": "Afficher les détails", + "INSTALLER_EXTRACT_COLLAPSE": "Masquer les détails", + "INSTALLER_EXTRACT_SAVED": "Le rapport complet a été enregistré dans %s", + "INSTALLER_EXTRACT_UNSAVED": "Le rapport complet n'a pas pu être enregistré. Utilisez Copier les détails de l'erreur pour le conserver.", + "INSTALLER_EXTRACT_COPIED": "Les détails de l'erreur ont été copiés dans le presse-papiers." + }, + "uninstaller": { + "welcome": "Bienvenue", + "finished": "a été supprimé" + } +} diff --git a/apps/desktop/installer/locales/pt_BR.json b/apps/desktop/installer/locales/pt_BR.json new file mode 100644 index 0000000000..dda249e46f --- /dev/null +++ b/apps/desktop/installer/locales/pt_BR.json @@ -0,0 +1,40 @@ +{ + "nsisLanguage": "PORTUGUESEBR", + "strings": { + "INSTALLER_INSTALL": "Instale agora", + "INSTALLER_FINISH": "Concluir", + "INSTALLER_NATIVE_PROGRESS": "Preparando a instalação… %d%%", + "INSTALLER_PROGRESS_EXTRACT": "Extraindo arquivos… %d%%", + "INSTALLER_PROGRESS_COPY": "Instalando arquivos… %d%%", + "INSTALLER_PROGRESS_REGISTER": "Concluindo a instalação… %d%%", + "INSTALLER_PROGRESS_CLEAN": "Limpando arquivos temporários… %d%%", + "INSTALLER_CHOOSE_PATH": "Escolha o local", + "INSTALLER_BROWSE": "Procurar", + "INSTALLER_LAUNCH": "Lançar agora", + "INSTALLER_LAUNCH_FAILED": "DeepSeek Harness não pôde ser iniciado. Tente novamente ou desmarque Iniciar agora e feche o instalador.", + "INSTALLER_UI_ERROR": "O instalador não conseguiu inicializar sua janela. Feche-o e tente novamente.", + "INSTALLER_THEME_ERROR": "Use /THEME=auto, /THEME=light ou /THEME=dark.", + "INSTALLER_FAILED": "A instalação não foi concluída. Feche este instalador e tente novamente. Se o problema persistir, baixe o instalador novamente.", + "INSTALLER_RUNNING": "DeepSeek Harness está em execução. Saia da bandeja do sistema e tente novamente.", + "INSTALLER_DIRECTORY_FAILED": "O diretório de instalação não pôde ser substituído.", + "INSTALLER_DIRECTORY_HINT": "Verifique o acesso ao diretório de instalação e feche os programas usando seus arquivos e execute o instalador novamente. Copie os detalhes do erro se o problema persistir.", + "INSTALLER_DIRECTORY_RESTORE_HINT": "A instalação anterior não pôde ser restaurada. Mantenha o diretório de backup mostrado nos detalhes do erro e entre em contato com o suporte antes de instalar novamente.", + "INSTALLER_PATH_INVALID": "Escolha um caminho completo para a pasta local. Raízes de unidade, pastas de sistema, links e caracteres especiais não são suportados.", + "INSTALLER_PATH_OWNERSHIP": "Escolha uma pasta vazia ou a pasta de instalação DeepSeek Harness registrada.", + "INSTALLER_PATH_WRITABLE": "Este local não é gravável. Escolha uma pasta disponível para o usuário atual.", + "INSTALLER_DISK_SPACE": "Não há espaço livre suficiente em disco. Escolha outro local.", + "INSTALLER_PER_USER": "Este instalador oferece suporte apenas ao usuário atual. Desinstale primeiro a instalação existente para todos os usuários.", + "INSTALLER_EXTRACT_FAILED": "Os arquivos do aplicativo não puderam ser extraídos.", + "INSTALLER_EXTRACT_HINT": "O software de segurança pode ter bloqueado um arquivo ou o disco pode estar cheio. Feche este instalador e tente novamente. Se continuar falhando, envie-nos os detalhes do erro abaixo.", + "INSTALLER_EXTRACT_COPY": "Copiar detalhes do erro", + "INSTALLER_EXTRACT_EXPAND": "Mostrar detalhes", + "INSTALLER_EXTRACT_COLLAPSE": "Ocultar detalhes", + "INSTALLER_EXTRACT_SAVED": "O relatório completo foi salvo em %s", + "INSTALLER_EXTRACT_UNSAVED": "Não foi possível salvar o relatório completo. Use Copiar detalhes do erro para mantê-lo.", + "INSTALLER_EXTRACT_COPIED": "Os detalhes do erro foram copiados para a área de transferência." + }, + "uninstaller": { + "welcome": "Bem-vindo", + "finished": "foi desinstalado" + } +} diff --git a/apps/desktop/installer/locales/ru_RU.json b/apps/desktop/installer/locales/ru_RU.json new file mode 100644 index 0000000000..e5fec3f8d1 --- /dev/null +++ b/apps/desktop/installer/locales/ru_RU.json @@ -0,0 +1,40 @@ +{ + "nsisLanguage": "RUSSIAN", + "strings": { + "INSTALLER_INSTALL": "Установить сейчас", + "INSTALLER_FINISH": "Готово", + "INSTALLER_NATIVE_PROGRESS": "Подготовка установки… %d%%", + "INSTALLER_PROGRESS_EXTRACT": "Извлечение файлов… %d%%", + "INSTALLER_PROGRESS_COPY": "Установка файлов… %d%%", + "INSTALLER_PROGRESS_REGISTER": "Завершение установки… %d%%", + "INSTALLER_PROGRESS_CLEAN": "Очистка временных файлов… %d%%", + "INSTALLER_CHOOSE_PATH": "Выберите местоположение", + "INSTALLER_BROWSE": "Обзор", + "INSTALLER_LAUNCH": "Запустить сейчас", + "INSTALLER_LAUNCH_FAILED": "DeepSeek Harness не удалось запустить. Повторите попытку или снимите флажок «Запустить сейчас» и закройте программу установки.", + "INSTALLER_UI_ERROR": "Установщику не удалось инициализировать свое окно. Закройте его и попробуйте еще раз.", + "INSTALLER_THEME_ERROR": "Используйте /THEME=auto, /THEME=light или /THEME=dark.", + "INSTALLER_FAILED": "Установка не завершена. Закройте этот установщик и повторите попытку. Если проблема не устранена, загрузите установщик еще раз.", + "INSTALLER_RUNNING": "DeepSeek Harness работает. Закройте его из системного трея и повторите попытку.", + "INSTALLER_DIRECTORY_FAILED": "Не удалось заменить каталог установки.", + "INSTALLER_DIRECTORY_HINT": "Проверьте доступ к каталогу установки и закройте программы, использующие его файлы, затем снова запустите установщик. Скопируйте сведения об ошибке, если проблема не устранена.", + "INSTALLER_DIRECTORY_RESTORE_HINT": "Предыдущую установку восстановить не удалось. Сохраните каталог резервной копии, указанный в сведениях об ошибке, и обратитесь в службу поддержки перед повторной установкой.", + "INSTALLER_PATH_INVALID": "Выберите полный путь к локальной папке. Корни дисков, системные папки, ссылки и специальные символы не поддерживаются.", + "INSTALLER_PATH_OWNERSHIP": "Выберите пустую папку или зарегистрированную папку установки DeepSeek Harness.", + "INSTALLER_PATH_WRITABLE": "Это местоположение недоступно для записи. Выберите папку, доступную текущему пользователю.", + "INSTALLER_DISK_SPACE": "Недостаточно свободного места на диске. Выберите другое место.", + "INSTALLER_PER_USER": "Этот установщик поддерживает только текущего пользователя. Сначала удалите существующую установку для всех пользователей.", + "INSTALLER_EXTRACT_FAILED": "Файлы приложения не удалось извлечь.", + "INSTALLER_EXTRACT_HINT": "Возможно, программное обеспечение безопасности заблокировало файл или диск переполнен. Закройте этот установщик и повторите попытку. Если ошибка продолжает возникать, отправьте нам сведения об ошибке ниже.", + "INSTALLER_EXTRACT_COPY": "Скопировать сведения об ошибке", + "INSTALLER_EXTRACT_EXPAND": "Показать детали", + "INSTALLER_EXTRACT_COLLAPSE": "Скрыть детали", + "INSTALLER_EXTRACT_SAVED": "Полный отчет сохранен в %s.", + "INSTALLER_EXTRACT_UNSAVED": "Полный отчет не удалось сохранить. Используйте Скопировать сведения об ошибке, чтобы сохранить их.", + "INSTALLER_EXTRACT_COPIED": "Подробности об ошибке скопированы в буфер обмена." + }, + "uninstaller": { + "welcome": "Вас приветствует мастер удаления", + "finished": "удалена" + } +} diff --git a/apps/desktop/scripts/electron-builder-config.mjs b/apps/desktop/scripts/electron-builder-config.mjs index 4444b68ae1..d396ae55f1 100644 --- a/apps/desktop/scripts/electron-builder-config.mjs +++ b/apps/desktop/scripts/electron-builder-config.mjs @@ -165,7 +165,7 @@ export function createElectronBuilderConfig( category: 'public.app-category.developer-tools', // macOS matches the application locale against this bundle, not Electron Framework resources. extendInfo: { - CFBundleLocalizations: ['en', 'zh_CN', 'ja'], + CFBundleLocalizations: ['en', 'zh_CN', 'ja', 'es', 'fr', 'de', 'ru', 'pt'], NSMicrophoneUsageDescription: 'DeepSeek Harness uses your microphone to transcribe speech into message drafts.', }, // Ad-hoc signing keeps the modified Electron executable runnable without a Developer ID. diff --git a/apps/desktop/scripts/installer-locales.mjs b/apps/desktop/scripts/installer-locales.mjs index f9f9b55138..539f2b163a 100644 --- a/apps/desktop/scripts/installer-locales.mjs +++ b/apps/desktop/scripts/installer-locales.mjs @@ -34,7 +34,7 @@ export function readInstallerLocales(directory = defaultDirectory) { return { id: name.slice(0, -5), nsisLanguage: resource.nsisLanguage, strings, uninstaller: dictionary('uninstaller' in resource ? resource.uninstaller : undefined) } }) - for (const id of ['en_US', 'zh_CN', 'ja_JP']) { + for (const id of ['en_US', 'zh_CN', 'ja_JP', 'es_ES', 'fr_FR', 'de_DE', 'ru_RU', 'pt_BR']) { if (!locales.some(locale => locale.id === id)) throw new Error(`installer locales: missing ${id}.json`) } const english = locales.find(locale => locale.id === 'en_US') @@ -49,8 +49,8 @@ export function readInstallerLocales(directory = defaultDirectory) { const actual = locale[field] if (Object.keys(expected).sort().join(',') !== Object.keys(actual).sort().join(',')) throw new Error(`${locale.id}: ${field} keys differ from English`) for (const [key, text] of Object.entries(expected)) { - const placeholders = (/** @type {string} */ value) => (value.match(/%.?/gu) ?? []).join(',') - if (placeholders(text) !== placeholders(actual[key])) throw new Error(`${locale.id}: ${key} changes format placeholders`) + const placeholders = (/** @type {string} */ value) => (value.match(/%.?|(? +/** Spanish dictionary, checked against the English keys. */ +export const es = { + cliCommandMenu: 'Administrar el comando dsh…', + cliCommandTitle: 'Administrar el comando dsh', + cliCommandLocation: 'Comando de escritorio: {path}', + cliCommandSelected: 'Comando dsh actual: {path}', + cliCommandTarget: 'Objetivo actual del lanzador: {path}', + cliCommandShadowed: 'Otro dsh tiene prioridad. Elimine o reordene esa instalación para usar el comando Escritorio de forma predeterminada. También puede ejecutar el comando Escritorio por su ruta completa.', + cliCommandSelectionUnknown: 'No se pudo verificar su comando de shell. Un alias u otra instalación de dsh puede tener prioridad.', + cliCommandInstalled: 'El comando Escritorio está instalado.', + cliCommandNotInstalled: 'Agregue el comando Escritorio a su terminal.', + cliCommandBroken: 'El comando de escritorio necesita reparación.', + cliCommandInstall: 'Instalar', + cliCommandRepair: 'Reparación', + cliCommandRemove: 'Quitar', + cliCommandClose: 'Cerrar', + cliCommandSwitch: '¿Continuar con el comando Escritorio?', + cliCommandPreserve: 'Se conservará un comando existente. Otras instalaciones y archivos de inicio del shell no se modificarán.', + cliCommandContinue: 'Continuar', + cliCommandInstallApp: 'Instale Desktop en su carpeta de Aplicaciones antes de administrar el comando dsh.', + cliCommandUpdating: 'Se está instalando una actualización. Administre el comando una vez finalizada la instalación.', + cliCommandNewTerminal: 'Abra una nueva terminal y ejecute dsh --version.', + cliCommandRemoved: 'Se eliminó el registro de comandos de escritorio.', + cliCommandPreviousRestored: 'El lanzador anterior ha sido restaurado.', + cliCommandOtherKept: 'Otras instalaciones de mando se han dejado en su lugar.', + cliCommandBackupKept: 'Se conserva un lanzador anterior en: {path}', + cliCommandChanged: 'El comando o RUTA cambió mientras este cuadro de diálogo estaba abierto. Abra Administrar comando dsh nuevamente para revisar el estado actual.', + cliCommandOwnershipError: 'El registro del comando o la copia de seguridad cambió. No se eliminó ningún comando no relacionado.', + cliCommandFailed: 'El comando no se pudo actualizar. Verifique que la aplicación esté instalada y que se pueda escribir en el destino, luego vuelva a intentarlo.', + application: 'Solicitud', + fileMenu: 'Archivo', + closePage: 'Cerrar página o ventana', + aboutMenu: 'Acerca de DeepSeek Harness', + aboutProduct: 'DeepSeek Harness', + aboutVersion: 'Versión V{version}', + hideApplication: 'Ocultar DeepSeek Harness', + hideOtherApplications: 'Ocultar otros', + showAllApplications: 'Mostrar todo', + quitApplication: 'Salir de DeepSeek Harness', + openApplication: 'Abrir DeepSeek Harness', + quit: 'dejar de fumar', + cancel: 'Cancelar', + quitTitle: '¿Salir de DeepSeek Harness?', + quitActiveTasks: 'Las tareas en ejecución se interrumpirán.', + quitScheduledTasks: 'Las tareas programadas no se ejecutarán mientras la aplicación esté cerrada.', + quitActiveAndScheduledTasks: 'Las tareas en ejecución se interrumpirán y las tareas programadas no se ejecutarán mientras la aplicación esté cerrada.', + backgroundNoticeBody: 'Las tareas en ejecución continuarán. Puede volver a abrir la ventana desde la bandeja del sistema.', + backgroundNoticeConfirm: 'Confirmar', + edit: 'Editar', + menuBar: 'Menú de aplicaciones', + delete: 'Eliminar', + undo: 'Deshacer', + redo: 'Rehacer', + cut: 'cortar', + copy: 'Copiar', + paste: 'Pegar', + selectAll: 'Seleccionar todo', + startupFailed: 'DeepSeek Harness no está disponible', + fatalSummary: 'La aplicación no pudo iniciarse o se detuvo inesperadamente.', + startupAddressInUse: 'Se está ejecutando otra instancia de DSH (como la web de dsh o la aplicación de escritorio). No pueden empezar al mismo tiempo. Salga de la otra instancia DSH en ejecución y luego reinicie.', + diagnosticTruncated: '… Detalles del error acortados.', + reportWrittenTo: 'Informe de diagnóstico: {path}', + startupReinstallAdvice: 'Si faltan archivos de la aplicación o están dañados, ciérrela y vuelva a instalarla. Sus tareas se almacenan por separado.', + exitApplication: 'Salir', + restartApplication: 'Reiniciar', + recoveryOperationFailed: 'La operación de recuperación falló', + disableThirdPartyPlugins: 'Deshabilite los complementos de terceros, haga una copia de seguridad del parche del perfil y reinicie', + welcomeTitle: 'DeepSeek Harness', + welcomeBrand: 'DeepSeek Harness', + welcomeTaglineBefore: 'Bienvenido a ', + welcomeTaglineBrand: 'DeepSeek Harness', + welcomeTaglineAfter: '', + welcomeDescription: 'Desarrollar potencial. Explora la inteligencia.', + welcomeAuthStarting: 'Abriendo inicio de sesión…', + welcomeAuthWaiting: '¿El navegador no se abrió automáticamente?', + welcomeAuthWaitingDescription: 'Copie el enlace de inicio de sesión y ábralo en su navegador para iniciar sesión.', + welcomeAuthExchanging: 'Completando el inicio de sesión…', + welcomeAuthExpired: 'Se agotó el tiempo de inicio de sesión', + welcomeAuthExpiredDescription: 'Inicia sesión nuevamente para continuar', + welcomeAuthFailed: 'No se pudo completar el inicio de sesión. Inténtelo de nuevo.', + welcomeAuthCopyLink: 'Copiar enlace de inicio de sesión', + welcomeAuthCopied: 'Copiado', + welcomeAuthCopyFailed: 'No se pudo copiar. Intentar otra vez.', + welcomeAuthCancel: 'Cancelar', + welcomeAuthRetry: 'Iniciar sesión nuevamente', + welcomeSignIn: 'Iniciar sesión', + welcomeApiKey: 'Agregar clave API', + welcomeKeyTitle: 'Agregue una clave API para comenzar', + welcomeKeyDescription: 'Configura los modelos oficiales DeepSeek para empezar a utilizar Harness', + welcomeKeyPlaceholder: 'Ingrese la clave API', + welcomeKeySave: 'Guardar y continuar', + welcomeKeyLater: 'Configurar más tarde', + welcomeKeyBack: 'Volver para iniciar sesión', + welcomeSessionExpired: 'Has cerrado sesión en tu cuenta, inicia sesión nuevamente.', + welcomeKeyBlank: 'Ingrese una clave API.', + welcomeKeyInvalid: 'Ingrese la clave API, sin comillas, espacios ni una asignación de variable de entorno.', + welcomeKeyFailed: 'No se pudo guardar la clave API. Por favor inténtalo de nuevo.', + welcomeContinueFailed: 'No se pudo abrir el espacio de trabajo. Por favor inténtalo de nuevo.', + checkUpdatesMenu: 'Buscar actualizaciones...', + reloadPageMenu: 'Recargar página', + restartAppHostMenu: 'Reiniciar la aplicación y el host', + updateCheckFailedTitle: 'Error en la comprobación de actualización', + updateCheckFailed: 'No se pudo buscar actualizaciones. Inténtelo de nuevo más tarde.', + updateDownloadFailed: 'No se pudo descargar la actualización. Por favor inténtalo de nuevo.', + updateInstallFailed: 'No se pudo instalar la actualización. Inténtelo de nuevo más tarde.', + updateCheckNetworkFailed: 'No se pudo buscar actualizaciones. Comprueba tu conexión y vuelve a intentarlo.', + updateDownloadNetworkFailed: 'No se pudo descargar la actualización. Comprueba tu conexión y vuelve a intentarlo.', + updateInstallNetworkFailed: 'No se pudo instalar la actualización. Comprueba tu conexión y vuelve a intentarlo.', + unknownError: 'Error desconocido', + updateCheckTitle: 'Buscar actualizaciones', + updateCurrentDetail: 'Versión actual: {version}', + updateCurrent: '¡Estás al día!', + updateChecking: 'Buscando actualizaciones...', + updateDownload: 'Descargar actualización', + updateDownloadedTitle: 'La versión {version} está lista para instalar.', + updateDownloadedDetail: 'La aplicación se cerrará durante la actualización y se volverá a abrir automáticamente cuando se complete.', + updateDownloadedDetailWindows: 'La aplicación se cerrará temporalmente durante la actualización y se volverá a abrir automáticamente cuando se complete.\n\nLa actualización puede tardar algún tiempo. Espere y no vuelva a iniciar la aplicación durante la instalación.', + updateClose: 'Cerrar', + updateAcknowledge: 'OK', + updateLater: 'Actualizar más tarde', + updateDownloading: 'Descargando {percent}%…', + updateVerifying: 'Verificando archivos de actualización...', + updateInstalling: 'Preparándose para reiniciar…', + updateRetry: 'Reintentar actualización', + updateActiveTasks: 'Las tareas aún están en progreso', + updateActiveTasksDetail: 'La actualización detendrá las tareas en curso y reiniciará la aplicación. ¿Continuar?', + updateStopTasks: 'Detener tareas y actualizar', + updateTasksChanged: 'Han comenzado nuevas tareas. Confirme nuevamente para detener las tareas y actualizar.', + updateTasksUnavailable: 'El estado de la tarea no está disponible. Intente actualizar nuevamente cuando el espacio de trabajo esté listo.', + updateFullscreenTimeout: 'No se pudo salir de la pantalla completa. Salga de la pantalla completa y luego vuelva a intentar la actualización.', + updateStopFailed: 'No se pudieron detener las tareas de forma segura. La actualización no se ha instalado. Inténtelo de nuevo más tarde.', + updateTechnicalDetails: 'Ver detalles técnicos', + updateTitle: 'Actualización DeepSeek Harness', + updateAvailable: 'Nueva versión disponible: {version}', + updateDetail: 'Una vez que se completa la descarga, puede instalar la actualización y reiniciar la aplicación.', + installAndRestart: 'Instalar y reiniciar', + later: 'Más tarde', + updateFailedTitle: 'Actualización fallida', + mandatoryTitle: 'Actualizar para continuar', + mandatoryDetail: 'Esta versión ya no es compatible. Actualiza para continuar. Las tareas en curso seguirán ejecutándose hasta que confirme la instalación y reinicie.', + mandatoryUnavailable: 'No se pudieron verificar los requisitos de actualización. Inténtelo de nuevo más tarde.', + policyLoginTitle: 'Inicie sesión en el entorno de prueba', + policyLoginRequired: 'Inicie sesión con Feishu para verificar los requisitos de actualización para esta versión de prueba. Iniciar sesión no descargará ni instalará una actualización.', + policyLogin: 'Iniciar sesión con Feishu', + policyLoginFailed: 'El inicio de sesión de Feishu no se completó. Por favor inténtalo de nuevo.', + policyLoginLoading: 'Cargando página de inicio de sesión...', + mandatoryNoRelease: 'No se encontró ninguna actualización compatible. Verifique nuevamente o comuníquese con el soporte.', + mandatoryRefresh: 'comprobar de nuevo', + mandatoryPage: 'Descargar desde el sitio web oficial.', + mandatoryCopy: 'Copiar enlace de descarga', + mandatoryPageFailed: 'No se pudo abrir la página de descarga oficial. Copie el enlace y ábralo en su navegador.', + mandatoryViewDownload: 'Abrir página de descarga', + mandatoryViewPageFailed: 'No se pudo abrir la página de descarga. Por favor inténtalo de nuevo.', + mandatoryActionFailed: 'La acción fracasó. Por favor inténtalo de nuevo. Puede utilizar la aplicación nuevamente una vez completada la actualización.', + mandatoryReady: 'Actualización lista', + mandatoryVersion: 'Nueva versión: {version}', + mandatoryReadyDetail: 'La aplicación se cerrará durante la actualización y se volverá a abrir automáticamente cuando se complete.', + mandatoryDeferred: 'Las tareas en curso seguirán ejecutándose. Complete la actualización antes de volver a utilizar la aplicación.', + mandatoryContinue: 'Continuar actualizando', + mandatoryInspecting: 'Comprobando tareas...', + mandatoryStopping: 'Deteniendo tareas…', + mandatoryRestarting: 'La aplicación se reiniciará en breve. Espere por favor.', + mandatoryDownloadFailed: 'Los archivos de actualización no se pudieron descargar ni preparar. Vuelva a intentarlo.', + mandatoryInstallFailed: 'La actualización no se ha instalado. Verifique las tareas nuevamente y vuelva a intentarlo.', + mandatoryOpenHelp: '¿La página no se abrió?', + mandatoryReopen: 'Abre la página de descarga oficial nuevamente.', + mandatoryCopied: 'Enlace copiado', + mandatoryCopyFailed: 'No se pudo copiar el enlace. Selecciónelo y cópielo a continuación.', + mandatoryAddress: 'Enlace de descarga', + mandatoryNotification: 'Regrese a la aplicación para confirmar la instalación y reiniciar.', +} satisfies DesktopMessages + +/** French dictionary, checked against the English keys. */ +export const fr = { + cliCommandMenu: 'Gérer la commande dsh…', + cliCommandTitle: 'Gérer la commande dsh', + cliCommandLocation: 'Commande de bureau : {path}', + cliCommandSelected: 'Commande dsh actuelle : {path}', + cliCommandTarget: 'Cible actuelle du lanceur : {path}', + cliCommandShadowed: 'Un autre dsh est prioritaire. Supprimez ou réorganisez cette installation pour utiliser la commande Bureau par défaut. Vous pouvez également exécuter la commande Desktop par son chemin complet.', + cliCommandSelectionUnknown: "Votre commande shell n'a pas pu être vérifiée. Un alias ou une autre installation dsh peut être prioritaire.", + cliCommandInstalled: 'La commande Bureau est installée.', + cliCommandNotInstalled: 'Ajoutez la commande Bureau à votre terminal.', + cliCommandBroken: 'La commande Bureau doit être réparée.', + cliCommandInstall: 'Installer', + cliCommandRepair: 'Réparation', + cliCommandRemove: 'Supprimer', + cliCommandClose: 'Fermer', + cliCommandSwitch: 'Continuer avec la commande Bureau ?', + cliCommandPreserve: 'Une commande existante sera conservée. Les autres installations et fichiers de démarrage du shell ne seront pas modifiés.', + cliCommandContinue: 'Continuer', + cliCommandInstallApp: 'Installez Desktop dans votre dossier Applications avant de gérer la commande dsh.', + cliCommandUpdating: "Une mise à jour est en cours d'installation. Gérez la commande une fois l'installation terminée.", + cliCommandNewTerminal: 'Ouvrez un nouveau terminal et exécutez dsh --version.', + cliCommandRemoved: 'Enregistrement des commandes de bureau supprimé.', + cliCommandPreviousRestored: 'Le lanceur précédent a été restauré.', + cliCommandOtherKept: "D'autres installations de commandement ont été laissées en place.", + cliCommandBackupKept: 'Un lanceur précédent est conservé à : {path}', + cliCommandChanged: "La commande ou PATH a changé pendant que cette boîte de dialogue était ouverte. Ouvrez à nouveau la commande Gérer dsh pour vérifier l'état actuel.", + cliCommandOwnershipError: "L'enregistrement ou la sauvegarde de la commande a été modifiée. Aucune commande sans rapport n'a été supprimée.", + cliCommandFailed: "La commande n'a pas pu être mise à jour. Vérifiez que l'application est installée et que la destination est accessible en écriture, puis réessayez.", + application: 'Demande', + fileMenu: 'Fichier', + closePage: 'Fermer la page ou la fenêtre', + aboutMenu: 'À propos de DeepSeek Harness', + aboutProduct: 'DeepSeek Harness', + aboutVersion: 'VersionV{version}', + hideApplication: 'Masquer DeepSeek Harness', + hideOtherApplications: 'Masquer les autres', + showAllApplications: 'Afficher tout', + quitApplication: 'Quitter DeepSeek Harness', + openApplication: 'Ouvrir DeepSeek Harness', + quit: 'Quitter', + cancel: 'Annuler', + quitTitle: 'Quitter DeepSeek Harness ?', + quitActiveTasks: 'Les tâches en cours seront interrompues.', + quitScheduledTasks: "Les tâches planifiées ne s'exécuteront pas lorsque l'application est fermée.", + quitActiveAndScheduledTasks: "Les tâches en cours d'exécution seront interrompues et les tâches planifiées ne s'exécuteront pas tant que l'application sera fermée.", + backgroundNoticeBody: "Les tâches en cours continueront. Vous pouvez rouvrir la fenêtre à partir de la barre d'état système.", + backgroundNoticeConfirm: 'Confirmer', + edit: 'Modifier', + menuBar: 'Menu des applications', + delete: 'Supprimer', + undo: 'Annuler', + redo: 'Refaire', + cut: 'Couper', + copy: 'Copier', + paste: 'Coller', + selectAll: 'Sélectionner tout', + startupFailed: "DeepSeek Harness n'est pas disponible", + fatalSummary: "L'application n'a pas pu démarrer ou s'est arrêtée de manière inattendue.", + startupAddressInUse: "Une autre instance DSH (telle que le Web dsh ou l'application de bureau) est en cours d'exécution. Ils ne peuvent pas démarrer en même temps. Quittez l'autre instance DSH en cours d'exécution, puis redémarrez.", + diagnosticTruncated: '… Détails de l’erreur raccourcis.', + reportWrittenTo: 'Rapport de diagnostic : {path}', + startupReinstallAdvice: "Si les fichiers de l'application sont manquants ou endommagés, fermez l'application et réinstallez-la. Vos tâches sont stockées séparément.", + exitApplication: 'Quitter', + restartApplication: 'Redémarrer', + recoveryOperationFailed: "L'opération de récupération a échoué", + disableThirdPartyPlugins: 'Désactivez les plugins tiers, sauvegardez le correctif de profil et redémarrez', + welcomeTitle: 'DeepSeek Harness', + welcomeBrand: 'DeepSeek Harness', + welcomeTaglineBefore: 'Bienvenue à ', + welcomeTaglineBrand: 'DeepSeek Harness', + welcomeTaglineAfter: '', + welcomeDescription: "Développer le potentiel. Explorez l'intelligence.", + welcomeAuthStarting: 'Ouverture de la connexion…', + welcomeAuthWaiting: "Le navigateur ne s'est pas ouvert automatiquement ?", + welcomeAuthWaitingDescription: 'Copiez le lien de connexion et ouvrez-le dans votre navigateur pour vous connecter.', + welcomeAuthExchanging: 'Connexion terminée…', + welcomeAuthExpired: 'La connexion a expiré', + welcomeAuthExpiredDescription: 'Connectez-vous à nouveau pour continuer', + welcomeAuthFailed: 'Impossible de terminer la connexion. Veuillez réessayer.', + welcomeAuthCopyLink: 'Copier le lien de connexion', + welcomeAuthCopied: 'Copié', + welcomeAuthCopyFailed: 'Impossible de copier. Essayer à nouveau.', + welcomeAuthCancel: 'Annuler', + welcomeAuthRetry: 'Connectez-vous à nouveau', + welcomeSignIn: 'Connectez-vous', + welcomeApiKey: 'Ajouter une clé API', + welcomeKeyTitle: 'Ajoutez une clé API pour commencer', + welcomeKeyDescription: 'Configurez les modèles DeepSeek officiels pour commencer à utiliser Harness', + welcomeKeyPlaceholder: 'Entrez la clé API', + welcomeKeySave: 'Enregistrer et continuer', + welcomeKeyLater: 'Configurer plus tard', + welcomeKeyBack: 'Retour pour vous connecter', + welcomeSessionExpired: 'Vous vous êtes déconnecté de votre compte, veuillez vous reconnecter.', + welcomeKeyBlank: 'Entrez une clé API.', + welcomeKeyInvalid: "Entrez la clé API elle-même, sans guillemets, espaces ni affectation de variable d'environnement.", + welcomeKeyFailed: "Impossible d'enregistrer la clé API. Veuillez réessayer.", + welcomeContinueFailed: "Impossible d'ouvrir l'espace de travail. Veuillez réessayer.", + checkUpdatesMenu: 'Vérifiez les mises à jour…', + reloadPageMenu: 'Recharger la page', + restartAppHostMenu: "Redémarrez l'application et l'hôte", + updateCheckFailedTitle: 'Échec de la vérification de la mise à jour', + updateCheckFailed: 'Impossible de vérifier les mises à jour. Veuillez réessayer plus tard.', + updateDownloadFailed: 'Impossible de télécharger la mise à jour. Veuillez réessayer.', + updateInstallFailed: "Impossible d'installer la mise à jour. Veuillez réessayer plus tard.", + updateCheckNetworkFailed: 'Impossible de vérifier les mises à jour. Vérifiez votre connexion et réessayez.', + updateDownloadNetworkFailed: 'Impossible de télécharger la mise à jour. Vérifiez votre connexion et réessayez.', + updateInstallNetworkFailed: "Impossible d'installer la mise à jour. Vérifiez votre connexion et réessayez.", + unknownError: 'Erreur inconnue', + updateCheckTitle: 'Vérifier les mises à jour', + updateCurrentDetail: 'Version actuelle : {version}', + updateCurrent: 'Vous êtes à jour !', + updateChecking: 'Vérification des mises à jour…', + updateDownload: 'Télécharger la mise à jour', + updateDownloadedTitle: 'La version {version} est prête à installer', + updateDownloadedDetail: "L'application se fermera pendant la mise à jour et rouvrira automatiquement une fois celle-ci terminée.", + updateDownloadedDetailWindows: "L'application se fermera temporairement pendant la mise à jour et rouvrira automatiquement une fois celle-ci terminée.\n\nLa mise à jour peut prendre un certain temps. Veuillez patienter et ne pas relancer l'application pendant l'installation.", + updateClose: 'Fermer', + updateAcknowledge: 'OK', + updateLater: 'Mettre à jour plus tard', + updateDownloading: 'Téléchargement de {percent}%…', + updateVerifying: 'Vérification des fichiers de mise à jour…', + updateInstalling: 'Préparation du redémarrage…', + updateRetry: 'Réessayez la mise à jour', + updateActiveTasks: 'Les tâches sont toujours en cours', + updateActiveTasksDetail: "La mise à jour arrêtera les tâches en cours et redémarrera l'application. Continuer?", + updateStopTasks: 'Arrêter les tâches et mettre à jour', + updateTasksChanged: 'De nouvelles tâches ont commencé. Confirmez à nouveau pour arrêter les tâches et mettre à jour.', + updateTasksUnavailable: "L'état de la tâche n'est pas disponible. Essayez à nouveau de mettre à jour lorsque l'espace de travail est prêt.", + updateFullscreenTimeout: 'Impossible de quitter le mode plein écran. Quittez le mode plein écran, puis réessayez la mise à jour.', + updateStopFailed: "Impossible d'arrêter les tâches en toute sécurité. La mise à jour n'a pas été installée. Veuillez réessayer plus tard.", + updateTechnicalDetails: 'Voir les détails techniques', + updateTitle: 'Mise à jour DeepSeek Harness', + updateAvailable: 'Nouvelle version disponible : {version}', + updateDetail: "Une fois le téléchargement terminé, vous pouvez installer la mise à jour et redémarrer l'application.", + installAndRestart: 'Installer et redémarrer', + later: 'Plus tard', + updateFailedTitle: 'Échec de la mise à jour', + mandatoryTitle: 'Mettre à jour pour continuer', + mandatoryDetail: "Cette version n'est plus prise en charge. Mettez à jour pour continuer. Les tâches en cours continueront à s'exécuter jusqu'à ce que vous confirmiez l'installation et redémarriez.", + mandatoryUnavailable: 'Impossible de vérifier les exigences de mise à jour. Veuillez réessayer plus tard.', + policyLoginTitle: "Connectez-vous à l'environnement de test", + policyLoginRequired: 'Connectez-vous avec Feishu pour vérifier les exigences de mise à jour pour cette version de test. La connexion ne téléchargera ni n’installera de mise à jour.', + policyLogin: 'Connectez-vous avec Feishu', + policyLoginFailed: 'La connexion à Feishu n’a pas abouti. Veuillez réessayer.', + policyLoginLoading: 'Chargement de la page de connexion…', + mandatoryNoRelease: "Aucune mise à jour compatible n'a été trouvée. Vérifiez à nouveau ou contactez l'assistance.", + mandatoryRefresh: 'Vérifiez à nouveau', + mandatoryPage: 'Télécharger depuis le site officiel', + mandatoryCopy: 'Copier le lien de téléchargement', + mandatoryPageFailed: "Impossible d'ouvrir la page de téléchargement officielle. Copiez le lien et ouvrez-le dans votre navigateur.", + mandatoryViewDownload: 'Ouvrir la page de téléchargement', + mandatoryViewPageFailed: "Impossible d'ouvrir la page de téléchargement. Veuillez réessayer.", + mandatoryActionFailed: "L'action a échoué. Veuillez réessayer. Vous pourrez réutiliser l'application une fois la mise à jour terminée.", + mandatoryReady: 'Mise à jour prête', + mandatoryVersion: 'Nouvelle version : {version}', + mandatoryReadyDetail: "L'application se fermera pendant la mise à jour et rouvrira automatiquement une fois celle-ci terminée.", + mandatoryDeferred: "Les tâches en cours continueront à s'exécuter. Terminez la mise à jour avant d'utiliser à nouveau l'application.", + mandatoryContinue: 'Continuer la mise à jour', + mandatoryInspecting: 'Vérification des tâches…', + mandatoryStopping: 'Arrêt des tâches…', + mandatoryRestarting: "L'application redémarrera sous peu. S'il vous plaît, attendez.", + mandatoryDownloadFailed: "Les fichiers de mise à jour n'ont pas pu être téléchargés ou préparés. Veuillez réessayer.", + mandatoryInstallFailed: "La mise à jour n'a pas été installée. Vérifiez à nouveau les tâches et réessayez.", + mandatoryOpenHelp: "La page ne s'est pas ouverte ?", + mandatoryReopen: 'Ouvrez à nouveau la page de téléchargement officielle', + mandatoryCopied: 'Lien copié', + mandatoryCopyFailed: 'Impossible de copier le lien. Sélectionnez-le et copiez-le ci-dessous.', + mandatoryAddress: 'Lien de téléchargement', + mandatoryNotification: "Revenez à l'application pour confirmer l'installation et redémarrer.", +} satisfies DesktopMessages + +/** German dictionary, checked against the English keys. */ +export const de = { + cliCommandMenu: 'dsh-Befehl verwalten…', + cliCommandTitle: 'Verwalten Sie den dsh-Befehl', + cliCommandLocation: 'Desktop-Befehl: {path}', + cliCommandSelected: 'Aktueller dsh-Befehl: {path}', + cliCommandTarget: 'Aktuelles Launcher-Ziel: {path}', + cliCommandShadowed: 'Ein anderer dsh hat Vorrang. Entfernen Sie diese Installation oder ordnen Sie sie neu an, um standardmäßig den Desktop-Befehl zu verwenden. Sie können den Desktop-Befehl auch über seinen vollständigen Pfad ausführen.', + cliCommandSelectionUnknown: 'Ihr Shell-Befehl konnte nicht überprüft werden. Ein Alias ​​oder eine andere dsh-Installation kann Vorrang haben.', + cliCommandInstalled: 'Der Desktop-Befehl ist installiert.', + cliCommandNotInstalled: 'Fügen Sie den Desktop-Befehl zu Ihrem Terminal hinzu.', + cliCommandBroken: 'Der Desktop-Befehl muss repariert werden.', + cliCommandInstall: 'Installieren', + cliCommandRepair: 'Reparieren', + cliCommandRemove: 'Entfernen', + cliCommandClose: 'Schließen', + cliCommandSwitch: 'Mit dem Desktop-Befehl fortfahren?', + cliCommandPreserve: 'Ein vorhandener Befehl bleibt erhalten. Andere Installationen und Shell-Startdateien werden nicht geändert.', + cliCommandContinue: 'Weiter', + cliCommandInstallApp: 'Installieren Sie Desktop in Ihrem Anwendungsordner, bevor Sie den Befehl dsh verwalten.', + cliCommandUpdating: 'Ein Update wird installiert. Verwalten Sie den Befehl nach Abschluss der Installation.', + cliCommandNewTerminal: 'Öffnen Sie ein neues Terminal und führen Sie dsh --version aus.', + cliCommandRemoved: 'Desktop-Befehlsregistrierung entfernt.', + cliCommandPreviousRestored: 'Der vorherige Launcher wurde wiederhergestellt.', + cliCommandOtherKept: 'Andere Befehlsinstallationen wurden beibehalten.', + cliCommandBackupKept: 'Ein früherer Launcher ist unter folgender Adresse erhalten: {path}', + cliCommandChanged: 'Der Befehl oder PATH hat sich geändert, während dieses Dialogfeld geöffnet war. Öffnen Sie den Befehl „dsh verwalten“ erneut, um den aktuellen Status zu überprüfen.', + cliCommandOwnershipError: 'Die Befehlsregistrierung oder Sicherung wurde geändert. Es wurde kein nicht verwandter Befehl entfernt.', + cliCommandFailed: 'Der Befehl konnte nicht aktualisiert werden. Überprüfen Sie, ob die Anwendung installiert ist und das Ziel beschreibbar ist, und versuchen Sie es dann erneut.', + application: 'Bewerbung', + fileMenu: 'Datei', + closePage: 'Seite oder Fenster schließen', + aboutMenu: 'Über DeepSeek Harness', + aboutProduct: 'DeepSeek Harness', + aboutVersion: 'Version V{version}', + hideApplication: 'DeepSeek Harness ausblenden', + hideOtherApplications: 'Andere ausblenden', + showAllApplications: 'Alle anzeigen', + quitApplication: 'Beenden Sie DeepSeek Harness', + openApplication: 'Öffnen Sie DeepSeek Harness', + quit: 'Hör auf', + cancel: 'Abbrechen', + quitTitle: 'DeepSeek Harness beenden?', + quitActiveTasks: 'Laufende Aufgaben werden unterbrochen.', + quitScheduledTasks: 'Geplante Aufgaben werden nicht ausgeführt, während die App geschlossen ist.', + quitActiveAndScheduledTasks: 'Laufende Aufgaben werden unterbrochen und geplante Aufgaben werden nicht ausgeführt, während die App geschlossen ist.', + backgroundNoticeBody: 'Laufende Aufgaben werden fortgesetzt. Sie können das Fenster über die Taskleiste erneut öffnen.', + backgroundNoticeConfirm: 'Bestätigen', + edit: 'Bearbeiten', + menuBar: 'Anwendungsmenü', + delete: 'Löschen', + undo: 'Rückgängig machen', + redo: 'Wiederholen', + cut: 'Schneiden', + copy: 'Kopieren', + paste: 'Einfügen', + selectAll: 'Wählen Sie „Alle“ aus', + startupFailed: 'DeepSeek Harness ist nicht verfügbar', + fatalSummary: 'Die Anwendung konnte nicht gestartet werden oder wurde unerwartet gestoppt.', + startupAddressInUse: 'Eine andere DSH-Instanz (z. B. dsh Web oder die Desktop-App) wird ausgeführt. Sie können nicht gleichzeitig starten. Beenden Sie die andere laufende DSH-Instanz und starten Sie sie neu.', + diagnosticTruncated: '… Fehlerdetails gekürzt.', + reportWrittenTo: 'Diagnosebericht: {path}', + startupReinstallAdvice: 'Wenn Anwendungsdateien fehlen oder beschädigt sind, schließen Sie die Anwendung und installieren Sie sie erneut. Ihre Aufgaben werden separat gespeichert.', + exitApplication: 'Ausstieg', + restartApplication: 'Neustart', + recoveryOperationFailed: 'Der Wiederherstellungsvorgang ist fehlgeschlagen', + disableThirdPartyPlugins: 'Deaktivieren Sie Plugins von Drittanbietern, sichern Sie den Profil-Patch und starten Sie neu', + welcomeTitle: 'DeepSeek Harness', + welcomeBrand: 'DeepSeek Harness', + welcomeTaglineBefore: 'Willkommen bei ', + welcomeTaglineBrand: 'DeepSeek Harness', + welcomeTaglineAfter: '', + welcomeDescription: 'Potenzial aufbauen. Entdecken Sie Intelligenz.', + welcomeAuthStarting: 'Eröffnungsanmeldung…', + welcomeAuthWaiting: 'Browser wurde nicht automatisch geöffnet?', + welcomeAuthWaitingDescription: 'Kopieren Sie den Anmeldelink und öffnen Sie ihn in Ihrem Browser, um sich anzumelden.', + welcomeAuthExchanging: 'Anmeldung wird abgeschlossen…', + welcomeAuthExpired: 'Zeitüberschreitung bei der Anmeldung', + welcomeAuthExpiredDescription: 'Melden Sie sich erneut an, um fortzufahren', + welcomeAuthFailed: 'Die Anmeldung konnte nicht abgeschlossen werden. Bitte versuchen Sie es erneut.', + welcomeAuthCopyLink: 'Anmeldelink kopieren', + welcomeAuthCopied: 'Kopiert', + welcomeAuthCopyFailed: 'Konnte nicht kopiert werden. Versuchen Sie es erneut.', + welcomeAuthCancel: 'Abbrechen', + welcomeAuthRetry: 'Melden Sie sich erneut an', + welcomeSignIn: 'Melden Sie sich an', + welcomeApiKey: 'Fügen Sie den API-Schlüssel hinzu', + welcomeKeyTitle: 'Fügen Sie einen API-Schlüssel hinzu, um loszulegen', + welcomeKeyDescription: 'Konfigurieren Sie offizielle DeepSeek-Modelle für die Verwendung von Harness', + welcomeKeyPlaceholder: 'Geben Sie den Schlüssel API ein', + welcomeKeySave: 'Speichern und fortfahren', + welcomeKeyLater: 'Später einrichten', + welcomeKeyBack: 'Zurück zur Anmeldung', + welcomeSessionExpired: 'Sie haben sich von Ihrem Konto abgemeldet. Bitte melden Sie sich erneut an.', + welcomeKeyBlank: 'Geben Sie einen API-Schlüssel ein.', + welcomeKeyInvalid: 'Geben Sie den API-Schlüssel selbst ein, ohne Anführungszeichen, Leerzeichen oder eine Umgebungsvariablenzuweisung.', + welcomeKeyFailed: 'Der Schlüssel API konnte nicht gespeichert werden. Bitte versuchen Sie es erneut.', + welcomeContinueFailed: 'Der Arbeitsbereich konnte nicht geöffnet werden. Bitte versuchen Sie es erneut.', + checkUpdatesMenu: 'Nach Updates suchen…', + reloadPageMenu: 'Seite neu laden', + restartAppHostMenu: 'Starten Sie App und Host neu', + updateCheckFailedTitle: 'Update-Überprüfung fehlgeschlagen', + updateCheckFailed: 'Es konnte nicht nach Updates gesucht werden. Bitte versuchen Sie es später noch einmal.', + updateDownloadFailed: 'Das Update konnte nicht heruntergeladen werden. Bitte versuchen Sie es erneut.', + updateInstallFailed: 'Das Update konnte nicht installiert werden. Bitte versuchen Sie es später noch einmal.', + updateCheckNetworkFailed: 'Es konnte nicht nach Updates gesucht werden. Überprüfen Sie Ihre Verbindung und versuchen Sie es erneut.', + updateDownloadNetworkFailed: 'Das Update konnte nicht heruntergeladen werden. Überprüfen Sie Ihre Verbindung und versuchen Sie es erneut.', + updateInstallNetworkFailed: 'Das Update konnte nicht installiert werden. Überprüfen Sie Ihre Verbindung und versuchen Sie es erneut.', + unknownError: 'Unbekannter Fehler', + updateCheckTitle: 'Suchen Sie nach Updates', + updateCurrentDetail: 'Aktuelle Version: {version}', + updateCurrent: 'Du bist auf dem Laufenden!', + updateChecking: 'Suche nach Updates…', + updateDownload: 'Update herunterladen', + updateDownloadedTitle: 'Die Version {version} ist zur Installation bereit', + updateDownloadedDetail: 'Die App wird während des Updates geschlossen und nach Abschluss automatisch wieder geöffnet.', + updateDownloadedDetailWindows: 'Die App wird während des Updates vorübergehend geschlossen und nach Abschluss automatisch wieder geöffnet.\n\nDas Update kann einige Zeit dauern. Bitte warten Sie und starten Sie die App während der Installation nicht erneut.', + updateClose: 'Schließen', + updateAcknowledge: 'OK', + updateLater: 'Später aktualisieren', + updateDownloading: '{percent}% wird heruntergeladen…', + updateVerifying: 'Aktualisierungsdateien werden überprüft…', + updateInstalling: 'Neustart wird vorbereitet…', + updateRetry: 'Update erneut versuchen', + updateActiveTasks: 'Aufgaben sind noch in Bearbeitung', + updateActiveTasksDetail: 'Durch die Aktualisierung werden die laufenden Aufgaben gestoppt und die App neu gestartet. Weitermachen?', + updateStopTasks: 'Stoppen Sie Aufgaben und aktualisieren Sie sie', + updateTasksChanged: 'Neue Aufgaben haben begonnen. Bestätigen Sie erneut, um die Aufgaben zu stoppen und zu aktualisieren.', + updateTasksUnavailable: 'Der Aufgabenstatus ist nicht verfügbar. Versuchen Sie erneut, die Aktualisierung durchzuführen, wenn der Arbeitsbereich bereit ist.', + updateFullscreenTimeout: 'Der Vollbildmodus konnte nicht beendet werden. Beenden Sie den Vollbildmodus und versuchen Sie dann erneut, das Update durchzuführen.', + updateStopFailed: 'Die Aufgaben konnten nicht sicher gestoppt werden. Das Update wurde nicht installiert. Bitte versuchen Sie es später noch einmal.', + updateTechnicalDetails: 'Technische Details anzeigen', + updateTitle: 'DeepSeek Harness-Update', + updateAvailable: 'Neue Version verfügbar: {version}', + updateDetail: 'Sobald der Download abgeschlossen ist, können Sie das Update installieren und die App neu starten.', + installAndRestart: 'Installieren und neu starten', + later: 'Später', + updateFailedTitle: 'Aktualisierung fehlgeschlagen', + mandatoryTitle: 'Aktualisieren, um fortzufahren', + mandatoryDetail: 'Diese Version wird nicht mehr unterstützt. Aktualisieren, um fortzufahren. Laufende Aufgaben werden so lange ausgeführt, bis Sie die Installation bestätigen und neu starten.', + mandatoryUnavailable: 'Update-Anforderungen konnten nicht überprüft werden. Bitte versuchen Sie es später noch einmal.', + policyLoginTitle: 'Melden Sie sich bei der Testumgebung an', + policyLoginRequired: 'Melden Sie sich bei Feishu an, um die Update-Anforderungen für diesen Test-Build zu prüfen. Durch die Anmeldung wird kein Update heruntergeladen oder installiert.', + policyLogin: 'Melden Sie sich mit Feishu an', + policyLoginFailed: 'Die Feishu-Anmeldung wurde nicht abgeschlossen. Bitte versuchen Sie es erneut.', + policyLoginLoading: 'Anmeldeseite wird geladen…', + mandatoryNoRelease: 'Es wurde kein kompatibles Update gefunden. Überprüfen Sie es erneut oder wenden Sie sich an den Support.', + mandatoryRefresh: 'Überprüfen Sie es noch einmal', + mandatoryPage: 'Von der offiziellen Website herunterladen', + mandatoryCopy: 'Download-Link kopieren', + mandatoryPageFailed: 'Die offizielle Download-Seite konnte nicht geöffnet werden. Kopieren Sie den Link und öffnen Sie ihn in Ihrem Browser.', + mandatoryViewDownload: 'Download-Seite öffnen', + mandatoryViewPageFailed: 'Die Download-Seite konnte nicht geöffnet werden. Bitte versuchen Sie es erneut.', + mandatoryActionFailed: 'Die Aktion ist fehlgeschlagen. Bitte versuchen Sie es erneut. Nach Abschluss des Updates können Sie die App wieder verwenden.', + mandatoryReady: 'Update bereit', + mandatoryVersion: 'Neue Version: {version}', + mandatoryReadyDetail: 'Die App wird während des Updates geschlossen und nach Abschluss automatisch wieder geöffnet.', + mandatoryDeferred: 'Laufende Aufgaben werden weiterhin ausgeführt. Schließen Sie das Update ab, bevor Sie die App erneut verwenden.', + mandatoryContinue: 'Weiter aktualisieren', + mandatoryInspecting: 'Aufgaben prüfen…', + mandatoryStopping: 'Aufgaben stoppen…', + mandatoryRestarting: 'Die App wird in Kürze neu gestartet. Bitte warten.', + mandatoryDownloadFailed: 'Die Update-Dateien konnten nicht heruntergeladen oder vorbereitet werden. Bitte versuchen Sie es erneut.', + mandatoryInstallFailed: 'Das Update wurde nicht installiert. Überprüfen Sie die Aufgaben erneut und versuchen Sie es erneut.', + mandatoryOpenHelp: 'Seite wurde nicht geöffnet?', + mandatoryReopen: 'Öffnen Sie die offizielle Download-Seite erneut', + mandatoryCopied: 'Link kopiert', + mandatoryCopyFailed: 'Der Link konnte nicht kopiert werden. Wählen Sie es aus und kopieren Sie es unten.', + mandatoryAddress: 'Download-Link', + mandatoryNotification: 'Kehren Sie zur Anwendung zurück, um die Installation zu bestätigen und neu zu starten.', +} satisfies DesktopMessages + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + cliCommandMenu: 'Управление командой dsh…', + cliCommandTitle: 'Управление командой dsh', + cliCommandLocation: 'Команда рабочего стола: {path}', + cliCommandSelected: 'Текущая команда dsh: {path}.', + cliCommandTarget: 'Текущая цель лаунчера: {path}', + cliCommandShadowed: 'Другой dsh имеет приоритет. Удалите или измените порядок установки, чтобы использовать команду «Рабочий стол» по умолчанию. Вы также можете запустить команду «Рабочий стол» по ее полному пути.', + cliCommandSelectionUnknown: 'Не удалось проверить вашу команду оболочки. Псевдоним или другая установка dsh может иметь приоритет.', + cliCommandInstalled: 'Команда «Рабочий стол» установлена.', + cliCommandNotInstalled: 'Добавьте команду «Рабочий стол» в свой терминал.', + cliCommandBroken: 'Команда Desktop требует ремонта.', + cliCommandInstall: 'Установить', + cliCommandRepair: 'Ремонт', + cliCommandRemove: 'Удалить', + cliCommandClose: 'Закрыть', + cliCommandSwitch: 'Продолжить команду «Рабочий стол»?', + cliCommandPreserve: 'Существующая команда будет сохранена. Другие установки и файлы запуска оболочки не будут изменены.', + cliCommandContinue: 'Продолжить', + cliCommandInstallApp: 'Установите Desktop в папку «Приложения», прежде чем управлять командой dsh.', + cliCommandUpdating: 'Идет установка обновления. Управляйте командой после завершения установки.', + cliCommandNewTerminal: 'Откройте новый терминал и запустите dsh --version.', + cliCommandRemoved: 'Регистрация команд рабочего стола удалена.', + cliCommandPreviousRestored: 'Предыдущий лаунчер восстановлен.', + cliCommandOtherKept: 'Остальные командные установки остались на месте.', + cliCommandBackupKept: 'Предыдущий лаунчер сохранился по адресу: {path}.', + cliCommandChanged: 'Команда или PATH изменилась, пока это диалоговое окно было открыто. Откройте команду «Управление dsh» еще раз, чтобы просмотреть текущее состояние.', + cliCommandOwnershipError: 'Регистрация команд или резервное копирование изменены. Ни одна несвязанная команда не была удалена.', + cliCommandFailed: 'Не удалось обновить команду. Убедитесь, что приложение установлено и место назначения доступно для записи, затем повторите попытку.', + application: 'Приложение', + fileMenu: 'Файл', + closePage: 'Закрыть страницу или окно', + aboutMenu: 'О DeepSeek Harness', + aboutProduct: 'DeepSeek Harness', + aboutVersion: 'Версия V{version}', + hideApplication: 'Скрыть DeepSeek Harness', + hideOtherApplications: 'Скрыть других', + showAllApplications: 'Показать все', + quitApplication: 'Выйти из DeepSeek Harness', + openApplication: 'Открыть DeepSeek Harness', + quit: 'Выйти', + cancel: 'Отмена', + quitTitle: 'Выйти из DeepSeek Harness?', + quitActiveTasks: 'Выполнение задач будет прервано.', + quitScheduledTasks: 'Запланированные задачи не будут выполняться, пока приложение закрыто.', + quitActiveAndScheduledTasks: 'Выполнение задач будет прервано, а запланированные задачи не будут выполняться, пока приложение закрыто.', + backgroundNoticeBody: 'Выполнение задач продолжится. Вы можете снова открыть окно из системного трея.', + backgroundNoticeConfirm: 'Подтвердить', + edit: 'Редактировать', + menuBar: 'Меню приложения', + delete: 'Удалить', + undo: 'Отменить', + redo: 'Повторить', + cut: 'Вырезать', + copy: 'Копировать', + paste: 'Вставить', + selectAll: 'Выбрать все', + startupFailed: 'DeepSeek Harness недоступен.', + fatalSummary: 'Приложение не могло запуститься или неожиданно остановилось.', + startupAddressInUse: 'Другой экземпляр DSH (например, веб-приложение dsh или настольное приложение) запущен. Они не могут начаться одновременно. Закройте другой работающий экземпляр DSH, а затем перезапустите.', + diagnosticTruncated: '… Подробности об ошибках сокращены.', + reportWrittenTo: 'Диагностический отчет: {path}', + startupReinstallAdvice: 'Если файлы приложения отсутствуют или повреждены, закройте приложение и переустановите его. Ваши задачи хранятся отдельно.', + exitApplication: 'Выход', + restartApplication: 'Перезапустить', + recoveryOperationFailed: 'Операция восстановления не удалась', + disableThirdPartyPlugins: 'Отключите сторонние плагины, создайте резервную копию патча профиля и перезапустите.', + welcomeTitle: 'DeepSeek Harness', + welcomeBrand: 'DeepSeek Harness', + welcomeTaglineBefore: 'Добро пожаловать в ', + welcomeTaglineBrand: 'DeepSeek Harness', + welcomeTaglineAfter: '', + welcomeDescription: 'Развивайте потенциал. Исследуйте интеллект.', + welcomeAuthStarting: 'Открытие входа в систему…', + welcomeAuthWaiting: 'Браузер не открылся автоматически?', + welcomeAuthWaitingDescription: 'Скопируйте ссылку для входа и откройте ее в браузере, чтобы войти.', + welcomeAuthExchanging: 'Завершение входа…', + welcomeAuthExpired: 'Время входа в систему истекло', + welcomeAuthExpiredDescription: 'Войдите еще раз, чтобы продолжить', + welcomeAuthFailed: 'Не удалось завершить вход. Повторите попытку.', + welcomeAuthCopyLink: 'Скопировать ссылку для входа', + welcomeAuthCopied: 'Скопировано', + welcomeAuthCopyFailed: 'Не удалось скопировать. Попробуйте еще раз.', + welcomeAuthCancel: 'Отмена', + welcomeAuthRetry: 'Войдите снова', + welcomeSignIn: 'Войти', + welcomeApiKey: 'Добавить ключ API', + welcomeKeyTitle: 'Добавьте ключ API, чтобы начать работу.', + welcomeKeyDescription: 'Настройте официальные модели DeepSeek, чтобы начать использовать Harness.', + welcomeKeyPlaceholder: 'Введите ключ API', + welcomeKeySave: 'Сохранить и продолжить', + welcomeKeyLater: 'Настроить позже', + welcomeKeyBack: 'Вернуться для входа в систему', + welcomeSessionExpired: 'Вы вышли из своей учетной записи, пожалуйста, войдите снова.', + welcomeKeyBlank: 'Введите ключ API.', + welcomeKeyInvalid: 'Введите сам ключ API без кавычек, пробелов и присвоения переменной среды.', + welcomeKeyFailed: 'Не удалось сохранить ключ API. Пожалуйста, попробуйте еще раз.', + welcomeContinueFailed: 'Не удалось открыть рабочую область. Пожалуйста, попробуйте еще раз.', + checkUpdatesMenu: 'Проверить наличие обновлений…', + reloadPageMenu: 'Обновить страницу', + restartAppHostMenu: 'Перезапустите приложение и хост.', + updateCheckFailedTitle: 'Проверка обновления не удалась', + updateCheckFailed: 'Не удалось проверить наличие обновлений. Пожалуйста, повторите попытку позже.', + updateDownloadFailed: 'Не удалось загрузить обновление. Пожалуйста, попробуйте еще раз.', + updateInstallFailed: 'Не удалось установить обновление. Пожалуйста, повторите попытку позже.', + updateCheckNetworkFailed: 'Не удалось проверить наличие обновлений. Проверьте подключение и повторите попытку.', + updateDownloadNetworkFailed: 'Не удалось загрузить обновление. Проверьте подключение и повторите попытку.', + updateInstallNetworkFailed: 'Не удалось установить обновление. Проверьте подключение и повторите попытку.', + unknownError: 'Неизвестная ошибка', + updateCheckTitle: 'Проверьте наличие обновлений', + updateCurrentDetail: 'Текущая версия: {version}.', + updateCurrent: 'Вы в курсе!', + updateChecking: 'Проверка обновлений…', + updateDownload: 'Скачать обновление', + updateDownloadedTitle: 'Версия {version} готова к установке.', + updateDownloadedDetail: 'Приложение закроется во время обновления и автоматически откроется после его завершения.', + updateDownloadedDetailWindows: 'Приложение временно закроется во время обновления и автоматически откроется после его завершения.\n\nОбновление может занять некоторое время. Пожалуйста, подождите и не запускайте приложение снова во время установки.', + updateClose: 'Закрыть', + updateAcknowledge: 'OK', + updateLater: 'Обновить позже', + updateDownloading: 'Загрузка {percent}%…', + updateVerifying: 'Проверка файлов обновлений…', + updateInstalling: 'Подготовка к перезапуску…', + updateRetry: 'Повторить обновление', + updateActiveTasks: 'Задачи еще выполняются', + updateActiveTasksDetail: 'Обновление остановит выполняемые задачи и перезапустит приложение. Продолжать?', + updateStopTasks: 'Остановить задачи и обновить', + updateTasksChanged: 'Начались новые задачи. Подтвердите еще раз, чтобы остановить выполнение задач и выполнить обновление.', + updateTasksUnavailable: 'Статус задачи недоступен. Попробуйте обновить еще раз, когда рабочая область будет готова.', + updateFullscreenTimeout: 'Не удалось выйти из полноэкранного режима. Выйдите из полноэкранного режима и повторите попытку обновления.', + updateStopFailed: 'Не удалось безопасно остановить задачи. Обновление не установлено. Пожалуйста, повторите попытку позже.', + updateTechnicalDetails: 'Посмотреть технические подробности', + updateTitle: 'DeepSeek Harness Обновление', + updateAvailable: 'Доступна новая версия: {version}.', + updateDetail: 'После завершения загрузки вы можете установить обновление и перезапустить приложение.', + installAndRestart: 'Установить и перезапустить', + later: 'Позже', + updateFailedTitle: 'Обновление не выполнено', + mandatoryTitle: 'Обновите, чтобы продолжить', + mandatoryDetail: 'Эта версия больше не поддерживается. Обновите, чтобы продолжить. Выполняемые задачи будут продолжать выполняться до тех пор, пока вы не подтвердите установку и не перезапустите.', + mandatoryUnavailable: 'Не удалось проверить требования к обновлению. Пожалуйста, повторите попытку позже.', + policyLoginTitle: 'Войдите в тестовую среду', + policyLoginRequired: 'Войдите в систему с помощью Feishu, чтобы проверить требования к обновлению для этой тестовой сборки. При входе в систему обновление не загружается и не устанавливается.', + policyLogin: 'Войти через Feishu', + policyLoginFailed: 'Вход в Feishu не завершен. Пожалуйста, попробуйте еще раз.', + policyLoginLoading: 'Загрузка страницы входа…', + mandatoryNoRelease: 'Совместимое обновление не найдено. Проверьте еще раз или обратитесь в службу поддержки.', + mandatoryRefresh: 'Проверьте еще раз', + mandatoryPage: 'Скачать с официального сайта', + mandatoryCopy: 'Скопировать ссылку для скачивания', + mandatoryPageFailed: 'Не удалось открыть официальную страницу загрузки. Скопируйте ссылку и откройте ее в браузере.', + mandatoryViewDownload: 'Открыть страницу загрузки', + mandatoryViewPageFailed: 'Не удалось открыть страницу загрузки. Пожалуйста, попробуйте еще раз.', + mandatoryActionFailed: 'Акция провалилась. Пожалуйста, попробуйте еще раз. Вы сможете снова использовать приложение после завершения обновления.', + mandatoryReady: 'Обновление готово', + mandatoryVersion: 'Новая версия: {version}', + mandatoryReadyDetail: 'Приложение закроется во время обновления и автоматически откроется после его завершения.', + mandatoryDeferred: 'Выполняемые задачи будут продолжать выполняться. Завершите обновление, прежде чем снова использовать приложение.', + mandatoryContinue: 'Продолжить обновление', + mandatoryInspecting: 'Проверка задач…', + mandatoryStopping: 'Остановка задач…', + mandatoryRestarting: 'Приложение вскоре перезапустится. Пожалуйста, подождите.', + mandatoryDownloadFailed: 'Файлы обновления не удалось загрузить или подготовить. Пожалуйста, повторите попытку.', + mandatoryInstallFailed: 'Обновление не установлено. Проверьте задачи еще раз и повторите попытку.', + mandatoryOpenHelp: 'Страница не открылась?', + mandatoryReopen: 'Откройте официальную страницу загрузки еще раз.', + mandatoryCopied: 'Ссылка скопирована', + mandatoryCopyFailed: 'Не удалось скопировать ссылку. Выделите и скопируйте его ниже.', + mandatoryAddress: 'Ссылка для скачивания', + mandatoryNotification: 'Вернитесь в приложение, чтобы подтвердить установку и перезапустить.', +} satisfies DesktopMessages + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + cliCommandMenu: 'Gerenciar comando dsh…', + cliCommandTitle: 'Gerenciar comando dsh', + cliCommandLocation: 'Comando da área de trabalho: {path}', + cliCommandSelected: 'Comando dsh atual: {path}', + cliCommandTarget: 'Alvo atual do iniciador: {path}', + cliCommandShadowed: 'Outro dsh tem precedência. Remova ou reordene essa instalação para usar o comando Desktop por padrão. Você também pode executar o comando Desktop pelo caminho completo.', + cliCommandSelectionUnknown: 'Seu comando shell não pôde ser verificado. Um alias ou outra instalação do dsh pode ter precedência.', + cliCommandInstalled: 'O comando Desktop está instalado.', + cliCommandNotInstalled: 'Adicione o comando Desktop ao seu terminal.', + cliCommandBroken: 'O comando Desktop precisa de reparo.', + cliCommandInstall: 'Instalar', + cliCommandRepair: 'Reparar', + cliCommandRemove: 'Remover', + cliCommandClose: 'Fechar', + cliCommandSwitch: 'Continuar com o comando Desktop?', + cliCommandPreserve: 'Um comando existente será preservado. Outras instalações e arquivos de inicialização do shell não serão alterados.', + cliCommandContinue: 'Continuar', + cliCommandInstallApp: 'Instale o Desktop na pasta Aplicativos antes de gerenciar o comando dsh.', + cliCommandUpdating: 'Uma atualização está sendo instalada. Gerencie o comando após a conclusão da instalação.', + cliCommandNewTerminal: 'Abra um novo terminal e execute dsh --version.', + cliCommandRemoved: 'Registro de comando da área de trabalho removido.', + cliCommandPreviousRestored: 'O inicializador anterior foi restaurado.', + cliCommandOtherKept: 'Outras instalações de comando foram mantidas.', + cliCommandBackupKept: 'Um inicializador anterior é preservado em: {path}', + cliCommandChanged: 'O comando ou PATH foi alterado enquanto esta caixa de diálogo estava aberta. Abra o comando Gerenciar dsh novamente para revisar o estado atual.', + cliCommandOwnershipError: 'O registro ou backup do comando foi alterado. Nenhum comando não relacionado foi removido.', + cliCommandFailed: 'O comando não pôde ser atualizado. Verifique se o aplicativo está instalado e se o destino é gravável e tente novamente.', + application: 'Aplicação', + fileMenu: 'Arquivo', + closePage: 'Fechar página ou janela', + aboutMenu: 'Sobre DeepSeek Harness', + aboutProduct: 'DeepSeek Harness', + aboutVersion: 'Versão V{version}', + hideApplication: 'Ocultar DeepSeek Harness', + hideOtherApplications: 'Ocultar outros', + showAllApplications: 'Mostrar tudo', + quitApplication: 'Sair de DeepSeek Harness', + openApplication: 'Abra DeepSeek Harness', + quit: 'Sair', + cancel: 'Cancelar', + quitTitle: 'Sair de DeepSeek Harness?', + quitActiveTasks: 'As tarefas em execução serão interrompidas.', + quitScheduledTasks: 'As tarefas agendadas não serão executadas enquanto o aplicativo estiver fechado.', + quitActiveAndScheduledTasks: 'As tarefas em execução serão interrompidas e as tarefas agendadas não serão executadas enquanto o aplicativo estiver fechado.', + backgroundNoticeBody: 'As tarefas em execução continuarão. Você pode reabrir a janela na bandeja do sistema.', + backgroundNoticeConfirm: 'Confirmar', + edit: 'Editar', + menuBar: 'Menu de aplicativos', + delete: 'Excluir', + undo: 'Desfazer', + redo: 'Refazer', + cut: 'Cortar', + copy: 'Copiar', + paste: 'Colar', + selectAll: 'Selecionar tudo', + startupFailed: 'DeepSeek Harness não está disponível', + fatalSummary: 'O aplicativo não pôde ser iniciado ou parou inesperadamente.', + startupAddressInUse: 'Outra instância DSH (como dsh web ou aplicativo de desktop) está em execução. Eles não podem começar ao mesmo tempo. Saia da outra instância DSH em execução e reinicie.', + diagnosticTruncated: '… Detalhes do erro reduzidos.', + reportWrittenTo: 'Relatório de diagnóstico: {path}', + startupReinstallAdvice: 'Se os arquivos do aplicativo estiverem ausentes ou danificados, feche o aplicativo e reinstale-o. Suas tarefas são armazenadas separadamente.', + exitApplication: 'Sair', + restartApplication: 'Reiniciar', + recoveryOperationFailed: 'A operação de recuperação falhou', + disableThirdPartyPlugins: 'Desative plug-ins de terceiros, faça backup do patch do perfil e reinicie', + welcomeTitle: 'DeepSeek Harness', + welcomeBrand: 'DeepSeek Harness', + welcomeTaglineBefore: 'Bem-vindo ao ', + welcomeTaglineBrand: 'DeepSeek Harness', + welcomeTaglineAfter: '', + welcomeDescription: 'Construir potencial. Explore a inteligência.', + welcomeAuthStarting: 'Abrindo login…', + welcomeAuthWaiting: 'O navegador não abriu automaticamente?', + welcomeAuthWaitingDescription: 'Copie o link de login e abra-o em seu navegador para fazer login.', + welcomeAuthExchanging: 'Concluindo login…', + welcomeAuthExpired: 'O tempo limite de login expirou', + welcomeAuthExpiredDescription: 'Faça login novamente para continuar', + welcomeAuthFailed: 'Não foi possível concluir o login. Tente novamente.', + welcomeAuthCopyLink: 'Copiar link de login', + welcomeAuthCopied: 'Copiado', + welcomeAuthCopyFailed: 'Não foi possível copiar. Tente novamente.', + welcomeAuthCancel: 'Cancelar', + welcomeAuthRetry: 'Faça login novamente', + welcomeSignIn: 'Faça login', + welcomeApiKey: 'Adicionar chave API', + welcomeKeyTitle: 'Adicione uma chave API para começar', + welcomeKeyDescription: 'Configure modelos DeepSeek oficiais para começar a usar o Harness', + welcomeKeyPlaceholder: 'Insira a tecla API', + welcomeKeySave: 'Salvar e continuar', + welcomeKeyLater: 'Configurar mais tarde', + welcomeKeyBack: 'Voltar para fazer login', + welcomeSessionExpired: 'Você saiu da sua conta, faça login novamente.', + welcomeKeyBlank: 'Insira uma chave API.', + welcomeKeyInvalid: 'Insira a própria chave API, sem aspas, espaços ou atribuição de variável de ambiente.', + welcomeKeyFailed: 'Não foi possível salvar a chave API. Por favor, tente novamente.', + welcomeContinueFailed: 'Não foi possível abrir o espaço de trabalho. Por favor, tente novamente.', + checkUpdatesMenu: 'Verifique se há atualizações…', + reloadPageMenu: 'Recarregar página', + restartAppHostMenu: 'Reinicie o aplicativo e o host', + updateCheckFailedTitle: 'Falha na verificação de atualização', + updateCheckFailed: 'Não foi possível verificar se há atualizações. Por favor, tente novamente mais tarde.', + updateDownloadFailed: 'Não foi possível baixar a atualização. Por favor, tente novamente.', + updateInstallFailed: 'Não foi possível instalar a atualização. Por favor, tente novamente mais tarde.', + updateCheckNetworkFailed: 'Não foi possível verificar se há atualizações. Verifique sua conexão e tente novamente.', + updateDownloadNetworkFailed: 'Não foi possível baixar a atualização. Verifique sua conexão e tente novamente.', + updateInstallNetworkFailed: 'Não foi possível instalar a atualização. Verifique sua conexão e tente novamente.', + unknownError: 'Erro desconhecido', + updateCheckTitle: 'Verifique se há atualizações', + updateCurrentDetail: 'Versão atual: {version}', + updateCurrent: 'Você está atualizado!', + updateChecking: 'Verificando atualizações…', + updateDownload: 'Baixar atualização', + updateDownloadedTitle: 'A versão {version} está pronta para instalação', + updateDownloadedDetail: 'O aplicativo será fechado durante a atualização e reaberto automaticamente quando for concluída.', + updateDownloadedDetailWindows: 'O aplicativo será fechado temporariamente durante a atualização e reaberto automaticamente quando for concluída.\n\nA atualização pode levar algum tempo. Aguarde e não inicie o aplicativo novamente durante a instalação.', + updateClose: 'Fechar', + updateAcknowledge: 'OK', + updateLater: 'Atualizar mais tarde', + updateDownloading: 'Baixando {percent}%…', + updateVerifying: 'Verificando arquivos de atualização…', + updateInstalling: 'Preparando para reiniciar…', + updateRetry: 'Tentar atualizar novamente', + updateActiveTasks: 'As tarefas ainda estão em andamento', + updateActiveTasksDetail: 'A atualização interromperá as tarefas em andamento e reiniciará o aplicativo. Continuar?', + updateStopTasks: 'Pare tarefas e atualize', + updateTasksChanged: 'Novas tarefas foram iniciadas. Confirme novamente para interromper as tarefas e atualizar.', + updateTasksUnavailable: 'O status da tarefa não está disponível. Tente atualizar novamente quando o espaço de trabalho estiver pronto.', + updateFullscreenTimeout: 'Não foi possível sair da tela cheia. Saia da tela inteira e tente atualizar novamente.', + updateStopFailed: 'Não foi possível interromper as tarefas com segurança. A atualização não foi instalada. Por favor, tente novamente mais tarde.', + updateTechnicalDetails: 'Ver detalhes técnicos', + updateTitle: 'DeepSeek Harness Atualização', + updateAvailable: 'Nova versão disponível: {version}', + updateDetail: 'Assim que o download for concluído, você pode instalar a atualização e reiniciar o aplicativo.', + installAndRestart: 'Instalar e reiniciar', + later: 'Mais tarde', + updateFailedTitle: 'Falha na atualização', + mandatoryTitle: 'Atualizar para continuar', + mandatoryDetail: 'Esta versão não é mais suportada. Atualize para continuar. As tarefas em andamento continuarão em execução até você confirmar a instalação e reiniciar.', + mandatoryUnavailable: 'Não foi possível verificar os requisitos de atualização. Por favor, tente novamente mais tarde.', + policyLoginTitle: 'Faça login no ambiente de teste', + policyLoginRequired: 'Faça login com Feishu para verificar os requisitos de atualização para esta versão de teste. O login não baixará nem instalará uma atualização.', + policyLogin: 'Faça login com Feishu', + policyLoginFailed: 'O login do Feishu não foi concluído. Por favor, tente novamente.', + policyLoginLoading: 'Carregando página de login…', + mandatoryNoRelease: 'Nenhuma atualização compatível foi encontrada. Verifique novamente ou entre em contato com o suporte.', + mandatoryRefresh: 'Verifique novamente', + mandatoryPage: 'Baixe do site oficial', + mandatoryCopy: 'Copiar link de download', + mandatoryPageFailed: 'Não foi possível abrir a página oficial de download. Copie o link e abra-o no seu navegador.', + mandatoryViewDownload: 'Abrir página de download', + mandatoryViewPageFailed: 'Não foi possível abrir a página de download. Por favor, tente novamente.', + mandatoryActionFailed: 'A ação falhou. Por favor, tente novamente. Você poderá usar o aplicativo novamente após a conclusão da atualização.', + mandatoryReady: 'Atualização pronta', + mandatoryVersion: 'Nova versão: {version}', + mandatoryReadyDetail: 'O aplicativo será fechado durante a atualização e reaberto automaticamente quando for concluída.', + mandatoryDeferred: 'As tarefas em andamento continuarão em execução. Conclua a atualização antes de usar o aplicativo novamente.', + mandatoryContinue: 'Continuar atualização', + mandatoryInspecting: 'Verificando tarefas…', + mandatoryStopping: 'Parando tarefas…', + mandatoryRestarting: 'O aplicativo será reiniciado em breve. Por favor, aguarde.', + mandatoryDownloadFailed: 'Os arquivos de atualização não puderam ser baixados ou preparados. Por favor, tente novamente.', + mandatoryInstallFailed: 'A atualização não foi instalada. Verifique as tarefas novamente e tente novamente.', + mandatoryOpenHelp: 'A página não abriu?', + mandatoryReopen: 'Abra a página oficial de download novamente', + mandatoryCopied: 'Link copiado', + mandatoryCopyFailed: 'Não foi possível copiar o link. Selecione e copie abaixo.', + mandatoryAddress: 'Baixar link', + mandatoryNotification: 'Retorne ao aplicativo para confirmar a instalação e reinicie.', +} satisfies DesktopMessages + /** Locale payload exposed to the Desktop-owned renderer. */ export interface DesktopLocale { - readonly id: 'en' | 'zh-CN' | 'ja' + readonly id: 'en' | 'zh-CN' | 'ja' | 'es' | 'fr' | 'de' | 'ru' | 'pt' readonly messages: DesktopMessages } /** Resolve Electron's locale to one shipped Desktop dictionary. */ export function resolveDesktopLocale(locale: string): DesktopLocale { const primary = locale.toLowerCase().split('-')[0] - if (primary === 'ja') return { id: 'ja', messages: ja } + const dictionaries = { ja, es, fr, de, ru, pt } + if (primary !== undefined && Object.hasOwn(dictionaries, primary)) { + const id = primary as keyof typeof dictionaries + return { id, messages: dictionaries[id] } + } return primary === 'zh' ? { id: 'zh-CN', messages: zh } : { id: 'en', messages: en } @@ -540,10 +1404,10 @@ export function resolveDesktopLocale(locale: string): DesktopLocale { */ export function resolveDesktopStartupLocale(preference: string | null, languages: readonly string[]): DesktopLocale { const selected = preference?.toLowerCase() - if (selected === 'zh' || selected === 'en' || selected === 'ja') return resolveDesktopLocale(selected) + if (selected !== undefined && ['zh', 'en', 'ja', 'es', 'fr', 'de', 'ru', 'pt'].includes(selected)) return resolveDesktopLocale(selected) for (const language of languages) { const primary = language.toLowerCase().split('-')[0] - if (primary === 'zh' || primary === 'en' || primary === 'ja') return resolveDesktopLocale(primary) + if (primary !== undefined && ['zh', 'en', 'ja', 'es', 'fr', 'de', 'ru', 'pt'].includes(primary)) return resolveDesktopLocale(primary) } return resolveDesktopLocale('en') } diff --git a/apps/desktop/tests/installer-locales.spec.ts b/apps/desktop/tests/installer-locales.spec.ts index 4dea51a414..7602679f9b 100644 --- a/apps/desktop/tests/installer-locales.spec.ts +++ b/apps/desktop/tests/installer-locales.spec.ts @@ -8,7 +8,7 @@ import { readInstallerLocales, renderInstallerStrings } from '../scripts/install function fixture(): string { const directory = mkdtempSync(join(tmpdir(), 'dsh-installer-locales-')) onTestFinished(() => { rmSync(directory, { recursive: true, force: true }) }) - for (const id of ['en_US', 'zh_CN', 'ja_JP']) { + for (const id of ['en_US', 'zh_CN', 'ja_JP', 'es_ES', 'fr_FR', 'de_DE', 'ru_RU', 'pt_BR']) { writeFileSync(join(directory, `${id}.json`), readFileSync(new URL(`../installer/locales/${id}.json`, import.meta.url))) } return directory @@ -16,17 +16,17 @@ function fixture(): string { it('generates Japanese NSIS strings from the same files that select packaged languages', () => { const locales = readInstallerLocales() - expect(locales.map(locale => locale.id)).toEqual(['en_US', 'ja_JP', 'zh_CN']) + expect(locales.map(locale => locale.id)).toEqual(['de_DE', 'en_US', 'es_ES', 'fr_FR', 'ja_JP', 'pt_BR', 'ru_RU', 'zh_CN']) const source = renderInstallerStrings(locales) expect(source).toContain('LangString INSTALLER_INSTALL ${LANG_JAPANESE} "今すぐインストール"') expect(source).toContain('LangString INSTALLER_NATIVE_PROGRESS ${LANG_JAPANESE} "インストールを準備しています… %d%%"') expect(source).toContain('!ifdef LANG_JAPANESE\n') - expect(source.match(/^LangString /gmu)).toHaveLength(93) + expect(source.match(/^LangString /gmu)).toHaveLength(248) const japanese = locales.filter(locale => locale.id === 'ja_JP') expect(renderInstallerStrings(japanese)).not.toContain('${LANG_ENGLISH}') }) -it.each(['en_US', 'zh_CN', 'ja_JP'])('rejects a missing %s configuration', (id) => { +it.each(['en_US', 'zh_CN', 'ja_JP', 'es_ES', 'fr_FR', 'de_DE', 'ru_RU', 'pt_BR'])('rejects a missing %s configuration', (id) => { const directory = fixture() rmSync(join(directory, `${id}.json`)) expect(() => readInstallerLocales(directory)).toThrow(`missing ${id}.json`) @@ -39,6 +39,7 @@ it.each([ ['changed placeholder', (resource: ReturnType[number]) => { resource.strings.INSTALLER_NATIVE_PROGRESS = '%s%%' }, 'format placeholders'], ['missing percent escape', (resource: ReturnType[number]) => { resource.strings.INSTALLER_NATIVE_PROGRESS = '%d%' }, 'format placeholders'], ['extra format specifier', (resource: ReturnType[number]) => { resource.strings.INSTALLER_NATIVE_PROGRESS = '%d%% %q' }, 'format placeholders'], + ['translated command', (resource: ReturnType[number]) => { resource.strings.INSTALLER_THEME_ERROR = 'Use /THEME=claro.' }, 'format placeholders'], ['duplicate language', (resource: ReturnType[number]) => { resource.nsisLanguage = 'ENGLISH' }, 'duplicate NSIS language'], ['invalid compiler token', (resource: ReturnType[number]) => { resource.nsisLanguage = 'JA\n!error' }, 'invalid NSIS language'], ])('rejects %s', (_name, mutate, diagnostic) => { diff --git a/apps/desktop/tests/locale.spec.ts b/apps/desktop/tests/locale.spec.ts index eb9f2ccb81..fcf8f747dc 100644 --- a/apps/desktop/tests/locale.spec.ts +++ b/apps/desktop/tests/locale.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { en, formatDesktopMessage, resolveDesktopLocale, resolveDesktopStartupLocale, ja, zh } from '../src/locale.ts' +import { en, formatDesktopMessage, resolveDesktopLocale, resolveDesktopStartupLocale, ja, zh, es, fr, de, ru, pt } from '../src/locale.ts' describe('desktop locale dictionaries', () => { it('ships the same key set in English, Chinese, and Japanese', () => { @@ -8,7 +8,21 @@ describe('desktop locale dictionaries', () => { expect(resolveDesktopLocale('JA-jp')).toEqual({ id: 'ja', messages: ja }) expect(resolveDesktopLocale('zh-Hans-CN').messages).toEqual(zh) expect(resolveDesktopLocale('en-US').messages).toEqual(en) - expect(resolveDesktopLocale('fr-FR').messages).toEqual(en) + expect(resolveDesktopLocale('it-IT').messages).toEqual(en) + }) + + it.each([ + ['es', 'es-MX', es], ['fr', 'fr-CA', fr], ['de', 'de-DE', de], + ['ru', 'ru-RU', ru], ['pt', 'pt-BR', pt], + ] as const)('resolves %s, preserves placeholders, and honors saved preferences', (id, tag, messages) => { + expect(resolveDesktopLocale(tag.toUpperCase())).toEqual({ id, messages }) + expect(resolveDesktopStartupLocale(id, ['zh-CN']).id).toBe(id) + expect(resolveDesktopStartupLocale(null, ['it-IT', tag, 'en-US']).id).toBe(id) + expect(Object.keys(messages)).toEqual(Object.keys(en)) + for (const key of Object.keys(en) as (keyof typeof en)[]) { + const placeholders = (text: string): string[] => (text.match(/\{\w+\}/gu) ?? []).sort() + expect(placeholders(messages[key]), key).toEqual(placeholders(en[key])) + } }) it('formats named values without consuming unknown placeholders', () => { diff --git a/apps/desktop/tests/macos-signature.spec.ts b/apps/desktop/tests/macos-signature.spec.ts index afe2092791..b688a293e7 100644 --- a/apps/desktop/tests/macos-signature.spec.ts +++ b/apps/desktop/tests/macos-signature.spec.ts @@ -51,7 +51,7 @@ describe('desktop macOS release signature', () => { expect(config.protocols).toEqual([{ name: 'DeepSeek Harness', schemes: ['dsh'] }]) expect(portablePath(config.directories.output)).toContain('/.desktop-build/targets/mac-arm64/artifacts') expect(config.mac.extendInfo.NSMicrophoneUsageDescription).toContain('microphone') - expect(config.mac.extendInfo.CFBundleLocalizations).toEqual(['en', 'zh_CN', 'ja']) + expect(config.mac.extendInfo.CFBundleLocalizations).toEqual(['en', 'zh_CN', 'ja', 'es', 'fr', 'de', 'ru', 'pt']) expect(config.mac.entitlementsInherit).toBe(config.mac.entitlements) const entitlements = readFileSync(config.mac.entitlements, 'utf8') for (const key of ['com.apple.security.cs.allow-jit', 'com.apple.security.cs.allow-unsigned-executable-memory', diff --git a/apps/web/tests/additional-locales.e2e.ts b/apps/web/tests/additional-locales.e2e.ts new file mode 100644 index 0000000000..d23b4da924 --- /dev/null +++ b/apps/web/tests/additional-locales.e2e.ts @@ -0,0 +1,58 @@ +/** Shipped language selection, metadata and narrow settings through the assembled Web profile. */ +import { readFile } from 'node:fs/promises' +import { join } from 'node:path' +import { fileURLToPath } from 'node:url' +import { chromium, type Browser } from 'playwright' +import { expect, it, onTestFailed, onTestFinished } from 'vitest' +import { acknowledgeReloadConnectionLoss, captureStableAria, compareOrRefreshGolden, launchWebScaffold, watchConsole, webSnapshotMode, type WebScaffold } from './scaffold.ts' +import { saveFailureShot } from './support.ts' + +const languages = [ + ['es', 'es-MX', 'Menú de cuenta', 'Configuración', 'Complementos', 'Idioma', 'Español'], + ['fr', 'fr-CA', 'Menu du compte', 'Paramètres', 'Plugins', 'Langue', 'Français'], + ['de', 'de-DE', 'Kontomenü', 'Einstellungen', 'Plugins', 'Sprache', 'Deutsch'], + ['ru', 'ru-RU', 'Меню аккаунта', 'Настройки', 'Плагины', 'Язык', 'Русский'], + ['pt', 'pt-BR', 'Menu da conta', 'Configurações', 'Plug-ins', 'Idioma', 'Português'], +] as const + +it.each(languages)('selects %s from the browser, localizes metadata and persists an explicit choice', async (id, tag, accountMenu, settings, plugins, language, label) => { + const resources: { scaffold?: WebScaffold; browser?: Browser } = {} + onTestFinished(async () => { + try { await resources.browser?.close() } finally { await resources.scaffold?.close() } + }) + const scaffold = await launchWebScaffold() + resources.scaffold = scaffold + const browser = await chromium.launch() + resources.browser = browser + const page = await browser.newPage({ locale: tag, viewport: { width: 1440, height: 960 } }) + const tripwire = watchConsole(page) + onTestFailed(() => saveFailureShot(page, `additional-locale-${id}`)) + await page.goto(scaffold.authenticatedUrl) + await expect.poll(() => page.evaluate(() => document.documentElement.lang)).toBe(id) + await page.getByRole('button', { name: plugins, exact: true }).click() + const panel = page.locator('[data-plugin-panel]') + const metadata = JSON.parse(await readFile(new URL(`../../../packages/experimental/auto-review/locale/${id}.json`, import.meta.url), 'utf8')) as { meta: { title: string; description: string } } + await panel.getByText(metadata.meta.title, { exact: true }).waitFor() + await panel.getByText(metadata.meta.description, { exact: true }).waitFor() + await compareOrRefreshGolden(fileURLToPath(new URL(`./expected/additional-locales/${id}.expected.md`, import.meta.url)), + await captureStableAria(page, `[data-plugin-panel] li:has-text(${JSON.stringify(metadata.meta.title)})`, scaffold.workspaceCwd), webSnapshotMode()) + await page.getByRole('button', { name: accountMenu, exact: true }).click() + await page.getByRole('menuitem', { name: settings, exact: true }).click() + const dialog = page.getByRole('dialog', { name: settings, exact: true }) + await dialog.getByText(language, { exact: true }).waitFor() + await dialog.getByRole('button', { name: label, exact: true }).waitFor() + await page.setViewportSize({ width: 390, height: 844 }) + await expect.poll(() => dialog.evaluate((element) => { + const content = element.lastElementChild! + return { panel: element.scrollWidth <= element.clientWidth + 1, content: content.scrollWidth <= content.clientWidth + 1 } + })).toEqual({ panel: true, content: true }) + await dialog.getByRole('button', { name: label, exact: true }).click() + await page.getByRole('menuitem', { name: 'English', exact: true }).click() + await expect.poll(() => readFile(join(scaffold.harnessHome, 'profiles', 'scaffold', 'cordis.patch.yml'), 'utf8')).toContain('preference: en') + const warningsBeforeReload = tripwire.warnings.length + await page.reload() + acknowledgeReloadConnectionLoss(tripwire, warningsBeforeReload) + await expect.poll(() => page.evaluate(() => document.documentElement.lang)).toBe('en') + expect(tripwire.warnings).toEqual([]) + expect(tripwire.pageErrors).toEqual([]) +}) diff --git a/apps/web/tests/desktop-locale.e2e.ts b/apps/web/tests/desktop-locale.e2e.ts index cc43d697f1..4ede5dee36 100644 --- a/apps/web/tests/desktop-locale.e2e.ts +++ b/apps/web/tests/desktop-locale.e2e.ts @@ -21,7 +21,7 @@ describe.skipIf(MODE === 'record')('web e2e: native and Client locale preference let page: Page let tripwire: ReturnType const reported: string[] = [] - let languages = ['fr-FR', 'zh-CN', 'en-US'] + let languages = ['it-IT', 'zh-CN', 'en-US'] beforeAll(async () => { scaffold = await launchWebScaffold() diff --git a/apps/web/tests/expected/additional-locales/de.expected.md b/apps/web/tests/expected/additional-locales/de.expected.md new file mode 100644 index 0000000000..210ffed2fb --- /dev/null +++ b/apps/web/tests/expected/additional-locales/de.expected.md @@ -0,0 +1,5 @@ +- listitem: + - button "Siehe Automatische Autorisierungsüberprüfung": Automatische Autorisierungsüberprüfung + - text: Experimentell Fügen Sie einen Auto review-Berechtigungsmodus hinzu, der das Modell verwendet, um die Autorisierung vor jedem Toolaufruf zu bewerten. + - status + - switch "Aktivieren Sie Automatische Autorisierungsüberprüfung" diff --git a/apps/web/tests/expected/additional-locales/es.expected.md b/apps/web/tests/expected/additional-locales/es.expected.md new file mode 100644 index 0000000000..c1e0233d70 --- /dev/null +++ b/apps/web/tests/expected/additional-locales/es.expected.md @@ -0,0 +1,5 @@ +- listitem: + - button "Ver Revisión de autorización automática": Revisión de autorización automática + - text: Experimental Agregue un modo de permiso Auto review que utilice el modelo para evaluar la autorización antes de cada llamada a la herramienta. + - status + - switch "Habilitar Revisión de autorización automática" diff --git a/apps/web/tests/expected/additional-locales/fr.expected.md b/apps/web/tests/expected/additional-locales/fr.expected.md new file mode 100644 index 0000000000..88c6dad142 --- /dev/null +++ b/apps/web/tests/expected/additional-locales/fr.expected.md @@ -0,0 +1,5 @@ +- listitem: + - button "Voir Examen des autorisations automatiques": Examen des autorisations automatiques + - text: Expérimental Ajoutez un mode d'autorisation Auto review qui utilise le modèle pour évaluer l'autorisation avant chaque appel d'outil. + - status + - switch "Activer Examen des autorisations automatiques" diff --git a/apps/web/tests/expected/additional-locales/pt.expected.md b/apps/web/tests/expected/additional-locales/pt.expected.md new file mode 100644 index 0000000000..1119ad2aa1 --- /dev/null +++ b/apps/web/tests/expected/additional-locales/pt.expected.md @@ -0,0 +1,5 @@ +- listitem: + - button "Ver Revisão de autorização automática": Revisão de autorização automática + - text: Experimental Adicione um modo de permissão Auto review que usa o modelo para avaliar a autorização antes de cada chamada de ferramenta. + - status + - switch "Ativar Revisão de autorização automática" diff --git a/apps/web/tests/expected/additional-locales/ru.expected.md b/apps/web/tests/expected/additional-locales/ru.expected.md new file mode 100644 index 0000000000..e4f02c9c69 --- /dev/null +++ b/apps/web/tests/expected/additional-locales/ru.expected.md @@ -0,0 +1,5 @@ +- listitem: + - button "Посмотреть Проверка автоматической авторизации": Проверка автоматической авторизации + - text: Экспериментальный Добавьте режим разрешений Auto review, который использует модель для оценки авторизации перед каждым вызовом инструмента. + - status + - switch "Включить Проверка автоматической авторизации" diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json index 057a50fbea..35ce38031c 100644 --- a/apps/web/tsconfig.json +++ b/apps/web/tsconfig.json @@ -24,6 +24,7 @@ // cannot see both sides of the cordis Context merges). "exclude": [ "tests/japanese-plugin-metadata.e2e.ts", + "tests/additional-locales.e2e.ts", "tests/rich-text-quotes.e2e.ts", "tests/hover-input.e2e.ts", "tests/collapse-timing.e2e.ts", diff --git a/docs/cookbook/adding-a-package.i18n.yaml b/docs/cookbook/adding-a-package.i18n.yaml index 2f95205489..35b674ff1e 100644 --- a/docs/cookbook/adding-a-package.i18n.yaml +++ b/docs/cookbook/adding-a-package.i18n.yaml @@ -21,8 +21,8 @@ en: 0894bd9f35430753 zh: 2d28090e71134edd /cookbook-adding-a-workspace-package/5-add-optional-plugin-display-metadata: - en: 1238eaea376391d1 - zh: c7e606f95d8980bf + en: 3725e456d5cddfde + zh: e847b8bb65e0a1ea /cookbook-adding-a-workspace-package/6-verify: en: 80c7fb90b1175aae zh: 2ba37962dbc57299 diff --git a/docs/cookbook/adding-a-package.md b/docs/cookbook/adding-a-package.md index 2950932479..7358401366 100644 --- a/docs/cookbook/adding-a-package.md +++ b/docs/cookbook/adding-a-package.md @@ -136,7 +136,7 @@ Merge these entries into `package.json`, retaining existing runtime exports and } ``` -Keep language files together in `locale/`, with `en.json` as the discovery entry. Fields are optional; present values must be non-empty strings. English `meta.title` and `meta.description` use sentence case: capitalize only the first word, proper nouns, and product names, as in `Git worktrees` ([rule](../../.agents/skills/dsh-prose-standard/SKILL.md#required-coverage-by-prose-location)). At runtime, missing files or fields permit fallback, while malformed JSON or invalid fields produce a per-plugin diagnostic. First-party packages and plugin templates must provide `ja.json` covering every field present in `en.json` or optional `zh.json`, preserving placeholders; detail paths may point to the existing English document. Subpath resources under `locale//` follow the same checks. English descriptions explain user-visible behavior and end with sentence punctuation. Run `pnpm run check:i18n` to verify JSON metadata and UI dictionary completeness; the JSON checks also run in `check:all`, CI static checks, and hygiene. +Keep language files together in `locale/`, with `en.json` as the discovery entry. Fields are optional; present values must be non-empty strings. English `meta.title` and `meta.description` use sentence case: capitalize only the first word, proper nouns, and product names, as in `Git worktrees` ([rule](../../.agents/skills/dsh-prose-standard/SKILL.md#required-coverage-by-prose-location)). At runtime, missing files or fields permit fallback, while malformed JSON or invalid fields produce a per-plugin diagnostic. First-party packages and plugin templates must provide `ja.json`, `es.json`, `fr.json`, `de.json`, `ru.json`, and `pt.json` covering every field present in `en.json` or optional `zh.json`, preserving placeholders, slash commands, and API field names; detail paths may point to the existing English document. Subpath resources under `locale//` follow the same checks. English descriptions explain user-visible behavior and end with sentence punctuation. Run `pnpm run check:i18n` to verify JSON metadata and UI dictionary completeness; the JSON checks also run in `check:all`, CI static checks, and hygiene. Fields fall back independently before view-specific name formatting, using the existing locale language chain first: diff --git a/docs/cookbook/adding-a-package.zh.md b/docs/cookbook/adding-a-package.zh.md index 6ab95ce3b3..9a308697c2 100644 --- a/docs/cookbook/adding-a-package.zh.md +++ b/docs/cookbook/adding-a-package.zh.md @@ -136,7 +136,7 @@ Append-only, prefix-stable, replacing, or independent behavior, including the ex } ``` -语言文件统一放在 `locale/`,并保留 `en.json` 作为发现入口。字段可选,填写时必须是非空字符串。英文 `meta.title` 和 `meta.description` 使用 sentence case:只大写首个单词、专有名词和产品名,例如 `Git worktrees`([rule](../../.agents/skills/dsh-prose-standard/SKILL.md#required-coverage-by-prose-location))。运行时文件或字段缺失时允许回退,JSON 损坏或字段无效时显示单插件诊断。仓库内的包和插件模板必须提供 `ja.json`,覆盖 `en.json` 或可选 `zh.json` 中的全部字段并保留占位符;详情路径可指向现有英文文档。`locale//` 下的子路径资源使用相同检查。英文描述面向产品用户说明可见行为,并以句末标点结束。运行 `pnpm run check:i18n` 检查 JSON 元数据和 UI 字典完整性;JSON 检查也接入 `check:all`、CI 静态检查和 hygiene。 +语言文件统一放在 `locale/`,并保留 `en.json` 作为发现入口。字段可选,填写时必须是非空字符串。英文 `meta.title` 和 `meta.description` 使用 sentence case:只大写首个单词、专有名词和产品名,例如 `Git worktrees`([rule](../../.agents/skills/dsh-prose-standard/SKILL.md#required-coverage-by-prose-location))。运行时文件或字段缺失时允许回退,JSON 损坏或字段无效时显示单插件诊断。仓库内的包和插件模板必须提供 `ja.json`、`es.json`、`fr.json`、`de.json`、`ru.json` 和 `pt.json`,覆盖 `en.json` 或可选 `zh.json` 中的全部字段并保留占位符、斜杠命令和 API 字段名;详情路径可指向现有英文文档。`locale//` 下的子路径资源使用相同检查。英文描述面向产品用户说明可见行为,并以句末标点结束。运行 `pnpm run check:i18n` 检查 JSON 元数据和 UI 字典完整性;JSON 检查也接入 `check:all`、CI 静态检查和 hygiene。 各字段先独立回退,再按页面规则格式化技术名称;回退优先经过现有 locale 语言链: diff --git a/docs/upgrade-guide/v0.2.1-rc.2/built-in-japanese/guide.i18n.yaml b/docs/upgrade-guide/v0.2.1-rc.2/built-in-japanese/guide.i18n.yaml index a13ae70849..9e6e37a1bf 100644 --- a/docs/upgrade-guide/v0.2.1-rc.2/built-in-japanese/guide.i18n.yaml +++ b/docs/upgrade-guide/v0.2.1-rc.2/built-in-japanese/guide.i18n.yaml @@ -3,14 +3,14 @@ # After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/upgrade-guide/v0.2.1-rc.2/built-in-japanese/guide.md /: - en: 383326881143f69b - zh: cd7ff0e2b97f9c2f -/japanese-is-a-built-in-language: - en: f97bae63a42a3627 - zh: cec418f8bf6ac168 -/japanese-is-a-built-in-language/change: - en: feb1f2d1cafdcfe0 - zh: 94d527865ec108bb -/japanese-is-a-built-in-language/migration: - en: ced2c2baad9124b4 - zh: 7b0b5b0e345994b8 + en: cfd1ffd2cd268220 + zh: 2ed03b1063f3319d +/built-in-languages-replace-duplicate-language-packs: + en: 5855b69ac12a5f50 + zh: a81de3239837f1c4 +/built-in-languages-replace-duplicate-language-packs/change: + en: 665e68d784661f15 + zh: 2fff6fcfceea7994 +/built-in-languages-replace-duplicate-language-packs/migration: + en: 6f77e0b507e09ca7 + zh: 59e0c71780f06e9e diff --git a/docs/upgrade-guide/v0.2.1-rc.2/built-in-japanese/guide.md b/docs/upgrade-guide/v0.2.1-rc.2/built-in-japanese/guide.md index 256e77ae05..5c6cf0eaea 100644 --- a/docs/upgrade-guide/v0.2.1-rc.2/built-in-japanese/guide.md +++ b/docs/upgrade-guide/v0.2.1-rc.2/built-in-japanese/guide.md @@ -1,18 +1,18 @@ --- kind: upgrade-guide -description: "Built-in Japanese registrations conflict with third-party Japanese language packs." +description: "Built-in language registrations conflict with third-party language packs using the same ids." --- -# Japanese is a built-in language +# Built-in languages replace duplicate language packs English | [中文](guide.zh.md) ## Change -The locale plugin registers the `ja` language and Japanese dictionaries for `common` and `settings.locale`. Third-party language packs following the previous Japanese README example now fail with an already-registered language or dictionary error. +The locale plugin registers `ja`, `es`, `fr`, `de`, `ru`, and `pt`, with dictionaries for `common`, `settings.locale`, and the built-in UI plugins. Third-party language packs using these ids now fail with an already-registered language or dictionary error, including packs based on the earlier Japanese or French README examples. ## Migration -1. In the language pack's client entry, remove `ctx.locale.addLanguage({ id: 'ja', ... })` and registrations for `common` and `settings.locale` under `ja`. Remove other Japanese dictionary registrations whose namespaces are now supplied by built-in plugins; keep translations for namespaces owned by your own plugins. -2. If the pack represents a distinct language variant, register a separate BCP 47-style id, such as `ja-JP`, for both the definition and its dictionaries instead of `ja`. +1. In the language pack's client entry, remove `ctx.locale.addLanguage(...)` for these ids and dictionary registrations in namespaces supplied by built-in plugins. Keep translations for namespaces owned by your own plugins. +2. If the pack represents a distinct language variant, register a separate BCP 47-style id, such as `fr-CA`, for both the definition and its dictionaries instead of the built-in id. 3. Reload the application with the pack enabled. Confirm it starts without duplicate-registration errors and that selecting the intended language displays its translations. diff --git a/docs/upgrade-guide/v0.2.1-rc.2/built-in-japanese/guide.zh.md b/docs/upgrade-guide/v0.2.1-rc.2/built-in-japanese/guide.zh.md index 80382ebe9e..dd98916cc6 100644 --- a/docs/upgrade-guide/v0.2.1-rc.2/built-in-japanese/guide.zh.md +++ b/docs/upgrade-guide/v0.2.1-rc.2/built-in-japanese/guide.zh.md @@ -1,18 +1,18 @@ --- kind: upgrade-guide -description: "内置日语注册会与第三方日语语言包冲突。" +description: "内置语言注册会与使用相同 id 的第三方语言包冲突。" --- -# 日语成为内置语言 +# 内置语言取代重复的语言包 [English](guide.md) | 中文 ## 变更 -locale 插件注册 `ja` 语言,以及 `common` 和 `settings.locale` 的日文字典。按此前 README 日语示例编写的第三方语言包会因语言或字典已注册而加载失败。 +locale 插件注册 `ja`、`es`、`fr`、`de`、`ru` 和 `pt`,并提供 `common`、`settings.locale` 以及内置 UI 插件的字典。使用这些 id 的第三方语言包会因语言或字典已注册而加载失败,包括按此前 README 日语或法语示例编写的语言包。 ## 迁移 -1. 在语言包的 client 入口中,删除 `ctx.locale.addLanguage({ id: 'ja', ... })`,以及 `common` 和 `settings.locale` 下的 `ja` 注册。删除其他已由内置插件提供的命名空间的日语字典注册;保留自己插件所拥有命名空间的翻译。 -2. 如果语言包代表不同的语言变体,为语言定义及其字典注册独立的 BCP 47 风格 id,例如 `ja-JP`,代替 `ja`。 +1. 在语言包的 client 入口中,删除这些 id 的 `ctx.locale.addLanguage(...)`,以及内置插件已提供的命名空间下的字典注册。保留自己插件所拥有命名空间的翻译。 +2. 如果语言包代表不同的语言变体,为语言定义及其字典注册独立的 BCP 47 风格 id,例如 `fr-CA`,代替内置 id。 3. 启用语言包并重新加载应用。确认启动时没有重复注册错误,且选择目标语言后显示对应译文。 diff --git a/packages/acp/acp/locale/de.json b/packages/acp/acp/locale/de.json new file mode 100644 index 0000000000..1d616ae6f6 --- /dev/null +++ b/packages/acp/acp/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "ACP-Server", + "description": "Führen Sie Agenten zur Automatisierung über JSON-RPC über Standardeingabe und -ausgabe aus." + } +} diff --git a/packages/acp/acp/locale/es.json b/packages/acp/acp/locale/es.json new file mode 100644 index 0000000000..4970a451fb --- /dev/null +++ b/packages/acp/acp/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "servidor ACP", + "description": "Ejecute agentes a través de JSON-RPC a través de entrada y salida estándar para automatización." + } +} diff --git a/packages/acp/acp/locale/fr.json b/packages/acp/acp/locale/fr.json new file mode 100644 index 0000000000..a8faaceeaa --- /dev/null +++ b/packages/acp/acp/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Serveur ACP", + "description": "Exécutez les agents via JSON-RPC via une entrée et une sortie standard pour l'automatisation." + } +} diff --git a/packages/acp/acp/locale/pt.json b/packages/acp/acp/locale/pt.json new file mode 100644 index 0000000000..cad2b3ae48 --- /dev/null +++ b/packages/acp/acp/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "ACP servidor", + "description": "Execute agentes por meio de JSON-RPC em entradas e saídas padrão para automação." + } +} diff --git a/packages/acp/acp/locale/ru.json b/packages/acp/acp/locale/ru.json new file mode 100644 index 0000000000..fefd7d956d --- /dev/null +++ b/packages/acp/acp/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "ACP сервер", + "description": "Запускайте агенты через JSON-RPC через стандартный ввод и вывод для автоматизации." + } +} diff --git a/packages/api/account-controller/locale/de.json b/packages/api/account-controller/locale/de.json new file mode 100644 index 0000000000..f1e7b8ca6c --- /dev/null +++ b/packages/api/account-controller/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Benutzeroberfläche für den Kontobetrieb", + "description": "Bieten Sie authentifizierten Clients Kontoverwaltungsfunktionen." + } +} diff --git a/packages/api/account-controller/locale/es.json b/packages/api/account-controller/locale/es.json new file mode 100644 index 0000000000..7bfaac6431 --- /dev/null +++ b/packages/api/account-controller/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de operación de cuenta", + "description": "Proporcionar capacidades de operación de cuentas a clientes autenticados." + } +} diff --git a/packages/api/account-controller/locale/fr.json b/packages/api/account-controller/locale/fr.json new file mode 100644 index 0000000000..a77bd7e7a1 --- /dev/null +++ b/packages/api/account-controller/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface d'opération de compte", + "description": "Fournir des capacités d’exploitation de compte aux clients authentifiés." + } +} diff --git a/packages/api/account-controller/locale/pt.json b/packages/api/account-controller/locale/pt.json new file mode 100644 index 0000000000..22670a3e3b --- /dev/null +++ b/packages/api/account-controller/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de operação da conta", + "description": "Fornece recursos de operação de conta para clientes autenticados." + } +} diff --git a/packages/api/account-controller/locale/ru.json b/packages/api/account-controller/locale/ru.json new file mode 100644 index 0000000000..dd3e515e30 --- /dev/null +++ b/packages/api/account-controller/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Интерфейс работы со счетом", + "description": "Предоставьте возможности управления учетной записью аутентифицированным клиентам." + } +} diff --git a/packages/api/gateway/locale/de.json b/packages/api/gateway/locale/de.json new file mode 100644 index 0000000000..f2fd7153f5 --- /dev/null +++ b/packages/api/gateway/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Remote-Call-Gateway", + "description": "Empfangen Sie den Schnittstellenaufruf des Clients und verteilen Sie ihn an den entsprechenden Dienst." + } +} diff --git a/packages/api/gateway/locale/es.json b/packages/api/gateway/locale/es.json new file mode 100644 index 0000000000..7c02c79a8e --- /dev/null +++ b/packages/api/gateway/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "puerta de enlace de llamada remota", + "description": "Recibir la llamada de interfaz del cliente y distribuirla al servicio correspondiente." + } +} diff --git a/packages/api/gateway/locale/fr.json b/packages/api/gateway/locale/fr.json new file mode 100644 index 0000000000..2eec7623b4 --- /dev/null +++ b/packages/api/gateway/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "passerelle d'appel à distance", + "description": "Recevez l'appel d'interface du client et distribuez-le au service correspondant." + } +} diff --git a/packages/api/gateway/locale/pt.json b/packages/api/gateway/locale/pt.json new file mode 100644 index 0000000000..856eba1312 --- /dev/null +++ b/packages/api/gateway/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "gateway de chamada remota", + "description": "Receba a chamada de interface do cliente e distribua-a ao serviço correspondente." + } +} diff --git a/packages/api/gateway/locale/ru.json b/packages/api/gateway/locale/ru.json new file mode 100644 index 0000000000..7e7cf69bd3 --- /dev/null +++ b/packages/api/gateway/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "шлюз удаленных вызовов", + "description": "Получите вызов интерфейса клиента и передайте его соответствующему сервису." + } +} diff --git a/packages/api/job-controller/locale/de.json b/packages/api/job-controller/locale/de.json new file mode 100644 index 0000000000..ffddc2d9c6 --- /dev/null +++ b/packages/api/job-controller/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Schnittstelle zur Beobachtung von Hintergrundaufgaben", + "description": "Stellen Sie dem Kunden kontinuierlich den Status und die Ausgabe von Hintergrundaufgaben zur Verfügung." + } +} diff --git a/packages/api/job-controller/locale/es.json b/packages/api/job-controller/locale/es.json new file mode 100644 index 0000000000..d7fbfdc02e --- /dev/null +++ b/packages/api/job-controller/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de observación de tareas en segundo plano", + "description": "Proporcionar continuamente el estado y la salida de las tareas en segundo plano al cliente." + } +} diff --git a/packages/api/job-controller/locale/fr.json b/packages/api/job-controller/locale/fr.json new file mode 100644 index 0000000000..aad494710a --- /dev/null +++ b/packages/api/job-controller/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface d'observation des tâches en arrière-plan", + "description": "Fournir en permanence l'état et la sortie des tâches en arrière-plan au client." + } +} diff --git a/packages/api/job-controller/locale/pt.json b/packages/api/job-controller/locale/pt.json new file mode 100644 index 0000000000..c98a63561b --- /dev/null +++ b/packages/api/job-controller/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de observação de tarefas em segundo plano", + "description": "Fornece continuamente o status e a saída de tarefas em segundo plano ao cliente." + } +} diff --git a/packages/api/job-controller/locale/ru.json b/packages/api/job-controller/locale/ru.json new file mode 100644 index 0000000000..60ecb46b94 --- /dev/null +++ b/packages/api/job-controller/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Интерфейс наблюдения за фоновыми задачами", + "description": "Постоянно предоставляйте клиенту статус и вывод фоновых задач." + } +} diff --git a/packages/api/remote-access/locale/de.json b/packages/api/remote-access/locale/de.json new file mode 100644 index 0000000000..14b83f143c --- /dev/null +++ b/packages/api/remote-access/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Fernzugriffskontrolle", + "description": "Steuern Sie, mit welchen Methoden Nicht-Eigentümer-Verbindungen auf Berechtigungs-Snapshots für jede Verbindung zugreifen und diese beibehalten können." + } +} diff --git a/packages/api/remote-access/locale/es.json b/packages/api/remote-access/locale/es.json new file mode 100644 index 0000000000..dda54e1529 --- /dev/null +++ b/packages/api/remote-access/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "control de acceso remoto", + "description": "Controle a qué métodos pueden acceder las conexiones que no son propietarios y retener instantáneas de permisos para cada conexión." + } +} diff --git a/packages/api/remote-access/locale/fr.json b/packages/api/remote-access/locale/fr.json new file mode 100644 index 0000000000..96082a9342 --- /dev/null +++ b/packages/api/remote-access/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Contrôle d'accès à distance", + "description": "Contrôlez les méthodes auxquelles les connexions non propriétaires peuvent accéder et conserver les instantanés d'autorisation pour chaque connexion." + } +} diff --git a/packages/api/remote-access/locale/pt.json b/packages/api/remote-access/locale/pt.json new file mode 100644 index 0000000000..840eaf556f --- /dev/null +++ b/packages/api/remote-access/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Controle de acesso remoto", + "description": "Controle quais métodos as conexões não proprietárias podem acessar e reter instantâneos de permissão para cada conexão." + } +} diff --git a/packages/api/remote-access/locale/ru.json b/packages/api/remote-access/locale/ru.json new file mode 100644 index 0000000000..1faa15dd38 --- /dev/null +++ b/packages/api/remote-access/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Управление удаленным доступом", + "description": "Контролируйте, какие методы соединения, не являющиеся владельцами, могут получать доступ и сохранять снимки разрешений для каждого соединения." + } +} diff --git a/packages/api/remotes/locale/de.json b/packages/api/remotes/locale/de.json new file mode 100644 index 0000000000..dcc7ff1da3 --- /dev/null +++ b/packages/api/remotes/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Zusammenfassung des Kunden API", + "description": "Fasst die Serverfunktionen zusammen, die Clients durch Anwendungen zur Verfügung stehen." + } +} diff --git a/packages/api/remotes/locale/es.json b/packages/api/remotes/locale/es.json new file mode 100644 index 0000000000..d731b0c788 --- /dev/null +++ b/packages/api/remotes/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Resumen del cliente API", + "description": "Resume las capacidades del servidor abiertas a los clientes por las aplicaciones." + } +} diff --git a/packages/api/remotes/locale/fr.json b/packages/api/remotes/locale/fr.json new file mode 100644 index 0000000000..a85835665d --- /dev/null +++ b/packages/api/remotes/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Récapitulatif du client API", + "description": "Résume les fonctionnalités du serveur ouvertes aux clients par les applications." + } +} diff --git a/packages/api/remotes/locale/pt.json b/packages/api/remotes/locale/pt.json new file mode 100644 index 0000000000..9bc13b83ff --- /dev/null +++ b/packages/api/remotes/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Resumo do cliente API", + "description": "Resume os recursos do servidor abertos aos clientes pelos aplicativos." + } +} diff --git a/packages/api/remotes/locale/ru.json b/packages/api/remotes/locale/ru.json new file mode 100644 index 0000000000..804cf94148 --- /dev/null +++ b/packages/api/remotes/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Сводная информация о клиенте API", + "description": "Обобщает возможности сервера, открытые для клиентов приложениями." + } +} diff --git a/packages/api/session-controller/locale/de.json b/packages/api/session-controller/locale/de.json new file mode 100644 index 0000000000..217f0baf00 --- /dev/null +++ b/packages/api/session-controller/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sitzungssteuerungsschnittstelle", + "description": "Bietet Clients Funktionen zum Lesen von Sitzungen, zur Laufsteuerung und zur Statusaktualisierung." + } +} diff --git a/packages/api/session-controller/locale/es.json b/packages/api/session-controller/locale/es.json new file mode 100644 index 0000000000..764c28e00b --- /dev/null +++ b/packages/api/session-controller/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "interfaz de control de sesión", + "description": "Proporciona capacidades de lectura de sesiones, control de ejecución y actualización de estado a los clientes." + } +} diff --git a/packages/api/session-controller/locale/fr.json b/packages/api/session-controller/locale/fr.json new file mode 100644 index 0000000000..689e058b56 --- /dev/null +++ b/packages/api/session-controller/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "interface de contrôle de session", + "description": "Fournit des fonctionnalités de lecture de session, de contrôle d’exécution et de mise à jour de statut aux clients." + } +} diff --git a/packages/api/session-controller/locale/pt.json b/packages/api/session-controller/locale/pt.json new file mode 100644 index 0000000000..537a8f934d --- /dev/null +++ b/packages/api/session-controller/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "interface de controle de sessão", + "description": "Fornece leitura de sessão, controle de execução e recursos de atualização de status aos clientes." + } +} diff --git a/packages/api/session-controller/locale/ru.json b/packages/api/session-controller/locale/ru.json new file mode 100644 index 0000000000..885910a705 --- /dev/null +++ b/packages/api/session-controller/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "интерфейс управления сеансом", + "description": "Предоставляет клиентам возможности чтения сеанса, управления запуском и обновления статуса." + } +} diff --git a/packages/api/settings-controller/locale/de.json b/packages/api/settings-controller/locale/de.json new file mode 100644 index 0000000000..f27d4899d3 --- /dev/null +++ b/packages/api/settings-controller/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Lese- und Schreibschnittstelle einrichten", + "description": "Bieten Sie dem Kunden die Möglichkeit, verschiedene Einstellungen zu lesen und zu ändern." + } +} diff --git a/packages/api/settings-controller/locale/es.json b/packages/api/settings-controller/locale/es.json new file mode 100644 index 0000000000..39d21f44e7 --- /dev/null +++ b/packages/api/settings-controller/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Configurar la interfaz de lectura y escritura", + "description": "Proporcionar al cliente la capacidad de leer y modificar varias configuraciones." + } +} diff --git a/packages/api/settings-controller/locale/fr.json b/packages/api/settings-controller/locale/fr.json new file mode 100644 index 0000000000..7fe6fcd1d9 --- /dev/null +++ b/packages/api/settings-controller/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Configurer l'interface de lecture et d'écriture", + "description": "Offrir au client la possibilité de lire et de modifier divers paramètres." + } +} diff --git a/packages/api/settings-controller/locale/pt.json b/packages/api/settings-controller/locale/pt.json new file mode 100644 index 0000000000..46507f0ae7 --- /dev/null +++ b/packages/api/settings-controller/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Configurar interface de leitura e gravação", + "description": "Forneça ao cliente a capacidade de ler e modificar várias configurações." + } +} diff --git a/packages/api/settings-controller/locale/ru.json b/packages/api/settings-controller/locale/ru.json new file mode 100644 index 0000000000..a24ae67e2d --- /dev/null +++ b/packages/api/settings-controller/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Настройка интерфейса чтения и записи", + "description": "Предоставьте клиенту возможность читать и изменять различные настройки." + } +} diff --git a/packages/api/terminal-controller/locale/de.json b/packages/api/terminal-controller/locale/de.json new file mode 100644 index 0000000000..40a84f00ec --- /dev/null +++ b/packages/api/terminal-controller/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Terminal-Steuerungsschnittstelle", + "description": "Bietet Clients die Möglichkeit, Sitzungsterminals zu erstellen, einzugeben, zu lesen und wiederherzustellen." + } +} diff --git a/packages/api/terminal-controller/locale/es.json b/packages/api/terminal-controller/locale/es.json new file mode 100644 index 0000000000..89251b9b70 --- /dev/null +++ b/packages/api/terminal-controller/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "interfaz de control terminal", + "description": "Proporciona a los clientes la capacidad de crear, ingresar, leer y restaurar terminales de sesión." + } +} diff --git a/packages/api/terminal-controller/locale/fr.json b/packages/api/terminal-controller/locale/fr.json new file mode 100644 index 0000000000..e016120a32 --- /dev/null +++ b/packages/api/terminal-controller/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "interface de contrôle des terminaux", + "description": "Fournit aux clients la possibilité de créer, saisir, lire et restaurer des terminaux de session." + } +} diff --git a/packages/api/terminal-controller/locale/pt.json b/packages/api/terminal-controller/locale/pt.json new file mode 100644 index 0000000000..3e2aa9afb6 --- /dev/null +++ b/packages/api/terminal-controller/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "interface de controle de terminal", + "description": "Fornece aos clientes a capacidade de criar, inserir, ler e restaurar terminais de sessão." + } +} diff --git a/packages/api/terminal-controller/locale/ru.json b/packages/api/terminal-controller/locale/ru.json new file mode 100644 index 0000000000..c2c8651003 --- /dev/null +++ b/packages/api/terminal-controller/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "интерфейс управления терминалом", + "description": "Предоставляет клиентам возможность создавать, вводить, читать и восстанавливать сеансовые терминалы." + } +} diff --git a/packages/api/workspace-controller/locale/de.json b/packages/api/workspace-controller/locale/de.json new file mode 100644 index 0000000000..f36dfe99d3 --- /dev/null +++ b/packages/api/workspace-controller/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Schnittstelle zur Arbeitsbereichssteuerung", + "description": "Bietet Clients Arbeitsbereichsvorgänge und einen Status, der bei erneuter Verbindung wiederhergestellt werden kann." + } +} diff --git a/packages/api/workspace-controller/locale/es.json b/packages/api/workspace-controller/locale/es.json new file mode 100644 index 0000000000..3a451aba01 --- /dev/null +++ b/packages/api/workspace-controller/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de control del espacio de trabajo", + "description": "Proporciona a los clientes operaciones en el espacio de trabajo y un estado que se puede restaurar tras la reconexión." + } +} diff --git a/packages/api/workspace-controller/locale/fr.json b/packages/api/workspace-controller/locale/fr.json new file mode 100644 index 0000000000..d6b5f2a527 --- /dev/null +++ b/packages/api/workspace-controller/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de contrôle de l'espace de travail", + "description": "Fournit aux clients des opérations d’espace de travail et un état qui peut être restauré lors de la reconnexion." + } +} diff --git a/packages/api/workspace-controller/locale/pt.json b/packages/api/workspace-controller/locale/pt.json new file mode 100644 index 0000000000..0564e0743f --- /dev/null +++ b/packages/api/workspace-controller/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de controle do espaço de trabalho", + "description": "Fornece aos clientes operações de espaço de trabalho e um estado que pode ser restaurado após a reconexão." + } +} diff --git a/packages/api/workspace-controller/locale/ru.json b/packages/api/workspace-controller/locale/ru.json new file mode 100644 index 0000000000..19da086fb1 --- /dev/null +++ b/packages/api/workspace-controller/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Интерфейс управления рабочей областью", + "description": "Предоставляет клиентам операции в рабочей области и состояние, которое можно восстановить при повторном подключении." + } +} diff --git a/packages/api/workspace-files/locale/de.json b/packages/api/workspace-files/locale/de.json new file mode 100644 index 0000000000..60f31b3a27 --- /dev/null +++ b/packages/api/workspace-files/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Workspace-Dateischnittstelle", + "description": "Bietet das Lesen von Arbeitsbereichsdateien, das Auflisten von Verzeichnissen und die Aktualisierung von Dateiinformationen." + } +} diff --git a/packages/api/workspace-files/locale/es.json b/packages/api/workspace-files/locale/es.json new file mode 100644 index 0000000000..91db1da1f2 --- /dev/null +++ b/packages/api/workspace-files/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de archivos del espacio de trabajo", + "description": "Proporciona lectura de archivos del espacio de trabajo, listado de directorios y actualizaciones de información de archivos." + } +} diff --git a/packages/api/workspace-files/locale/fr.json b/packages/api/workspace-files/locale/fr.json new file mode 100644 index 0000000000..490d88dcbf --- /dev/null +++ b/packages/api/workspace-files/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de fichier de l'espace de travail", + "description": "Fournit la lecture des fichiers de l'espace de travail, la liste des répertoires et les mises à jour des informations sur les fichiers." + } +} diff --git a/packages/api/workspace-files/locale/pt.json b/packages/api/workspace-files/locale/pt.json new file mode 100644 index 0000000000..e0d49a666d --- /dev/null +++ b/packages/api/workspace-files/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de arquivo do espaço de trabalho", + "description": "Fornece leitura de arquivos do espaço de trabalho, listagem de diretórios e atualizações de informações de arquivos." + } +} diff --git a/packages/api/workspace-files/locale/ru.json b/packages/api/workspace-files/locale/ru.json new file mode 100644 index 0000000000..3d514ad55b --- /dev/null +++ b/packages/api/workspace-files/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Файловый интерфейс рабочей области", + "description": "Обеспечивает чтение файлов рабочей области, список каталогов и обновление информации о файлах." + } +} diff --git a/packages/attachment/attachment-local/locale/de.json b/packages/attachment/attachment-local/locale/de.json new file mode 100644 index 0000000000..1095b25bb2 --- /dev/null +++ b/packages/attachment/attachment-local/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Lokaler Anhangsspeicher", + "description": "Speichern Sie Anhänge wie Bilder in der Sitzung und lesen Sie sie entsprechend der Inhaltskennung." + } +} diff --git a/packages/attachment/attachment-local/locale/es.json b/packages/attachment/attachment-local/locale/es.json new file mode 100644 index 0000000000..59ca4b5d35 --- /dev/null +++ b/packages/attachment/attachment-local/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Almacenamiento de archivos adjuntos locales", + "description": "Guarde archivos adjuntos como imágenes de la sesión y léalos según el identificador de contenido." + } +} diff --git a/packages/attachment/attachment-local/locale/fr.json b/packages/attachment/attachment-local/locale/fr.json new file mode 100644 index 0000000000..cb5019bfc5 --- /dev/null +++ b/packages/attachment/attachment-local/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Stockage local des pièces jointes", + "description": "Enregistrez les pièces jointes telles que les images dans la session et lisez-les en fonction de l'identifiant du contenu." + } +} diff --git a/packages/attachment/attachment-local/locale/pt.json b/packages/attachment/attachment-local/locale/pt.json new file mode 100644 index 0000000000..030a96aed5 --- /dev/null +++ b/packages/attachment/attachment-local/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Armazenamento local de anexos", + "description": "Salve anexos como fotos na sessão e leia-os de acordo com o identificador de conteúdo." + } +} diff --git a/packages/attachment/attachment-local/locale/ru.json b/packages/attachment/attachment-local/locale/ru.json new file mode 100644 index 0000000000..d452d5a8f5 --- /dev/null +++ b/packages/attachment/attachment-local/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Локальное хранилище вложений", + "description": "Сохраняйте вложения, например изображения, в сеансе и читайте их в соответствии с идентификатором контента." + } +} diff --git a/packages/boot/config-editor/locale/de.json b/packages/boot/config-editor/locale/de.json new file mode 100644 index 0000000000..d72e2c7250 --- /dev/null +++ b/packages/boot/config-editor/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Plug-in-Konfigurationseditor", + "description": "Speichern Sie die Plug-in-Konfiguration und übernehmen Sie Änderungen auf die aktuell ausgeführte Konfiguration." + } +} diff --git a/packages/boot/config-editor/locale/es.json b/packages/boot/config-editor/locale/es.json new file mode 100644 index 0000000000..a2448c1f5d --- /dev/null +++ b/packages/boot/config-editor/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Editor de configuración de complementos", + "description": "Guarde la configuración del complemento y aplique los cambios a la configuración en ejecución actual." + } +} diff --git a/packages/boot/config-editor/locale/fr.json b/packages/boot/config-editor/locale/fr.json new file mode 100644 index 0000000000..f2b3eb621d --- /dev/null +++ b/packages/boot/config-editor/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Éditeur de configuration de plug-in", + "description": "Enregistrez la configuration du plug-in et appliquez les modifications à la configuration en cours d'exécution." + } +} diff --git a/packages/boot/config-editor/locale/pt.json b/packages/boot/config-editor/locale/pt.json new file mode 100644 index 0000000000..8f2a80a8aa --- /dev/null +++ b/packages/boot/config-editor/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Editor de configuração de plug-ins", + "description": "Salve a configuração do plug-in e aplique as alterações à configuração em execução atual." + } +} diff --git a/packages/boot/config-editor/locale/ru.json b/packages/boot/config-editor/locale/ru.json new file mode 100644 index 0000000000..b14ff9c92c --- /dev/null +++ b/packages/boot/config-editor/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Редактор конфигурации плагина", + "description": "Сохраните конфигурацию плагина и примените изменения к текущей работающей конфигурации." + } +} diff --git a/packages/boot/hmr/locale/de.json b/packages/boot/hmr/locale/de.json new file mode 100644 index 0000000000..45ffdf967a --- /dev/null +++ b/packages/boot/hmr/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Hmr", + "description": "Laden Sie den Plugin-Code und die Konfiguration neu, während die App ausgeführt wird." + } +} diff --git a/packages/boot/hmr/locale/es.json b/packages/boot/hmr/locale/es.json new file mode 100644 index 0000000000..06af2d1b51 --- /dev/null +++ b/packages/boot/hmr/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "hmr", + "description": "Vuelva a cargar el código y la configuración del complemento mientras la aplicación se está ejecutando." + } +} diff --git a/packages/boot/hmr/locale/fr.json b/packages/boot/hmr/locale/fr.json new file mode 100644 index 0000000000..096306a34e --- /dev/null +++ b/packages/boot/hmr/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "hum", + "description": "Rechargez le code et la configuration du plugin pendant que l'application est en cours d'exécution." + } +} diff --git a/packages/boot/hmr/locale/pt.json b/packages/boot/hmr/locale/pt.json new file mode 100644 index 0000000000..b9ee71fba2 --- /dev/null +++ b/packages/boot/hmr/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "hum", + "description": "Recarregue o código e a configuração do plugin enquanto o aplicativo estiver em execução." + } +} diff --git a/packages/boot/hmr/locale/ru.json b/packages/boot/hmr/locale/ru.json new file mode 100644 index 0000000000..0ed5dc0fdc --- /dev/null +++ b/packages/boot/hmr/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "хмр", + "description": "Перезагрузите код и конфигурацию плагина во время работы приложения." + } +} diff --git a/packages/boot/official-bundles/src/catalog.generated.ts b/packages/boot/official-bundles/src/catalog.generated.ts index 52be77c5ca..8a0cfb7579 100644 --- a/packages/boot/official-bundles/src/catalog.generated.ts +++ b/packages/boot/official-bundles/src/catalog.generated.ts @@ -7,16 +7,16 @@ export const OFFICIAL_ON_DEMAND_CATALOG: readonly OfficialBundleCatalogEntry[] = { packageName: '@deepseek-ai/dsh-subagent-claude-code', meta: { - title: { 'en': 'Claude Code subagent', 'ja': 'Claude Code \u30B5\u30D6\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8', 'zh': 'Claude Code \u5B50\u667A\u80FD\u4F53' }, - description: { 'en': 'Delegate one task to Claude Code using its native authentication and settings.', 'ja': 'Claude Code \u306E\u30CD\u30A4\u30C6\u30A3\u30D6\u306E\u8A8D\u8A3C\u3068\u8A2D\u5B9A\u3092\u4F7F\u7528\u3057\u3066\u3001\u5358\u72EC\u306E\u30BF\u30B9\u30AF\u3092\u59D4\u6D3E\u3057\u307E\u3059\u3002', 'zh': '\u4F7F\u7528 Claude Code \u539F\u751F\u8BA4\u8BC1\u548C\u8BBE\u7F6E\u59D4\u6D3E\u5355\u4E2A\u4EFB\u52A1\u3002' }, + title: { 'de': 'Claude Code-Subagent', 'en': 'Claude Code subagent', 'es': 'Subagente Claude Code', 'fr': 'Sous-agent Claude Code', 'ja': 'Claude Code \u30B5\u30D6\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8', 'pt': 'Claude Code subagente', 'ru': '\u0421\u0443\u0431\u0430\u0433\u0435\u043D\u0442 Claude Code', 'zh': 'Claude Code \u5B50\u667A\u80FD\u4F53' }, + description: { 'de': 'Delegieren Sie eine Aufgabe an Claude Code, indem Sie dessen native Authentifizierung und Einstellungen verwenden.', 'en': 'Delegate one task to Claude Code using its native authentication and settings.', 'es': 'Delegue una tarea a Claude Code utilizando su autenticaci\u00F3n y configuraci\u00F3n nativas.', 'fr': 'D\u00E9l\u00E9guez une t\u00E2che \u00E0 Claude Code \u00E0 l\u2019aide de son authentification et de ses param\u00E8tres natifs.', 'ja': 'Claude Code \u306E\u30CD\u30A4\u30C6\u30A3\u30D6\u306E\u8A8D\u8A3C\u3068\u8A2D\u5B9A\u3092\u4F7F\u7528\u3057\u3066\u3001\u5358\u72EC\u306E\u30BF\u30B9\u30AF\u3092\u59D4\u6D3E\u3057\u307E\u3059\u3002', 'pt': 'Delegue uma tarefa a Claude Code usando sua autentica\u00E7\u00E3o e configura\u00E7\u00F5es nativas.', 'ru': '\u0414\u0435\u043B\u0435\u0433\u0438\u0440\u0443\u0439\u0442\u0435 \u043E\u0434\u043D\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 Claude Code, \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u044F \u0435\u0433\u043E \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u0443\u044E \u0430\u0443\u0442\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u044E \u0438 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438.', 'zh': '\u4F7F\u7528 Claude Code \u539F\u751F\u8BA4\u8BC1\u548C\u8BBE\u7F6E\u59D4\u6D3E\u5355\u4E2A\u4EFB\u52A1\u3002' }, icon: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzYiIGhlaWdodD0iMzYiIHZpZXdCb3g9IjAgMCAzNiAzNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB4PSIxNC45ODkzIiB5PSIxNS4xODc3IiB3aWR0aD0iMTIuMjM2NSIgaGVpZ2h0PSIxMi4yMzY1IiByeD0iMiIgZmlsbD0idXJsKCNkc2hfcGx1Z2luX2FydF9SMGEpIiBmaWxsLW9wYWNpdHk9IjAuOCI+PC9yZWN0PjxyZWN0IHg9IjguODcxMDkiIHk9IjkuMDY5NyIgd2lkdGg9IjEyLjIzNjUiIGhlaWdodD0iMTIuMjM2NSIgcng9IjIiIGZpbGw9InVybCgjZHNoX3BsdWdpbl9hcnRfUjBiKSIgZmlsbC1vcGFjaXR5PSIwLjgiPjwvcmVjdD48ZGVmcz48bGluZWFyR3JhZGllbnQgaWQ9ImRzaF9wbHVnaW5fYXJ0X1IwYSIgeDE9IjIxLjEwNzUiIHkxPSIxNS4xODc3IiB4Mj0iMjEuMTA3NSIgeTI9IjI3LjQyNDMiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj48c3RvcCBzdG9wLWNvbG9yPSIjNDVFN0E0Ij48L3N0b3A+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMDU5MDlEIj48L3N0b3A+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImRzaF9wbHVnaW5fYXJ0X1IwYiIgeDE9IjE0Ljk4OTQiIHkxPSI5LjA2OTciIHgyPSIxNC45ODk0IiB5Mj0iMjEuMzA2MyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPjxzdG9wIHN0b3AtY29sb3I9IiM2OUI5RkYiPjwvc3RvcD48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMzMjRERTIiPjwvc3RvcD48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48L3N2Zz4K', }, }, { packageName: '@deepseek-ai/dsh-subagent-codex', meta: { - title: { 'en': 'Codex subagent', 'ja': 'Codex \u30B5\u30D6\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8', 'zh': 'Codex \u5B50\u667A\u80FD\u4F53' }, - description: { 'en': 'Delegate one task to Codex using its native authentication and settings.', 'ja': 'Codex \u306E\u30CD\u30A4\u30C6\u30A3\u30D6\u306E\u8A8D\u8A3C\u3068\u8A2D\u5B9A\u3092\u4F7F\u7528\u3057\u3066\u3001\u5358\u72EC\u306E\u30BF\u30B9\u30AF\u3092\u59D4\u6D3E\u3057\u307E\u3059\u3002', 'zh': '\u4F7F\u7528 Codex \u539F\u751F\u8BA4\u8BC1\u548C\u8BBE\u7F6E\u59D4\u6D3E\u5355\u4E2A\u4EFB\u52A1\u3002' }, + title: { 'de': 'Codex-Subagent', 'en': 'Codex subagent', 'es': 'Subagente Codex', 'fr': 'Sous-agent Codex', 'ja': 'Codex \u30B5\u30D6\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8', 'pt': 'Codex subagente', 'ru': '\u0421\u0443\u0431\u0430\u0433\u0435\u043D\u0442 Codex', 'zh': 'Codex \u5B50\u667A\u80FD\u4F53' }, + description: { 'de': 'Delegieren Sie eine Aufgabe an Codex, indem Sie dessen native Authentifizierung und Einstellungen verwenden.', 'en': 'Delegate one task to Codex using its native authentication and settings.', 'es': 'Delegue una tarea a Codex utilizando su autenticaci\u00F3n y configuraci\u00F3n nativas.', 'fr': 'D\u00E9l\u00E9guez une t\u00E2che \u00E0 Codex \u00E0 l\u2019aide de son authentification et de ses param\u00E8tres natifs.', 'ja': 'Codex \u306E\u30CD\u30A4\u30C6\u30A3\u30D6\u306E\u8A8D\u8A3C\u3068\u8A2D\u5B9A\u3092\u4F7F\u7528\u3057\u3066\u3001\u5358\u72EC\u306E\u30BF\u30B9\u30AF\u3092\u59D4\u6D3E\u3057\u307E\u3059\u3002', 'pt': 'Delegue uma tarefa a Codex usando sua autentica\u00E7\u00E3o e configura\u00E7\u00F5es nativas.', 'ru': '\u0414\u0435\u043B\u0435\u0433\u0438\u0440\u0443\u0439\u0442\u0435 \u043E\u0434\u043D\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 Codex, \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u044F \u0435\u0433\u043E \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u0443\u044E \u0430\u0443\u0442\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u044E \u0438 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438.', 'zh': '\u4F7F\u7528 Codex \u539F\u751F\u8BA4\u8BC1\u548C\u8BBE\u7F6E\u59D4\u6D3E\u5355\u4E2A\u4EFB\u52A1\u3002' }, icon: 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzYiIGhlaWdodD0iMzYiIHZpZXdCb3g9IjAgMCAzNiAzNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB4PSIxNC45ODkzIiB5PSIxNS4xODc3IiB3aWR0aD0iMTIuMjM2NSIgaGVpZ2h0PSIxMi4yMzY1IiByeD0iMiIgZmlsbD0idXJsKCNkc2hfcGx1Z2luX2FydF9SMGEpIiBmaWxsLW9wYWNpdHk9IjAuOCI+PC9yZWN0PjxyZWN0IHg9IjguODcxMDkiIHk9IjkuMDY5NyIgd2lkdGg9IjEyLjIzNjUiIGhlaWdodD0iMTIuMjM2NSIgcng9IjIiIGZpbGw9InVybCgjZHNoX3BsdWdpbl9hcnRfUjBiKSIgZmlsbC1vcGFjaXR5PSIwLjgiPjwvcmVjdD48ZGVmcz48bGluZWFyR3JhZGllbnQgaWQ9ImRzaF9wbHVnaW5fYXJ0X1IwYSIgeDE9IjIxLjEwNzUiIHkxPSIxNS4xODc3IiB4Mj0iMjEuMTA3NSIgeTI9IjI3LjQyNDMiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj48c3RvcCBzdG9wLWNvbG9yPSIjNDVFN0E0Ij48L3N0b3A+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMDU5MDlEIj48L3N0b3A+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImRzaF9wbHVnaW5fYXJ0X1IwYiIgeDE9IjE0Ljk4OTQiIHkxPSI5LjA2OTciIHgyPSIxNC45ODk0IiB5Mj0iMjEuMzA2MyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPjxzdG9wIHN0b3AtY29sb3I9IiM2OUI5RkYiPjwvc3RvcD48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMzMjRERTIiPjwvc3RvcD48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48L3N2Zz4K', }, }, diff --git a/packages/boot/plugin-manager/locale/de.json b/packages/boot/plugin-manager/locale/de.json new file mode 100644 index 0000000000..d9a82e0464 --- /dev/null +++ b/packages/boot/plugin-manager/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Plug-in-Verwaltungsdienst", + "description": "Verwalten Sie Plug-Ins und Plug-In-Pakete in der aktuell ausgeführten Konfiguration und unterstützen Sie Installation, Entfernung, Starten und Stoppen." + } +} diff --git a/packages/boot/plugin-manager/locale/es.json b/packages/boot/plugin-manager/locale/es.json new file mode 100644 index 0000000000..b4a6c2409a --- /dev/null +++ b/packages/boot/plugin-manager/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Servicio de gestión de complementos", + "description": "Administre complementos y paquetes de complementos en la configuración en ejecución actual, admitiendo la instalación, eliminación, inicio y detención." + } +} diff --git a/packages/boot/plugin-manager/locale/fr.json b/packages/boot/plugin-manager/locale/fr.json new file mode 100644 index 0000000000..51fb19f402 --- /dev/null +++ b/packages/boot/plugin-manager/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Service de gestion des plug-ins", + "description": "Gérez les plug-ins et les packages de plug-ins dans la configuration en cours d'exécution, prenant en charge l'installation, la suppression, le démarrage et l'arrêt." + } +} diff --git a/packages/boot/plugin-manager/locale/pt.json b/packages/boot/plugin-manager/locale/pt.json new file mode 100644 index 0000000000..63e8e2ffdb --- /dev/null +++ b/packages/boot/plugin-manager/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Serviço de gerenciamento de plug-ins", + "description": "Gerencie plug-ins e pacotes de plug-ins na configuração atual em execução, oferecendo suporte à instalação, remoção, início e parada." + } +} diff --git a/packages/boot/plugin-manager/locale/ru.json b/packages/boot/plugin-manager/locale/ru.json new file mode 100644 index 0000000000..1cd9a4db0d --- /dev/null +++ b/packages/boot/plugin-manager/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Служба управления плагинами", + "description": "Управляйте плагинами и пакетами плагинов в текущей работающей конфигурации, поддерживая установку, удаление, запуск и остановку." + } +} diff --git a/packages/boot/plugin-manager/locale/tools/de.json b/packages/boot/plugin-manager/locale/tools/de.json new file mode 100644 index 0000000000..0c51343ea1 --- /dev/null +++ b/packages/boot/plugin-manager/locale/tools/de.json @@ -0,0 +1,5 @@ +{ + "meta": { + "title": "Werkzeuge zur Plugin-Verwaltung" + } +} diff --git a/packages/boot/plugin-manager/locale/tools/es.json b/packages/boot/plugin-manager/locale/tools/es.json new file mode 100644 index 0000000000..43198339a7 --- /dev/null +++ b/packages/boot/plugin-manager/locale/tools/es.json @@ -0,0 +1,5 @@ +{ + "meta": { + "title": "Herramientas de gestión de plugins" + } +} diff --git a/packages/boot/plugin-manager/locale/tools/fr.json b/packages/boot/plugin-manager/locale/tools/fr.json new file mode 100644 index 0000000000..4119d2e33a --- /dev/null +++ b/packages/boot/plugin-manager/locale/tools/fr.json @@ -0,0 +1,5 @@ +{ + "meta": { + "title": "Outils de gestion des plugins" + } +} diff --git a/packages/boot/plugin-manager/locale/tools/pt.json b/packages/boot/plugin-manager/locale/tools/pt.json new file mode 100644 index 0000000000..d1b8e8d2ac --- /dev/null +++ b/packages/boot/plugin-manager/locale/tools/pt.json @@ -0,0 +1,5 @@ +{ + "meta": { + "title": "Ferramentas de gerenciamento de plug-ins" + } +} diff --git a/packages/boot/plugin-manager/locale/tools/ru.json b/packages/boot/plugin-manager/locale/tools/ru.json new file mode 100644 index 0000000000..9bf83c6a3d --- /dev/null +++ b/packages/boot/plugin-manager/locale/tools/ru.json @@ -0,0 +1,5 @@ +{ + "meta": { + "title": "Инструменты управления плагинами" + } +} diff --git a/packages/boot/plugin-market/locale/de.json b/packages/boot/plugin-market/locale/de.json new file mode 100644 index 0000000000..edf6f6a22e --- /dev/null +++ b/packages/boot/plugin-market/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Plugin-Marktindizes", + "description": "Verwalten Sie konfigurierte Marktindizes für die Plugin-Erkennung und das plugin_market-Tool." + } +} diff --git a/packages/boot/plugin-market/locale/es.json b/packages/boot/plugin-market/locale/es.json new file mode 100644 index 0000000000..f6c2037b9e --- /dev/null +++ b/packages/boot/plugin-market/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Índices de mercado de complementos", + "description": "Administre índices de mercado configurados para el descubrimiento de complementos y la herramienta plugin_market." + } +} diff --git a/packages/boot/plugin-market/locale/fr.json b/packages/boot/plugin-market/locale/fr.json new file mode 100644 index 0000000000..270312048c --- /dev/null +++ b/packages/boot/plugin-market/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Indices du marché des plugins", + "description": "Gérez les index de marché configurés pour la découverte de plugins et l'outil plugin_market." + } +} diff --git a/packages/boot/plugin-market/locale/pt.json b/packages/boot/plugin-market/locale/pt.json new file mode 100644 index 0000000000..05d6b2f8d2 --- /dev/null +++ b/packages/boot/plugin-market/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Índices de mercado de plug-ins", + "description": "Gerencie índices de mercado configurados para descoberta de plugins e a ferramenta plugin_market." + } +} diff --git a/packages/boot/plugin-market/locale/ru.json b/packages/boot/plugin-market/locale/ru.json new file mode 100644 index 0000000000..adaee686d2 --- /dev/null +++ b/packages/boot/plugin-market/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Плагин рыночных индексов", + "description": "Управляйте настроенными рыночными индексами для обнаружения плагинов и инструментом plugin_market." + } +} diff --git a/packages/browser-use/browser-use/locale/de.json b/packages/browser-use/browser-use/locale/de.json new file mode 100644 index 0000000000..21cf74b920 --- /dev/null +++ b/packages/browser-use/browser-use/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Registrierung des Browser-Anbieters", + "description": "Registrieren Sie Browser-Automatisierungsanbieter namentlich, mit einem Anbieter pro Name." + } +} diff --git a/packages/browser-use/browser-use/locale/es.json b/packages/browser-use/browser-use/locale/es.json new file mode 100644 index 0000000000..971b6dc650 --- /dev/null +++ b/packages/browser-use/browser-use/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Registro de proveedores de navegador", + "description": "Registre proveedores de automatización del navegador por nombre, con un proveedor por nombre." + } +} diff --git a/packages/browser-use/browser-use/locale/fr.json b/packages/browser-use/browser-use/locale/fr.json new file mode 100644 index 0000000000..a8d05dae20 --- /dev/null +++ b/packages/browser-use/browser-use/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Registre des fournisseurs de navigateur", + "description": "Enregistrez les fournisseurs d'automatisation de navigateur par nom, avec un fournisseur par nom." + } +} diff --git a/packages/browser-use/browser-use/locale/pt.json b/packages/browser-use/browser-use/locale/pt.json new file mode 100644 index 0000000000..a737a4da16 --- /dev/null +++ b/packages/browser-use/browser-use/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Registro do provedor de navegador", + "description": "Registre provedores de automação de navegador por nome, com um provedor por nome." + } +} diff --git a/packages/browser-use/browser-use/locale/ru.json b/packages/browser-use/browser-use/locale/ru.json new file mode 100644 index 0000000000..070de4c045 --- /dev/null +++ b/packages/browser-use/browser-use/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Реестр поставщиков браузеров", + "description": "Зарегистрируйте поставщиков автоматизации браузера по имени, по одному поставщику на имя." + } +} diff --git a/packages/bundle/acp-app/locale/de.json b/packages/bundle/acp-app/locale/de.json new file mode 100644 index 0000000000..69374bc3d2 --- /dev/null +++ b/packages/bundle/acp-app/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "ACP-Profil", + "description": "Bietet rein automatisierte ACP-Kommunikation und Prozesslebenszyklusmanagement über die dsh-Basis." + } +} diff --git a/packages/bundle/acp-app/locale/es.json b/packages/bundle/acp-app/locale/es.json new file mode 100644 index 0000000000..3ea80933ba --- /dev/null +++ b/packages/bundle/acp-app/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Perfil ACP", + "description": "Proporcione comunicación ACP exclusivamente automatizada y gestión del ciclo de vida del proceso a través de la base dsh." + } +} diff --git a/packages/bundle/acp-app/locale/fr.json b/packages/bundle/acp-app/locale/fr.json new file mode 100644 index 0000000000..320c4228e2 --- /dev/null +++ b/packages/bundle/acp-app/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Profil ACP", + "description": "Fournissez une communication ACP uniquement automatisée et une gestion du cycle de vie des processus sur la base dsh." + } +} diff --git a/packages/bundle/acp-app/locale/pt.json b/packages/bundle/acp-app/locale/pt.json new file mode 100644 index 0000000000..b402f4d287 --- /dev/null +++ b/packages/bundle/acp-app/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "ACP perfil", + "description": "Forneça comunicação ACP somente para automação e gerenciamento do ciclo de vida do processo em dshbase." + } +} diff --git a/packages/bundle/acp-app/locale/ru.json b/packages/bundle/acp-app/locale/ru.json new file mode 100644 index 0000000000..ef78a7910e --- /dev/null +++ b/packages/bundle/acp-app/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "ACP профиль", + "description": "Обеспечьте связь только с ACP для автоматизации и управление жизненным циклом процессов через базу dsh." + } +} diff --git a/packages/bundle/headless/locale/de.json b/packages/bundle/headless/locale/de.json new file mode 100644 index 0000000000..df096072aa --- /dev/null +++ b/packages/bundle/headless/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Kopfloses Profil", + "description": "Führen Sie eine einzelne Aufgabe direkt mit dem Kernagenten/Sitzungsläufer über die dsh-Basis aus, ohne Host, HTTP oder Browserebene." + } +} diff --git a/packages/bundle/headless/locale/es.json b/packages/bundle/headless/locale/es.json new file mode 100644 index 0000000000..3916ac6658 --- /dev/null +++ b/packages/bundle/headless/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "perfil sin cabeza", + "description": "Ejecute una sola tarea directamente con el agente principal/ejecutor de sesión sobre la base dsh, sin un host, HTTP o una capa de navegador." + } +} diff --git a/packages/bundle/headless/locale/fr.json b/packages/bundle/headless/locale/fr.json new file mode 100644 index 0000000000..101db58c1b --- /dev/null +++ b/packages/bundle/headless/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Profil sans tête", + "description": "Exécutez une seule tâche directement avec le principal agent/exécuteur de session sur la base dsh, sans hôte, HTTP ou couche de navigateur." + } +} diff --git a/packages/bundle/headless/locale/pt.json b/packages/bundle/headless/locale/pt.json new file mode 100644 index 0000000000..ff379c6db0 --- /dev/null +++ b/packages/bundle/headless/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Perfil sem cabeça", + "description": "Execute uma única tarefa diretamente com o executor principal de agente/sessão em dsh-base, sem um host, HTTP ou camada de navegador." + } +} diff --git a/packages/bundle/headless/locale/ru.json b/packages/bundle/headless/locale/ru.json new file mode 100644 index 0000000000..e84fbba427 --- /dev/null +++ b/packages/bundle/headless/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Безголовый профиль", + "description": "Запустите одну задачу напрямую с помощью основного средства запуска агента/сеанса через базу dsh, без уровня хоста, HTTP или браузера." + } +} diff --git a/packages/bundle/sdk-app/locale/de.json b/packages/bundle/sdk-app/locale/de.json new file mode 100644 index 0000000000..efe87657eb --- /dev/null +++ b/packages/bundle/sdk-app/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "SDK-Profil", + "description": "Stellen Sie JSON-RPC über die Standardeingabe und -ausgabe bereit und verwalten Sie den Prozesslebenszyklus über die dsh-Basis." + } +} diff --git a/packages/bundle/sdk-app/locale/es.json b/packages/bundle/sdk-app/locale/es.json new file mode 100644 index 0000000000..b1b409e2b9 --- /dev/null +++ b/packages/bundle/sdk-app/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Perfil SDK", + "description": "Proporcione JSON-RPC a través de entrada y salida estándar y administre el ciclo de vida del proceso a través de la base dsh." + } +} diff --git a/packages/bundle/sdk-app/locale/fr.json b/packages/bundle/sdk-app/locale/fr.json new file mode 100644 index 0000000000..9de8913e48 --- /dev/null +++ b/packages/bundle/sdk-app/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Profil SDK", + "description": "Fournissez JSON-RPC sur une entrée et une sortie standard et gérez le cycle de vie du processus sur la base dsh." + } +} diff --git a/packages/bundle/sdk-app/locale/pt.json b/packages/bundle/sdk-app/locale/pt.json new file mode 100644 index 0000000000..187ca1d1e0 --- /dev/null +++ b/packages/bundle/sdk-app/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "SDK perfil", + "description": "Forneça JSON-RPC sobre entrada e saída padrão e gerencie o ciclo de vida do processo em dsh-base." + } +} diff --git a/packages/bundle/sdk-app/locale/ru.json b/packages/bundle/sdk-app/locale/ru.json new file mode 100644 index 0000000000..0502de6690 --- /dev/null +++ b/packages/bundle/sdk-app/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "SDK профиль", + "description": "Обеспечьте JSON-RPC поверх стандартного ввода и вывода и управляйте жизненным циклом процесса через dsh-base." + } +} diff --git a/packages/bundle/web-app/locale/de.json b/packages/bundle/web-app/locale/de.json new file mode 100644 index 0000000000..e7f067a8fd --- /dev/null +++ b/packages/bundle/web-app/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Unterstützung bei der Ausführung von Webanwendungen", + "description": "Stellen Sie Front-End-Seitenressourcen bereit und verbinden Sie die für die Webanwendung erforderliche laufende Konfiguration." + } +} diff --git a/packages/bundle/web-app/locale/es.json b/packages/bundle/web-app/locale/es.json new file mode 100644 index 0000000000..70e2cd3b9b --- /dev/null +++ b/packages/bundle/web-app/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Soporte de ejecución de aplicaciones web", + "description": "Proporcione recursos de la página de inicio y conecte la configuración en ejecución requerida por la aplicación web." + } +} diff --git a/packages/bundle/web-app/locale/fr.json b/packages/bundle/web-app/locale/fr.json new file mode 100644 index 0000000000..d33d200823 --- /dev/null +++ b/packages/bundle/web-app/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Prise en charge de l'exécution d'applications Web", + "description": "Fournissez les ressources de la page frontale et connectez la configuration en cours requise par l'application Web." + } +} diff --git a/packages/bundle/web-app/locale/pt.json b/packages/bundle/web-app/locale/pt.json new file mode 100644 index 0000000000..acf7b54d8e --- /dev/null +++ b/packages/bundle/web-app/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Suporte à execução de aplicações web", + "description": "Fornece recursos de página front-end e conecta a configuração de execução exigida pelo aplicativo da web." + } +} diff --git a/packages/bundle/web-app/locale/ru.json b/packages/bundle/web-app/locale/ru.json new file mode 100644 index 0000000000..bfddc6aa87 --- /dev/null +++ b/packages/bundle/web-app/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Поддержка выполнения веб-приложений", + "description": "Предоставьте ресурсы интерфейсной страницы и подключите работающую конфигурацию, необходимую веб-приложению." + } +} diff --git a/packages/bundle/web-app/locale/startup/de.json b/packages/bundle/web-app/locale/startup/de.json new file mode 100644 index 0000000000..3efc2eb5ef --- /dev/null +++ b/packages/bundle/web-app/locale/startup/de.json @@ -0,0 +1,5 @@ +{ + "meta": { + "title": "Web-Startkonfiguration" + } +} diff --git a/packages/bundle/web-app/locale/startup/es.json b/packages/bundle/web-app/locale/startup/es.json new file mode 100644 index 0000000000..b9ad99c565 --- /dev/null +++ b/packages/bundle/web-app/locale/startup/es.json @@ -0,0 +1,5 @@ +{ + "meta": { + "title": "Configuración de inicio web" + } +} diff --git a/packages/bundle/web-app/locale/startup/fr.json b/packages/bundle/web-app/locale/startup/fr.json new file mode 100644 index 0000000000..da69faa205 --- /dev/null +++ b/packages/bundle/web-app/locale/startup/fr.json @@ -0,0 +1,5 @@ +{ + "meta": { + "title": "Configuration du démarrage Web" + } +} diff --git a/packages/bundle/web-app/locale/startup/pt.json b/packages/bundle/web-app/locale/startup/pt.json new file mode 100644 index 0000000000..fe1f8baa0c --- /dev/null +++ b/packages/bundle/web-app/locale/startup/pt.json @@ -0,0 +1,5 @@ +{ + "meta": { + "title": "Configuração de inicialização Web" + } +} diff --git a/packages/bundle/web-app/locale/startup/ru.json b/packages/bundle/web-app/locale/startup/ru.json new file mode 100644 index 0000000000..c2c9f6862c --- /dev/null +++ b/packages/bundle/web-app/locale/startup/ru.json @@ -0,0 +1,5 @@ +{ + "meta": { + "title": "Настройки запуска веб-приложения" + } +} diff --git a/packages/client/connection/locale/de.json b/packages/client/connection/locale/de.json new file mode 100644 index 0000000000..85da6331b4 --- /dev/null +++ b/packages/client/connection/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Verbindung", + "description": "Richten Sie authentifizierte Client-Kommunikation ein und verwalten Sie den Verbindungslebenszyklus." + } +} diff --git a/packages/client/connection/locale/es.json b/packages/client/connection/locale/es.json new file mode 100644 index 0000000000..fa2080ac53 --- /dev/null +++ b/packages/client/connection/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "conexión", + "description": "Establezca comunicaciones autenticadas con el cliente y administre el ciclo de vida de la conexión." + } +} diff --git a/packages/client/connection/locale/fr.json b/packages/client/connection/locale/fr.json new file mode 100644 index 0000000000..d1665120c9 --- /dev/null +++ b/packages/client/connection/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "connexion", + "description": "Établissez des communications client authentifiées et gérez le cycle de vie des connexions." + } +} diff --git a/packages/client/connection/locale/pt.json b/packages/client/connection/locale/pt.json new file mode 100644 index 0000000000..760379ae67 --- /dev/null +++ b/packages/client/connection/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "conexão", + "description": "Estabeleça comunicações autenticadas de clientes e gerencie o ciclo de vida da conexão." + } +} diff --git a/packages/client/connection/locale/ru.json b/packages/client/connection/locale/ru.json new file mode 100644 index 0000000000..adfddadc3d --- /dev/null +++ b/packages/client/connection/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "соединение", + "description": "Установите аутентифицированную клиентскую связь и управляйте жизненным циклом соединения." + } +} diff --git a/packages/client/file-upload/locale/de.json b/packages/client/file-upload/locale/de.json new file mode 100644 index 0000000000..80c9e5ab6f --- /dev/null +++ b/packages/client/file-upload/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Datei-Upload", + "description": "Laden Sie Dateien vom Browser in die aktuelle Sitzung hoch, um sie von Nachrichten und Tools zu verwenden." + } +} diff --git a/packages/client/file-upload/locale/es.json b/packages/client/file-upload/locale/es.json new file mode 100644 index 0000000000..45732e15c5 --- /dev/null +++ b/packages/client/file-upload/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Carga de archivos", + "description": "Cargue archivos desde el navegador a la sesión actual para utilizarlos en mensajes y herramientas." + } +} diff --git a/packages/client/file-upload/locale/fr.json b/packages/client/file-upload/locale/fr.json new file mode 100644 index 0000000000..a518389efe --- /dev/null +++ b/packages/client/file-upload/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Téléchargement de fichiers", + "description": "Téléchargez des fichiers du navigateur vers la session en cours pour les utiliser par les messages et les outils." + } +} diff --git a/packages/client/file-upload/locale/pt.json b/packages/client/file-upload/locale/pt.json new file mode 100644 index 0000000000..e50ef62390 --- /dev/null +++ b/packages/client/file-upload/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Carregamento de arquivo", + "description": "Carregue arquivos do navegador para a sessão atual para uso por mensagens e ferramentas." + } +} diff --git a/packages/client/file-upload/locale/ru.json b/packages/client/file-upload/locale/ru.json new file mode 100644 index 0000000000..b8a733cc10 --- /dev/null +++ b/packages/client/file-upload/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Загрузка файла", + "description": "Загружайте файлы из браузера в текущий сеанс для использования сообщениями и инструментами." + } +} diff --git a/packages/client/hmr/locale/de.json b/packages/client/hmr/locale/de.json new file mode 100644 index 0000000000..6a8ba35a12 --- /dev/null +++ b/packages/client/hmr/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Hmr", + "description": "Synchronisieren Sie die Plug-Ins im Browser und aktualisieren Sie die entsprechende Schnittstelle, nachdem der Code neu erstellt wurde." + } +} diff --git a/packages/client/hmr/locale/es.json b/packages/client/hmr/locale/es.json new file mode 100644 index 0000000000..f2ca5cf4fa --- /dev/null +++ b/packages/client/hmr/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "hmr", + "description": "Sincronice los complementos en el navegador y actualice la interfaz relevante después de reconstruir el código." + } +} diff --git a/packages/client/hmr/locale/fr.json b/packages/client/hmr/locale/fr.json new file mode 100644 index 0000000000..295a751727 --- /dev/null +++ b/packages/client/hmr/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "hum", + "description": "Synchronisez les plug-ins dans le navigateur et mettez à jour l'interface correspondante une fois le code reconstruit." + } +} diff --git a/packages/client/hmr/locale/pt.json b/packages/client/hmr/locale/pt.json new file mode 100644 index 0000000000..33c1516cf2 --- /dev/null +++ b/packages/client/hmr/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "hum", + "description": "Sincronize os plug-ins no navegador e atualize a interface relevante após a reconstrução do código." + } +} diff --git a/packages/client/hmr/locale/ru.json b/packages/client/hmr/locale/ru.json new file mode 100644 index 0000000000..cb8f218fe1 --- /dev/null +++ b/packages/client/hmr/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "хмр", + "description": "Синхронизируйте плагины в браузере и обновите соответствующий интерфейс после перестройки кода." + } +} diff --git a/packages/client/locale/README.i18n.yaml b/packages/client/locale/README.i18n.yaml index f2259ee13c..a475185694 100644 --- a/packages/client/locale/README.i18n.yaml +++ b/packages/client/locale/README.i18n.yaml @@ -9,8 +9,8 @@ en: 9365090d78467dea zh: 74b6fbb9769d795f /deepseek-ai-dsh-client-locale/summary: - en: a2c282377f0a043e - zh: 2274f1ea41774549 + en: d11ef1c4b5b4fe86 + zh: 86eb53d8578eadbf /deepseek-ai-dsh-client-locale/table-of-contents: en: d152484eb41ac6b4 zh: bda879a892f240f0 @@ -21,8 +21,8 @@ en: 2b82458e185ba321 zh: e55a7e709a3f0158 /deepseek-ai-dsh-client-locale/use-this-package/registering-a-dictionary: - en: 69b07cde5b2b4deb - zh: b8204c127b10a711 + en: 525a74ea5e5f152f + zh: 06fd145b189f37ee /deepseek-ai-dsh-client-locale/use-this-package/resolving-package-text: en: 3b63e84fe0fdf8f4 zh: e97b5d1b92dff7ec @@ -45,7 +45,7 @@ en: 68373e745761494c zh: 43a5b8c19d03268a /deepseek-ai-dsh-client-locale/understand-the-implementation/source-map: - en: fc93a8f6804aa5bd + en: 6f329e4872398634 zh: 9d8364dc4c03d055 /deepseek-ai-dsh-client-locale/further-exploration: en: f73d411c9e90dead diff --git a/packages/client/locale/README.md b/packages/client/locale/README.md index e5afbfbde0..7838364e68 100644 --- a/packages/client/locale/README.md +++ b/packages/client/locale/README.md @@ -9,7 +9,7 @@ English | [中文](README.zh.md) ## Summary -Use `dsh-client-locale` to switch the web GUI between the shipped English, Chinese, and Japanese locales or languages added by client plugins. User selections take effect immediately; every authenticated browser persists them as `locale.preference` in `$DSH_HOME/cordis.patch.yml` through the Host settings service. New browsers use the first supported language requested by the browser until the Host read delivers a stored preference. Plugin authors add typed namespace dictionaries and translate through the public locale API; slot-rendered copy updates without a reload. +Use `dsh-client-locale` to switch the web GUI between the shipped English, Chinese, Japanese, Spanish, French, German, Russian, and Portuguese locales or languages added by client plugins. User selections take effect immediately; every authenticated browser persists them as `locale.preference` in `$DSH_HOME/cordis.patch.yml` through the Host settings service. New browsers use the first supported language requested by the browser until the Host read delivers a stored preference. Plugin authors add typed namespace dictionaries and translate through the public locale API; slot-rendered copy updates without a reload. ## Table of Contents @@ -37,7 +37,7 @@ Native shells may provide `__DSH_LOCALE__` with an asynchronous `read()` and an ### Registering a dictionary -Call `ctx.locale.register(ns, { zh, en, ja })` with a namespace merged into `LocaleNamespaceMap`; the compiler checks every key against the namespace's typed key union and requires both baseline locales (`zh` and `en`). Additional locale ids are optional, and their dictionaries are checked against the same namespace keys. Consumers translate through `ctx.locale.bind(ns)` or the framework-injected `t` seat. A dictionary registered after the UI is already mounted is picked up without a remount. +Call `ctx.locale.register(ns, { zh, en, ja })` with a namespace merged into `LocaleNamespaceMap`; the compiler checks every key against the namespace's typed key union and requires both baseline locales (`zh` and `en`). Additional locale ids are optional, and their dictionaries are checked against the same namespace keys. Consumers translate through `ctx.locale.bind(ns)` or the framework-injected `t` seat. A dictionary registered after the UI is already mounted is picked up without a remount. Preserve named placeholders, slash commands, and API field names verbatim in translations; `pnpm run check:i18n` checks first-party dictionaries. ### Resolving package text @@ -52,13 +52,13 @@ export const inject = ['locale'] export function apply(ctx) { ctx.effect( - () => ctx.locale.addLanguage({ id: 'fr', label: 'Français', fallback: 'en' }), + () => ctx.locale.addLanguage({ id: 'it', label: 'Italiano', fallback: 'en' }), 'my-locale: language', ) ctx.effect( - () => ctx.locale.register('common', 'fr', { - cancel: 'Annuler', - close: 'Fermer', + () => ctx.locale.register('common', 'it', { + cancel: 'Annulla', + close: 'Chiudi', }), 'my-locale: common dictionary', ) @@ -102,7 +102,7 @@ The typed object form requires complete dictionaries for both baseline locales. | [`src/client/index.ts`](src/client/index.ts) | `LocaleRuntime`, dictionary registry, Language row registration, `locale/change` event | | [`src/index.ts`](src/index.ts) | Node half: registers the `locale` settings namespace | | [`src/locale-settings.ts`](src/locale-settings.ts) | The durable schema for `locale.preference` | -| [`src/locales/`](src/locales/) | The shipped `zh`/`en`/`ja` dictionaries | +| [`src/locales/`](src/locales/) | The shipped language dictionaries | diff --git a/packages/client/locale/README.zh.md b/packages/client/locale/README.zh.md index 84965430c9..9054fdedee 100644 --- a/packages/client/locale/README.zh.md +++ b/packages/client/locale/README.zh.md @@ -9,7 +9,7 @@ kind: "package-reference" ## 概述 -使用 `dsh-client-locale` 可在 web GUI 中切换内置的英文、中文和日文 locale,或 client 插件添加的语言。用户选择会立即生效;每个已认证浏览器都通过 Host settings 服务把选择以 `locale.preference` 持久化到 `$DSH_HOME/cordis.patch.yml`。全新浏览器会使用浏览器请求的第一个受支持语言,直到 Host 读取送达已存储偏好。插件作者可添加类型化命名空间字典,并通过公开 locale API 翻译;经 slot 渲染的文案无需重新加载即可随语言切换更新。 +使用 `dsh-client-locale` 可在 web GUI 中切换内置的英文、中文、日语、西班牙语、法语、德语、俄语和葡萄牙语 locale,或 client 插件添加的语言。用户选择会立即生效;每个已认证浏览器都通过 Host settings 服务把选择以 `locale.preference` 持久化到 `$DSH_HOME/cordis.patch.yml`。全新浏览器会使用浏览器请求的第一个受支持语言,直到 Host 读取送达已存储偏好。插件作者可添加类型化命名空间字典,并通过公开 locale API 翻译;经 slot 渲染的文案无需重新加载即可随语言切换更新。 ## 目录 @@ -37,7 +37,7 @@ kind: "package-reference" ### 注册字典 -用已合并进 `LocaleNamespaceMap` 的命名空间调用 `ctx.locale.register(ns, { zh, en, ja })`;编译器会对照该命名空间的类型化键并集检查每个键,并要求两个基础 locale(`zh` 和 `en`)齐全。其他 locale id 为可选项,其字典同样按该命名空间的键检查。消费方通过 `ctx.locale.bind(ns)` 或框架注入的 `t` 席位翻译。UI 已挂载后再注册的字典无需重新挂载即可生效。 +用已合并进 `LocaleNamespaceMap` 的命名空间调用 `ctx.locale.register(ns, { zh, en, ja })`;编译器会对照该命名空间的类型化键并集检查每个键,并要求两个基础 locale(`zh` 和 `en`)齐全。其他 locale id 为可选项,其字典同样按该命名空间的键检查。消费方通过 `ctx.locale.bind(ns)` 或框架注入的 `t` 席位翻译。UI 已挂载后再注册的字典无需重新挂载即可生效。 翻译必须原样保留命名占位符、斜杠命令和 API 字段名;`pnpm run check:i18n` 检查仓库内的字典。 ### 解析包文本 @@ -52,13 +52,13 @@ export const inject = ['locale'] export function apply(ctx) { ctx.effect( - () => ctx.locale.addLanguage({ id: 'fr', label: 'Français', fallback: 'en' }), + () => ctx.locale.addLanguage({ id: 'it', label: 'Italiano', fallback: 'en' }), 'my-locale: language', ) ctx.effect( - () => ctx.locale.register('common', 'fr', { - cancel: 'Annuler', - close: 'Fermer', + () => ctx.locale.register('common', 'it', { + cancel: 'Annulla', + close: 'Chiudi', }), 'my-locale: common dictionary', ) diff --git a/packages/client/locale/locale/de.json b/packages/client/locale/locale/de.json new file mode 100644 index 0000000000..f7eb734545 --- /dev/null +++ b/packages/client/locale/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Gebietsschema", + "description": "Verwalten Sie die Spracheinstellungen der Benutzeroberfläche und die Übersetzungskopie jedes Plug-Ins." + } +} diff --git a/packages/client/locale/locale/es.json b/packages/client/locale/locale/es.json new file mode 100644 index 0000000000..ea4d2f0869 --- /dev/null +++ b/packages/client/locale/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "local", + "description": "Administre las preferencias de idioma de la interfaz y la copia de traducción de cada complemento." + } +} diff --git a/packages/client/locale/locale/fr.json b/packages/client/locale/locale/fr.json new file mode 100644 index 0000000000..c3ff597891 --- /dev/null +++ b/packages/client/locale/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "paramètres régionaux", + "description": "Gérez les préférences linguistiques de l’interface et la copie de traduction de chaque plug-in." + } +} diff --git a/packages/client/locale/locale/pt.json b/packages/client/locale/locale/pt.json new file mode 100644 index 0000000000..7b4b751941 --- /dev/null +++ b/packages/client/locale/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "localidade", + "description": "Gerencie as preferências de idioma da interface e a cópia de tradução de cada plug-in." + } +} diff --git a/packages/client/locale/locale/ru.json b/packages/client/locale/locale/ru.json new file mode 100644 index 0000000000..4b11903438 --- /dev/null +++ b/packages/client/locale/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "локаль", + "description": "Управляйте языковыми настройками интерфейса и копией перевода каждого плагина." + } +} diff --git a/packages/client/locale/src/client/index.ts b/packages/client/locale/src/client/index.ts index c6484b8908..3ba1bae29b 100644 --- a/packages/client/locale/src/client/index.ts +++ b/packages/client/locale/src/client/index.ts @@ -20,9 +20,10 @@ import { LOCALE_ID_PATTERN, LOCALE_IDS, LOCALE_PREFERENCE_FIELD, LOCALE_SETTINGS_NAMESPACE, type BuiltInLocaleId, type LocaleId, type LocaleSettings, } from '../locale-settings.ts' -import { en, ja, zh, type CommonKey } from '../locales/index.ts' +import { en, ja, es, fr, de, ru, pt, zh, type CommonKey } from '../locales/index.ts' import { - en as settingsEn, ja as settingsJa, zh as settingsZh, type SettingsLocaleKey, + en as settingsEn, ja as settingsJa, es as settingsEs, fr as settingsFr, + de as settingsDe, ru as settingsRu, pt as settingsPt, zh as settingsZh, type SettingsLocaleKey, } from '../locales/settings.ts' import type { LanguageRowInjected } from './LanguageRow.tsx' import { LanguageRow } from './LanguageRow.tsx' @@ -579,9 +580,11 @@ export async function apply(ctx: ClientContext): Promise { } const host = ctx.configForms.get(LOCALE_SETTINGS_NAMESPACE) const locale = new LocaleRuntime(ctx, host, bootstrap) - ctx.effect(() => locale.addLanguage({ id: 'ja', label: '日本語', fallback: 'en' }), 'locale: Japanese language') - ctx.effect(() => locale.register(COMMON_NS, { zh, en, ja }), 'locale: common dictionaries') - ctx.effect(() => locale.register(SETTINGS_NS, { zh: settingsZh, en: settingsEn, ja: settingsJa }), 'locale: settings dictionaries') + for (const [id, label] of [['ja', '日本語'], ['es', 'Español'], ['fr', 'Français'], ['de', 'Deutsch'], ['ru', 'Русский'], ['pt', 'Português']] as const) { + ctx.effect(() => locale.addLanguage({ id, label, fallback: 'en' }), `locale: ${id} language`) + } + ctx.effect(() => locale.register(COMMON_NS, { zh, en, ja, es, fr, de, ru, pt }), 'locale: common dictionaries') + ctx.effect(() => locale.register(SETTINGS_NS, { zh: settingsZh, en: settingsEn, ja: settingsJa, es: settingsEs, fr: settingsFr, de: settingsDe, ru: settingsRu, pt: settingsPt }), 'locale: settings dictionaries') ctx.provide('locale', locale) if (bridge !== undefined) { ctx.on('locale/change', (snapshot) => { bridge.onChange(snapshot.active) }) diff --git a/packages/client/locale/src/locales/de.ts b/packages/client/locale/src/locales/de.ts new file mode 100644 index 0000000000..3acbad94b3 --- /dev/null +++ b/packages/client/locale/src/locales/de.ts @@ -0,0 +1,47 @@ +/** German common-namespace dictionary. */ +import type { en } from './en.ts' + +/** Complete German copy for the common namespace. */ +export const de = { + 'ok': 'OK', + 'cancel': 'Abbrechen', + 'close': 'Schließen', + 'copy': 'Kopieren', + 'copied': 'Kopiert', + 'codeBlock.title': 'Codeblock', + 'codeBlock.wrap': 'Zeilen umbrechen', + 'codeBlock.unwrap': 'Zeilen nicht umbrechen', + 'copy.failed': 'Das Kopieren ist fehlgeschlagen', + 'copy.value': 'Wert kopieren', + 'copy.json': 'JSON kopieren', + 'copy.path': 'Eigenschaftspfad kopieren', + 'copy.prettyJson': 'Formatiertes JSON kopieren', + 'copy.compactJson': 'Kompaktes JSON kopieren', + 'copy.optionsHint': '{action}; Klicken Sie mit der rechten Maustaste, um die Kopieroptionen anzuzeigen', + 'retry': 'Erneut versuchen', + 'loading': 'Laden…', + 'load.failed': 'Laden fehlgeschlagen', + 'submit': 'Senden', + 'submitting': 'Wird gesendet…', + 'next': 'Weiter', + 'previous': 'Zurück', + 'skip': 'Überspringen', + 'delete': 'Löschen', + 'edit': 'Bearbeiten', + 'save': 'Speichern', + 'search': 'Suchen', + 'more': 'Mehr', + 'collapse': 'Einklappen', + 'expand': 'Ausklappen', + 'back': 'Zurück', + 'brand.localBuild': 'Lokaler DSH-Build', + 'workspace.defaultName': 'Standardarbeitsbereich', + 'unknown': 'Unbekannt', + 'none': 'Keine', + 'truncated': 'Abgeschnitten', + 'json.label': 'JSON', + 'markdown.footnotes': 'Fußnoten', + 'markdown.truncatedCharacters': '… bei {total}-Zeichen abgeschnitten', + 'number.thousand': '{value}K', + 'number.million': '{value}M', +} satisfies Record diff --git a/packages/client/locale/src/locales/es.ts b/packages/client/locale/src/locales/es.ts new file mode 100644 index 0000000000..8ff4607619 --- /dev/null +++ b/packages/client/locale/src/locales/es.ts @@ -0,0 +1,47 @@ +/** Spanish common-namespace dictionary. */ +import type { en } from './en.ts' + +/** Complete Spanish copy for the common namespace. */ +export const es = { + 'ok': 'OK', + 'cancel': 'Cancelar', + 'close': 'Cerrar', + 'copy': 'Copiar', + 'copied': 'Copiado', + 'codeBlock.title': 'Bloque de código', + 'codeBlock.wrap': 'Ajustar líneas', + 'codeBlock.unwrap': 'No ajustar líneas', + 'copy.failed': 'Copia fallida', + 'copy.value': 'Copiar valor', + 'copy.json': 'Copiar JSON', + 'copy.path': 'Copiar ruta de propiedad', + 'copy.prettyJson': 'Copiar JSON con formato', + 'copy.compactJson': 'Copiar JSON compacto', + 'copy.optionsHint': '{action}; haga clic derecho para opciones de copia', + 'retry': 'Reintentar', + 'loading': 'Cargando…', + 'load.failed': 'No se pudo cargar', + 'submit': 'Enviar', + 'submitting': 'Enviando…', + 'next': 'Siguiente', + 'previous': 'Anterior', + 'skip': 'Saltar', + 'delete': 'Eliminar', + 'edit': 'Editar', + 'save': 'Guardar', + 'search': 'Buscar', + 'more': 'Más', + 'collapse': 'Contraer', + 'expand': 'Expandir', + 'back': 'Atrás', + 'brand.localBuild': 'Compilación local de DSH', + 'workspace.defaultName': 'Espacio de trabajo predeterminado', + 'unknown': 'Desconocido', + 'none': 'Ninguno', + 'truncated': 'truncado', + 'json.label': 'JSON', + 'markdown.footnotes': 'Notas a pie de página', + 'markdown.truncatedCharacters': '… truncado en caracteres {total}', + 'number.thousand': '{value}K', + 'number.million': '{value}M', +} satisfies Record diff --git a/packages/client/locale/src/locales/fr.ts b/packages/client/locale/src/locales/fr.ts new file mode 100644 index 0000000000..2585b59af0 --- /dev/null +++ b/packages/client/locale/src/locales/fr.ts @@ -0,0 +1,47 @@ +/** French common-namespace dictionary. */ +import type { en } from './en.ts' + +/** Complete French copy for the common namespace. */ +export const fr = { + 'ok': 'OK', + 'cancel': 'Annuler', + 'close': 'Fermer', + 'copy': 'Copier', + 'copied': 'Copié', + 'codeBlock.title': 'Bloc de code', + 'codeBlock.wrap': 'Activer le retour à la ligne', + 'codeBlock.unwrap': 'Désactiver le retour à la ligne', + 'copy.failed': 'Échec de la copie', + 'copy.value': 'Copier la valeur', + 'copy.json': 'Copier le JSON', + 'copy.path': 'Copier le chemin de la propriété', + 'copy.prettyJson': 'Copier le JSON formaté', + 'copy.compactJson': 'Copier le JSON compact', + 'copy.optionsHint': '{action}; clic droit pour les options de copie', + 'retry': 'Réessayer', + 'loading': 'Chargement…', + 'load.failed': 'Échec du chargement', + 'submit': 'Soumettre', + 'submitting': 'Envoi…', + 'next': 'Suivant', + 'previous': 'Précédent', + 'skip': 'Sauter', + 'delete': 'Supprimer', + 'edit': 'Modifier', + 'save': 'Enregistrer', + 'search': 'Rechercher', + 'more': 'Plus', + 'collapse': 'Réduire', + 'expand': 'Développer', + 'back': 'Retour', + 'brand.localBuild': 'Version locale de DSH', + 'workspace.defaultName': 'Espace de travail par défaut', + 'unknown': 'Inconnu', + 'none': 'Aucun', + 'truncated': 'Tronqué', + 'json.label': 'JSON', + 'markdown.footnotes': 'Notes de bas de page', + 'markdown.truncatedCharacters': '… tronqué aux caractères {total}', + 'number.thousand': '{value}K', + 'number.million': '{value}M', +} satisfies Record diff --git a/packages/client/locale/src/locales/index.ts b/packages/client/locale/src/locales/index.ts index a01489ccfd..6690d74aeb 100644 --- a/packages/client/locale/src/locales/index.ts +++ b/packages/client/locale/src/locales/index.ts @@ -1,8 +1,13 @@ /** - * Common-namespace dictionaries. Chinese defines the keys; English and - * Japanese are checked against the same keys by TypeScript. + * Common-namespace dictionaries. Chinese defines the keys; + * every shipped language is checked against them by TypeScript. */ export { zh } from './zh.ts' export { en } from './en.ts' export { ja } from './ja.ts' export type { CommonKey } from './zh.ts' +export { es } from './es.ts' +export { fr } from './fr.ts' +export { de } from './de.ts' +export { ru } from './ru.ts' +export { pt } from './pt.ts' diff --git a/packages/client/locale/src/locales/pt.ts b/packages/client/locale/src/locales/pt.ts new file mode 100644 index 0000000000..75cdb19c29 --- /dev/null +++ b/packages/client/locale/src/locales/pt.ts @@ -0,0 +1,47 @@ +/** Portuguese common-namespace dictionary. */ +import type { en } from './en.ts' + +/** Complete Portuguese copy for the common namespace. */ +export const pt = { + 'ok': 'OK', + 'cancel': 'Cancelar', + 'close': 'Fechar', + 'copy': 'Copiar', + 'copied': 'Copiado', + 'codeBlock.title': 'Bloco de código', + 'codeBlock.wrap': 'Quebrar linhas', + 'codeBlock.unwrap': 'Não quebrar linhas', + 'copy.failed': 'Falha na cópia', + 'copy.value': 'Copiar valor', + 'copy.json': 'Copiar JSON', + 'copy.path': 'Copiar caminho da propriedade', + 'copy.prettyJson': 'Copiar JSON formatado', + 'copy.compactJson': 'Copiar JSON compacto', + 'copy.optionsHint': '{action}; clique com o botão direito para opções de cópia', + 'retry': 'Tentar novamente', + 'loading': 'Carregando…', + 'load.failed': 'Falha ao carregar', + 'submit': 'Enviar', + 'submitting': 'Enviando…', + 'next': 'Próximo', + 'previous': 'Anterior', + 'skip': 'Pular', + 'delete': 'Excluir', + 'edit': 'Editar', + 'save': 'Salvar', + 'search': 'Pesquisar', + 'more': 'Mais', + 'collapse': 'Recolher', + 'expand': 'Expandir', + 'back': 'Voltar', + 'brand.localBuild': 'Versão local do DSH', + 'workspace.defaultName': 'Espaço de trabalho padrão', + 'unknown': 'Desconhecido', + 'none': 'Nenhum', + 'truncated': 'Truncado', + 'json.label': 'JSON', + 'markdown.footnotes': 'Notas de rodapé', + 'markdown.truncatedCharacters': '… truncado em {total} caracteres', + 'number.thousand': '{value}K', + 'number.million': '{value}M', +} satisfies Record diff --git a/packages/client/locale/src/locales/ru.ts b/packages/client/locale/src/locales/ru.ts new file mode 100644 index 0000000000..040ac417ed --- /dev/null +++ b/packages/client/locale/src/locales/ru.ts @@ -0,0 +1,47 @@ +/** Russian common-namespace dictionary. */ +import type { en } from './en.ts' + +/** Complete Russian copy for the common namespace. */ +export const ru = { + 'ok': 'OK', + 'cancel': 'Отмена', + 'close': 'Закрыть', + 'copy': 'Копировать', + 'copied': 'Скопировано', + 'codeBlock.title': 'Блок кода', + 'codeBlock.wrap': 'Переносить строки', + 'codeBlock.unwrap': 'Не переносить строки', + 'copy.failed': 'Не удалось скопировать', + 'copy.value': 'Копировать значение', + 'copy.json': 'Копировать JSON', + 'copy.path': 'Копировать путь к свойству', + 'copy.prettyJson': 'Копировать форматированный JSON', + 'copy.compactJson': 'Копировать компактный JSON', + 'copy.optionsHint': '{action}; щелкните правой кнопкой мыши, чтобы просмотреть параметры копирования', + 'retry': 'Повторить', + 'loading': 'Загрузка…', + 'load.failed': 'Не удалось загрузить', + 'submit': 'Отправить', + 'submitting': 'Отправка…', + 'next': 'Далее', + 'previous': 'Назад', + 'skip': 'Пропустить', + 'delete': 'Удалить', + 'edit': 'Редактировать', + 'save': 'Сохранить', + 'search': 'Поиск', + 'more': 'Ещё', + 'collapse': 'Свернуть', + 'expand': 'Развернуть', + 'back': 'Назад', + 'brand.localBuild': 'Локальная сборка DSH', + 'workspace.defaultName': 'Рабочая область по умолчанию', + 'unknown': 'Неизвестно', + 'none': 'Нет', + 'truncated': 'Усечено', + 'json.label': 'JSON', + 'markdown.footnotes': 'Сноски', + 'markdown.truncatedCharacters': '… усекается до символов {total}', + 'number.thousand': '{value}K', + 'number.million': '{value}M', +} satisfies Record diff --git a/packages/client/locale/src/locales/settings.ts b/packages/client/locale/src/locales/settings.ts index 76c5fd1ffb..8aafb48c44 100644 --- a/packages/client/locale/src/locales/settings.ts +++ b/packages/client/locale/src/locales/settings.ts @@ -17,3 +17,28 @@ export const en = { export const ja = { 'language.title': '言語', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'language.title': 'Idioma', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'language.title': 'Langue', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'language.title': 'Sprache', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'language.title': 'Язык', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'language.title': 'Idioma', +} satisfies Record diff --git a/packages/client/locale/tests/apply.client.spec.ts b/packages/client/locale/tests/apply.client.spec.ts index 97209c4ab3..e45dc44e69 100644 --- a/packages/client/locale/tests/apply.client.spec.ts +++ b/packages/client/locale/tests/apply.client.spec.ts @@ -155,7 +155,7 @@ describe('locale apply', () => { const { entry, instance, face } = faceOf(b.slots) // The inject-time re-sync sealed the init window: the mirror is current. expect(instance.getSnapshot().active).toBe('en') - expect(instance.getSnapshot().options.map(o => o.id)).toEqual(['zh', 'en', 'ja']) + expect(instance.getSnapshot().options.map(o => o.id)).toEqual(['zh', 'en', 'ja', 'es', 'fr', 'de', 'ru', 'pt']) // Copy rides the standard locale seat: the entry declares the namespace. expect(entry.locale).toBe(SETTINGS_NS) expect(locale.bind(SETTINGS_NS)('language.title')).toBe('Language') @@ -176,7 +176,7 @@ describe('locale apply', () => { const languagePack = b.ctx.plugin({ inject: ['locale'], apply: packCtx => packCtx.effect( - () => packCtx.locale.addLanguage({ id: 'fr', label: 'Français', fallback: 'en' }), + () => packCtx.locale.addLanguage({ id: 'it', label: 'Italiano', fallback: 'en' }), 'test language pack registration', ), }) @@ -185,33 +185,45 @@ describe('locale apply', () => { { id: 'zh', label: '中文' }, { id: 'en', label: 'English' }, { id: 'ja', label: '日本語' }, + { id: 'es', label: 'Español' }, { id: 'fr', label: 'Français' }, + { id: 'de', label: 'Deutsch' }, + { id: 'ru', label: 'Русский' }, + { id: 'pt', label: 'Português' }, + { id: 'it', label: 'Italiano' }, ]) await languagePack.dispose() - expect(instance.getSnapshot().options.map(option => option.id)).toEqual(['zh', 'en', 'ja']) + expect(instance.getSnapshot().options.map(option => option.id)).toEqual(['zh', 'en', 'ja', 'es', 'fr', 'de', 'ru', 'pt']) }) - it('restores Japanese from the Host and releases its language and dictionaries on unload', async () => { - const b = await bench('ja') + it.each([ + ['ja', '日本語', '言語', 'キャンセル'], + ['es', 'Español', 'Idioma', 'Cancelar'], + ['fr', 'Français', 'Langue', 'Annuler'], + ['de', 'Deutsch', 'Sprache', 'Abbrechen'], + ['ru', 'Русский', 'Язык', 'Отмена'], + ['pt', 'Português', 'Idioma', 'Cancelar'], + ])('restores %s from the Host and releases its language and dictionaries on unload', async (id, label, languageTitle, cancel) => { + const b = await bench(id) onTestFinished(() => b.ctx.fiber.dispose()) declareItems(b.slots) const fiber = b.ctx.plugin({ inject: [...inject], apply }) await fiber.await() const locale = b.ctx.get('locale') as LocaleRuntime const { instance, face } = faceOf(b.slots) - expect(instance.getSnapshot().active).toBe('ja') - expect(locale.bind(SETTINGS_NS)('language.title')).toBe('言語') - expect(locale.bind('common')('cancel')).toBe('キャンセル') + expect(instance.getSnapshot().active).toBe(id) + expect(locale.bind(SETTINGS_NS)('language.title')).toBe(languageTitle) + expect(locale.bind('common')('cancel')).toBe(cancel) face.setLocale('en') - face.setLocale('ja') + face.setLocale(id) await vi.waitFor(() => { expect(b.mutate).toHaveBeenCalledTimes(2) }) - expect(b.mutate.mock.calls.at(-1)?.[1]).toEqual([{ op: 'set', path: ['preference'], value: 'ja' }]) + expect(b.mutate.mock.calls.at(-1)?.[1]).toEqual([{ op: 'set', path: ['preference'], value: id }]) await fiber.dispose() expect(locale.getSnapshot().locales.map(option => option.id)).toEqual(['zh', 'en']) - expect(() => { locale.setLocale('ja') }).toThrow('not registered') - const remove = locale.addLanguage({ id: 'ja', label: '日本語', fallback: 'en' }) - locale.setLocale('ja') + expect(() => { locale.setLocale(id) }).toThrow('not registered') + const remove = locale.addLanguage({ id, label, fallback: 'en' }) + locale.setLocale(id) expect(locale.bind('common')('cancel')).toBe('cancel') remove() }) diff --git a/packages/client/modules/locale/de.json b/packages/client/modules/locale/de.json new file mode 100644 index 0000000000..4e5c22fba2 --- /dev/null +++ b/packages/client/modules/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Module", + "description": "Verwalten Sie Browser-Plug-in-Module und ihre Ladeabhängigkeiten." + } +} diff --git a/packages/client/modules/locale/es.json b/packages/client/modules/locale/es.json new file mode 100644 index 0000000000..f005ac4417 --- /dev/null +++ b/packages/client/modules/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "módulos", + "description": "Administre los módulos de complementos del navegador y sus dependencias de carga." + } +} diff --git a/packages/client/modules/locale/fr.json b/packages/client/modules/locale/fr.json new file mode 100644 index 0000000000..29801bfe86 --- /dev/null +++ b/packages/client/modules/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "modules", + "description": "Gérez les modules de plug-in du navigateur et leurs dépendances de chargement." + } +} diff --git a/packages/client/modules/locale/pt.json b/packages/client/modules/locale/pt.json new file mode 100644 index 0000000000..167cc3f507 --- /dev/null +++ b/packages/client/modules/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "módulos", + "description": "Gerencie módulos de plug-in do navegador e suas dependências de carregamento." + } +} diff --git a/packages/client/modules/locale/ru.json b/packages/client/modules/locale/ru.json new file mode 100644 index 0000000000..67041fde84 --- /dev/null +++ b/packages/client/modules/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "модули", + "description": "Управляйте подключаемыми модулями браузера и их зависимостями при загрузке." + } +} diff --git a/packages/client/product-analytics/locale/de.json b/packages/client/product-analytics/locale/de.json new file mode 100644 index 0000000000..fb577f04ad --- /dev/null +++ b/packages/client/product-analytics/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Statistiken zur Desktop-Nutzung", + "description": "Sammeln Sie bestimmte Interaktionsereignisse auf dem Desktop und übermitteln Sie sie an den Produktstatistikdienst." + } +} diff --git a/packages/client/product-analytics/locale/es.json b/packages/client/product-analytics/locale/es.json new file mode 100644 index 0000000000..838528b1c4 --- /dev/null +++ b/packages/client/product-analytics/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Estadísticas de uso de escritorio", + "description": "Recopile eventos de interacción específicos en el escritorio y envíelos al servicio de estadísticas del producto." + } +} diff --git a/packages/client/product-analytics/locale/fr.json b/packages/client/product-analytics/locale/fr.json new file mode 100644 index 0000000000..2edef0a2b3 --- /dev/null +++ b/packages/client/product-analytics/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Statistiques d'utilisation du bureau", + "description": "Collectez les événements d'interaction spécifiés sur le bureau et soumettez-les au service de statistiques du produit." + } +} diff --git a/packages/client/product-analytics/locale/pt.json b/packages/client/product-analytics/locale/pt.json new file mode 100644 index 0000000000..de66d5a74b --- /dev/null +++ b/packages/client/product-analytics/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Estatísticas de uso da área de trabalho", + "description": "Colete eventos de interação especificados na área de trabalho e envie-os ao serviço de estatísticas do produto." + } +} diff --git a/packages/client/product-analytics/locale/ru.json b/packages/client/product-analytics/locale/ru.json new file mode 100644 index 0000000000..f089774778 --- /dev/null +++ b/packages/client/product-analytics/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Статистика использования рабочего стола", + "description": "Собирайте указанные события взаимодействия на рабочем столе и отправляйте их в сервис статистики продукта." + } +} diff --git a/packages/client/resources/locale/de.json b/packages/client/resources/locale/de.json new file mode 100644 index 0000000000..c5d2e7508e --- /dev/null +++ b/packages/client/resources/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ressourcen", + "description": "Lösen Sie Ressourcenadressen wie Dateien in Inhalte auf, die von der Schnittstelle gelesen werden können." + } +} diff --git a/packages/client/resources/locale/es.json b/packages/client/resources/locale/es.json new file mode 100644 index 0000000000..a09f476f6d --- /dev/null +++ b/packages/client/resources/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "recursos", + "description": "Resuelva direcciones de recursos, como archivos, en contenido que la interfaz pueda leer." + } +} diff --git a/packages/client/resources/locale/fr.json b/packages/client/resources/locale/fr.json new file mode 100644 index 0000000000..4c02e4e9fe --- /dev/null +++ b/packages/client/resources/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "ressources", + "description": "Résolvez les adresses de ressources telles que les fichiers en contenu pouvant être lu par l'interface." + } +} diff --git a/packages/client/resources/locale/pt.json b/packages/client/resources/locale/pt.json new file mode 100644 index 0000000000..9b5f1c60fa --- /dev/null +++ b/packages/client/resources/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "recursos", + "description": "Resolva endereços de recursos, como arquivos, em conteúdo que possa ser lido pela interface." + } +} diff --git a/packages/client/resources/locale/ru.json b/packages/client/resources/locale/ru.json new file mode 100644 index 0000000000..e5571b2d32 --- /dev/null +++ b/packages/client/resources/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "ресурсы", + "description": "Преобразуйте адреса ресурсов, такие как файлы, в контент, который может быть прочитан интерфейсом." + } +} diff --git a/packages/client/shortcuts/locale/de.json b/packages/client/shortcuts/locale/de.json new file mode 100644 index 0000000000..0de9fbe7f1 --- /dev/null +++ b/packages/client/shortcuts/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Abkürzungen", + "description": "Registrieren Sie Tastenkombinationen für Anwendungen und verteilen Sie Tastenoperationen auf entsprechende Funktionen." + } +} diff --git a/packages/client/shortcuts/locale/es.json b/packages/client/shortcuts/locale/es.json new file mode 100644 index 0000000000..e6d9faac53 --- /dev/null +++ b/packages/client/shortcuts/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "atajos", + "description": "Registre las teclas de acceso directo de la aplicación y distribuya las operaciones clave a las funciones correspondientes." + } +} diff --git a/packages/client/shortcuts/locale/fr.json b/packages/client/shortcuts/locale/fr.json new file mode 100644 index 0000000000..85dcaf0f78 --- /dev/null +++ b/packages/client/shortcuts/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "raccourcis", + "description": "Enregistrez les touches de raccourci de l'application et distribuez les opérations clés aux fonctions correspondantes." + } +} diff --git a/packages/client/shortcuts/locale/pt.json b/packages/client/shortcuts/locale/pt.json new file mode 100644 index 0000000000..10f9714ea8 --- /dev/null +++ b/packages/client/shortcuts/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "atalhos", + "description": "Registre teclas de atalho do aplicativo e distribua as operações das teclas para as funções correspondentes." + } +} diff --git a/packages/client/shortcuts/locale/ru.json b/packages/client/shortcuts/locale/ru.json new file mode 100644 index 0000000000..eedd6069c5 --- /dev/null +++ b/packages/client/shortcuts/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "ярлыки", + "description": "Зарегистрируйте сочетания клавиш приложения и распределите ключевые операции по соответствующим функциям." + } +} diff --git a/packages/client/ui-agent-preset/locale/de.json b/packages/client/ui-agent-preset/locale/de.json new file mode 100644 index 0000000000..bb0817b9bb --- /dev/null +++ b/packages/client/ui-agent-preset/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Standardschnittstelle des Agenten", + "description": "Wählen Sie Agent-Standardeinstellungen für aktuelle und neue Sitzungen aus und bearbeiten Sie die von den Standardeinstellungen verwendeten Plugins." + } +} diff --git a/packages/client/ui-agent-preset/locale/es.json b/packages/client/ui-agent-preset/locale/es.json new file mode 100644 index 0000000000..71f9b56076 --- /dev/null +++ b/packages/client/ui-agent-preset/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz predeterminada del agente", + "description": "Seleccione los valores predeterminados del agente para las sesiones actuales y nuevas, y edite los complementos utilizados por los valores predeterminados." + } +} diff --git a/packages/client/ui-agent-preset/locale/fr.json b/packages/client/ui-agent-preset/locale/fr.json new file mode 100644 index 0000000000..55d48a7007 --- /dev/null +++ b/packages/client/ui-agent-preset/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface par défaut de l'agent", + "description": "Sélectionnez les valeurs par défaut de l'agent pour les sessions actuelles et les nouvelles, et modifiez les plugins utilisés par les valeurs par défaut." + } +} diff --git a/packages/client/ui-agent-preset/locale/pt.json b/packages/client/ui-agent-preset/locale/pt.json new file mode 100644 index 0000000000..794e0ca90c --- /dev/null +++ b/packages/client/ui-agent-preset/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface padrão do agente", + "description": "Selecione Padrões do agente para sessões atuais e novas e edite os plug-ins usados pelos padrões." + } +} diff --git a/packages/client/ui-agent-preset/locale/ru.json b/packages/client/ui-agent-preset/locale/ru.json new file mode 100644 index 0000000000..5ee3dcb323 --- /dev/null +++ b/packages/client/ui-agent-preset/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Интерфейс агента по умолчанию", + "description": "Выберите параметры агента по умолчанию для текущего и нового сеансов и отредактируйте плагины, используемые по умолчанию." + } +} diff --git a/packages/client/ui-agent-preset/src/client/guide-locales.ts b/packages/client/ui-agent-preset/src/client/guide-locales.ts index ff5a5b5529..7e4392dfca 100644 --- a/packages/client/ui-agent-preset/src/client/guide-locales.ts +++ b/packages/client/ui-agent-preset/src/client/guide-locales.ts @@ -173,3 +173,378 @@ export const guideJa = { 'guideCordisExplanation': '### 作成できるもの\n\nクリエイターモードには標準的なタスクツールに加え、ランタイムの検査、Cordis プラグインやエージェントプリセットの作成ガイドが含まれます。機能や UI を追加するプラグインを作成することも、特定の作業向けにツールとプロンプトを組み合わせたプリセットを作成することもできます。\n\n### プラグインとモード\n\nプラグインはツール、サービス接続、UI エントリなど、DSH に機能を追加します。モードはエージェントプリセットであり、ツールを選択し、タスク内でのエージェントの動作を定義します。プラグインはカスタムプリセットに含めることができます。\n\n### 結果を反映させる方法\n\nソースコードを生成するだけでなく、エージェントにインストールと確認を依頼してください。プラグインは変更内容によっては即座に読み込まれるか、再起動が必要になる場合があります。新しく作成したプリセットは、新しいタスクを始めるときに選択されます。', 'guideCordisUsage': '### UI を追加する\n\n> サイドバーにプロジェクトメモのエントリを追加する DSH プラグインを作成してください。このワークスペース内の Markdown ファイルを閲覧でき、選択したメモをプレビューできるようにしてください。インストールしてページが開くことを確認してください。\n\n期待される出力: 動作するエントリとプレビューページを備えた、インストール済みのプラグイン。残っている有効化手順があればそれも含みます。\n\n### ツールを追加する\n\n> このプロジェクトのテストレポートを読み、失敗したテストを要約するツールを備えたプラグインを作成してください。登録し、サンプルのレポートで確認してください。\n\n期待される出力: 呼び出し可能なツールを備えたプラグインと、確認済みのサンプル呼び出し。\n\n### 独自のモードを作成する\n\n> 標準モードをベースに「コードレビュー」モードを作成してください。潜在的なバグとテストの不足を優先し、ファイルパスと行番号を示し、ファイルを変更する前に確認を求めるようにしてください。選択可能なプリセットとして保存してください。\n\n期待される出力: 新しいタスク用のカスタムプリセット。これらのレビュー指示はエージェントを導くものであり、実行できる操作は権限設定によって決まります。', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const guideEs = { + modeExplanation: 'Detalles del modo', + howToUse: 'como usar', + guideSections: 'Secciones de guía', + guideExampleTask: 'Tarea de ejemplo', + guideCopy: 'Copiar', + guideCopied: 'Copiado', + guideFootnotes: 'Notas a pie de página', + guideStandardIntro: 'Elija el modo Estándar al iniciar una nueva tarea. Describe lo que quieres lograr, señala los archivos relevantes y explica cómo verificar el resultado.', + guideStandardExplanation: [ + '### Cómo funciona', + 'El agente llama a herramientas directamente para leer y editar archivos, buscar y ejecutar comandos de terminal. Incluye habilidades, planificación, objetivos, subagentes, flujos de trabajo, gestión de complementos y compactación de contexto.', + '### Cuándo elegirlo', + 'Comience aquí para la codificación, el trabajo con archivos y la investigación diaria. El modo estándar también puede escribir scripts y procesar archivos en lotes. PTC cambia la forma en que se organizan las llamadas a herramientas; no es necesario para tareas por lotes.', + ].join('\n\n\n\n'), + guideStandardUsage: [ + '### Corregir un error', + '> Descubra por qué enviar el formulario de búsqueda dos veces hace que los resultados desaparezcan. Arréglalo y ejecuta las pruebas pertinentes. Explique la causa y qué cambió.', + 'Resultado esperado: un cambio de código, los resultados de las pruebas relevantes y una explicación de la causa.', + '### Organizar notas del proyecto', + '> Lea las Markdown notas de este proyecto. Resuma las decisiones acordadas y las preguntas abiertas, con enlaces a los archivos fuente.', + 'Resultado esperado: un resumen con referencias que puede comparar con las notas originales.', + ].join('\n\n\n\n'), + guidePtcIntro: 'Elija el modo PTC al iniciar una nueva tarea. Especifique los archivos de entrada, las reglas de procesamiento y el formato de salida. El agente escribe el código.', + guidePtcExplanation: [ + '### Cómo se llaman las herramientas', + 'PTC significa llamada a herramientas programáticas. En este ajuste preestablecido integrado, el agente usa run_code para escribir un programa TypeScript que llama a herramientas a través de un SDK generado. El programa puede utilizar bucles, condiciones, manejo de errores y llamadas simultáneas cuando corresponda.', + '### Lo que llega al modelo', + 'Los resultados de la herramienta llegan primero al programa, que puede filtrarlos y combinarlos. El modelo recibe lo que el programa imprime o devuelve; Los resultados de la imagen se adjuntan por separado. Las llamadas a herramientas anidadas aún se registran y permanecen sujetas a los permisos de la herramienta.', + '### Comparado con el modo Estándar', + 'Ambos modos pueden manejar tareas de codificación y por lotes. El modo estándar expone herramientas individuales directamente; PTC organiza llamadas a herramientas en código. El ajuste preestablecido actual PTC ​​deja las herramientas de administración de complementos y flujo de trabajo deshabilitadas. La velocidad y el uso de tokens dependen de la tarea y de cómo el programa maneja sus resultados.', + ].join('\n\n\n\n'), + guidePtcUsage: [ + '### Verifique un conjunto de archivos de configuración', + '> Verifique todos los JSON archivos en configs/. Enumere los campos obligatorios faltantes y los valores no válidos en el archivo Schema.json. Guarde un CSV con una fila por número. Incluya archivos ilegibles en el informe y siga revisando el resto. Deje los archivos originales sin cambios.', + 'Resultado esperado: un resumen del problema y un informe CSV. El programa puede repetir las mismas comprobaciones, gestionar fallos individuales y recopilar los resultados.', + '### Resumir registros de errores', + '> Analizar los archivos de registro en logs/. Agrupe errores por servicio y tipo de error. Muestra los diez grupos más frecuentes y un ejemplo de cada uno. Guarde los recuentos completos en un CSV.', + 'Resultado esperado: los principales grupos de errores y una tabla de recuento completa. Los datos intermedios se pueden agregar en el programa antes de que el resumen llegue al modelo.', + ].join('\n\n\n\n'), + guideMinimalIntro: 'Elija el modo mínimo para una nueva tarea. Para realizar una comparación, mantenga constantes el modelo, los permisos, la entrada y el estado inicial del espacio de trabajo en todas las ejecuciones.', + guideMinimalExplanation: [ + '### ¿Qué está incluido?', + 'Una herramienta de shell persistente, read_image, y un indicador de sistema fijo. La lectura de imágenes requiere un modelo compatible con imágenes. La historia más antigua se compacta automáticamente bajo la presión del contexto; use /compact mientras el agente esté inactivo para compactarlo manualmente. El ajuste preestablecido integrado no carga las habilidades, la planificación ni el contexto de tiempo de ejecución estándar.', + '### Cuándo elegirlo', + 'Úselo como base para experimentos y comparaciones. Todavía puede leer archivos y ejecutar scripts mediante comandos de shell, pero ofrece menos formas integradas de gestionar una tarea larga. Menos herramientas no necesariamente lo hace más fácil para un principiante.', + ].join('\n\n\n\n'), + guideMinimalUsage: [ + '### Comparar el rendimiento en una pequeña corrección de errores', + '> Ejecute las pruebas para este proyecto, encuentre la causa del error y realice la solución más pequeña. Ejecute las pruebas pertinentes nuevamente e informe el resultado.', + 'Ejecute la misma tarea por separado en los modos Estándar y Mínimo desde el mismo estado inicial. Compare la finalización de tareas, las llamadas a herramientas y los cambios resultantes. El modo mínimo realiza el trabajo a través de comandos de terminal.', + ].join('\n\n\n\n'), + guideCordisIntro: 'Elija el modo Creador para una nueva tarea. Describe la capacidad que deseas, dónde debería aparecer y cómo la verificarás.', + guideCordisExplanation: [ + '### Lo que puedes crear', + 'El modo Creador incluye las herramientas de tareas estándar además de inspección del tiempo de ejecución y orientación para crear Cordis complementos y ajustes preestablecidos de agentes. Puede crear un complemento que agregue una capacidad o interfaz de usuario, o un ajuste preestablecido que combine herramientas e indicaciones para un trabajo en particular.', + '### Complementos y modos', + 'Un complemento agrega capacidades a DSH, como una herramienta, una conexión de servicio o una entrada de UI. Un modo es un ajuste preestablecido del agente que selecciona herramientas y define cómo trabaja el agente en una tarea. Se puede incluir un complemento en un ajuste preestablecido personalizado.', + '### Cómo surte efecto el resultado', + 'Pídale al agente que instale y verifique el resultado, no solo que genere el código fuente. Un complemento puede cargarse inmediatamente o requerir un reinicio, dependiendo de lo que cambie. Se selecciona un ajuste preestablecido recién creado al iniciar una nueva tarea.', + ].join('\n\n\n\n'), + guideCordisUsage: [ + '### Agregar una interfaz de usuario', + '> Cree un complemento DSH que agregue una entrada de notas del proyecto a la barra lateral. Permítanme explorar los Markdown archivos en este espacio de trabajo y obtener una vista previa de una nota seleccionada. Instálalo y verifica que se abre la página.', + 'Resultado esperado: un complemento instalado con una entrada funcional y una página de vista previa, además de los pasos de activación restantes.', + '### Agregar una herramienta', + '> Cree un complemento con una herramienta que lea el informe de prueba de este proyecto y resuma las pruebas fallidas. Regístrelo y verifíquelo con un informe de muestra.', + 'Resultado esperado: un complemento con una herramienta invocable y una llamada de muestra verificada.', + '### Crear mi propio modo', + '> Cree un modo de “Revisión de código” basado en el modo Estándar. Haga que priorice posibles errores y pruebe las lagunas, cite rutas y líneas de archivos y pregunte antes de modificar archivos. Guárdelo como un ajuste preestablecido seleccionable.', + 'Resultado esperado: un ajuste preestablecido personalizado para nuevas tareas. Estas instrucciones de revisión guían al agente; La configuración de permisos determina qué acciones puede ejecutar.', + ].join('\n\n\n\n'), +} satisfies typeof guideEn + +/** French dictionary, checked against the English keys. */ +export const guideFr = { + modeExplanation: 'Détails du mode', + howToUse: 'Comment utiliser', + guideSections: 'Sections du guide', + guideExampleTask: 'Exemple de tâche', + guideCopy: 'Copier', + guideCopied: 'Copié', + guideFootnotes: 'Notes de bas de page', + guideStandardIntro: 'Choisissez le mode Standard lorsque vous démarrez une nouvelle tâche. Décrivez ce que vous souhaitez accomplir, pointez vers les fichiers pertinents et expliquez comment vérifier le résultat.', + guideStandardExplanation: [ + '### Comment ça marche', + "L'agent appelle directement des outils pour lire et modifier des fichiers, rechercher et exécuter des commandes de terminal. Il comprend les compétences, la planification, les objectifs, les sous-agents, les flux de travail, la gestion des plugins et le compactage du contexte.", + '### Quand le choisir', + "Commencez ici pour le codage quotidien, le travail sur les fichiers et la recherche. Le mode standard peut également écrire des scripts et traiter des fichiers par lots. PTC modifie la façon dont les appels d'outils sont organisés ; il n'est pas requis pour les tâches par lots.", + ].join('\n\n\n\n'), + guideStandardUsage: [ + "### Correction d'un bug", + '> Découvrez pourquoi le fait de soumettre deux fois le formulaire de recherche fait disparaître les résultats. Corrigez-le et exécutez les tests appropriés. Expliquez la cause et ce qui a changé.', + 'Résultat attendu : un changement de code, les résultats des tests pertinents et une explication de la cause.', + '### Organiser les notes de projet', + '> Lisez les Markdown notes de ce projet. Résumez les décisions convenues et les questions ouvertes, avec des liens vers les fichiers sources.', + 'Résultat attendu : un résumé avec des références que vous pouvez vérifier par rapport aux notes originales.', + ].join('\n\n\n\n'), + guidePtcIntro: "Choisissez le mode PTC lorsque vous démarrez une nouvelle tâche. Spécifiez les fichiers d'entrée, les règles de traitement et le format de sortie. L'agent écrit le code.", + guidePtcExplanation: [ + '### Comment sont appelés les outils', + "PTC signifie appel d'outil de programmation. Dans ce préréglage intégré, l'agent utilise run_code pour écrire un programme TypeScript qui appelle des outils via un SDK généré. Le programme peut utiliser des boucles, des conditions, une gestion des erreurs et des appels simultanés, le cas échéant.", + '### Ce qui arrive au modèle', + "Les résultats des outils parviennent d’abord au programme, qui peut les filtrer et les combiner. Le modèle reçoit ce que le programme imprime ou renvoie ; les résultats des images sont joints séparément. Les appels d'outils imbriqués sont toujours enregistrés et restent soumis aux autorisations de l'outil.", + '### Par rapport au mode Standard', + "Les deux modes peuvent gérer les tâches de codage et par lots. Le mode standard expose directement les outils individuels ; PTC organise les appels d'outils dans le code. Le préréglage PTC actuel laisse les outils de gestion de flux de travail et de plugins désactivés. La vitesse et l'utilisation des jetons dépendent de la tâche et de la manière dont le programme gère ses résultats.", + ].join('\n\n\n\n'), + guidePtcUsage: [ + '### Vérifier un ensemble de fichiers de configuration', + '> Vérifiez tous les JSON fichiers dans configs/. Répertoriez les champs obligatoires manquants et les valeurs non valides par rapport à schema.json. Enregistrez un CSV avec une ligne par numéro. Incluez les fichiers illisibles dans le rapport et continuez à vérifier le reste. Laissez les fichiers originaux inchangés.', + 'Résultat attendu : un résumé du problème et un rapport CSV. Le programme peut répéter les mêmes vérifications, gérer les échecs individuels et collecter les résultats.', + "### Résumer les journaux d'erreurs", + '> Analysez les fichiers journaux dans logs/. Regroupez les erreurs par service et type d’erreur. Montrez les dix groupes les plus fréquents et un exemple de chacun. Enregistrez les décomptes complets dans un CSV.', + "Résultat attendu : les principaux groupes d’erreurs et un tableau de décompte complet. Les données intermédiaires peuvent être agrégées dans le programme avant que le résumé n'atteigne le modèle.", + ].join('\n\n\n\n'), + guideMinimalIntro: 'Choisissez le mode Minimal pour une nouvelle tâche. À des fins de comparaison, maintenez le modèle, les autorisations, l’entrée et l’état de départ de l’espace de travail constants d’une exécution à l’autre.', + guideMinimalExplanation: [ + '### Ce qui est inclus', + "Un outil shell persistant, read_image et une invite système fixe. La lecture d'images nécessite un modèle compatible avec les images. L’historique plus ancien est automatiquement compacté sous la pression du contexte ; utilisez /compact pendant que l'agent est inactif pour le compacter manuellement. Le préréglage intégré ne charge pas les compétences, la planification ou le contexte d'exécution standard.", + '### Quand le choisir', + 'Utilisez-le comme base de référence pour des expériences et des comparaisons. Il peut toujours lire des fichiers et exécuter des scripts via des commandes shell, mais offre moins de moyens intégrés pour gérer une tâche longue. Moins d’outils ne facilite pas nécessairement la tâche d’un débutant.', + ].join('\n\n\n\n'), + guideMinimalUsage: [ + '### Comparez les performances sur une petite correction de bug', + "> Exécutez les tests pour ce projet, trouvez la cause de l'échec et effectuez le moindre correctif. Exécutez à nouveau les tests pertinents et rapportez le résultat.", + "Exécutez la même tâche séparément en modes Standard et Minimal à partir du même état de départ. Comparez l'achèvement des tâches, les appels d'outils et les modifications qui en résultent. Le mode minimal effectue le travail via les commandes du terminal.", + ].join('\n\n\n\n'), + guideCordisIntro: 'Choisissez le mode Créateur pour une nouvelle tâche. Décrivez la fonctionnalité souhaitée, où elle doit apparaître et comment vous la vérifierez.', + guideCordisExplanation: [ + '### Ce que vous pouvez créer', + "Le mode Créateur inclut les outils de tâches standard, ainsi qu'une inspection d'exécution et des conseils pour la création de Cordis plug-ins et préréglages d'agent. Il peut créer un plugin qui ajoute une fonctionnalité ou une interface utilisateur, ou un préréglage combinant des outils et des invites pour une tâche particulière.", + '### Plugins et modes', + "Un plug-in ajoute des fonctionnalités à DSH, telles qu'un outil, une connexion à un service ou une entrée d'interface utilisateur. Un mode est un préréglage d'agent qui sélectionne les outils et définit la manière dont l'agent fonctionne dans une tâche. Un plugin peut être inclus dans un préréglage personnalisé.", + '### Comment le résultat prend effet', + "Demandez à l'agent d'installer et de vérifier le résultat, pas seulement de générer le code source. Un plugin peut se charger immédiatement ou nécessiter un redémarrage, en fonction de ce qu'il modifie. Un préréglage nouvellement créé est sélectionné lors du démarrage d'une nouvelle tâche.", + ].join('\n\n\n\n'), + guideCordisUsage: [ + '### Ajouter une interface utilisateur', + "> Créez un plugin DSH qui ajoute une entrée de notes de projet à la barre latérale. Permettez-moi de parcourir les Markdown fichiers de cet espace de travail et de prévisualiser une note sélectionnée. Installez-le et vérifiez que la page s'ouvre.", + "Résultat attendu : un plugin installé avec une page d'entrée et d'aperçu fonctionnelle, ainsi que toutes les étapes d'activation restantes.", + '### Ajouter un outil', + '> Créez un plugin avec un outil qui lit le rapport de test de ce projet et résume les tests échoués. Enregistrez-le et vérifiez-le avec un exemple de rapport.', + "Résultat attendu : un plugin avec un outil appelable et un exemple d'appel vérifié.", + '### Créer mon propre mode', + '> Créer un mode « Revue de code » basé sur le mode Standard. Demandez-lui de prioriser les bogues potentiels et de tester les lacunes, de citer les chemins et les lignes des fichiers et de demander avant de modifier les fichiers. Enregistrez-le en tant que préréglage sélectionnable.', + "Résultat attendu : un préréglage personnalisé pour les nouvelles tâches. Ces instructions de révision guident l'agent ; les paramètres d'autorisation déterminent les actions qu'il peut exécuter.", + ].join('\n\n\n\n'), +} satisfies typeof guideEn + +/** German dictionary, checked against the English keys. */ +export const guideDe = { + modeExplanation: 'Modusdetails', + howToUse: 'Wie zu verwenden', + guideSections: 'Leitfadenabschnitte', + guideExampleTask: 'Beispielaufgabe', + guideCopy: 'Kopieren', + guideCopied: 'Kopiert', + guideFootnotes: 'Fußnoten', + guideStandardIntro: 'Wählen Sie den Standardmodus, wenn Sie eine neue Aufgabe starten. Beschreiben Sie, was Sie erreichen möchten, zeigen Sie auf die relevanten Dateien und erklären Sie, wie Sie das Ergebnis überprüfen können.', + guideStandardExplanation: [ + '### Wie es funktioniert', + 'Der Agent ruft Tools direkt auf, um Dateien zu lesen und zu bearbeiten, zu suchen und Terminalbefehle auszuführen. Es umfasst Fähigkeiten, Planung, Ziele, Subagenten, Arbeitsabläufe, Plugin-Verwaltung und Kontextkomprimierung.', + '### Wann man es wählt', + 'Beginnen Sie hier mit alltäglicher Codierung, Dateiarbeit und Recherche. Im Standardmodus können auch Skripts geschrieben und Dateien stapelweise verarbeitet werden. PTC ändert die Organisation von Toolaufrufen; Für Batch-Aufgaben ist es nicht erforderlich.', + ].join('\n\n\n\n'), + guideStandardUsage: [ + '### Einen Fehler beheben', + '> Finden Sie heraus, warum das zweimalige Absenden des Suchformulars dazu führt, dass die Ergebnisse verschwinden. Beheben Sie das Problem und führen Sie die entsprechenden Tests durch. Erklären Sie die Ursache und was sich geändert hat.', + 'Erwartete Ausgabe: eine Codeänderung, die relevanten Testergebnisse und eine Erklärung der Ursache.', + '### Projektnotizen organisieren', + '> Lesen Sie die Markdown-Hinweise in diesem Projekt. Fassen Sie die vereinbarten Entscheidungen und offenen Fragen zusammen, mit Links zu den Quelldateien.', + 'Erwartete Ausgabe: eine Zusammenfassung mit Referenzen, die Sie mit den Originalnotizen vergleichen können.', + ].join('\n\n\n\n'), + guidePtcIntro: 'Wählen Sie den Modus PTC, wenn Sie eine neue Aufgabe starten. Geben Sie die Eingabedateien, Verarbeitungsregeln und das Ausgabeformat an. Der Agent schreibt den Code.', + guidePtcExplanation: [ + '### Wie Werkzeuge heißen', + 'PTC bedeutet Programmatic Tool Calling. In dieser integrierten Voreinstellung verwendet der Agent run_code, um ein TypeScript-Programm zu schreiben, das Tools über ein generiertes SDK aufruft. Das Programm kann gegebenenfalls Schleifen, Bedingungen, Fehlerbehandlung und gleichzeitige Aufrufe verwenden.', + '### Was das Modell erreicht', + 'Werkzeugergebnisse gelangen zunächst in das Programm, das diese filtern und kombinieren kann. Das Modell empfängt, was das Programm ausgibt oder zurückgibt; Bildergebnisse sind separat beigefügt. Verschachtelte Werkzeugaufrufe werden weiterhin aufgezeichnet und unterliegen weiterhin den Werkzeugberechtigungen.', + '### Im Vergleich zum Standardmodus', + 'Beide Modi können Codierungs- und Batch-Aufgaben bewältigen. Im Standardmodus werden einzelne Tools direkt verfügbar gemacht. PTC organisiert Toolaufrufe im Code. Die aktuelle Voreinstellung PTC lässt die Workflow- und Plugin-Verwaltungstools deaktiviert. Geschwindigkeit und Token-Nutzung hängen von der Aufgabe ab und davon, wie das Programm mit seinen Ergebnissen umgeht.', + ].join('\n\n\n\n'), + guidePtcUsage: [ + '### Überprüfen Sie eine Reihe von Konfigurationsdateien', + '> Überprüfen Sie alle JSON Dateien in configs/. Fehlende Pflichtfelder und ungültige Werte für schema.json auflisten. Speichern Sie eine CSV-Datei mit einer Zeile pro Ausgabe. Fügen Sie unleserliche Dateien in den Bericht ein und überprüfen Sie den Rest weiter. Lassen Sie die Originaldateien unverändert.', + 'Erwartete Ausgabe: eine Problemzusammenfassung und ein CSV-Bericht. Das Programm kann dieselben Prüfungen wiederholen, einzelne Fehler behandeln und die Ergebnisse sammeln.', + '### Fehlerprotokolle zusammenfassen', + '> Analysieren Sie die Protokolldateien in logs/. Gruppieren Sie Fehler nach Dienst und Fehlertyp. Zeigen Sie die zehn häufigsten Gruppen und jeweils ein Beispiel. Speichern Sie die vollständigen Zählungen in einer CSV-Datei.', + 'Erwartete Ausgabe: die Top-Fehlergruppen und eine vollständige Zähltabelle. Zwischendaten können im Programm aggregiert werden, bevor die Zusammenfassung das Modell erreicht.', + ].join('\n\n\n\n'), + guideMinimalIntro: 'Wählen Sie den Minimalmodus für eine neue Aufgabe. Halten Sie für einen Vergleich das Modell, die Berechtigungen, die Eingabe und den Status des Startarbeitsbereichs über alle Ausführungen hinweg konstant.', + guideMinimalExplanation: [ + '### Was ist enthalten', + 'Ein persistentes Shell-Tool, read_image, und eine feste Systemeingabeaufforderung. Das Lesen von Bildern erfordert ein bildfähiges Modell. Der ältere Verlauf wird unter Kontextdruck automatisch komprimiert; Verwenden Sie /compact, während der Agent inaktiv ist, um ihn manuell zu komprimieren. Die integrierte Voreinstellung lädt weder Skills, Planung noch den Standardlaufzeitkontext.', + '### Wann man es wählt', + 'Verwenden Sie es als Grundlage für Experimente und Vergleiche. Es kann weiterhin Dateien lesen und Skripte über Shell-Befehle ausführen, bietet jedoch weniger integrierte Möglichkeiten zur Verwaltung einer langen Aufgabe. Weniger Werkzeuge machen es einem Anfänger nicht unbedingt einfacher.', + ].join('\n\n\n\n'), + guideMinimalUsage: [ + '### Vergleichen Sie die Leistung mit einer kleinen Fehlerbehebung', + '> Führen Sie die Tests für dieses Projekt durch, finden Sie die Fehlerursache und nehmen Sie die kleinste Lösung vor. Führen Sie die entsprechenden Tests erneut durch und melden Sie das Ergebnis.', + 'Führen Sie dieselbe Aufgabe separat im Standard- und Minimalmodus aus, und zwar im selben Startzustand. Vergleichen Sie die Aufgabenerledigung, Werkzeugaufrufe und die daraus resultierenden Änderungen. Der Minimalmodus führt die Arbeit über Terminalbefehle aus.', + ].join('\n\n\n\n'), + guideCordisIntro: 'Wählen Sie den Erstellermodus für eine neue Aufgabe. Beschreiben Sie die gewünschte Funktion, wo sie angezeigt werden soll und wie Sie sie überprüfen.', + guideCordisExplanation: [ + '### Was Sie erstellen können', + 'Der Erstellermodus umfasst die Standardaufgabentools sowie eine Laufzeitprüfung und Anleitungen zum Erstellen von Cordis-Plugins und Agent-Voreinstellungen. Es kann ein Plugin erstellt werden, das eine Funktion oder Benutzeroberfläche hinzufügt, oder eine Voreinstellung, die Tools und Eingabeaufforderungen für einen bestimmten Job kombiniert.', + '### Plugins und Modi', + 'Ein Plugin fügt DSH Funktionen hinzu, beispielsweise ein Tool, eine Dienstverbindung oder einen UI-Eintrag. Ein Modus ist eine Agentenvoreinstellung, die Tools auswählt und definiert, wie der Agent in einer Aufgabe arbeitet. Ein Plugin kann in eine benutzerdefinierte Voreinstellung eingebunden werden.', + '### Wie das Ergebnis wirksam wird', + 'Bitten Sie den Agenten, das Ergebnis zu installieren und zu überprüfen und nicht nur Quellcode zu generieren. Abhängig von den Änderungen kann ein Plugin sofort geladen werden oder einen Neustart erfordern. Beim Starten einer neuen Aufgabe wird eine neu erstellte Voreinstellung ausgewählt.', + ].join('\n\n\n\n'), + guideCordisUsage: [ + '### Fügen Sie eine Benutzeroberfläche hinzu', + '> Erstellen Sie ein DSH-Plugin, das der Seitenleiste einen Eintrag für Projektnotizen hinzufügt. Lassen Sie mich die Markdown Dateien in diesem Arbeitsbereich durchsuchen und eine Vorschau einer ausgewählten Notiz anzeigen. Installieren Sie es und stellen Sie sicher, dass die Seite geöffnet wird.', + 'Erwartete Ausgabe: ein installiertes Plugin mit einer funktionierenden Einstiegs- und Vorschauseite sowie allen verbleibenden Aktivierungsschritten.', + '### Ein Werkzeug hinzufügen', + '> Erstellen Sie ein Plugin mit einem Tool, das den Testbericht dieses Projekts liest und die fehlgeschlagenen Tests zusammenfasst. Registrieren Sie es und überprüfen Sie es anhand eines Beispielberichts.', + 'Erwartete Ausgabe: ein Plugin mit einem aufrufbaren Tool und einem verifizierten Beispielaufruf.', + '### Erstelle meinen eigenen Modus', + '> Erstellen Sie einen „Code Review“-Modus basierend auf dem Standardmodus. Lassen Sie potenzielle Fehler priorisieren und Lücken testen, geben Sie Dateipfade und -zeilen an und fragen Sie nach, bevor Sie Dateien ändern. Speichern Sie es als auswählbare Voreinstellung.', + 'Erwartete Ausgabe: eine benutzerdefinierte Voreinstellung für neue Aufgaben. Diese Überprüfungsanweisungen leiten den Agenten; Berechtigungseinstellungen bestimmen, welche Aktionen ausgeführt werden können.', + ].join('\n\n\n\n'), +} satisfies typeof guideEn + +/** Russian dictionary, checked against the English keys. */ +export const guideRu = { + modeExplanation: 'Подробности режима', + howToUse: 'Как использовать', + guideSections: 'Разделы руководства', + guideExampleTask: 'Пример задачи', + guideCopy: 'Копировать', + guideCopied: 'Скопировано', + guideFootnotes: 'Сноски', + guideStandardIntro: 'Выбирайте стандартный режим при запуске новой задачи. Опишите, чего вы хотите добиться, укажите соответствующие файлы и объясните, как проверить результат.', + guideStandardExplanation: [ + '### Как это работает', + 'Агент напрямую вызывает инструменты для чтения и редактирования файлов, поиска и выполнения команд терминала. Он включает в себя навыки, планирование, цели, субагенты, рабочие процессы, управление плагинами и сжатие контекста.', + '### Когда это выбирать', + 'Начните здесь ежедневное программирование, работу с файлами и исследования. Стандартный режим также позволяет писать сценарии и обрабатывать файлы в пакетном режиме. PTC изменяет организацию вызовов инструментов; для пакетных задач это не требуется.', + ].join('\n\n\n\n'), + guideStandardUsage: [ + '### Исправить ошибку', + '> Узнайте, почему при двойной отправке формы поиска результаты исчезают. Исправьте это и запустите соответствующие тесты. Объясните причину и что изменилось.', + 'Ожидаемый результат: изменение кода, соответствующие результаты испытаний и объяснение причины.', + '### Организация заметок по проекту', + '> Прочтите примечания Markdown в этом проекте. Кратко изложите согласованные решения и открытые вопросы со ссылками на исходные файлы.', + 'Ожидаемый результат: резюме со ссылками, которые вы можете сверить с исходными заметками.', + ].join('\n\n\n\n'), + guidePtcIntro: 'Выберите режим PTC при запуске новой задачи. Укажите входные файлы, правила обработки и выходной формат. Агент пишет код.', + guidePtcExplanation: [ + '### Как называются инструменты', + 'PTC означает программный вызов инструмента. В этой встроенной настройке агент использует run_code для написания программы TypeScript, которая вызывает инструменты через сгенерированный SDK. Программа может использовать циклы, условия, обработку ошибок и параллельные вызовы, где это необходимо.', + '### Что достигает модели', + 'Результаты инструмента сначала поступают в программу, которая может их фильтровать и комбинировать. Модель получает то, что программа печатает или возвращает; Результаты изображения прилагаются отдельно. Вызовы вложенных инструментов по-прежнему записываются, и для них действуют разрешения инструмента.', + '### По сравнению со стандартным режимом', + 'Оба режима могут выполнять кодирование и пакетные задачи. Стандартный режим напрямую предоставляет доступ к отдельным инструментам; PTC организует вызовы инструментов в коде. Текущая предустановка PTC оставляет инструменты управления рабочим процессом и плагинами отключенными. Скорость и использование токенов зависят от задачи и того, как программа обрабатывает ее результаты.', + ].join('\n\n\n\n'), + guidePtcUsage: [ + '### Проверка набора файлов конфигурации', + '> Проверьте все файлы JSON в configs/. Перечислите отсутствующие обязательные поля и недопустимые значения в файле Schema.json. Сохраните CSV-файл с одной строкой на каждую проблему. Включите в отчет нечитаемые файлы и продолжайте проверять остальные. Оставьте исходные файлы без изменений.', + 'Ожидаемый результат: краткое описание проблемы и отчет в формате CSV. Программа может повторять одни и те же проверки, обрабатывать отдельные сбои и собирать результаты.', + '### Обобщение журналов ошибок', + '> Проанализируйте файлы журналов в logs/. Группируйте ошибки по сервису и типу ошибки. Покажите десять наиболее часто встречающихся групп и по одному примеру из каждой. Сохраните полные данные в формате CSV.', + 'Ожидаемый результат: основные группы ошибок и полная таблица подсчета. Промежуточные данные могут быть агрегированы в программе до того, как сводка достигнет модели.', + ].join('\n\n\n\n'), + guideMinimalIntro: 'Выберите минимальный режим для новой задачи. Для сравнения сохраняйте постоянство модели, разрешений, входных данных и состояния начальной рабочей области во всех запусках.', + guideMinimalExplanation: [ + '### Что включено', + 'Один постоянный инструмент оболочки read_image и фиксированное системное приглашение. Для чтения изображений требуется модель с поддержкой изображений. Старая история автоматически сжимается под давлением контекста; используйте /compact, пока агент простаивает, чтобы сжать его вручную. Встроенная предустановка не загружает навыки, планирование или стандартный контекст времени выполнения.', + '### Когда это выбирать', + 'Используйте его как основу для экспериментов и сравнений. Он по-прежнему может читать файлы и выполнять сценарии с помощью команд оболочки, но предлагает меньше встроенных способов управления длительными задачами. Меньшее количество инструментов не обязательно облегчает работу новичку.', + ].join('\n\n\n\n'), + guideMinimalUsage: [ + '### Сравните производительность с исправлением небольшой ошибки', + '> Запустите тесты для этого проекта, найдите причину сбоя и внесите минимальные исправления. Запустите соответствующие тесты еще раз и сообщите о результате.', + 'Запустите одну и ту же задачу отдельно в стандартном и минимальном режимах из одного и того же начального состояния. Сравните выполнение задач, вызовы инструментов и результирующие изменения. Минимальный режим выполняет работу посредством команд терминала.', + ].join('\n\n\n\n'), + guideCordisIntro: 'Выберите режим «Создатель» для новой задачи. Опишите желаемую возможность, где она должна появиться и как вы ее проверите.', + guideCordisExplanation: [ + '### Что вы можете создать', + 'Режим Creator включает в себя стандартные инструменты задач, а также проверку во время выполнения и рекомендации по созданию подключаемых модулей Cordis и предустановок агента. Он может создать плагин, добавляющий возможности или пользовательский интерфейс, или предустановку, объединяющую инструменты и подсказки для конкретной работы.', + '### Плагины и режимы', + 'Плагин добавляет к DSH возможности, такие как инструмент, подключение к службе или запись пользовательского интерфейса. Режим — это предустановка агента, которая выбирает инструменты и определяет, как агент работает над задачей. Плагин может быть включен в пользовательский пресет.', + '### Как результат вступает в силу', + 'Попросите агента установить и проверить результат, а не просто генерировать исходный код. Плагин может загрузиться немедленно или потребовать перезагрузки, в зависимости от того, что он меняет. Вновь созданный пресет выбирается при запуске новой задачи.', + ].join('\n\n\n\n'), + guideCordisUsage: [ + '### Добавьте пользовательский интерфейс', + '> Создайте плагин DSH, который добавляет запись примечаний к проекту на боковую панель. Позвольте мне просмотреть файлы Markdown в этом рабочем пространстве и просмотреть выбранную заметку. Установите его и убедитесь, что страница открывается.', + 'Ожидаемый результат: установленный плагин с работающей страницей входа и предварительного просмотра, а также все оставшиеся шаги активации.', + '### Добавить инструмент', + '> Создайте плагин с инструментом, который читает отчет об испытаниях этого проекта и суммирует неудачные тесты. Зарегистрируйте его и проверьте с помощью образца отчета.', + 'Ожидаемый результат: плагин с вызываемым инструментом и проверенным примером вызова.', + '### Создать свой режим', + '> Создайте режим «Проверка кода» на основе стандартного режима. Попросите его определить приоритетность потенциальных ошибок и проверить пробелы, указать пути и строки к файлам и спросить, прежде чем изменять файлы. Сохраните его как выбираемую предустановку.', + 'Ожидаемый результат: индивидуальная настройка для новых задач. Эти инструкции по проверке помогут агенту; настройки разрешений определяют, какие действия он может выполнять.', + ].join('\n\n\n\n'), +} satisfies typeof guideEn + +/** Portuguese dictionary, checked against the English keys. */ +export const guidePt = { + modeExplanation: 'Detalhes do modo', + howToUse: 'Como usar', + guideSections: 'Seções do guia', + guideExampleTask: 'Tarefa de exemplo', + guideCopy: 'Copiar', + guideCopied: 'Copiado', + guideFootnotes: 'Notas de rodapé', + guideStandardIntro: 'Escolha o modo Padrão ao iniciar uma nova tarefa. Descreva o que você deseja realizar, indique os arquivos relevantes e explique como verificar o resultado.', + guideStandardExplanation: [ + '### Como funciona', + 'O agente chama ferramentas diretamente para ler e editar arquivos, pesquisar e executar comandos de terminal. Inclui habilidades, planejamento, metas, subagentes, fluxos de trabalho, gerenciamento de plugins e compactação de contexto.', + '### Quando escolher', + 'Comece aqui para codificação diária, trabalho de arquivo e pesquisa. O modo padrão também pode escrever scripts e processar arquivos em lotes. PTC altera a forma como as chamadas de ferramenta são organizadas; não é necessário para tarefas em lote.', + ].join('\n\n\n\n'), + guideStandardUsage: [ + '### Corrigir um bug', + '> Descubra por que enviar o formulário de pesquisa duas vezes faz com que os resultados desapareçam. Corrija-o e execute os testes relevantes. Explique a causa e o que mudou.', + 'Resultado esperado: uma alteração de código, os resultados de teste relevantes e uma explicação da causa.', + '### Organize notas do projeto', + '> Leia as Markdown notas deste projeto. Resuma as decisões acordadas e as questões abertas, com links para os arquivos originais.', + 'Resultado esperado: um resumo com referências que você pode comparar com as notas originais.', + ].join('\n\n\n\n'), + guidePtcIntro: 'Escolha o modo PTC ao iniciar uma nova tarefa. Especifique os arquivos de entrada, regras de processamento e formato de saída. O agente escreve o código.', + guidePtcExplanation: [ + '### Como as ferramentas são chamadas', + 'PTC significa chamada de ferramenta programática. Nesta predefinição integrada, o agente usa run_code para escrever um programa TypeScript que chama ferramentas por meio de um SDK gerado. O programa pode usar loops, condições, tratamento de erros e chamadas simultâneas quando apropriado.', + '### O que chega ao modelo', + 'Os resultados da ferramenta chegam primeiro ao programa, que pode filtrá-los e combiná-los. O modelo recebe o que o programa imprime ou retorna; os resultados da imagem são anexados separadamente. As chamadas de ferramentas aninhadas ainda são gravadas e permanecem sujeitas às permissões da ferramenta.', + '### Comparado com o modo Padrão', + 'Ambos os modos podem lidar com tarefas de codificação e em lote. O modo padrão expõe ferramentas individuais diretamente; PTC organiza chamadas de ferramentas em código. A predefinição PTC atual deixa o fluxo de trabalho e as ferramentas de gerenciamento de plug-ins desativados. A velocidade e o uso do token dependem da tarefa e de como o programa lida com seus resultados.', + ].join('\n\n\n\n'), + guidePtcUsage: [ + '### Verifique um conjunto de arquivos de configuração', + '> Verifique todos os arquivos JSON em configs/. Liste os campos obrigatórios ausentes e os valores inválidos em relação ao schema.json. Salve um CSV com uma linha por problema. Inclua arquivos ilegíveis no relatório e continue verificando o restante. Deixe os arquivos originais inalterados.', + 'Resultado esperado: um resumo do problema e um relatório CSV. O programa pode repetir as mesmas verificações, tratar falhas individuais e coletar os resultados.', + '### Resumir logs de erros', + '> Analise os arquivos de log em logs/. Agrupe erros por serviço e tipo de erro. Mostre os dez grupos mais frequentes e um exemplo de cada. Salve as contagens completas em um CSV.', + 'Resultado esperado: os principais grupos de erros e uma tabela de contagem completa. Os dados intermediários podem ser agregados no programa antes que o resumo chegue ao modelo.', + ].join('\n\n\n\n'), + guideMinimalIntro: 'Escolha o modo Mínimo para uma nova tarefa. Para uma comparação, mantenha o modelo, as permissões, a entrada e o estado inicial do espaço de trabalho constantes em todas as execuções.', + guideMinimalExplanation: [ + '### O que está incluído', + 'Uma ferramenta de shell persistente, read_image, e um prompt de sistema fixo. A leitura de imagens requer um modelo com capacidade de imagem. O histórico mais antigo é compactado automaticamente sob pressão do contexto; use /compact enquanto o agente estiver ocioso para compactá-lo manualmente. A predefinição integrada não carrega habilidades, planejamento ou contexto de tempo de execução padrão.', + '### Quando escolher', + 'Use-o como base para experimentos e comparações. Ele ainda pode ler arquivos e executar scripts por meio de comandos shell, mas oferece menos maneiras integradas de gerenciar uma tarefa longa. Menos ferramentas não torna necessariamente mais fácil para um iniciante.', + ].join('\n\n\n\n'), + guideMinimalUsage: [ + '### Compare o desempenho em uma pequena correção de bug', + '> Execute os testes para este projeto, encontre a causa da falha e faça a menor correção. Execute os testes relevantes novamente e relate o resultado.', + 'Execute a mesma tarefa separadamente nos modos Padrão e Mínimo a partir do mesmo estado inicial. Compare a conclusão da tarefa, as chamadas de ferramentas e as alterações resultantes. O modo mínimo executa o trabalho por meio de comandos de terminal.', + ].join('\n\n\n\n'), + guideCordisIntro: 'Escolha o modo Criador para uma nova tarefa. Descreva o recurso desejado, onde ele deve aparecer e como você o verificará.', + guideCordisExplanation: [ + '### O que você pode criar', + 'O modo Criador inclui ferramentas de tarefas padrão, além de inspeção de tempo de execução e orientação para criação de Cordis plug-ins e predefinições de agente. Ele pode criar um plug-in que adicione um recurso ou UI, ou uma predefinição que combine ferramentas e prompts para um trabalho específico.', + '### Plug-ins e modos', + 'Um plug-in adiciona recursos a DSH, como uma ferramenta, uma conexão de serviço ou uma entrada de IU. Um modo é uma predefinição de agente que seleciona ferramentas e define como o agente trabalha em uma tarefa. Um plugin pode ser incluído em uma predefinição personalizada.', + '### Como o resultado entra em vigor', + 'Peça ao agente para instalar e verificar o resultado, não apenas gerar o código-fonte. Um plug-in pode carregar imediatamente ou exigir uma reinicialização, dependendo do que for alterado. Uma predefinição recém-criada é selecionada ao iniciar uma nova tarefa.', + ].join('\n\n\n\n'), + guideCordisUsage: [ + '### Adicionar uma IU', + '> Crie um plug-in DSH que adicione uma entrada de notas do projeto à barra lateral. Deixe-me navegar pelos arquivos Markdown nesta área de trabalho e visualizar uma nota selecionada. Instale-o e verifique se a página abre.', + 'Resultado esperado: um plug-in instalado com uma entrada funcional e uma página de visualização, além de quaisquer etapas de ativação restantes.', + '### Adicionar uma ferramenta', + '> Crie um plugin com uma ferramenta que leia o relatório de teste deste projeto e resuma os testes que falharam. Registre-o e verifique-o com um relatório de amostra.', + 'Resultado esperado: um plugin com uma ferramenta que pode ser chamada e uma chamada de amostra verificada.', + '### Crie meu próprio modo', + '> Crie um modo “Revisão de código” baseado no modo Padrão. Faça com que ele priorize possíveis bugs e teste lacunas, cite caminhos e linhas de arquivos e pergunte antes de modificar arquivos. Salve-o como uma predefinição selecionável.', + 'Resultado esperado: uma predefinição personalizada para novas tarefas. Estas instruções de revisão orientam o agente; as configurações de permissão determinam quais ações ele pode executar.', + ].join('\n\n\n\n'), +} satisfies typeof guideEn diff --git a/packages/client/ui-agent-preset/src/client/index.ts b/packages/client/ui-agent-preset/src/client/index.ts index 0d9d61e621..b9e1363c6d 100644 --- a/packages/client/ui-agent-preset/src/client/index.ts +++ b/packages/client/ui-agent-preset/src/client/index.ts @@ -42,7 +42,7 @@ import { AgentPresetSection } from './AgentPresetSection.tsx' import type { AgentPresetSectionInjected } from './AgentPresetSection.tsx' import { AgentPresetSeatController, type AgentPresetStage } from './seat-store.ts' import { AgentPresetSectionController } from './section-store.ts' -import { en, ja, zh, type AgentPresetSettingsKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh, type AgentPresetSettingsKey } from './locales.ts' import { AGENT_PRESET_SETTINGS_NS, AgentPresetSettingsController } from './settings-store.ts' import { analyticsMode } from './analytics.ts' @@ -128,7 +128,7 @@ export function apply(ctx: ClientContext): void { return binding === undefined ? undefined : seatFor(binding) } - ctx.effect(() => ctx.locale.register('settings.agentPreset', { zh, en, ja }), 'ui-agent-preset: settings row dictionaries') + ctx.effect(() => ctx.locale.register('settings.agentPreset', { zh, en, ja, es, fr, de, ru, pt }), 'ui-agent-preset: settings row dictionaries') ctx.effect(() => { let requested = 0 diff --git a/packages/client/ui-agent-preset/src/client/locales.ts b/packages/client/ui-agent-preset/src/client/locales.ts index 00fce156ee..f5a3c8ed67 100644 --- a/packages/client/ui-agent-preset/src/client/locales.ts +++ b/packages/client/ui-agent-preset/src/client/locales.ts @@ -1,6 +1,6 @@ /** Locale bundles for the agent-preset hero chip, header label, and management section. */ -import { guideEn, guideJa, guideZh, type PresetGuideKey } from './guide-locales.ts' +import { guideEn, guideJa, guideEs, guideFr, guideDe, guideRu, guidePt, guideZh, type PresetGuideKey } from './guide-locales.ts' /** Locale keys these surfaces render. */ export type AgentPresetSettingsKey = @@ -158,3 +158,228 @@ export const ja = { 'createPluginUnavailable': '一時的に利用できません。このメニューを開き直して再試行してください', 'createPluginMissing': 'この構成にはクリエイターモードが含まれていません', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + ...guideEs, + builtInGroup: 'Incorporado', customGroup: 'personalizado', + sectionIntro: 'Elija las herramientas del agente y cómo funciona. Utilice el modo Estándar para las tareas diarias o el modo Creador para agregar capacidades a DSH.', + + seatHint: 'Elija el agente preestablecido para su nueva tarea', + headerHint: 'El agente preestablecido elegido cuando comenzó esta tarea', + nav: 'Ajustes preestablecidos del agente', + + setDefault: 'Establecer como nueva tarea predeterminada', + view: 'Ver configuración', + + presetStandardName: 'Modo estándar', + presetStandardDescription: + 'Trabaje con código, archivos e información. Adecuado para la mayoría de las tareas, con búsqueda, edición, comandos de terminal y otras herramientas disponibles según sea necesario.', + presetPtcName: 'Modo PTC', + presetPtcDescription: + 'Incluye todas las capacidades del modo Estándar. Más adecuado para tareas que llaman a herramientas en lotes y luego filtran, organizan, deduplican, cuentan o resumen los resultados.', + presetMinimalName: 'modo mínimo', + presetMinimalDescription: + 'El agente utiliza un terminal y lectura de imágenes, con compactación de contexto. Útil para probar y comparar su rendimiento básico.', + presetCordisName: 'Modo creador', + presetCordisDescription: + 'Personaliza DSH a través de la conversación. Deje que el agente escriba complementos que agreguen funciones o interfaz de usuario, o combine herramientas e indicaciones para crear su propio modo.', + + inUse: 'Nueva tarea predeterminada', + + noDescription: 'Sin descripción.', + brokenBadge: 'No se pudo cargar', + + switchRefused: 'No se pudo cambiar a {name}: {reason}', + standardUnavailable: 'El modo estándar no está disponible. Restáuralo o elige otro modo disponible.', + + close: 'Cerrar', + + creatorDraft: 'Deja que el agente me ayude a crear un preset', + createPlugin: 'Deje que el agente cree un complemento', + createPluginDescription: 'Ingrese al modo Creador y cree su propio complemento DSH', + createPluginChecking: 'Comprobando si el modo Creador está disponible', + createPluginUnavailable: 'Temporalmente no disponible. Vuelve a abrir este menú para volver a intentarlo.', + createPluginMissing: 'El modo creador no está incluido en esta configuración.', + +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + ...guideFr, + builtInGroup: 'Intégré', customGroup: 'Personnalisé', + sectionIntro: 'Choisissez les outils de l’agent et son fonctionnement. Utilisez le mode Standard pour les tâches quotidiennes ou le mode Créateur pour ajouter des fonctionnalités à DSH.', + + seatHint: "Choisissez le préréglage d'agent pour votre nouvelle tâche", + headerHint: "Le préréglage d'agent choisi au démarrage de cette tâche", + nav: "Préréglages d'agent", + + setDefault: 'Définir comme nouvelle tâche par défaut', + view: 'Afficher la configuration', + + presetStandardName: 'Mode standard', + presetStandardDescription: + 'Travaillez avec du code, des fichiers et des informations. Convient à la plupart des tâches, avec recherche, édition, commandes de terminal et autres outils disponibles selon les besoins.', + presetPtcName: 'Mode PTC', + presetPtcDescription: + 'Inclut toutes les fonctionnalités du mode Standard. Mieux adapté aux tâches qui appellent des outils par lots, puis filtrent, organisent, dédupliquent, comptent ou résument les résultats.', + presetMinimalName: 'Mode minimal', + presetMinimalDescription: + "L'agent utilise un terminal et une lecture d'image, avec compactage du contexte. Utile pour tester et comparer ses performances de base.", + presetCordisName: 'Mode Créateur', + presetCordisDescription: + "Personnalisez DSH via la conversation. Laissez l'agent écrire des plugins qui ajoutent des fonctionnalités ou une interface utilisateur, ou combinez des outils et des invites pour créer votre propre mode.", + + inUse: 'Nouvelle tâche par défaut', + + noDescription: 'Aucune description.', + brokenBadge: 'Échec du chargement', + + switchRefused: 'Impossible de passer à {name} : {reason}', + standardUnavailable: "Le mode standard n'est pas disponible. Restaurez-le ou choisissez un autre mode disponible.", + + close: 'Fermer', + + creatorDraft: "Laissez l'agent m'aider à créer un préréglage", + createPlugin: "Laissez l'agent créer un plugin", + createPluginDescription: 'Entrez en mode Créateur et créez votre propre plugin DSH', + createPluginChecking: 'Vérifier si le mode Créateur est disponible', + createPluginUnavailable: 'Temporairement indisponible. Rouvrez ce menu pour réessayer', + createPluginMissing: "Le mode Créateur n'est pas inclus dans cette configuration", + +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + ...guideDe, + builtInGroup: 'Eingebaut', customGroup: 'Benutzerdefiniert', + sectionIntro: 'Wählen Sie die Tools des Agenten und deren Funktionsweise aus. Verwenden Sie den Standardmodus für alltägliche Aufgaben oder den Creator-Modus, um DSH Funktionen hinzuzufügen.', + + seatHint: 'Wählen Sie die Agentenvoreinstellung für Ihre neue Aufgabe', + headerHint: 'Die Agentenvoreinstellung, die beim Start dieser Aufgabe ausgewählt wurde', + nav: 'Agentenvoreinstellungen', + + setDefault: 'Als Standard für neue Aufgabe festlegen', + view: 'Konfiguration anzeigen', + + presetStandardName: 'Standardmodus', + presetStandardDescription: + 'Arbeiten Sie mit Code, Dateien und Informationen. Geeignet für die meisten Aufgaben, da bei Bedarf Suche, Bearbeitung, Terminalbefehle und andere Tools verfügbar sind.', + presetPtcName: 'PTC-Modus', + presetPtcDescription: + 'Beinhaltet alle Funktionen des Standardmodus. Besser geeignet für Aufgaben, bei denen Tools stapelweise aufgerufen und die Ergebnisse dann gefiltert, organisiert, dedupliziert, gezählt oder zusammengefasst werden.', + presetMinimalName: 'Minimalmodus', + presetMinimalDescription: + 'Der Agent verwendet ein Terminal und das Lesen von Bildern mit Kontextkomprimierung. Nützlich zum Testen und Vergleichen der Grundleistung.', + presetCordisName: 'Erstellermodus', + presetCordisDescription: + 'Passen Sie DSH durch Gespräche an. Lassen Sie den Agenten Plugins schreiben, die Funktionen oder Benutzeroberflächen hinzufügen, oder kombinieren Sie Tools und Eingabeaufforderungen, um Ihren eigenen Modus zu erstellen.', + + inUse: 'Neuer Aufgabenstandard', + + noDescription: 'Keine Beschreibung.', + brokenBadge: 'Laden fehlgeschlagen', + + switchRefused: 'Konnte nicht zu {name} wechseln: {reason}', + standardUnavailable: 'Der Standardmodus ist nicht verfügbar. Stellen Sie es wieder her oder wählen Sie einen anderen verfügbaren Modus.', + + close: 'Schließen', + + creatorDraft: 'Lassen Sie sich vom Agenten beim Erstellen einer Voreinstellung helfen', + createPlugin: 'Lassen Sie den Agenten ein Plugin erstellen', + createPluginDescription: 'Wechseln Sie in den Erstellermodus und erstellen Sie Ihr eigenes DSH-Plugin', + createPluginChecking: 'Prüfen, ob der Creator-Modus verfügbar ist', + createPluginUnavailable: 'Vorübergehend nicht verfügbar. Öffnen Sie dieses Menü erneut, um es erneut zu versuchen', + createPluginMissing: 'Der Creator-Modus ist in dieser Konfiguration nicht enthalten', + +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + ...guideRu, + builtInGroup: 'Встроенный', customGroup: 'Пользовательский', + sectionIntro: 'Выбирайте инструменты агента и то, как они работают. Используйте стандартный режим для повседневных задач или режим Creator, чтобы расширить возможности DSH.', + + seatHint: 'Выберите предустановку агента для вашей новой задачи', + headerHint: 'Предварительная настройка агента, выбранная при запуске этой задачи', + nav: 'Настройки агента', + + setDefault: 'Установить в качестве новой задачи по умолчанию', + view: 'Посмотреть конфигурацию', + + presetStandardName: 'Стандартный режим', + presetStandardDescription: + 'Работайте с кодом, файлами и информацией. Подходит для большинства задач, с поиском, редактированием, командами терминала и другими инструментами, доступными по мере необходимости.', + presetPtcName: 'Режим PTC', + presetPtcDescription: + 'Включает все возможности стандартного режима. Лучше подходит для задач, которые вызывают инструменты в пакетном режиме, а затем фильтруют, организуют, дедуплицируют, подсчитывают или суммируют результаты.', + presetMinimalName: 'Минимальный режим', + presetMinimalDescription: + 'Агент использует терминал и чтение изображений со сжатием контекста. Полезно для тестирования и сравнения его базовой производительности.', + presetCordisName: 'Режим автора', + presetCordisDescription: + 'Настройте DSH через разговор. Позвольте агенту писать плагины, которые добавляют функции или пользовательский интерфейс, или комбинируйте инструменты и подсказки для создания собственного режима.', + + inUse: 'Новая задача по умолчанию', + + noDescription: 'Нет описания.', + brokenBadge: 'Не удалось загрузить', + + switchRefused: 'Не удалось переключиться на {name}: {reason}', + standardUnavailable: 'Стандартный режим недоступен. Восстановите его или выберите другой доступный режим.', + + close: 'Закрыть', + + creatorDraft: 'Позвольте агенту помочь мне создать пресет', + createPlugin: 'Позвольте агенту создать плагин', + createPluginDescription: 'Войдите в режим Creator и создайте свой собственный плагин DSH.', + createPluginChecking: 'Проверка доступности режима Creator', + createPluginUnavailable: 'Временно недоступен. Откройте это меню еще раз, чтобы повторить попытку.', + createPluginMissing: 'Режим Creator не включен в эту конфигурацию.', + +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + ...guidePt, + builtInGroup: 'Integrado', customGroup: 'Personalizado', + sectionIntro: 'Escolha as ferramentas do agente e como funciona. Use o modo Padrão para tarefas diárias ou o modo Criador para adicionar recursos ao DSH.', + + seatHint: 'Escolha a predefinição de agente para sua nova tarefa', + headerHint: 'A predefinição do agente escolhida quando esta tarefa foi iniciada', + nav: 'Predefinições de agente', + + setDefault: 'Definir como nova tarefa padrão', + view: 'Ver configuração', + + presetStandardName: 'Modo padrão', + presetStandardDescription: + 'Trabalhe com código, arquivos e informações. Adequado para a maioria das tarefas, com pesquisa, edição, comandos de terminal e outras ferramentas disponíveis conforme necessário.', + presetPtcName: 'modo PTC', + presetPtcDescription: + 'Inclui todos os recursos do modo Padrão. Mais adequado para tarefas que chamam ferramentas em lotes e depois filtram, organizam, desduplicam, contam ou resumem os resultados.', + presetMinimalName: 'Modo mínimo', + presetMinimalDescription: + 'O agente utiliza terminal e leitura de imagens, com compactação de contexto. Útil para testar e comparar seu desempenho básico.', + presetCordisName: 'Modo criador', + presetCordisDescription: + 'Personalize DSH por meio de conversa. Deixe o agente escrever plug-ins que adicionem recursos ou UI, ou combine ferramentas e prompts para criar seu próprio modo.', + + inUse: 'Novo padrão de tarefa', + + noDescription: 'Nenhuma descrição.', + brokenBadge: 'Falha ao carregar', + + switchRefused: 'Não foi possível mudar para {name}: {reason}', + standardUnavailable: 'O modo padrão não está disponível. Restaure-o ou escolha outro modo disponível.', + + close: 'Fechar', + + creatorDraft: 'Deixe o agente me ajudar a criar uma predefinição', + createPlugin: 'Deixe o agente criar um plugin', + createPluginDescription: 'Entre no modo Criador e crie seu próprio plug-in DSH', + createPluginChecking: 'Verificando se o modo Criador está disponível', + createPluginUnavailable: 'Temporariamente indisponível. Reabra este menu para tentar novamente', + createPluginMissing: 'O modo criador não está incluído nesta configuração', + +} satisfies Record diff --git a/packages/client/ui-approval/locale/de.json b/packages/client/ui-approval/locale/de.json new file mode 100644 index 0000000000..ee89d86fe1 --- /dev/null +++ b/packages/client/ui-approval/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Schnittstelle zur Betriebsgenehmigung", + "description": "Zeigt Aktionen an, deren Genehmigung noch aussteht, und führt Benutzerauswahlen zu laufenden Aufgaben zurück." + } +} diff --git a/packages/client/ui-approval/locale/es.json b/packages/client/ui-approval/locale/es.json new file mode 100644 index 0000000000..115786cd1c --- /dev/null +++ b/packages/client/ui-approval/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de aprobación de operación", + "description": "Muestra acciones pendientes de aprobación y devuelve las selecciones del usuario a las tareas en ejecución." + } +} diff --git a/packages/client/ui-approval/locale/fr.json b/packages/client/ui-approval/locale/fr.json new file mode 100644 index 0000000000..69768c0bab --- /dev/null +++ b/packages/client/ui-approval/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface d'approbation des opérations", + "description": "Affiche les actions en attente d'approbation et renvoie les sélections de l'utilisateur aux tâches en cours d'exécution." + } +} diff --git a/packages/client/ui-approval/locale/pt.json b/packages/client/ui-approval/locale/pt.json new file mode 100644 index 0000000000..7fe00b6570 --- /dev/null +++ b/packages/client/ui-approval/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de aprovação de operação", + "description": "Exibe ações com aprovação pendente e retorna as seleções do usuário para tarefas em execução." + } +} diff --git a/packages/client/ui-approval/locale/ru.json b/packages/client/ui-approval/locale/ru.json new file mode 100644 index 0000000000..b656b6b2d5 --- /dev/null +++ b/packages/client/ui-approval/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Интерфейс одобрения операций", + "description": "Отображает действия, ожидающие утверждения, и возвращает выбранные пользователем действия к выполняемым задачам." + } +} diff --git a/packages/client/ui-approval/src/client/index.ts b/packages/client/ui-approval/src/client/index.ts index a667d507e9..4073a85aa2 100644 --- a/packages/client/ui-approval/src/client/index.ts +++ b/packages/client/ui-approval/src/client/index.ts @@ -11,7 +11,7 @@ import type { ShortcutCommandId } from '@deepseek-ai/dsh-client-shortcuts/client import { ApprovalCard } from './ApprovalCard.tsx' import { ApprovalPanel } from './ApprovalPanel.tsx' import { PendingApproval } from './contract/slots.ts' -import { en, ja, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh } from './locales.ts' export type { ApprovalCardInput, @@ -77,7 +77,7 @@ async function answerApproval( * @param ctx - Client root context. */ export function apply(ctx: ClientContext): void { - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-approval: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-approval: dictionaries') ctx.inject(['shortcuts'], (scope) => { const t = ctx.locale.bind(NS) scope.effect(() => scope.shortcuts.registerFixed({ diff --git a/packages/client/ui-approval/src/client/locales.ts b/packages/client/ui-approval/src/client/locales.ts index c8e540fd49..99408815d9 100644 --- a/packages/client/ui-approval/src/client/locales.ts +++ b/packages/client/ui-approval/src/client/locales.ts @@ -35,3 +35,58 @@ export const ja = { 'allowOnce': '1 回だけ許可', 'allowAlways': '常に許可', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + waiting: 'Esperando aprobación', + 'detail.aria': 'Detalles de aprobación', + escalation: 'La herramienta {toolName} solicita ejecución privilegiada', + reject: 'Rechazar', + allow: 'Permitir', + allowOnce: 'permitir una vez', + allowAlways: 'Permitir siempre', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + waiting: "En attente d'approbation", + 'detail.aria': "Détails de l'approbation", + escalation: "L'outil {toolName} demande une exécution privilégiée", + reject: 'Rejeter', + allow: 'Autoriser', + allowOnce: 'Autoriser une fois', + allowAlways: 'Toujours autoriser', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + waiting: 'Warten auf Genehmigung', + 'detail.aria': 'Einzelheiten zur Genehmigung', + escalation: 'Tool {toolName} fordert privilegierte Ausführung an', + reject: 'Ablehnen', + allow: 'Erlauben', + allowOnce: 'Einmal zulassen', + allowAlways: 'Immer zulassen', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + waiting: 'Ожидание одобрения', + 'detail.aria': 'Детали утверждения', + escalation: 'Инструмент {toolName} запрашивает привилегированное выполнение', + reject: 'Отклонить', + allow: 'Разрешить', + allowOnce: 'Разрешить один раз', + allowAlways: 'Всегда разрешать', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + waiting: 'Aguardando aprovação', + 'detail.aria': 'Detalhes de aprovação', + escalation: 'A ferramenta {toolName} solicita execução privilegiada', + reject: 'Rejeitar', + allow: 'Permitir', + allowOnce: 'Permitir uma vez', + allowAlways: 'Sempre permitir', +} satisfies Record diff --git a/packages/client/ui-attachment/locale/de.json b/packages/client/ui-attachment/locale/de.json new file mode 100644 index 0000000000..07c79593b0 --- /dev/null +++ b/packages/client/ui-attachment/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Anhangsanzeige", + "description": "Zeigen Sie Anhänge und Bilder in Nachrichteneingaben, Konversationen und Ausführungsprotokollen an." + } +} diff --git a/packages/client/ui-attachment/locale/es.json b/packages/client/ui-attachment/locale/es.json new file mode 100644 index 0000000000..635cff5f3d --- /dev/null +++ b/packages/client/ui-attachment/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Visualización de archivos adjuntos", + "description": "Muestre archivos adjuntos e imágenes en la entrada de mensajes, conversaciones y registros de ejecución." + } +} diff --git a/packages/client/ui-attachment/locale/fr.json b/packages/client/ui-attachment/locale/fr.json new file mode 100644 index 0000000000..c89a8bf6f9 --- /dev/null +++ b/packages/client/ui-attachment/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Affichage des pièces jointes", + "description": "Affichez les pièces jointes et les images dans la saisie des messages, les conversations et les journaux d'exécution." + } +} diff --git a/packages/client/ui-attachment/locale/pt.json b/packages/client/ui-attachment/locale/pt.json new file mode 100644 index 0000000000..6295a88f6d --- /dev/null +++ b/packages/client/ui-attachment/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Exibição de anexo", + "description": "Exiba anexos e imagens em entradas de mensagens, conversas e registros de execução." + } +} diff --git a/packages/client/ui-attachment/locale/ru.json b/packages/client/ui-attachment/locale/ru.json new file mode 100644 index 0000000000..8f81ace343 --- /dev/null +++ b/packages/client/ui-attachment/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Отображение вложений", + "description": "Отображение вложений и изображений при вводе сообщений, разговорах и журналах запуска." + } +} diff --git a/packages/client/ui-brand-official/locale/de.json b/packages/client/ui-brand-official/locale/de.json new file mode 100644 index 0000000000..953f8dbf7e --- /dev/null +++ b/packages/client/ui-brand-official/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Markendarstellung", + "description": "Zeigen Sie offizielle Markenelemente an Orten wie der App-Seitenleiste an." + } +} diff --git a/packages/client/ui-brand-official/locale/es.json b/packages/client/ui-brand-official/locale/es.json new file mode 100644 index 0000000000..108c571dbe --- /dev/null +++ b/packages/client/ui-brand-official/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Visualización de marca", + "description": "Muestre elementos oficiales de la marca en lugares como la barra lateral de la aplicación." + } +} diff --git a/packages/client/ui-brand-official/locale/fr.json b/packages/client/ui-brand-official/locale/fr.json new file mode 100644 index 0000000000..5a47875c99 --- /dev/null +++ b/packages/client/ui-brand-official/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Affichage de la marque", + "description": "Affichez les éléments officiels de la marque dans des endroits tels que la barre latérale de l'application." + } +} diff --git a/packages/client/ui-brand-official/locale/pt.json b/packages/client/ui-brand-official/locale/pt.json new file mode 100644 index 0000000000..2b06cd6c7a --- /dev/null +++ b/packages/client/ui-brand-official/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Exibição da marca", + "description": "Exiba elementos oficiais da marca em locais como a barra lateral do aplicativo." + } +} diff --git a/packages/client/ui-brand-official/locale/ru.json b/packages/client/ui-brand-official/locale/ru.json new file mode 100644 index 0000000000..e3e9d5cead --- /dev/null +++ b/packages/client/ui-brand-official/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Дисплей бренда", + "description": "Отображайте официальные элементы бренда в таких местах, как боковая панель приложения." + } +} diff --git a/packages/client/ui-chat/locale/de.json b/packages/client/ui-chat/locale/de.json new file mode 100644 index 0000000000..15ae984c6b --- /dev/null +++ b/packages/client/ui-chat/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Anzeige von Chat-Inhalten", + "description": "Rendern Sie Chat-Nachrichten, Tool-Inhalte und zugehörige Details." + } +} diff --git a/packages/client/ui-chat/locale/es.json b/packages/client/ui-chat/locale/es.json new file mode 100644 index 0000000000..eb088700ac --- /dev/null +++ b/packages/client/ui-chat/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Visualización del contenido del chat", + "description": "Representa mensajes de chat, contenido de herramientas y detalles relacionados." + } +} diff --git a/packages/client/ui-chat/locale/fr.json b/packages/client/ui-chat/locale/fr.json new file mode 100644 index 0000000000..95efa01a16 --- /dev/null +++ b/packages/client/ui-chat/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Affichage du contenu du chat", + "description": "Rendre les messages de discussion, le contenu de l'outil et les détails associés." + } +} diff --git a/packages/client/ui-chat/locale/pt.json b/packages/client/ui-chat/locale/pt.json new file mode 100644 index 0000000000..0a5efa2be2 --- /dev/null +++ b/packages/client/ui-chat/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Exibição de conteúdo de bate-papo", + "description": "Renderize mensagens de bate-papo, conteúdo de ferramentas e detalhes relacionados." + } +} diff --git a/packages/client/ui-chat/locale/ru.json b/packages/client/ui-chat/locale/ru.json new file mode 100644 index 0000000000..ffb6e15666 --- /dev/null +++ b/packages/client/ui-chat/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Отображение содержимого чата", + "description": "Отображение сообщений чата, содержимого инструментов и связанных с ними деталей." + } +} diff --git a/packages/client/ui-chat/src/client/apply.ts b/packages/client/ui-chat/src/client/apply.ts index fcbc44d9be..fbabf95903 100644 --- a/packages/client/ui-chat/src/client/apply.ts +++ b/packages/client/ui-chat/src/client/apply.ts @@ -37,7 +37,7 @@ import { UserContent } from './chat/UserContent.tsx' import { ActivityPill, UsagePill } from './chat/StatsPills.tsx' import { registerConversationNodes } from './conversation-nodes/register.ts' import { QuotaNoticeHost } from './chat/QuotaNoticeHost.tsx' -import { en, ja, NS, zh } from './locale.ts' +import { en, ja, es, fr, de, ru, pt, NS, zh } from './locale.ts' import { TranscriptViewRow, type TranscriptViewRowInjected } from './settings/TranscriptViewRow.tsx' import { createChatStore } from './stores.ts' import { TranscriptViewPolicy } from './transcript-view.ts' @@ -134,7 +134,7 @@ export function apply(ctx: Context): void { resolve: binding => ({ hooks: { chat: chatSource(binding) } }), }) - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-chat: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-chat: dictionaries') const t = ctx.locale.bind(NS) const chatStore = createChatStore() const chatScrollPositions = new Map() diff --git a/packages/client/ui-chat/src/client/locale.ts b/packages/client/ui-chat/src/client/locale.ts index c5ffa1e87c..2c986490fb 100644 --- a/packages/client/ui-chat/src/client/locale.ts +++ b/packages/client/ui-chat/src/client/locale.ts @@ -602,3 +602,998 @@ export const ja = { 'clock.md': '{m}/{d}', 'clock.ymd': '{y}-{m}-{d}', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'message.stepProcess.thinking': 'Analizando la solicitud', + 'message.stepProcess.read': 'Leyendo archivos', + 'message.stepProcess.readImage': 'Leyendo imágenes', + 'message.stepProcess.write': 'Escribir archivos', + 'message.stepProcess.search': 'código de búsqueda', + 'message.stepProcess.edit': 'Editar archivos', + 'message.stepProcess.commands': 'Ejecutar comandos', + 'message.stepProcess.code': 'Código en ejecución', + 'message.stepProcess.webSearch': 'buscando en la web', + 'message.stepProcess.webFetch': 'Visitar páginas web', + 'message.stepProcess.subagents': 'Subagentes coordinadores', + 'message.stepProcess.plan': 'Actualizando el plan', + 'message.stepProcess.questions': 'Esperando tu acción', + 'message.stepProcess.tools': 'herramientas de llamada', + 'message.stepProcess.prepare.read': 'Preparándose para leer archivos', + 'message.stepProcess.prepare.readImage': 'Preparándose para leer imágenes', + 'message.stepProcess.prepare.write': 'Preparándose para escribir archivos', + 'message.stepProcess.prepare.search': 'Preparándose para buscar el código', + 'message.stepProcess.prepare.edit': 'Preparándose para editar archivos', + 'message.stepProcess.prepare.commands': 'Preparándose para ejecutar comandos', + 'message.stepProcess.prepare.code': 'Preparándose para ejecutar código', + 'message.stepProcess.prepare.webSearch': 'Preparándose para buscar en la web', + 'message.stepProcess.prepare.webFetch': 'Preparándose para visitar páginas web', + 'message.stepProcess.prepare.subagents': 'Preparándose para coordinar subagentes', + 'message.stepProcess.prepare.plan': 'Preparándose para actualizar el plan', + 'message.stepProcess.prepare.questions': 'Preparando preguntas', + 'message.stepProcess.prepare.tools': 'Preparando llamadas a herramientas', + 'message.stepProcess.done.thinking': 'Análisis completado', + 'message.stepProcess.done.read': 'leer archivos', + 'message.stepProcess.done.readImage': 'Leer imágenes', + 'message.stepProcess.done.write': 'Escribió archivos', + 'message.stepProcess.done.search': 'código buscado', + 'message.stepProcess.done.edit': 'Archivos editados', + 'message.stepProcess.done.commands': 'Comandos ejecutados', + 'message.stepProcess.done.code': 'código ejecutado', + 'message.stepProcess.done.webSearch': 'Busqué en la web', + 'message.stepProcess.done.webFetch': 'Paginas web visitadas', + 'message.stepProcess.done.subagents': 'Subagentes coordinados', + 'message.stepProcess.done.plan': 'Actualizado el plan', + 'message.stepProcess.done.questions': 'preguntas hechas', + 'message.stepProcess.done.tools': 'herramientas llamadas', + 'message.stepProcess.joinTwo': '{first} y {second}', + 'message.stepProcess.comma': ', ', + 'message.stepProcess.sharedPrefix': '', + 'message.stepProcess.more': '{title}, etc.', + 'message.trigger.request': 'Ejecución solicitada', + 'message.trigger.goal': 'Objetivo continuo', + 'message.trigger.agent': 'Mensaje de tarea recibido', + 'message.trigger.team': 'Mensaje del equipo recibido', + 'message.trigger.subagent': 'Estado de subtarea actualizado', + 'message.trigger.github': 'Evento GitHub recibido', + 'message.trigger.webhook': 'Evento externo recibido', + 'message.trigger.schedule': 'Tarea de automatización', + 'message.trigger.job': 'Tarea en segundo plano actualizada', + 'message.trigger.plugin': 'Estado del complemento actualizado', + 'message.trigger.explanation': 'Esta notificación desencadenó esta respuesta.', + 'message.turnProcess.worked': 'Completado', + 'message.turnProcess.took': 'Completado en ', + 'message.turnProcess.failed': 'Fallido', + 'view.chat': 'Charla', + 'image.open': 'Ver imagen completa', + 'image.loading': 'Cargando imagen…', + 'image.failed': 'Vista previa de la imagen no disponible', + 'image.dialog': 'Vista previa de la imagen', + 'image.close': 'Cerrar vista previa de la imagen', + 'number.groupSeparator': ',', + 'duration.compactSeconds': '{seconds}s', + 'duration.compactMinutes': '{minutes}m{seconds}s', + 'duration.milliseconds': '{milliseconds}ms', + 'stats.counts': '{turns} turnos, {steps} pasos', + 'stats.cacheHit': 'Golpe de caché {percent}%', + 'stats.dialog.title': 'Estadísticas de sesión', + 'stats.dialog.usageTitle': 'Uso de tokens', + 'stats.dialog.llmTime': 'tiempo de maestría', + 'stats.dialog.toolTime': 'tiempo de herramienta', + 'stats.dialog.ttft': 'Tiempo promedio hasta el primer token (TTFT)', + 'stats.dialog.speed': 'Fichas por segundo (TPS)', + 'chat.loadingHistory': 'Cargando historial…', + 'chat.loadError': 'No se pudo cargar el historial: {message} ({code})', + 'chat.loadOlder': 'Cargar antes', + 'chat.toBottom': 'Volver al fondo', + 'chat.deepDiving': 'buceo profundo', + 'chat.deepDivingFor': 'Buceo profundo para {duration} ···', + 'chat.turnNavigation.label': 'Navegación por turnos', + 'chat.turnNavigation.jump': 'Ir al turno {turn}', + 'chat.turnNavigation.jumpLoad': 'Cargar e ir al turno {turn}', + 'chat.turnNavigation.turn': 'Turno {turn}', + 'settings.performance.title': 'Rendimiento y uso', + 'settings.performance.description': 'Elija cuánta información de rendimiento y uso desea mostrar', + 'settings.performance.compact': 'Compacto', + 'settings.performance.detailed': 'Detallado', + 'settings.links.title': 'Abrir enlaces de chat en', + 'settings.links.description': 'Elija dónde abrir enlaces web', + 'settings.links.sidebar': 'Barra lateral en la aplicación', + 'settings.links.newTab': 'Navegador predeterminado', + 'settings.transcript.title': 'Detalles del trabajo', + 'settings.transcript.description': 'Elija cuántos detalles mostrar para las llamadas de herramientas', + 'settings.collapse.title': 'Cuándo contraer los detalles del trabajo', + 'settings.collapse.description': 'Elija cuándo contraer automáticamente los detalles del trabajo', + 'settings.collapse.completion': 'Al finalizar', + 'settings.collapse.nextInput': 'En el siguiente mensaje', + 'settings.foldedReplies.title': 'Respuestas después del colapso', + 'settings.foldedReplies.description': 'Elija qué respuestas del asistente permanecen visibles cuando los detalles del trabajo colapsan', + 'settings.foldedReplies.all': 'Todas las respuestas', + 'settings.foldedReplies.final': 'Solo respuesta final', + 'settings.transcript.compact': 'Compacto', + 'settings.transcript.standard': 'Estándar', + 'settings.transcript.detailed': 'Detallado', + 'settings.transcript.verbose': 'Detallado', + 'fileOpen.title': 'No se pudo abrir el archivo', + 'fileOpen.unknown': 'No se pudo abrir este archivo', + 'message.extraBlock': 'Bloque de contenido adicional', + 'message.systemPrompt': 'Aviso del sistema', + 'message.systemPromptUpdate': 'Actualización del mensaje del sistema', + 'message.toolAdded': 'Herramienta agregada: {name}', + 'message.toolRemoved': 'Herramienta eliminada: {name}', + 'message.toolsAdded': 'Añadido: {names}', + 'message.toolsAddedCount': '{count} añadido', + 'message.toolsChanged': '{added} agregado, {removed} eliminado', + 'message.toolsRemoved': 'Eliminado: {names}', + 'message.toolsRemovedCount': '{count} eliminado', + 'message.toolsUpdated': 'Herramientas actualizadas', + 'message.contextInjection': 'inyección de contexto', + 'message.contextRecall': 'Recuerdo de sesión', + 'message.referenceSummary': 'Sesión referenciada · {labels}', + 'message.referenceSeparator': ', ', + 'message.context.instructions.loaded': 'cargado', + 'message.context.instructions.added': 'añadido', + 'message.context.instructions.updated': 'actualizado', + 'message.context.instructions.removed': 'eliminado', + 'message.context.catalog.replaced': 'Catálogo de repuestos', + 'message.context.catalog.more': '… {count} más', + 'message.context.snapshot.supersedes': 'Reemplaza instantáneas anteriores', + 'message.context.relay.from': 'De la sesión {session}', + 'message.context.recall.counts': '{retained} mantenido · {omitted} omitido', + 'message.context.recall.truncated': 'truncado', + 'message.compaction': 'Contexto compactado', + 'message.compaction.running': 'Contexto de compactación…', + 'message.compaction.completed': 'Elementos del historial {items} compactados (~tokens {tokens})', + 'message.compaction.expand': 'Ver resumen de compactación', + 'message.compaction.unavailable': 'Resumen de compactación no disponible', + 'message.compaction.commandTitle': 'compacto', + 'message.think': 'pensar', + 'message.unknownSurface': 'Evento de superficie desconocido: {type}', + 'message.unknownBlock': 'Bloque de contenido desconocido', + 'message.turnProcess.toolCalls.one': 'Llamada a la herramienta {count}', + 'message.turnProcess.toolCalls.other': 'Llamadas a herramientas {count}', + 'message.turnProcess.messages.one': 'Mensaje {count}', + 'message.turnProcess.messages.other': 'Mensajes {count}', + 'message.turnProcess.subagents.one': 'Subagente {count}', + 'message.turnProcess.subagents.other': 'Subagentes {count}', + 'message.turnProcess.thoughtForAWhile': 'Pensé por un tiempo', + 'message.turnProcess.separator': ' · ', + 'message.stopped': 'Detenido', + 'message.branch': 'Pasar a una nueva conversación', + 'message.branchUnavailable': 'Disponible solo en el último mensaje de un turno completado', + 'message.retry.active': 'Reintentando solicitud de modelo', + 'message.retry.cancelled': 'Reintento de solicitud de modelo cancelado', + 'message.retry.started': 'Solicitud de modelo reintentada', + 'message.retry.scheduled': 'Esperando para volver a intentar la solicitud de modelo', + 'message.retry.status': '{label} ({retry}/{maximum}) · {seconds}s', + 'message.retry.delay': 'Retraso de reintento: ', + 'message.retry.failure': 'Razón del fracaso: ', + 'message.failure.auth': 'La clave API no es válida', + 'message.taskStopped': 'Tarea detenida', + 'message.failure.accountSignedOut': 'Se detuvo porque cerró sesión en DeepSeek.', + 'message.failure.interrupted': 'El proceso DSH salió antes de que terminara este turno (por ejemplo, se detuvo, se estrelló o se agotó el tiempo de espera mientras se apagaba), por lo que el turno se cerró cuando se reinició DSH. Las llamadas a herramientas inacabadas tienen resultados desconocidos.', + 'message.failure.accountSignInRequired': 'Inicie sesión en DeepSeek y asegúrese de que el destino de la solicitud admita la autenticación de la cuenta.', + 'message.failure.quota': 'Solicitud de cupo agotado.', + 'message.turnError': 'Este turno falló', + 'message.maxTokens': 'Se alcanzó el límite del token de salida', + 'message.maxTokens.hint': 'La respuesta fue cortada; La salida anterior se conserva en la conversación. Envíe "continuar" para permitir que se reanude el modelo.', + 'message.tokensPerSecond': '{tps} tok/s', + 'message.turnUsage.title': 'Uso del turno', + 'message.turnUsage.consumed': 'Uso {total}', + 'message.turnUsage.model': 'Proveedor / modelo', + 'message.turnUsage.cacheHit': 'Golpe de caché', + 'message.turnUsage.input': 'Entrada sin caché', + 'message.turnUsage.cacheRead': 'Entrada en caché', + 'message.turnUsage.cacheWrite': 'escritura en caché', + 'message.turnUsage.output': 'Salida', + 'message.turnUsage.reasoning': ' (razonamiento {tokens})', + 'message.turnUsage.count': 'Tok {count}', + 'duration.secondUnit': 's', + 'duration.minuteUnit': 'm ', + 'duration.hourUnit': 'h ', + 'command.running': 'Corriendo…', + 'command.failed': 'El comando falló', + 'command.done': 'Completado', + 'command.title': 'Comando', + 'row.running': 'corriendo', + 'row.failed': 'Fallido', + 'json.truncated': '… truncado, caracteres {total} en total', + 'clock.md': '{m}/{d}', + 'clock.ymd': '{y}-{m}-{d}', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'message.stepProcess.thinking': 'Analyser la demande', + 'message.stepProcess.read': 'Lecture de fichiers', + 'message.stepProcess.readImage': 'Lire des images', + 'message.stepProcess.write': 'Écriture de fichiers', + 'message.stepProcess.search': 'Recherche de code', + 'message.stepProcess.edit': 'Modification de fichiers', + 'message.stepProcess.commands': 'Exécuter des commandes', + 'message.stepProcess.code': 'Exécution du code', + 'message.stepProcess.webSearch': 'Recherche sur le Web', + 'message.stepProcess.webFetch': 'Visiter des pages Web', + 'message.stepProcess.subagents': 'Sous-agents de coordination', + 'message.stepProcess.plan': 'Mise à jour du plan', + 'message.stepProcess.questions': 'En attendant votre action', + 'message.stepProcess.tools': "Outils d'appel", + 'message.stepProcess.prepare.read': 'Préparation à la lecture de fichiers', + 'message.stepProcess.prepare.readImage': 'Se préparer à lire des images', + 'message.stepProcess.prepare.write': "Préparation à l'écriture de fichiers", + 'message.stepProcess.prepare.search': 'Préparation à la recherche de code', + 'message.stepProcess.prepare.edit': 'Préparation à la modification de fichiers', + 'message.stepProcess.prepare.commands': "Préparation à l'exécution de commandes", + 'message.stepProcess.prepare.code': "Préparation à l'exécution du code", + 'message.stepProcess.prepare.webSearch': 'Se préparer à effectuer une recherche sur le Web', + 'message.stepProcess.prepare.webFetch': 'Se préparer à visiter des pages Web', + 'message.stepProcess.prepare.subagents': 'Se préparer à coordonner les sous-agents', + 'message.stepProcess.prepare.plan': 'Préparation de la mise à jour du plan', + 'message.stepProcess.prepare.questions': 'Préparation des questions', + 'message.stepProcess.prepare.tools': "Préparation des appels d'outils", + 'message.stepProcess.done.thinking': 'Analyse terminée', + 'message.stepProcess.done.read': 'Lire des fichiers', + 'message.stepProcess.done.readImage': 'Lire des images', + 'message.stepProcess.done.write': 'A écrit des fichiers', + 'message.stepProcess.done.search': 'Code recherché', + 'message.stepProcess.done.edit': 'Fichiers modifiés', + 'message.stepProcess.done.commands': 'Commandes exécutées', + 'message.stepProcess.done.code': 'Code exécuté', + 'message.stepProcess.done.webSearch': "J'ai cherché sur le Web", + 'message.stepProcess.done.webFetch': 'Pages Web visitées', + 'message.stepProcess.done.subagents': 'Sous-agents coordonnés', + 'message.stepProcess.done.plan': 'Plan mis à jour', + 'message.stepProcess.done.questions': 'Questions posées', + 'message.stepProcess.done.tools': 'Outils appelés', + 'message.stepProcess.joinTwo': '{first} et {second}', + 'message.stepProcess.comma': ', ', + 'message.stepProcess.sharedPrefix': '', + 'message.stepProcess.more': '{title}, etc.', + 'message.trigger.request': 'Exécution demandée', + 'message.trigger.goal': 'Objectif continu', + 'message.trigger.agent': 'Message de tâche reçu', + 'message.trigger.team': "Message d'équipe reçu", + 'message.trigger.subagent': 'Statut de la sous-tâche mis à jour', + 'message.trigger.github': 'Événement GitHub reçu', + 'message.trigger.webhook': 'Événement externe reçu', + 'message.trigger.schedule': "Tâche d'automatisation", + 'message.trigger.job': 'Tâche en arrière-plan mise à jour', + 'message.trigger.plugin': 'Statut du plugin mis à jour', + 'message.trigger.explanation': 'Cette notification a déclenché cette réponse.', + 'message.turnProcess.worked': 'Terminé', + 'message.turnProcess.took': 'Terminé en ', + 'message.turnProcess.failed': 'Échec', + 'view.chat': 'Discuter', + 'image.open': "Voir l'image complète", + 'image.loading': "Chargement de l'image…", + 'image.failed': "Aperçu de l'image indisponible", + 'image.dialog': "Aperçu de l'image", + 'image.close': "Fermer l'aperçu de l'image", + 'number.groupSeparator': ',', + 'duration.compactSeconds': '{seconds}s', + 'duration.compactMinutes': '{minutes}m{seconds}s', + 'duration.milliseconds': '{milliseconds}ms', + 'stats.counts': '{turns} tours, {steps} étapes', + 'stats.cacheHit': 'Cache atteint {percent}%', + 'stats.dialog.title': 'Statistiques de session', + 'stats.dialog.usageTitle': 'Utilisation des jetons', + 'stats.dialog.llmTime': 'Temps LLM', + 'stats.dialog.toolTime': "Temps d'outil", + 'stats.dialog.ttft': "Temps moyen jusqu'au premier jeton (TTFT)", + 'stats.dialog.speed': 'Jetons par seconde (TPS)', + 'chat.loadingHistory': "Chargement de l'historique…", + 'chat.loadError': "Échec du chargement de l'historique : {message} ({code})", + 'chat.loadOlder': 'Charger plus tôt', + 'chat.toBottom': 'Retour en bas', + 'chat.deepDiving': 'Plongée profonde', + 'chat.deepDivingFor': 'Plongée profonde pour {duration} ···', + 'chat.turnNavigation.label': 'Navigation entre les tours', + 'chat.turnNavigation.jump': 'Aller au tour {turn}', + 'chat.turnNavigation.jumpLoad': 'Charger et aller au tour {turn}', + 'chat.turnNavigation.turn': 'Tour {turn}', + 'settings.performance.title': 'Performances et utilisation', + 'settings.performance.description': "Choisissez la quantité d'informations sur les performances et l'utilisation à afficher", + 'settings.performance.compact': 'Compacte', + 'settings.performance.detailed': 'Détaillé', + 'settings.links.title': 'Ouvrir les liens de discussion dans', + 'settings.links.description': 'Choisissez où ouvrir les liens Web', + 'settings.links.sidebar': "Barre latérale dans l'application", + 'settings.links.newTab': 'Navigateur par défaut', + 'settings.transcript.title': 'Détails du travail', + 'settings.transcript.description': "Choisissez le niveau de détails à afficher pour les appels d'outils", + 'settings.collapse.title': 'Quand réduire les détails du travail', + 'settings.collapse.description': 'Choisissez quand réduire automatiquement les détails du travail', + 'settings.collapse.completion': 'À la fin', + 'settings.collapse.nextInput': 'Au prochain message', + 'settings.foldedReplies.title': "Réponses après l'effondrement", + 'settings.foldedReplies.description': "Choisissez quelles réponses de l'assistant restent visibles lorsque les détails du travail sont réduits", + 'settings.foldedReplies.all': 'Toutes les réponses', + 'settings.foldedReplies.final': 'Réponse finale seulement', + 'settings.transcript.compact': 'Compacte', + 'settings.transcript.standard': 'Norme', + 'settings.transcript.detailed': 'Détaillé', + 'settings.transcript.verbose': 'Verbeux', + 'fileOpen.title': "Impossible d'ouvrir le fichier", + 'fileOpen.unknown': "Impossible d'ouvrir ce fichier", + 'message.extraBlock': 'Bloc de contenu supplémentaire', + 'message.systemPrompt': 'Invite système', + 'message.systemPromptUpdate': "Mise à jour de l'invite du système", + 'message.toolAdded': 'Outil ajouté : {name}', + 'message.toolRemoved': 'Outil supprimé : {name}', + 'message.toolsAdded': 'Ajouté : {names}', + 'message.toolsAddedCount': '{count} ajouté', + 'message.toolsChanged': '{added} ajouté, {removed} supprimé', + 'message.toolsRemoved': 'Supprimé : {names}', + 'message.toolsRemovedCount': '{count} supprimé', + 'message.toolsUpdated': 'Outils mis à jour', + 'message.contextInjection': 'Injection de contexte', + 'message.contextRecall': 'Rappel de session', + 'message.referenceSummary': 'Séance référencée · {labels}', + 'message.referenceSeparator': ', ', + 'message.context.instructions.loaded': 'chargé', + 'message.context.instructions.added': 'ajouté', + 'message.context.instructions.updated': 'mis à jour', + 'message.context.instructions.removed': 'supprimé', + 'message.context.catalog.replaced': 'Catalogue de remplacement', + 'message.context.catalog.more': '… {count} plus', + 'message.context.snapshot.supersedes': 'Remplace les instantanés précédents', + 'message.context.relay.from': 'De la séance {session}', + 'message.context.recall.counts': '{retained} conservé · {omitted} omis', + 'message.context.recall.truncated': 'tronqué', + 'message.compaction': 'Contexte compacté', + 'message.compaction.running': 'Contexte de compactage…', + 'message.compaction.completed': "Éléments d'historique {items} compactés (~jetons {tokens})", + 'message.compaction.expand': 'Afficher le résumé du compactage', + 'message.compaction.unavailable': 'Résumé du compactage indisponible', + 'message.compaction.commandTitle': 'compacte', + 'message.think': 'Pensez', + 'message.unknownSurface': 'Événement de surface inconnu : {type}', + 'message.unknownBlock': 'Bloc de contenu inconnu', + 'message.turnProcess.toolCalls.one': "Appel d'outil {count}", + 'message.turnProcess.toolCalls.other': "Appels d'outil {count}", + 'message.turnProcess.messages.one': 'Message {count}', + 'message.turnProcess.messages.other': 'Messages {count}', + 'message.turnProcess.subagents.one': 'Sous-agent {count}', + 'message.turnProcess.subagents.other': 'Sous-agents {count}', + 'message.turnProcess.thoughtForAWhile': "J'ai pensé pendant un moment", + 'message.turnProcess.separator': ' · ', + 'message.stopped': 'Arrêté', + 'message.branch': 'Lancez-vous dans une nouvelle conversation', + 'message.branchUnavailable': "Disponible uniquement sur le dernier message d'un tour terminé", + 'message.retry.active': 'Nouvelle tentative de demande de modèle', + 'message.retry.cancelled': 'Nouvelle tentative de demande de modèle annulée', + 'message.retry.started': 'Demande de modèle réessayée', + 'message.retry.scheduled': 'En attente de réessayer la demande de modèle', + 'message.retry.status': '{label} ({retry}/{maximum}) · {seconds}', + 'message.retry.delay': 'Délai de nouvelle tentative : ', + 'message.retry.failure': "Raison de l'échec : ", + 'message.failure.auth': "La clé API n'est pas valide", + 'message.taskStopped': 'Tâche arrêtée', + 'message.failure.accountSignedOut': 'Arrêté car vous vous êtes déconnecté de DeepSeek.', + 'message.failure.interrupted': "Le processus DSH s'est terminé avant la fin de ce tour (par exemple, il a été arrêté, s'est écrasé ou a expiré lors de l'arrêt), de sorte que le tour a été fermé lorsque DSH a redémarré. Les appels d’outils inachevés ont des résultats inconnus.", + 'message.failure.accountSignInRequired': "Connectez-vous à DeepSeek et assurez-vous que la destination de la demande prend en charge l'authentification du compte.", + 'message.failure.quota': 'Quota de demandes épuisé.', + 'message.turnError': 'Ce tour a échoué', + 'message.maxTokens': 'Limite de jetons de sortie atteinte', + 'message.maxTokens.hint': 'La réponse fut coupée ; la sortie antérieure est conservée dans la conversation. Envoyez « continuer » pour laisser le modèle reprendre.', + 'message.tokensPerSecond': '{tps} jetons/s', + 'message.turnUsage.title': 'Consommation du tour', + 'message.turnUsage.consumed': 'Utilisation {total}', + 'message.turnUsage.model': 'Fournisseur / modèle', + 'message.turnUsage.cacheHit': 'Accès au cache', + 'message.turnUsage.input': 'Entrée non mise en cache', + 'message.turnUsage.cacheRead': 'Entrée en cache', + 'message.turnUsage.cacheWrite': 'Écriture en cache', + 'message.turnUsage.output': 'Sortie', + 'message.turnUsage.reasoning': ' (raisonnement {tokens})', + 'message.turnUsage.count': 'Jeton {count}', + 'duration.secondUnit': 's', + 'duration.minuteUnit': 'm ', + 'duration.hourUnit': 'h ', + 'command.running': 'Courir…', + 'command.failed': 'La commande a échoué', + 'command.done': 'Terminé', + 'command.title': 'Commande', + 'row.running': 'Courir', + 'row.failed': 'Échec', + 'json.truncated': '… tronqué, nombre total de caractères {total}', + 'clock.md': '{m}/{d}', + 'clock.ymd': '{y}-{m}-{d}', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'message.stepProcess.thinking': 'Analyse der Anfrage', + 'message.stepProcess.read': 'Dateien lesen', + 'message.stepProcess.readImage': 'Bilder lesen', + 'message.stepProcess.write': 'Dateien schreiben', + 'message.stepProcess.search': 'Code wird gesucht', + 'message.stepProcess.edit': 'Bearbeiten von Dateien', + 'message.stepProcess.commands': 'Befehle ausführen', + 'message.stepProcess.code': 'Ausführen von Code', + 'message.stepProcess.webSearch': 'Suche im Internet', + 'message.stepProcess.webFetch': 'Besuch von Webseiten', + 'message.stepProcess.subagents': 'Koordinierende Unteragenten', + 'message.stepProcess.plan': 'Aktualisierung des Plans', + 'message.stepProcess.questions': 'Ich warte auf Ihre Aktion', + 'message.stepProcess.tools': 'Aufrufende Werkzeuge', + 'message.stepProcess.prepare.read': 'Vorbereitung zum Lesen von Dateien', + 'message.stepProcess.prepare.readImage': 'Vorbereitung zum Lesen von Bildern', + 'message.stepProcess.prepare.write': 'Vorbereitung zum Schreiben von Dateien', + 'message.stepProcess.prepare.search': 'Vorbereiten der Codesuche', + 'message.stepProcess.prepare.edit': 'Vorbereitung zum Bearbeiten von Dateien', + 'message.stepProcess.prepare.commands': 'Vorbereitung zum Ausführen von Befehlen', + 'message.stepProcess.prepare.code': 'Vorbereiten, Code auszuführen', + 'message.stepProcess.prepare.webSearch': 'Bereiten Sie sich auf die Suche im Internet vor', + 'message.stepProcess.prepare.webFetch': 'Vorbereitung auf den Besuch von Webseiten', + 'message.stepProcess.prepare.subagents': 'Vorbereitung zur Koordinierung von Subagenten', + 'message.stepProcess.prepare.plan': 'Vorbereitung zur Aktualisierung des Plans', + 'message.stepProcess.prepare.questions': 'Fragen vorbereiten', + 'message.stepProcess.prepare.tools': 'Toolaufrufe vorbereiten', + 'message.stepProcess.done.thinking': 'Analyse abgeschlossen', + 'message.stepProcess.done.read': 'Dateien lesen', + 'message.stepProcess.done.readImage': 'Bilder lesen', + 'message.stepProcess.done.write': 'Dateien geschrieben', + 'message.stepProcess.done.search': 'Gesuchter Code', + 'message.stepProcess.done.edit': 'Bearbeitete Dateien', + 'message.stepProcess.done.commands': 'Befehle ausgeführt', + 'message.stepProcess.done.code': 'Code ausgeführt', + 'message.stepProcess.done.webSearch': 'Habe das Internet durchsucht', + 'message.stepProcess.done.webFetch': 'Besuchte Webseiten', + 'message.stepProcess.done.subagents': 'Koordinierte Unteragenten', + 'message.stepProcess.done.plan': 'Plan aktualisiert', + 'message.stepProcess.done.questions': 'Gestellte Fragen', + 'message.stepProcess.done.tools': 'Werkzeuge genannt', + 'message.stepProcess.joinTwo': '{first} und {second}', + 'message.stepProcess.comma': ', ', + 'message.stepProcess.sharedPrefix': '', + 'message.stepProcess.more': '{title} usw.', + 'message.trigger.request': 'Ausführung beantragt', + 'message.trigger.goal': 'Weiterführendes Ziel', + 'message.trigger.agent': 'Aufgabennachricht erhalten', + 'message.trigger.team': 'Teamnachricht erhalten', + 'message.trigger.subagent': 'Unteraufgabenstatus aktualisiert', + 'message.trigger.github': 'GitHub-Ereignis empfangen', + 'message.trigger.webhook': 'Externes Ereignis empfangen', + 'message.trigger.schedule': 'Automatisierungsaufgabe', + 'message.trigger.job': 'Hintergrundaufgabe aktualisiert', + 'message.trigger.plugin': 'Plugin-Status aktualisiert', + 'message.trigger.explanation': 'Diese Benachrichtigung hat diese Reaktion ausgelöst.', + 'message.turnProcess.worked': 'Abgeschlossen', + 'message.turnProcess.took': 'Fertiggestellt in ', + 'message.turnProcess.failed': 'Fehlgeschlagen', + 'view.chat': 'Chatten', + 'image.open': 'Vollständiges Bild anzeigen', + 'image.loading': 'Bild wird geladen…', + 'image.failed': 'Bildvorschau nicht verfügbar', + 'image.dialog': 'Bildvorschau', + 'image.close': 'Bildvorschau schließen', + 'number.groupSeparator': ',', + 'duration.compactSeconds': '{seconds}s', + 'duration.compactMinutes': '{minutes}m{seconds}s', + 'duration.milliseconds': '{milliseconds}ms', + 'stats.counts': '{turns} Runden, {steps} Schritte', + 'stats.cacheHit': 'Cache-Treffer {percent}%', + 'stats.dialog.title': 'Sitzungsstatistiken', + 'stats.dialog.usageTitle': 'Token-Nutzung', + 'stats.dialog.llmTime': 'LLM-Zeit', + 'stats.dialog.toolTime': 'Werkzeugzeit', + 'stats.dialog.ttft': 'Durchschnittliche Zeit bis zum ersten Token (TTFT)', + 'stats.dialog.speed': 'Token pro Sekunde (TPS)', + 'chat.loadingHistory': 'Verlauf wird geladen…', + 'chat.loadError': 'Fehler beim Laden des Verlaufs: {message} ({code})', + 'chat.loadOlder': 'Früher laden', + 'chat.toBottom': 'Zurück nach unten', + 'chat.deepDiving': 'Tieftauchen', + 'chat.deepDivingFor': 'Tieftauchen für {duration} ···', + 'chat.turnNavigation.label': 'Rundennavigation', + 'chat.turnNavigation.jump': 'Zu Runde {turn} springen', + 'chat.turnNavigation.jumpLoad': 'Runde {turn} laden und öffnen', + 'chat.turnNavigation.turn': 'Runde {turn}', + 'settings.performance.title': 'Leistung und Nutzung', + 'settings.performance.description': 'Wählen Sie aus, wie viele Leistungs- und Nutzungsinformationen angezeigt werden sollen', + 'settings.performance.compact': 'Kompakt', + 'settings.performance.detailed': 'Ausführlich', + 'settings.links.title': 'Öffnen Sie Chat-Links in', + 'settings.links.description': 'Wählen Sie aus, wo Weblinks geöffnet werden sollen', + 'settings.links.sidebar': 'In-App-Seitenleiste', + 'settings.links.newTab': 'Standardbrowser', + 'settings.transcript.title': 'Arbeitsdetails', + 'settings.transcript.description': 'Wählen Sie aus, wie viele Details für Werkzeugaufrufe angezeigt werden sollen', + 'settings.collapse.title': 'Wann Arbeitsdetails minimiert werden sollten', + 'settings.collapse.description': 'Wählen Sie aus, wann Arbeitsdetails automatisch ausgeblendet werden sollen', + 'settings.collapse.completion': 'Nach Fertigstellung', + 'settings.collapse.nextInput': 'Bei der nächsten Nachricht', + 'settings.foldedReplies.title': 'Antworten nach dem Zusammenbruch', + 'settings.foldedReplies.description': 'Wählen Sie aus, welche Assistentenantworten sichtbar bleiben, wenn die Arbeitsdetails ausgeblendet werden', + 'settings.foldedReplies.all': 'Alle Antworten', + 'settings.foldedReplies.final': 'Nur die endgültige Antwort', + 'settings.transcript.compact': 'Kompakt', + 'settings.transcript.standard': 'Standard', + 'settings.transcript.detailed': 'Ausführlich', + 'settings.transcript.verbose': 'Ausführlich', + 'fileOpen.title': 'Datei konnte nicht geöffnet werden', + 'fileOpen.unknown': 'Diese Datei konnte nicht geöffnet werden', + 'message.extraBlock': 'Zusätzlicher Inhaltsblock', + 'message.systemPrompt': 'Systemaufforderung', + 'message.systemPromptUpdate': 'Aktualisierung der Systemaufforderung', + 'message.toolAdded': 'Tool hinzugefügt: {name}', + 'message.toolRemoved': 'Entferntes Werkzeug: {name}', + 'message.toolsAdded': 'Hinzugefügt: {names}', + 'message.toolsAddedCount': '{count} hinzugefügt', + 'message.toolsChanged': '{added} hinzugefügt, {removed} entfernt', + 'message.toolsRemoved': 'Entfernt: {names}', + 'message.toolsRemovedCount': '{count} entfernt', + 'message.toolsUpdated': 'Werkzeuge aktualisiert', + 'message.contextInjection': 'Kontextinjektion', + 'message.contextRecall': 'Sitzungsrückruf', + 'message.referenceSummary': 'Referenzierte Sitzung · {labels}', + 'message.referenceSeparator': ', ', + 'message.context.instructions.loaded': 'geladen', + 'message.context.instructions.added': 'hinzugefügt', + 'message.context.instructions.updated': 'aktualisiert', + 'message.context.instructions.removed': 'entfernt', + 'message.context.catalog.replaced': 'Ersatzkatalog', + 'message.context.catalog.more': '… {count} mehr', + 'message.context.snapshot.supersedes': 'Ersetzt frühere Schnappschüsse', + 'message.context.relay.from': 'Aus der Sitzung {session}', + 'message.context.recall.counts': '{retained} beibehalten · {omitted} weggelassen', + 'message.context.recall.truncated': 'abgeschnitten', + 'message.compaction': 'Kontext verdichtet', + 'message.compaction.running': 'Kontext verdichten…', + 'message.compaction.completed': 'Komprimierte {items}-Verlaufselemente (~{tokens}-Tokens)', + 'message.compaction.expand': 'Komprimierungszusammenfassung anzeigen', + 'message.compaction.unavailable': 'Komprimierungszusammenfassung nicht verfügbar', + 'message.compaction.commandTitle': 'kompakt', + 'message.think': 'Denken Sie nach', + 'message.unknownSurface': 'Unbekanntes Oberflächenereignis: {type}', + 'message.unknownBlock': 'Unbekannter Inhaltsblock', + 'message.turnProcess.toolCalls.one': 'Werkzeugaufruf {count}', + 'message.turnProcess.toolCalls.other': '{count} Toolaufrufe', + 'message.turnProcess.messages.one': '{count}-Nachricht', + 'message.turnProcess.messages.other': '{count}-Nachrichten', + 'message.turnProcess.subagents.one': '{count}-Subagent', + 'message.turnProcess.subagents.other': '{count}-Subagenten', + 'message.turnProcess.thoughtForAWhile': 'Habe eine Weile nachgedacht', + 'message.turnProcess.separator': ' · ', + 'message.stopped': 'Angehalten', + 'message.branch': 'Verzweigen Sie in ein neues Gespräch', + 'message.branchUnavailable': 'Nur verfügbar bei der letzten Nachricht einer abgeschlossenen Runde', + 'message.retry.active': 'Modellanforderung wird erneut versucht', + 'message.retry.cancelled': 'Wiederholungsversuch der Modellanforderung abgebrochen', + 'message.retry.started': 'Modellanfrage erneut versucht', + 'message.retry.scheduled': 'Warten auf erneuten Versuch der Modellanforderung', + 'message.retry.status': '{label} ({retry}/{maximum}) · {seconds}s', + 'message.retry.delay': 'Wiederholungsverzögerung: ', + 'message.retry.failure': 'Fehlergrund: ', + 'message.failure.auth': 'Der API-Schlüssel ist ungültig', + 'message.taskStopped': 'Aufgabe gestoppt', + 'message.failure.accountSignedOut': 'Gestoppt, weil Sie sich von DeepSeek abgemeldet haben.', + 'message.failure.interrupted': 'Der DSH-Prozess wurde beendet, bevor dieser Zug beendet war (z. B. wurde er beendet, stürzte ab oder es kam zu einer Zeitüberschreitung beim Herunterfahren), sodass der Zug geschlossen wurde, als DSH neu gestartet wurde. Unvollendete Werkzeugaufrufe haben unbekannte Ergebnisse.', + 'message.failure.accountSignInRequired': 'Melden Sie sich bei DeepSeek an und stellen Sie sicher, dass das Anforderungsziel die Kontoauthentifizierung unterstützt.', + 'message.failure.quota': 'Anforderungskontingent ausgeschöpft.', + 'message.turnError': 'Diese Runde ist fehlgeschlagen', + 'message.maxTokens': 'Ausgabe-Token-Limit erreicht', + 'message.maxTokens.hint': 'Die Antwort wurde abgeschnitten; Frühere Ausgaben bleiben in der Konversation erhalten. Senden Sie „Weiter“, um das Modell fortzusetzen.', + 'message.tokensPerSecond': '{tps} tok/s', + 'message.turnUsage.title': 'Rundenverbrauch', + 'message.turnUsage.consumed': 'Verwendung {total}', + 'message.turnUsage.model': 'Anbieter / Modell', + 'message.turnUsage.cacheHit': 'Cache-Treffer', + 'message.turnUsage.input': 'Nicht zwischengespeicherte Eingabe', + 'message.turnUsage.cacheRead': 'Zwischengespeicherte Eingabe', + 'message.turnUsage.cacheWrite': 'Cache-Schreiben', + 'message.turnUsage.output': 'Ausgabe', + 'message.turnUsage.reasoning': ' ({tokens}-Argumentation)', + 'message.turnUsage.count': '{count}-Token', + 'duration.secondUnit': 's', + 'duration.minuteUnit': 'm ', + 'duration.hourUnit': 'h ', + 'command.running': 'Laufen…', + 'command.failed': 'Der Befehl ist fehlgeschlagen', + 'command.done': 'Abgeschlossen', + 'command.title': 'Befehl', + 'row.running': 'Laufen', + 'row.failed': 'Fehlgeschlagen', + 'json.truncated': '… gekürzt, {total} Zeichen insgesamt', + 'clock.md': '{m}/{d}', + 'clock.ymd': '{y}-{m}-{d}', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'message.stepProcess.thinking': 'Анализ запроса', + 'message.stepProcess.read': 'Чтение файлов', + 'message.stepProcess.readImage': 'Чтение изображений', + 'message.stepProcess.write': 'Запись файлов', + 'message.stepProcess.search': 'Поиск кода', + 'message.stepProcess.edit': 'Редактирование файлов', + 'message.stepProcess.commands': 'Запуск команд', + 'message.stepProcess.code': 'Запуск кода', + 'message.stepProcess.webSearch': 'Поиск в Интернете', + 'message.stepProcess.webFetch': 'Посещение веб-страниц', + 'message.stepProcess.subagents': 'Координирующие субагенты', + 'message.stepProcess.plan': 'Обновление плана', + 'message.stepProcess.questions': 'Жду ваших действий', + 'message.stepProcess.tools': 'Вызов инструментов', + 'message.stepProcess.prepare.read': 'Подготовка к чтению файлов', + 'message.stepProcess.prepare.readImage': 'Подготовка к чтению изображений', + 'message.stepProcess.prepare.write': 'Подготовка к записи файлов', + 'message.stepProcess.prepare.search': 'Подготовка к поиску кода', + 'message.stepProcess.prepare.edit': 'Подготовка к редактированию файлов', + 'message.stepProcess.prepare.commands': 'Подготовка к выполнению команд', + 'message.stepProcess.prepare.code': 'Подготовка к запуску кода', + 'message.stepProcess.prepare.webSearch': 'Подготовка к поиску в Интернете', + 'message.stepProcess.prepare.webFetch': 'Подготовка к посещению веб-страниц', + 'message.stepProcess.prepare.subagents': 'Подготовка к координации субагентов', + 'message.stepProcess.prepare.plan': 'Подготовка к обновлению плана', + 'message.stepProcess.prepare.questions': 'Подготовка вопросов', + 'message.stepProcess.prepare.tools': 'Подготовка вызовов инструментов', + 'message.stepProcess.done.thinking': 'Анализ завершен', + 'message.stepProcess.done.read': 'Чтение файлов', + 'message.stepProcess.done.readImage': 'Чтение изображений', + 'message.stepProcess.done.write': 'Написал файлы', + 'message.stepProcess.done.search': 'Искомый код', + 'message.stepProcess.done.edit': 'Отредактированные файлы', + 'message.stepProcess.done.commands': 'Выполнение команд', + 'message.stepProcess.done.code': 'Выполненный код', + 'message.stepProcess.done.webSearch': 'Искал в Интернете', + 'message.stepProcess.done.webFetch': 'Посещенные веб-страницы', + 'message.stepProcess.done.subagents': 'Координированные субагенты', + 'message.stepProcess.done.plan': 'Обновлен план', + 'message.stepProcess.done.questions': 'Задаваемые вопросы', + 'message.stepProcess.done.tools': 'Вызываемые инструменты', + 'message.stepProcess.joinTwo': '{first} и {second}', + 'message.stepProcess.comma': ', ', + 'message.stepProcess.sharedPrefix': '', + 'message.stepProcess.more': '{title} и т. д.', + 'message.trigger.request': 'Запрошено выполнение', + 'message.trigger.goal': 'Постоянная цель', + 'message.trigger.agent': 'Сообщение о задаче получено', + 'message.trigger.team': 'Сообщение команды получено', + 'message.trigger.subagent': 'Статус подзадачи обновлен', + 'message.trigger.github': 'Событие GitHub получено', + 'message.trigger.webhook': 'Получено внешнее событие', + 'message.trigger.schedule': 'Задача автоматизации', + 'message.trigger.job': 'Фоновая задача обновлена.', + 'message.trigger.plugin': 'Статус плагина обновлен', + 'message.trigger.explanation': 'Это уведомление вызвало такой ответ.', + 'message.turnProcess.worked': 'Завершено', + 'message.turnProcess.took': 'Завершено в ', + 'message.turnProcess.failed': 'Не удалось', + 'view.chat': 'Чат', + 'image.open': 'Посмотреть полное изображение', + 'image.loading': 'Загрузка изображения…', + 'image.failed': 'Предварительный просмотр изображения недоступен.', + 'image.dialog': 'Предварительный просмотр изображения', + 'image.close': 'Закрыть предварительный просмотр изображения', + 'number.groupSeparator': ',', + 'duration.compactSeconds': '{seconds}s', + 'duration.compactMinutes': '{minutes}m{seconds}s', + 'duration.milliseconds': '{milliseconds}ms', + 'stats.counts': 'Ходов: {turns}, шагов: {steps}', + 'stats.cacheHit': 'Попадание в кэш {percent}%', + 'stats.dialog.title': 'Статистика сеансов', + 'stats.dialog.usageTitle': 'Использование токена', + 'stats.dialog.llmTime': 'время магистратуры', + 'stats.dialog.toolTime': 'Время работы инструмента', + 'stats.dialog.ttft': 'Среднее время до первого токена (TTFT)', + 'stats.dialog.speed': 'Токенов в секунду (TPS)', + 'chat.loadingHistory': 'Загрузка истории…', + 'chat.loadError': 'Не удалось загрузить историю: {message} ({code})', + 'chat.loadOlder': 'Загрузить раньше', + 'chat.toBottom': 'Вернуться к низу', + 'chat.deepDiving': 'Глубокое погружение', + 'chat.deepDivingFor': 'Глубокое погружение в {duration} ···', + 'chat.turnNavigation.label': 'Навигация по ходам', + 'chat.turnNavigation.jump': 'Перейти к ходу {turn}', + 'chat.turnNavigation.jumpLoad': 'Загрузить ход {turn} и перейти к нему', + 'chat.turnNavigation.turn': 'Ход {turn}', + 'settings.performance.title': 'Производительность и использование', + 'settings.performance.description': 'Выберите, какой объем информации о производительности и использовании показывать', + 'settings.performance.compact': 'Компактный', + 'settings.performance.detailed': 'Подробный', + 'settings.links.title': 'Открыть ссылки на чат в', + 'settings.links.description': 'Выберите, где открывать веб-ссылки', + 'settings.links.sidebar': 'Боковая панель в приложении', + 'settings.links.newTab': 'Браузер по умолчанию', + 'settings.transcript.title': 'Детали работы', + 'settings.transcript.description': 'Выберите, насколько подробно следует отображать вызовы инструментов.', + 'settings.collapse.title': 'Когда сворачивать детали работы', + 'settings.collapse.description': 'Выберите, когда автоматически сворачивать сведения о работе', + 'settings.collapse.completion': 'По завершении', + 'settings.collapse.nextInput': 'В следующем сообщении', + 'settings.foldedReplies.title': 'Ответы после краха', + 'settings.foldedReplies.description': 'Выберите, какие ответы помощника останутся видимыми, когда сведения о работе будут свернуты.', + 'settings.foldedReplies.all': 'Все ответы', + 'settings.foldedReplies.final': 'Только окончательный ответ', + 'settings.transcript.compact': 'Компактный', + 'settings.transcript.standard': 'Стандартный', + 'settings.transcript.detailed': 'Подробный', + 'settings.transcript.verbose': 'Многословный', + 'fileOpen.title': 'Не удалось открыть файл', + 'fileOpen.unknown': 'Не удалось открыть этот файл', + 'message.extraBlock': 'Дополнительный блок контента', + 'message.systemPrompt': 'Системная подсказка', + 'message.systemPromptUpdate': 'Обновление системного запроса', + 'message.toolAdded': 'Добавлен инструмент: {name}.', + 'message.toolRemoved': 'Инструмент удален: {name}.', + 'message.toolsAdded': 'Добавлено: {names}', + 'message.toolsAddedCount': '{count} добавлен', + 'message.toolsChanged': '{added} добавлен, {removed} удален.', + 'message.toolsRemoved': 'Удалено: {names}.', + 'message.toolsRemovedCount': '{count} удален.', + 'message.toolsUpdated': 'Инструменты обновлены', + 'message.contextInjection': 'Внедрение контекста', + 'message.contextRecall': 'Отзыв сеанса', + 'message.referenceSummary': 'Ссылка на сессию · {labels}', + 'message.referenceSeparator': ', ', + 'message.context.instructions.loaded': 'загружен', + 'message.context.instructions.added': 'добавлено', + 'message.context.instructions.updated': 'обновлено', + 'message.context.instructions.removed': 'удалено', + 'message.context.catalog.replaced': 'Каталог замены', + 'message.context.catalog.more': '… {count} ещё', + 'message.context.snapshot.supersedes': 'Заменяет предыдущие снимки', + 'message.context.relay.from': 'Из сеанса {session}', + 'message.context.recall.counts': '{retained} сохранен · {omitted} опущен', + 'message.context.recall.truncated': 'усеченный', + 'message.compaction': 'Контекст сжат', + 'message.compaction.running': 'Сжатие контекста…', + 'message.compaction.completed': 'Сжатые элементы истории {items} (токены ~{tokens})', + 'message.compaction.expand': 'Посмотреть сводку по уплотнению', + 'message.compaction.unavailable': 'Сводка по уплотнению недоступна.', + 'message.compaction.commandTitle': 'компактный', + 'message.think': 'Подумайте', + 'message.unknownSurface': 'Неизвестное событие на поверхности: {type}.', + 'message.unknownBlock': 'Неизвестный блок контента', + 'message.turnProcess.toolCalls.one': '{count} вызов инструмента', + 'message.turnProcess.toolCalls.other': '{count} вызовов инструментов', + 'message.turnProcess.messages.one': 'Сообщение {count}', + 'message.turnProcess.messages.other': 'Сообщения {count}', + 'message.turnProcess.subagents.one': 'Субагент {count}', + 'message.turnProcess.subagents.other': 'Субагенты {count}', + 'message.turnProcess.thoughtForAWhile': 'Подумал какое-то время', + 'message.turnProcess.separator': ' · ', + 'message.stopped': 'Остановлено', + 'message.branch': 'Перейти к новому разговору', + 'message.branchUnavailable': 'Доступно только в последнем сообщении о завершенном ходу.', + 'message.retry.active': 'Повторный запрос модели', + 'message.retry.cancelled': 'Повтор запроса модели отменен.', + 'message.retry.started': 'Повторный запрос модели', + 'message.retry.scheduled': 'Ожидание повторного запроса модели', + 'message.retry.status': '{label} ({retry}/{maximum}) · {seconds}s', + 'message.retry.delay': 'Задержка повтора: ', + 'message.retry.failure': 'Причина неисправности: ', + 'message.failure.auth': 'Ключ API недействителен.', + 'message.taskStopped': 'Задача остановлена', + 'message.failure.accountSignedOut': 'Остановлено, поскольку вы вышли из DeepSeek.', + 'message.failure.interrupted': 'Процесс DSH завершился до завершения этого хода (например, был завершен, произошел сбой или истекло время ожидания при завершении работы), поэтому ход был закрыт при перезапуске DSH. Незавершенные вызовы инструментов имеют неизвестные результаты.', + 'message.failure.accountSignInRequired': 'Войдите в DeepSeek и убедитесь, что пункт назначения запроса поддерживает аутентификацию учетной записи.', + 'message.failure.quota': 'Квота запросов исчерпана.', + 'message.turnError': 'Этот ход завершился ошибкой', + 'message.maxTokens': 'Достигнут предел выходных токенов', + 'message.maxTokens.hint': 'Ответ был прерван; более ранний вывод сохраняется в разговоре. Отправьте «продолжить», чтобы модель возобновила работу.', + 'message.tokensPerSecond': '{tps} ток/с', + 'message.turnUsage.title': 'Использование ресурсов за ход', + 'message.turnUsage.consumed': 'Использование {total}', + 'message.turnUsage.model': 'Поставщик/модель', + 'message.turnUsage.cacheHit': 'Попадание в кэш', + 'message.turnUsage.input': 'Некэшированный ввод', + 'message.turnUsage.cacheRead': 'Кэшированный ввод', + 'message.turnUsage.cacheWrite': 'Запись в кэш', + 'message.turnUsage.output': 'Выход', + 'message.turnUsage.reasoning': ' (рассуждение {tokens})', + 'message.turnUsage.count': '{count} ток', + 'duration.secondUnit': 'с', + 'duration.minuteUnit': 'м ', + 'duration.hourUnit': 'ч ', + 'command.running': 'Бег…', + 'command.failed': 'Команда не выполнена', + 'command.done': 'Завершено', + 'command.title': 'Команда', + 'row.running': 'Бег', + 'row.failed': 'Не удалось', + 'json.truncated': '… усечено, всего символов {total}', + 'clock.md': '{m}/{d}', + 'clock.ymd': '{y}-{m}-{d}', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'message.stepProcess.thinking': 'Analisando a solicitação', + 'message.stepProcess.read': 'Lendo arquivos', + 'message.stepProcess.readImage': 'Lendo imagens', + 'message.stepProcess.write': 'Gravando arquivos', + 'message.stepProcess.search': 'Pesquisando código', + 'message.stepProcess.edit': 'Editando arquivos', + 'message.stepProcess.commands': 'Executando comandos', + 'message.stepProcess.code': 'Executando código', + 'message.stepProcess.webSearch': 'Pesquisando na web', + 'message.stepProcess.webFetch': 'Visitando páginas da web', + 'message.stepProcess.subagents': 'Coordenando subagentes', + 'message.stepProcess.plan': 'Atualizando o plano', + 'message.stepProcess.questions': 'Esperando por sua ação', + 'message.stepProcess.tools': 'Ferramentas de chamada', + 'message.stepProcess.prepare.read': 'Preparando-se para ler arquivos', + 'message.stepProcess.prepare.readImage': 'Preparando-se para ler imagens', + 'message.stepProcess.prepare.write': 'Preparando-se para gravar arquivos', + 'message.stepProcess.prepare.search': 'Preparando-se para pesquisar o código', + 'message.stepProcess.prepare.edit': 'Preparando-se para editar arquivos', + 'message.stepProcess.prepare.commands': 'Preparando para executar comandos', + 'message.stepProcess.prepare.code': 'Preparando-se para executar o código', + 'message.stepProcess.prepare.webSearch': 'Preparando-se para pesquisar na web', + 'message.stepProcess.prepare.webFetch': 'Preparando-se para visitar páginas da web', + 'message.stepProcess.prepare.subagents': 'Preparando-se para coordenar subagentes', + 'message.stepProcess.prepare.plan': 'Preparando-se para atualizar o plano', + 'message.stepProcess.prepare.questions': 'Preparando perguntas', + 'message.stepProcess.prepare.tools': 'Preparando chamadas de ferramenta', + 'message.stepProcess.done.thinking': 'Análise concluída', + 'message.stepProcess.done.read': 'Ler arquivos', + 'message.stepProcess.done.readImage': 'Ler imagens', + 'message.stepProcess.done.write': 'Escreveu arquivos', + 'message.stepProcess.done.search': 'Código pesquisado', + 'message.stepProcess.done.edit': 'Arquivos editados', + 'message.stepProcess.done.commands': 'Comandos executados', + 'message.stepProcess.done.code': 'Código executado', + 'message.stepProcess.done.webSearch': 'Pesquisei na web', + 'message.stepProcess.done.webFetch': 'Páginas da web visitadas', + 'message.stepProcess.done.subagents': 'Subagentes coordenados', + 'message.stepProcess.done.plan': 'Atualizado o plano', + 'message.stepProcess.done.questions': 'Perguntas feitas', + 'message.stepProcess.done.tools': 'Ferramentas chamadas', + 'message.stepProcess.joinTwo': '{first} e {second}', + 'message.stepProcess.comma': ', ', + 'message.stepProcess.sharedPrefix': '', + 'message.stepProcess.more': '{title}, etc.', + 'message.trigger.request': 'Execução solicitada', + 'message.trigger.goal': 'Objetivo contínuo', + 'message.trigger.agent': 'Mensagem de tarefa recebida', + 'message.trigger.team': 'Mensagem da equipe recebida', + 'message.trigger.subagent': 'Status da subtarefa atualizado', + 'message.trigger.github': 'GitHub evento recebido', + 'message.trigger.webhook': 'Evento externo recebido', + 'message.trigger.schedule': 'Tarefa de automação', + 'message.trigger.job': 'Tarefa em segundo plano atualizada', + 'message.trigger.plugin': 'Status do plug-in atualizado', + 'message.trigger.explanation': 'Esta notificação desencadeou esta resposta.', + 'message.turnProcess.worked': 'Concluído', + 'message.turnProcess.took': 'Concluído em ', + 'message.turnProcess.failed': 'Falha', + 'view.chat': 'Bate-papo', + 'image.open': 'Ver imagem completa', + 'image.loading': 'Carregando imagem…', + 'image.failed': 'Visualização da imagem indisponível', + 'image.dialog': 'Visualização da imagem', + 'image.close': 'Fechar visualização da imagem', + 'number.groupSeparator': ',', + 'duration.compactSeconds': '{seconds}s', + 'duration.compactMinutes': '{minutes}m{seconds}s', + 'duration.milliseconds': '{milliseconds}ms', + 'stats.counts': '{turns} turnos, {steps} etapas', + 'stats.cacheHit': 'Ocorrência de cache {percent}%', + 'stats.dialog.title': 'Estatísticas da sessão', + 'stats.dialog.usageTitle': 'Uso de token', + 'stats.dialog.llmTime': 'Horário do LLM', + 'stats.dialog.toolTime': 'Tempo da ferramenta', + 'stats.dialog.ttft': 'Tempo médio para o primeiro token (TTFT)', + 'stats.dialog.speed': 'Tokens por segundo (TPS)', + 'chat.loadingHistory': 'Carregando histórico…', + 'chat.loadError': 'Falha ao carregar o histórico: {message} ({code})', + 'chat.loadOlder': 'Carregar mais cedo', + 'chat.toBottom': 'De volta ao fundo', + 'chat.deepDiving': 'Mergulho profundo', + 'chat.deepDivingFor': 'Mergulho profundo para {duration} ···', + 'chat.turnNavigation.label': 'Navegação entre turnos', + 'chat.turnNavigation.jump': 'Ir para o turno {turn}', + 'chat.turnNavigation.jumpLoad': 'Carregar e ir para o turno {turn}', + 'chat.turnNavigation.turn': 'Turno {turn}', + 'settings.performance.title': 'Desempenho e uso', + 'settings.performance.description': 'Escolha quantas informações de desempenho e uso serão exibidas', + 'settings.performance.compact': 'Compacto', + 'settings.performance.detailed': 'Detalhado', + 'settings.links.title': 'Abra links de bate-papo em', + 'settings.links.description': 'Escolha onde abrir links da web', + 'settings.links.sidebar': 'Barra lateral no aplicativo', + 'settings.links.newTab': 'Navegador padrão', + 'settings.transcript.title': 'Detalhes do trabalho', + 'settings.transcript.description': 'Escolha quantos detalhes serão exibidos nas chamadas de ferramenta', + 'settings.collapse.title': 'Quando recolher detalhes do trabalho', + 'settings.collapse.description': 'Escolha quando recolher automaticamente os detalhes do trabalho', + 'settings.collapse.completion': 'Na conclusão', + 'settings.collapse.nextInput': 'Na próxima mensagem', + 'settings.foldedReplies.title': 'Respostas após o colapso', + 'settings.foldedReplies.description': 'Escolha quais respostas do assistente permanecerão visíveis quando os detalhes do trabalho forem recolhidos', + 'settings.foldedReplies.all': 'Todas as respostas', + 'settings.foldedReplies.final': 'Apenas resposta final', + 'settings.transcript.compact': 'Compacto', + 'settings.transcript.standard': 'Padrão', + 'settings.transcript.detailed': 'Detalhado', + 'settings.transcript.verbose': 'Verboso', + 'fileOpen.title': 'Não foi possível abrir o arquivo', + 'fileOpen.unknown': 'Não foi possível abrir este arquivo', + 'message.extraBlock': 'Bloco de conteúdo extra', + 'message.systemPrompt': 'Alerta do sistema', + 'message.systemPromptUpdate': 'Atualização imediata do sistema', + 'message.toolAdded': 'Ferramenta adicionada: {name}', + 'message.toolRemoved': 'Ferramenta removida: {name}', + 'message.toolsAdded': 'Adicionado: {names}', + 'message.toolsAddedCount': '{count} adicionado', + 'message.toolsChanged': '{added} adicionado, {removed} removido', + 'message.toolsRemoved': 'Removido: {names}', + 'message.toolsRemovedCount': '{count} removido', + 'message.toolsUpdated': 'Ferramentas atualizadas', + 'message.contextInjection': 'Injeção de contexto', + 'message.contextRecall': 'Recuperação de sessão', + 'message.referenceSummary': 'Sessão referenciada · {labels}', + 'message.referenceSeparator': ', ', + 'message.context.instructions.loaded': 'carregado', + 'message.context.instructions.added': 'adicionado', + 'message.context.instructions.updated': 'atualizado', + 'message.context.instructions.removed': 'removido', + 'message.context.catalog.replaced': 'Catálogo de substituição', + 'message.context.catalog.more': '… {count} mais', + 'message.context.snapshot.supersedes': 'Substitui instantâneos anteriores', + 'message.context.relay.from': 'Da sessão {session}', + 'message.context.recall.counts': '{retained} mantido · {omitted} omitido', + 'message.context.recall.truncated': 'truncado', + 'message.compaction': 'Contexto compactado', + 'message.compaction.running': 'Contexto compactado…', + 'message.compaction.completed': '{items} itens de histórico compactados (~{tokens} tokens)', + 'message.compaction.expand': 'Ver resumo de compactação', + 'message.compaction.unavailable': 'Resumo de compactação indisponível', + 'message.compaction.commandTitle': 'compacto', + 'message.think': 'Pense', + 'message.unknownSurface': 'Evento de superfície desconhecido: {type}', + 'message.unknownBlock': 'Bloco de conteúdo desconhecido', + 'message.turnProcess.toolCalls.one': '{count} chamada de ferramenta', + 'message.turnProcess.toolCalls.other': '{count} chamadas de ferramenta', + 'message.turnProcess.messages.one': '{count} mensagem', + 'message.turnProcess.messages.other': '{count} mensagens', + 'message.turnProcess.subagents.one': '{count} subagente', + 'message.turnProcess.subagents.other': '{count} subagentes', + 'message.turnProcess.thoughtForAWhile': 'Pensei por um tempo', + 'message.turnProcess.separator': ' · ', + 'message.stopped': 'Parado', + 'message.branch': 'Ramifique para uma nova conversa', + 'message.branchUnavailable': 'Disponível apenas na última mensagem de um turno concluído', + 'message.retry.active': 'Tentando novamente a solicitação de modelo', + 'message.retry.cancelled': 'Nova tentativa de solicitação de modelo cancelada', + 'message.retry.started': 'Solicitação de modelo repetida', + 'message.retry.scheduled': 'Aguardando para tentar novamente a solicitação de modelo', + 'message.retry.status': '{label} ({retry}/{maximum}) · {seconds}s', + 'message.retry.delay': 'Atraso na nova tentativa: ', + 'message.retry.failure': 'Motivo da falha: ', + 'message.failure.auth': 'A chave API é inválida', + 'message.taskStopped': 'Tarefa interrompida', + 'message.failure.accountSignedOut': 'Interrompido porque você saiu de DeepSeek.', + 'message.failure.interrupted': 'O processo DSH foi encerrado antes do término deste turno (por exemplo, ele foi eliminado, travou ou expirou durante o desligamento), portanto, o turno foi encerrado quando DSH foi reiniciado. Chamadas de ferramentas inacabadas têm resultados desconhecidos.', + 'message.failure.accountSignInRequired': 'Faça login em DeepSeek e verifique se o destino da solicitação suporta autenticação de conta.', + 'message.failure.quota': 'Cota de solicitação esgotada.', + 'message.turnError': 'Este turno falhou', + 'message.maxTokens': 'Limite de token de saída atingido', + 'message.maxTokens.hint': 'A resposta foi cortada; a saída anterior é preservada na conversa. Envie "continuar" para permitir que o modelo seja retomado.', + 'message.tokensPerSecond': '{tps} tok/s', + 'message.turnUsage.title': 'Uso do turno', + 'message.turnUsage.consumed': 'Uso {total}', + 'message.turnUsage.model': 'Provedor/modelo', + 'message.turnUsage.cacheHit': 'Acerto no cache', + 'message.turnUsage.input': 'Entrada sem cache', + 'message.turnUsage.cacheRead': 'Entrada em cache', + 'message.turnUsage.cacheWrite': 'Gravação em cache', + 'message.turnUsage.output': 'Saída', + 'message.turnUsage.reasoning': ' ({tokens} raciocínio)', + 'message.turnUsage.count': '{count} valor', + 'duration.secondUnit': 'é', + 'duration.minuteUnit': 'eu ', + 'duration.hourUnit': 'h ', + 'command.running': 'Correndo…', + 'command.failed': 'Falha no comando', + 'command.done': 'Concluído', + 'command.title': 'Comando', + 'row.running': 'Correndo', + 'row.failed': 'Falha', + 'json.truncated': '… truncado, {total} caracteres no total', + 'clock.md': '{m}/{d}', + 'clock.ymd': '{y}-{m}-{d}', +} satisfies Record diff --git a/packages/client/ui-commands/locale/de.json b/packages/client/ui-commands/locale/de.json new file mode 100644 index 0000000000..8fdc53edce --- /dev/null +++ b/packages/client/ui-commands/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Befehlsauswahlschnittstelle", + "description": "Bietet ein Slash-Befehlsmenü und eine zugehörige Bedienoberfläche im Eingabefeld." + } +} diff --git a/packages/client/ui-commands/locale/es.json b/packages/client/ui-commands/locale/es.json new file mode 100644 index 0000000000..9fb9b09c55 --- /dev/null +++ b/packages/client/ui-commands/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de selección de comandos", + "description": "Proporciona un menú de comando de barra diagonal y una interfaz de operación relacionada en el cuadro de entrada." + } +} diff --git a/packages/client/ui-commands/locale/fr.json b/packages/client/ui-commands/locale/fr.json new file mode 100644 index 0000000000..e0e61417a6 --- /dev/null +++ b/packages/client/ui-commands/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de sélection de commandes", + "description": "Fournit un menu de commande slash et une interface d’opération associée dans la zone de saisie." + } +} diff --git a/packages/client/ui-commands/locale/pt.json b/packages/client/ui-commands/locale/pt.json new file mode 100644 index 0000000000..01fc89d3a8 --- /dev/null +++ b/packages/client/ui-commands/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de seleção de comandos", + "description": "Fornece um menu de comando de barra e interface de operação relacionada na caixa de entrada." + } +} diff --git a/packages/client/ui-commands/locale/ru.json b/packages/client/ui-commands/locale/ru.json new file mode 100644 index 0000000000..529ec9773b --- /dev/null +++ b/packages/client/ui-commands/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Интерфейс выбора команд", + "description": "Предоставляет меню команд с косой чертой и соответствующий рабочий интерфейс в поле ввода." + } +} diff --git a/packages/client/ui-commands/src/client/index.ts b/packages/client/ui-commands/src/client/index.ts index fc098764a4..f1e8d62bf2 100644 --- a/packages/client/ui-commands/src/client/index.ts +++ b/packages/client/ui-commands/src/client/index.ts @@ -18,7 +18,7 @@ import type {} from '@deepseek-ai/dsh-client-ui-session/client' import { CommandUiRuntime } from './service.ts' import type { PopupSelectInjected } from './PopupSelectView.tsx' import { PopupSelectView } from './PopupSelectView.tsx' -import { en, ja, zh, type CommandKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh, type CommandKey } from './locales.ts' export { CommandUiRuntime } from './service.ts' export { CommandDirectory } from './directory.ts' @@ -56,7 +56,7 @@ export const inject = ['inputTriggers', 'sessions', 'remote', 'remote.commands', * @param ctx - client root context. */ export function apply(ctx: ClientContext): void { - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-commands: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-commands: dictionaries') ctx.plugin(CommandUiRuntime) ctx.inject(['slots', 'commandUi', 'sessions'], (scope: ClientContext) => { const command = scope.commandUi diff --git a/packages/client/ui-commands/src/client/locales.ts b/packages/client/ui-commands/src/client/locales.ts index de34e25cb7..c669964471 100644 --- a/packages/client/ui-commands/src/client/locales.ts +++ b/packages/client/ui-commands/src/client/locales.ts @@ -103,3 +103,163 @@ export const ja = { 'listbox.aria': '/{command} の一致項目', 'notice.attachmentsUnsupported': '/{command} は添付ファイルを受け付けません。先に削除してください', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'section.add': 'Añadir', + 'section.commands': 'Comandos', + 'label.goal': 'Objetivo', + 'label.plan': 'Planificar', + 'label.feedback': 'Comentarios', + 'label.compact': 'Compacto', + 'label.permission': 'Permiso', + 'label.export': 'Exportar', + 'description.goal': 'Establecer o ver el objetivo de una tarea de larga duración', + 'description.plan': 'Entrar o salir del modo plan', + 'description.feedback': 'Registrar comentarios sobre esta sesión', + 'description.compact': 'Historial de conversaciones antiguo compacto', + 'description.permission': 'Cambiar el ajuste preestablecido de permisos (modo sandbox + política de aprobación)', + 'description.export': 'Descargue este registro de sesión como un archivo ZIP', + 'token.goal': 'objetivo', + 'token.plan': 'planear', + 'token.feedback': 'retroalimentación', + 'token.compact': 'compacto', + 'token.permission': 'permiso', + 'token.export': 'exportar', + 'search.placeholder': 'Buscar…', + 'search.aria': 'Opciones de filtro', + 'status.loading': 'Cargando opciones…', + 'status.applying': 'Aplicando…', + 'status.empty': 'Sin opciones', + 'overlay.aria': 'Opciones de /{command}', + 'listbox.aria': '/{command} coincidencias', + 'notice.attachmentsUnsupported': '/{command} no acepta archivos adjuntos; eliminarlos primero', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'section.add': 'Ajouter', + 'section.commands': 'Commandes', + 'label.goal': 'Objectif', + 'label.plan': 'Planifier', + 'label.feedback': 'Commentaires', + 'label.compact': 'Compacte', + 'label.permission': 'Autorisation', + 'label.export': 'Exporter', + 'description.goal': "Définir ou afficher l'objectif d'une tâche de longue durée", + 'description.plan': 'Entrer ou quitter le mode Plan', + 'description.feedback': 'Enregistrer les commentaires sur cette session', + 'description.compact': 'Compacter l’historique des conversations anciennes', + 'description.permission': "Changer le préréglage d'autorisation (mode sandbox + politique d'approbation)", + 'description.export': "Téléchargez ce journal de session sous forme d'archive ZIP", + 'token.goal': 'objectif', + 'token.plan': 'planifier', + 'token.feedback': 'commentaires', + 'token.compact': 'compacte', + 'token.permission': 'autorisation', + 'token.export': 'exporter', + 'search.placeholder': 'Rechercher…', + 'search.aria': 'Options de filtrage', + 'status.loading': 'Options de chargement…', + 'status.applying': 'Candidature…', + 'status.empty': 'Aucune option', + 'overlay.aria': 'Options /{command}', + 'listbox.aria': '/{command} correspondances', + 'notice.attachmentsUnsupported': "/{command} n'accepte pas les pièces jointes ; retirez-les d'abord", +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'section.add': 'Hinzufügen', + 'section.commands': 'Befehle', + 'label.goal': 'Ziel', + 'label.plan': 'Planen', + 'label.feedback': 'Rückmeldung', + 'label.compact': 'Kompakt', + 'label.permission': 'Erlaubnis', + 'label.export': 'Exportieren', + 'description.goal': 'Legen Sie das Ziel für eine Aufgabe mit langer Laufzeit fest oder zeigen Sie es an', + 'description.plan': 'Aktivieren oder verlassen Sie den Planmodus', + 'description.feedback': 'Zeichnen Sie Feedback zu dieser Sitzung auf', + 'description.compact': 'Kompakter älterer Gesprächsverlauf', + 'description.permission': 'Ändern Sie die Berechtigungsvoreinstellung (Sandbox-Modus + Genehmigungsrichtlinie).', + 'description.export': 'Laden Sie dieses Sitzungsprotokoll als ZIP-Archiv herunter', + 'token.goal': 'Ziel', + 'token.plan': 'planen', + 'token.feedback': 'Rückmeldung', + 'token.compact': 'kompakt', + 'token.permission': 'Erlaubnis', + 'token.export': 'exportieren', + 'search.placeholder': 'Suchen…', + 'search.aria': 'Filteroptionen', + 'status.loading': 'Ladeoptionen…', + 'status.applying': 'Bewerben…', + 'status.empty': 'Keine Optionen', + 'overlay.aria': '/{command}-Optionen', + 'listbox.aria': '/{command} stimmt überein', + 'notice.attachmentsUnsupported': '/{command} akzeptiert keine Anhänge; Entfernen Sie sie zuerst', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'section.add': 'Добавить', + 'section.commands': 'Команды', + 'label.goal': 'Цель', + 'label.plan': 'План', + 'label.feedback': 'Обратная связь', + 'label.compact': 'Компактный', + 'label.permission': 'Разрешение', + 'label.export': 'Экспорт', + 'description.goal': 'Установите или просмотрите цель для долгосрочной задачи', + 'description.plan': 'Войти в режим плана или выйти из него', + 'description.feedback': 'Запишите отзыв об этом сеансе', + 'description.compact': 'Сжать старую историю разговоров', + 'description.permission': 'Переключение настроек разрешений (режим песочницы + политика утверждения)', + 'description.export': 'Загрузите этот журнал сеанса в виде ZIP-архива.', + 'token.goal': 'цель', + 'token.plan': 'план', + 'token.feedback': 'обратная связь', + 'token.compact': 'компактный', + 'token.permission': 'разрешение', + 'token.export': 'экспорт', + 'search.placeholder': 'Искать…', + 'search.aria': 'Параметры фильтра', + 'status.loading': 'Загрузка параметров…', + 'status.applying': 'Применение…', + 'status.empty': 'Нет вариантов', + 'overlay.aria': 'Опции /{command}', + 'listbox.aria': '/{command} совпадений', + 'notice.attachmentsUnsupported': '/{command} не принимает вложения; сначала удали их', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'section.add': 'Adicionar', + 'section.commands': 'Comandos', + 'label.goal': 'Objetivo', + 'label.plan': 'Plano', + 'label.feedback': 'Comentários', + 'label.compact': 'Compacto', + 'label.permission': 'Permissão', + 'label.export': 'Exportar', + 'description.goal': 'Defina ou visualize a meta para uma tarefa de longa duração', + 'description.plan': 'Entrar ou sair do modo de plano', + 'description.feedback': 'Registre feedback sobre esta sessão', + 'description.compact': 'Histórico compacto de conversas antigas', + 'description.permission': 'Alterar a predefinição de permissão (modo sandbox + política de aprovação)', + 'description.export': 'Baixe este log de sessão como um arquivo ZIP', + 'token.goal': 'objetivo', + 'token.plan': 'planejar', + 'token.feedback': 'comentários', + 'token.compact': 'compacto', + 'token.permission': 'permissão', + 'token.export': 'exportar', + 'search.placeholder': 'Pesquisar…', + 'search.aria': 'Opções de filtro', + 'status.loading': 'Carregando opções…', + 'status.applying': 'Aplicando…', + 'status.empty': 'Sem opções', + 'overlay.aria': '/{command} opções', + 'listbox.aria': '/{command} correspondências', + 'notice.attachmentsUnsupported': '/{command} não aceita anexos; remova-os primeiro', +} satisfies Record diff --git a/packages/client/ui-conversation/locale/de.json b/packages/client/ui-conversation/locale/de.json new file mode 100644 index 0000000000..def54f49a5 --- /dev/null +++ b/packages/client/ui-conversation/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Konversationsschnittstellen-Framework", + "description": "Organisieren Sie Dialoginhalte, Eingabefelder, Nachrichtenwarteschlangen und zeigen Sie die Navigation an." + } +} diff --git a/packages/client/ui-conversation/locale/es.json b/packages/client/ui-conversation/locale/es.json new file mode 100644 index 0000000000..89664f8f6a --- /dev/null +++ b/packages/client/ui-conversation/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "marco de interfaz conversacional", + "description": "Organice el contenido del diálogo, los cuadros de entrada, las colas de mensajes y vea la navegación." + } +} diff --git a/packages/client/ui-conversation/locale/fr.json b/packages/client/ui-conversation/locale/fr.json new file mode 100644 index 0000000000..a24689adf7 --- /dev/null +++ b/packages/client/ui-conversation/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "cadre d'interface conversationnelle", + "description": "Organisez le contenu des boîtes de dialogue, les zones de saisie, les files d'attente de messages et la navigation dans les vues." + } +} diff --git a/packages/client/ui-conversation/locale/pt.json b/packages/client/ui-conversation/locale/pt.json new file mode 100644 index 0000000000..25642a6dc7 --- /dev/null +++ b/packages/client/ui-conversation/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "estrutura de interface conversacional", + "description": "Organize o conteúdo da caixa de diálogo, caixas de entrada, filas de mensagens e visualize a navegação." + } +} diff --git a/packages/client/ui-conversation/locale/ru.json b/packages/client/ui-conversation/locale/ru.json new file mode 100644 index 0000000000..5e527b7f33 --- /dev/null +++ b/packages/client/ui-conversation/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "структура диалогового интерфейса", + "description": "Упорядочивайте содержимое диалогов, поля ввода, очереди сообщений и навигацию по просмотрам." + } +} diff --git a/packages/client/ui-conversation/src/client/apply.ts b/packages/client/ui-conversation/src/client/apply.ts index 6a004c8740..52fe6be6b4 100644 --- a/packages/client/ui-conversation/src/client/apply.ts +++ b/packages/client/ui-conversation/src/client/apply.ts @@ -46,7 +46,7 @@ import { todoDockEntry } from './skeleton/TodoPanel.tsx' import { installStopShortcut } from './stop-shortcut.ts' import { TRAJECTORY_VIEW_ID, resolveActiveView } from './view-selection.ts' import { createViewPins } from './view-pins.ts' -import { en, ja, NS, zh, type ConversationKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, NS, zh, type ConversationKey } from './locales.ts' import { CONVERSATION_SETTINGS_NAMESPACE, type ConversationSettings } from '../submission-settings.ts' declare module '@deepseek-ai/dsh-client-ui-slots' { @@ -185,7 +185,7 @@ export function apply(ctx: Context, config: Config = Config({})): void { yield slots.register({ name: 'conversation.user.text.node', key: 'session', priority: 100 }, SessionReference) }) - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-conversation: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-conversation: dictionaries') const t = ctx.locale.bind(NS) const conversationStore = createConversationStore() const submissionPolicy = new ComposerSubmissionPolicy( diff --git a/packages/client/ui-conversation/src/client/locales.ts b/packages/client/ui-conversation/src/client/locales.ts index cde0c51e72..85c593a675 100644 --- a/packages/client/ui-conversation/src/client/locales.ts +++ b/packages/client/ui-conversation/src/client/locales.ts @@ -1148,3 +1148,1908 @@ export const ja = { 'terminal.sendInput': '(入力を送信)', 'terminal.session': 'ターミナル {sessionId}', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'quote.remove': 'Eliminar cotización', + 'shortcut.newline': 'Nueva linea', + 'shortcut.complementary': 'Utilice la acción complementaria Cola/Dirigir', + 'shortcut.slash': 'Abrir menú de comandos', + 'shortcut.mention': 'Abrir menú de referencia', + 'hint.plan': PLAN_NEXT_ACTION_EN, + 'hint.goal': 'describir el objetivo de una tarea de larga duración', + 'hint.goal.active': 'Objetivo activo: editar/pausar/reanudar/borrar', + 'placeholder.plan': PLAN_NEXT_ACTION_EN, + 'placeholder.default': 'Envía mensajes o ejecuta una tarea, / comandos, @ archivos o sesiones', + 'placeholder.unavailable': 'Sesión no disponible', + 'placeholder.parentOffline': 'Sesión para padres sin conexión; El envío no está disponible pero aún puedes detener la ejecución.', + 'placeholder.hero': 'Describe lo que quieres construir, / comandos, @ archivos o sesiones', + 'placeholder.workspace': 'Elija un espacio de trabajo para comenzar', + 'placeholder.steerQueue': 'Cmd/Ctrl+Enter dirige todos los mensajes en cola', + 'input.commands': 'Agregar archivos o ejecutar comandos', + 'input.file': 'Archivo', + 'input.stop': 'dejar de generar', + 'input.send': 'enviar mensaje', + 'input.send.queue': 'mensaje de cola', + 'input.send.steer': 'Mensaje de dirección', + 'attachment.pending': 'Anexos pendientes', + 'attachment.scrollLeft': 'Desplazar archivos adjuntos hacia la izquierda', + 'attachment.scrollRight': 'Desplazar archivos adjuntos hacia la derecha', + 'attachment.dropTitle': 'Arrastre archivos o imágenes aquí para agregarlos', + 'attachment.dropDesc': 'Límite de imágenes: hasta imágenes {count}, {size} cada una', + 'attachment.dropBlocked': 'No se pueden agregar archivos e imágenes en este momento', + 'attachment.directoryDesktopOnly': 'Las carpetas sólo se pueden agregar en la aplicación de escritorio; agregar archivos individuales en el navegador', + 'attachment.pathUnavailable': 'No se pudo obtener la ruta de la carpeta; arrástralo de nuevo', + 'attachment.pathUnsupported': 'La ruta contiene caracteres que una referencia no puede contener; cámbiale el nombre y vuelve a intentarlo.', + 'image.pending': 'Imágenes pendientes', + 'image.openOriginal': 'Ver original', + 'image.openOriginalLabel': '{label}, haga clic para ver el original', + 'image.remove': 'Eliminar imagen {name}', + 'image.original': 'imagen original', + 'image.label': 'Imagen', + 'image.loadFailed': 'La imagen no se pudo cargar; haga clic para volver a intentar', + 'image.loading': 'Cargando imagen…', + 'image.preview': 'Vista previa de la imagen original', + 'image.closePreview': 'Cerrar vista previa de la imagen original', + 'image.unsupportedType': 'Solo se admiten imágenes PNG, JPG, WebP y GIF', + 'image.tooMany': 'Un mensaje puede incluir hasta imágenes {count}.', + 'image.fileTooLarge': 'Cada imagen debe ser más pequeña que {size}.', + 'image.totalTooLarge': 'Las imágenes superan {size} en total; elimina algunos y vuelve a intentarlo', + 'image.tooManyPixels': 'La resolución de la imagen es demasiado alta; comprímelo y vuelve a intentarlo.', + 'image.dimensionTooLarge': 'Los lados de la imagen deben ser como máximo {size}px; reduce la escala y vuelve a intentarlo', + 'image.modelUnsupported': 'El modelo actual no admite imágenes; cambiar a un modelo que lo haga', + 'image.sendFailed': 'Error al enviar imágenes ({reason}); Vuelve a agregarlos y vuelve a intentarlo.', + 'file.pending': 'Archivos pendientes', + 'file.remove': 'Eliminar archivo {name}', + 'file.uploading': 'Subiendo…', + 'file.uploadFailed': 'La carga falló; haga clic para volver a intentar', + 'file.retry': 'Reintente cargar {name}', + 'file.stillUploading': 'Los archivos todavía se están cargando; enviar después de que terminen', + 'file.sessionUnavailable': 'Sesión no disponible; los archivos no se pueden cargar', + 'file.notStaged': 'El archivo no ha terminado de cargarse; vuelve a agregarlo y vuelve a intentarlo', + 'file.label': 'Archivo', + 'context.aria': '{percent} de contexto utilizado', + 'context.used': 'de contexto utilizado', + 'context.system': 'Aviso del sistema', + 'context.tools': 'Definiciones de herramientas', + 'context.messages': 'Mensajes', + 'settings.enter.title': 'Enviar comportamiento mientras está ocupado', + 'settings.enter.description': 'Qué hacen los botones Intro y Enviar mientras el agente se está ejecutando; Cmd/Ctrl+Enter usa el otro comportamiento', + 'settings.enter.queue': 'cola', + 'settings.enter.steer': 'dirigir', + 'hero.headline': 'Hacia lo desconocido', + 'hero.preview': 'Vista previa', + 'hero.chooseWorkspace': 'Elige espacio de trabajo', + 'session.hierarchy': 'Jerarquía de sesiones', + 'session.moreViews': 'Más vistas de conversación', + 'todo.title': 'Tareas pendientes', + 'todo.progress.done': '{done} completado', + 'todo.progress.active': '{active} en progreso', + 'todo.progress.pending': '{pending} pendiente', + 'todo.status.completed': 'Completado', + 'todo.status.inProgress': 'En progreso', + 'todo.status.pending': 'Pendiente', + 'todo.rowTitle': 'Actualizar lista de tareas pendientes', + 'tool.title.createGoal': 'Crear objetivo', + 'tool.title.getGoal': 'Ver objetivo', + 'tool.title.updateGoal': 'Actualizar objetivo', + 'tool.preparing.content': '{kilobytes}KB', + 'tool.title.createSchedule': 'Crear recordatorio', + 'tool.title.listSchedules': 'Recordatorios de lista', + 'tool.title.deleteSchedule': 'Eliminar recordatorio', + 'tool.title.updateSchedule': 'Recordatorio de actualización', + 'detail.state': 'Estado', + 'detail.todo.completed': 'Completado', + 'detail.todo.in_progress': 'En progreso', + 'detail.todo.pending': 'Pendiente', + 'detail.todo.empty': 'La lista de tareas pendientes está vacía', + 'todo.diff.initial': 'lista inicial', + 'todo.diff.compare': 'Cambios desde la lista anterior', + 'todo.diff.unavailable': 'Lista anterior no disponible', + 'todo.diff.noChanges': 'No hay cambios en la lista.', + 'todo.diff.added': '{count} añadido', + 'todo.diff.updated': '{count} actualizado', + 'todo.diff.removed': '{count} eliminado', + 'todo.diff.unchanged': '{count} sin cambios', + 'todo.diff.addedItem': 'Añadido', + 'todo.diff.updatedItem': 'Estado cambiado', + 'todo.diff.movedItem': 'Reordenado', + 'todo.diff.removedItem': 'Eliminado', + 'detail.goal.empty': 'Sin gol', + 'detail.goal.active': 'Activo', + 'detail.goal.disarmed': 'En espera de continuación', + 'detail.goal.paused': 'En pausa', + 'detail.goal.blocked': 'Bloqueado', + 'detail.goal.complete': 'Completado', + 'detail.goal.rounds': 'Rondas', + 'detail.goal.reason': 'bloqueador', + 'detail.days': '{count} d', + 'detail.hours': '{count} h', + 'detail.minutes': '{count} mín.', + 'detail.seconds': '{count}', + 'detail.schedule.once': 'una vez', + 'detail.schedule.every': 'Cada {interval}', + 'detail.schedule.when': 'Programado para', + 'detail.schedule.frequency': 'repetir', + 'detail.schedule.scheduled': 'Programado', + 'detail.schedule.overdue': 'Atrasado, a la espera de reanudar la sesión.', + 'detail.schedule.empty': 'Sin recordatorios', + 'detail.schedule.deleted': 'Eliminado', + 'detail.schedule.count': 'Recordatorios de {count}', + 'detail.schedule.daily': 'Todos los días en {time} ({zone})', + 'detail.schedule.weekly': 'Semanalmente en {days} en {time} ({zone})', + 'detail.schedule.cron': 'Cron {expression} ({zone})', + 'detail.weekday.1': 'lun', + 'detail.weekday.2': 'mar', + 'detail.weekday.3': 'mié', + 'detail.weekday.4': 'jueves', + 'detail.weekday.5': 'viernes', + 'detail.weekday.6': 'sábado', + 'detail.weekday.7': 'sol', + 'detail.weekday.join': ', ', + 'tool.title.inspectProviders': 'Inspeccionar proveedores', + 'tool.title.queryRuntime': 'Tiempo de ejecución de consultas', + 'tool.title.inspectPlugins': 'Inspeccionar complementos', + 'tool.title.workflow': 'Ejecutar flujo de trabajo', + 'tool.title.ralph': 'Ejecutar bucle ralph', + 'tool.title.readEvent': 'Leer evento', + 'tool.title.searchEvents': 'Buscar eventos', + 'tool.title.traceEvent': 'Evento de seguimiento', + 'tool.title.searchSessions': 'Sesiones de búsqueda', + 'tool.title.traceSession': 'Sesión de seguimiento', + 'tool.title.listModels': 'Listar modelos', + 'tool.title.subagent': 'Crear subagente', + 'tool.title.listAgents': 'Listar subagentes', + 'tool.title.sendMessage': 'enviar mensaje', + 'tool.title.interruptAgent': 'agente de interrupción', + 'tool.title.listJobs': 'Listar trabajos en segundo plano', + 'tool.title.readJob': 'Leer la salida del trabajo', + 'tool.title.killJob': 'Cancelar trabajo en segundo plano', + 'tool.title.openTerminal': 'terminal abierta', + 'tool.title.readTerminal': 'Leer terminal', + 'tool.title.listTerminals': 'Lista de terminales', + 'tool.title.signalTerminal': 'terminal de señal', + 'tool.title.closeTerminal': 'Cerrar terminal', + 'tool.title.lsp': 'Símbolos de código de consulta', + 'tool.title.findDefinition': 'encontrar definición', + 'tool.title.findReferences': 'encontrar referencias', + 'tool.title.findImplementation': 'Encontrar implementación', + 'tool.title.hoverSymbol': 'Símbolo de inspección', + 'tool.title.spawnTeammate': 'Crear compañero de equipo', + 'tool.title.createTeamTask': 'Crear tarea de equipo', + 'tool.title.getTeamTask': 'Leer tarea de equipo', + 'tool.title.updateTeamTask': 'Actualizar tarea de equipo', + 'tool.title.listTeamTasks': 'Listar tareas del equipo', + 'tool.title.waitAgent': 'Espere al subagente', + 'detail.recordedResult': 'Resultado registrado', + 'detail.empty': 'Sin resultados', + 'detail.none': 'Ninguno', + 'detail.yes': 'si', + 'detail.no': 'No', + 'detail.moreInInspect': '{count} más artículos disponibles en Inspeccionar', + 'detail.status.running': 'corriendo', + 'detail.status.idle': 'inactivo', + 'detail.status.ready': 'Listo', + 'detail.status.inactive': 'Inactivo', + 'detail.status.provisioning': 'Aprovisionamiento', + 'detail.status.failed': 'Fallido', + 'detail.status.completed': 'Completado', + 'detail.status.deleted': 'Eliminado', + 'detail.status.killed': 'Cancelado', + 'detail.status.accepted': 'Aceptado', + 'detail.status.queued': 'En cola', + 'detail.status.exited': 'Salido', + 'detail.field.id': 'ID', + 'detail.field.revision': 'Revisión', + 'detail.field.platform': 'Plataforma', + 'detail.field.provider': 'Proveedor', + 'detail.field.model': 'modelo', + 'detail.field.role': 'Rol', + 'detail.field.context': 'Contexto', + 'detail.field.owner': 'propietario', + 'detail.field.ready': 'Listo', + 'detail.field.dependencies': 'Dependencias', + 'detail.field.writeScopes': 'Escribir alcances', + 'detail.field.warnings': 'Advertencias', + 'detail.field.diagnostics': 'Diagnóstico', + 'detail.field.methods': 'Métodos', + 'detail.field.inputSchema': 'Esquema de entrada', + 'detail.field.outputSchema': 'Esquema de salida', + 'detail.field.currentPackage': 'Paquete actual', + 'detail.field.nextPackage': 'Siguiente paquete', + 'detail.field.latestRun': 'Última ejecución', + 'detail.field.packages': 'Paquetes', + 'detail.field.registrations': 'Inscripciones', + 'detail.field.props': 'Accesorios', + 'detail.field.data': 'Datos', + 'detail.field.source': 'Fuente', + 'detail.field.content': 'Contenido', + 'detail.field.message': 'Mensaje', + 'detail.field.messageId': 'ID de mensaje', + 'detail.field.root': 'raíz', + 'detail.field.pid': 'ID de proceso', + 'detail.field.type': 'Tipo', + 'detail.field.time': 'tiempo', + 'detail.field.seq': 'Secuencia de eventos', + 'detail.field.turn': 'Turno', + 'detail.field.step': 'paso', + 'detail.field.callId': 'ID de llamada', + 'detail.field.agents': 'Los agentes comenzaron', + 'detail.field.result': 'Resultado', + 'detail.field.parent': 'Padre', + 'detail.field.depth': 'Profundidad', + 'detail.field.exitCode': 'código de salida', + 'detail.field.signal': 'señal', + 'detail.field.previousStatus': 'Estado anterior', + 'detail.field.agent': 'ID del agente', + 'detail.field.job': 'ID de trabajo', + 'detail.field.task': 'Tarea', + 'detail.field.processGroup': 'grupo de procesos', + 'detail.field.availability': 'Disponibilidad', + 'detail.field.bestMatch': 'mejor partido', + 'detail.field.target': 'Evento objetivo', + 'detail.field.surface': 'Estado de registro', + 'detail.agents.count': 'Agentes {count}', + 'detail.jobs.count': 'Trabajos en segundo plano {count}', + 'detail.terminals.count': 'Terminales {count}', + 'detail.tasks.count': 'Tareas del equipo {count}', + 'detail.tasks.nextPage': 'Más tareas disponibles; el siguiente cursor es {cursor}', + 'detail.locations.count': 'Ubicaciones de {count}', + 'detail.location': 'Línea {line}, columna {column}', + 'detail.receipt.delivered': 'Mensaje entregado', + 'detail.receipt.interrupt': 'Interrupción solicitada', + 'detail.receipt.started': 'iniciado', + 'detail.receipt.cancel': 'Cancelación solicitada', + 'detail.receipt.alreadyFinished': 'ya terminé', + 'detail.receipt.signal': 'Señal entregada', + 'detail.receipt.closed': 'Cerrado', + 'detail.receipt.closing': 'Cierre', + 'detail.wait.noProgress': 'No hay subagentes activos', + 'detail.wait.title': 'Actividad del subagente', + 'detail.wait.timeout': 'Se agotó el tiempo de espera', + 'detail.wait.changed': 'Cambio detectado', + 'detail.agent.reply': 'Respuesta del agente', + 'detail.models.title': 'Modelos disponibles', + 'detail.output.lines': 'Líneas {begin}–{end} de {total}', + 'detail.output.truncated': 'Salida truncada', + 'detail.providers.count': '{count} inspeccionar proveedores', + 'detail.plugins.count': 'Complementos dinámicos {count}', + 'detail.workflow.script': 'Guión de flujo de trabajo', + 'detail.ralph.reportedComplete': 'finalización reportada por el trabajador', + 'detail.ralph.reportedBlocker': 'Trabajador reportó un bloqueador', + 'detail.ralph.limit': 'Límite de ronda alcanzado', + 'detail.report.nextSteps': 'Trabajo restante', + 'detail.trace.replacedBy': 'Reemplazado por', + 'detail.trace.replacementChain': 'Cadena de repuesto', + 'detail.trace.replaces': 'Eventos reemplazados', + 'detail.trace.sources': 'Eventos de origen', + 'detail.trace.derived': 'Eventos derivados', + 'detail.trace.ancestors': 'Sesiones de antepasados', + 'detail.trace.descendants': 'Sesiones de descendientes', + 'detail.matches.count': 'Partidos {count}', + 'detail.matches.capped': 'Límite de resultados alcanzado; acotar la búsqueda para más', + 'detail.event.neighbors': 'Eventos circundantes', + 'todo.completed': '{done}/{total} completado', + 'command.attachmentsUnsupported': '/{command} no acepta archivos adjuntos; eliminarlos primero', + 'ask.rowTitle': 'hacer pregunta', + 'ask.waiting': 'esperando', + 'ask.pending': 'continuó; respuesta aún disponible', + 'ask.pendingDetail': 'Estas cuestiones pendientes siguen siendo responsabilidad del compositor.', + 'ask.reopen': 'respuesta', + 'ask.review': 'Ver respuestas', + 'ask.closed': 'cerrado', + 'ask.closedDetail': 'Esta pregunta está cerrada; su resultado está en la conversación a continuación.', + 'ask.cancelled': 'cancelado', + 'ask.cancelledDetail': 'Este conjunto de preguntas se canceló antes de enviar las respuestas.', + 'ask.interrupted': 'interrumpido', + 'ask.interruptedDetail': 'Este conjunto de preguntas se interrumpió antes de que se enviaran las respuestas.', + 'ask.answered': '{answered}/{total} respondió', + 'ask.skipped': 'No respondido', + 'bash.running': 'corriendo', + 'bash.failed': 'Fallido', + 'bash.stopped': 'Detenido', + 'row.running': 'corriendo', + 'row.preparing': 'Preparando la llamada a la herramienta', + 'row.failed': 'Fallido', + 'row.stopped': 'Detenido', + 'row.commandArguments': 'Argumentos de comando', + 'row.input': 'IN', + 'row.output': 'OUT', + 'row.inspect': 'inspeccionar', + 'row.imageSize': '{width}x{height}px, {bytes} bytes', + 'row.imageSizeDownscaled': '{width}x{height}px (reducido de {originalWidth}x{originalHeight}px), {bytes} bytes', + 'tool.title.search': 'Buscar', + 'tool.title.read': 'leer', + 'tool.title.bash': 'golpe', + 'tool.title.write': 'escribir', + 'tool.title.edit': 'Editar', + 'tool.title.code': 'Código', + 'tool.title.generic': 'llamada de herramienta', + 'tool.title.inspect': 'Consulta entorno Cordis', + 'tool.title.runCordis': 'Ejecute el complemento Cordis', + 'tool.title.stopCordis': 'Detener el complemento Cordis', + 'tool.title.removeCordis': 'Eliminar el complemento Cordis', + 'tool.title.pwsh': 'Pwsh', + 'tool.title.readImage': 'Leer imagen', + 'tool.title.grep': 'grep', + 'tool.title.glob': 'globo', + 'tool.title.webSearch': 'Buscar', + 'tool.title.webFetch': 'buscar', + 'tool.autoReviewRejected': 'Rechazado por Auto review', + 'tool.autoReviewNotExecuted': 'La herramienta no fue ejecutada. Razón: {reason}', + 'tool.autoReviewReasonFallback': 'Auto review no autorizó esta acción', + 'diff.collapseAria': 'Contraer diferencia', + 'diff.expandAria': 'Expanda {count} más líneas diferenciales', + 'diff.expandRest': '… {count} más líneas', + 'read.window': 'Mostrando {shown} de líneas {total}', + 'read.collapseAria': 'Contraer contenido', + 'read.expandAria': 'Ampliar {count} más líneas', + 'read.expandRest': '… {count} más líneas', + 'search.paths': 'Rutas {shown}', + 'search.paths.truncated': 'Mostrando {shown} de las rutas {total}', + 'search.matches': 'Coincidencias {shown} · Archivos {files}', + 'search.matches.truncated': 'Mostrando {shown} de coincidencias {total} · Archivos {files}', + 'search.noResults': 'Sin resultados', + 'search.collapseAria': 'Contraer resultados', + 'search.expandAria': 'Expandir {count} más líneas de resultados', + 'search.expandRest': '… {count} más líneas', + 'web.noResults': 'No se encontraron resultados', + 'web.sourcesTruncated': 'Lista de fuentes truncada', + 'web.http': 'HTTP', + 'web.contentTruncated': 'Contenido truncado', + 'details.running': 'Corriendo…', + 'queue.count': 'Mensajes en cola {n}', + 'queue.sending': 'Enviando…', + 'queue.image': 'Imagen de mensaje en cola', + 'queue.file': 'Archivo en cola {name}', + 'queue.edit': 'Editar mensaje en cola', + 'queue.edit.unsupported': 'Contiene contenido que no es texto; la edición aún no es compatible', + 'queue.save': 'Guardar mensaje en cola', + 'queue.cancelEdit': 'Cancelar edición', + 'queue.remove': 'Eliminar mensaje en cola', + 'queue.steer': 'Mensaje de dirección en cola', + 'queue.steer.unavailable': 'La dirección solo está disponible mientras el agente está en ejecución', + 'error.sessionInUse': 'Esta sesión ya está en uso, posiblemente por otra instancia de DSH en ejecución (como la web dsh o la aplicación de escritorio). Salga de otras instancias de DSH en ejecución y vuelva a intentarlo.', + 'queue.editFailed': 'Error de edición: es posible que este mensaje ya haya comenzado a enviarse.', + 'queue.removeFailed': 'Error al eliminar: es posible que este mensaje ya haya comenzado a enviarse.', + 'queue.steerFailed': 'La dirección falló. Intentar otra vez.', + 'terminal.signal': 'señal {signal}', + 'terminal.exitCode': 'código de salida {code}', + 'terminal.noExitCode': 'sin código de salida', + 'terminal.commandLine': 'Línea de comando {n}', + 'terminal.running': 'corriendo', + 'terminal.failed': 'Fallido', + 'terminal.done': 'hecho', + 'terminal.noOutput': 'Sin salida', + 'terminal.collapseAria': 'Contraer salida', + 'terminal.expandAria': 'Expanda las líneas de salida {n} restantes', + 'terminal.expandRest': '… {n} más líneas', + // The Host terminal_send presenter has no locale seat; keep its fallbacks + // aligned with these English values. + 'terminal.sendInput': '(enviar entrada)', + 'terminal.session': 'Terminal {sessionId}', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'quote.remove': 'Supprimer le devis', + 'shortcut.newline': 'Nouvelle ligne', + 'shortcut.complementary': "Utiliser l'action complémentaire File d'attente / Diriger", + 'shortcut.slash': 'Ouvrir le menu des commandes', + 'shortcut.mention': 'Ouvrir le menu de référence', + 'hint.plan': PLAN_NEXT_ACTION_EN, + 'hint.goal': "décrire l'objectif d'une tâche de longue durée", + 'hint.goal.active': 'objectif actif — modifier/mettre en pause/reprendre/effacer', + 'placeholder.plan': PLAN_NEXT_ACTION_EN, + 'placeholder.default': 'Envoyez un message ou exécutez une tâche, des commandes /, des fichiers @ ou des sessions', + 'placeholder.unavailable': 'Séance indisponible', + 'placeholder.parentOffline': "Session parent hors ligne ; l'envoi n'est pas disponible mais vous pouvez toujours arrêter l'exécution", + 'placeholder.hero': 'Décrivez ce que vous souhaitez construire, / commandes, @ fichiers ou sessions', + 'placeholder.workspace': 'Choisissez un espace de travail pour commencer', + 'placeholder.steerQueue': "Cmd/Ctrl+Entrée dirige tous les messages en file d'attente", + 'input.commands': 'Ajouter des fichiers ou exécuter des commandes', + 'input.file': 'Fichier', + 'input.stop': 'Arrêter de générer', + 'input.send': 'Envoyer un message', + 'input.send.queue': "Message de file d'attente", + 'input.send.steer': 'Message de direction', + 'attachment.pending': 'Pièces jointes en attente', + 'attachment.scrollLeft': 'Faire défiler les pièces jointes vers la gauche', + 'attachment.scrollRight': 'Faire défiler les pièces jointes vers la droite', + 'attachment.dropTitle': 'Faites glisser des fichiers ou des images ici pour les ajouter', + 'attachment.dropDesc': "Limite d'images : jusqu'à des images {count}, {size} chacune", + 'attachment.dropBlocked': 'Les fichiers et les images ne peuvent pas être ajoutés pour le moment', + 'attachment.directoryDesktopOnly': "Les dossiers ne peuvent être ajoutés que dans l'application de bureau ; ajouter des fichiers individuels dans le navigateur", + 'attachment.pathUnavailable': "Impossible d'obtenir le chemin du dossier ; fais-le glisser à nouveau", + 'attachment.pathUnsupported': "Le chemin contient des caractères qu'une référence ne peut pas transporter ; renommez-le et réessayez", + 'image.pending': 'Images en attente', + 'image.openOriginal': "Voir l'original", + 'image.openOriginalLabel': "{label}, cliquez pour voir l'original", + 'image.remove': "Supprimer l'image {name}", + 'image.original': 'Image originale', + 'image.label': 'Images', + 'image.loadFailed': "L'image n'a pas pu être chargée ; cliquez pour réessayer", + 'image.loading': "Chargement de l'image…", + 'image.preview': "Aperçu de l'image originale", + 'image.closePreview': "Fermer l'aperçu de l'image d'origine", + 'image.unsupportedType': 'Seules les images PNG, JPG, WebP et GIF sont prises en charge', + 'image.tooMany': "Un message peut inclure jusqu'à des images {count}", + 'image.fileTooLarge': 'Chaque image doit être plus petite que {size}', + 'image.totalTooLarge': 'Les images dépassent {size} au total ; enlève-en un peu et réessaye', + 'image.tooManyPixels': "La résolution de l'image est trop élevée ; compressez-le et réessayez", + 'image.dimensionTooLarge': "Les côtés de l'image doivent être au maximum {size}px ; réduisez-le et réessayez", + 'image.modelUnsupported': 'Le modèle actuel ne prend pas en charge les images ; passer à un modèle qui le fait', + 'image.sendFailed': "L'envoi des images a échoué ({reason}) ; rajoutez-les et réessayez", + 'file.pending': 'Fichiers en attente', + 'file.remove': 'Supprimer le fichier {name}', + 'file.uploading': 'Téléchargement…', + 'file.uploadFailed': 'Échec du téléchargement ; cliquez pour réessayer', + 'file.retry': 'Réessayez de télécharger {name}', + 'file.stillUploading': 'Les fichiers sont toujours en cours de téléchargement ; envoyer après avoir fini', + 'file.sessionUnavailable': 'Séance indisponible ; les fichiers ne peuvent pas être téléchargés', + 'file.notStaged': "Le téléchargement du fichier n'est pas terminé ; rajoutez-le et réessayez", + 'file.label': 'Fichier', + 'context.aria': '{percent} de contexte utilisé', + 'context.used': 'du contexte utilisé', + 'context.system': 'Invite système', + 'context.tools': "Définitions d'outils", + 'context.messages': 'Messages', + 'settings.enter.title': "Comportement d'envoi lorsque vous êtes occupé", + 'settings.enter.description': "Ce que font Entrée et le bouton Envoyer pendant l'exécution de l'agent ; Cmd/Ctrl+Entrée utilise l'autre comportement", + 'settings.enter.queue': "File d'attente", + 'settings.enter.steer': 'Diriger', + 'hero.headline': "Dans l'inconnu", + 'hero.preview': 'Aperçu', + 'hero.chooseWorkspace': 'Choisir un espace de travail', + 'session.hierarchy': 'Hiérarchie des sessions', + 'session.moreViews': 'Plus de vues de conversations', + 'todo.title': 'À faire', + 'todo.progress.done': '{done} terminé', + 'todo.progress.active': '{active} en cours', + 'todo.progress.pending': '{pending} en attente', + 'todo.status.completed': 'Terminé', + 'todo.status.inProgress': 'En cours', + 'todo.status.pending': 'En attente', + 'todo.rowTitle': 'Mettre à jour la liste de tâches', + 'tool.title.createGoal': 'Créer un objectif', + 'tool.title.getGoal': "Afficher l'objectif", + 'tool.title.updateGoal': 'Objectif de mise à jour', + 'tool.preparing.content': '{kilobytes}KB', + 'tool.title.createSchedule': 'Créer un rappel', + 'tool.title.listSchedules': 'Liste des rappels', + 'tool.title.deleteSchedule': 'Supprimer le rappel', + 'tool.title.updateSchedule': 'Rappel de mise à jour', + 'detail.state': 'Statut', + 'detail.todo.completed': 'Terminé', + 'detail.todo.in_progress': 'En cours', + 'detail.todo.pending': 'En attente', + 'detail.todo.empty': 'La liste de tâches est vide', + 'todo.diff.initial': 'Liste initiale', + 'todo.diff.compare': 'Changements depuis la liste précédente', + 'todo.diff.unavailable': 'Liste précédente indisponible', + 'todo.diff.noChanges': 'Aucun changement dans la liste', + 'todo.diff.added': '{count} ajouté', + 'todo.diff.updated': '{count} mis à jour', + 'todo.diff.removed': '{count} supprimé', + 'todo.diff.unchanged': '{count} inchangé', + 'todo.diff.addedItem': 'Ajouté', + 'todo.diff.updatedItem': 'Statut modifié', + 'todo.diff.movedItem': 'Réorganisé', + 'todo.diff.removedItem': 'Supprimé', + 'detail.goal.empty': 'Aucun but', + 'detail.goal.active': 'Actif', + 'detail.goal.disarmed': 'En attente de suite', + 'detail.goal.paused': 'En pause', + 'detail.goal.blocked': 'Bloqué', + 'detail.goal.complete': 'Terminé', + 'detail.goal.rounds': 'Tours', + 'detail.goal.reason': 'Bloqueur', + 'detail.days': '{count}d', + 'detail.hours': '{count} h', + 'detail.minutes': '{count} min.', + 'detail.seconds': '{count}s', + 'detail.schedule.once': 'Une fois', + 'detail.schedule.every': 'Chaque {interval}', + 'detail.schedule.when': 'Prévu pour', + 'detail.schedule.frequency': 'Répéter', + 'detail.schedule.scheduled': 'Programmé', + 'detail.schedule.overdue': 'En retard, en attente de reprise de la session', + 'detail.schedule.empty': 'Aucun rappel', + 'detail.schedule.deleted': 'Supprimé', + 'detail.schedule.count': 'Rappels {count}', + 'detail.schedule.daily': 'Tous les jours à {time} ({zone})', + 'detail.schedule.weekly': 'Hebdomadaire sur {days} à {time} ({zone})', + 'detail.schedule.cron': 'Cron {expression} ({zone})', + 'detail.weekday.1': 'lundi', + 'detail.weekday.2': 'mar.', + 'detail.weekday.3': 'mer', + 'detail.weekday.4': 'jeu.', + 'detail.weekday.5': 'vendredi', + 'detail.weekday.6': 'Samedi', + 'detail.weekday.7': 'Soleil', + 'detail.weekday.join': ', ', + 'tool.title.inspectProviders': 'Inspecter les fournisseurs', + 'tool.title.queryRuntime': 'Exécution de la requête', + 'tool.title.inspectPlugins': 'Inspecter les plugins', + 'tool.title.workflow': 'Exécuter le flux de travail', + 'tool.title.ralph': 'Exécuter la boucle Ralph', + 'tool.title.readEvent': "Lire l'événement", + 'tool.title.searchEvents': 'Rechercher des événements', + 'tool.title.traceEvent': 'Événement de trace', + 'tool.title.searchSessions': 'Sessions de recherche', + 'tool.title.traceSession': 'Session de traçage', + 'tool.title.listModels': 'Liste des modèles', + 'tool.title.subagent': 'Créer un sous-agent', + 'tool.title.listAgents': 'Liste des sous-agents', + 'tool.title.sendMessage': 'Envoyer un message', + 'tool.title.interruptAgent': "Agent d'interruption", + 'tool.title.listJobs': 'Répertorier les tâches en arrière-plan', + 'tool.title.readJob': 'Lire le résultat de la tâche', + 'tool.title.killJob': 'Annuler le travail en arrière-plan', + 'tool.title.openTerminal': 'Terminal ouvert', + 'tool.title.readTerminal': 'Lire le terminal', + 'tool.title.listTerminals': 'Liste des terminaux', + 'tool.title.signalTerminal': 'Borne de signal', + 'tool.title.closeTerminal': 'Fermer le terminal', + 'tool.title.lsp': 'Symboles du code de requête', + 'tool.title.findDefinition': 'Trouver une définition', + 'tool.title.findReferences': 'Trouver des références', + 'tool.title.findImplementation': 'Trouver la mise en œuvre', + 'tool.title.hoverSymbol': 'Inspecter le symbole', + 'tool.title.spawnTeammate': 'Créer un coéquipier', + 'tool.title.createTeamTask': "Créer une tâche d'équipe", + 'tool.title.getTeamTask': "Lire la tâche d'équipe", + 'tool.title.updateTeamTask': "Mettre à jour la tâche de l'équipe", + 'tool.title.listTeamTasks': "Répertorier les tâches de l'équipe", + 'tool.title.waitAgent': 'Attendez le sous-agent', + 'detail.recordedResult': 'Résultat enregistré', + 'detail.empty': 'Aucun résultat', + 'detail.none': 'Aucun', + 'detail.yes': 'Oui', + 'detail.no': 'Non', + 'detail.moreInInspect': "{count} plus d'articles disponibles dans Inspecter", + 'detail.status.running': 'Courir', + 'detail.status.idle': 'Inactif', + 'detail.status.ready': 'Prêt', + 'detail.status.inactive': 'Inactif', + 'detail.status.provisioning': 'Approvisionnement', + 'detail.status.failed': 'Échec', + 'detail.status.completed': 'Terminé', + 'detail.status.deleted': 'Supprimé', + 'detail.status.killed': 'Annulé', + 'detail.status.accepted': 'Accepté', + 'detail.status.queued': "En file d'attente", + 'detail.status.exited': 'Quitté', + 'detail.field.id': 'ID', + 'detail.field.revision': 'Révision', + 'detail.field.platform': 'Plateforme', + 'detail.field.provider': 'Fournisseur', + 'detail.field.model': 'Modèle', + 'detail.field.role': 'Rôle', + 'detail.field.context': 'Contexte', + 'detail.field.owner': 'Propriétaire', + 'detail.field.ready': 'Prêt', + 'detail.field.dependencies': 'Dépendances', + 'detail.field.writeScopes': 'Écrire des étendues', + 'detail.field.warnings': 'Avertissements', + 'detail.field.diagnostics': 'Diagnostic', + 'detail.field.methods': 'Méthodes', + 'detail.field.inputSchema': "Schéma d'entrée", + 'detail.field.outputSchema': 'Schéma de sortie', + 'detail.field.currentPackage': 'Forfait actuel', + 'detail.field.nextPackage': 'Forfait suivant', + 'detail.field.latestRun': 'Dernière course', + 'detail.field.packages': 'Forfaits', + 'detail.field.registrations': 'Inscriptions', + 'detail.field.props': 'Accessoires', + 'detail.field.data': 'Données', + 'detail.field.source': 'Source', + 'detail.field.content': 'Contenu', + 'detail.field.message': 'Message', + 'detail.field.messageId': 'Identifiant du message', + 'detail.field.root': 'Racine', + 'detail.field.pid': 'ID de processus', + 'detail.field.type': 'Tapez', + 'detail.field.time': 'Temps', + 'detail.field.seq': "Séquence d'événements", + 'detail.field.turn': 'Tour', + 'detail.field.step': 'Étape', + 'detail.field.callId': "Identifiant d'appel", + 'detail.field.agents': 'Les agents ont commencé', + 'detail.field.result': 'Résultat', + 'detail.field.parent': 'Parent', + 'detail.field.depth': 'Profondeur', + 'detail.field.exitCode': 'Code de sortie', + 'detail.field.signal': 'Signal', + 'detail.field.previousStatus': 'Statut précédent', + 'detail.field.agent': "ID d'agent", + 'detail.field.job': 'ID de travail', + 'detail.field.task': 'Tâche', + 'detail.field.processGroup': 'Groupe de processus', + 'detail.field.availability': 'Disponibilité', + 'detail.field.bestMatch': 'Meilleure correspondance', + 'detail.field.target': 'Événement cible', + 'detail.field.surface': "Statut d'enregistrement", + 'detail.agents.count': 'Agents {count}', + 'detail.jobs.count': "Travaux d'arrière-plan {count}", + 'detail.terminals.count': 'Bornes {count}', + 'detail.tasks.count': "Tâches de l'équipe {count}", + 'detail.tasks.nextPage': 'Plus de tâches disponibles ; le curseur suivant est {cursor}', + 'detail.locations.count': 'Localisations {count}', + 'detail.location': 'Ligne {line}, colonne {column}', + 'detail.receipt.delivered': 'Message délivré', + 'detail.receipt.interrupt': 'Interruption demandée', + 'detail.receipt.started': 'Commencé', + 'detail.receipt.cancel': 'Annulation demandée', + 'detail.receipt.alreadyFinished': 'Déjà fini', + 'detail.receipt.signal': 'Signal délivré', + 'detail.receipt.closed': 'Fermé', + 'detail.receipt.closing': 'Clôture', + 'detail.wait.noProgress': 'Aucun sous-agent actif', + 'detail.wait.title': 'Activité du sous-agent', + 'detail.wait.timeout': "Le délai d'attente a expiré", + 'detail.wait.changed': 'Changement détecté', + 'detail.agent.reply': "Réponse de l'agent", + 'detail.models.title': 'Modèles disponibles', + 'detail.output.lines': 'Lignes {begin}–{end} de {total}', + 'detail.output.truncated': 'Sortie tronquée', + 'detail.providers.count': '{count} inspecte les fournisseurs', + 'detail.plugins.count': 'Plugins dynamiques {count}', + 'detail.workflow.script': 'Script de flux de travail', + 'detail.ralph.reportedComplete': "Le travailleur a signalé l'achèvement", + 'detail.ralph.reportedBlocker': 'Le travailleur a signalé un bloqueur', + 'detail.ralph.limit': 'Limite de tours atteinte', + 'detail.report.nextSteps': 'Travail restant', + 'detail.trace.replacedBy': 'Remplacé par', + 'detail.trace.replacementChain': 'Chaîne de remplacement', + 'detail.trace.replaces': 'Événements remplacés', + 'detail.trace.sources': 'Événements sources', + 'detail.trace.derived': 'Événements dérivés', + 'detail.trace.ancestors': "Séances d'ancêtres", + 'detail.trace.descendants': 'Séances descendantes', + 'detail.matches.count': 'Correspondances {count}', + 'detail.matches.capped': 'Limite de résultat atteinte ; affiner la recherche pour en savoir plus', + 'detail.event.neighbors': 'Événements environnants', + 'todo.completed': '{done}/{total} terminé', + 'command.attachmentsUnsupported': "/{command} n'accepte pas les pièces jointes ; retirez-les d'abord", + 'ask.rowTitle': 'Poser une question', + 'ask.waiting': 'en attendant', + 'ask.pending': 'suite ; réponse toujours disponible', + 'ask.pendingDetail': 'Ces questions en suspens restent à la charge du compositeur.', + 'ask.reopen': 'Réponse', + 'ask.review': 'Afficher les réponses', + 'ask.closed': 'fermé', + 'ask.closedDetail': 'Cette question est fermée ; son résultat est dans la conversation ci-dessous.', + 'ask.cancelled': 'annulé', + 'ask.cancelledDetail': 'Cet ensemble de questions a été annulé avant que les réponses ne soient soumises.', + 'ask.interrupted': 'interrompu', + 'ask.interruptedDetail': 'Cette série de questions a été interrompue avant que les réponses ne soient soumises.', + 'ask.answered': '{answered}/{total} répondu', + 'ask.skipped': 'Pas de réponse', + 'bash.running': 'Courir', + 'bash.failed': 'Échec', + 'bash.stopped': 'Arrêté', + 'row.running': 'Courir', + 'row.preparing': "Préparation de l'appel à l'outil", + 'row.failed': 'Échec', + 'row.stopped': 'Arrêté', + 'row.commandArguments': 'Arguments de commande', + 'row.input': 'IN', + 'row.output': 'OUT', + 'row.inspect': 'Inspecter', + 'row.imageSize': '{width}x{height}px, {bytes} octets', + 'row.imageSizeDownscaled': '{width}x{height}px (réduction de {originalWidth}x{originalHeight}px), {bytes} octets', + 'tool.title.search': 'Rechercher', + 'tool.title.read': 'Lire', + 'tool.title.bash': 'Frapper', + 'tool.title.write': 'Écrire', + 'tool.title.edit': 'Modifier', + 'tool.title.code': 'Coder', + 'tool.title.generic': "Appel d'outil", + 'tool.title.inspect': "Interroger l'environnement Cordis", + 'tool.title.runCordis': 'Exécuter le plugin Cordis', + 'tool.title.stopCordis': 'Arrêter le plug-in Cordis', + 'tool.title.removeCordis': 'Supprimer le plug-in Cordis', + 'tool.title.pwsh': 'Pwsh', + 'tool.title.readImage': "Lire l'image", + 'tool.title.grep': 'Grep', + 'tool.title.glob': 'Glob', + 'tool.title.webSearch': 'Rechercher', + 'tool.title.webFetch': 'Récupérer', + 'tool.autoReviewRejected': 'Rejeté par Auto review', + 'tool.autoReviewNotExecuted': "L'outil n'a pas été exécuté. Raison : {reason}", + 'tool.autoReviewReasonFallback': "Auto review n'a pas autorisé cette action", + 'diff.collapseAria': 'Réduire la différence', + 'diff.expandAria': 'Développez {count} plus de lignes de différence', + 'diff.expandRest': '… {count} plus de lignes', + 'read.window': 'Affichage des lignes {shown} des lignes {total}', + 'read.collapseAria': 'Réduire le contenu', + 'read.expandAria': 'Développez {count} plus de lignes', + 'read.expandRest': '… {count} plus de lignes', + 'search.paths': 'Chemins {shown}', + 'search.paths.truncated': 'Affichage des chemins {shown} sur {total}', + 'search.matches': 'Correspondances {shown} · Fichiers {files}', + 'search.matches.truncated': 'Affichage des correspondances {shown} des correspondances {total} · Fichiers {files}', + 'search.noResults': 'Aucun résultat', + 'search.collapseAria': 'Réduire les résultats', + 'search.expandAria': 'Développez {count} plus de lignes de résultats', + 'search.expandRest': '… {count} plus de lignes', + 'web.noResults': 'Aucun résultat trouvé', + 'web.sourcesTruncated': 'Liste source tronquée', + 'web.http': 'HTTP', + 'web.contentTruncated': 'Contenu tronqué', + 'details.running': 'Courir…', + 'queue.count': "Messages en file d'attente {n}", + 'queue.sending': 'Envoi…', + 'queue.image': "Image du message en file d'attente", + 'queue.file': "Fichier en file d'attente {name}", + 'queue.edit': "Modifier le message en file d'attente", + 'queue.edit.unsupported': "Contient du contenu non textuel ; l'édition n'est pas encore prise en charge", + 'queue.save': "Enregistrer le message en file d'attente", + 'queue.cancelEdit': 'Annuler la modification', + 'queue.remove': "Supprimer le message en file d'attente", + 'queue.steer': "Message en file d'attente", + 'queue.steer.unavailable': "Le pilotage est disponible uniquement lorsque l'agent est en cours d'exécution", + 'error.sessionInUse': "Cette session est déjà utilisée, éventuellement par une autre instance DSH en cours d'exécution (telle que le Web dsh ou l'application de bureau). Quittez les autres instances DSH en cours d'exécution et réessayez.", + 'queue.editFailed': "Échec de la modification : l'envoi de ce message a peut-être déjà commencé.", + 'queue.removeFailed': "Échec de la suppression : l'envoi de ce message a peut-être déjà commencé.", + 'queue.steerFailed': 'La direction a échoué. Essayer à nouveau.', + 'terminal.signal': 'signal {signal}', + 'terminal.exitCode': 'code de sortie {code}', + 'terminal.noExitCode': 'pas de code de sortie', + 'terminal.commandLine': 'Ligne de commande {n}', + 'terminal.running': 'Courir', + 'terminal.failed': 'Échec', + 'terminal.done': 'Terminé', + 'terminal.noOutput': 'Aucune sortie', + 'terminal.collapseAria': 'Réduire la sortie', + 'terminal.expandAria': 'Développez les lignes de sortie {n} restantes', + 'terminal.expandRest': '… {n} plus de lignes', + // The Host terminal_send presenter has no locale seat; keep its fallbacks + // aligned with these English values. + 'terminal.sendInput': '(envoyer une entrée)', + 'terminal.session': 'Borne {sessionId}', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'quote.remove': 'Zitat entfernen', + 'shortcut.newline': 'Neue Zeile', + 'shortcut.complementary': 'Nutzen Sie die ergänzende Aktion „Warteschlange/Steer“.', + 'shortcut.slash': 'Befehlsmenü öffnen', + 'shortcut.mention': 'Referenzmenü öffnen', + 'hint.plan': PLAN_NEXT_ACTION_EN, + 'hint.goal': 'Beschreiben Sie das Ziel einer lang andauernden Aufgabe', + 'hint.goal.active': 'Ziel aktiv – Bearbeiten / Anhalten / Fortsetzen / Löschen', + 'placeholder.plan': PLAN_NEXT_ACTION_EN, + 'placeholder.default': 'Senden Sie eine Nachricht oder führen Sie eine Aufgabe, /-Befehle, @-Dateien oder Sitzungen aus', + 'placeholder.unavailable': 'Sitzung nicht verfügbar', + 'placeholder.parentOffline': 'Elternsitzung offline; Das Senden ist nicht möglich, aber Sie können den Lauf trotzdem stoppen', + 'placeholder.hero': 'Beschreiben Sie, was Sie erstellen möchten: /-Befehle, @-Dateien oder Sitzungen', + 'placeholder.workspace': 'Wählen Sie einen Arbeitsbereich zum Starten aus', + 'placeholder.steerQueue': 'Cmd/Strg+Enter steuert alle Nachrichten in der Warteschlange', + 'input.commands': 'Fügen Sie Dateien hinzu oder führen Sie Befehle aus', + 'input.file': 'Datei', + 'input.stop': 'Hören Sie auf zu generieren', + 'input.send': 'Nachricht senden', + 'input.send.queue': 'Warteschlangennachricht', + 'input.send.steer': 'Steuerbotschaft', + 'attachment.pending': 'Ausstehende Anhänge', + 'attachment.scrollLeft': 'Anhänge nach links scrollen', + 'attachment.scrollRight': 'Anhänge nach rechts scrollen', + 'attachment.dropTitle': 'Ziehen Sie Dateien oder Bilder hierher, um sie hinzuzufügen', + 'attachment.dropDesc': 'Bildbeschränkung: bis zu {count} Bilder, jeweils {size}', + 'attachment.dropBlocked': 'Dateien und Bilder können derzeit nicht hinzugefügt werden', + 'attachment.directoryDesktopOnly': 'Ordner können nur in der Desktop-App hinzugefügt werden; einzelne Dateien im Browser hinzufügen', + 'attachment.pathUnavailable': 'Der Ordnerpfad konnte nicht abgerufen werden; Ziehen Sie es erneut hinein', + 'attachment.pathUnsupported': 'Der Pfad enthält Zeichen, die eine Referenz nicht enthalten kann; Benennen Sie es um und versuchen Sie es erneut', + 'image.pending': 'Ausstehende Bilder', + 'image.openOriginal': 'Original ansehen', + 'image.openOriginalLabel': '{label}, klicken Sie, um das Original anzuzeigen', + 'image.remove': 'Bild {name} entfernen', + 'image.original': 'Originalbild', + 'image.label': 'Bild', + 'image.loadFailed': 'Bild konnte nicht geladen werden; Klicken Sie, um es noch einmal zu versuchen', + 'image.loading': 'Bild wird geladen…', + 'image.preview': 'Originalbildvorschau', + 'image.closePreview': 'Originalbildvorschau schließen', + 'image.unsupportedType': 'Es werden nur PNG-, JPG-, WebP- und GIF-Bilder unterstützt', + 'image.tooMany': 'Eine Nachricht kann bis zu {count} Bilder enthalten', + 'image.fileTooLarge': 'Jedes Bild muss kleiner als {size} sein', + 'image.totalTooLarge': 'Die Anzahl der Bilder übersteigt insgesamt {size}; Entfernen Sie einige davon und versuchen Sie es erneut', + 'image.tooManyPixels': 'Die Bildauflösung ist zu hoch; Komprimieren Sie es und versuchen Sie es erneut', + 'image.dimensionTooLarge': 'Bildseiten dürfen höchstens {size}px sein; Skalieren Sie es herunter und versuchen Sie es erneut', + 'image.modelUnsupported': 'Das aktuelle Modell unterstützt keine Bilder; Wechseln Sie zu einem Modell, das dies tut', + 'image.sendFailed': 'Das Senden von Bildern ist fehlgeschlagen ({reason}); Fügen Sie sie erneut hinzu und versuchen Sie es erneut', + 'file.pending': 'Ausstehende Dateien', + 'file.remove': 'Datei {name} entfernen', + 'file.uploading': 'Hochladen…', + 'file.uploadFailed': 'Hochladen fehlgeschlagen; Klicken Sie, um es noch einmal zu versuchen', + 'file.retry': 'Versuchen Sie erneut, {name} hochzuladen', + 'file.stillUploading': 'Dateien werden noch hochgeladen; senden, nachdem sie fertig sind', + 'file.sessionUnavailable': 'Sitzung nicht verfügbar; Dateien können nicht hochgeladen werden', + 'file.notStaged': 'Der Upload der Datei wurde noch nicht abgeschlossen. Fügen Sie es erneut hinzu und versuchen Sie es erneut', + 'file.label': 'Datei', + 'context.aria': '{percent} des verwendeten Kontexts', + 'context.used': 'des verwendeten Kontexts', + 'context.system': 'Systemaufforderung', + 'context.tools': 'Werkzeugdefinitionen', + 'context.messages': 'Nachrichten', + 'settings.enter.title': 'Sendeverhalten, während beschäftigt ist', + 'settings.enter.description': 'Was die Eingabetaste und die Schaltfläche „Senden“ bewirken, während der Agent ausgeführt wird; Cmd/Strg+Enter verwendet das andere Verhalten', + 'settings.enter.queue': 'Warteschlange', + 'settings.enter.steer': 'Lenken', + 'hero.headline': 'Ins Unbekannte', + 'hero.preview': 'Vorschau', + 'hero.chooseWorkspace': 'Wählen Sie einen Arbeitsbereich', + 'session.hierarchy': 'Sitzungshierarchie', + 'session.moreViews': 'Weitere Konversationsansichten', + 'todo.title': 'Aufgaben', + 'todo.progress.done': '{done} abgeschlossen', + 'todo.progress.active': '{active} in Bearbeitung', + 'todo.progress.pending': '{pending} ausstehend', + 'todo.status.completed': 'Abgeschlossen', + 'todo.status.inProgress': 'In Bearbeitung', + 'todo.status.pending': 'Ausstehend', + 'todo.rowTitle': 'To-Do-Liste aktualisieren', + 'tool.title.createGoal': 'Ziel erstellen', + 'tool.title.getGoal': 'Ziel ansehen', + 'tool.title.updateGoal': 'Ziel aktualisieren', + 'tool.preparing.content': '{kilobytes}KB', + 'tool.title.createSchedule': 'Erinnerung erstellen', + 'tool.title.listSchedules': 'Listen Sie Erinnerungen auf', + 'tool.title.deleteSchedule': 'Erinnerung löschen', + 'tool.title.updateSchedule': 'Update-Erinnerung', + 'detail.state': 'Status', + 'detail.todo.completed': 'Abgeschlossen', + 'detail.todo.in_progress': 'In Bearbeitung', + 'detail.todo.pending': 'Ausstehend', + 'detail.todo.empty': 'Die To-Do-Liste ist leer', + 'todo.diff.initial': 'Erste Liste', + 'todo.diff.compare': 'Änderungen gegenüber der vorherigen Liste', + 'todo.diff.unavailable': 'Vorherige Liste nicht verfügbar', + 'todo.diff.noChanges': 'Keine Änderungen an der Liste', + 'todo.diff.added': '{count} hinzugefügt', + 'todo.diff.updated': '{count} aktualisiert', + 'todo.diff.removed': '{count} entfernt', + 'todo.diff.unchanged': '{count} unverändert', + 'todo.diff.addedItem': 'Hinzugefügt', + 'todo.diff.updatedItem': 'Status geändert', + 'todo.diff.movedItem': 'Nachbestellt', + 'todo.diff.removedItem': 'Entfernt', + 'detail.goal.empty': 'Kein Ziel', + 'detail.goal.active': 'Aktiv', + 'detail.goal.disarmed': 'Warten auf Fortsetzung', + 'detail.goal.paused': 'Angehalten', + 'detail.goal.blocked': 'Blockiert', + 'detail.goal.complete': 'Abgeschlossen', + 'detail.goal.rounds': 'Runden', + 'detail.goal.reason': 'Blocker', + 'detail.days': '{count} d', + 'detail.hours': '{count} h', + 'detail.minutes': '{count} min', + 'detail.seconds': '{count} s', + 'detail.schedule.once': 'Einmal', + 'detail.schedule.every': 'Jeder {interval}', + 'detail.schedule.when': 'Geplant für', + 'detail.schedule.frequency': 'Wiederholen', + 'detail.schedule.scheduled': 'Geplant', + 'detail.schedule.overdue': 'Überfällig, ich warte auf die Fortsetzung der Sitzung', + 'detail.schedule.empty': 'Keine Erinnerungen', + 'detail.schedule.deleted': 'Gelöscht', + 'detail.schedule.count': '{count} Erinnerungen', + 'detail.schedule.daily': 'Täglich um {time} ({zone})', + 'detail.schedule.weekly': 'Wöchentlich auf {days} um {time} ({zone})', + 'detail.schedule.cron': 'Cron {expression} ({zone})', + 'detail.weekday.1': 'Mo', + 'detail.weekday.2': 'Di', + 'detail.weekday.3': 'Mi', + 'detail.weekday.4': 'Do', + 'detail.weekday.5': 'Fr', + 'detail.weekday.6': 'Sa', + 'detail.weekday.7': 'Sonne', + 'detail.weekday.join': ', ', + 'tool.title.inspectProviders': 'Anbieter prüfen', + 'tool.title.queryRuntime': 'Abfragelaufzeit', + 'tool.title.inspectPlugins': 'Plugins prüfen', + 'tool.title.workflow': 'Workflow ausführen', + 'tool.title.ralph': 'Führen Sie die Ralph-Schleife aus', + 'tool.title.readEvent': 'Veranstaltung lesen', + 'tool.title.searchEvents': 'Suchen Sie nach Ereignissen', + 'tool.title.traceEvent': 'Trace-Ereignis', + 'tool.title.searchSessions': 'Suchsitzungen', + 'tool.title.traceSession': 'Trace-Sitzung', + 'tool.title.listModels': 'Modelle auflisten', + 'tool.title.subagent': 'Subagent erstellen', + 'tool.title.listAgents': 'Subagenten auflisten', + 'tool.title.sendMessage': 'Nachricht senden', + 'tool.title.interruptAgent': 'Interrupt-Agent', + 'tool.title.listJobs': 'Hintergrundjobs auflisten', + 'tool.title.readJob': 'Jobausgabe lesen', + 'tool.title.killJob': 'Hintergrundjob abbrechen', + 'tool.title.openTerminal': 'Terminal öffnen', + 'tool.title.readTerminal': 'Terminal lesen', + 'tool.title.listTerminals': 'Terminals auflisten', + 'tool.title.signalTerminal': 'Signalklemme', + 'tool.title.closeTerminal': 'Terminal schließen', + 'tool.title.lsp': 'Codesymbole abfragen', + 'tool.title.findDefinition': 'Definition finden', + 'tool.title.findReferences': 'Finden Sie Referenzen', + 'tool.title.findImplementation': 'Umsetzung finden', + 'tool.title.hoverSymbol': 'Symbol prüfen', + 'tool.title.spawnTeammate': 'Teamkollege erstellen', + 'tool.title.createTeamTask': 'Teamaufgabe erstellen', + 'tool.title.getTeamTask': 'Teamaufgabe lesen', + 'tool.title.updateTeamTask': 'Teamaufgabe aktualisieren', + 'tool.title.listTeamTasks': 'Teamaufgaben auflisten', + 'tool.title.waitAgent': 'Warten Sie auf den Subagenten', + 'detail.recordedResult': 'Aufgezeichnetes Ergebnis', + 'detail.empty': 'Keine Ergebnisse', + 'detail.none': 'Keine', + 'detail.yes': 'Ja', + 'detail.no': 'Nein', + 'detail.moreInInspect': '{count} weitere Artikel in Inspect verfügbar', + 'detail.status.running': 'Laufen', + 'detail.status.idle': 'Leerlauf', + 'detail.status.ready': 'Bereit', + 'detail.status.inactive': 'Inaktiv', + 'detail.status.provisioning': 'Bereitstellung', + 'detail.status.failed': 'Fehlgeschlagen', + 'detail.status.completed': 'Abgeschlossen', + 'detail.status.deleted': 'Gelöscht', + 'detail.status.killed': 'Abgesagt', + 'detail.status.accepted': 'Akzeptiert', + 'detail.status.queued': 'In der Warteschlange', + 'detail.status.exited': 'Ausgegangen', + 'detail.field.id': 'ID', + 'detail.field.revision': 'Überarbeitung', + 'detail.field.platform': 'Plattform', + 'detail.field.provider': 'Anbieter', + 'detail.field.model': 'Modell', + 'detail.field.role': 'Rolle', + 'detail.field.context': 'Kontext', + 'detail.field.owner': 'Besitzer', + 'detail.field.ready': 'Bereit', + 'detail.field.dependencies': 'Abhängigkeiten', + 'detail.field.writeScopes': 'Bereiche schreiben', + 'detail.field.warnings': 'Warnungen', + 'detail.field.diagnostics': 'Diagnose', + 'detail.field.methods': 'Methoden', + 'detail.field.inputSchema': 'Eingabeschema', + 'detail.field.outputSchema': 'Ausgabeschema', + 'detail.field.currentPackage': 'Aktuelles Paket', + 'detail.field.nextPackage': 'Nächstes Paket', + 'detail.field.latestRun': 'Letzter Lauf', + 'detail.field.packages': 'Pakete', + 'detail.field.registrations': 'Anmeldungen', + 'detail.field.props': 'Requisiten', + 'detail.field.data': 'Daten', + 'detail.field.source': 'Quelle', + 'detail.field.content': 'Inhalt', + 'detail.field.message': 'Nachricht', + 'detail.field.messageId': 'Nachrichten-ID', + 'detail.field.root': 'Wurzel', + 'detail.field.pid': 'Prozess-ID', + 'detail.field.type': 'Typ', + 'detail.field.time': 'Zeit', + 'detail.field.seq': 'Ereignissequenz', + 'detail.field.turn': 'Runde', + 'detail.field.step': 'Schritt', + 'detail.field.callId': 'Aufruf-ID', + 'detail.field.agents': 'Agenten begannen', + 'detail.field.result': 'Ergebnis', + 'detail.field.parent': 'Eltern', + 'detail.field.depth': 'Tiefe', + 'detail.field.exitCode': 'Exit-Code', + 'detail.field.signal': 'Signal', + 'detail.field.previousStatus': 'Vorheriger Stand', + 'detail.field.agent': 'Agenten-ID', + 'detail.field.job': 'Job-ID', + 'detail.field.task': 'Aufgabe', + 'detail.field.processGroup': 'Prozessgruppe', + 'detail.field.availability': 'Verfügbarkeit', + 'detail.field.bestMatch': 'Beste Übereinstimmung', + 'detail.field.target': 'Zielereignis', + 'detail.field.surface': 'Aufnahmestatus', + 'detail.agents.count': '{count}-Agenten', + 'detail.jobs.count': '{count} Hintergrundjobs', + 'detail.terminals.count': '{count}-Klemmen', + 'detail.tasks.count': '{count} Teamaufgaben', + 'detail.tasks.nextPage': 'Weitere Aufgaben verfügbar; Der nächste Cursor ist {cursor}', + 'detail.locations.count': '{count}-Standorte', + 'detail.location': 'Zeile {line}, Spalte {column}', + 'detail.receipt.delivered': 'Nachricht zugestellt', + 'detail.receipt.interrupt': 'Unterbrechung angefordert', + 'detail.receipt.started': 'Begonnen', + 'detail.receipt.cancel': 'Stornierung beantragt', + 'detail.receipt.alreadyFinished': 'Schon fertig', + 'detail.receipt.signal': 'Signal geliefert', + 'detail.receipt.closed': 'Geschlossen', + 'detail.receipt.closing': 'Schließung', + 'detail.wait.noProgress': 'Keine aktiven Subagenten', + 'detail.wait.title': 'Aktivität des Subagenten', + 'detail.wait.timeout': 'Wartezeit abgelaufen', + 'detail.wait.changed': 'Änderung erkannt', + 'detail.agent.reply': 'Antwort des Agenten', + 'detail.models.title': 'Verfügbare Modelle', + 'detail.output.lines': 'Linien {begin}–{end} von {total}', + 'detail.output.truncated': 'Ausgabe abgeschnitten', + 'detail.providers.count': '{count} prüft Anbieter', + 'detail.plugins.count': 'Dynamische {count}-Plugins', + 'detail.workflow.script': 'Workflow-Skript', + 'detail.ralph.reportedComplete': 'Der Arbeiter hat die Fertigstellung gemeldet', + 'detail.ralph.reportedBlocker': 'Der Arbeiter hat einen Blocker gemeldet', + 'detail.ralph.limit': 'Rundenlimit erreicht', + 'detail.report.nextSteps': 'Verbleibende Arbeit', + 'detail.trace.replacedBy': 'Ersetzt durch', + 'detail.trace.replacementChain': 'Ersatzkette', + 'detail.trace.replaces': 'Ereignisse ersetzt', + 'detail.trace.sources': 'Quellereignisse', + 'detail.trace.derived': 'Abgeleitete Ereignisse', + 'detail.trace.ancestors': 'Ahnensitzungen', + 'detail.trace.descendants': 'Nachkommende Sitzungen', + 'detail.matches.count': '{count} Übereinstimmungen', + 'detail.matches.capped': 'Ergebnisgrenze erreicht; Grenzen Sie die Suche auf mehr ein', + 'detail.event.neighbors': 'Umliegende Veranstaltungen', + 'todo.completed': '{done}/{total} abgeschlossen', + 'command.attachmentsUnsupported': '/{command} akzeptiert keine Anhänge; Entfernen Sie sie zuerst', + 'ask.rowTitle': 'Frage stellen', + 'ask.waiting': 'warten', + 'ask.pending': 'Fortsetzung; Antwort noch verfügbar', + 'ask.pendingDetail': 'Diese offenen Fragen bleiben vom Komponisten zu beantworten.', + 'ask.reopen': 'Antwort', + 'ask.review': 'Antworten anzeigen', + 'ask.closed': 'geschlossen', + 'ask.closedDetail': 'Diese Frage ist geschlossen; Das Ergebnis finden Sie im folgenden Gespräch.', + 'ask.cancelled': 'abgesagt', + 'ask.cancelledDetail': 'Dieser Fragensatz wurde gelöscht, bevor die Antworten übermittelt wurden.', + 'ask.interrupted': 'unterbrochen', + 'ask.interruptedDetail': 'Dieser Fragensatz wurde unterbrochen, bevor Antworten übermittelt wurden.', + 'ask.answered': '{answered}/{total} antwortete', + 'ask.skipped': 'Nicht beantwortet', + 'bash.running': 'Laufen', + 'bash.failed': 'Fehlgeschlagen', + 'bash.stopped': 'Angehalten', + 'row.running': 'Laufen', + 'row.preparing': 'Werkzeugaufruf wird vorbereitet', + 'row.failed': 'Fehlgeschlagen', + 'row.stopped': 'Angehalten', + 'row.commandArguments': 'Befehlsargumente', + 'row.input': 'IN', + 'row.output': 'OUT', + 'row.inspect': 'Inspizieren', + 'row.imageSize': '{width}x{height}px, {bytes} Bytes', + 'row.imageSizeDownscaled': '{width}x{height}px (herunterskaliert von {originalWidth}x{originalHeight}px), {bytes} Bytes', + 'tool.title.search': 'Suchen', + 'tool.title.read': 'Lesen', + 'tool.title.bash': 'Bash', + 'tool.title.write': 'Schreiben', + 'tool.title.edit': 'Bearbeiten', + 'tool.title.code': 'Code', + 'tool.title.generic': 'Werkzeugaufruf', + 'tool.title.inspect': 'Fragen Sie die Cordis-Umgebung ab', + 'tool.title.runCordis': 'Führen Sie das Cordis-Plugin aus', + 'tool.title.stopCordis': 'Stoppen Sie das Cordis-Plugin', + 'tool.title.removeCordis': 'Entfernen Sie das Cordis-Plugin', + 'tool.title.pwsh': 'Pwsh', + 'tool.title.readImage': 'Bild lesen', + 'tool.title.grep': 'Grep', + 'tool.title.glob': 'Globus', + 'tool.title.webSearch': 'Suchen', + 'tool.title.webFetch': 'Holen', + 'tool.autoReviewRejected': 'Abgelehnt von Auto review', + 'tool.autoReviewNotExecuted': 'Werkzeug wurde nicht ausgeführt. Grund: {reason}', + 'tool.autoReviewReasonFallback': 'Auto review hat diese Aktion nicht autorisiert', + 'diff.collapseAria': 'Differenz ausblenden', + 'diff.expandAria': 'Erweitern Sie {count} um weitere Diff-Linien', + 'diff.expandRest': '… {count} weitere Zeilen', + 'read.window': 'Zeigt {shown} der {total}-Linien', + 'read.collapseAria': 'Inhalt reduzieren', + 'read.expandAria': 'Erweitern Sie {count} um weitere Zeilen', + 'read.expandRest': '… {count} weitere Zeilen', + 'search.paths': '{shown}-Pfade', + 'search.paths.truncated': 'Zeigt {shown} von {total}-Pfaden', + 'search.matches': '{shown} entspricht · {files}-Dateien', + 'search.matches.truncated': 'Zeigt {shown} von {total}-Übereinstimmungen · {files}-Dateien', + 'search.noResults': 'Keine Ergebnisse', + 'search.collapseAria': 'Ergebnisse reduzieren', + 'search.expandAria': 'Erweitern Sie {count} um weitere Ergebniszeilen', + 'search.expandRest': '… {count} weitere Zeilen', + 'web.noResults': 'Keine Ergebnisse gefunden', + 'web.sourcesTruncated': 'Quellenliste gekürzt', + 'web.http': 'HTTP', + 'web.contentTruncated': 'Inhalt abgeschnitten', + 'details.running': 'Laufen…', + 'queue.count': '{n} Nachrichten in der Warteschlange', + 'queue.sending': 'Senden…', + 'queue.image': 'Nachrichtenbild in der Warteschlange', + 'queue.file': 'Datei in der Warteschlange {name}', + 'queue.edit': 'Bearbeiten Sie die Nachricht in der Warteschlange', + 'queue.edit.unsupported': 'Enthält Nicht-Textinhalte; Bearbeitung wird noch nicht unterstützt', + 'queue.save': 'Speichern Sie die Nachricht in der Warteschlange', + 'queue.cancelEdit': 'Bearbeitung abbrechen', + 'queue.remove': 'Entfernen Sie die Nachricht in der Warteschlange', + 'queue.steer': 'Steuern Sie die Nachricht in der Warteschlange', + 'queue.steer.unavailable': 'Die Steuerung ist nur verfügbar, während der Agent ausgeführt wird', + 'error.sessionInUse': 'Diese Sitzung wird bereits verwendet, möglicherweise von einer anderen laufenden DSH-Instanz (z. B. dsh Web oder der Desktop-App). Beenden Sie andere laufende DSH-Instanzen und versuchen Sie es erneut.', + 'queue.editFailed': 'Bearbeitung fehlgeschlagen: Der Versand dieser Nachricht wurde möglicherweise bereits gestartet.', + 'queue.removeFailed': 'Fehler beim Entfernen: Der Versand dieser Nachricht wurde möglicherweise bereits gestartet.', + 'queue.steerFailed': 'Lenkung versagt. Versuchen Sie es erneut.', + 'terminal.signal': 'Signal {signal}', + 'terminal.exitCode': 'Exit-Code {code}', + 'terminal.noExitCode': 'kein Exit-Code', + 'terminal.commandLine': 'Befehlszeile {n}', + 'terminal.running': 'Laufen', + 'terminal.failed': 'Fehlgeschlagen', + 'terminal.done': 'Fertig', + 'terminal.noOutput': 'Keine Ausgabe', + 'terminal.collapseAria': 'Ausgabe reduzieren', + 'terminal.expandAria': 'Erweitern Sie die verbleibenden {n}-Ausgabezeilen', + 'terminal.expandRest': '… {n} weitere Zeilen', + // The Host terminal_send presenter has no locale seat; keep its fallbacks + // aligned with these English values. + 'terminal.sendInput': '(Eingabe senden)', + 'terminal.session': 'Terminal {sessionId}', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'quote.remove': 'Удалить цитату', + 'shortcut.newline': 'Новая линия', + 'shortcut.complementary': 'Используйте дополнительное действие «Очередь/Управление»', + 'shortcut.slash': 'Открыть командное меню', + 'shortcut.mention': 'Открыть справочное меню', + 'hint.plan': PLAN_NEXT_ACTION_EN, + 'hint.goal': 'описать цель долгосрочной задачи', + 'hint.goal.active': 'цель активна — изменить/приостановить/возобновить/очистить', + 'placeholder.plan': PLAN_NEXT_ACTION_EN, + 'placeholder.default': 'Отправьте сообщение или запустите задачу, /команды, @файлы или сеансы', + 'placeholder.unavailable': 'Сеанс недоступен', + 'placeholder.parentOffline': 'Родительская сессия в автономном режиме; отправка недоступна, но вы все равно можете остановить запуск', + 'placeholder.hero': 'Опишите, что вы хотите построить: /команды, @файлы или сеансы.', + 'placeholder.workspace': 'Выберите рабочее пространство для начала', + 'placeholder.steerQueue': 'Cmd/Ctrl+Enter управляет всеми сообщениями в очереди.', + 'input.commands': 'Добавляйте файлы или запускайте команды', + 'input.file': 'Файл', + 'input.stop': 'Прекратить генерировать', + 'input.send': 'Отправить сообщение', + 'input.send.queue': 'Сообщение в очереди', + 'input.send.steer': 'Управляйте сообщением', + 'attachment.pending': 'Ожидающие вложения', + 'attachment.scrollLeft': 'Прокрутить вложения влево', + 'attachment.scrollRight': 'Прокрутить вложения вправо', + 'attachment.dropTitle': 'Перетащите файлы или изображения сюда, чтобы добавить их.', + 'attachment.dropDesc': 'Ограничение изображений: до изображений {count}, по {size} каждое.', + 'attachment.dropBlocked': 'Файлы и изображения не могут быть добавлены прямо сейчас.', + 'attachment.directoryDesktopOnly': 'Папки можно добавлять только в настольном приложении; добавлять отдельные файлы в браузере', + 'attachment.pathUnavailable': 'Не удалось получить путь к папке; перетащите это снова', + 'attachment.pathUnsupported': 'Путь содержит символы, которые не может содержать ссылка; переименуй его и попробуй еще раз', + 'image.pending': 'Ожидающие изображения', + 'image.openOriginal': 'Посмотреть оригинал', + 'image.openOriginalLabel': '{label}, нажмите, чтобы посмотреть оригинал', + 'image.remove': 'Удалить изображение {name}', + 'image.original': 'Исходное изображение', + 'image.label': 'Изображение', + 'image.loadFailed': 'Изображение не удалось загрузить; нажмите, чтобы повторить попытку', + 'image.loading': 'Загрузка изображения…', + 'image.preview': 'Предварительный просмотр исходного изображения', + 'image.closePreview': 'Закрыть предварительный просмотр исходного изображения', + 'image.unsupportedType': 'Поддерживаются только изображения PNG, JPG, WebP и GIF.', + 'image.tooMany': 'Сообщение может содержать до {count} изображений.', + 'image.fileTooLarge': 'Каждое изображение должно быть меньше {size}.', + 'image.totalTooLarge': 'Общее количество изображений превышает {size}; удалите некоторые и попробуйте еще раз', + 'image.tooManyPixels': 'Разрешение изображения слишком высокое; сожми его и попробуй еще раз', + 'image.dimensionTooLarge': 'Стороны изображения должны быть не более {size}px; уменьшите масштаб и попробуйте еще раз', + 'image.modelUnsupported': 'Текущая модель не поддерживает изображения; переключиться на модель, которая делает', + 'image.sendFailed': 'Отправка изображений не удалась ({reason}); добавьте их повторно и попробуйте еще раз', + 'file.pending': 'Ожидающие файлы', + 'file.remove': 'Удалить файл {name}', + 'file.uploading': 'Загрузка…', + 'file.uploadFailed': 'Загрузка не удалась; нажмите, чтобы повторить попытку', + 'file.retry': 'Повторите загрузку {name}.', + 'file.stillUploading': 'Файлы все еще загружаются; отправить после того, как они закончат', + 'file.sessionUnavailable': 'Сессия недоступна; файлы не могут быть загружены', + 'file.notStaged': 'Загрузка файла не завершена; добавьте его еще раз и попробуйте еще раз', + 'file.label': 'Файл', + 'context.aria': '{percent} используемого контекста', + 'context.used': 'используемого контекста', + 'context.system': 'Системная подсказка', + 'context.tools': 'Определения инструментов', + 'context.messages': 'Сообщения', + 'settings.enter.title': 'Отправлять поведение во время занятости', + 'settings.enter.description': 'Что делают кнопки «Ввод» и «Отправить» во время работы агента; Cmd/Ctrl+Enter использует другое поведение.', + 'settings.enter.queue': 'Очередь', + 'settings.enter.steer': 'Управлять', + 'hero.headline': 'В неизвестность', + 'hero.preview': 'Предварительный просмотр', + 'hero.chooseWorkspace': 'Выберите рабочее пространство', + 'session.hierarchy': 'Иерархия сеансов', + 'session.moreViews': 'Больше просмотров беседы', + 'todo.title': 'Дела', + 'todo.progress.done': '{done} завершено', + 'todo.progress.active': '{active} в процессе', + 'todo.progress.pending': '{pending} в ожидании', + 'todo.status.completed': 'Завершено', + 'todo.status.inProgress': 'В процессе', + 'todo.status.pending': 'Ожидается', + 'todo.rowTitle': 'Обновить список дел', + 'tool.title.createGoal': 'Создать цель', + 'tool.title.getGoal': 'Посмотреть цель', + 'tool.title.updateGoal': 'Обновить цель', + 'tool.preparing.content': '{kilobytes}KB', + 'tool.title.createSchedule': 'Создать напоминание', + 'tool.title.listSchedules': 'Список напоминаний', + 'tool.title.deleteSchedule': 'Удалить напоминание', + 'tool.title.updateSchedule': 'Обновить напоминание', + 'detail.state': 'Статус', + 'detail.todo.completed': 'Завершено', + 'detail.todo.in_progress': 'В процессе', + 'detail.todo.pending': 'Ожидается', + 'detail.todo.empty': 'Список дел пуст', + 'todo.diff.initial': 'Первоначальный список', + 'todo.diff.compare': 'Изменения по сравнению с предыдущим списком', + 'todo.diff.unavailable': 'Предыдущий список недоступен', + 'todo.diff.noChanges': 'Никаких изменений в списке', + 'todo.diff.added': '{count} добавлен', + 'todo.diff.updated': '{count} обновлен', + 'todo.diff.removed': '{count} удален.', + 'todo.diff.unchanged': '{count} без изменений', + 'todo.diff.addedItem': 'Добавлено', + 'todo.diff.updatedItem': 'Статус изменен', + 'todo.diff.movedItem': 'Переупорядочен', + 'todo.diff.removedItem': 'Удален', + 'detail.goal.empty': 'Нет цели', + 'detail.goal.active': 'Активный', + 'detail.goal.disarmed': 'Ожидание продолжения', + 'detail.goal.paused': 'Приостановлено', + 'detail.goal.blocked': 'Заблокировано', + 'detail.goal.complete': 'Завершено', + 'detail.goal.rounds': 'Раунды', + 'detail.goal.reason': 'Блокатор', + 'detail.days': '{count} д', + 'detail.hours': '{count} ч', + 'detail.minutes': '{count} мин.', + 'detail.seconds': '{count} с', + 'detail.schedule.once': 'Однажды', + 'detail.schedule.every': 'Каждый {interval}', + 'detail.schedule.when': 'Запланировано на', + 'detail.schedule.frequency': 'Повторить', + 'detail.schedule.scheduled': 'Запланировано', + 'detail.schedule.overdue': 'Просрочено, ждём возобновления сеанса', + 'detail.schedule.empty': 'Нет напоминаний', + 'detail.schedule.deleted': 'Удалено', + 'detail.schedule.count': '{count} напоминания', + 'detail.schedule.daily': 'Каждый день в {time} ({zone})', + 'detail.schedule.weekly': 'Еженедельно на {days} по адресу {time} ({zone})', + 'detail.schedule.cron': 'Крон {expression} ({zone})', + 'detail.weekday.1': 'Пн.', + 'detail.weekday.2': 'Вт', + 'detail.weekday.3': 'ср.', + 'detail.weekday.4': 'Чт', + 'detail.weekday.5': 'Пт', + 'detail.weekday.6': 'Суббота', + 'detail.weekday.7': 'Солнце', + 'detail.weekday.join': ', ', + 'tool.title.inspectProviders': 'Проверка поставщиков', + 'tool.title.queryRuntime': 'Время выполнения запроса', + 'tool.title.inspectPlugins': 'Проверьте плагины', + 'tool.title.workflow': 'Запустить рабочий процесс', + 'tool.title.ralph': 'Запустить цикл Ральфа', + 'tool.title.readEvent': 'Чтение события', + 'tool.title.searchEvents': 'Поиск событий', + 'tool.title.traceEvent': 'Отследить событие', + 'tool.title.searchSessions': 'Поиск сеансов', + 'tool.title.traceSession': 'Трассировка сеанса', + 'tool.title.listModels': 'Список моделей', + 'tool.title.subagent': 'Создать субагент', + 'tool.title.listAgents': 'Список субагентов', + 'tool.title.sendMessage': 'Отправить сообщение', + 'tool.title.interruptAgent': 'Агент прерываний', + 'tool.title.listJobs': 'Список фоновых заданий', + 'tool.title.readJob': 'Чтение результатов задания', + 'tool.title.killJob': 'Отменить фоновое задание', + 'tool.title.openTerminal': 'Открыть терминал', + 'tool.title.readTerminal': 'Чтение терминала', + 'tool.title.listTerminals': 'Список терминалов', + 'tool.title.signalTerminal': 'Сигнальный терминал', + 'tool.title.closeTerminal': 'Закрыть терминал', + 'tool.title.lsp': 'Символы кода запроса', + 'tool.title.findDefinition': 'Найти определение', + 'tool.title.findReferences': 'Найдите ссылки', + 'tool.title.findImplementation': 'Найти реализацию', + 'tool.title.hoverSymbol': 'Символ проверки', + 'tool.title.spawnTeammate': 'Создать товарища по команде', + 'tool.title.createTeamTask': 'Создать командную задачу', + 'tool.title.getTeamTask': 'Прочитать командное задание', + 'tool.title.updateTeamTask': 'Обновить групповую задачу', + 'tool.title.listTeamTasks': 'Перечислить командные задачи', + 'tool.title.waitAgent': 'Подождите субагента', + 'detail.recordedResult': 'Записанный результат', + 'detail.empty': 'Нет результатов', + 'detail.none': 'Нет', + 'detail.yes': 'Да', + 'detail.no': 'Нет', + 'detail.moreInInspect': '{count} больше элементов доступно в Inspect', + 'detail.status.running': 'Бег', + 'detail.status.idle': 'Простой', + 'detail.status.ready': 'Готово', + 'detail.status.inactive': 'Неактивный', + 'detail.status.provisioning': 'обеспечение', + 'detail.status.failed': 'Не удалось', + 'detail.status.completed': 'Завершено', + 'detail.status.deleted': 'Удалено', + 'detail.status.killed': 'Отменено', + 'detail.status.accepted': 'Принято', + 'detail.status.queued': 'В очереди', + 'detail.status.exited': 'Вышел', + 'detail.field.id': 'ID', + 'detail.field.revision': 'Редакция', + 'detail.field.platform': 'Платформа', + 'detail.field.provider': 'Поставщик', + 'detail.field.model': 'Модель', + 'detail.field.role': 'Роль', + 'detail.field.context': 'Контекст', + 'detail.field.owner': 'Владелец', + 'detail.field.ready': 'Готово', + 'detail.field.dependencies': 'Зависимости', + 'detail.field.writeScopes': 'Запись областей', + 'detail.field.warnings': 'Предупреждения', + 'detail.field.diagnostics': 'Диагностика', + 'detail.field.methods': 'Методы', + 'detail.field.inputSchema': 'Входная схема', + 'detail.field.outputSchema': 'Выходная схема', + 'detail.field.currentPackage': 'Текущий пакет', + 'detail.field.nextPackage': 'Следующий пакет', + 'detail.field.latestRun': 'Последний запуск', + 'detail.field.packages': 'Пакеты', + 'detail.field.registrations': 'Регистрации', + 'detail.field.props': 'Реквизит', + 'detail.field.data': 'Данные', + 'detail.field.source': 'Источник', + 'detail.field.content': 'Содержание', + 'detail.field.message': 'Сообщение', + 'detail.field.messageId': 'Идентификатор сообщения', + 'detail.field.root': 'Корень', + 'detail.field.pid': 'Идентификатор процесса', + 'detail.field.type': 'Тип', + 'detail.field.time': 'Время', + 'detail.field.seq': 'Последовательность событий', + 'detail.field.turn': 'Ход', + 'detail.field.step': 'Шаг', + 'detail.field.callId': 'Идентификатор вызова', + 'detail.field.agents': 'Агенты запущены', + 'detail.field.result': 'Результат', + 'detail.field.parent': 'Родитель', + 'detail.field.depth': 'Глубина', + 'detail.field.exitCode': 'Код выхода', + 'detail.field.signal': 'Сигнал', + 'detail.field.previousStatus': 'Предыдущий статус', + 'detail.field.agent': 'Идентификатор агента', + 'detail.field.job': 'Идентификатор вакансии', + 'detail.field.task': 'Задача', + 'detail.field.processGroup': 'Группа процессов', + 'detail.field.availability': 'Доступность', + 'detail.field.bestMatch': 'Лучший матч', + 'detail.field.target': 'Целевое событие', + 'detail.field.surface': 'Статус записи', + 'detail.agents.count': '{count} агенты', + 'detail.jobs.count': '{count} фоновые задания', + 'detail.terminals.count': 'Клеммы {count}', + 'detail.tasks.count': '{count} командные задачи', + 'detail.tasks.nextPage': 'Доступно больше задач; следующий курсор — {cursor}', + 'detail.locations.count': '{count} локации', + 'detail.location': 'Строка {line}, столбец {column}', + 'detail.receipt.delivered': 'Сообщение доставлено', + 'detail.receipt.interrupt': 'Запрошено прерывание', + 'detail.receipt.started': 'Началось', + 'detail.receipt.cancel': 'Запрос на отмену', + 'detail.receipt.alreadyFinished': 'Уже закончено', + 'detail.receipt.signal': 'Сигнал доставлен', + 'detail.receipt.closed': 'Закрыто', + 'detail.receipt.closing': 'Закрытие', + 'detail.wait.noProgress': 'Нет активных субагентов', + 'detail.wait.title': 'Субагентская деятельность', + 'detail.wait.timeout': 'Время ожидания истекло', + 'detail.wait.changed': 'Обнаружено изменение', + 'detail.agent.reply': 'Ответ агента', + 'detail.models.title': 'Доступные модели', + 'detail.output.lines': 'Линии {begin} – {end} из {total}', + 'detail.output.truncated': 'Вывод усечен', + 'detail.providers.count': '{count} проверяет поставщиков', + 'detail.plugins.count': 'Динамические плагины {count}', + 'detail.workflow.script': 'Сценарий рабочего процесса', + 'detail.ralph.reportedComplete': 'Работник сообщил о завершении', + 'detail.ralph.reportedBlocker': 'Работник сообщил о блокировщике', + 'detail.ralph.limit': 'Достигнут лимит раундов', + 'detail.report.nextSteps': 'Оставшаяся работа', + 'detail.trace.replacedBy': 'Заменено на', + 'detail.trace.replacementChain': 'Замена цепи', + 'detail.trace.replaces': 'Замененные события', + 'detail.trace.sources': 'Исходные события', + 'detail.trace.derived': 'Производные события', + 'detail.trace.ancestors': 'Сеансы предков', + 'detail.trace.descendants': 'Потомки сеансов', + 'detail.matches.count': '{count} совпадений', + 'detail.matches.capped': 'Достигнут предел результатов; сузить поиск для большего', + 'detail.event.neighbors': 'Сопутствующие события', + 'todo.completed': '{done}/{total} завершено', + 'command.attachmentsUnsupported': '/{command} не принимает вложения; сначала удали их', + 'ask.rowTitle': 'Задать вопрос', + 'ask.waiting': 'ожидание', + 'ask.pending': 'продолжение; ответ еще доступен', + 'ask.pendingDetail': 'На эти нерешенные вопросы остается ответ композитора.', + 'ask.reopen': 'Ответ', + 'ask.review': 'Посмотреть ответы', + 'ask.closed': 'закрыто', + 'ask.closedDetail': 'Этот вопрос закрыт; его результат в разговоре ниже.', + 'ask.cancelled': 'отменен', + 'ask.cancelledDetail': 'Этот набор вопросов был отменен до того, как были отправлены ответы.', + 'ask.interrupted': 'прерванный', + 'ask.interruptedDetail': 'Этот набор вопросов был прерван до того, как были представлены ответы.', + 'ask.answered': '{answered}/{total} ответил', + 'ask.skipped': 'Не ответил', + 'bash.running': 'Бег', + 'bash.failed': 'Не удалось', + 'bash.stopped': 'Остановлено', + 'row.running': 'Бег', + 'row.preparing': 'Подготовка вызова инструмента', + 'row.failed': 'Не удалось', + 'row.stopped': 'Остановлено', + 'row.commandArguments': 'Аргументы команды', + 'row.input': 'IN', + 'row.output': 'OUT', + 'row.inspect': 'Осмотреть', + 'row.imageSize': '{width}x{height}px, {bytes} байт', + 'row.imageSizeDownscaled': '{width}x{height}px (уменьшено с {originalWidth}x{originalHeight}px), {bytes} байт', + 'tool.title.search': 'Поиск', + 'tool.title.read': 'Читать', + 'tool.title.bash': 'Баш', + 'tool.title.write': 'Написать', + 'tool.title.edit': 'Редактировать', + 'tool.title.code': 'Код', + 'tool.title.generic': 'Вызов инструмента', + 'tool.title.inspect': 'Запрос среды Cordis', + 'tool.title.runCordis': 'Запустите плагин Cordis', + 'tool.title.stopCordis': 'Остановить плагин Cordis', + 'tool.title.removeCordis': 'Удалить плагин Cordis', + 'tool.title.pwsh': 'Пшш', + 'tool.title.readImage': 'Читать изображение', + 'tool.title.grep': 'Греп', + 'tool.title.glob': 'Глоб', + 'tool.title.webSearch': 'Поиск', + 'tool.title.webFetch': 'Получить', + 'tool.autoReviewRejected': 'Отклонено Auto review', + 'tool.autoReviewNotExecuted': 'Инструмент не был выполнен. Причина: {reason}', + 'tool.autoReviewReasonFallback': 'Auto review не санкционировал это действие', + 'diff.collapseAria': 'Свернуть разницу', + 'diff.expandAria': 'Разверните {count} больше строк различий', + 'diff.expandRest': '… {count} еще строки', + 'read.window': 'Показаны линии {shown} {total}.', + 'read.collapseAria': 'Свернуть содержимое', + 'read.expandAria': 'Разверните {count} еще строки', + 'read.expandRest': '… {count} еще строки', + 'search.paths': '{shown} пути', + 'search.paths.truncated': 'Отображение путей {shown} из {total}', + 'search.matches': '{shown} соответствует · файлам {files}', + 'search.matches.truncated': 'Отображение {shown} совпадений {total} · Файлы {files}', + 'search.noResults': 'Нет результатов', + 'search.collapseAria': 'Свернуть результаты', + 'search.expandAria': 'Разверните {count} больше строк результатов', + 'search.expandRest': '… {count} еще строки', + 'web.noResults': 'Результаты не найдены', + 'web.sourcesTruncated': 'Список источников сокращен', + 'web.http': 'HTTP', + 'web.contentTruncated': 'Содержание усечено', + 'details.running': 'Бег…', + 'queue.count': 'Сообщения в очереди {n}', + 'queue.sending': 'Отправка…', + 'queue.image': 'Изображение сообщения в очереди', + 'queue.file': 'Файл в очереди {name}', + 'queue.edit': 'Изменить сообщение в очереди', + 'queue.edit.unsupported': 'Содержит нетекстовый контент; редактирование пока не поддерживается', + 'queue.save': 'Сохранить сообщение в очереди', + 'queue.cancelEdit': 'Отменить редактирование', + 'queue.remove': 'Удалить сообщение из очереди', + 'queue.steer': 'Управление сообщением в очереди', + 'queue.steer.unavailable': 'Управление доступно только во время работы агента.', + 'error.sessionInUse': 'Этот сеанс уже используется, возможно, другим работающим экземпляром DSH (например, веб-сайтом dsh или настольным приложением). Закройте другие работающие экземпляры DSH и повторите попытку.', + 'queue.editFailed': 'Не удалось изменить: возможно, это сообщение уже начало отправляться.', + 'queue.removeFailed': 'Удаление не удалось: возможно, это сообщение уже начало отправляться.', + 'queue.steerFailed': 'Рулевое управление не удалось. Попробуйте еще раз.', + 'terminal.signal': 'сигнал {signal}', + 'terminal.exitCode': 'код выхода {code}', + 'terminal.noExitCode': 'нет кода выхода', + 'terminal.commandLine': 'Командная строка {n}', + 'terminal.running': 'Бег', + 'terminal.failed': 'Не удалось', + 'terminal.done': 'Готово', + 'terminal.noOutput': 'Нет вывода', + 'terminal.collapseAria': 'Свернуть вывод', + 'terminal.expandAria': 'Разверните оставшиеся выходные строки {n}.', + 'terminal.expandRest': '… {n} еще строки', + // The Host terminal_send presenter has no locale seat; keep its fallbacks + // aligned with these English values. + 'terminal.sendInput': '(отправить ввод)', + 'terminal.session': 'Терминал {sessionId}', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'quote.remove': 'Remover cotação', + 'shortcut.newline': 'Nova linha', + 'shortcut.complementary': 'Use a ação complementar Queue / Steer', + 'shortcut.slash': 'Abrir menu de comando', + 'shortcut.mention': 'Abrir menu de referência', + 'hint.plan': PLAN_NEXT_ACTION_EN, + 'hint.goal': 'descrever o objetivo de uma tarefa de longa duração', + 'hint.goal.active': 'meta ativa — editar/pausar/resumir/limpar', + 'placeholder.plan': PLAN_NEXT_ACTION_EN, + 'placeholder.default': 'Envie mensagens ou execute uma tarefa, / comandos, @ arquivos ou sessões', + 'placeholder.unavailable': 'Sessão indisponível', + 'placeholder.parentOffline': 'Sessão pai offline; o envio não está disponível, mas você ainda pode interromper a execução', + 'placeholder.hero': 'Descreva o que você deseja construir, / comandos, @ arquivos ou sessões', + 'placeholder.workspace': 'Escolha um espaço de trabalho para começar', + 'placeholder.steerQueue': 'Cmd/Ctrl+Enter direciona todas as mensagens na fila', + 'input.commands': 'Adicione arquivos ou execute comandos', + 'input.file': 'Arquivo', + 'input.stop': 'Pare de gerar', + 'input.send': 'Enviar mensagem', + 'input.send.queue': 'Mensagem de fila', + 'input.send.steer': 'Mensagem de orientação', + 'attachment.pending': 'Anexos pendentes', + 'attachment.scrollLeft': 'Rolar anexos para a esquerda', + 'attachment.scrollRight': 'Rolar os anexos para a direita', + 'attachment.dropTitle': 'Arraste arquivos ou imagens aqui para adicioná-los', + 'attachment.dropDesc': 'Limite de imagens: até {count} imagens, {size} cada', + 'attachment.dropBlocked': 'Arquivos e imagens não podem ser adicionados no momento', + 'attachment.directoryDesktopOnly': 'As pastas só podem ser adicionadas no aplicativo de desktop; adicione arquivos individuais no navegador', + 'attachment.pathUnavailable': 'Não foi possível obter o caminho da pasta; arraste-o novamente', + 'attachment.pathUnsupported': 'O caminho contém caracteres que uma referência não pode transportar; renomeie-o e tente novamente', + 'image.pending': 'Imagens pendentes', + 'image.openOriginal': 'Ver original', + 'image.openOriginalLabel': '{label}, clique para ver o original', + 'image.remove': 'Remover imagem {name}', + 'image.original': 'Imagem original', + 'image.label': 'Imagem', + 'image.loadFailed': 'A imagem não foi carregada; clique para tentar novamente', + 'image.loading': 'Carregando imagem…', + 'image.preview': 'Visualização da imagem original', + 'image.closePreview': 'Fechar visualização da imagem original', + 'image.unsupportedType': 'Somente imagens PNG, JPG, WebP e GIF são suportadas', + 'image.tooMany': 'Uma mensagem pode incluir até {count} imagens', + 'image.fileTooLarge': 'Cada imagem deve ser menor que {size}', + 'image.totalTooLarge': 'As imagens excedem {size} no total; remova alguns e tente novamente', + 'image.tooManyPixels': 'A resolução da imagem é muito alta; comprima e tente novamente', + 'image.dimensionTooLarge': 'Os lados da imagem devem ter no máximo {size}px; diminua a escala e tente novamente', + 'image.modelUnsupported': 'O modelo atual não suporta imagens; mude para um modelo que faça', + 'image.sendFailed': 'Falha no envio de imagens ({reason}); adicione-os novamente e tente novamente', + 'file.pending': 'Arquivos pendentes', + 'file.remove': 'Remover arquivo {name}', + 'file.uploading': 'Fazendo upload…', + 'file.uploadFailed': 'Falha no upload; clique para tentar novamente', + 'file.retry': 'Tente fazer upload novamente {name}', + 'file.stillUploading': 'Os arquivos ainda estão sendo carregados; enviar depois que terminarem', + 'file.sessionUnavailable': 'Sessão indisponível; os arquivos não podem ser carregados', + 'file.notStaged': 'O upload do arquivo não foi concluído; adicione novamente e tente novamente', + 'file.label': 'Arquivo', + 'context.aria': '{percent} de contexto usado', + 'context.used': 'do contexto usado', + 'context.system': 'Alerta do sistema', + 'context.tools': 'Definições de ferramentas', + 'context.messages': 'Mensagens', + 'settings.enter.title': 'Enviar comportamento enquanto estiver ocupado', + 'settings.enter.description': 'O que o botão Enter e o botão Enviar fazem enquanto o agente está em execução; Cmd/Ctrl+Enter usa o outro comportamento', + 'settings.enter.queue': 'Fila', + 'settings.enter.steer': 'Dirigir', + 'hero.headline': 'Para o desconhecido', + 'hero.preview': 'Visualização', + 'hero.chooseWorkspace': 'Escolha o espaço de trabalho', + 'session.hierarchy': 'Hierarquia de sessão', + 'session.moreViews': 'Mais visualizações de conversas', + 'todo.title': 'Tarefas', + 'todo.progress.done': '{done} concluído', + 'todo.progress.active': '{active} em andamento', + 'todo.progress.pending': '{pending} pendente', + 'todo.status.completed': 'Concluído', + 'todo.status.inProgress': 'Em andamento', + 'todo.status.pending': 'Pendente', + 'todo.rowTitle': 'Atualizar lista de tarefas', + 'tool.title.createGoal': 'Criar meta', + 'tool.title.getGoal': 'Ver meta', + 'tool.title.updateGoal': 'Atualizar meta', + 'tool.preparing.content': '{kilobytes}KB', + 'tool.title.createSchedule': 'Criar lembrete', + 'tool.title.listSchedules': 'Listar lembretes', + 'tool.title.deleteSchedule': 'Excluir lembrete', + 'tool.title.updateSchedule': 'Lembrete de atualização', + 'detail.state': 'Estado', + 'detail.todo.completed': 'Concluído', + 'detail.todo.in_progress': 'Em andamento', + 'detail.todo.pending': 'Pendente', + 'detail.todo.empty': 'A lista de tarefas está vazia', + 'todo.diff.initial': 'Lista inicial', + 'todo.diff.compare': 'Mudanças desde a lista anterior', + 'todo.diff.unavailable': 'Lista anterior indisponível', + 'todo.diff.noChanges': 'Sem alterações na lista', + 'todo.diff.added': '{count} adicionado', + 'todo.diff.updated': '{count} atualizado', + 'todo.diff.removed': '{count} removido', + 'todo.diff.unchanged': '{count} inalterado', + 'todo.diff.addedItem': 'Adicionado', + 'todo.diff.updatedItem': 'Status alterado', + 'todo.diff.movedItem': 'Reordenado', + 'todo.diff.removedItem': 'Removido', + 'detail.goal.empty': 'Sem objetivo', + 'detail.goal.active': 'Ativo', + 'detail.goal.disarmed': 'Aguardando continuação', + 'detail.goal.paused': 'Pausado', + 'detail.goal.blocked': 'Bloqueado', + 'detail.goal.complete': 'Concluído', + 'detail.goal.rounds': 'Rodadas', + 'detail.goal.reason': 'Bloqueador', + 'detail.days': '{count}d', + 'detail.hours': '{count}h', + 'detail.minutes': '{count} min', + 'detail.seconds': '{count} segundos', + 'detail.schedule.once': 'Uma vez', + 'detail.schedule.every': 'A cada {interval}', + 'detail.schedule.when': 'Agendado para', + 'detail.schedule.frequency': 'Repetir', + 'detail.schedule.scheduled': 'Agendado', + 'detail.schedule.overdue': 'Atrasado, aguardando retomada da sessão', + 'detail.schedule.empty': 'Sem lembretes', + 'detail.schedule.deleted': 'Excluído', + 'detail.schedule.count': '{count} lembretes', + 'detail.schedule.daily': 'Todos os dias às {time} ({zone})', + 'detail.schedule.weekly': 'Semanalmente em {days} às {time} ({zone})', + 'detail.schedule.cron': 'Cron {expression} ({zone})', + 'detail.weekday.1': 'segunda-feira', + 'detail.weekday.2': 'Terça', + 'detail.weekday.3': 'Quarta', + 'detail.weekday.4': 'Qui', + 'detail.weekday.5': 'Sexta-feira', + 'detail.weekday.6': 'Sábado', + 'detail.weekday.7': 'Sol', + 'detail.weekday.join': ', ', + 'tool.title.inspectProviders': 'Inspecionar fornecedores', + 'tool.title.queryRuntime': 'Tempo de execução da consulta', + 'tool.title.inspectPlugins': 'Inspecionar plug-ins', + 'tool.title.workflow': 'Executar fluxo de trabalho', + 'tool.title.ralph': 'Execute o circuito Ralph', + 'tool.title.readEvent': 'Ler evento', + 'tool.title.searchEvents': 'Pesquisar eventos', + 'tool.title.traceEvent': 'Evento de rastreamento', + 'tool.title.searchSessions': 'Sessões de pesquisa', + 'tool.title.traceSession': 'Sessão de rastreamento', + 'tool.title.listModels': 'Listar modelos', + 'tool.title.subagent': 'Criar subagente', + 'tool.title.listAgents': 'Listar subagentes', + 'tool.title.sendMessage': 'Enviar mensagem', + 'tool.title.interruptAgent': 'Agente de interrupção', + 'tool.title.listJobs': 'Listar trabalhos em segundo plano', + 'tool.title.readJob': 'Ler saída do trabalho', + 'tool.title.killJob': 'Cancelar trabalho em segundo plano', + 'tool.title.openTerminal': 'Terminal aberto', + 'tool.title.readTerminal': 'Ler terminal', + 'tool.title.listTerminals': 'Listar terminais', + 'tool.title.signalTerminal': 'Terminal de sinal', + 'tool.title.closeTerminal': 'Fechar terminal', + 'tool.title.lsp': 'Símbolos de código de consulta', + 'tool.title.findDefinition': 'Encontre a definição', + 'tool.title.findReferences': 'Encontre referências', + 'tool.title.findImplementation': 'Encontre implementação', + 'tool.title.hoverSymbol': 'Símbolo de inspeção', + 'tool.title.spawnTeammate': 'Criar companheiro de equipe', + 'tool.title.createTeamTask': 'Criar tarefa de equipe', + 'tool.title.getTeamTask': 'Ler tarefa da equipe', + 'tool.title.updateTeamTask': 'Atualizar tarefa da equipe', + 'tool.title.listTeamTasks': 'Listar tarefas da equipe', + 'tool.title.waitAgent': 'Aguarde o subagente', + 'detail.recordedResult': 'Resultado registrado', + 'detail.empty': 'Nenhum resultado', + 'detail.none': 'Nenhum', + 'detail.yes': 'Sim', + 'detail.no': 'Não', + 'detail.moreInInspect': 'Mais {count} itens disponíveis no Inspecionar', + 'detail.status.running': 'Correndo', + 'detail.status.idle': 'Inativo', + 'detail.status.ready': 'Pronto', + 'detail.status.inactive': 'Inativo', + 'detail.status.provisioning': 'Provisionamento', + 'detail.status.failed': 'Falha', + 'detail.status.completed': 'Concluído', + 'detail.status.deleted': 'Excluído', + 'detail.status.killed': 'Cancelado', + 'detail.status.accepted': 'Aceito', + 'detail.status.queued': 'Na fila', + 'detail.status.exited': 'Saiu', + 'detail.field.id': 'ID', + 'detail.field.revision': 'Revisão', + 'detail.field.platform': 'Plataforma', + 'detail.field.provider': 'Provedor', + 'detail.field.model': 'Modelo', + 'detail.field.role': 'Função', + 'detail.field.context': 'Contexto', + 'detail.field.owner': 'Proprietário', + 'detail.field.ready': 'Pronto', + 'detail.field.dependencies': 'Dependências', + 'detail.field.writeScopes': 'Escrever escopos', + 'detail.field.warnings': 'Avisos', + 'detail.field.diagnostics': 'Diagnóstico', + 'detail.field.methods': 'Métodos', + 'detail.field.inputSchema': 'Esquema de entrada', + 'detail.field.outputSchema': 'Esquema de saída', + 'detail.field.currentPackage': 'Pacote atual', + 'detail.field.nextPackage': 'Próximo pacote', + 'detail.field.latestRun': 'Última execução', + 'detail.field.packages': 'Pacotes', + 'detail.field.registrations': 'Inscrições', + 'detail.field.props': 'Adereços', + 'detail.field.data': 'Dados', + 'detail.field.source': 'Fonte', + 'detail.field.content': 'Conteúdo', + 'detail.field.message': 'Mensagem', + 'detail.field.messageId': 'ID da mensagem', + 'detail.field.root': 'Raiz', + 'detail.field.pid': 'ID do processo', + 'detail.field.type': 'Tipo', + 'detail.field.time': 'Hora', + 'detail.field.seq': 'Sequência de eventos', + 'detail.field.turn': 'Turno', + 'detail.field.step': 'Passo', + 'detail.field.callId': 'ID de chamada', + 'detail.field.agents': 'Agentes iniciados', + 'detail.field.result': 'Resultado', + 'detail.field.parent': 'Pai', + 'detail.field.depth': 'Profundidade', + 'detail.field.exitCode': 'Código de saída', + 'detail.field.signal': 'Sinal', + 'detail.field.previousStatus': 'Estado anterior', + 'detail.field.agent': 'ID do agente', + 'detail.field.job': 'ID do trabalho', + 'detail.field.task': 'Tarefa', + 'detail.field.processGroup': 'Grupo de processos', + 'detail.field.availability': 'Disponibilidade', + 'detail.field.bestMatch': 'Melhor correspondência', + 'detail.field.target': 'Evento alvo', + 'detail.field.surface': 'Status do registro', + 'detail.agents.count': '{count} agentes', + 'detail.jobs.count': '{count} trabalhos em segundo plano', + 'detail.terminals.count': '{count} terminais', + 'detail.tasks.count': '{count} tarefas de equipe', + 'detail.tasks.nextPage': 'Mais tarefas disponíveis; o próximo cursor é {cursor}', + 'detail.locations.count': '{count} locais', + 'detail.location': 'Linha {line}, coluna {column}', + 'detail.receipt.delivered': 'Mensagem entregue', + 'detail.receipt.interrupt': 'Interrupção solicitada', + 'detail.receipt.started': 'Iniciado', + 'detail.receipt.cancel': 'Cancelamento solicitado', + 'detail.receipt.alreadyFinished': 'Já terminei', + 'detail.receipt.signal': 'Sinal entregue', + 'detail.receipt.closed': 'Fechado', + 'detail.receipt.closing': 'Fechando', + 'detail.wait.noProgress': 'Nenhum subagente ativo', + 'detail.wait.title': 'Atividade do subagente', + 'detail.wait.timeout': 'A espera expirou', + 'detail.wait.changed': 'Alteração detectada', + 'detail.agent.reply': 'Resposta do agente', + 'detail.models.title': 'Modelos disponíveis', + 'detail.output.lines': 'Linhas {begin}–{end} de {total}', + 'detail.output.truncated': 'Saída truncada', + 'detail.providers.count': '{count} inspecionar provedores', + 'detail.plugins.count': '{count} plug-ins dinâmicos', + 'detail.workflow.script': 'Roteiro de fluxo de trabalho', + 'detail.ralph.reportedComplete': 'Conclusão relatada pelo trabalhador', + 'detail.ralph.reportedBlocker': 'Trabalhador relatou um bloqueador', + 'detail.ralph.limit': 'Limite de rodadas atingido', + 'detail.report.nextSteps': 'Trabalho restante', + 'detail.trace.replacedBy': 'Substituído por', + 'detail.trace.replacementChain': 'Cadeia de substituição', + 'detail.trace.replaces': 'Eventos substituídos', + 'detail.trace.sources': 'Eventos de origem', + 'detail.trace.derived': 'Eventos derivados', + 'detail.trace.ancestors': 'Sessões ancestrais', + 'detail.trace.descendants': 'Sessões de descendentes', + 'detail.matches.count': '{count} correspondências', + 'detail.matches.capped': 'Limite de resultados atingido; restringir a busca por mais', + 'detail.event.neighbors': 'Eventos circundantes', + 'todo.completed': '{done}/{total} concluído', + 'command.attachmentsUnsupported': '/{command} não aceita anexos; remova-os primeiro', + 'ask.rowTitle': 'Faça uma pergunta', + 'ask.waiting': 'esperando', + 'ask.pending': 'continuou; resposta ainda disponível', + 'ask.pendingDetail': 'Essas questões pendentes permanecem respondidas pelo compositor.', + 'ask.reopen': 'Resposta', + 'ask.review': 'Ver respostas', + 'ask.closed': 'fechado', + 'ask.closedDetail': 'Esta questão está encerrada; seu resultado está na conversa abaixo.', + 'ask.cancelled': 'cancelado', + 'ask.cancelledDetail': 'Este conjunto de perguntas foi cancelado antes do envio das respostas.', + 'ask.interrupted': 'interrompido', + 'ask.interruptedDetail': 'Este conjunto de perguntas foi interrompido antes do envio das respostas.', + 'ask.answered': '{answered}/{total} respondeu', + 'ask.skipped': 'Não respondido', + 'bash.running': 'Correndo', + 'bash.failed': 'Falha', + 'bash.stopped': 'Parado', + 'row.running': 'Correndo', + 'row.preparing': 'Preparando chamada de ferramenta', + 'row.failed': 'Falha', + 'row.stopped': 'Parado', + 'row.commandArguments': 'Argumentos de comando', + 'row.input': 'IN', + 'row.output': 'OUT', + 'row.inspect': 'Inspecionar', + 'row.imageSize': '{width}x{height}px, {bytes} bytes', + 'row.imageSizeDownscaled': '{width}x{height}px (reduzido de {originalWidth}x{originalHeight}px), {bytes} bytes', + 'tool.title.search': 'Pesquisar', + 'tool.title.read': 'Leia', + 'tool.title.bash': 'Bash', + 'tool.title.write': 'Escreva', + 'tool.title.edit': 'Editar', + 'tool.title.code': 'Código', + 'tool.title.generic': 'Chamada de ferramenta', + 'tool.title.inspect': 'Consultar ambiente Cordis', + 'tool.title.runCordis': 'Execute o plug-in Cordis', + 'tool.title.stopCordis': 'Parar o plug-in Cordis', + 'tool.title.removeCordis': 'Remover plug-in Cordis', + 'tool.title.pwsh': 'Pwsh', + 'tool.title.readImage': 'Ler imagem', + 'tool.title.grep': 'Grep', + 'tool.title.glob': 'globo', + 'tool.title.webSearch': 'Pesquisar', + 'tool.title.webFetch': 'Buscar', + 'tool.autoReviewRejected': 'Rejeitado por Auto review', + 'tool.autoReviewNotExecuted': 'A ferramenta não foi executada. Motivo: {reason}', + 'tool.autoReviewReasonFallback': 'Auto review não autorizou esta ação', + 'diff.collapseAria': 'Recolher diferença', + 'diff.expandAria': 'Expanda mais {count} linhas de diferenças', + 'diff.expandRest': '… mais {count} linhas', + 'read.window': 'Mostrando {shown} de {total} linhas', + 'read.collapseAria': 'Recolher conteúdo', + 'read.expandAria': 'Expanda mais {count} linhas', + 'read.expandRest': '… mais {count} linhas', + 'search.paths': '{shown} caminhos', + 'search.paths.truncated': 'Mostrando {shown} de {total} caminhos', + 'search.matches': '{shown} correspondências · {files} arquivos', + 'search.matches.truncated': 'Mostrando {shown} de {total} correspondências · {files} arquivos', + 'search.noResults': 'Nenhum resultado', + 'search.collapseAria': 'Recolher resultados', + 'search.expandAria': 'Expanda mais {count} linhas de resultados', + 'search.expandRest': '… mais {count} linhas', + 'web.noResults': 'Nenhum resultado encontrado', + 'web.sourcesTruncated': 'Lista de fontes truncada', + 'web.http': 'HTTP', + 'web.contentTruncated': 'Conteúdo truncado', + 'details.running': 'Correndo…', + 'queue.count': '{n} mensagens na fila', + 'queue.sending': 'Enviando…', + 'queue.image': 'Imagem de mensagem na fila', + 'queue.file': 'Arquivo na fila {name}', + 'queue.edit': 'Editar mensagem na fila', + 'queue.edit.unsupported': 'Contém conteúdo não textual; a edição ainda não é suportada', + 'queue.save': 'Salvar mensagem na fila', + 'queue.cancelEdit': 'Cancelar edição', + 'queue.remove': 'Remover mensagem na fila', + 'queue.steer': 'Orientar mensagem na fila', + 'queue.steer.unavailable': 'A direção está disponível apenas enquanto o agente está em execução', + 'error.sessionInUse': 'Esta sessão já está em uso, possivelmente por outra instância DSH em execução (como dsh web ou aplicativo de desktop). Saia de outras instâncias DSH em execução e tente novamente.', + 'queue.editFailed': 'Falha na edição: esta mensagem pode já ter começado a ser enviada.', + 'queue.removeFailed': 'Falha na remoção: esta mensagem pode já ter começado a ser enviada.', + 'queue.steerFailed': 'A direção falhou. Tente novamente.', + 'terminal.signal': 'sinal {signal}', + 'terminal.exitCode': 'código de saída {code}', + 'terminal.noExitCode': 'sem código de saída', + 'terminal.commandLine': 'Linha de comando {n}', + 'terminal.running': 'Correndo', + 'terminal.failed': 'Falha', + 'terminal.done': 'Concluído', + 'terminal.noOutput': 'Sem saída', + 'terminal.collapseAria': 'Recolher saída', + 'terminal.expandAria': 'Expanda as {n} linhas de saída restantes', + 'terminal.expandRest': '… mais {n} linhas', + // The Host terminal_send presenter has no locale seat; keep its fallbacks + // aligned with these English values. + 'terminal.sendInput': '(enviar entrada)', + 'terminal.session': 'Terminal {sessionId}', +} satisfies Record diff --git a/packages/client/ui-deepseek-model-label-1017/locale/de.json b/packages/client/ui-deepseek-model-label-1017/locale/de.json new file mode 100644 index 0000000000..97f572f313 --- /dev/null +++ b/packages/client/ui-deepseek-model-label-1017/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek 1017 Modellplakette", + "description": "Fügen Sie den offiziellen DeepSeek Flash-Modellnamen ein temporäres 1017-Release-Abzeichen hinzu." + } +} diff --git a/packages/client/ui-deepseek-model-label-1017/locale/es.json b/packages/client/ui-deepseek-model-label-1017/locale/es.json new file mode 100644 index 0000000000..39db24f093 --- /dev/null +++ b/packages/client/ui-deepseek-model-label-1017/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Insignia del modelo DeepSeek 1017", + "description": "Agregue una insignia de lanzamiento temporal 1017 a los nombres oficiales de los modelos Flash DeepSeek." + } +} diff --git a/packages/client/ui-deepseek-model-label-1017/locale/fr.json b/packages/client/ui-deepseek-model-label-1017/locale/fr.json new file mode 100644 index 0000000000..a0d47622b6 --- /dev/null +++ b/packages/client/ui-deepseek-model-label-1017/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Badge modèle DeepSeek 1017", + "description": "Ajoutez un badge de version 1017 temporaire aux noms de modèles Flash DeepSeek officiels." + } +} diff --git a/packages/client/ui-deepseek-model-label-1017/locale/pt.json b/packages/client/ui-deepseek-model-label-1017/locale/pt.json new file mode 100644 index 0000000000..10be9f4c03 --- /dev/null +++ b/packages/client/ui-deepseek-model-label-1017/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek selo do modelo 1017", + "description": "Adicione um selo de versão temporário 1017 aos nomes oficiais dos modelos do DeepSeek Flash." + } +} diff --git a/packages/client/ui-deepseek-model-label-1017/locale/ru.json b/packages/client/ui-deepseek-model-label-1017/locale/ru.json new file mode 100644 index 0000000000..1d116a03be --- /dev/null +++ b/packages/client/ui-deepseek-model-label-1017/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Значок модели 1017", + "description": "Добавьте временный значок выпуска 1017 к официальным названиям моделей Flash DeepSeek." + } +} diff --git a/packages/client/ui-deepseek-model-label-1017/src/client/index.ts b/packages/client/ui-deepseek-model-label-1017/src/client/index.ts index 5a38858688..7e35d4e14c 100644 --- a/packages/client/ui-deepseek-model-label-1017/src/client/index.ts +++ b/packages/client/ui-deepseek-model-label-1017/src/client/index.ts @@ -4,7 +4,7 @@ import type {} from '@deepseek-ai/dsh-client-locale/client' import type {} from '@deepseek-ai/dsh-client-ui-model-selection/client' import type {} from '@deepseek-ai/dsh-client-ui-renderer/client' import { DeepSeekModelLabel } from './DeepSeekModelLabel.tsx' -import { en, ja, zh, type LabelKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh, type LabelKey } from './locales.ts' declare module '@deepseek-ai/dsh-client-ui-slots' { interface LocaleNamespaceMap { @@ -22,7 +22,7 @@ export const inject = ['slots', 'locale'] */ export function apply(ctx: Context): void { const namespace = 'deepseek-model-label-1017' - ctx.effect(() => ctx.locale.register(namespace, { zh, en, ja }), 'deepseek-model-label-1017: dictionaries') + ctx.effect(() => ctx.locale.register(namespace, { zh, en, ja, es, fr, de, ru, pt }), 'deepseek-model-label-1017: dictionaries') ctx.slots.inject('conversation.input.model.label', () => ctx.slots.register({ name: 'conversation.input.model.label', locale: namespace, }, DeepSeekModelLabel)) diff --git a/packages/client/ui-deepseek-model-label-1017/src/client/locales.ts b/packages/client/ui-deepseek-model-label-1017/src/client/locales.ts index 95ca2cb796..d23df8c829 100644 --- a/packages/client/ui-deepseek-model-label-1017/src/client/locales.ts +++ b/packages/client/ui-deepseek-model-label-1017/src/client/locales.ts @@ -13,3 +13,18 @@ export const en: Record = { 'badge.label': '1017' } export const ja = { 'badge.label': '1017', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { 'badge.label': '1017' } satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { 'badge.label': '1017' } satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { 'badge.label': '1017' } satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { 'badge.label': '1017' } satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { 'badge.label': '1017' } satisfies Record diff --git a/packages/client/ui-deliverables/locale/de.json b/packages/client/ui-deliverables/locale/de.json new file mode 100644 index 0000000000..a87831a167 --- /dev/null +++ b/packages/client/ui-deliverables/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Dokumentänderungen und Lieferpräsentation", + "description": "Anzeige geänderter Dateien, Inhaltsvergleich und Eingabe der Lieferdatei." + } +} diff --git a/packages/client/ui-deliverables/locale/es.json b/packages/client/ui-deliverables/locale/es.json new file mode 100644 index 0000000000..930c363d05 --- /dev/null +++ b/packages/client/ui-deliverables/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Cambios de documentos y presentación de entrega.", + "description": "Muestra archivos modificados, comparación de contenido y entrada de archivos de entrega." + } +} diff --git a/packages/client/ui-deliverables/locale/fr.json b/packages/client/ui-deliverables/locale/fr.json new file mode 100644 index 0000000000..965bcb788d --- /dev/null +++ b/packages/client/ui-deliverables/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Modifications du document et présentation de la livraison", + "description": "Afficher les fichiers modifiés, la comparaison du contenu et la saisie du fichier de livraison." + } +} diff --git a/packages/client/ui-deliverables/locale/pt.json b/packages/client/ui-deliverables/locale/pt.json new file mode 100644 index 0000000000..caef83a2ab --- /dev/null +++ b/packages/client/ui-deliverables/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Alterações de documentos e apresentação de entrega", + "description": "Exibir arquivos modificados, comparação de conteúdo e entrada de arquivo de entrega." + } +} diff --git a/packages/client/ui-deliverables/locale/ru.json b/packages/client/ui-deliverables/locale/ru.json new file mode 100644 index 0000000000..b940a1eba1 --- /dev/null +++ b/packages/client/ui-deliverables/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Изменения документов и представление поставки", + "description": "Отображение измененных файлов, сравнение содержимого и запись файла доставки." + } +} diff --git a/packages/client/ui-deliverables/src/client/index.ts b/packages/client/ui-deliverables/src/client/index.ts index ef5bc4b06d..5750f585f3 100644 --- a/packages/client/ui-deliverables/src/client/index.ts +++ b/packages/client/ui-deliverables/src/client/index.ts @@ -27,7 +27,7 @@ import { DeliverablesTail, type DeliverablesInjected } from './Deliverables.tsx' import { ReviewTab, type ReviewInjected } from './ReviewTab.tsx' import { CHANGES_REVIEW_ID, changesReviewDefinition } from './review-definition.ts' import { createReviewStore } from './review-store.ts' -import { en, ja, NS, zh, type DeliverablesKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, NS, zh, type DeliverablesKey } from './locales.ts' import { deliverablesDefinition, presentedForClosing, producedFileMentions, selectProducedFiles, } from './turn-deliverables.ts' @@ -57,7 +57,7 @@ export function apply(ctx: ClientContext): void { diffs.reset() }) ctx.uiConversation.events.register(deliverablesDefinition) - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-deliverables: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-deliverables: dictionaries') ctx.slots.inject( 'conversation.chat.turnTail', () => ctx.slots.register({ diff --git a/packages/client/ui-deliverables/src/client/locales.ts b/packages/client/ui-deliverables/src/client/locales.ts index d5c67949ca..e25cc96c43 100644 --- a/packages/client/ui-deliverables/src/client/locales.ts +++ b/packages/client/ui-deliverables/src/client/locales.ts @@ -197,3 +197,323 @@ export const ja = { 'diff.coarse': '行比較がタイムアウトしたため、ファイル全体の置換として表示しています', 'diff.truncated': '最初の{count}行を表示', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'presented.nativeUnavailable': 'Este archivo no tiene una ruta de host disponible. Vista previa en la barra lateral.', + 'presented.revealError': 'No se pudo mostrar en el administrador de archivos. Intentar otra vez.', + 'presented.directoryError': 'No se pudo abrir la carpeta que lo contiene. Intentar otra vez.', + 'presented.directoryOpening': 'Abriendo la carpeta que contiene...', + 'presented.directoryOpened': 'Apertura solicitada que contiene la carpeta', + 'presented.revealed': 'Visualización solicitada en el administrador de archivos.', + 'presented.revealing': 'Mostrando en el administrador de archivos…', + 'presented.unavailable': 'Este Host no tiene un escritorio disponible para abrir archivos o carpetas en aplicaciones externas. Los archivos aún se pueden obtener una vista previa en la barra lateral.', + 'presented.retry': 'Reintentar', + 'presented.hostError': 'No se pudo leer la información del escritorio del host', + 'presented.preview': 'Vista previa en la barra lateral', + 'presented.previewButton': 'Abra {name} en la barra lateral', + 'presented.previewCard': 'Vista previa de {name} en la barra lateral', + 'presented.all': 'Todos los archivos {count}', + 'presented.expandAria': 'Mostrar todos los archivos entregados {count}', + 'presented.collapse': 'Contraer', + 'presented.collapseAria': 'Contraer archivos entregados', + 'presented.opening': 'Abriendo…', + 'presented.opened': 'Abierto solicitado', + 'presented.error': 'No se pudo abrir. Haga clic para volver a intentarlo.', + 'presented.file': 'Archivo', + 'row.title': 'Presentar archivos', + 'row.running': 'Entregando', + 'row.preparing': 'Preparando entregables', + 'row.ok': 'Entregado', + 'row.error': 'Entrega fallida', + 'row.stopped': 'interrumpido', + 'row.inspect': 'inspeccionar llamada', + 'changes.title': 'Archivos {count} editados', + 'changes.singleTitle': 'Editado {name}', + 'changes.added': '+{count}', + 'changes.deleted': '-{count}', + 'changes.binary': 'binario', + 'changes.openReview': 'Revisa los cambios de este turno en la barra lateral.', + 'changes.all': 'Todos los archivos {count}', + 'changes.expandAria': 'Mostrar todos los archivos modificados {count}', + 'changes.collapse': 'Contraer', + 'changes.collapseAria': 'Contraer archivos modificados', + 'changes.oversized': 'demasiado grande', + 'changes.viewDiff': 'Ver cambios en {name}', + 'review.title': 'Revisión · turno {turn}', + 'review.selectFile': 'Elija el archivo para revisar', + 'review.split': 'Cambiar a vista dividida', + 'review.unified': 'Cambiar a vista unificada', + 'review.splitAria': 'Vista dividida', + 'review.wrap': 'Habilitar ajuste de línea', + 'review.nowrap': 'Desactivar ajuste de línea', + 'review.wrapAria': 'Ajuste de línea', + 'review.openFile': 'Abra el archivo completo en la barra lateral.', + 'review.openFileAria': 'Abra {name} en la barra lateral', + 'diff.loading': 'Cambios de lectura…', + 'diff.missing': 'El contenido de los cambios de este turno ya no está disponible.', + 'diff.error': 'No se pudieron leer los cambios.', + 'diff.binary': 'Archivo binario; los cambios no se pueden mostrar', + 'diff.oversized': 'Archivo demasiado grande; los cambios no se pueden mostrar', + 'diff.created': 'Creado en este turno', + 'diff.deleted': 'Eliminado en este turno', + 'diff.unchanged': 'Ambos lados mantienen las mismas líneas.', + 'diff.coarse': 'Se agotó el tiempo de espera para la comparación de líneas; se muestra como un reemplazo de archivo completo', + 'diff.truncated': 'Mostrando las primeras líneas {count}', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'presented.nativeUnavailable': "Ce fichier n'a pas de chemin d'hôte disponible. Prévisualisez-le dans la barre latérale.", + 'presented.revealError': "Impossible d'afficher dans le gestionnaire de fichiers. Essayer à nouveau.", + 'presented.directoryError': "Impossible d'ouvrir le dossier contenant. Essayer à nouveau.", + 'presented.directoryOpening': 'Ouverture du dossier contenant…', + 'presented.directoryOpened': 'Ouverture demandée contenant le dossier', + 'presented.revealed': 'Affichage demandé dans le gestionnaire de fichiers', + 'presented.revealing': 'Affichage dans le gestionnaire de fichiers…', + 'presented.unavailable': 'Cet hôte ne dispose pas de bureau disponible pour ouvrir des fichiers ou des dossiers dans des applications externes. Les fichiers peuvent toujours être prévisualisés dans la barre latérale.', + 'presented.retry': 'Réessayer', + 'presented.hostError': 'Impossible de lire les informations du bureau hôte', + 'presented.preview': 'Aperçu dans la barre latérale', + 'presented.previewButton': 'Ouvrir {name} dans la barre latérale', + 'presented.previewCard': 'Aperçu de {name} dans la barre latérale', + 'presented.all': 'Tous les fichiers {count}', + 'presented.expandAria': 'Afficher tous les fichiers livrés {count}', + 'presented.collapse': 'Réduire', + 'presented.collapseAria': 'Réduire les fichiers livrés', + 'presented.opening': 'Ouverture…', + 'presented.opened': 'Ouvert demandé', + 'presented.error': "Impossible d'ouvrir. Cliquez pour réessayer.", + 'presented.file': 'Fichier', + 'row.title': 'Présenter des fichiers', + 'row.running': 'Livrer', + 'row.preparing': 'Préparation des livrables', + 'row.ok': 'Livré', + 'row.error': 'La livraison a échoué', + 'row.stopped': 'Interrompu', + 'row.inspect': "Inspecter l'appel", + 'changes.title': 'Fichiers {count} modifiés', + 'changes.singleTitle': 'Modifié {name}', + 'changes.added': '+{count}', + 'changes.deleted': '-{count}', + 'changes.binary': 'binaire', + 'changes.openReview': 'Consultez les modifications de ce tour dans la barre latérale', + 'changes.all': 'Tous les fichiers {count}', + 'changes.expandAria': 'Afficher tous les fichiers modifiés {count}', + 'changes.collapse': 'Réduire', + 'changes.collapseAria': 'Réduire les fichiers modifiés', + 'changes.oversized': 'trop grand', + 'changes.viewDiff': 'Afficher les modifications apportées à {name}', + 'review.title': 'Révision · tour {turn}', + 'review.selectFile': 'Choisissez le fichier à examiner', + 'review.split': 'Passer à la vue fractionnée', + 'review.unified': 'Passer à la vue unifiée', + 'review.splitAria': 'Vue fractionnée', + 'review.wrap': 'Activer le retour à la ligne', + 'review.nowrap': 'Désactiver le retour à la ligne', + 'review.wrapAria': 'Retour à la ligne', + 'review.openFile': "Ouvrez l'intégralité du fichier dans la barre latérale", + 'review.openFileAria': 'Ouvrir {name} dans la barre latérale', + 'diff.loading': 'La lecture change…', + 'diff.missing': "Le contenu des modifications de ce tour n'est plus disponible", + 'diff.error': 'Impossible de lire les modifications', + 'diff.binary': 'Fichier binaire ; les modifications ne peuvent pas être affichées', + 'diff.oversized': 'Fichier trop volumineux ; les modifications ne peuvent pas être affichées', + 'diff.created': 'Créé à ce tour', + 'diff.deleted': 'Supprimé à ce tour', + 'diff.unchanged': 'Les deux côtés tiennent les mêmes lignes', + 'diff.coarse': "La comparaison de lignes a expiré ; affiché en remplacement de l'ensemble du fichier", + 'diff.truncated': 'Affichage des premières lignes {count}', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'presented.nativeUnavailable': 'Für diese Datei ist kein Hostpfad verfügbar. Sehen Sie sich die Vorschau in der Seitenleiste an.', + 'presented.revealError': 'Konnte im Dateimanager nicht angezeigt werden. Versuchen Sie es erneut.', + 'presented.directoryError': 'Der enthaltende Ordner konnte nicht geöffnet werden. Versuchen Sie es erneut.', + 'presented.directoryOpening': 'Öffnen des enthaltenden Ordners…', + 'presented.directoryOpened': 'Angeforderte Öffnung mit Ordner', + 'presented.revealed': 'Angeforderte Anzeige im Dateimanager', + 'presented.revealing': 'Wird im Dateimanager angezeigt…', + 'presented.unavailable': 'Auf diesem Host steht kein Desktop zum Öffnen von Dateien oder Ordnern in externen Apps zur Verfügung. Dateien können weiterhin in der Seitenleiste in der Vorschau angezeigt werden.', + 'presented.retry': 'Erneut versuchen', + 'presented.hostError': 'Die Host-Desktop-Informationen konnten nicht gelesen werden', + 'presented.preview': 'Vorschau in der Seitenleiste', + 'presented.previewButton': 'Öffnen Sie {name} in der Seitenleiste', + 'presented.previewCard': 'Vorschau von {name} in der Seitenleiste', + 'presented.all': 'Alle {count}-Dateien', + 'presented.expandAria': 'Alle von {count} gelieferten Dateien anzeigen', + 'presented.collapse': 'Einklappen', + 'presented.collapseAria': 'Gelieferte Dateien ausblenden', + 'presented.opening': 'Eröffnung…', + 'presented.opened': 'Öffnung erbeten', + 'presented.error': 'Konnte nicht geöffnet werden. Klicken Sie, um es erneut zu versuchen.', + 'presented.file': 'Datei', + 'row.title': 'Vorhandene Akten', + 'row.running': 'Liefern', + 'row.preparing': 'Vorbereiten von Liefergegenständen', + 'row.ok': 'Geliefert', + 'row.error': 'Die Lieferung ist fehlgeschlagen', + 'row.stopped': 'Unterbrochen', + 'row.inspect': 'Aufruf prüfen', + 'changes.title': 'Bearbeitete {count}-Dateien', + 'changes.singleTitle': 'Bearbeitet {name}', + 'changes.added': '+{count}', + 'changes.deleted': '-{count}', + 'changes.binary': 'binär', + 'changes.openReview': 'Überprüfen Sie die Änderungen dieser Runde in der Seitenleiste', + 'changes.all': 'Alle {count}-Dateien', + 'changes.expandAria': 'Alle von {count} geänderten Dateien anzeigen', + 'changes.collapse': 'Einklappen', + 'changes.collapseAria': 'Geänderte Dateien reduzieren', + 'changes.oversized': 'zu groß', + 'changes.viewDiff': 'Änderungen an {name} anzeigen', + 'review.title': 'Überprüfung · Runde {turn}', + 'review.selectFile': 'Wählen Sie die zu überprüfende Datei aus', + 'review.split': 'Wechseln Sie zur geteilten Ansicht', + 'review.unified': 'Wechseln Sie zur einheitlichen Ansicht', + 'review.splitAria': 'Geteilte Ansicht', + 'review.wrap': 'Zeilenumbruch aktivieren', + 'review.nowrap': 'Zeilenumbruch deaktivieren', + 'review.wrapAria': 'Zeilenumbruch', + 'review.openFile': 'Öffnen Sie die gesamte Datei in der Seitenleiste', + 'review.openFileAria': 'Öffnen Sie {name} in der Seitenleiste', + 'diff.loading': 'Änderungen lesen…', + 'diff.missing': 'Der Inhalt der Änderungen dieser Runde ist nicht mehr verfügbar', + 'diff.error': 'Die Änderungen konnten nicht gelesen werden', + 'diff.binary': 'Binärdatei; Änderungen können nicht angezeigt werden', + 'diff.oversized': 'Datei zu groß; Änderungen können nicht angezeigt werden', + 'diff.created': 'In dieser Runde erstellt', + 'diff.deleted': 'In dieser Runde gelöscht', + 'diff.unchanged': 'Beide Seiten vertreten die gleichen Linien', + 'diff.coarse': 'Zeitüberschreitung beim Leitungsvergleich; wird als vollständige Dateiersetzung angezeigt', + 'diff.truncated': 'Zeigt die ersten {count}-Zeilen', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'presented.nativeUnavailable': 'У этого файла нет доступного пути к хосту. Предварительный просмотр на боковой панели.', + 'presented.revealError': 'Не удалось отобразить в файловом менеджере. Попробуйте еще раз.', + 'presented.directoryError': 'Не удалось открыть содержащую папку. Попробуйте еще раз.', + 'presented.directoryOpening': 'Открытие папки, содержащей…', + 'presented.directoryOpened': 'Запрошенное открытие, содержащее папку', + 'presented.revealed': 'Запрошенное отображение в файловом менеджере', + 'presented.revealing': 'Отображается в файловом менеджере…', + 'presented.unavailable': 'У этого хоста нет рабочего стола, на котором можно было бы открывать файлы или папки во внешних приложениях. Файлы по-прежнему можно просматривать на боковой панели.', + 'presented.retry': 'Повторить', + 'presented.hostError': 'Не удалось прочитать информацию о рабочем столе хоста.', + 'presented.preview': 'Предварительный просмотр в боковой панели', + 'presented.previewButton': 'Откройте {name} на боковой панели.', + 'presented.previewCard': 'Предварительный просмотр {name} на боковой панели', + 'presented.all': 'Все файлы {count}', + 'presented.expandAria': 'Показать все доставленные файлы {count}', + 'presented.collapse': 'Свернуть', + 'presented.collapseAria': 'Свернуть доставленные файлы', + 'presented.opening': 'Открытие…', + 'presented.opened': 'Открыть запрос', + 'presented.error': 'Не удалось открыть. Нажмите, чтобы повторить попытку.', + 'presented.file': 'Файл', + 'row.title': 'Представление файлов', + 'row.running': 'Доставка', + 'row.preparing': 'Подготовка результатов', + 'row.ok': 'Доставлено', + 'row.error': 'Доставка не удалась', + 'row.stopped': 'Прерванный', + 'row.inspect': 'Проверить вызов', + 'changes.title': 'Отредактированные файлы {count}.', + 'changes.singleTitle': 'Отредактировано {name}', + 'changes.added': '+{count}', + 'changes.deleted': '-{count}', + 'changes.binary': 'двоичный', + 'changes.openReview': 'Просмотрите изменения этого хода на боковой панели.', + 'changes.all': 'Все файлы {count}', + 'changes.expandAria': 'Показать все измененные файлы {count}', + 'changes.collapse': 'Свернуть', + 'changes.collapseAria': 'Свернуть измененные файлы', + 'changes.oversized': 'слишком большой', + 'changes.viewDiff': 'Посмотреть изменения в {name}', + 'review.title': 'Проверка · ход {turn}', + 'review.selectFile': 'Выберите файл для просмотра', + 'review.split': 'Переключиться на разделенный вид', + 'review.unified': 'Переключиться на единый вид', + 'review.splitAria': 'Разделенный вид', + 'review.wrap': 'Включить перенос строк', + 'review.nowrap': 'Отключить перенос строк', + 'review.wrapAria': 'Перенос строки', + 'review.openFile': 'Открыть весь файл на боковой панели', + 'review.openFileAria': 'Откройте {name} на боковой панели.', + 'diff.loading': 'Чтение изменений…', + 'diff.missing': 'Содержимое изменений этого хода больше не доступно.', + 'diff.error': 'Не удалось прочитать изменения', + 'diff.binary': 'Бинарный файл; изменения не могут быть показаны', + 'diff.oversized': 'Файл слишком большой; изменения не могут быть показаны', + 'diff.created': 'Создано в этом ходу', + 'diff.deleted': 'Удален на этом ходу', + 'diff.unchanged': 'Обе стороны держат одни и те же линии', + 'diff.coarse': 'Время сравнения строк истекло; отображается как замена всего файла', + 'diff.truncated': 'Показаны первые строки {count}', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'presented.nativeUnavailable': 'Este arquivo não possui caminho de host disponível. Visualize-o na barra lateral.', + 'presented.revealError': 'Não foi possível mostrar no gerenciador de arquivos. Tente novamente.', + 'presented.directoryError': 'Não foi possível abrir a pasta que contém. Tente novamente.', + 'presented.directoryOpening': 'Abrindo a pasta que contém…', + 'presented.directoryOpened': 'Abertura solicitada contendo pasta', + 'presented.revealed': 'Exibição solicitada no gerenciador de arquivos', + 'presented.revealing': 'Mostrando no gerenciador de arquivos…', + 'presented.unavailable': 'Este Host não possui área de trabalho disponível para abrir arquivos ou pastas em aplicativos externos. Os arquivos ainda podem ser visualizados na barra lateral.', + 'presented.retry': 'Tentar novamente', + 'presented.hostError': 'Não foi possível ler as informações da área de trabalho do Host', + 'presented.preview': 'Pré-visualização na barra lateral', + 'presented.previewButton': 'Abra {name} na barra lateral', + 'presented.previewCard': 'Visualizar {name} na barra lateral', + 'presented.all': 'Todos os {count} arquivos', + 'presented.expandAria': 'Mostrar todos os {count} arquivos entregues', + 'presented.collapse': 'Recolher', + 'presented.collapseAria': 'Recolher arquivos entregues', + 'presented.opening': 'Abrindo…', + 'presented.opened': 'Aberto solicitado', + 'presented.error': 'Não foi possível abrir. Clique para tentar novamente.', + 'presented.file': 'Arquivo', + 'row.title': 'Apresentar arquivos', + 'row.running': 'Entregando', + 'row.preparing': 'Preparando resultados', + 'row.ok': 'Entregue', + 'row.error': 'Falha na entrega', + 'row.stopped': 'Interrompido', + 'row.inspect': 'Inspecionar chamada', + 'changes.title': '{count} arquivos editados', + 'changes.singleTitle': 'Editado {name}', + 'changes.added': '+{count}', + 'changes.deleted': '-{count}', + 'changes.binary': 'binário', + 'changes.openReview': 'Revise as mudanças deste turno na barra lateral', + 'changes.all': 'Todos os {count} arquivos', + 'changes.expandAria': 'Mostrar todos os {count} arquivos alterados', + 'changes.collapse': 'Recolher', + 'changes.collapseAria': 'Recolher arquivos alterados', + 'changes.oversized': 'muito grande', + 'changes.viewDiff': 'Ver alterações em {name}', + 'review.title': 'Revisão · turno {turn}', + 'review.selectFile': 'Escolha o arquivo para revisar', + 'review.split': 'Mudar para visualização dividida', + 'review.unified': 'Mudar para visualização unificada', + 'review.splitAria': 'Visualização dividida', + 'review.wrap': 'Ativar quebra de linha', + 'review.nowrap': 'Desativar quebra de linha', + 'review.wrapAria': 'Quebra de linha', + 'review.openFile': 'Abra o arquivo inteiro na barra lateral', + 'review.openFileAria': 'Abra {name} na barra lateral', + 'diff.loading': 'A leitura muda…', + 'diff.missing': 'O conteúdo das alterações deste turno não está mais disponível', + 'diff.error': 'Não foi possível ler as alterações', + 'diff.binary': 'Arquivo binário; as alterações não podem ser mostradas', + 'diff.oversized': 'Arquivo muito grande; as alterações não podem ser mostradas', + 'diff.created': 'Criado neste turno', + 'diff.deleted': 'Excluído neste turno', + 'diff.unchanged': 'Ambos os lados mantêm as mesmas linhas', + 'diff.coarse': 'A comparação de linha expirou; mostrado como uma substituição de arquivo inteiro', + 'diff.truncated': 'Mostrando as primeiras {count} linhas', +} satisfies Record diff --git a/packages/client/ui-directory-picker-browse/locale/de.json b/packages/client/ui-directory-picker-browse/locale/de.json new file mode 100644 index 0000000000..0ae1c16fad --- /dev/null +++ b/packages/client/ui-directory-picker-browse/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Schnittstelle zur In-App-Verzeichnisauswahl", + "description": "Durchsuchen, erstellen und wählen Sie ein Arbeitsbereichsverzeichnis innerhalb der App aus." + } +} diff --git a/packages/client/ui-directory-picker-browse/locale/es.json b/packages/client/ui-directory-picker-browse/locale/es.json new file mode 100644 index 0000000000..1ae27d3528 --- /dev/null +++ b/packages/client/ui-directory-picker-browse/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de selección de directorio en la aplicación", + "description": "Busque, cree y seleccione un directorio de espacio de trabajo dentro de la aplicación." + } +} diff --git a/packages/client/ui-directory-picker-browse/locale/fr.json b/packages/client/ui-directory-picker-browse/locale/fr.json new file mode 100644 index 0000000000..c68b6dfdcd --- /dev/null +++ b/packages/client/ui-directory-picker-browse/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de sélection de répertoire dans l'application", + "description": "Parcourez, créez et sélectionnez un répertoire d'espace de travail dans l'application." + } +} diff --git a/packages/client/ui-directory-picker-browse/locale/pt.json b/packages/client/ui-directory-picker-browse/locale/pt.json new file mode 100644 index 0000000000..236a105e59 --- /dev/null +++ b/packages/client/ui-directory-picker-browse/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de seleção de diretório no aplicativo", + "description": "Navegue, crie e selecione um diretório de espaço de trabalho no aplicativo." + } +} diff --git a/packages/client/ui-directory-picker-browse/locale/ru.json b/packages/client/ui-directory-picker-browse/locale/ru.json new file mode 100644 index 0000000000..5c2a88cff4 --- /dev/null +++ b/packages/client/ui-directory-picker-browse/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Интерфейс выбора каталога в приложении", + "description": "Просмотрите, создайте и выберите каталог рабочей области в приложении." + } +} diff --git a/packages/client/ui-directory-picker-browse/src/client/index.ts b/packages/client/ui-directory-picker-browse/src/client/index.ts index bc78900e0b..d3cff16b31 100644 --- a/packages/client/ui-directory-picker-browse/src/client/index.ts +++ b/packages/client/ui-directory-picker-browse/src/client/index.ts @@ -80,6 +80,81 @@ export function apply(ctx: ClientContext): void { 'browser.truncated': 'フォルダが多すぎて一覧表示できません。先頭のみ表示しています。', 'browser.showHidden': '隠しファイルを表示', }], + ['es', { + 'browser.title': 'Seleccionar carpeta de trabajo', + 'browser.home': 'Inicio', + 'browser.newFolder': 'Nueva carpeta', + 'browser.folderName': 'Nombre de la carpeta', + 'browser.createIn': 'Nueva carpeta en "{name}"', + 'browser.untitledFolder': 'Carpeta sin título', + 'browser.create': 'Crear', + 'browser.cancel': 'Cancelar', + 'browser.open': 'Abrir', + 'browser.editPath': 'Editar ruta', + 'browser.loading': 'Cargando…', + 'browser.truncated': 'Hay demasiadas carpetas; solo se muestra el principio.', + 'browser.showHidden': 'Mostrar archivos ocultos', + }], + ['fr', { + 'browser.title': 'Choisir le dossier de travail', + 'browser.home': 'Dossier personnel', + 'browser.newFolder': 'Nouveau dossier', + 'browser.folderName': 'Nom du dossier', + 'browser.createIn': 'Nouveau dossier dans « {name} »', + 'browser.untitledFolder': 'Dossier sans titre', + 'browser.create': 'Créer', + 'browser.cancel': 'Annuler', + 'browser.open': 'Ouvrir', + 'browser.editPath': 'Modifier le chemin', + 'browser.loading': 'Chargement…', + 'browser.truncated': 'Trop de dossiers à afficher ; seul le début est affiché.', + 'browser.showHidden': 'Afficher les fichiers cachés', + }], + ['de', { + 'browser.title': 'Arbeitsverzeichnis auswählen', + 'browser.home': 'Persönlicher Ordner', + 'browser.newFolder': 'Neuer Ordner', + 'browser.folderName': 'Ordnername', + 'browser.createIn': 'Neuer Ordner in „{name}“', + 'browser.untitledFolder': 'Unbenannter Ordner', + 'browser.create': 'Erstellen', + 'browser.cancel': 'Abbrechen', + 'browser.open': 'Öffnen', + 'browser.editPath': 'Pfad bearbeiten', + 'browser.loading': 'Laden…', + 'browser.truncated': 'Zu viele Ordner; nur der Anfang wird angezeigt.', + 'browser.showHidden': 'Versteckte Dateien anzeigen', + }], + ['ru', { + 'browser.title': 'Выбрать рабочую папку', + 'browser.home': 'Домашняя папка', + 'browser.newFolder': 'Новая папка', + 'browser.folderName': 'Имя папки', + 'browser.createIn': 'Новая папка в «{name}»', + 'browser.untitledFolder': 'Папка без названия', + 'browser.create': 'Создать', + 'browser.cancel': 'Отмена', + 'browser.open': 'Открыть', + 'browser.editPath': 'Изменить путь', + 'browser.loading': 'Загрузка…', + 'browser.truncated': 'Папок слишком много; показана только начальная часть списка.', + 'browser.showHidden': 'Показать скрытые файлы', + }], + ['pt', { + 'browser.title': 'Selecionar pasta de trabalho', + 'browser.home': 'Pasta pessoal', + 'browser.newFolder': 'Nova pasta', + 'browser.folderName': 'Nome da pasta', + 'browser.createIn': 'Nova pasta em "{name}"', + 'browser.untitledFolder': 'Pasta sem nome', + 'browser.create': 'Criar', + 'browser.cancel': 'Cancelar', + 'browser.open': 'Abrir', + 'browser.editPath': 'Editar caminho', + 'browser.loading': 'Carregando…', + 'browser.truncated': 'Há pastas demais; apenas o início é exibido.', + 'browser.showHidden': 'Mostrar arquivos ocultos', + }], ] try { for (const [locale, dict] of dictionaries) disposers.push(ctx.locale.register(LOCALE_NS, locale, dict)) diff --git a/packages/client/ui-directory-picker-native/locale/de.json b/packages/client/ui-directory-picker-native/locale/de.json new file mode 100644 index 0000000000..d0bd0ff6aa --- /dev/null +++ b/packages/client/ui-directory-picker-native/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Schnittstelle zur Auswahl des Systemverzeichnisses", + "description": "Verbinden Sie das Arbeitsbereich-Auswahlportal und das Systemverzeichnis-Auswahldialogfeld." + } +} diff --git a/packages/client/ui-directory-picker-native/locale/es.json b/packages/client/ui-directory-picker-native/locale/es.json new file mode 100644 index 0000000000..67dfd34b96 --- /dev/null +++ b/packages/client/ui-directory-picker-native/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de selección del directorio del sistema", + "description": "Conecte el portal de selección del espacio de trabajo y el cuadro de diálogo de selección del directorio del sistema." + } +} diff --git a/packages/client/ui-directory-picker-native/locale/fr.json b/packages/client/ui-directory-picker-native/locale/fr.json new file mode 100644 index 0000000000..87bff91413 --- /dev/null +++ b/packages/client/ui-directory-picker-native/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de sélection du répertoire système", + "description": "Connectez le portail de sélection de l'espace de travail et la boîte de dialogue de sélection du répertoire système." + } +} diff --git a/packages/client/ui-directory-picker-native/locale/pt.json b/packages/client/ui-directory-picker-native/locale/pt.json new file mode 100644 index 0000000000..908a8e4105 --- /dev/null +++ b/packages/client/ui-directory-picker-native/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de seleção de diretório do sistema", + "description": "Conecte o portal de seleção de espaço de trabalho e a caixa de diálogo de seleção de diretório do sistema." + } +} diff --git a/packages/client/ui-directory-picker-native/locale/ru.json b/packages/client/ui-directory-picker-native/locale/ru.json new file mode 100644 index 0000000000..e57e07e0d0 --- /dev/null +++ b/packages/client/ui-directory-picker-native/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Интерфейс выбора системного каталога", + "description": "Соедините портал выбора рабочего пространства и диалоговое окно выбора системного каталога." + } +} diff --git a/packages/client/ui-entry-customization/locale/de.json b/packages/client/ui-entry-customization/locale/de.json new file mode 100644 index 0000000000..b00350d66a --- /dev/null +++ b/packages/client/ui-entry-customization/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Anpassung der Benutzeroberfläche", + "description": "Passen Sie Plugin-Einträge in der linken Seitenleiste, den Konversationsansichten und der rechten Seitenleiste an und erstellen Sie schnell neue Plugins." + } +} diff --git a/packages/client/ui-entry-customization/locale/es.json b/packages/client/ui-entry-customization/locale/es.json new file mode 100644 index 0000000000..c91bc568a9 --- /dev/null +++ b/packages/client/ui-entry-customization/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Personalización de la interfaz", + "description": "Personalice las entradas de complementos en la barra lateral izquierda, las vistas de conversación y la barra lateral derecha, y cree rápidamente nuevos complementos." + } +} diff --git a/packages/client/ui-entry-customization/locale/fr.json b/packages/client/ui-entry-customization/locale/fr.json new file mode 100644 index 0000000000..b5209dccd1 --- /dev/null +++ b/packages/client/ui-entry-customization/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Personnalisation de l'interface", + "description": "Personnalisez les entrées de plugin dans la barre latérale gauche, les vues de conversation et la barre latérale droite, et créez rapidement de nouveaux plugins." + } +} diff --git a/packages/client/ui-entry-customization/locale/pt.json b/packages/client/ui-entry-customization/locale/pt.json new file mode 100644 index 0000000000..d0171b4721 --- /dev/null +++ b/packages/client/ui-entry-customization/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Personalização da interface", + "description": "Personalize as entradas de plug-ins na barra lateral esquerda, nas visualizações de conversas e na barra lateral direita e crie novos plug-ins rapidamente." + } +} diff --git a/packages/client/ui-entry-customization/locale/ru.json b/packages/client/ui-entry-customization/locale/ru.json new file mode 100644 index 0000000000..52ba475bb5 --- /dev/null +++ b/packages/client/ui-entry-customization/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Настройка интерфейса", + "description": "Настраивайте записи плагинов на левой боковой панели, в представлениях бесед и на правой боковой панели и быстро создавайте новые плагины." + } +} diff --git a/packages/client/ui-entry-customization/src/client/index.ts b/packages/client/ui-entry-customization/src/client/index.ts index ba41d131a9..261a9eb3ba 100644 --- a/packages/client/ui-entry-customization/src/client/index.ts +++ b/packages/client/ui-entry-customization/src/client/index.ts @@ -10,7 +10,7 @@ import type {} from '@deepseek-ai/dsh-client-ui-sidebar-right/client' import type {} from '@deepseek-ai/dsh-client-ui-plugin-manager/client' import type {} from '@deepseek-ai/dsh-client-ui-workspace/client' import { EntryMenuContent, type EntryMenuInjected, type EntryRegion } from './EntryMenuContent.tsx' -import { en, ja, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh } from './locales.ts' declare module '@deepseek-ai/dsh-client-ui-slots' { interface LocaleNamespaceMap { @@ -27,7 +27,7 @@ export const inject = ['slots', 'locale', 'uiWorkspace'] * @param ctx - Browser context with slot, locale, and Workspace services, and the optional plugin navigation. */ export function apply(ctx: Context): void { - ctx.effect(() => ctx.locale.register('entryCustomization', { en, zh, ja })) + ctx.effect(() => ctx.locale.register('entryCustomization', { en, zh, ja, es, fr, de, ru, pt })) const t = ctx.locale.bind('entryCustomization') // The Plugins page provides its navigation only while the current Peer may use it. const pluginNavigation = createSnapshotStore(false) diff --git a/packages/client/ui-entry-customization/src/client/locales.ts b/packages/client/ui-entry-customization/src/client/locales.ts index 6693ed6fc2..471e143dba 100644 --- a/packages/client/ui-entry-customization/src/client/locales.ts +++ b/packages/client/ui-entry-customization/src/client/locales.ts @@ -45,3 +45,83 @@ export const ja = { 'createPrompt.conversation': 'DSH 会話ビュープラグインを作成します。', 'createPrompt.rightbar': '右サイドバーにエントリを持つ DSH プラグインを作成します。', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'pin.sidebar': 'Fijar a la barra lateral izquierda', + 'unpin.sidebar': 'Desanclar de la barra lateral izquierda', + 'pin.conversation': 'Anclar a pestañas de conversación', + 'unpin.conversation': 'Desanclar de las pestañas de conversación', + 'pin.rightbar': 'Fijar a la barra lateral derecha', + 'unpin.rightbar': 'Desanclar de la barra lateral derecha', + pinLabel: '{action}: {name}', + install: 'Explorar otros complementos', + create: 'Crea tu complemento', + 'createPrompt.sidebar': 'Cree un complemento DSH con una entrada en la barra lateral izquierda.', + 'createPrompt.conversation': 'Cree un complemento de vista de conversación DSH.', + 'createPrompt.rightbar': 'Cree un complemento DSH con una entrada en la barra lateral derecha.', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'pin.sidebar': 'Épingler sur la barre latérale gauche', + 'unpin.sidebar': "Retirer l'épingle de la barre latérale gauche", + 'pin.conversation': 'Épingler aux onglets de conversation', + 'unpin.conversation': "Retirer l'épingle des onglets de conversation", + 'pin.rightbar': 'Épingler sur la barre latérale droite', + 'unpin.rightbar': "Retirer l'épingle de la barre latérale droite", + pinLabel: '{action} : {name}', + install: "Parcourir d'autres plugins", + create: 'Créez votre plugin', + 'createPrompt.sidebar': 'Créez un plugin DSH avec une entrée dans la barre latérale gauche.', + 'createPrompt.conversation': "Créez un plugin d'affichage de conversation DSH.", + 'createPrompt.rightbar': 'Créez un plugin DSH avec une entrée dans la barre latérale droite.', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'pin.sidebar': 'An die linke Seitenleiste anpinnen', + 'unpin.sidebar': 'Von der linken Seitenleiste lösen', + 'pin.conversation': 'An Konversationsregisterkarten anpinnen', + 'unpin.conversation': 'Von Konversations-Tabs lösen', + 'pin.rightbar': 'An rechte Seitenleiste anheften', + 'unpin.rightbar': 'Von der rechten Seitenleiste lösen', + pinLabel: '{action}: {name}', + install: 'Durchsuchen Sie andere Plugins', + create: 'Erstellen Sie Ihr Plugin', + 'createPrompt.sidebar': 'Erstellen Sie ein DSH-Plugin mit einem Eintrag in der linken Seitenleiste.', + 'createPrompt.conversation': 'Erstellen Sie ein DSH-Plugin für die Konversationsansicht.', + 'createPrompt.rightbar': 'Erstellen Sie ein DSH-Plugin mit einem Eintrag in der rechten Seitenleiste.', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'pin.sidebar': 'Закрепить на левой боковой панели', + 'unpin.sidebar': 'Открепить от левой боковой панели', + 'pin.conversation': 'Закрепить на вкладках беседы', + 'unpin.conversation': 'Открепить от вкладок беседы', + 'pin.rightbar': 'Закрепить на правой боковой панели', + 'unpin.rightbar': 'Открепить от правой боковой панели', + pinLabel: '{action}: {name}', + install: 'Просмотрите другие плагины', + create: 'Создайте свой плагин', + 'createPrompt.sidebar': 'Создайте плагин DSH с записью на левой боковой панели.', + 'createPrompt.conversation': 'Создайте плагин просмотра диалога DSH.', + 'createPrompt.rightbar': 'Создайте плагин DSH с записью на правой боковой панели.', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'pin.sidebar': 'Fixar na barra lateral esquerda', + 'unpin.sidebar': 'Soltar da barra lateral esquerda', + 'pin.conversation': 'Fixar nas guias de conversa', + 'unpin.conversation': 'Liberar das guias de conversa', + 'pin.rightbar': 'Fixar na barra lateral direita', + 'unpin.rightbar': 'Soltar da barra lateral direita', + pinLabel: '{action}: {name}', + install: 'Procure outros plug-ins', + create: 'Crie seu plug-in', + 'createPrompt.sidebar': 'Crie um plug-in DSH com uma entrada na barra lateral esquerda.', + 'createPrompt.conversation': 'Crie um plug-in de visualização de conversa DSH.', + 'createPrompt.rightbar': 'Crie um plug-in DSH com uma entrada na barra lateral direita.', +} satisfies Record diff --git a/packages/client/ui-file-drag/locale/de.json b/packages/client/ui-file-drag/locale/de.json new file mode 100644 index 0000000000..5f610493c3 --- /dev/null +++ b/packages/client/ui-file-drag/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ziehen von Dateien", + "description": "Ziehen Sie Originaldateien in den Composer oder andere Anwendungen, mit lokalisierter Fehlerrückmeldung." + } +} diff --git a/packages/client/ui-file-drag/locale/es.json b/packages/client/ui-file-drag/locale/es.json new file mode 100644 index 0000000000..ff04cd6d4c --- /dev/null +++ b/packages/client/ui-file-drag/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Arrastrar archivos", + "description": "Arrastre los archivos originales al compositor u otras aplicaciones, con comentarios de falla localizados." + } +} diff --git a/packages/client/ui-file-drag/locale/fr.json b/packages/client/ui-file-drag/locale/fr.json new file mode 100644 index 0000000000..302a536b7d --- /dev/null +++ b/packages/client/ui-file-drag/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Glisser un fichier", + "description": "Faites glisser les fichiers originaux dans le composeur ou d'autres applications, avec un retour d'échec localisé." + } +} diff --git a/packages/client/ui-file-drag/locale/pt.json b/packages/client/ui-file-drag/locale/pt.json new file mode 100644 index 0000000000..9d59d7c683 --- /dev/null +++ b/packages/client/ui-file-drag/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Arrastando arquivo", + "description": "Arraste os arquivos originais para o compositor ou outros aplicativos, com feedback de falha localizado." + } +} diff --git a/packages/client/ui-file-drag/locale/ru.json b/packages/client/ui-file-drag/locale/ru.json new file mode 100644 index 0000000000..00cd72b430 --- /dev/null +++ b/packages/client/ui-file-drag/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Перетаскивание файлов", + "description": "Перетащите исходные файлы в композитор или другие приложения с локализованной обратной связью об ошибках." + } +} diff --git a/packages/client/ui-file-drag/src/client/index.ts b/packages/client/ui-file-drag/src/client/index.ts index efe3fb7eab..cfc9c1c85c 100644 --- a/packages/client/ui-file-drag/src/client/index.ts +++ b/packages/client/ui-file-drag/src/client/index.ts @@ -8,7 +8,7 @@ import type {} from '@deepseek-ai/dsh-client-ui-layout/client' import type {} from '@deepseek-ai/dsh-client-locale/client' import { FileDragFeedback, type FileDragFailure, type FileDragFeedbackInjected } from './feedback.tsx' import { FileTransfers } from './transfers.ts' -import { en, ja, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh } from './locales.ts' /** Application-local file preparation and drop resolution. */ export interface FileDragService { @@ -33,7 +33,7 @@ export function apply(ctx: Context): void { const desktop = bridge?.protocolVersion === 1 ? bridge.fileDrag : undefined const failure = createSnapshotStore(null) const t = ctx.locale.bind('fileDrag') - ctx.effect(() => ctx.locale.register('fileDrag', { zh, en, ja })) + ctx.effect(() => ctx.locale.register('fileDrag', { zh, en, ja, es, fr, de, ru, pt })) let sequence = 0 const reportFailure = (): void => { failure.set({ text: t('failed'), sequence: ++sequence }) } const transfers = new FileTransfers(desktop, reportFailure) diff --git a/packages/client/ui-file-drag/src/client/locales.ts b/packages/client/ui-file-drag/src/client/locales.ts index 9497b29dbc..d0da371eca 100644 --- a/packages/client/ui-file-drag/src/client/locales.ts +++ b/packages/client/ui-file-drag/src/client/locales.ts @@ -7,6 +7,21 @@ export const en = { failed: 'Drag failed. Try again.' } satisfies Record +/** Spanish dictionary, checked against the English keys. */ +export const es = { failed: 'Error al arrastrar. Intentar otra vez.' } satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { failed: 'Le glissement a échoué. Essayer à nouveau.' } satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { failed: 'Ziehen ist fehlgeschlagen. Versuchen Sie es erneut.' } satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { failed: 'Перетащить не удалось. Попробуйте еще раз.' } satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { failed: 'Falha ao arrastar. Tente novamente.' } satisfies Record + declare module '@deepseek-ai/dsh-client-ui-slots' { interface LocaleNamespaceMap { /** File transfer failure feedback. */ diff --git a/packages/client/ui-goal/locale/de.json b/packages/client/ui-goal/locale/de.json new file mode 100644 index 0000000000..2a2420166b --- /dev/null +++ b/packages/client/ui-goal/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sitzungszielleiste", + "description": "Zeigt das Ziel und den Status der aktuellen Sitzung über dem Eingabefeld an." + } +} diff --git a/packages/client/ui-goal/locale/es.json b/packages/client/ui-goal/locale/es.json new file mode 100644 index 0000000000..e0135182ed --- /dev/null +++ b/packages/client/ui-goal/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "barra de destino de sesión", + "description": "Muestra el objetivo y el estado de la sesión actual encima del cuadro de entrada." + } +} diff --git a/packages/client/ui-goal/locale/fr.json b/packages/client/ui-goal/locale/fr.json new file mode 100644 index 0000000000..2282fdbd25 --- /dev/null +++ b/packages/client/ui-goal/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "barre de cible de session", + "description": "Affiche l'objectif et le statut de la session en cours au-dessus de la zone de saisie." + } +} diff --git a/packages/client/ui-goal/locale/pt.json b/packages/client/ui-goal/locale/pt.json new file mode 100644 index 0000000000..d7e3fa30c3 --- /dev/null +++ b/packages/client/ui-goal/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "barra de destino da sessão", + "description": "Exibe a meta e o status da sessão atual acima da caixa de entrada." + } +} diff --git a/packages/client/ui-goal/locale/ru.json b/packages/client/ui-goal/locale/ru.json new file mode 100644 index 0000000000..2736841f94 --- /dev/null +++ b/packages/client/ui-goal/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "целевая панель сеанса", + "description": "Отображает цель и статус текущего сеанса над полем ввода." + } +} diff --git a/packages/client/ui-goal/src/client/index.ts b/packages/client/ui-goal/src/client/index.ts index a38de98032..7c1eadb38a 100644 --- a/packages/client/ui-goal/src/client/index.ts +++ b/packages/client/ui-goal/src/client/index.ts @@ -35,7 +35,7 @@ import { GoalCommandReference } from './GoalCommandReference.tsx' import { goalCommandInputDefinition } from './goal-command-input.ts' import { goalCommandReferenceRule } from './user-text-rules.ts' export type {} from './user-text-rules.ts' -import { en, ja, zh, type GoalKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh, type GoalKey } from './locales.ts' export { GoalBar, GoalDock } from './GoalBar.tsx' export type { @@ -70,7 +70,7 @@ export const inject = ['slots', 'sessions', 'remote', 'remote.goals', 'locale', export function apply(ctx: ClientContext): void { ctx.uiConversation.events.register(goalCommandInputDefinition) ctx.uiConversation.userText.register(goalCommandReferenceRule) - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-goal: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-goal: dictionaries') ctx.slots.inject('conversation.user.text.node', () => ctx.slots.register({ name: 'conversation.user.text.node', diff --git a/packages/client/ui-goal/src/client/locales.ts b/packages/client/ui-goal/src/client/locales.ts index b196c8c7a9..f52946329e 100644 --- a/packages/client/ui-goal/src/client/locales.ts +++ b/packages/client/ui-goal/src/client/locales.ts @@ -50,3 +50,83 @@ export const ja = { 'action.edit': '目標を編集', 'action.clear': '目標をクリア', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'phase.active': 'Meta en curso', + 'phase.active.disarmed': 'Meta inactiva', + 'phase.paused': 'Objetivo en pausa', + 'phase.blocked': 'Meta bloqueada', + 'objective.aria': 'Objetivo de meta', + 'commandInput.aria': 'Entrada de comando', + 'action.save': 'Guardar gol', + 'action.cancel': 'Cancelar edición', + 'action.pause': 'Pausar objetivo', + 'action.resume': 'Reanudar objetivo', + 'action.edit': 'Editar objetivo', + 'action.clear': 'Objetivo claro', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'phase.active': 'Objectif continu', + 'phase.active.disarmed': 'Objectif inactif', + 'phase.paused': 'Objectif suspendu', + 'phase.blocked': 'Objectif bloqué', + 'objective.aria': 'Objectif du but', + 'commandInput.aria': 'Entrée de commande', + 'action.save': "Sauvegarder l'objectif", + 'action.cancel': 'Annuler la modification', + 'action.pause': "Suspendre l'objectif", + 'action.resume': "Reprendre l'objectif", + 'action.edit': "Modifier l'objectif", + 'action.clear': 'Objectif clair', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'phase.active': 'Fortlaufendes Ziel', + 'phase.active.disarmed': 'Inaktives Ziel', + 'phase.paused': 'Pausiertes Ziel', + 'phase.blocked': 'Blockiertes Ziel', + 'objective.aria': 'Zielziel', + 'commandInput.aria': 'Befehlseingabe', + 'action.save': 'Ziel speichern', + 'action.cancel': 'Bearbeitung abbrechen', + 'action.pause': 'Ziel pausieren', + 'action.resume': 'Ziel fortsetzen', + 'action.edit': 'Ziel bearbeiten', + 'action.clear': 'Klares Ziel', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'phase.active': 'Текущая цель', + 'phase.active.disarmed': 'Неактивная цель', + 'phase.paused': 'Приостановленная цель', + 'phase.blocked': 'Заблокированная цель', + 'objective.aria': 'Цель Цель', + 'commandInput.aria': 'Ввод команды', + 'action.save': 'Сохранить цель', + 'action.cancel': 'Отменить редактирование', + 'action.pause': 'Приостановить цель', + 'action.resume': 'Возобновить цель', + 'action.edit': 'Изменить цель', + 'action.clear': 'Четкая цель', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'phase.active': 'Meta contínua', + 'phase.active.disarmed': 'Meta inativa', + 'phase.paused': 'Meta pausada', + 'phase.blocked': 'Meta bloqueada', + 'objective.aria': 'Objetivo da meta', + 'commandInput.aria': 'Entrada de comando', + 'action.save': 'Salvar meta', + 'action.cancel': 'Cancelar edição', + 'action.pause': 'Pausar meta', + 'action.resume': 'Retomar meta', + 'action.edit': 'Editar meta', + 'action.clear': 'Objetivo claro', +} satisfies Record diff --git a/packages/client/ui-input-trigger/locale/de.json b/packages/client/ui-input-trigger/locale/de.json new file mode 100644 index 0000000000..be4ceb8980 --- /dev/null +++ b/packages/client/ui-input-trigger/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Geben Sie Lenovo Services ein", + "description": "Erkennen Sie / und @ in der Eingabe, zeigen Sie die entsprechenden Kandidaten an und wählen Sie sie aus." + } +} diff --git a/packages/client/ui-input-trigger/locale/es.json b/packages/client/ui-input-trigger/locale/es.json new file mode 100644 index 0000000000..48be835ec5 --- /dev/null +++ b/packages/client/ui-input-trigger/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ingrese a los servicios de Lenovo", + "description": "Reconocer / y @ en la entrada, mostrar y seleccionar los candidatos correspondientes." + } +} diff --git a/packages/client/ui-input-trigger/locale/fr.json b/packages/client/ui-input-trigger/locale/fr.json new file mode 100644 index 0000000000..225c4f9e3f --- /dev/null +++ b/packages/client/ui-input-trigger/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Entrez dans les services Lenovo", + "description": "Reconnaître / et @ dans la saisie, afficher et sélectionner les candidats correspondants." + } +} diff --git a/packages/client/ui-input-trigger/locale/pt.json b/packages/client/ui-input-trigger/locale/pt.json new file mode 100644 index 0000000000..91b25e4363 --- /dev/null +++ b/packages/client/ui-input-trigger/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Entre nos serviços Lenovo", + "description": "Reconheça / e @ na entrada, exiba e selecione os candidatos correspondentes." + } +} diff --git a/packages/client/ui-input-trigger/locale/ru.json b/packages/client/ui-input-trigger/locale/ru.json new file mode 100644 index 0000000000..9aeeefffd6 --- /dev/null +++ b/packages/client/ui-input-trigger/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Войдите в услуги Lenovo", + "description": "Распознайте / и @ во входных данных, отобразите и выберите соответствующих кандидатов." + } +} diff --git a/packages/client/ui-input-trigger/src/client/index.ts b/packages/client/ui-input-trigger/src/client/index.ts index cad11a5452..de4186135f 100644 --- a/packages/client/ui-input-trigger/src/client/index.ts +++ b/packages/client/ui-input-trigger/src/client/index.ts @@ -13,7 +13,7 @@ import type {} from '@deepseek-ai/dsh-client-ui-session/client' import { InputTriggerService } from './service.ts' import type { MenuViewInjected } from './slots.ts' import { MenuView } from './MenuView.tsx' -import { en, ja, zh, type MenuKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh, type MenuKey } from './locales.ts' export { InputTriggerService } from './service.ts' export { InputTriggerController } from './controller.ts' @@ -58,7 +58,7 @@ export const inject = ['sessions', 'locale'] */ export function apply(ctx: ClientContext): void { ctx.plugin(InputTriggerService) - ctx.effect(() => ctx.locale.register(MENU_NS, { zh, en, ja }), 'ui-input-trigger: menu dictionaries') + ctx.effect(() => ctx.locale.register(MENU_NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-input-trigger: menu dictionaries') ctx.inject(['slots', 'inputTriggers', 'sessions'], (scope: ClientContext) => { const inputTriggers = scope.inputTriggers const sessions = scope.sessions diff --git a/packages/client/ui-input-trigger/src/client/locales.ts b/packages/client/ui-input-trigger/src/client/locales.ts index 1b11342393..63f0780d1d 100644 --- a/packages/client/ui-input-trigger/src/client/locales.ts +++ b/packages/client/ui-input-trigger/src/client/locales.ts @@ -45,3 +45,68 @@ export const ja = { 'crumbs.aria': 'フォルダナビゲーション', 'suggestions.aria': '候補を表示', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'command': 'Comandos', + 'skill': 'Habilidades', + 'subagent': 'Subagentes', + 'loading': 'Cargando…', + 'drill.aria': 'Explorar carpeta', + 'drill.hint': 'Explorar carpeta', + 'drill.key': 'Pestaña', + 'crumbs.aria': 'Navegación de carpetas', + 'suggestions.aria': 'Sugerencias de activación', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'command': 'Commandes', + 'skill': 'Compétences', + 'subagent': 'Sous-agents', + 'loading': 'Chargement…', + 'drill.aria': 'Parcourir le dossier', + 'drill.hint': 'Parcourir le dossier', + 'drill.key': 'Onglet', + 'crumbs.aria': 'Navigation dans les dossiers', + 'suggestions.aria': 'Suggestions de déclenchement', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'command': 'Befehle', + 'skill': 'Fähigkeiten', + 'subagent': 'Subagenten', + 'loading': 'Laden…', + 'drill.aria': 'Ordner durchsuchen', + 'drill.hint': 'Ordner durchsuchen', + 'drill.key': 'Tab', + 'crumbs.aria': 'Ordnernavigation', + 'suggestions.aria': 'Trigger-Vorschläge', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'command': 'Команды', + 'skill': 'Навыки', + 'subagent': 'Субагенты', + 'loading': 'Загрузка…', + 'drill.aria': 'Просмотреть папку', + 'drill.hint': 'Просмотреть папку', + 'drill.key': 'Вкладка', + 'crumbs.aria': 'Навигация по папкам', + 'suggestions.aria': 'Триггерные предложения', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'command': 'Comandos', + 'skill': 'Habilidades', + 'subagent': 'Subagentes', + 'loading': 'Carregando…', + 'drill.aria': 'Navegar na pasta', + 'drill.hint': 'Navegar na pasta', + 'drill.key': 'Guia', + 'crumbs.aria': 'Navegação de pastas', + 'suggestions.aria': 'Sugestões de gatilho', +} satisfies Record diff --git a/packages/client/ui-jobs/locale/de.json b/packages/client/ui-jobs/locale/de.json new file mode 100644 index 0000000000..87cc3c7d1f --- /dev/null +++ b/packages/client/ui-jobs/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Hintergrundaufgabenschnittstelle", + "description": "Zeigen Sie Hintergrundaufgabenlisten, Status und Echtzeitausgabe innerhalb einer Sitzung an." + } +} diff --git a/packages/client/ui-jobs/locale/es.json b/packages/client/ui-jobs/locale/es.json new file mode 100644 index 0000000000..9ce2933127 --- /dev/null +++ b/packages/client/ui-jobs/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de tareas en segundo plano", + "description": "Vea listas de tareas en segundo plano, estados y resultados en tiempo real dentro de una sesión." + } +} diff --git a/packages/client/ui-jobs/locale/fr.json b/packages/client/ui-jobs/locale/fr.json new file mode 100644 index 0000000000..e950919b81 --- /dev/null +++ b/packages/client/ui-jobs/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de tâche en arrière-plan", + "description": "Affichez les listes de tâches en arrière-plan, l'état et la sortie en temps réel au sein d'une session." + } +} diff --git a/packages/client/ui-jobs/locale/pt.json b/packages/client/ui-jobs/locale/pt.json new file mode 100644 index 0000000000..2820658f19 --- /dev/null +++ b/packages/client/ui-jobs/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de tarefa em segundo plano", + "description": "Visualize listas de tarefas em segundo plano, status e resultados em tempo real em uma sessão." + } +} diff --git a/packages/client/ui-jobs/locale/ru.json b/packages/client/ui-jobs/locale/ru.json new file mode 100644 index 0000000000..3d2a910429 --- /dev/null +++ b/packages/client/ui-jobs/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Интерфейс фоновой задачи", + "description": "Просматривайте списки фоновых задач, статус и выходные данные в режиме реального времени в течение сеанса." + } +} diff --git a/packages/client/ui-jobs/src/client/index.ts b/packages/client/ui-jobs/src/client/index.ts index eb5f4d920c..5174aa1fb8 100644 --- a/packages/client/ui-jobs/src/client/index.ts +++ b/packages/client/ui-jobs/src/client/index.ts @@ -12,7 +12,7 @@ import type {} from '@deepseek-ai/dsh-api-job-controller/client' import type {} from '@deepseek-ai/dsh-client-locale/client' import type {} from '@deepseek-ai/dsh-client-ui-renderer/client' import type {} from '@deepseek-ai/dsh-client-ui-session/client' -import { en, ja, NS, zh, type JobKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, NS, zh, type JobKey } from './locales.ts' declare module '@deepseek-ai/dsh-client-ui-slots' { interface LocaleNamespaceMap { @@ -31,7 +31,7 @@ export const inject = ['jobs', 'slots', 'locale'] * @param ctx - client root context. */ export function apply(ctx: ClientContext): void { - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-jobs: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-jobs: dictionaries') ctx.slots.inject( 'conversation.session.header.actions', () => ctx.slots.register({ diff --git a/packages/client/ui-jobs/src/client/locales.ts b/packages/client/ui-jobs/src/client/locales.ts index c1aff15b1c..a978744d96 100644 --- a/packages/client/ui-jobs/src/client/locales.ts +++ b/packages/client/ui-jobs/src/client/locales.ts @@ -137,3 +137,223 @@ export const ja = { 'terminal.expand': '残り {n} 行を表示', 'terminal.expandAria': '折りたたまれた出力 {n} 行を展開', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'count.live.one': 'Trabajo en segundo plano {count} ejecutándose', + 'count.live.other': 'Trabajos en segundo plano {count} en ejecución', + 'count.idle.one': 'Trabajo en segundo plano {count}', + 'count.idle.other': 'Trabajos en segundo plano {count}', + 'list.aria': 'Trabajos en segundo plano', + 'section.live': 'corriendo', + 'section.settledCount': 'Terminado {count}', + 'section.clear': 'Borrar', + 'row.expandAria': 'Mostrar salida en vivo de {label}', + 'row.collapseAria': 'Ocultar salida en vivo de {label}', + 'kill.stop': 'Detener tarea {label}', + 'kill.confirm': 'Haga clic nuevamente para confirmar', + 'kill.confirmAction': 'Confirmar parada', + 'kill.failed': 'Detener falló', + 'status.running': 'corriendo', + 'status.stopping': 'parando', + 'status.completed': 'completado', + 'status.killed': 'cancelado', + 'status.failed': 'falló', + 'duration.seconds': '{seconds}s', + 'duration.minutes': '{minutes}m {seconds}s', + 'duration.hours': '{hours}h {minutes}m', + 'duration.title.live': 'Corriendo para {duration}', + 'duration.title.done': 'Tomó {duration}', + 'output.gap': '… la producción anterior cayó…', + 'output.error': 'transmisión de salida en vivo interrumpida: {error}', + 'terminal.signal': 'señal {signal}', + 'terminal.exitCode': 'salir {code}', + 'terminal.noExitCode': 'sin código de salida', + 'terminal.commandLine': 'Línea de comando {n}', + 'terminal.running': 'corriendo', + 'terminal.failed': 'falló', + 'terminal.done': 'hecho', + 'terminal.copy': 'Copiar', + 'terminal.copied': 'Copiado', + 'terminal.noOutput': '(sin salida)', + 'terminal.collapse': 'Contraer', + 'terminal.collapseAria': 'Contraer salida', + 'terminal.expand': 'Mostrar {n} más líneas', + 'terminal.expandAria': 'Expandir líneas de salida colapsadas {n}', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'count.live.one': "Travail en arrière-plan {count} en cours d'exécution", + 'count.live.other': "Travaux en arrière-plan {count} en cours d'exécution", + 'count.idle.one': 'Travail en arrière-plan {count}', + 'count.idle.other': "Travaux d'arrière-plan {count}", + 'list.aria': 'Travaux en arrière-plan', + 'section.live': 'Courir', + 'section.settledCount': 'Terminé {count}', + 'section.clear': 'Effacer', + 'row.expandAria': 'Afficher la sortie en direct de {label}', + 'row.collapseAria': 'Masquer la sortie en direct de {label}', + 'kill.stop': 'Arrêter la tâche {label}', + 'kill.confirm': 'Cliquez à nouveau pour confirmer', + 'kill.confirmAction': "Confirmer l'arrêt", + 'kill.failed': "L'arrêt a échoué", + 'status.running': 'courir', + 'status.stopping': 'arrêter', + 'status.completed': 'terminé', + 'status.killed': 'annulé', + 'status.failed': 'échoué', + 'duration.seconds': '{seconds}s', + 'duration.minutes': '{minutes}m {seconds}s', + 'duration.hours': '{hours}h {minutes}m', + 'duration.title.live': 'Courir pour {duration}', + 'duration.title.done': 'A pris {duration}', + 'output.gap': '… la production antérieure a chuté…', + 'output.error': 'flux de sortie en direct interrompu : {error}', + 'terminal.signal': 'signal {signal}', + 'terminal.exitCode': 'quitter {code}', + 'terminal.noExitCode': 'pas de code de sortie', + 'terminal.commandLine': 'Ligne de commande {n}', + 'terminal.running': 'courir', + 'terminal.failed': 'échoué', + 'terminal.done': 'fait', + 'terminal.copy': 'Copier', + 'terminal.copied': 'Copié', + 'terminal.noOutput': '(pas de sortie)', + 'terminal.collapse': 'Réduire', + 'terminal.collapseAria': 'Réduire la sortie', + 'terminal.expand': 'Afficher {n} plus de lignes', + 'terminal.expandAria': 'Développer les lignes de sortie réduites {n}', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'count.live.one': '{count} Hintergrundjob läuft', + 'count.live.other': '{count} Hintergrundjobs werden ausgeführt', + 'count.idle.one': '{count} Hintergrundjob', + 'count.idle.other': '{count} Hintergrundjobs', + 'list.aria': 'Hintergrundjobs', + 'section.live': 'Laufen', + 'section.settledCount': 'Fertig {count}', + 'section.clear': 'Klar', + 'row.expandAria': 'Live-Ausgabe von {label} anzeigen', + 'row.collapseAria': 'Live-Ausgabe von {label} ausblenden', + 'kill.stop': 'Stoppen Sie die Aufgabe {label}', + 'kill.confirm': 'Klicken Sie zur Bestätigung erneut', + 'kill.confirmAction': 'Stopp bestätigen', + 'kill.failed': 'Stoppen ist fehlgeschlagen', + 'status.running': 'laufen', + 'status.stopping': 'anhalten', + 'status.completed': 'abgeschlossen', + 'status.killed': 'abgesagt', + 'status.failed': 'gescheitert', + 'duration.seconds': '{seconds}s', + 'duration.minutes': '{minutes}m {seconds}s', + 'duration.hours': '{hours}h {minutes}m', + 'duration.title.live': 'Laufen für {duration}', + 'duration.title.done': 'Nahm {duration}', + 'output.gap': '… frühere Produktion gesunken …', + 'output.error': 'Live-Ausgabestream unterbrochen: {error}', + 'terminal.signal': 'Signal {signal}', + 'terminal.exitCode': 'Beenden Sie {code}', + 'terminal.noExitCode': 'kein Exit-Code', + 'terminal.commandLine': 'Befehlszeile {n}', + 'terminal.running': 'laufen', + 'terminal.failed': 'gescheitert', + 'terminal.done': 'erledigt', + 'terminal.copy': 'Kopieren', + 'terminal.copied': 'Kopiert', + 'terminal.noOutput': '(keine Ausgabe)', + 'terminal.collapse': 'Einklappen', + 'terminal.collapseAria': 'Ausgabe reduzieren', + 'terminal.expand': 'Zeige {n} weitere Zeilen', + 'terminal.expandAria': 'Erweitern Sie die minimierten Ausgabezeilen {n}', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'count.live.one': '{count} фоновое задание выполняется', + 'count.live.other': '{count} выполняются фоновые задания', + 'count.idle.one': '{count} фоновое задание', + 'count.idle.other': '{count} фоновые задания', + 'list.aria': 'Фоновые задания', + 'section.live': 'Бег', + 'section.settledCount': 'Закончено {count}', + 'section.clear': 'Очистить', + 'row.expandAria': 'Показать живой вывод {label}', + 'row.collapseAria': 'Скрыть прямой вывод {label}', + 'kill.stop': 'Остановить задачу {label}', + 'kill.confirm': 'Нажмите еще раз, чтобы подтвердить', + 'kill.confirmAction': 'Подтвердить остановку', + 'kill.failed': 'Остановить не удалось', + 'status.running': 'бег', + 'status.stopping': 'остановка', + 'status.completed': 'завершено', + 'status.killed': 'отменен', + 'status.failed': 'не удалось', + 'duration.seconds': '{seconds}s', + 'duration.minutes': '{minutes}m {seconds}s', + 'duration.hours': '{hours}h {minutes}m', + 'duration.title.live': 'Бегу за {duration}', + 'duration.title.done': 'Взял {duration}', + 'output.gap': '… ранее объемы производства упали …', + 'output.error': 'поток вывода в реальном времени прерван: {error}', + 'terminal.signal': 'сигнал {signal}', + 'terminal.exitCode': 'выход {code}', + 'terminal.noExitCode': 'нет кода выхода', + 'terminal.commandLine': 'Командная строка {n}', + 'terminal.running': 'бег', + 'terminal.failed': 'не удалось', + 'terminal.done': 'сделано', + 'terminal.copy': 'Копировать', + 'terminal.copied': 'Скопировано', + 'terminal.noOutput': '(нет вывода)', + 'terminal.collapse': 'Свернуть', + 'terminal.collapseAria': 'Свернуть вывод', + 'terminal.expand': 'Показать {n} больше строк', + 'terminal.expandAria': 'Развернуть свернутые выходные строки {n}', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'count.live.one': '{count} trabalho em segundo plano em execução', + 'count.live.other': '{count} jobs em segundo plano em execução', + 'count.idle.one': '{count} tarefa em segundo plano', + 'count.idle.other': '{count} trabalhos em segundo plano', + 'list.aria': 'Trabalhos em segundo plano', + 'section.live': 'Correndo', + 'section.settledCount': 'Concluído {count}', + 'section.clear': 'Limpar', + 'row.expandAria': 'Mostrar saída ao vivo de {label}', + 'row.collapseAria': 'Ocultar saída ao vivo de {label}', + 'kill.stop': 'Parar tarefa {label}', + 'kill.confirm': 'Clique novamente para confirmar', + 'kill.confirmAction': 'Confirmar parada', + 'kill.failed': 'Falha na parada', + 'status.running': 'correndo', + 'status.stopping': 'parando', + 'status.completed': 'concluído', + 'status.killed': 'cancelado', + 'status.failed': 'falhou', + 'duration.seconds': '{seconds}s', + 'duration.minutes': '{minutes}m {seconds}s', + 'duration.hours': '{hours}h {minutes}m', + 'duration.title.live': 'Correndo por {duration}', + 'duration.title.done': 'Levou {duration}', + 'output.gap': '… a produção anterior caiu…', + 'output.error': 'transmissão ao vivo interrompida: {error}', + 'terminal.signal': 'sinal {signal}', + 'terminal.exitCode': 'sair {code}', + 'terminal.noExitCode': 'sem código de saída', + 'terminal.commandLine': 'Linha de comando {n}', + 'terminal.running': 'correndo', + 'terminal.failed': 'falhou', + 'terminal.done': 'feito', + 'terminal.copy': 'Copiar', + 'terminal.copied': 'Copiado', + 'terminal.noOutput': '(sem saída)', + 'terminal.collapse': 'Recolher', + 'terminal.collapseAria': 'Recolher saída', + 'terminal.expand': 'Mostrar mais {n} linhas', + 'terminal.expandAria': 'Expanda {n} linhas de saída recolhidas', +} satisfies Record diff --git a/packages/client/ui-layout/locale/de.json b/packages/client/ui-layout/locale/de.json new file mode 100644 index 0000000000..9d6d23789f --- /dev/null +++ b/packages/client/ui-layout/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Layout anwenden", + "description": "Organisieren Sie Navigation, Konversationen und Seitenbereiche und unterstützen Sie das Ziehen, um das Layout anzupassen." + } +} diff --git a/packages/client/ui-layout/locale/es.json b/packages/client/ui-layout/locale/es.json new file mode 100644 index 0000000000..01d553183d --- /dev/null +++ b/packages/client/ui-layout/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Aplicar diseño", + "description": "Organice la navegación, las conversaciones y los paneles laterales, y admita arrastrar para ajustar el diseño." + } +} diff --git a/packages/client/ui-layout/locale/fr.json b/packages/client/ui-layout/locale/fr.json new file mode 100644 index 0000000000..7526ace8cc --- /dev/null +++ b/packages/client/ui-layout/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Appliquer la mise en page", + "description": "Organisez la navigation, les conversations et les panneaux latéraux, et prenez en charge le glisser-déposer pour ajuster la mise en page." + } +} diff --git a/packages/client/ui-layout/locale/pt.json b/packages/client/ui-layout/locale/pt.json new file mode 100644 index 0000000000..10b0dcaae8 --- /dev/null +++ b/packages/client/ui-layout/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Aplicar layout", + "description": "Organize a navegação, as conversas e os painéis laterais e suporte o recurso de arrastar para ajustar o layout." + } +} diff --git a/packages/client/ui-layout/locale/ru.json b/packages/client/ui-layout/locale/ru.json new file mode 100644 index 0000000000..ab90630f4d --- /dev/null +++ b/packages/client/ui-layout/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Применить макет", + "description": "Организуйте навигацию, диалоги и боковые панели, а также поддерживайте перетаскивание для настройки макета." + } +} diff --git a/packages/client/ui-layout/src/client/index.ts b/packages/client/ui-layout/src/client/index.ts index fb66376cfb..ee9da22d2b 100644 --- a/packages/client/ui-layout/src/client/index.ts +++ b/packages/client/ui-layout/src/client/index.ts @@ -18,7 +18,7 @@ import { AppFrame } from './AppFrame.tsx' import { createLayoutStore } from './stores.ts' import { LayoutController } from './service.ts' import type { ShortcutCommandId } from '@deepseek-ai/dsh-client-shortcuts/client' -import { en, ja, zh } from './shortcut-locales.ts' +import { en, ja, es, fr, de, ru, pt, zh } from './shortcut-locales.ts' import { ThemePresenter } from './theme-presenter.ts' // Contract exports only (export-convergence rule: cross-package consumers @@ -156,7 +156,7 @@ export const inject = ['slots', 'theme', 'locale', 'shortcuts'] * @param ctx - client root context. */ export function apply(ctx: ClientContext): void { - ctx.effect(() => ctx.locale.register('shortcuts.layout', { zh, en, ja }), 'layout: command labels') + ctx.effect(() => ctx.locale.register('shortcuts.layout', { zh, en, ja, es, fr, de, ru, pt }), 'layout: command labels') const t = ctx.locale.bind('shortcuts.layout') ctx.effect(() => { diff --git a/packages/client/ui-layout/src/client/shortcut-locales.ts b/packages/client/ui-layout/src/client/shortcut-locales.ts index dcccfc8641..c87cdc5026 100644 --- a/packages/client/ui-layout/src/client/shortcut-locales.ts +++ b/packages/client/ui-layout/src/client/shortcut-locales.ts @@ -7,3 +7,18 @@ export const en: Record = { toggle: 'Toggle left sideba export const ja = { 'toggle': '左サイドバーを切り替え', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { toggle: 'Alternar barra lateral izquierda' } satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { toggle: 'Basculer la barre latérale gauche' } satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { toggle: 'Linke Seitenleiste umschalten' } satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { toggle: 'Переключить левую боковую панель' } satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { toggle: 'Alternar barra lateral esquerda' } satisfies Record diff --git a/packages/client/ui-message-feedback/locale/de.json b/packages/client/ui-message-feedback/locale/de.json new file mode 100644 index 0000000000..71b5fc4559 --- /dev/null +++ b/packages/client/ui-message-feedback/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Nachrichten-Feedback-Schnittstelle", + "description": "Stellen Sie „Gefällt mir“- und „Gefällt mir nicht“-Schaltflächen für Antworten und Popup-Fenster für Gesprächsfeedback bereit." + } +} diff --git a/packages/client/ui-message-feedback/locale/es.json b/packages/client/ui-message-feedback/locale/es.json new file mode 100644 index 0000000000..26672a96ab --- /dev/null +++ b/packages/client/ui-message-feedback/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de comentarios de mensajes", + "description": "Proporcione botones Me gusta y No me gusta para las ventanas emergentes de respuestas y comentarios de la conversación." + } +} diff --git a/packages/client/ui-message-feedback/locale/fr.json b/packages/client/ui-message-feedback/locale/fr.json new file mode 100644 index 0000000000..71009572ad --- /dev/null +++ b/packages/client/ui-message-feedback/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de retour de messages", + "description": "Fournissez des boutons J'aime et Je n'aime pas pour les réponses et les fenêtres contextuelles de commentaires sur la conversation." + } +} diff --git a/packages/client/ui-message-feedback/locale/pt.json b/packages/client/ui-message-feedback/locale/pt.json new file mode 100644 index 0000000000..dcb779d6b0 --- /dev/null +++ b/packages/client/ui-message-feedback/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de feedback de mensagens", + "description": "Forneça botões de gostar e não gostar para respostas e janelas pop-up de feedback de conversas." + } +} diff --git a/packages/client/ui-message-feedback/locale/ru.json b/packages/client/ui-message-feedback/locale/ru.json new file mode 100644 index 0000000000..388f33bf3a --- /dev/null +++ b/packages/client/ui-message-feedback/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Интерфейс обратной связи по сообщениям", + "description": "Предоставьте кнопки «Мне нравится» и «Не нравится» для ответов и всплывающих окон обратной связи." + } +} diff --git a/packages/client/ui-message-feedback/src/client/index.ts b/packages/client/ui-message-feedback/src/client/index.ts index 7d95fe469a..0d22230e13 100644 --- a/packages/client/ui-message-feedback/src/client/index.ts +++ b/packages/client/ui-message-feedback/src/client/index.ts @@ -26,7 +26,7 @@ import { FeedbackDialog } from './FeedbackDialog.tsx' import { MessageFeedbackActions } from './MessageFeedbackActions.tsx' import type { FeedbackDialogInjected, MessageFeedbackInjected } from './slots.ts' import { FeedbackSurface } from './surface.ts' -import { en, ja, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh } from './locales.ts' export type { MessageFeedbackActionFailure, MessageFeedbackActionResult, MessageFeedbackStatus, @@ -66,7 +66,7 @@ export const inject = ['slots', 'remote', 'remote.messageFeedback', 'remote.sess * @param ctx - client root context. */ export function apply(ctx: ClientContext): void { - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-message-feedback: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-message-feedback: dictionaries') const surfaces = new Map() const surfaceFor = (sessionId: SessionId): FeedbackSurface => { diff --git a/packages/client/ui-message-feedback/src/client/locales.ts b/packages/client/ui-message-feedback/src/client/locales.ts index f55054c71d..d5a0fc66e3 100644 --- a/packages/client/ui-message-feedback/src/client/locales.ts +++ b/packages/client/ui-message-feedback/src/client/locales.ts @@ -81,3 +81,123 @@ export const ja = { 'error.generic': 'フィードバックを保存できませんでした', 'error.noteTooLarge': '説明が長すぎます。短くして再送信してください', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'action.like': 'buena respuesta', + 'action.likeActive': 'Eliminar calificación', + 'action.dislike': 'Mala respuesta', + 'action.dislikeActive': 'Eliminar calificación', + 'dialog.title': 'Enviar comentarios', + 'dialog.categories': 'Categoría de comentarios', + 'dialog.detail': 'Detalles de comentarios', + 'dialog.hint': 'Añade detalles para ayudarnos a mejorar. Su envío incluirá el registro de conversación actual.', + 'category.task-result': 'Resultado de la tarea', + 'category.instruction-following': 'Comprensión y seguimiento de instrucciones.', + 'category.product-interaction': 'Características del producto e interacción.', + 'category.service-stability': 'Estabilidad y velocidad', + 'category.resource-cost': 'Uso y costo de recursos', + 'category.security-privacy-permission': 'Seguridad, privacidad y permisos', + 'category.other': 'Otro', + 'toast.recorded': 'Gracias por tus comentarios', + 'error.conflict': 'Esta retroalimentación cambió en otros lugares; se muestra el último estado', + 'error.load': 'No se pudieron cargar los comentarios', + 'error.generic': 'No se pudieron guardar los comentarios', + 'error.noteTooLarge': 'La descripción es demasiado larga; acortarlo y enviarlo de nuevo', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'action.like': 'Bonne réponse', + 'action.likeActive': 'Supprimer la note', + 'action.dislike': 'Mauvaise réponse', + 'action.dislikeActive': 'Supprimer la note', + 'dialog.title': 'Soumettre des commentaires', + 'dialog.categories': 'Catégorie de commentaires', + 'dialog.detail': 'Détails des commentaires', + 'dialog.hint': 'Ajoutez des détails pour nous aider à nous améliorer. Votre soumission inclura le journal de conversation actuel.', + 'category.task-result': 'Résultat de la tâche', + 'category.instruction-following': 'Compréhension et suivi des instructions', + 'category.product-interaction': 'Caractéristiques du produit et interaction', + 'category.service-stability': 'Stabilité et vitesse', + 'category.resource-cost': 'Utilisation et coût des ressources', + 'category.security-privacy-permission': 'Sécurité, confidentialité et autorisations', + 'category.other': 'Autre', + 'toast.recorded': 'Merci pour vos commentaires', + 'error.conflict': 'Cette rétroaction a changé ailleurs ; le dernier état est affiché', + 'error.load': 'Impossible de charger les commentaires', + 'error.generic': "Impossible d'enregistrer les commentaires", + 'error.noteTooLarge': 'La description est trop longue ; raccourcissez-le et soumettez-le à nouveau', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'action.like': 'Gute Resonanz', + 'action.likeActive': 'Bewertung entfernen', + 'action.dislike': 'Schlechte Reaktion', + 'action.dislikeActive': 'Bewertung entfernen', + 'dialog.title': 'Feedback abgeben', + 'dialog.categories': 'Feedback-Kategorie', + 'dialog.detail': 'Feedback-Details', + 'dialog.hint': 'Fügen Sie Details hinzu, um uns bei der Verbesserung zu helfen. Ihre Einreichung enthält das aktuelle Gesprächsprotokoll.', + 'category.task-result': 'Aufgabenergebnis', + 'category.instruction-following': 'Anweisungen verstehen und befolgen', + 'category.product-interaction': 'Produkteigenschaften und Interaktion', + 'category.service-stability': 'Stabilität und Geschwindigkeit', + 'category.resource-cost': 'Ressourcennutzung und Kosten', + 'category.security-privacy-permission': 'Sicherheit, Datenschutz und Berechtigungen', + 'category.other': 'Andere', + 'toast.recorded': 'Vielen Dank für Ihr Feedback', + 'error.conflict': 'Dieses Feedback hat sich an anderer Stelle geändert; der aktuelle Stand wird angezeigt', + 'error.load': 'Feedback konnte nicht geladen werden', + 'error.generic': 'Das Feedback konnte nicht gespeichert werden', + 'error.noteTooLarge': 'Die Beschreibung ist zu lang; kürzen Sie es und reichen Sie es erneut ein', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'action.like': 'Хороший ответ', + 'action.likeActive': 'Удалить оценку', + 'action.dislike': 'Плохой ответ', + 'action.dislikeActive': 'Удалить оценку', + 'dialog.title': 'Отправить отзыв', + 'dialog.categories': 'Категория обратной связи', + 'dialog.detail': 'Подробности обратной связи', + 'dialog.hint': 'Добавьте детали, чтобы помочь нам стать лучше. Ваше сообщение будет включать текущий журнал разговоров.', + 'category.task-result': 'Результат задачи', + 'category.instruction-following': 'Понимание и следование инструкциям', + 'category.product-interaction': 'Особенности продукта и взаимодействие', + 'category.service-stability': 'Стабильность и скорость', + 'category.resource-cost': 'Использование ресурсов и стоимость', + 'category.security-privacy-permission': 'Безопасность, конфиденциальность и разрешения', + 'category.other': 'Другое', + 'toast.recorded': 'Спасибо за ваш отзыв', + 'error.conflict': 'Этот отзыв изменился в другом месте; отображается последнее состояние', + 'error.load': 'Не удалось загрузить отзыв.', + 'error.generic': 'Не удалось сохранить отзыв', + 'error.noteTooLarge': 'Описание слишком длинное; сократите его и отправьте снова', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'action.like': 'Boa resposta', + 'action.likeActive': 'Remover avaliação', + 'action.dislike': 'Resposta ruim', + 'action.dislikeActive': 'Remover avaliação', + 'dialog.title': 'Enviar comentários', + 'dialog.categories': 'Categoria de comentários', + 'dialog.detail': 'Detalhes do feedback', + 'dialog.hint': 'Adicione detalhes para nos ajudar a melhorar. Seu envio incluirá o registro da conversa atual.', + 'category.task-result': 'Resultado da tarefa', + 'category.instruction-following': 'Compreensão e seguimento das instruções', + 'category.product-interaction': 'Recursos e interação do produto', + 'category.service-stability': 'Estabilidade e velocidade', + 'category.resource-cost': 'Uso e custo de recursos', + 'category.security-privacy-permission': 'Segurança, privacidade e permissões', + 'category.other': 'Outro', + 'toast.recorded': 'Obrigado pelo seu feedback', + 'error.conflict': 'Este feedback mudou em outro lugar; o estado mais recente é mostrado', + 'error.load': 'Não foi possível carregar o feedback', + 'error.generic': 'Não foi possível salvar o feedback', + 'error.noteTooLarge': 'A descrição é muito longa; encurte-o e envie novamente', +} satisfies Record diff --git a/packages/client/ui-model-selection/locale/de.json b/packages/client/ui-model-selection/locale/de.json new file mode 100644 index 0000000000..c37cd4ec24 --- /dev/null +++ b/packages/client/ui-model-selection/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Schnittstelle zur Modellauswahl", + "description": "Sehen Sie sich die verfügbaren Modelle an und wechseln Sie das von der aktuellen Sitzung verwendete Modell." + } +} diff --git a/packages/client/ui-model-selection/locale/es.json b/packages/client/ui-model-selection/locale/es.json new file mode 100644 index 0000000000..4ce95350a1 --- /dev/null +++ b/packages/client/ui-model-selection/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de selección de modelo", + "description": "Vea los modelos disponibles y cambie el modelo utilizado por la sesión actual." + } +} diff --git a/packages/client/ui-model-selection/locale/fr.json b/packages/client/ui-model-selection/locale/fr.json new file mode 100644 index 0000000000..bc3548d52e --- /dev/null +++ b/packages/client/ui-model-selection/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de sélection de modèle", + "description": "Affichez les modèles disponibles et changez le modèle utilisé par la session en cours." + } +} diff --git a/packages/client/ui-model-selection/locale/pt.json b/packages/client/ui-model-selection/locale/pt.json new file mode 100644 index 0000000000..17caef7c92 --- /dev/null +++ b/packages/client/ui-model-selection/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de seleção de modelo", + "description": "Visualize os modelos disponíveis e alterne o modelo usado pela sessão atual." + } +} diff --git a/packages/client/ui-model-selection/locale/ru.json b/packages/client/ui-model-selection/locale/ru.json new file mode 100644 index 0000000000..572c9b5541 --- /dev/null +++ b/packages/client/ui-model-selection/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Интерфейс выбора модели", + "description": "Просмотрите доступные модели и переключите модель, используемую в текущем сеансе." + } +} diff --git a/packages/client/ui-model-selection/src/client/index.ts b/packages/client/ui-model-selection/src/client/index.ts index ae47f156ed..f1f15a1154 100644 --- a/packages/client/ui-model-selection/src/client/index.ts +++ b/packages/client/ui-model-selection/src/client/index.ts @@ -27,7 +27,7 @@ import type { ModelDirectoryState } from './directory.ts' import { ModelDirectoryResolver } from './service.ts' import type { ModelSelectInjected } from './slots.ts' import { ModelSelect } from './ModelSelect.tsx' -import { en, ja, zh, type ModelKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh, type ModelKey } from './locales.ts' import { orderModelProviders } from './provider-order.ts' export { ModelDirectory } from './directory.ts' @@ -113,7 +113,7 @@ export const inject = ['commandUi', 'locale', 'sessions', 'slots', 'remote', 're * @param ctx - client root context. */ export function apply(ctx: ClientContext): void { - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-model-selection: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-model-selection: dictionaries') // Non-slot faces (the command description, the popup option builder) read // through the bound translate; the seat component reads the standard seat. diff --git a/packages/client/ui-model-selection/src/client/locales.ts b/packages/client/ui-model-selection/src/client/locales.ts index 4e931226ea..cb2749f9a9 100644 --- a/packages/client/ui-model-selection/src/client/locales.ts +++ b/packages/client/ui-model-selection/src/client/locales.ts @@ -91,3 +91,138 @@ export const ja = { 'empty.models': '利用可能なモデルがありません。', 'empty.efforts': 'このモデルには推論強度の設定がありません。', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'provider.account': 'Cuenta DeepSeek', + 'command.label': 'modelo', + 'command.description': 'Selecciona el modelo para esta conversación', + 'option.loadError': 'No se pudo cargar el catálogo: {message}', + 'trigger.fallback': 'Seleccionar modelo', + 'trigger.loading': 'Cargando modelos…', + 'trigger.selectAria': 'Seleccionar modelo', + 'trigger.aria': 'Seleccionar modelo, actual {model}', + 'trigger.ariaEffort': 'Seleccionar modelo, {model} actual, esfuerzo de razonamiento {effort}', + 'menu.aria': 'Esfuerzo de modelo y razonamiento.', + 'menu.model': 'modelo', + 'menu.effort': 'Esfuerzo', + 'effort.providerDefault': 'Predeterminado', + 'status.loading': 'Lista de modelos refrescante...', + 'error.action': 'Error en la operación del modelo: {message}', + 'error.sessionInUse': 'Esta sesión ya está en uso, posiblemente por otra instancia de DSH en ejecución (como la web dsh o la aplicación de escritorio). Salga de otras instancias de DSH en ejecución y vuelva a intentarlo.', + 'action.reload': 'recargar', + 'warning.groupLoad': '{name} no pudo cargar: {message}', + 'search.placeholder': 'Buscar modelos…', + 'search.clear': 'Borrar búsqueda', + 'search.empty': 'No hay modelos coincidentes.', + 'empty.models': 'No hay modelos disponibles.', + 'empty.efforts': 'Este modelo no proporciona niveles de esfuerzo de razonamiento.', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'provider.account': 'Compte DeepSeek', + 'command.label': 'Modèle', + 'command.description': 'Sélectionnez le modèle pour cette conversation', + 'option.loadError': 'Échec du chargement du catalogue : {message}', + 'trigger.fallback': 'Sélectionnez le modèle', + 'trigger.loading': 'Chargement des modèles…', + 'trigger.selectAria': 'Sélectionnez le modèle', + 'trigger.aria': 'Sélectionnez le modèle, {model} actuel', + 'trigger.ariaEffort': 'Sélectionnez le modèle, {model} actuel, effort de raisonnement {effort}', + 'menu.aria': 'Effort de modélisation et de raisonnement', + 'menu.model': 'Modèle', + 'menu.effort': 'Effort', + 'effort.providerDefault': 'Par défaut', + 'status.loading': 'Liste des modèles actualisée…', + 'error.action': "Échec de l'opération du modèle : {message}", + 'error.sessionInUse': "Cette session est déjà utilisée, éventuellement par une autre instance DSH en cours d'exécution (telle que le Web dsh ou l'application de bureau). Quittez les autres instances DSH en cours d'exécution et réessayez.", + 'action.reload': 'Recharger', + 'warning.groupLoad': 'Échec du chargement de {name} : {message}', + 'search.placeholder': 'Rechercher des modèles…', + 'search.clear': 'Effacer la recherche', + 'search.empty': 'Aucun modèle correspondant.', + 'empty.models': 'Aucun modèle disponible.', + 'empty.efforts': 'Ce modèle ne fournit aucun niveau d’effort de raisonnement.', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'provider.account': 'DeepSeek-Konto', + 'command.label': 'Modell', + 'command.description': 'Wählen Sie das Modell für dieses Gespräch aus', + 'option.loadError': 'Katalog konnte nicht geladen werden: {message}', + 'trigger.fallback': 'Modell auswählen', + 'trigger.loading': 'Modelle werden geladen…', + 'trigger.selectAria': 'Modell auswählen', + 'trigger.aria': 'Modell auswählen, aktuell {model}', + 'trigger.ariaEffort': 'Modell auswählen, aktuell {model}, Argumentationsaufwand {effort}', + 'menu.aria': 'Modell- und Argumentationsaufwand', + 'menu.model': 'Modell', + 'menu.effort': 'Aufwand', + 'effort.providerDefault': 'Standard', + 'status.loading': 'Erfrischende Modellliste…', + 'error.action': 'Modellvorgang fehlgeschlagen: {message}', + 'error.sessionInUse': 'Diese Sitzung wird bereits verwendet, möglicherweise von einer anderen laufenden DSH-Instanz (z. B. dsh Web oder der Desktop-App). Beenden Sie andere laufende DSH-Instanzen und versuchen Sie es erneut.', + 'action.reload': 'Neu laden', + 'warning.groupLoad': '{name} konnte nicht geladen werden: {message}', + 'search.placeholder': 'Modelle suchen…', + 'search.clear': 'Suche löschen', + 'search.empty': 'Keine passenden Modelle.', + 'empty.models': 'Keine Modelle verfügbar.', + 'empty.efforts': 'Dieses Modell liefert keine Argumentationsaufwandsstufen.', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'provider.account': 'DeepSeek Аккаунт', + 'command.label': 'Модель', + 'command.description': 'Выберите модель для этого разговора', + 'option.loadError': 'Не удалось загрузить каталог: {message}.', + 'trigger.fallback': 'Выберите модель', + 'trigger.loading': 'Загрузка моделей…', + 'trigger.selectAria': 'Выберите модель', + 'trigger.aria': 'Выберите модель, текущую {model}', + 'trigger.ariaEffort': 'Выберите модель, текущую версию {model}, аргументацию {effort}', + 'menu.aria': 'Модель и рассуждения', + 'menu.model': 'Модель', + 'menu.effort': 'Усилие', + 'effort.providerDefault': 'По умолчанию', + 'status.loading': 'Обновление списка моделей…', + 'error.action': 'Не удалось выполнить операцию модели: {message}.', + 'error.sessionInUse': 'Этот сеанс уже используется, возможно, другим работающим экземпляром DSH (например, веб-сайтом dsh или настольным приложением). Закройте другие работающие экземпляры DSH и повторите попытку.', + 'action.reload': 'Перезагрузить', + 'warning.groupLoad': '{name} не удалось загрузить: {message}', + 'search.placeholder': 'Поиск моделей…', + 'search.clear': 'Очистить поиск', + 'search.empty': 'Нет подходящих моделей.', + 'empty.models': 'Нет доступных моделей.', + 'empty.efforts': 'Эта модель не обеспечивает обоснования уровней усилий.', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'provider.account': 'DeepSeek Conta', + 'command.label': 'Modelo', + 'command.description': 'Selecione o modelo para esta conversa', + 'option.loadError': 'Falha ao carregar o catálogo: {message}', + 'trigger.fallback': 'Selecione o modelo', + 'trigger.loading': 'Carregando modelos…', + 'trigger.selectAria': 'Selecione o modelo', + 'trigger.aria': 'Selecione o modelo, atual {model}', + 'trigger.ariaEffort': 'Selecione modelo, atual {model}, esforço de raciocínio {effort}', + 'menu.aria': 'Modelo e esforço de raciocínio', + 'menu.model': 'Modelo', + 'menu.effort': 'Esforço', + 'effort.providerDefault': 'Padrão', + 'status.loading': 'Atualizando lista de modelos…', + 'error.action': 'Falha na operação do modelo: {message}', + 'error.sessionInUse': 'Esta sessão já está em uso, possivelmente por outra instância DSH em execução (como dsh web ou aplicativo de desktop). Saia de outras instâncias DSH em execução e tente novamente.', + 'action.reload': 'Recarregar', + 'warning.groupLoad': '{name} falhou ao carregar: {message}', + 'search.placeholder': 'Pesquisar modelos…', + 'search.clear': 'Limpar pesquisa', + 'search.empty': 'Não há modelos correspondentes.', + 'empty.models': 'Nenhum modelo disponível.', + 'empty.efforts': 'Este modelo não fornece níveis de esforço de raciocínio.', +} satisfies Record diff --git a/packages/client/ui-open-in-app/locale/de.json b/packages/client/ui-open-in-app/locale/de.json new file mode 100644 index 0000000000..f5b24225cb --- /dev/null +++ b/packages/client/ui-open-in-app/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Schnittstelle zum Öffnen externer Anwendungen", + "description": "Bietet den Eintrag „Öffnen mit“ in der Sitzungs- und Dokumentvorschau." + } +} diff --git a/packages/client/ui-open-in-app/locale/es.json b/packages/client/ui-open-in-app/locale/es.json new file mode 100644 index 0000000000..1164cb3c6b --- /dev/null +++ b/packages/client/ui-open-in-app/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de apertura de aplicaciones externas", + "description": "Proporciona entrada \"Abrir con\" en la sesión y vista previa del documento." + } +} diff --git a/packages/client/ui-open-in-app/locale/fr.json b/packages/client/ui-open-in-app/locale/fr.json new file mode 100644 index 0000000000..5f104625e3 --- /dev/null +++ b/packages/client/ui-open-in-app/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface d'ouverture d'application externe", + "description": "Fournit une entrée « Ouvrir avec » dans la session et un aperçu du document." + } +} diff --git a/packages/client/ui-open-in-app/locale/pt.json b/packages/client/ui-open-in-app/locale/pt.json new file mode 100644 index 0000000000..105759e7e0 --- /dev/null +++ b/packages/client/ui-open-in-app/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de abertura de aplicativo externo", + "description": "Fornece entrada \"Abrir com\" na sessão e visualização do documento." + } +} diff --git a/packages/client/ui-open-in-app/locale/ru.json b/packages/client/ui-open-in-app/locale/ru.json new file mode 100644 index 0000000000..2655015ac7 --- /dev/null +++ b/packages/client/ui-open-in-app/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Интерфейс открытия внешнего приложения", + "description": "Обеспечивает запись «Открыть с помощью» в сеансе и предварительном просмотре документа." + } +} diff --git a/packages/client/ui-open-in-app/src/client/index.ts b/packages/client/ui-open-in-app/src/client/index.ts index db99a2a23e..8da9f15f9e 100644 --- a/packages/client/ui-open-in-app/src/client/index.ts +++ b/packages/client/ui-open-in-app/src/client/index.ts @@ -25,7 +25,7 @@ import { OpenInAppPathController } from './open-path.ts' import { OpenPathAction, type OpenPathInjected } from './OpenPathAction.tsx' import { FileRouteAction } from './FileRouteAction.tsx' import { OpenPathEmptyAction } from './OpenPathEmptyAction.tsx' -import { en, ja, NS, zh, type OpenInAppKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, NS, zh, type OpenInAppKey } from './locales.ts' declare module '@deepseek-ai/dsh-client-ui-slots' { interface LocaleNamespaceMap { @@ -51,7 +51,7 @@ export function apply(ctx: ClientContext): void { const controller = new OpenInAppController() void controller.load() const paths = new OpenInAppPathController(ctx.remote) - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'open-in-app: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'open-in-app: dictionaries') const t = ctx.locale.bind(NS) const target = () => { if (ctx.layout.panelInfo.getSnapshot().activePanelId !== null) return undefined diff --git a/packages/client/ui-open-in-app/src/client/locales.ts b/packages/client/ui-open-in-app/src/client/locales.ts index f43d4746bb..5cf52790f1 100644 --- a/packages/client/ui-open-in-app/src/client/locales.ts +++ b/packages/client/ui-open-in-app/src/client/locales.ts @@ -99,3 +99,103 @@ export const ja = { 'app.filemanager': 'ファイル', 'app.terminal': 'ターミナル', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'open.title': 'Abierto en {app}', + 'path.appDefault': '{app} (predeterminado)', + 'path.appsError': 'No se pudieron cargar aplicaciones', + 'shortcut.busy': 'Abrir espacio de trabajo', + 'shortcut.unavailable': 'El espacio de trabajo actual o la aplicación local no están disponibles', + 'open.tooltip': 'Abierto localmente', + 'path.open': 'Abrir', + 'path.more': 'Más formas de abrir', + 'path.reveal': 'Mostrar ubicación del archivo', + 'path.openError': 'No se pudo abrir. Intentar otra vez.', + 'path.revealError': 'No se pudo mostrar la ubicación del archivo. Intentar otra vez.', + ...PRODUCT_NAMES, + 'app.finder': 'Buscador', + 'app.explorer': 'Explorador de archivos', + 'app.filemanager': 'Archivos', + 'app.terminal': 'terminales', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'open.title': 'Ouvrir dans {app}', + 'path.appDefault': '{app} (par défaut)', + 'path.appsError': 'Impossible de charger les applications', + 'shortcut.busy': "Ouverture de l'espace de travail", + 'shortcut.unavailable': 'Espace de travail actuel ou application locale indisponible', + 'open.tooltip': 'Ouvrir localement', + 'path.open': 'Ouvrir', + 'path.more': "Plus de façons d'ouvrir", + 'path.reveal': "Afficher l'emplacement du fichier", + 'path.openError': "Impossible d'ouvrir. Essayer à nouveau.", + 'path.revealError': "Impossible d'afficher l'emplacement du fichier. Essayer à nouveau.", + ...PRODUCT_NAMES, + 'app.finder': 'Chercheur', + 'app.explorer': 'Explorateur de fichiers', + 'app.filemanager': 'Fichiers', + 'app.terminal': 'Borne', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'open.title': 'Öffnen Sie in {app}', + 'path.appDefault': '{app} (Standard)', + 'path.appsError': 'Anwendungen konnten nicht geladen werden', + 'shortcut.busy': 'Arbeitsbereich öffnen', + 'shortcut.unavailable': 'Aktueller Arbeitsbereich oder lokale Anwendung nicht verfügbar', + 'open.tooltip': 'Vor Ort geöffnet', + 'path.open': 'Öffnen', + 'path.more': 'Mehr Möglichkeiten zum Öffnen', + 'path.reveal': 'Dateispeicherort anzeigen', + 'path.openError': 'Konnte nicht geöffnet werden. Versuchen Sie es erneut.', + 'path.revealError': 'Der Dateispeicherort konnte nicht angezeigt werden. Versuchen Sie es erneut.', + ...PRODUCT_NAMES, + 'app.finder': 'Finder', + 'app.explorer': 'Datei-Explorer', + 'app.filemanager': 'Dateien', + 'app.terminal': 'Terminal', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'open.title': 'Открыть в {app}', + 'path.appDefault': '{app} (по умолчанию)', + 'path.appsError': 'Не удалось загрузить приложения', + 'shortcut.busy': 'Открытие рабочей области', + 'shortcut.unavailable': 'Текущая рабочая область или локальное приложение недоступно.', + 'open.tooltip': 'Открыть локально', + 'path.open': 'Открыть', + 'path.more': 'Больше способов открыть', + 'path.reveal': 'Показать местоположение файла', + 'path.openError': 'Не удалось открыть. Попробуйте еще раз.', + 'path.revealError': 'Не удалось показать местоположение файла. Попробуйте еще раз.', + ...PRODUCT_NAMES, + 'app.finder': 'Искатель', + 'app.explorer': 'Проводник файлов', + 'app.filemanager': 'Файлы', + 'app.terminal': 'Терминал', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'open.title': 'Abrir em {app}', + 'path.appDefault': '{app} (padrão)', + 'path.appsError': 'Não foi possível carregar aplicativos', + 'shortcut.busy': 'Abrindo espaço de trabalho', + 'shortcut.unavailable': 'Espaço de trabalho atual ou aplicativo local indisponível', + 'open.tooltip': 'Abrir localmente', + 'path.open': 'Abrir', + 'path.more': 'Mais maneiras de abrir', + 'path.reveal': 'Mostrar localização do arquivo', + 'path.openError': 'Não foi possível abrir. Tente novamente.', + 'path.revealError': 'Não foi possível mostrar o local do arquivo. Tente novamente.', + ...PRODUCT_NAMES, + 'app.finder': 'Localizador', + 'app.explorer': 'Explorador de arquivos', + 'app.filemanager': 'Arquivos', + 'app.terminal': 'Terminais', +} satisfies Record diff --git a/packages/client/ui-permission-presets/locale/de.json b/packages/client/ui-permission-presets/locale/de.json new file mode 100644 index 0000000000..0f2614b5c2 --- /dev/null +++ b/packages/client/ui-permission-presets/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Schnittstelle für den Berechtigungsmodus", + "description": "Legt die Standardberechtigungen für neue Sitzungen fest und wechselt den Berechtigungsmodus für die aktuelle Sitzung." + } +} diff --git a/packages/client/ui-permission-presets/locale/es.json b/packages/client/ui-permission-presets/locale/es.json new file mode 100644 index 0000000000..aed991a5c6 --- /dev/null +++ b/packages/client/ui-permission-presets/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de modo de permiso", + "description": "Establece los permisos predeterminados para nuevas sesiones y cambia el modo de permisos para la sesión actual." + } +} diff --git a/packages/client/ui-permission-presets/locale/fr.json b/packages/client/ui-permission-presets/locale/fr.json new file mode 100644 index 0000000000..8119ff4849 --- /dev/null +++ b/packages/client/ui-permission-presets/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface du mode autorisation", + "description": "Définit les autorisations par défaut pour les nouvelles sessions et change le mode d'autorisations pour la session en cours." + } +} diff --git a/packages/client/ui-permission-presets/locale/pt.json b/packages/client/ui-permission-presets/locale/pt.json new file mode 100644 index 0000000000..fc65c0a5d0 --- /dev/null +++ b/packages/client/ui-permission-presets/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface do modo de permissão", + "description": "Define as permissões padrão para novas sessões e alterna o modo de permissões para a sessão atual." + } +} diff --git a/packages/client/ui-permission-presets/locale/ru.json b/packages/client/ui-permission-presets/locale/ru.json new file mode 100644 index 0000000000..74ad24f1d4 --- /dev/null +++ b/packages/client/ui-permission-presets/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Интерфейс режима разрешений", + "description": "Устанавливает разрешения по умолчанию для новых сеансов и переключает режим разрешений для текущего сеанса." + } +} diff --git a/packages/client/ui-permission-presets/src/client/index.ts b/packages/client/ui-permission-presets/src/client/index.ts index 940b5baa3f..8f4d98c854 100644 --- a/packages/client/ui-permission-presets/src/client/index.ts +++ b/packages/client/ui-permission-presets/src/client/index.ts @@ -41,7 +41,7 @@ import type { PermissionSelectInjected } from './PermissionSelect.tsx' import { PermissionRow } from './PermissionRow.tsx' import type { PermissionRowInjected } from './PermissionRow.tsx' import { - accessEn, accessJa, accessZh, en, ja, PERMISSION_ACCESS_NS, zh, + accessEn, accessJa, accessEs, accessFr, accessDe, accessRu, accessPt, accessZh, en, ja, es, fr, de, ru, pt, PERMISSION_ACCESS_NS, zh, } from './locales.ts' import { AUTO_REVIEW_PRESET, displayPermissionPreset, FULL_ACCESS_PRESET, @@ -113,7 +113,16 @@ function optionsOf( export function apply(ctx: ClientContext): void { const command = ctx.get('commandUi') as CommandUiContract const sessions = ctx.sessions - const accessDictionaries = { zh: accessZh, en: accessEn, ja: accessJa } + const accessDictionaries = { + zh: accessZh, + en: accessEn, + ja: accessJa, + es: accessEs, + fr: accessFr, + de: accessDe, + ru: accessRu, + pt: accessPt, + } ctx.effect( () => ctx.locale.register(PERMISSION_ACCESS_NS, accessDictionaries), 'ui-permission: current-session dictionaries', @@ -142,7 +151,7 @@ export function apply(ctx: ClientContext): void { 'ui-permission: dismiss stale slash choices', ) - ctx.effect(() => ctx.locale.register('settings.permission', { zh, en, ja }), 'ui-permission: settings row dictionaries') + ctx.effect(() => ctx.locale.register('settings.permission', { zh, en, ja, es, fr, de, ru, pt }), 'ui-permission: settings row dictionaries') // The shared ConfigForm mirror updates after document commits and reconnects. const controller = new PermissionPresetSettingsController( diff --git a/packages/client/ui-permission-presets/src/client/locales.ts b/packages/client/ui-permission-presets/src/client/locales.ts index 792c1d5605..9fe5025f87 100644 --- a/packages/client/ui-permission-presets/src/client/locales.ts +++ b/packages/client/ui-permission-presets/src/client/locales.ts @@ -99,6 +99,86 @@ export const ja = { 'confirm.enable': 'フルアクセスを有効にする', } satisfies Record +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'title': 'Permiso', + 'description': 'Elija el modo de permiso predeterminado para nuevas sesiones', + 'loading': 'Cargando', + 'unavailable': 'No disponible', + 'preset.readOnly': 'Sólo lectura', + 'preset.workspaceWrite': 'Escritura en el espacio de trabajo', + 'preset.fullAccess': 'Acceso completo', + 'confirm.title': '¿Habilitar acceso completo?', + 'confirm.description': 'El acceso completo permite que las nuevas sesiones reduzcan los pasos de confirmación y realicen más acciones directamente, incluidas operaciones confidenciales, cambios de archivos o comandos externos. Úselo sólo cuando confíe en las tareas posteriores.', + 'confirm.acknowledge': 'Entiendo los riesgos y quiero continuar.', + 'confirm.cancel': 'Cancelar', + 'confirm.enable': 'Habilitar acceso completo', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'title': 'Autorisation', + 'description': "Choisissez le mode d'autorisation par défaut pour les nouvelles sessions", + 'loading': 'Chargement', + 'unavailable': 'Indisponible', + 'preset.readOnly': 'Lecture seule', + 'preset.workspaceWrite': "Écriture dans l'espace de travail", + 'preset.fullAccess': 'Accès complet', + 'confirm.title': "Activer l'accès complet ?", + 'confirm.description': "L'accès complet permet aux nouvelles sessions de réduire les étapes de confirmation et d'effectuer directement davantage d'actions, notamment des opérations sensibles, des modifications de fichiers ou des commandes externes. Utilisez-le uniquement lorsque vous faites confiance aux tâches suivantes.", + 'confirm.acknowledge': 'Je comprends les risques et je veux continuer', + 'confirm.cancel': 'Annuler', + 'confirm.enable': "Activer l'accès complet", +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'title': 'Erlaubnis', + 'description': 'Wählen Sie den Standardberechtigungsmodus für neue Sitzungen', + 'loading': 'Laden', + 'unavailable': 'Nicht verfügbar', + 'preset.readOnly': 'Nur lesen', + 'preset.workspaceWrite': 'Arbeitsbereich schreiben', + 'preset.fullAccess': 'Voller Zugriff', + 'confirm.title': 'Vollzugriff aktivieren?', + 'confirm.description': 'Durch den vollständigen Zugriff können neue Sitzungen die Bestätigungsschritte reduzieren und mehr Aktionen direkt ausführen, einschließlich vertraulicher Vorgänge, Dateiänderungen oder externer Befehle. Verwenden Sie es nur, wenn Sie nachfolgenden Aufgaben vertrauen.', + 'confirm.acknowledge': 'Ich verstehe die Risiken und möchte weitermachen', + 'confirm.cancel': 'Abbrechen', + 'confirm.enable': 'Aktivieren Sie Vollzugriff', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'title': 'Разрешение', + 'description': 'Выберите режим разрешений по умолчанию для новых сеансов', + 'loading': 'Загрузка', + 'unavailable': 'Недоступно', + 'preset.readOnly': 'Только чтение', + 'preset.workspaceWrite': 'Запись в рабочей области', + 'preset.fullAccess': 'Полный доступ', + 'confirm.title': 'Включить полный доступ?', + 'confirm.description': 'Полный доступ позволяет новым сеансам сократить количество шагов подтверждения и напрямую выполнять больше действий, включая конфиденциальные операции, изменение файлов или внешние команды. Используйте его только в том случае, если вы доверяете последующим задачам.', + 'confirm.acknowledge': 'Я понимаю риски и хочу продолжить', + 'confirm.cancel': 'Отмена', + 'confirm.enable': 'Включить полный доступ', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'title': 'Permissão', + 'description': 'Escolha o modo de permissão padrão para novas sessões', + 'loading': 'Carregando', + 'unavailable': 'Indisponível', + 'preset.readOnly': 'Somente leitura', + 'preset.workspaceWrite': 'Gravação no espaço de trabalho', + 'preset.fullAccess': 'Acesso total', + 'confirm.title': 'Ativar acesso total?', + 'confirm.description': 'O acesso total permite que novas sessões reduzam as etapas de confirmação e executem mais ações diretamente, incluindo operações confidenciais, alterações de arquivos ou comandos externos. Use-o apenas quando confiar nas tarefas subsequentes.', + 'confirm.acknowledge': 'Entendo os riscos e quero continuar', + 'confirm.cancel': 'Cancelar', + 'confirm.enable': 'Ativar acesso total', +} satisfies Record + /** Japanese copy, checked against the English keys. */ export const accessJa = { 'mode': 'アクセスモード、現在: {name}', @@ -119,3 +199,108 @@ export const accessJa = { 'auto.confirm.acknowledge': 'これらのリスクを理解し、続行します', 'auto.confirm.enable': '自動認可レビューを有効にする', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const accessEs = { + 'mode': 'Modo de acceso, actual: {name}', + 'close': 'Cerrar', + 'preset.readOnly': 'Sólo lectura', + 'preset.workspaceWrite': 'Escritura en el espacio de trabajo', + 'preset.fullAccess': 'Acceso completo', + 'confirm.title': '¿Habilitar acceso completo?', + 'confirm.description': 'El acceso completo reduce los pasos de confirmación y permite al agente realizar más acciones directamente, incluidas operaciones confidenciales, cambios de archivos o comandos externos. Úselo solo cuando confíe en la tarea actual.', + 'confirm.acknowledge': 'Entiendo los riesgos y quiero continuar.', + 'confirm.cancel': 'Cancelar', + 'confirm.enable': 'Habilitar acceso completo', + 'auto.label': 'Auto review', + 'auto.badge': 'EXP', + 'auto.description': 'Ejecute sin una zona de pruebas después de una revisión experimental del mismo modelo de cada llamada de herramienta nativa y llamada interna PTC.', + 'auto.confirm.title': '¿Habilitar Auto review (experimental)?', + 'auto.confirm.description': 'Auto review se ejecuta sin zona de pruebas. Antes de cada llamada a la herramienta nativa y llamada interna PTC, el mismo modelo que el agente actual revisa si se permite; usted aprueba o rechaza cada llamada que rechaza. Esta característica es experimental, puede permitir o denegar acciones falsamente y utiliza tokens adicionales.', + 'auto.confirm.acknowledge': 'Entiendo estos riesgos y quiero continuar', + 'auto.confirm.enable': 'Habilitar Auto review', +} satisfies typeof accessEn + +/** French dictionary, checked against the English keys. */ +export const accessFr = { + 'mode': "Mode d'accès, actuel : {name}", + 'close': 'Fermer', + 'preset.readOnly': 'Lecture seule', + 'preset.workspaceWrite': "Écriture dans l'espace de travail", + 'preset.fullAccess': 'Accès complet', + 'confirm.title': "Activer l'accès complet ?", + 'confirm.description': "L'accès complet réduit les étapes de confirmation et permet à l'agent d'effectuer directement davantage d'actions, notamment des opérations sensibles, des modifications de fichiers ou des commandes externes. Utilisez-le uniquement lorsque vous faites confiance à la tâche en cours.", + 'confirm.acknowledge': 'Je comprends les risques et je veux continuer', + 'confirm.cancel': 'Annuler', + 'confirm.enable': "Activer l'accès complet", + 'auto.label': 'Auto review', + 'auto.badge': 'EXP', + 'auto.description': "Exécutez sans bac à sable après un examen expérimental sur le même modèle de chaque appel d'outil natif et appel interne PTC.", + 'auto.confirm.title': 'Activer Auto review (expérimental) ?', + 'auto.confirm.description': "Auto review fonctionne sans bac à sable. Avant chaque appel d'outil natif et appel interne PTC, le même modèle que l'agent actuel vérifie s'il doit l'autoriser ; vous approuvez ou rejetez chaque appel qu'il refuse. Cette fonctionnalité est expérimentale, peut autoriser ou refuser à tort des actions et utilise des jetons supplémentaires.", + 'auto.confirm.acknowledge': 'Je comprends ces risques et je veux continuer', + 'auto.confirm.enable': 'Activer Auto review', +} satisfies typeof accessEn + +/** German dictionary, checked against the English keys. */ +export const accessDe = { + 'mode': 'Zugriffsmodus, aktuell: {name}', + 'close': 'Schließen', + 'preset.readOnly': 'Nur lesen', + 'preset.workspaceWrite': 'Arbeitsbereich schreiben', + 'preset.fullAccess': 'Voller Zugriff', + 'confirm.title': 'Vollzugriff aktivieren?', + 'confirm.description': 'Durch den Vollzugriff werden Bestätigungsschritte reduziert und der Agent kann mehr Aktionen direkt ausführen, einschließlich vertraulicher Vorgänge, Dateiänderungen oder externer Befehle. Verwenden Sie es nur, wenn Sie der aktuellen Aufgabe vertrauen.', + 'confirm.acknowledge': 'Ich verstehe die Risiken und möchte weitermachen', + 'confirm.cancel': 'Abbrechen', + 'confirm.enable': 'Aktivieren Sie Vollzugriff', + 'auto.label': 'Auto review', + 'auto.badge': 'EXP', + 'auto.description': 'Ausführung ohne Sandbox nach einer experimentellen, modellgleichen Überprüfung jedes nativen Toolaufrufs und PTC-Innenaufrufs.', + 'auto.confirm.title': 'Auto review aktivieren (experimentell)?', + 'auto.confirm.description': 'Auto review läuft ohne Sandbox. Vor jedem nativen Tool-Aufruf und PTC-Innenaufruf überprüft dasselbe Modell wie der aktuelle Agent, ob dies zulässig ist. Sie genehmigen oder lehnen jeden abgelehnten Aufruf ab. Diese Funktion ist experimentell, kann Aktionen fälschlicherweise zulassen oder verweigern und verwendet zusätzliche Token.', + 'auto.confirm.acknowledge': 'Ich verstehe diese Risiken und möchte weitermachen', + 'auto.confirm.enable': 'Aktivieren Sie Auto review', +} satisfies typeof accessEn + +/** Russian dictionary, checked against the English keys. */ +export const accessRu = { + 'mode': 'Режим доступа, текущий: {name}', + 'close': 'Закрыть', + 'preset.readOnly': 'Только чтение', + 'preset.workspaceWrite': 'Запись в рабочей области', + 'preset.fullAccess': 'Полный доступ', + 'confirm.title': 'Включить полный доступ?', + 'confirm.description': 'Полный доступ сокращает количество шагов подтверждения и позволяет агенту напрямую выполнять больше действий, включая конфиденциальные операции, изменения файлов или внешние команды. Используйте его только в том случае, если вы доверяете текущей задаче.', + 'confirm.acknowledge': 'Я понимаю риски и хочу продолжить', + 'confirm.cancel': 'Отмена', + 'confirm.enable': 'Включить полный доступ', + 'auto.label': 'Auto review', + 'auto.badge': 'EXP', + 'auto.description': 'Запуск без песочницы после экспериментальной проверки одной и той же модели каждого вызова встроенного инструмента и внутреннего вызова PTC.', + 'auto.confirm.title': 'Включить Auto review (экспериментально)?', + 'auto.confirm.description': 'Auto review работает без песочницы. Перед каждым вызовом собственного инструмента и внутренним вызовом PTC та же модель, что и текущий агент, проверяет, разрешить ли это; вы одобряете или отклоняете каждый вызов, который он отклоняет. Эта функция является экспериментальной, может ошибочно разрешать или запрещать действия и использует дополнительные токены.', + 'auto.confirm.acknowledge': 'Я понимаю эти риски и хочу продолжить', + 'auto.confirm.enable': 'Включить Auto review', +} satisfies typeof accessEn + +/** Portuguese dictionary, checked against the English keys. */ +export const accessPt = { + 'mode': 'Modo de acesso, atual: {name}', + 'close': 'Fechar', + 'preset.readOnly': 'Somente leitura', + 'preset.workspaceWrite': 'Gravação no espaço de trabalho', + 'preset.fullAccess': 'Acesso total', + 'confirm.title': 'Ativar acesso total?', + 'confirm.description': 'O acesso total reduz as etapas de confirmação e permite que o agente execute mais ações diretamente, incluindo operações confidenciais, alterações de arquivos ou comandos externos. Use-o apenas quando confiar na tarefa atual.', + 'confirm.acknowledge': 'Entendo os riscos e quero continuar', + 'confirm.cancel': 'Cancelar', + 'confirm.enable': 'Ativar acesso total', + 'auto.label': 'Auto review', + 'auto.badge': 'EXP', + 'auto.description': 'Execute sem um sandbox após uma revisão experimental do mesmo modelo de cada chamada de ferramenta nativa e PTC chamada interna.', + 'auto.confirm.title': 'Ativar Auto review (experimental)?', + 'auto.confirm.description': 'Auto review é executado sem sandbox. Antes de cada chamada de ferramenta nativa e chamada interna PTC, o mesmo modelo do agente atual analisa se deve permitir isso; você aprova ou rejeita cada chamada negada. Este recurso é experimental, pode permitir ou negar ações falsamente e usa tokens adicionais.', + 'auto.confirm.acknowledge': 'Entendo esses riscos e quero continuar', + 'auto.confirm.enable': 'Ativar Auto review', +} satisfies typeof accessEn diff --git a/packages/client/ui-plan/locale/de.json b/packages/client/ui-plan/locale/de.json new file mode 100644 index 0000000000..ce90df31f6 --- /dev/null +++ b/packages/client/ui-plan/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Schnittstelle zur Planüberprüfung", + "description": "Zeigt Steuerelemente für den Planungsmodus, Planungskarten und eine Markdown-Vorschau an." + } +} diff --git a/packages/client/ui-plan/locale/es.json b/packages/client/ui-plan/locale/es.json new file mode 100644 index 0000000000..1bc8dde649 --- /dev/null +++ b/packages/client/ui-plan/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de revisión del plan", + "description": "Muestra controles del modo de planificación, tarjetas de planificación y vista previa de Markdown." + } +} diff --git a/packages/client/ui-plan/locale/fr.json b/packages/client/ui-plan/locale/fr.json new file mode 100644 index 0000000000..165c62a645 --- /dev/null +++ b/packages/client/ui-plan/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de révision des plans", + "description": "Affiche les commandes du mode planification, les cartes de planification et l'aperçu Markdown." + } +} diff --git a/packages/client/ui-plan/locale/pt.json b/packages/client/ui-plan/locale/pt.json new file mode 100644 index 0000000000..1ad0ee2f88 --- /dev/null +++ b/packages/client/ui-plan/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de revisão do plano", + "description": "Mostra controles do modo de planejamento, cartões de planejamento e visualização do Markdown." + } +} diff --git a/packages/client/ui-plan/locale/ru.json b/packages/client/ui-plan/locale/ru.json new file mode 100644 index 0000000000..08eba25394 --- /dev/null +++ b/packages/client/ui-plan/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Интерфейс проверки плана", + "description": "Показывает элементы управления режимом планирования, карты планирования и предварительный просмотр Markdown." + } +} diff --git a/packages/client/ui-plan/src/client/index.ts b/packages/client/ui-plan/src/client/index.ts index 1b226f8a37..34196a00da 100644 --- a/packages/client/ui-plan/src/client/index.ts +++ b/packages/client/ui-plan/src/client/index.ts @@ -25,7 +25,7 @@ import { planAddress, parsePlanAddress } from './plan.ts' import { isReviewPreviewAddress, reviewPreviewAddress } from './review-preview.ts' import { createPlanReviewStore } from './review-store.ts' import { PlanChip } from './PlanModeControl.tsx' -import { en, ja, zh, type PlanKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh, type PlanKey } from './locales.ts' export type { PlanKey } from './locales.ts' @@ -56,7 +56,7 @@ export const inject = ['slots', 'remote', 'remote.commands', 'remote.session', ' * @param ctx - client root context. */ export function apply(ctx: ClientContext): void { - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-plan: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-plan: dictionaries') const previewId = '@deepseek-ai/dsh-client-ui-plan' const t = ctx.locale.bind(NS) diff --git a/packages/client/ui-plan/src/client/locales.ts b/packages/client/ui-plan/src/client/locales.ts index 331fdb5234..5940519fa2 100644 --- a/packages/client/ui-plan/src/client/locales.ts +++ b/packages/client/ui-plan/src/client/locales.ts @@ -65,3 +65,108 @@ export const ja = { 'chip.on.title': '計画モードはオンです — クリックでオフ (/plan off)', 'chip.exitFailed': '計画モードを終了できませんでした', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'chip.label': 'Planificar', + 'preview.title': 'Planificar', + 'preview.document': 'Plano · Markdown', + 'preview.action': 'Abrir', + 'preview.open': 'Plan abierto en la barra lateral', + 'preview.full': 'Ver plano completo', + 'preview.openNamed': 'Plan abierto: {title}', + 'preview.loading': 'Cargando plan…', + 'preview.failed': 'No se pudo cargar el plan', + 'preview.invalidAddress': 'Dirección del plan no válida', + 'preview.historyUnavailable': 'El historial de sesiones no está disponible', + 'preview.notFound': 'Este plan no fue encontrado.', + 'preview.unavailable': 'La vista previa del plan no está disponible', + 'preview.expired': 'Esta vista previa del plan temporal ha caducado. Vuelva a abrirlo desde la tarjeta de revisión pendiente.', + 'chip.on.aria': 'Modo plan activado, presione para apagar', + 'chip.on.title': 'Modo de planificación activado: haga clic para desactivar (/plan off)', + 'chip.exitFailed': 'No se pudo salir del modo de plan', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'chip.label': 'Planifier', + 'preview.title': 'Planifier', + 'preview.document': 'Plan · Markdown', + 'preview.action': 'Ouvrir', + 'preview.open': 'Plan ouvert dans la barre latérale', + 'preview.full': 'Voir le forfait complet', + 'preview.openNamed': 'Plan ouvert : {title}', + 'preview.loading': 'Plan de chargement…', + 'preview.failed': 'Impossible de charger le plan', + 'preview.invalidAddress': 'Adresse du forfait invalide', + 'preview.historyUnavailable': "L'historique des sessions n'est pas disponible", + 'preview.notFound': "Ce plan n'a pas été trouvé", + 'preview.unavailable': "L'aperçu du plan n'est pas disponible", + 'preview.expired': 'Cet aperçu du plan temporaire a expiré. Rouvrez-le à partir de la carte de révision en attente.', + 'chip.on.aria': 'Mode Plan activé, appuyez pour désactiver', + 'chip.on.title': 'Mode Plan activé — cliquez pour désactiver (/plan off)', + 'chip.exitFailed': 'Échec de la sortie du mode Plan', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'chip.label': 'Planen', + 'preview.title': 'Planen', + 'preview.document': 'Plan · Markdown', + 'preview.action': 'Öffnen', + 'preview.open': 'Plan in der Seitenleiste öffnen', + 'preview.full': 'Vollständigen Plan anzeigen', + 'preview.openNamed': 'Offener Grundriss: {title}', + 'preview.loading': 'Ladeplan…', + 'preview.failed': 'Plan konnte nicht geladen werden', + 'preview.invalidAddress': 'Ungültige Planadresse', + 'preview.historyUnavailable': 'Der Sitzungsverlauf ist nicht verfügbar', + 'preview.notFound': 'Dieser Plan wurde nicht gefunden', + 'preview.unavailable': 'Die Planvorschau ist nicht verfügbar', + 'preview.expired': 'Diese temporäre Planvorschau ist abgelaufen. Öffnen Sie es erneut über die ausstehende Überprüfungskarte.', + 'chip.on.aria': 'Planmodus ein, zum Ausschalten drücken', + 'chip.on.title': 'Planmodus ein – zum Ausschalten klicken (/plan off)', + 'chip.exitFailed': 'Der Planmodus konnte nicht beendet werden', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'chip.label': 'План', + 'preview.title': 'План', + 'preview.document': 'План · Markdown', + 'preview.action': 'Открыть', + 'preview.open': 'Открытая планировка в боковой панели', + 'preview.full': 'Посмотреть полный план', + 'preview.openNamed': 'Открытая планировка: {title}', + 'preview.loading': 'План загрузки…', + 'preview.failed': 'Не удалось загрузить план', + 'preview.invalidAddress': 'Неверный адрес плана', + 'preview.historyUnavailable': 'История сеансов недоступна', + 'preview.notFound': 'Этот план не найден', + 'preview.unavailable': 'Предварительный просмотр плана недоступен.', + 'preview.expired': 'Срок действия этой временной предварительной версии плана истек. Откройте его снова из карточки ожидающего рассмотрения.', + 'chip.on.aria': 'Режим планирования включен. Нажмите, чтобы выключить.', + 'chip.on.title': 'Режим планирования включен — нажмите, чтобы выключить (/plan off)', + 'chip.exitFailed': 'Не удалось выйти из режима планирования.', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'chip.label': 'Plano', + 'preview.title': 'Plano', + 'preview.document': 'Plano · Markdown', + 'preview.action': 'Abrir', + 'preview.open': 'Abrir plano na barra lateral', + 'preview.full': 'Ver plano completo', + 'preview.openNamed': 'Plano aberto: {title}', + 'preview.loading': 'Carregando plano…', + 'preview.failed': 'Não foi possível carregar o plano', + 'preview.invalidAddress': 'Endereço do plano inválido', + 'preview.historyUnavailable': 'O histórico da sessão não está disponível', + 'preview.notFound': 'Este plano não foi encontrado', + 'preview.unavailable': 'A visualização do plano não está disponível', + 'preview.expired': 'Esta visualização temporária do plano expirou. Reabra-o no cartão de revisão pendente.', + 'chip.on.aria': 'Modo de planejamento ativado, pressione para desligar', + 'chip.on.title': 'Modo de planejamento ativado – clique para desligar (/plan off)', + 'chip.exitFailed': 'Falha ao sair do modo de plano', +} satisfies Record diff --git a/packages/client/ui-plugin-manager/locale/de.json b/packages/client/ui-plugin-manager/locale/de.json new file mode 100644 index 0000000000..16a03e8049 --- /dev/null +++ b/packages/client/ui-plugin-manager/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Plug-in-Verwaltungsschnittstelle", + "description": "Plug-in-Pakete anzeigen und installieren sowie Vorgänge aktivieren, deaktivieren und wiederholen." + } +} diff --git a/packages/client/ui-plugin-manager/locale/es.json b/packages/client/ui-plugin-manager/locale/es.json new file mode 100644 index 0000000000..3ca20e033d --- /dev/null +++ b/packages/client/ui-plugin-manager/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de gestión de complementos", + "description": "Vea e instale paquetes de complementos y habilite, deshabilite y reintente operaciones." + } +} diff --git a/packages/client/ui-plugin-manager/locale/fr.json b/packages/client/ui-plugin-manager/locale/fr.json new file mode 100644 index 0000000000..48bf4551cd --- /dev/null +++ b/packages/client/ui-plugin-manager/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de gestion des plug-ins", + "description": "Affichez et installez les packages de plug-ins, puis activez, désactivez et réessayez les opérations." + } +} diff --git a/packages/client/ui-plugin-manager/locale/pt.json b/packages/client/ui-plugin-manager/locale/pt.json new file mode 100644 index 0000000000..f1e246b3a2 --- /dev/null +++ b/packages/client/ui-plugin-manager/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de gerenciamento de plug-ins", + "description": "Visualize e instale pacotes de plug-ins e ative, desative e repita as operações." + } +} diff --git a/packages/client/ui-plugin-manager/locale/ru.json b/packages/client/ui-plugin-manager/locale/ru.json new file mode 100644 index 0000000000..155d905c69 --- /dev/null +++ b/packages/client/ui-plugin-manager/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Интерфейс управления плагинами", + "description": "Просмотрите и установите пакеты подключаемых модулей, а также включите, отключите и повторите операции." + } +} diff --git a/packages/client/ui-plugin-manager/src/client/index.ts b/packages/client/ui-plugin-manager/src/client/index.ts index 54dce2da8b..f5908227a4 100644 --- a/packages/client/ui-plugin-manager/src/client/index.ts +++ b/packages/client/ui-plugin-manager/src/client/index.ts @@ -30,7 +30,7 @@ import { PluginsPanelIcon } from './PluginsPanelIcon.tsx' import { configLedgerSource } from './config-ledger.ts' import { tabLedgerSource } from './tab-ledger.ts' import { PluginManagerController } from './manager-store.ts' -import { en, ja, zh, type PluginManagerLocaleKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh, type PluginManagerLocaleKey } from './locales.ts' import { createNavigationStore } from './navigation-store.ts' import type {} from './slot-contract.ts' @@ -92,7 +92,7 @@ export const inject = ['slots', 'locale', 'remote', 'remote.pluginManager', 'rem * @param ctx - the browser plugin context. */ export function apply(ctx: ClientContext): void { - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-plugin-manager: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-plugin-manager: dictionaries') const t = ctx.locale.bind(NS) const controller = new PluginManagerController(ctx) ctx.effect(() => () => { controller.dispose() }, 'ui-plugin-manager: controller') diff --git a/packages/client/ui-plugin-manager/src/client/locales.ts b/packages/client/ui-plugin-manager/src/client/locales.ts index 912baa2c35..a871ab3692 100644 --- a/packages/client/ui-plugin-manager/src/client/locales.ts +++ b/packages/client/ui-plugin-manager/src/client/locales.ts @@ -880,3 +880,1458 @@ export const ja = { 'detailFailed': '詳細を読み込めませんでした。', 'detailFootnotes': '脚注', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + panel: 'Complementos', + title: 'Complementos', + intro: 'Instalar, habilitar y configurar complementos', + infoLabel: 'Acerca de los complementos', + infoDescription: 'Configure complementos oficiales e instale o administre otros complementos aquí. Vea la lista de complementos integrados y el estado del tiempo de ejecución en Configuración → Complementos integrados.', + loading: 'Leyendo complementos…', + error: 'No se pudieron leer todos los complementos, posiblemente debido a un problema de red', + unavailable: 'Esta implementación se ejecuta sin un perfil manejable, por lo que los complementos no se pueden instalar ni cambiar aquí.', + retry: 'Reintentar', + refresh: 'Actualizar', + refreshError: 'Error al actualizar. Por favor inténtalo de nuevo.', + empty: 'Aún no hay complementos instalados.', + addPlugin: 'Agregar complemento', + chooseAddMethod: 'Elija cómo agregar un complemento', + installExisting: 'Instalar un complemento de terceros', + installExistingDescription: 'Admite paquetes npm, repositorios Git y directorios locales', + restartNotice: 'Reinicie DSH para aplicar el cambio. {reason}', + restartReasonNoHmr: 'Este perfil aplica cambios solo al inicio.', + restartReasonPackageMoved: 'Un paquete instalado ahora se resuelve en otro directorio o el cambio reemplaza un paquete que proporciona la instalación de DSH. Desinstale un paquete antes de instalarlo desde otra ubicación.', + restartReasonHostModule: 'El cambio llega a los módulos DSH propiamente cargados.', + restartReasonUnmanagedPlugin: 'El cambio afecta a un complemento que se ejecuta fuera de la lista de complementos.', + restartReasonModuleComparison: 'DSH no pudo comparar los complementos cargados con sus archivos.', + overriddenNotice: '{name} se guardó, pero una configuración de mayor prioridad lo anula, por lo que no está vigente', + bundlesTitle: 'Complementos instalados', + basicTitle: 'Configuración del complemento incorporado', + extensionsTitle: 'Complementos experimentales', + moreTitle: 'Complementos experimentales', + moreAction: 'Más', + tabsLabel: 'Vistas de complementos', + installedTab: 'Instalado', + statusProblem: 'problema', + statusBeta: 'Experimental', + reasonLabel: 'Razón', + metadataError: 'Error de metadatos del paquete: {error}', + versionTag: 'v{version}', + partsLabel: 'Componentes', + sourceTitle: 'Fuente', + sourceSpec: 'fuente del código', + sourceBuiltIn: 'Construido en', + sourceVersion: 'Versión actual', + partsEmpty: 'Este paquete de complementos no contiene componentes.', + partsCountTotal: '{count} total', + partsCountRunning: '{count} corriendo', + partsCountOff: '{count} apagado', + partOff: 'Apagado', + partsCountFailed: '{count} falló', + partsFilter: 'Componentes del filtro', + partsFilterEmpty: 'Ningún componente coincide.', + partToggle: 'Habilitar componente {name}', + rowPhasePending: 'Esperando dependencias', + rowPhaseLoading: 'Cargando', + rowPhaseActive: 'corriendo', + rowPhaseFailed: 'problema', + rowPhaseUnloading: 'Descarga', + enableToggle: 'Habilitar {name}', + applyingChange: 'Aplicar cambios a {name}', + openDetail: 'Ver {name}', + backToList: 'Volver a complementos', + crumbRoot: 'Complementos', + backToPackage: 'Volver a {name}', + configureRow: 'Configurar {name}', + rowStateIdle: 'no corriendo', + uninstall: 'Desinstalar', + uninstallLabel: 'Desinstalar {name}', + installTitle: 'Agregar complemento', + installDescription: 'Ingrese el nombre del paquete del complemento, la dirección del repositorio GitHub o la ruta del directorio local.', + installSpecLabel: 'Nombre o dirección del paquete', + installSpecPlaceholder: 'por ejemplo dsh-plugin-ballena-mascota', + installGuideToggle: 'Guía de instalación y ejemplos.', + installGuideHide: 'Ocultar la guía', + installGuideIdTitle: 'Ingrese el nombre del paquete npm del complemento', + installGuideIdExample: 'dsh-plugin-ballena-mascota', + installGuideIdHint: 'El nombre del paquete del complemento es el nombre del paquete npm (como dsh-xxx o @author/plugin): la parte después de dsh plugin add o pnpm add en el comando de instalación README de un complemento comunitario.', + installGuideExampleLabel: 'Ejemplo: ', + installGitTemplateHint: 'Reemplace esto con la dirección real del repositorio de Git.', + installPathTemplateHint: 'Reemplace esto con la ruta real a su directorio de complementos local.', + installGuideFill: 'ejemplo de uso', + installGuideFillAria: 'Utilice el ejemplo {example}', + installGuideSafety: 'Instale sólo complementos en los que confíe: se ejecutan con sus permisos y pueden dañar DeepSeek Harness o filtrar sus datos.', + installUpgradeNotice: 'Los complementos oficiales bajo demanda ofrecen actualización cuando su versión difiere de DSH. Para actualizar otros complementos, desinstálelos y vuelva a instalarlos.', + registryToggle: 'Registro', + registryLegend: 'El registro npm desde el que se descarga el complemento', + registryDefault: 'Registro predeterminado', + registryOfficial: 'Registro oficial de npm', + registryNpmmirror: 'Espejo de China continental', + registryCustom: 'Dirección personalizada', + registryCustomPlaceholder: 'https://npm.example.com/', + registryCustomHint: 'Ingrese una dirección de registro npm interna o privada que comience con http:// o https://.. Si requiere iniciar sesión, almacene las credenciales en ~/.npmrc en esta máquina.', + registryCustomInvalid: 'Introduzca una dirección que comience con http:// o https://', + registryListSeparator: ', ', + sentenceSeparator: ' ', + installRun: 'Instalar', + installChecking: 'Comprobando…', + installConfirmedTitle: 'Instalar complemento', + installConfirmedRefused: 'Este complemento no se puede instalar', + installProblemInvalid: 'Este no es un nombre o dirección de paquete que se pueda instalar: {reason}', + installProblemInstalled: 'Este complemento ya está instalado. Para actualizarlo, desinstálelo e instálelo nuevamente.', + installProblemShipped: 'Este complemento se envía con DSH; actualizar DSH lo actualiza', + installBundledTitle: 'Este complemento se envía con DSH', + installBundledDescription: 'Habilítelo sin descargar otra copia', + installProblemNotFound: 'No se encontró tal complemento', + installProblemNotPackage: 'La ruta no existe o no es un paquete de complemento válido', + installProblemNotBundle: 'Este paquete no declara ningún paquete, por lo que no se puede instalar como complemento: {reason}', + installProblemNetwork: 'No se pudo acceder al registro del complemento; comprueba la red y vuelve a intentarlo', + installProblemNetworkAll: 'No se pudo acceder a ningún registro (probado: {registries}); verifique la configuración de red o proxy, o cambie el registro', + installProblemUnknown: 'No se pudo buscar el complemento: {reason}', + installingTitle: 'Instalando el complemento…', + installedTitle: 'Instalado', + statusNotInstalled: 'No instalado', + statusMissingFiles: 'Paquete no disponible', + statusUpdateAvailable: 'Actualización disponible', + sourceNotInstalled: 'No instalado', + sourceTargetSpec: 'Fuente de este DSH', + sourceTargetVersion: 'Versión para este DSH', + update: 'Actualizar', + updateLabel: 'Actualización {name}', + versionsTitle: 'Versiones', + versionsRecheck: 'comprobar de nuevo', + versionsChecking: 'Buscando actualizaciones', + versionsAvailable: 'Actualización a {version} disponible', + versionsPublished: 'Publicado {date}', + versionsLatest: 'actualizado', + versionsCheckedAt: 'Última comprobación en {time}', + versionsBlocked: 'Las versiones más nuevas necesitan una actualización DSH', + versionsBlockedDetail: '{version} necesita {peers}; este DSH es {runtime}', + versionsNoneInstallable: 'No hay una versión más nueva para instalar directamente', + versionsNoneInstallableDetail: 'Las versiones más recientes están obsoletas, son versiones preliminares o no declaran ningún paquete. Ampliar para verlos', + versionsFailedNetwork: 'No se pudo acceder al registro', + versionsFailedOther: 'No se pudo buscar actualizaciones', + versionsDetails: 'Detalles', + versionsNewerCount: '{count} más nuevo', + versionsCollapse: 'Contraer', + versionsInstalledTag: 'Instalado', + versionsPrereleaseTag: 'Presentación', + versionsDeprecatedTag: 'En desuso', + versionsNeedsDsh: 'Necesita {peers}', + versionsNotBundle: 'Esta versión no declara ningún paquete y no se puede instalar.', + versionsUpdateLabel: 'Actualización a {version}', + versionsRegistry: 'Registro', + versionsCheckedAtLabel: 'Comprobado en', + versionsFallbackTag: 'Respaldo', + versionsFallbackHint: 'No se pudo alcanzar {registry}; la lista proviene de un registro alternativo', + versionsPrimaryTag: 'primero', + versionsShowPrerelease: 'Mostrar presentaciones preliminares', + versionsOmitted: '{count} no se enumeran más versiones más recientes que la instalada', + versionsProblemNetwork: 'Inalcanzable', + versionsProblemNotFound: 'No encontrado', + versionsProblemUnknown: 'Fallido', + updatesAvailable: 'Actualizaciones disponibles: {count}', + updatesNone: 'Todos los complementos están actualizados.', + updatesFailed: 'Algunos complementos no se pudieron verificar', + updateTitle: 'Actualización {name}', + updateSource: 'Instalar desde', + updateDescription: 'La actualización reemplaza {from} por {to}; el complemento puede detenerse brevemente. Si la instalación falla, {from} se conserva o se vuelve a instalar.', + updateRunning: 'Actualizando', + updateStepChecking: 'Comprobar {version}', + updateStepRemoving: 'Detener y eliminar {version}', + updateStepInstalling: 'Instale {version} desde {registry}', + updateStepRestoring: 'Instale {version} nuevamente', + updateDone: 'Actualizado a {version}', + updateDoneDetail: 'La nueva versión se está ejecutando.', + updateRestart: '{version} instalado; entra en vigor después de un reinicio', + updateRefused: 'No se puede actualizar a {version}', + updateRemoveFailed: 'No se pudo eliminar {version}', + updateRestored: 'La actualización falló; restaurado {version}', + updateRestoredDetail: '{to} no pudo instalarse; {from} se instaló nuevamente.', + updateKept: 'No se pudo actualizar a {version}', + updateKeptDetail: '{from} no se eliminó y permanece en uso. {reason}', + updateBroken: 'La actualización falló; el complemento no está instalado', + updateBrokenDetail: '{to} no se pudo instalar y la instalación de {from} nuevamente también falló. Instale {name} nuevamente desde Agregar complemento.', + updateLost: 'Se desconoce el resultado de la actualización.', + updateLostDetail: 'Se interrumpió la conexión con DSH: {reason}. Actualice la lista de complementos para ver la versión instalada.', + updateOutput: 'Mostrar resultado de instalación', + updateFinish: 'hecho', + installFailedTitle: 'No se pudo instalar el complemento', + installGithubFailedTitle: 'No se puede acceder a GitHub', + installGithubTimeoutTitle: 'Se agotó el tiempo de espera de la conexión GitHub', + installGithubFailedDescription: 'Pruebe con otra fuente de instalación.', + installUseGithubMirror: 'Utilice el espejo de China continental', + installTryAnotherWay: 'Prueba de otra manera', + installPackageLabel: 'Nombre del paquete del complemento', + installEdit: 'Editar', + installEditAria: 'Volver a editar', + installCancelAndEdit: 'Cancelar la instalación y volver a editar', + installApplyingCancellationError: 'La cancelación no fue confirmada. Se está aplicando la instalación; espera su resultado. {reason}', + installReconcile: 'Verificar el estado de la instalación', + installUnknownTitle: 'El resultado de la instalación no está disponible', + installUnknownDescription: 'El Host no tiene ninguna instalación activa con esta identificación de solicitud. Consulte la lista de complementos antes de volver a intentarlo.', + installResultUnconfirmed: 'No se recibió el resultado de la instalación. Verificar el estado de la instalación. {reason}', + installAwaitingAcceptance: 'Esperando que el Host acepte la instalación. La cancelación se volverá a intentar automáticamente después de la confirmación.', + installBackgroundUnknown: 'El resultado de la instalación no está disponible. Consulte la lista de complementos.', + installCancel: 'Cancelar instalación', + installCloseCancels: 'Cancelar instalación y cerrar', + installViewTask: 'Ver instalación', + installUnconfirmedTitle: 'Estado de instalación no confirmado', + installBackgroundDone: 'Instalación finalizada. Ver detalles de instalación.', + installBackgroundFailed: 'La instalación falló. Ver detalles de instalación.', + installBackgroundUnconfirmed: 'El estado de la instalación no está confirmado. Vea la instalación para más detalles.', + installBackgroundApplying: 'La instalación se está aplicando y no se puede cancelar. Ver el progreso de la instalación.', + installStarting: 'Preparando la instalación…', + installCancelling: 'Deteniendo la instalación…', + installApplying: 'Aplicando configuración, espere...', + installCancelledShort: 'Cancelado', + installCancelled: 'Instalación cancelada; el complemento no está habilitado y los archivos descargados pueden permanecer', + installCancelUnconfirmed: 'No se ha confirmado que la instalación se haya detenido. Vuelva a intentar la cancelación o espere el resultado de la instalación. {reason}', + installEnableNow: 'Habilitar ahora', + installDetailsShow: 'Mostrar detalles de instalación', + installDetailsHide: 'Ocultar detalles de instalación', + installVersion: 'Versión {version}', + installSubjectPath: 'directorio local', + installSubjectGit: 'repositorio git', + installSubjectTarball: 'bola de tar', + installLocation: 'Se instala en {dir}', + installRetry: 'Reintentar', + installChangeRegistry: 'Cambiar registro', + installAttempt: '{previous} no pudo entregar el paquete; reintentando a través de {registry} (registro {index} de {total})', + installAttemptBadge: 'Intento {index} · {registry}', + installFailureNetwork: 'La conexión de red falló', + installFailureNetworkAll: 'No se pudo acceder a ningún registro (probado: {registries}). Verifique la configuración de red o proxy, o cambie el registro y vuelva a intentarlo.', + installFailureNetworkHost: 'No se pudo contactar con {host}. Una dirección GitHub o un enlace .tgz no se recupera a través del registro: esta máquina debe llegar directamente o mediante un proxy. Si el complemento también está publicado en npm, ingrese el nombre del paquete.', + installFailureNotFound: 'No se encontró tal complemento', + installFailureNoMatchingVersion: 'Ninguna versión coincide con la solicitud', + installFailureDiskFull: 'El disco está lleno; la instalación se detuvo', + installFailurePermission: 'Sin permiso de escritura; el complemento no se puede instalar', + installFailureBuildBlocked: 'Los scripts de instalación de una dependencia necesitan su permiso antes de que la instalación pueda continuar', + installFailureBuildBlockedManual: 'pnpm bloqueó los scripts de instalación; permítalos en enableBuilds en pnpm-workspace.yaml y vuelva a intentarlo', + installFailureIntegrity: 'El paquete descargado no pasó la verificación de integridad', + installFailureTimeout: 'La instalación expiró', + installFailurePnpmMissing: 'No se encontró pnpm, por lo que no se puede instalar nada.', + installFailureGeneric: 'Algo salió mal durante la instalación; los detalles dicen lo que', + terminalCommandLine: 'Línea de comando {n}', + terminalRunning: 'corriendo', + terminalFailed: 'Fallido', + terminalDone: 'hecho', + terminalCopy: 'Copiar', + terminalCopied: 'Copiado', + terminalNoOutput: 'Sin salida', + terminalCollapseAria: 'Contraer salida', + terminalCollapse: 'Contraer', + terminalExpandAria: 'Expanda las líneas de salida {n} restantes', + terminalExpand: '… {n} más líneas', + terminalExitCode: 'código de salida {code}', + terminalSignal: 'señal {signal}', + terminalNoExitCode: 'sin código de salida', + installDoneNothing: 'Instalación finalizada sin nuevas dependencias.', + installDoneRestart: 'Instalado; reinicie DSH para cargarlo. {reason}', + installDoneApproved: 'Instalar scripts permitidos para {names}', + installDoneOtherVersion: 'Según la política de seguridad de la cadena de suministro de pnpm (minimumReleaseAge), las versiones publicadas más recientemente que la antigüedad requerida no se instalan automáticamente, por lo que esta instalación utilizó {installed} en lugar de la última versión {version}. Una versión recién publicada no ha completado este período de espera y puede contener códigos maliciosos o defectos no detectados. Si necesita {version}, desinstale la versión actual y luego instale {exact} para solicitar esa versión.', + installApprovalTitle: 'Instalar scripts necesita permiso', + installApprovalDescription: 'Estos paquetes tienen scripts de instalación que pnpm no ejecutó.', + installApprovalConsequence: 'Una vez permitidos, los scripts se ejecutan aquí con sus permisos y el permiso se guarda en este perfil.', + installApprovalCaution: 'Permita solo paquetes en los que confíe.', + installApproveAndRetry: 'Permita estos scripts y vuelva a intentarlo', + installClose: 'hecho', + close: 'Cerrar', + cancel: 'Cancelar', + confirmUninstallTitle: '¿Desinstalar "{name}"?', + confirmUninstallDescription: 'Lo que proporciona desaparece una vez que se desinstala.', + confirmUninstall: 'Desinstalar', + failedEnable: 'No se pudo habilitar: {reason}', + failedDisable: 'No se pudo desactivar: {reason}', + failedUninstall: 'No se pudo desinstalar: {reason}', + failedRowEnable: 'No se pudo habilitar el componente: {reason}', + failedRowDisable: 'No se pudo desactivar el componente: {reason}', + reasonManagementRequired: 'La gestión de complementos lo necesita; no se puede apagar ni desinstalar.', + reasonUnaddressable: 'El parche de perfil no puede abordar este de forma única.', + reasonUnknownPlugin: 'No existe tal complemento.', + reasonInvalidSpec: 'Ingrese un nombre o dirección de paquete válido.', + reasonAlreadyInstalled: 'Este paquete ya está instalado; desinstálelo antes de instalar otra versión.', + reasonAmbiguousInstall: 'No se puede saber qué paquete se instaló a partir del cambio de dependencia.', + reasonNotBundle: 'Este paquete no declara ningún paquete, por lo que no se puede administrar como un complemento.', + reasonNotRemovable: 'Este paquete no es propiedad del perfil o la administración del complemento lo necesita.', + reasonStopProfile: 'Este perfil se ejecuta sin HMR; deténgalo y desinstale el paquete con el complemento dsh.', + reasonBundleInUse: 'Otra configuración todavía usa los componentes de este paquete; apáguelos primero.', + reasonStaleApproval: 'Las aprobaciones de guiones pendientes cambiaron; instálelo nuevamente para actualizarlos.', + reasonIncompatibleVersion: '{plugin} es incompatible con DSH {runtime} (requiere {requirements}); ejecutarlo puede causar fallas o pérdida de datos.', + reasonIncompatibleVersionUnnamed: 'Este complemento es incompatible con la versión DSH en ejecución; ejecutarlo puede causar fallas o pérdida de datos.', + reasonIncompatibleInstall: 'Instale una versión del complemento compatible con este DSH.', + reasonIncompatibleInstalled: 'Desinstálalo e instala una versión compatible con este DSH.', + reasonOperationError: 'El anfitrión informó un error.', + detailTitle: 'Detalles', + detailLoading: 'Detalles de lectura', + detailTooLarge: 'Los detalles exceden el límite de tamaño y no se cargaron.', + detailNetwork: 'No se pudo llegar a la fuente de los detalles.', + detailInvalid: 'El complemento declara un archivo de detalles no válido.', + detailFailed: 'No se pudieron leer los detalles.', + detailFootnotes: 'Notas a pie de página', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + panel: 'Plugins', + title: 'Plugins', + intro: 'Installer, activer et configurer les plugins', + infoLabel: 'À propos des plugins', + infoDescription: "Configurez les plugins officiels et installez ou gérez d'autres plugins ici. Affichez la liste des plugins intégrés et l'état d'exécution dans Paramètres → Plugins intégrés.", + loading: 'Plugins de lecture…', + error: "Impossible de lire tous les plugins, probablement à cause d'un problème de réseau", + unavailable: "Ce déploiement s'exécute sans profil gérable, les plugins ne peuvent donc pas être installés ou commutés ici.", + retry: 'Réessayer', + refresh: 'Actualiser', + refreshError: "L'actualisation a échoué. Veuillez réessayer.", + empty: "Aucun plugin n'est encore installé.", + addPlugin: 'Ajouter un plugin', + chooseAddMethod: 'Choisissez comment ajouter un plugin', + installExisting: 'Installer un plugin tiers', + installExistingDescription: 'Prend en charge les packages npm, les référentiels Git et les répertoires locaux', + restartNotice: 'Redémarrez DSH pour appliquer la modification. {reason}', + restartReasonNoHmr: 'Ce profil applique les modifications uniquement au démarrage.', + restartReasonPackageMoved: "Un package installé est désormais résolu dans un autre répertoire ou la modification remplace un package fourni par l'installation de DSH. Désinstallez un package avant de l’installer à partir d’un autre emplacement.", + restartReasonHostModule: 'Le changement atteint les modules DSH lui-même chargés.', + restartReasonUnmanagedPlugin: 'La modification atteint un plugin exécuté en dehors de la liste des plugins.', + restartReasonModuleComparison: "DSH n'a pas pu comparer les plugins chargés avec leurs fichiers.", + overriddenNotice: "{name} a été enregistré, mais une configuration de priorité plus élevée l'écrase, elle n'est donc pas effective", + bundlesTitle: 'Plugins installés', + basicTitle: 'Paramètres du plugin intégré', + extensionsTitle: 'Plugins expérimentaux', + moreTitle: 'Plugins expérimentaux', + moreAction: 'Plus', + tabsLabel: 'Vues des plugins', + installedTab: 'Installé', + statusProblem: 'Problème', + statusBeta: 'Expérimental', + reasonLabel: 'Raison', + metadataError: 'Erreur de métadonnées du package : {error}', + versionTag: 'v{version}', + partsLabel: 'Composants', + sourceTitle: 'Source', + sourceSpec: 'Source du code', + sourceBuiltIn: 'Intégré', + sourceVersion: 'Version actuelle', + partsEmpty: 'Ce pack de plugins ne contient aucun composant.', + partsCountTotal: 'Total {count}', + partsCountRunning: "{count} en cours d'exécution", + partsCountOff: '{count} désactivé', + partOff: 'Désactivé', + partsCountFailed: 'Échec du {count}', + partsFilter: 'Composants du filtre', + partsFilterEmpty: 'Aucun composant ne correspond.', + partToggle: 'Activer le composant {name}', + rowPhasePending: 'En attente de dépendances', + rowPhaseLoading: 'Chargement', + rowPhaseActive: 'Courir', + rowPhaseFailed: 'Problème', + rowPhaseUnloading: 'Déchargement', + enableToggle: 'Activer {name}', + applyingChange: 'Application des modifications à {name}', + openDetail: 'Voir {name}', + backToList: 'Retour aux plugins', + crumbRoot: 'Plugins', + backToPackage: 'Retour à {name}', + configureRow: 'Configurer {name}', + rowStateIdle: 'Ne fonctionne pas', + uninstall: 'Désinstaller', + uninstallLabel: 'Désinstaller {name}', + installTitle: 'Ajouter un plugin', + installDescription: "Entrez le nom du package du plugin, l'adresse du référentiel GitHub ou le chemin du répertoire local.", + installSpecLabel: 'Nom ou adresse du colis', + installSpecPlaceholder: 'par exemple dsh-plugin-whale-pet', + installGuideToggle: "Guide d'installation et exemples", + installGuideHide: 'Masquer le guide', + installGuideIdTitle: 'Entrez le nom du package npm du plugin', + installGuideIdExample: 'dsh-plugin-baleine-animal de compagnie', + installGuideIdHint: "Le nom du package du plugin est le nom du package npm (comme dsh-xxx ou @author/plugin) : la partie après dsh plugin add ou pnpm add dans la commande d'installation README d'un plugin communautaire.", + installGuideExampleLabel: 'Exemple : ', + installGitTemplateHint: "Remplacez-le par l'adresse réelle du référentiel Git.", + installPathTemplateHint: 'Remplacez-le par le chemin réel vers votre répertoire de plugin local.', + installGuideFill: "Utiliser l'exemple", + installGuideFillAria: "Utilisez l'exemple {example}", + installGuideSafety: "Installez uniquement les plugins en qui vous avez confiance : ils s'exécutent avec vos autorisations et peuvent endommager DeepSeek Harness ou divulguer vos données.", + installUpgradeNotice: "Les plugins officiels à la demande proposent la mise à jour lorsque leur version diffère de DSH. Pour mettre à jour d'autres plugins, désinstallez-les et réinstallez-les.", + registryToggle: 'Registre', + registryLegend: 'Le registre npm à partir duquel le plugin est téléchargé', + registryDefault: 'Registre par défaut', + registryOfficial: 'Registre officiel npm', + registryNpmmirror: 'Miroir de Chine continentale', + registryCustom: 'Adresse personnalisée', + registryCustomPlaceholder: 'https://npm.example.com/', + registryCustomHint: "Entrez une adresse de registre npm interne ou privée commençant par http:// ou https://.. Si cela nécessite une connexion, stockez les informations d'identification dans ~/.npmrc sur cette machine.", + registryCustomInvalid: 'Saisissez une adresse commençant par http:// ou https://', + registryListSeparator: ', ', + sentenceSeparator: ' ', + installRun: 'Installer', + installChecking: 'Vérification…', + installConfirmedTitle: 'Installer le plug-in', + installConfirmedRefused: 'Ce plugin ne peut pas être installé', + installProblemInvalid: "Il ne s'agit pas d'un nom ou d'une adresse de package pouvant être installé : {reason}", + installProblemInstalled: 'Ce plugin est déjà installé. Pour le mettre à niveau, désinstallez-le et réinstallez-le', + installProblemShipped: 'Ce plugin est livré avec DSH ; la mise à niveau de DSH le met à jour', + installBundledTitle: 'Ce plugin est livré avec DSH', + installBundledDescription: 'Activez-le sans télécharger une autre copie', + installProblemNotFound: "Aucun plugin de ce type n'a été trouvé", + installProblemNotPackage: "Le chemin n'existe pas ou n'est pas un package de plugin valide", + installProblemNotBundle: 'Ce package ne déclare aucun bundle, il ne peut donc pas être installé en tant que plugin : {reason}', + installProblemNetwork: "Le registre du plugin n'a pas pu être atteint ; vérifie le réseau et réessaye", + installProblemNetworkAll: "Aucun registre n'a pu être atteint (essayé : {registries}) ; vérifiez les paramètres réseau ou proxy, ou modifiez le registre", + installProblemUnknown: "Le plugin n'a pas pu être recherché : {reason}", + installingTitle: 'Installation du plugin…', + installedTitle: 'Installé', + statusNotInstalled: 'Non installé', + statusMissingFiles: 'Forfait indisponible', + statusUpdateAvailable: 'Mise à jour disponible', + sourceNotInstalled: 'Non installé', + sourceTargetSpec: 'Source pour ce DSH', + sourceTargetVersion: 'Version pour ce DSH', + update: 'Mise à jour', + updateLabel: 'Mettre à jour {name}', + versionsTitle: 'Versions', + versionsRecheck: 'Vérifiez à nouveau', + versionsChecking: 'Vérification des mises à jour', + versionsAvailable: 'Mise à jour vers {version} disponible', + versionsPublished: 'Publié {date}', + versionsLatest: 'À jour', + versionsCheckedAt: 'Dernière vérification à {time}', + versionsBlocked: 'Les versions plus récentes nécessitent une mise à jour DSH', + versionsBlockedDetail: '{version} a besoin de {peers} ; ce DSH est {runtime}', + versionsNoneInstallable: 'Aucune version plus récente à installer directement', + versionsNoneInstallableDetail: 'Les versions les plus récentes sont obsolètes, sont des versions préliminaires ou ne déclarent aucun bundle. Agrandissez pour les voir', + versionsFailedNetwork: "Impossible d'accéder au registre", + versionsFailedOther: 'Impossible de vérifier les mises à jour', + versionsDetails: 'Détails', + versionsNewerCount: '{count} plus récent', + versionsCollapse: 'Réduire', + versionsInstalledTag: 'Installé', + versionsPrereleaseTag: 'Avant-première', + versionsDeprecatedTag: 'Obsolète', + versionsNeedsDsh: 'Besoins {peers}', + versionsNotBundle: 'Cette version ne déclare aucun bundle et ne peut pas être installée', + versionsUpdateLabel: 'Mise à jour vers {version}', + versionsRegistry: 'Registre', + versionsCheckedAtLabel: 'Vérifié à', + versionsFallbackTag: 'Repli', + versionsFallbackHint: "{registry} n'a pas pu être atteint ; la liste provient d'un registre de secours", + versionsPrimaryTag: "D'abord", + versionsShowPrerelease: 'Afficher les avant-premières', + versionsOmitted: '{count} et les versions plus récentes que celle installée ne sont pas répertoriées', + versionsProblemNetwork: 'Injoignable', + versionsProblemNotFound: 'Pas trouvé', + versionsProblemUnknown: 'Échec', + updatesAvailable: 'Mises à jour disponibles : {count}', + updatesNone: 'Tous les plugins sont à jour', + updatesFailed: "Certains plugins n'ont pas pu être vérifiés", + updateTitle: 'Mettre à jour {name}', + updateSource: 'Installer à partir de', + updateDescription: "La mise à jour remplace {from} par {to} ; le plugin peut s'arrêter brièvement. Si l'installation échoue, {from} est conservé ou réinstallé.", + updateRunning: 'Mise à jour', + updateStepChecking: 'Vérifiez {version}', + updateStepRemoving: 'Arrêtez et supprimez {version}', + updateStepInstalling: 'Installez {version} à partir de {registry}', + updateStepRestoring: 'Installez à nouveau {version}', + updateDone: 'Mis à jour vers {version}', + updateDoneDetail: "La nouvelle version est en cours d'exécution.", + updateRestart: '{version} installé ; cela prend effet après un redémarrage', + updateRefused: 'Impossible de mettre à jour vers {version}', + updateRemoveFailed: 'Impossible de supprimer {version}', + updateRestored: 'La mise à jour a échoué ; restauré {version}', + updateRestoredDetail: "Échec de l'installation de {to} ; {from} a été réinstallé.", + updateKept: 'Impossible de mettre à jour vers {version}', + updateKeptDetail: '{from} n’a pas été supprimé et reste utilisé. {reason}', + updateBroken: "La mise à jour a échoué ; le plugin n'est pas installé", + updateBrokenDetail: "L'installation de {to} a échoué et l'installation de {from} a également échoué. Installez à nouveau {name} à partir d'Ajouter un plugin.", + updateLost: 'Le résultat de la mise à jour est inconnu', + updateLostDetail: 'La connexion à DSH a été interrompue : {reason}. Actualisez la liste des plugins pour voir la version installée.', + updateOutput: "Afficher le résultat de l'installation", + updateFinish: 'Terminé', + installFailedTitle: "Le plugin n'a pas pu être installé", + installGithubFailedTitle: "Impossible d'accéder à GitHub", + installGithubTimeoutTitle: 'La connexion GitHub a expiré', + installGithubFailedDescription: "Essayez une autre source d'installation.", + installUseGithubMirror: 'Utiliser un miroir de Chine continentale', + installTryAnotherWay: 'Essayez une autre façon', + installPackageLabel: 'Nom du package du plugin', + installEdit: 'Modifier', + installEditAria: "Retour à l'édition", + installCancelAndEdit: "Annuler l'installation et revenir à l'édition", + installApplyingCancellationError: "L'annulation n'a pas été confirmée. L'installation est en cours d'application ; attendre son résultat. {reason}", + installReconcile: "Vérifier l'état de l'installation", + installUnknownTitle: "Résultat de l'installation indisponible", + installUnknownDescription: "L'hôte n'a aucune installation active avec cet identifiant de demande. Vérifiez la liste des plugins avant de réessayer.", + installResultUnconfirmed: "Le résultat de l'installation n'a pas été reçu. Vérifiez l'état de l'installation. {reason}", + installAwaitingAcceptance: "En attente que l'hôte accepte l'installation. L'annulation sera réessayée automatiquement après confirmation.", + installBackgroundUnknown: "Résultat de l'installation indisponible. Vérifiez la liste des plugins.", + installCancel: "Annuler l'installation", + installCloseCancels: "Annuler l'installation et fermer", + installViewTask: "Voir l'installation", + installUnconfirmedTitle: "État de l'installation non confirmé", + installBackgroundDone: "Installation terminée. Afficher les détails de l'installation.", + installBackgroundFailed: "L'installation a échoué. Afficher les détails de l'installation.", + installBackgroundUnconfirmed: "L'état de l'installation n'est pas confirmé. Consultez l'installation pour plus de détails.", + installBackgroundApplying: "L'installation est en cours d'application et ne peut pas être annulée. Afficher la progression de l'installation.", + installStarting: "Préparation de l'installation…", + installCancelling: "Arrêt de l'installation…", + installApplying: 'Application de la configuration, veuillez patienter…', + installCancelledShort: 'Annulé', + installCancelled: "Installation annulée ; le plugin n'est pas activé et les fichiers téléchargés peuvent rester", + installCancelUnconfirmed: "L'installation n'a pas été confirmée arrêtée. Réessayez l'annulation ou attendez le résultat de l'installation. {reason}", + installEnableNow: 'Activer maintenant', + installDetailsShow: "Afficher les détails de l'installation", + installDetailsHide: "Masquer les détails de l'installation", + installVersion: 'Version {version}', + installSubjectPath: 'Annuaire local', + installSubjectGit: 'Dépôt Git', + installSubjectTarball: 'Tarball', + installLocation: "S'installe dans {dir}", + installRetry: 'Réessayer', + installChangeRegistry: 'Changer de registre', + installAttempt: "{previous} n'a pas pu servir le package ; nouvelle tentative via {registry} (registre {index} de {total})", + installAttemptBadge: 'Tentative {index} · {registry}', + installFailureNetwork: 'La connexion réseau a échoué', + installFailureNetworkAll: "Aucun registre n'a pu être atteint (essayé : {registries}). Vérifiez les paramètres réseau ou proxy, ou modifiez le registre et réessayez.", + installFailureNetworkHost: "{host} n'a pas pu être atteint. Une adresse GitHub ou un lien .tgz ne sont pas récupérés via le registre : cette machine doit y accéder directement ou via un proxy. Si le plugin est également publié sur npm, saisissez plutôt le nom de son package.", + installFailureNotFound: "Aucun plugin de ce type n'a été trouvé", + installFailureNoMatchingVersion: 'Aucune version ne correspond à la demande', + installFailureDiskFull: "Le disque est plein ; l'installation s'est arrêtée", + installFailurePermission: "Aucune autorisation d'écriture ; le plugin ne peut pas être installé", + installFailureBuildBlocked: "Les scripts d'installation d'une dépendance ont besoin de votre autorisation avant que l'installation puisse continuer", + installFailureBuildBlockedManual: "pnpm a bloqué les scripts d'installation ; autorisez-les sous AllowBuilds dans pnpm-workspace.yaml et réessayez", + installFailureIntegrity: "Le package téléchargé a échoué à sa vérification d'intégrité", + installFailureTimeout: "L'installation a expiré", + installFailurePnpmMissing: "pnpm n'a pas été trouvé, donc rien ne peut être installé", + installFailureGeneric: "Quelque chose s'est mal passé lors de l'installation ; les détails disent quoi", + terminalCommandLine: 'Ligne de commande {n}', + terminalRunning: 'Courir', + terminalFailed: 'Échec', + terminalDone: 'Terminé', + terminalCopy: 'Copier', + terminalCopied: 'Copié', + terminalNoOutput: 'Aucune sortie', + terminalCollapseAria: 'Réduire la sortie', + terminalCollapse: 'Réduire', + terminalExpandAria: 'Développez les lignes de sortie {n} restantes', + terminalExpand: '… {n} plus de lignes', + terminalExitCode: 'code de sortie {code}', + terminalSignal: 'signal {signal}', + terminalNoExitCode: 'pas de code de sortie', + installDoneNothing: 'Installation terminée sans nouvelle dépendance.', + installDoneRestart: 'Installé ; redémarrez DSH pour le charger. {reason}', + installDoneApproved: "Scripts d'installation autorisés pour {names}", + installDoneOtherVersion: "Conformément à la politique de sécurité de la chaîne d'approvisionnement de pnpm (minimumReleaseAge), les versions publiées plus récemment que l'âge requis ne sont pas installées automatiquement. Cette installation a donc utilisé {installed} au lieu de la dernière version {version}. Une version nouvellement publiée n'a pas dépassé cette période d'attente et peut contenir du code malveillant ou des défauts non détectés. Si vous avez besoin de {version}, désinstallez la version actuelle, puis installez {exact} pour demander cette version.", + installApprovalTitle: "Les scripts d'installation nécessitent une autorisation", + installApprovalDescription: "Ces packages contiennent des scripts d'installation que pnpm n'a pas exécutés.", + installApprovalConsequence: "Une fois autorisés, les scripts s'exécutent ici avec vos autorisations et l'autorisation est enregistrée dans ce profil.", + installApprovalCaution: 'Autorisez uniquement les packages auxquels vous faites confiance.', + installApproveAndRetry: 'Autoriser ces scripts et réessayer', + installClose: 'Terminé', + close: 'Fermer', + cancel: 'Annuler', + confirmUninstallTitle: 'Désinstaller "{name}" ?', + confirmUninstallDescription: "Ce qu'il fournit disparaît une fois désinstallé.", + confirmUninstall: 'Désinstaller', + failedEnable: "Impossible d'activer : {reason}", + failedDisable: 'Impossible de désactiver : {reason}', + failedUninstall: 'Impossible de désinstaller : {reason}', + failedRowEnable: "Impossible d'activer le composant : {reason}", + failedRowDisable: 'Impossible de désactiver le composant : {reason}', + reasonManagementRequired: 'La gestion des plugins en a besoin ; il ne peut pas être éteint ou désinstallé.', + reasonUnaddressable: 'Le correctif de profil ne peut pas résoudre ce problème de manière unique.', + reasonUnknownPlugin: 'Aucun plugin de ce type.', + reasonInvalidSpec: 'Entrez un nom ou une adresse de package valide.', + reasonAlreadyInstalled: "Ce package est déjà installé ; désinstallez-le avant d'installer une autre version.", + reasonAmbiguousInstall: 'Le changement de dépendance ne permet pas de déterminer quel package a été installé.', + reasonNotBundle: 'Ce package ne déclare aucun bundle, il ne peut donc pas être géré comme un plugin.', + reasonNotRemovable: "Ce package n'appartient pas au profil, ou la gestion des plugins en a besoin.", + reasonStopProfile: "Ce profil s'exécute sans HMR ; arrêtez-le et désinstallez le package avec le plugin dsh.", + reasonBundleInUse: "Une autre configuration utilise toujours les composants de ce bundle ; éteignez-les d'abord.", + reasonStaleApproval: 'Les approbations de script en attente ont changé ; réinstallez-les pour les actualiser.', + reasonIncompatibleVersion: '{plugin} est incompatible avec DSH {runtime} (nécessite {requirements}) ; son exécution peut provoquer des plantages ou une perte de données.', + reasonIncompatibleVersionUnnamed: "Ce plugin est incompatible avec la version DSH en cours d'exécution ; son exécution peut provoquer des plantages ou une perte de données.", + reasonIncompatibleInstall: 'Installez une version du plugin compatible avec ce DSH.', + reasonIncompatibleInstalled: 'Désinstallez-le et installez une version compatible avec ce DSH.', + reasonOperationError: "L'hôte a signalé une erreur.", + detailTitle: 'Détails', + detailLoading: 'Détails de lecture', + detailTooLarge: "Les détails dépassent la limite de taille et n'ont pas été chargés.", + detailNetwork: "Impossible d'atteindre la source des détails.", + detailInvalid: 'Le plugin déclare un fichier de détails invalide.', + detailFailed: 'Impossible de lire les détails.', + detailFootnotes: 'Notes de bas de page', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + panel: 'Plugins', + title: 'Plugins', + intro: 'Plugins installieren, aktivieren und konfigurieren', + infoLabel: 'Über Plugins', + infoDescription: 'Konfigurieren Sie hier offizielle Plugins und installieren oder verwalten Sie andere Plugins. Sehen Sie sich die Liste der integrierten Plugins und den Laufzeitstatus unter Einstellungen → Integrierte Plugins an.', + loading: 'Plugins lesen…', + error: 'Es konnten nicht alle Plugins gelesen werden, möglicherweise aufgrund eines Netzwerkproblems', + unavailable: 'Diese Bereitstellung läuft ohne verwaltbares Profil, daher können hier keine Plugins installiert oder gewechselt werden.', + retry: 'Erneut versuchen', + refresh: 'Aktualisieren', + refreshError: 'Aktualisierung fehlgeschlagen. Bitte versuchen Sie es erneut.', + empty: 'Es sind noch keine Plugins installiert.', + addPlugin: 'Plugin hinzufügen', + chooseAddMethod: 'Wählen Sie aus, wie Sie ein Plugin hinzufügen möchten', + installExisting: 'Installieren Sie ein Drittanbieter-Plugin', + installExistingDescription: 'Unterstützt npm-Pakete, Git-Repositorys und lokale Verzeichnisse', + restartNotice: 'Starten Sie DSH neu, um die Änderung zu übernehmen. {reason}', + restartReasonNoHmr: 'Dieses Profil wendet Änderungen nur beim Start an.', + restartReasonPackageMoved: 'Ein installiertes Paket wird nun in ein anderes Verzeichnis aufgelöst, oder die Änderung ersetzt ein Paket, das die DSH-Installation bereitstellt. Deinstallieren Sie ein Paket, bevor Sie es von einem anderen Speicherort installieren.', + restartReasonHostModule: 'Die Änderung erreicht die geladenen Module DSH selbst.', + restartReasonUnmanagedPlugin: 'Die Änderung betrifft ein Plugin, das außerhalb der Plugin-Liste ausgeführt wird.', + restartReasonModuleComparison: 'DSH konnte die geladenen Plugins nicht mit ihren Dateien vergleichen.', + overriddenNotice: '{name} wurde gespeichert, aber eine Konfiguration mit höherer Priorität überschreibt es, sodass es nicht wirksam ist', + bundlesTitle: 'Installierte Plugins', + basicTitle: 'Integrierte Plugin-Einstellungen', + extensionsTitle: 'Experimentelle Plugins', + moreTitle: 'Experimentelle Plugins', + moreAction: 'Mehr', + tabsLabel: 'Plugin-Ansichten', + installedTab: 'Installiert', + statusProblem: 'Problem', + statusBeta: 'Experimentell', + reasonLabel: 'Grund', + metadataError: 'Paketmetadatenfehler: {error}', + versionTag: 'v{version}', + partsLabel: 'Komponenten', + sourceTitle: 'Quelle', + sourceSpec: 'Codequelle', + sourceBuiltIn: 'Eingebaut', + sourceVersion: 'Aktuelle Version', + partsEmpty: 'Dieses Plugin-Paket enthält keine Komponenten.', + partsCountTotal: '{count} insgesamt', + partsCountRunning: '{count} läuft', + partsCountOff: '{count} aus', + partOff: 'Aus', + partsCountFailed: '{count} ist fehlgeschlagen', + partsFilter: 'Komponenten filtern', + partsFilterEmpty: 'Keine Komponentenübereinstimmungen.', + partToggle: 'Aktivieren Sie die Komponente {name}', + rowPhasePending: 'Warten auf Abhängigkeiten', + rowPhaseLoading: 'Laden', + rowPhaseActive: 'Laufen', + rowPhaseFailed: 'Problem', + rowPhaseUnloading: 'Entladen', + enableToggle: 'Aktivieren Sie {name}', + applyingChange: 'Anwenden von Änderungen auf {name}', + openDetail: 'Siehe {name}', + backToList: 'Zurück zu Plugins', + crumbRoot: 'Plugins', + backToPackage: 'Zurück zu {name}', + configureRow: 'Konfigurieren Sie {name}', + rowStateIdle: 'Läuft nicht', + uninstall: 'Deinstallieren', + uninstallLabel: 'Deinstallieren Sie {name}', + installTitle: 'Plugin hinzufügen', + installDescription: 'Geben Sie den Paketnamen des Plugins, die GitHub-Repository-Adresse oder den lokalen Verzeichnispfad ein.', + installSpecLabel: 'Name oder Adresse des Pakets', + installSpecPlaceholder: 'zum Beispiel dsh-plugin-whale-pet', + installGuideToggle: 'Installationsanleitung und Beispiele', + installGuideHide: 'Verstecke den Leitfaden', + installGuideIdTitle: 'Geben Sie den NPM-Paketnamen des Plugins ein', + installGuideIdExample: 'dsh-plugin-whale-pet', + installGuideIdHint: 'Der Plugin-Paketname ist der npm-Paketname (wie dsh-xxx oder @author/plugin): der Teil nach dshplugin add oder pnpm add im README-Installationsbefehl eines Community-Plugins.', + installGuideExampleLabel: 'Beispiel: ', + installGitTemplateHint: 'Ersetzen Sie dies durch die tatsächliche Git-Repository-Adresse.', + installPathTemplateHint: 'Ersetzen Sie dies durch den tatsächlichen Pfad zu Ihrem lokalen Plugin-Verzeichnis.', + installGuideFill: 'Beispiel verwenden', + installGuideFillAria: 'Verwenden Sie das Beispiel {example}', + installGuideSafety: 'Installieren Sie nur Plugins, denen Sie vertrauen: Sie werden mit Ihren Berechtigungen ausgeführt und können DeepSeek Harness beschädigen oder Ihre Daten preisgeben.', + installUpgradeNotice: 'Offizielle On-Demand-Plugins bieten Updates an, wenn ihre Version von DSH abweicht. Um andere Plugins zu aktualisieren, deinstallieren Sie sie und installieren Sie sie erneut.', + registryToggle: 'Registrierung', + registryLegend: 'Die NPM-Registrierung, aus der das Plugin heruntergeladen wird', + registryDefault: 'Standardregistrierung', + registryOfficial: 'Offizielle npm-Registrierung', + registryNpmmirror: 'Spiegel vom chinesischen Festland', + registryCustom: 'Benutzerdefinierte Adresse', + registryCustomPlaceholder: 'https://npm.example.com/', + registryCustomHint: 'Geben Sie eine interne oder private NPM-Registrierungsadresse ein, beginnend mit http:// oder https://.. Wenn eine Anmeldung erforderlich ist, speichern Sie die Anmeldeinformationen in ~/.npmrc auf diesem Computer.', + registryCustomInvalid: 'Geben Sie eine Adresse ein, die mit http:// oder https:// beginnt.', + registryListSeparator: ', ', + sentenceSeparator: ' ', + installRun: 'Installieren', + installChecking: 'Überprüfen…', + installConfirmedTitle: 'Plugin installieren', + installConfirmedRefused: 'Dieses Plugin kann nicht installiert werden', + installProblemInvalid: 'Dies ist kein Paketname oder keine Adresse, die installiert werden kann: {reason}', + installProblemInstalled: 'Dieses Plugin ist bereits installiert. Um es zu aktualisieren, deinstallieren Sie es und installieren Sie es erneut', + installProblemShipped: 'Dieses Plugin wird mit DSH geliefert; Durch das Aktualisieren von DSH wird es aktualisiert', + installBundledTitle: 'Dieses Plugin wird mit DSH geliefert', + installBundledDescription: 'Aktivieren Sie es, ohne eine weitere Kopie herunterzuladen', + installProblemNotFound: 'Es wurde kein solches Plugin gefunden', + installProblemNotPackage: 'Der Pfad existiert nicht oder ist kein gültiges Plugin-Paket', + installProblemNotBundle: 'Dieses Paket deklariert kein Bundle und kann daher nicht als Plugin installiert werden: {reason}', + installProblemNetwork: 'Die Plugin-Registrierung konnte nicht erreicht werden; Überprüfen Sie das Netzwerk und versuchen Sie es erneut', + installProblemNetworkAll: 'Es konnte keine Registry erreicht werden (versucht: {registries}); Überprüfen Sie die Netzwerk- oder Proxy-Einstellungen oder ändern Sie die Registrierung', + installProblemUnknown: 'Das Plugin konnte nicht gefunden werden: {reason}', + installingTitle: 'Plugin installieren…', + installedTitle: 'Installiert', + statusNotInstalled: 'Nicht installiert', + statusMissingFiles: 'Paket nicht verfügbar', + statusUpdateAvailable: 'Update verfügbar', + sourceNotInstalled: 'Nicht installiert', + sourceTargetSpec: 'Quelle hierfür DSH', + sourceTargetVersion: 'Version für dieses DSH', + update: 'Aktualisieren', + updateLabel: 'Aktualisieren Sie {name}', + versionsTitle: 'Versionen', + versionsRecheck: 'Überprüfen Sie es noch einmal', + versionsChecking: 'Suche nach Updates', + versionsAvailable: 'Update auf {version} verfügbar', + versionsPublished: 'Veröffentlicht {date}', + versionsLatest: 'Auf dem neuesten Stand', + versionsCheckedAt: 'Zuletzt überprüft bei {time}', + versionsBlocked: 'Neuere Versionen benötigen ein DSH-Update', + versionsBlockedDetail: '{version} benötigt {peers}; dieser DSH ist {runtime}', + versionsNoneInstallable: 'Keine neuere Version zur direkten Installation', + versionsNoneInstallableDetail: 'Die neueren Versionen sind veraltet, Vorabversionen oder deklarieren kein Bundle. Erweitern Sie, um sie zu sehen', + versionsFailedNetwork: 'Die Registrierung konnte nicht erreicht werden', + versionsFailedOther: 'Es konnte nicht nach Updates gesucht werden', + versionsDetails: 'Details', + versionsNewerCount: '{count} neuer', + versionsCollapse: 'Einklappen', + versionsInstalledTag: 'Installiert', + versionsPrereleaseTag: 'Vorabversion', + versionsDeprecatedTag: 'Veraltet', + versionsNeedsDsh: 'Benötigt {peers}', + versionsNotBundle: 'Diese Version deklariert kein Bundle und kann nicht installiert werden', + versionsUpdateLabel: 'Update auf {version}', + versionsRegistry: 'Registrierung', + versionsCheckedAtLabel: 'Geprüft bei', + versionsFallbackTag: 'Rückfall', + versionsFallbackHint: '{registry} konnte nicht erreicht werden; Die Liste stammt aus einer Fallback-Registrierung', + versionsPrimaryTag: 'Erstens', + versionsShowPrerelease: 'Vorabversionen anzeigen', + versionsOmitted: '{count} Weitere Versionen, die neuer als die installierte sind, werden nicht aufgeführt', + versionsProblemNetwork: 'Unerreichbar', + versionsProblemNotFound: 'Nicht gefunden', + versionsProblemUnknown: 'Fehlgeschlagen', + updatesAvailable: 'Verfügbare Updates: {count}', + updatesNone: 'Alle Plugins sind auf dem neuesten Stand', + updatesFailed: 'Einige Plugins konnten nicht überprüft werden', + updateTitle: 'Aktualisieren Sie {name}', + updateSource: 'Installieren von', + updateDescription: 'Das Update ersetzt {from} durch {to}; Das Plugin stoppt möglicherweise kurzzeitig. Wenn die Installation fehlschlägt, bleibt {from} erhalten oder wird erneut installiert.', + updateRunning: 'Aktualisierung', + updateStepChecking: 'Überprüfen Sie {version}', + updateStepRemoving: 'Stoppen und entfernen Sie {version}', + updateStepInstalling: 'Installieren Sie {version} von {registry}', + updateStepRestoring: 'Installieren Sie {version} erneut', + updateDone: 'Aktualisiert auf {version}', + updateDoneDetail: 'Die neue Version läuft.', + updateRestart: '{version} installiert; es wird erst nach einem Neustart wirksam', + updateRefused: 'Aktualisierung auf {version} nicht möglich', + updateRemoveFailed: '{version} konnte nicht entfernt werden', + updateRestored: 'Aktualisierung fehlgeschlagen; wiederhergestellt {version}', + updateRestoredDetail: '{to} konnte nicht installiert werden; {from} wurde erneut installiert.', + updateKept: 'Konnte nicht auf {version} aktualisiert werden', + updateKeptDetail: '{from} wurde nicht entfernt und wird weiterhin verwendet. {reason}', + updateBroken: 'Aktualisierung fehlgeschlagen; Das Plugin ist nicht installiert', + updateBrokenDetail: 'Die Installation von {to} ist fehlgeschlagen, und auch die erneute Installation von {from} schlug fehl. Installieren Sie {name} erneut über Plugin hinzufügen.', + updateLost: 'Das Update-Ergebnis ist unbekannt', + updateLostDetail: 'Die Verbindung zu DSH wurde unterbrochen: {reason}. Aktualisieren Sie die Plugin-Liste, um die installierte Version anzuzeigen.', + updateOutput: 'Installationsausgabe anzeigen', + updateFinish: 'Fertig', + installFailedTitle: 'Das Plugin konnte nicht installiert werden', + installGithubFailedTitle: 'Auf GitHub kann nicht zugegriffen werden', + installGithubTimeoutTitle: 'Zeitüberschreitung bei der GitHub-Verbindung', + installGithubFailedDescription: 'Versuchen Sie es mit einer anderen Installationsquelle.', + installUseGithubMirror: 'Verwenden Sie einen Spiegel vom chinesischen Festland', + installTryAnotherWay: 'Versuchen Sie es anders', + installPackageLabel: 'Name des Plugin-Pakets', + installEdit: 'Bearbeiten', + installEditAria: 'Zurück zur Bearbeitung', + installCancelAndEdit: 'Brechen Sie die Installation ab und kehren Sie zur Bearbeitung zurück', + installApplyingCancellationError: 'Die Stornierung wurde nicht bestätigt. Installation wird angewendet; warte auf das Ergebnis. {reason}', + installReconcile: 'Überprüfen Sie den Installationsstatus', + installUnknownTitle: 'Installationsergebnis nicht verfügbar', + installUnknownDescription: 'Der Host verfügt über keine aktive Installation mit dieser Anforderungs-ID. Überprüfen Sie die Plugin-Liste, bevor Sie es erneut versuchen.', + installResultUnconfirmed: 'Das Installationsergebnis wurde nicht empfangen. Überprüfen Sie den Installationsstatus. {reason}', + installAwaitingAcceptance: 'Warten darauf, dass der Host die Installation akzeptiert. Die Stornierung wird nach der Bestätigung automatisch wiederholt.', + installBackgroundUnknown: 'Installationsergebnis nicht verfügbar. Überprüfen Sie die Plugin-Liste.', + installCancel: 'Installation abbrechen', + installCloseCancels: 'Installation abbrechen und schließen', + installViewTask: 'Installation ansehen', + installUnconfirmedTitle: 'Installationsstatus unbestätigt', + installBackgroundDone: 'Installation abgeschlossen. Installationsdetails anzeigen.', + installBackgroundFailed: 'Die Installation ist fehlgeschlagen. Installationsdetails anzeigen.', + installBackgroundUnconfirmed: 'Der Installationsstatus ist unbestätigt. Weitere Informationen finden Sie in der Installation.', + installBackgroundApplying: 'Die Installation wird ausgeführt und kann nicht abgebrochen werden. Installationsfortschritt anzeigen.', + installStarting: 'Installation vorbereiten…', + installCancelling: 'Installation wird gestoppt…', + installApplying: 'Konfiguration wird angewendet, bitte warten…', + installCancelledShort: 'Abgesagt', + installCancelled: 'Installation abgebrochen; Das Plugin ist nicht aktiviert und heruntergeladene Dateien bleiben möglicherweise bestehen', + installCancelUnconfirmed: 'Die Installation wurde nicht bestätigt und gestoppt. Versuchen Sie den Abbruch erneut oder warten Sie auf das Installationsergebnis. {reason}', + installEnableNow: 'Jetzt aktivieren', + installDetailsShow: 'Installationsdetails anzeigen', + installDetailsHide: 'Installationsdetails ausblenden', + installVersion: 'Version {version}', + installSubjectPath: 'Lokales Verzeichnis', + installSubjectGit: 'Git-Repository', + installSubjectTarball: 'Tarball', + installLocation: 'Wird in {dir} installiert', + installRetry: 'Erneut versuchen', + installChangeRegistry: 'Registrierung ändern', + installAttempt: '{previous} konnte das Paket nicht bereitstellen; erneuter Versuch über {registry} (Registrierung {index} von {total})', + installAttemptBadge: 'Versuchen Sie {index} · {registry}', + installFailureNetwork: 'Die Netzwerkverbindung ist fehlgeschlagen', + installFailureNetworkAll: 'Es konnte keine Registry erreicht werden (versucht: {registries}). Überprüfen Sie die Netzwerk- oder Proxy-Einstellungen oder ändern Sie die Registrierung und versuchen Sie es erneut.', + installFailureNetworkHost: '{host} konnte nicht erreicht werden. Eine GitHub-Adresse oder ein .tgz-Link wird nicht über die Registrierung abgerufen: Dieser Computer muss sie direkt oder über einen Proxy erreichen. Wenn das Plugin auch auf npm veröffentlicht wird, geben Sie stattdessen seinen Paketnamen ein.', + installFailureNotFound: 'Es wurde kein solches Plugin gefunden', + installFailureNoMatchingVersion: 'Keine Version entspricht der Anfrage', + installFailureDiskFull: 'Die Festplatte ist voll; Die Installation wurde gestoppt', + installFailurePermission: 'Keine Schreibberechtigung; Das Plugin kann nicht installiert werden', + installFailureBuildBlocked: 'Die Installationsskripte einer Abhängigkeit benötigen Ihre Erlaubnis, bevor die Installation fortgesetzt werden kann', + installFailureBuildBlockedManual: 'pnpm blockierte Installationsskripte; Erlauben Sie sie unter „allowBuilds“ in „pnpm-workspace.yaml“ und versuchen Sie es erneut', + installFailureIntegrity: 'Das heruntergeladene Paket hat die Integritätsprüfung nicht bestanden', + installFailureTimeout: 'Bei der Installation ist eine Zeitüberschreitung aufgetreten', + installFailurePnpmMissing: 'pnpm wurde nicht gefunden, daher kann nichts installiert werden', + installFailureGeneric: 'Bei der Installation ist ein Fehler aufgetreten. Die Details sagen was', + terminalCommandLine: 'Befehlszeile {n}', + terminalRunning: 'Laufen', + terminalFailed: 'Fehlgeschlagen', + terminalDone: 'Fertig', + terminalCopy: 'Kopieren', + terminalCopied: 'Kopiert', + terminalNoOutput: 'Keine Ausgabe', + terminalCollapseAria: 'Ausgabe reduzieren', + terminalCollapse: 'Einklappen', + terminalExpandAria: 'Erweitern Sie die verbleibenden {n}-Ausgabezeilen', + terminalExpand: '… {n} weitere Zeilen', + terminalExitCode: 'Exit-Code {code}', + terminalSignal: 'Signal {signal}', + terminalNoExitCode: 'kein Exit-Code', + installDoneNothing: 'Die Installation ist ohne neue Abhängigkeit abgeschlossen.', + installDoneRestart: 'Installiert; Starten Sie DSH neu, um es zu laden. {reason}', + installDoneApproved: 'Für {names} zulässige Installationsskripte', + installDoneOtherVersion: 'Gemäß der Supply-Chain-Sicherheitsrichtlinie von pnpm (minimumReleaseAge) werden Versionen, die jünger als das erforderliche Alter veröffentlicht wurden, nicht automatisch installiert. Daher wurde bei dieser Installation {installed} anstelle der neuesten Version {version} verwendet. Eine neu veröffentlichte Version hat diese Wartezeit nicht durchlaufen und kann unerkannten Schadcode oder Mängel enthalten. Wenn Sie {version} benötigen, deinstallieren Sie die aktuelle Version und installieren Sie dann {exact}, um diese Version anzufordern.', + installApprovalTitle: 'Installationsskripte benötigen eine Genehmigung', + installApprovalDescription: 'Diese Pakete verfügen über Installationsskripte, die pnpm nicht ausgeführt hat.', + installApprovalConsequence: 'Sobald sie zugelassen sind, werden die Skripte hier mit Ihren Berechtigungen ausgeführt und die Berechtigung wird in diesem Profil gespeichert.', + installApprovalCaution: 'Lassen Sie nur Pakete zu, denen Sie vertrauen.', + installApproveAndRetry: 'Lassen Sie diese Skripte zu und versuchen Sie es erneut', + installClose: 'Fertig', + close: 'Schließen', + cancel: 'Abbrechen', + confirmUninstallTitle: '„{name}“ deinstallieren?', + confirmUninstallDescription: 'Was es bietet, verschwindet, sobald es deinstalliert wird.', + confirmUninstall: 'Deinstallieren', + failedEnable: 'Konnte nicht aktiviert werden: {reason}', + failedDisable: 'Konnte nicht deaktiviert werden: {reason}', + failedUninstall: 'Konnte nicht deinstalliert werden: {reason}', + failedRowEnable: 'Die Komponente {reason} konnte nicht aktiviert werden', + failedRowDisable: 'Die Komponente {reason} konnte nicht deaktiviert werden', + reasonManagementRequired: 'Das Plugin-Management braucht es; Es kann nicht ausgeschaltet oder deinstalliert werden.', + reasonUnaddressable: 'Der Profil-Patch kann dieses Problem nicht eindeutig beheben.', + reasonUnknownPlugin: 'Kein solches Plugin.', + reasonInvalidSpec: 'Geben Sie einen gültigen Paketnamen oder eine gültige Paketadresse ein.', + reasonAlreadyInstalled: 'Dieses Paket ist bereits installiert; Deinstallieren Sie es, bevor Sie eine andere Version installieren.', + reasonAmbiguousInstall: 'Welches Paket installiert wurde, lässt sich anhand der Abhängigkeitsänderung nicht erkennen.', + reasonNotBundle: 'Dieses Paket deklariert kein Bundle und kann daher nicht als Plugin verwaltet werden.', + reasonNotRemovable: 'Dieses Paket gehört nicht dem Profil oder die Plugin-Verwaltung benötigt es.', + reasonStopProfile: 'Dieses Profil läuft ohne HMR; Stoppen Sie es und deinstallieren Sie das Paket mit dem dsh-Plugin.', + reasonBundleInUse: 'Andere Konfigurationen verwenden weiterhin die Komponenten dieses Bundles; Schalten Sie sie zuerst aus.', + reasonStaleApproval: 'Die ausstehenden Drehbuchgenehmigungen haben sich geändert; Installieren Sie es erneut, um sie zu aktualisieren.', + reasonIncompatibleVersion: '{plugin} ist nicht kompatibel mit DSH {runtime} (erfordert {requirements}); Die Ausführung kann zu Abstürzen oder Datenverlust führen.', + reasonIncompatibleVersionUnnamed: 'Dieses Plugin ist nicht mit der laufenden DSH-Version kompatibel. Die Ausführung kann zu Abstürzen oder Datenverlust führen.', + reasonIncompatibleInstall: 'Installieren Sie eine mit diesem DSH kompatible Plugin-Version.', + reasonIncompatibleInstalled: 'Deinstallieren Sie es und installieren Sie eine mit diesem DSH kompatible Version.', + reasonOperationError: 'Der Host hat einen Fehler gemeldet.', + detailTitle: 'Details', + detailLoading: 'Details lesen', + detailTooLarge: 'Die Details überschreiten die Größenbeschränkung und wurden nicht geladen.', + detailNetwork: 'Die Quelle der Details konnte nicht erreicht werden.', + detailInvalid: 'Das Plugin deklariert eine ungültige Detaildatei.', + detailFailed: 'Die Details konnten nicht gelesen werden.', + detailFootnotes: 'Fußnoten', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + panel: 'Плагины', + title: 'Плагины', + intro: 'Установите, включите и настройте плагины', + infoLabel: 'О плагинах', + infoDescription: 'Настройте официальные плагины, а также установите или управляйте другими плагинами здесь. Посмотреть список встроенных плагинов и статус выполнения можно в разделе «Настройки» → «Встроенные плагины».', + loading: 'Чтение плагинов…', + error: 'Не удалось прочитать все плагины, возможно, из-за проблем с сетью.', + unavailable: 'Это развертывание выполняется без управляемого профиля, поэтому здесь нельзя устанавливать или переключать плагины.', + retry: 'Повторить', + refresh: 'Обновить', + refreshError: 'Обновить не удалось. Пожалуйста, попробуйте еще раз.', + empty: 'Плагины пока не установлены.', + addPlugin: 'Добавить плагин', + chooseAddMethod: 'Выберите, как добавить плагин', + installExisting: 'Установите сторонний плагин', + installExistingDescription: 'Поддерживает пакеты npm, репозитории Git и локальные каталоги.', + restartNotice: 'Перезапустите DSH, чтобы применить изменения. {reason}', + restartReasonNoHmr: 'Этот профиль применяет изменения только при запуске.', + restartReasonPackageMoved: 'Установленный пакет теперь разрешается в другой каталог, или изменение заменяет пакет, предоставляемый установкой DSH. Удалите пакет перед установкой его из другого места.', + restartReasonHostModule: 'Изменение доходит до загруженных модулей DSH.', + restartReasonUnmanagedPlugin: 'Изменение достигает плагина, работающего за пределами списка плагинов.', + restartReasonModuleComparison: 'DSH не смог сравнить загруженные плагины с их файлами.', + overriddenNotice: '{name} был сохранен, но конфигурация с более высоким приоритетом переопределяет его, поэтому он не действует.', + bundlesTitle: 'Установленные плагины', + basicTitle: 'Встроенные настройки плагина', + extensionsTitle: 'Экспериментальные плагины', + moreTitle: 'Экспериментальные плагины', + moreAction: 'Ещё', + tabsLabel: 'Просмотры плагинов', + installedTab: 'Установлено', + statusProblem: 'Проблема', + statusBeta: 'Экспериментальный', + reasonLabel: 'Причина', + metadataError: 'Ошибка метаданных пакета: {error}.', + versionTag: 'v{version}', + partsLabel: 'Компоненты', + sourceTitle: 'Источник', + sourceSpec: 'Источник кода', + sourceBuiltIn: 'Встроенный', + sourceVersion: 'Текущая версия', + partsEmpty: 'Этот пакет плагинов не содержит компонентов.', + partsCountTotal: '{count} всего', + partsCountRunning: '{count} работает', + partsCountOff: '{count} выкл.', + partOff: 'Выкл.', + partsCountFailed: '{count} не удалось', + partsFilter: 'Компоненты фильтра', + partsFilterEmpty: 'Ни один компонент не соответствует.', + partToggle: 'Включить компонент {name}', + rowPhasePending: 'Ожидание зависимостей', + rowPhaseLoading: 'Загрузка', + rowPhaseActive: 'Бег', + rowPhaseFailed: 'Проблема', + rowPhaseUnloading: 'Разгрузка', + enableToggle: 'Включить {name}', + applyingChange: 'Применение изменений в {name}', + openDetail: 'Посмотреть {name}', + backToList: 'Вернуться к плагинам', + crumbRoot: 'Плагины', + backToPackage: 'Вернуться к {name}', + configureRow: 'Настроить {name}', + rowStateIdle: 'Не работает', + uninstall: 'Удалить', + uninstallLabel: 'Удалить {name}', + installTitle: 'Добавить плагин', + installDescription: 'Введите имя пакета плагина, адрес репозитория GitHub или путь к локальному каталогу.', + installSpecLabel: 'Название или адрес пакета', + installSpecPlaceholder: 'например dsh-plugin-whale-pet', + installGuideToggle: 'Руководство по установке и примеры', + installGuideHide: 'Скрыть руководство', + installGuideIdTitle: 'Введите имя пакета npm плагина.', + installGuideIdExample: 'dsh-плагин-кит-питомец', + installGuideIdHint: 'Имя пакета плагина — это имя пакета npm (например, dsh-xxx или @author/plugin): часть после добавления плагина dsh или добавления pnpm в команде установки README плагина сообщества.', + installGuideExampleLabel: 'Пример: ', + installGitTemplateHint: 'Замените это фактическим адресом репозитория Git.', + installPathTemplateHint: 'Замените это фактическим путем к вашему локальному каталогу плагина.', + installGuideFill: 'Используйте пример', + installGuideFillAria: 'Используйте пример {example}', + installGuideSafety: 'Устанавливайте только те плагины, которым вы доверяете: они запускаются с вашими разрешениями и могут повредить DeepSeek Harness или привести к утечке ваших данных.', + installUpgradeNotice: 'Официальные плагины по требованию предлагают обновление, если их версия отличается от DSH. Чтобы обновить другие плагины, удалите и переустановите их.', + registryToggle: 'Реестр', + registryLegend: 'Реестр npm, из которого загружается плагин.', + registryDefault: 'Реестр по умолчанию', + registryOfficial: 'Официальный реестр npm', + registryNpmmirror: 'Зеркало материкового Китая', + registryCustom: 'Пользовательский адрес', + registryCustomPlaceholder: 'https://npm.example.com/', + registryCustomHint: 'Введите внутренний или частный адрес реестра npm, начинающийся с http:// или https://.. Если требуется вход в систему, сохраните учетные данные в ~/.npmrc на этом компьютере.', + registryCustomInvalid: 'Введите адрес, начинающийся с http:// или https://.', + registryListSeparator: ', ', + sentenceSeparator: ' ', + installRun: 'Установить', + installChecking: 'Проверка…', + installConfirmedTitle: 'Установить плагин', + installConfirmedRefused: 'Этот плагин не может быть установлен', + installProblemInvalid: 'Это не имя или адрес пакета, который можно установить: {reason}.', + installProblemInstalled: 'Этот плагин уже установлен. Чтобы обновить его, удалите его и установите снова.', + installProblemShipped: 'Этот плагин поставляется с DSH; обновление DSH обновляет его', + installBundledTitle: 'Этот плагин поставляется с DSH.', + installBundledDescription: 'Включите его, не загружая другую копию.', + installProblemNotFound: 'Такой плагин не найден', + installProblemNotPackage: 'Путь не существует или не является допустимым пакетом плагина.', + installProblemNotBundle: 'Этот пакет не декларирует отсутствие пакета, поэтому его нельзя установить как плагин: {reason}', + installProblemNetwork: 'Не удалось получить доступ к реестру плагинов; проверьте сеть и попробуйте еще раз', + installProblemNetworkAll: 'Не удалось получить доступ к реестру (пробовал: {registries}); проверьте настройки сети или прокси или измените реестр', + installProblemUnknown: 'Не удалось найти плагин: {reason}.', + installingTitle: 'Установка плагина…', + installedTitle: 'Установлено', + statusNotInstalled: 'Не установлено', + statusMissingFiles: 'Пакет недоступен', + statusUpdateAvailable: 'Доступно обновление', + sourceNotInstalled: 'Не установлено', + sourceTargetSpec: 'Источник для этого DSH', + sourceTargetVersion: 'Версия для этого DSH', + update: 'Обновить', + updateLabel: 'Обновление {name}', + versionsTitle: 'Версии', + versionsRecheck: 'Проверьте еще раз', + versionsChecking: 'Проверка обновлений', + versionsAvailable: 'Доступно обновление до {version}.', + versionsPublished: 'Опубликовано {date}', + versionsLatest: 'Актуально', + versionsCheckedAt: 'Последняя проверка на {time}.', + versionsBlocked: 'Для более новых версий требуется обновление DSH.', + versionsBlockedDetail: '{version} нужен {peers}; этот DSH - это {runtime}', + versionsNoneInstallable: 'Нет более новой версии для установки напрямую', + versionsNoneInstallableDetail: 'Более новые версии устарели, являются предварительными выпусками или не содержат пакетов. Разверните, чтобы увидеть их', + versionsFailedNetwork: 'Не удалось войти в реестр', + versionsFailedOther: 'Не удалось проверить наличие обновлений', + versionsDetails: 'Подробности', + versionsNewerCount: '{count} новее', + versionsCollapse: 'Свернуть', + versionsInstalledTag: 'Установлено', + versionsPrereleaseTag: 'Пререлиз', + versionsDeprecatedTag: 'Устарело', + versionsNeedsDsh: 'Требуется {peers}', + versionsNotBundle: 'Эта версия не декларирует отсутствие пакета и не может быть установлена.', + versionsUpdateLabel: 'Обновление до {version}', + versionsRegistry: 'Реестр', + versionsCheckedAtLabel: 'Проверено в', + versionsFallbackTag: 'Резервный вариант', + versionsFallbackHint: '{registry} не удалось связаться; список взят из резервного реестра', + versionsPrimaryTag: 'Первый', + versionsShowPrerelease: 'Показать пререлизы', + versionsOmitted: '{count} больше версий новее установленной не указано', + versionsProblemNetwork: 'недостижимый', + versionsProblemNotFound: 'Не найден', + versionsProblemUnknown: 'Не удалось', + updatesAvailable: 'Доступные обновления: {count}', + updatesNone: 'Все плагины актуальны', + updatesFailed: 'Некоторые плагины не удалось проверить', + updateTitle: 'Обновление {name}', + updateSource: 'Установить из', + updateDescription: 'Обновление заменяет {from} на {to}; плагин может ненадолго остановиться. Если установка не удалась, {from} сохраняется или устанавливается снова.', + updateRunning: 'Обновление', + updateStepChecking: 'Проверьте {version}', + updateStepRemoving: 'Остановите и удалите {version}.', + updateStepInstalling: 'Установите {version} из {registry}.', + updateStepRestoring: 'Установите {version} еще раз.', + updateDone: 'Обновлено до {version}.', + updateDoneDetail: 'Новая версия работает.', + updateRestart: '{version} установлен; оно вступит в силу после перезагрузки', + updateRefused: 'Не могу обновиться до {version}.', + updateRemoveFailed: 'Не удалось удалить {version}.', + updateRestored: 'Обновление не удалось; восстановлен {version}', + updateRestoredDetail: '{to} не удалось установить; {from} был установлен снова.', + updateKept: 'Не удалось обновиться до {version}.', + updateKeptDetail: '{from} не был удален и продолжает использоваться. {reason}', + updateBroken: 'Обновление не удалось; плагин не установлен', + updateBrokenDetail: '{to} не удалось установить, и повторная установка {from} также не удалась. Установите {name} снова из меню «Добавить плагин».', + updateLost: 'Результат обновления неизвестен', + updateLostDetail: 'Соединение с DSH было прервано: {reason}. Обновите список плагинов, чтобы увидеть установленную версию.', + updateOutput: 'Показать выходные данные установки', + updateFinish: 'Готово', + installFailedTitle: 'Плагин не удалось установить', + installGithubFailedTitle: 'Не могу получить доступ к GitHub', + installGithubTimeoutTitle: 'Время ожидания соединения GitHub истекло', + installGithubFailedDescription: 'Попробуйте другой источник установки.', + installUseGithubMirror: 'Используйте зеркало материкового Китая.', + installTryAnotherWay: 'Попробуйте другой способ', + installPackageLabel: 'Название пакета плагина', + installEdit: 'Редактировать', + installEditAria: 'Вернуться к редактированию', + installCancelAndEdit: 'Отменить установку и вернуться к редактированию', + installApplyingCancellationError: 'Отмена не подтвердилась. Установка применяется; дождитесь его результата. {reason}', + installReconcile: 'Проверьте статус установки', + installUnknownTitle: 'Результат установки недоступен', + installUnknownDescription: 'На хосте нет активной установки с этим идентификатором запроса. Прежде чем повторить попытку, проверьте список плагинов.', + installResultUnconfirmed: 'Результат установки не получен. Проверьте статус установки. {reason}', + installAwaitingAcceptance: 'Ожидание, пока хост примет установку. Отмена будет повторена автоматически после подтверждения.', + installBackgroundUnknown: 'Результат установки недоступен. Проверьте список плагинов.', + installCancel: 'Отменить установку', + installCloseCancels: 'Отменить установку и закрыть', + installViewTask: 'Посмотреть установку', + installUnconfirmedTitle: 'Статус установки не подтвержден', + installBackgroundDone: 'Установка завершена. Посмотреть подробности установки.', + installBackgroundFailed: 'Установка не удалась. Посмотреть подробности установки.', + installBackgroundUnconfirmed: 'Статус установки не подтвержден. Подробности смотрите в установке.', + installBackgroundApplying: 'Установка применяется и не может быть отменена. Просмотр хода установки.', + installStarting: 'Подготовка к установке…', + installCancelling: 'Остановка установки…', + installApplying: 'Применяется конфигурация, пожалуйста, подождите…', + installCancelledShort: 'Отменено', + installCancelled: 'Установка отменена; плагин не включен и скачанные файлы могут остаться', + installCancelUnconfirmed: 'Установка не подтверждена, остановлена. Повторите попытку отмены или дождитесь результата установки. {reason}', + installEnableNow: 'Включить сейчас', + installDetailsShow: 'Показать детали установки', + installDetailsHide: 'Скрыть сведения об установке', + installVersion: 'Версия {version}', + installSubjectPath: 'Локальный каталог', + installSubjectGit: 'Git-репозиторий', + installSubjectTarball: 'Тарбол', + installLocation: 'Устанавливается в {dir}', + installRetry: 'Повторить', + installChangeRegistry: 'Изменить реестр', + installAttempt: '{previous} не смог обслужить пакет; повторная попытка через {registry} (реестр {index} из {total})', + installAttemptBadge: 'Попытка {index} · {registry}', + installFailureNetwork: 'Сетевое подключение не удалось', + installFailureNetworkAll: 'Не удалось достичь реестра (пробовал: {registries}). Проверьте настройки сети или прокси-сервера или измените реестр и повторите попытку.', + installFailureNetworkHost: 'Не удалось связаться с {host}. Адрес GitHub или ссылка .tgz не извлекаются через реестр: этот компьютер должен получить доступ к ним напрямую или через прокси. Если плагин также опубликован в npm, вместо этого введите имя его пакета.', + installFailureNotFound: 'Такой плагин не найден', + installFailureNoMatchingVersion: 'Ни одна версия не соответствует запросу', + installFailureDiskFull: 'Диск заполнен; установка остановлена', + installFailurePermission: 'Нет разрешения на запись; плагин не может быть установлен', + installFailureBuildBlocked: 'Для продолжения установки сценариям установки зависимости требуется ваше разрешение.', + installFailureBuildBlockedManual: 'pnpm блокировал сценарии установки; разрешите их в разделеallowBuilds в pnpm-workspace.yaml и повторите попытку.', + installFailureIntegrity: 'Загруженный пакет не прошел проверку целостности.', + installFailureTimeout: 'Время установки истекло', + installFailurePnpmMissing: 'pnpm не найден, поэтому ничего установить невозможно', + installFailureGeneric: 'Во время установки что-то пошло не так; детали говорят о чем', + terminalCommandLine: 'Командная строка {n}', + terminalRunning: 'Бег', + terminalFailed: 'Не удалось', + terminalDone: 'Готово', + terminalCopy: 'Копировать', + terminalCopied: 'Скопировано', + terminalNoOutput: 'Нет вывода', + terminalCollapseAria: 'Свернуть вывод', + terminalCollapse: 'Свернуть', + terminalExpandAria: 'Разверните оставшиеся выходные строки {n}.', + terminalExpand: '… {n} еще строки', + terminalExitCode: 'код выхода {code}', + terminalSignal: 'сигнал {signal}', + terminalNoExitCode: 'нет кода выхода', + installDoneNothing: 'Установка завершена без новых зависимостей.', + installDoneRestart: 'Установлен; перезапустите DSH, чтобы загрузить его. {reason}', + installDoneApproved: 'Скрипты установки разрешены для {names}', + installDoneOtherVersion: 'В соответствии с политикой безопасности цепочки поставок pnpm (minimumReleaseAge) версии, опубликованные позже требуемого возраста, не устанавливаются автоматически, поэтому в этой установке использовалась {installed} вместо последней версии {version}. Недавно опубликованная версия не завершила этот период ожидания и может содержать необнаруженный вредоносный код или дефекты. Если вам нужен {version}, удалите текущую версию, а затем установите {exact}, чтобы запросить эту версию.', + installApprovalTitle: 'Для установки скриптов требуется разрешение', + installApprovalDescription: 'Эти пакеты содержат сценарии установки, которые pnpm не запускал.', + installApprovalConsequence: 'После разрешения сценарии запускаются здесь с вашими разрешениями, а разрешение сохраняется в этом профиле.', + installApprovalCaution: 'Разрешите только те пакеты, которым вы доверяете.', + installApproveAndRetry: 'Разрешите эти сценарии и повторите попытку.', + installClose: 'Готово', + close: 'Закрыть', + cancel: 'Отмена', + confirmUninstallTitle: 'Удалить "{name}"?', + confirmUninstallDescription: 'То, что он предоставляет, исчезает после его удаления.', + confirmUninstall: 'Удалить', + failedEnable: 'Не удалось включить: {reason}', + failedDisable: 'Не удалось отключить: {reason}', + failedUninstall: 'Не удалось удалить: {reason}', + failedRowEnable: 'Не удалось включить компонент: {reason}.', + failedRowDisable: 'Не удалось отключить компонент: {reason}.', + reasonManagementRequired: 'Управление плагинами нуждается в этом; его нельзя отключить или удалить.', + reasonUnaddressable: 'Патч профиля не может решить эту проблему однозначно.', + reasonUnknownPlugin: 'Нет такого плагина.', + reasonInvalidSpec: 'Введите действительное имя или адрес пакета.', + reasonAlreadyInstalled: 'Этот пакет уже установлен; удалите его перед установкой другой версии.', + reasonAmbiguousInstall: 'Какой пакет был установлен, невозможно определить по изменению зависимостей.', + reasonNotBundle: 'В этом пакете не объявлен пакет, поэтому им нельзя управлять как плагином.', + reasonNotRemovable: 'Этот пакет не принадлежит профилю, или он нужен управлению плагинами.', + reasonStopProfile: 'Этот профиль работает без HMR; остановите его и удалите пакет с плагином dsh.', + reasonBundleInUse: 'Другая конфигурация по-прежнему использует компоненты этого пакета; сначала выключите их.', + reasonStaleApproval: 'Ожидаемые утверждения сценария изменились; установите еще раз, чтобы обновить их.', + reasonIncompatibleVersion: '{plugin} несовместим с DSH {runtime} (требуется {requirements}); его запуск может привести к сбоям или потере данных.', + reasonIncompatibleVersionUnnamed: 'Этот плагин несовместим с работающей версией DSH; его запуск может привести к сбоям или потере данных.', + reasonIncompatibleInstall: 'Установите версию плагина, совместимую с этим DSH.', + reasonIncompatibleInstalled: 'Удалите его и установите версию, совместимую с этим DSH.', + reasonOperationError: 'Хост сообщил об ошибке.', + detailTitle: 'Подробности', + detailLoading: 'Читаем подробности', + detailTooLarge: 'Детали превышают лимит размера и не были загружены.', + detailNetwork: 'До источника подробностей добраться не удалось.', + detailInvalid: 'Плагин объявляет неверный файл сведений.', + detailFailed: 'Подробности прочитать не удалось.', + detailFootnotes: 'Сноски', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + panel: 'Plug-ins', + title: 'Plug-ins', + intro: 'Instalar, habilitar e configurar plug-ins', + infoLabel: 'Sobre plug-ins', + infoDescription: 'Configure plugins oficiais e instale ou gerencie outros plugins aqui. Veja a lista de plug-ins integrados e o status do tempo de execução em Configurações → Plug-ins integrados.', + loading: 'Lendo plug-ins…', + error: 'Não foi possível ler todos os plugins, possivelmente devido a um problema de rede', + unavailable: 'Esta implantação é executada sem um perfil gerenciável, portanto, os plug-ins não podem ser instalados ou trocados aqui.', + retry: 'Tentar novamente', + refresh: 'Atualizar', + refreshError: 'Falha na atualização. Por favor, tente novamente.', + empty: 'Nenhum plug-in está instalado ainda.', + addPlugin: 'Adicionar plug-in', + chooseAddMethod: 'Escolha como adicionar um plugin', + installExisting: 'Instale um plugin de terceiros', + installExistingDescription: 'Suporta pacotes npm, repositórios Git e diretórios locais', + restartNotice: 'Reinicie DSH para aplicar a alteração. {reason}', + restartReasonNoHmr: 'Este perfil aplica alterações somente na inicialização.', + restartReasonPackageMoved: 'Um pacote instalado agora é resolvido para outro diretório ou a alteração substitui um pacote fornecido pela instalação DSH. Desinstale um pacote antes de instalá-lo de outro local.', + restartReasonHostModule: 'A mudança atinge os módulos DSH carregados.', + restartReasonUnmanagedPlugin: 'A mudança atinge um plugin rodando fora da lista de plugins.', + restartReasonModuleComparison: 'DSH não conseguiu comparar os plug-ins carregados com seus arquivos.', + overriddenNotice: '{name} foi salvo, mas uma configuração de prioridade mais alta o substitui, portanto não está em vigor', + bundlesTitle: 'Plug-ins instalados', + basicTitle: 'Configurações de plug-in integradas', + extensionsTitle: 'Plug-ins experimentais', + moreTitle: 'Plug-ins experimentais', + moreAction: 'Mais', + tabsLabel: 'Visualizações de plug-in', + installedTab: 'Instalado', + statusProblem: 'Problema', + statusBeta: 'Experimental', + reasonLabel: 'Razão', + metadataError: 'Erro de metadados do pacote: {error}', + versionTag: 'v{version}', + partsLabel: 'Componentes', + sourceTitle: 'Fonte', + sourceSpec: 'Fonte do código', + sourceBuiltIn: 'Construído em', + sourceVersion: 'Versão atual', + partsEmpty: 'Este pacote de plugins não contém componentes.', + partsCountTotal: '{count} total', + partsCountRunning: '{count} em execução', + partsCountOff: '{count} desativado', + partOff: 'Desligado', + partsCountFailed: '{count} falhou', + partsFilter: 'Filtrar componentes', + partsFilterEmpty: 'Nenhum componente corresponde.', + partToggle: 'Ativar componente {name}', + rowPhasePending: 'Esperando por dependências', + rowPhaseLoading: 'Carregando', + rowPhaseActive: 'Correndo', + rowPhaseFailed: 'Problema', + rowPhaseUnloading: 'Descarregando', + enableToggle: 'Ativar {name}', + applyingChange: 'Aplicando alterações em {name}', + openDetail: 'Ver {name}', + backToList: 'Voltar aos plug-ins', + crumbRoot: 'Plug-ins', + backToPackage: 'Voltar para {name}', + configureRow: 'Configurar {name}', + rowStateIdle: 'Não está em execução', + uninstall: 'Desinstalar', + uninstallLabel: 'Desinstalar {name}', + installTitle: 'Adicionar plug-in', + installDescription: 'Insira o nome do pacote do plug-in, o endereço do repositório GitHub ou o caminho do diretório local.', + installSpecLabel: 'Nome ou endereço do pacote', + installSpecPlaceholder: 'por exemplo dsh-plugin-baleia-animal de estimação', + installGuideToggle: 'Guia de instalação e exemplos', + installGuideHide: 'Ocultar o guia', + installGuideIdTitle: 'Digite o nome do pacote npm do plugin', + installGuideIdExample: 'dsh-plugin-baleia-animal de estimação', + installGuideIdHint: 'O nome do pacote do plug-in é o nome do pacote npm (como dsh-xxx ou @author/plugin): a parte após dsh plugin add ou pnpm add no comando de instalação README de um plug-in da comunidade.', + installGuideExampleLabel: 'Exemplo: ', + installGitTemplateHint: 'Substitua pelo endereço real do repositório Git.', + installPathTemplateHint: 'Substitua isso pelo caminho real para o diretório local do plugin.', + installGuideFill: 'Exemplo de uso', + installGuideFillAria: 'Use o exemplo {example}', + installGuideSafety: 'Instale apenas plug-ins em que você confia: eles são executados com suas permissões e podem danificar DeepSeek Harness ou vazar seus dados.', + installUpgradeNotice: 'Plug-ins oficiais sob demanda oferecem atualização quando sua versão é diferente de DSH. Para atualizar outros plug-ins, desinstale-os e reinstale-os.', + registryToggle: 'Registro', + registryLegend: 'O registro npm do qual o plugin é baixado', + registryDefault: 'Registro padrão', + registryOfficial: 'Registro oficial do npm', + registryNpmmirror: 'Espelho da China Continental', + registryCustom: 'Endereço personalizado', + registryCustomPlaceholder: 'https://npm.example.com/', + registryCustomHint: 'Insira um endereço de registro npm interno ou privado começando com http:// ou https://. Se for necessário um login, armazene as credenciais em ~/.npmrc nesta máquina.', + registryCustomInvalid: 'Insira um endereço começando com http:// ou https://', + registryListSeparator: ', ', + sentenceSeparator: ' ', + installRun: 'Instalar', + installChecking: 'Verificando…', + installConfirmedTitle: 'Instalar plug-in', + installConfirmedRefused: 'Este plugin não pode ser instalado', + installProblemInvalid: 'Este não é um nome ou endereço de pacote que pode ser instalado: {reason}', + installProblemInstalled: 'Este plugin já está instalado. Para atualizá-lo, desinstale-o e instale-o novamente', + installProblemShipped: 'Este plug-in é fornecido com DSH; atualizar DSH atualiza-o', + installBundledTitle: 'Este plug-in é fornecido com DSH', + installBundledDescription: 'Habilite-o sem baixar outra cópia', + installProblemNotFound: 'Nenhum plugin desse tipo foi encontrado', + installProblemNotPackage: 'O caminho não existe ou não é um pacote de plugin válido', + installProblemNotBundle: 'Este pacote não declara nenhum pacote, portanto não pode ser instalado como um plug-in: {reason}', + installProblemNetwork: 'O registro do plugin não pôde ser acessado; verifique a rede e tente novamente', + installProblemNetworkAll: 'Nenhum registro pôde ser acessado (tentativa: {registries}); verifique as configurações de rede ou proxy ou altere o registro', + installProblemUnknown: 'Não foi possível pesquisar o plug-in: {reason}', + installingTitle: 'Instalando o plug-in…', + installedTitle: 'Instalado', + statusNotInstalled: 'Não instalado', + statusMissingFiles: 'Pacote indisponível', + statusUpdateAvailable: 'Atualização disponível', + sourceNotInstalled: 'Não instalado', + sourceTargetSpec: 'Fonte para este DSH', + sourceTargetVersion: 'Versão para este DSH', + update: 'Atualizar', + updateLabel: 'Atualizar {name}', + versionsTitle: 'Versões', + versionsRecheck: 'Verifique novamente', + versionsChecking: 'Verificando atualizações', + versionsAvailable: 'Atualização para {version} disponível', + versionsPublished: 'Publicado {date}', + versionsLatest: 'Atualizado', + versionsCheckedAt: 'Última verificação em {time}', + versionsBlocked: 'Versões mais recentes precisam de uma atualização DSH', + versionsBlockedDetail: '{version} precisa de {peers}; este DSH é {runtime}', + versionsNoneInstallable: 'Nenhuma versão mais recente para instalar diretamente', + versionsNoneInstallableDetail: 'As versões mais recentes estão obsoletas, são pré-lançamentos ou não declaram nenhum pacote. Expanda para vê-los', + versionsFailedNetwork: 'Não foi possível acessar o registro', + versionsFailedOther: 'Não foi possível verificar atualizações', + versionsDetails: 'Detalhes', + versionsNewerCount: '{count} mais recente', + versionsCollapse: 'Recolher', + versionsInstalledTag: 'Instalado', + versionsPrereleaseTag: 'Pré-lançamento', + versionsDeprecatedTag: 'Obsoleto', + versionsNeedsDsh: 'Precisa de {peers}', + versionsNotBundle: 'Esta versão não declara nenhum pacote e não pode ser instalada', + versionsUpdateLabel: 'Atualizar para {version}', + versionsRegistry: 'Registro', + versionsCheckedAtLabel: 'Verificado em', + versionsFallbackTag: 'Alternativa', + versionsFallbackHint: '{registry} não pôde ser contatado; a lista vem de um registro substituto', + versionsPrimaryTag: 'Primeiro', + versionsShowPrerelease: 'Mostrar pré-lançamentos', + versionsOmitted: '{count} mais versões mais recentes que a instalada não estão listadas', + versionsProblemNetwork: 'Inacessível', + versionsProblemNotFound: 'Não encontrado', + versionsProblemUnknown: 'Falha', + updatesAvailable: 'Atualizações disponíveis: {count}', + updatesNone: 'Todos os plug-ins estão atualizados', + updatesFailed: 'Alguns plug-ins não puderam ser verificados', + updateTitle: 'Atualizar {name}', + updateSource: 'Instalar de', + updateDescription: 'A atualização substitui {from} por {to}; o plugin pode parar brevemente. Se a instalação falhar, {from} será mantido ou instalado novamente.', + updateRunning: 'Atualizando', + updateStepChecking: 'Verifique {version}', + updateStepRemoving: 'Pare e remova {version}', + updateStepInstalling: 'Instalar {version} de {registry}', + updateStepRestoring: 'Instale {version} novamente', + updateDone: 'Atualizado para {version}', + updateDoneDetail: 'A nova versão está em execução.', + updateRestart: '{version} instalado; entra em vigor após uma reinicialização', + updateRefused: 'Não é possível atualizar para {version}', + updateRemoveFailed: 'Não foi possível remover {version}', + updateRestored: 'Falha na atualização; restaurado {version}', + updateRestoredDetail: '{to} falhou ao instalar; {from} foi instalado novamente.', + updateKept: 'Não foi possível atualizar para {version}', + updateKeptDetail: '{from} não foi removido e permanece em uso. {reason}', + updateBroken: 'Falha na atualização; o plugin não está instalado', + updateBrokenDetail: '{to} falhou ao instalar e instalar {from} novamente também falhou. Instale {name} novamente em Adicionar plug-in.', + updateLost: 'O resultado da atualização é desconhecido', + updateLostDetail: 'A conexão com DSH foi interrompida: {reason}. Atualize a lista de plugins para ver a versão instalada.', + updateOutput: 'Mostrar resultado da instalação', + updateFinish: 'Concluído', + installFailedTitle: 'O plugin não pôde ser instalado', + installGithubFailedTitle: 'Não é possível acessar GitHub', + installGithubTimeoutTitle: 'GitHub conexão expirou', + installGithubFailedDescription: 'Tente outra fonte de instalação.', + installUseGithubMirror: 'Use o espelho da China continental', + installTryAnotherWay: 'Tente outra maneira', + installPackageLabel: 'Nome do pacote de plug-ins', + installEdit: 'Editar', + installEditAria: 'Voltar para edição', + installCancelAndEdit: 'Cancele a instalação e retorne à edição', + installApplyingCancellationError: 'O cancelamento não foi confirmado. A instalação está sendo aplicada; espere pelo seu resultado. {reason}', + installReconcile: 'Verifique o status da instalação', + installUnknownTitle: 'Resultado da instalação indisponível', + installUnknownDescription: 'O Host não possui instalação ativa com este ID de solicitação. Verifique a lista de plugins antes de tentar novamente.', + installResultUnconfirmed: 'O resultado da instalação não foi recebido. Verifique o status da instalação. {reason}', + installAwaitingAcceptance: 'Aguardando o Host aceitar a instalação. O cancelamento será tentado novamente automaticamente após a confirmação.', + installBackgroundUnknown: 'Resultado da instalação indisponível. Verifique a lista de plugins.', + installCancel: 'Cancelar instalação', + installCloseCancels: 'Cancelar instalação e fechar', + installViewTask: 'Ver instalação', + installUnconfirmedTitle: 'Status de instalação não confirmado', + installBackgroundDone: 'Instalação concluída. Veja detalhes da instalação.', + installBackgroundFailed: 'A instalação falhou. Veja detalhes da instalação.', + installBackgroundUnconfirmed: 'O status da instalação não foi confirmado. Veja a instalação para obter detalhes.', + installBackgroundApplying: 'A instalação está sendo aplicada e não pode ser cancelada. Veja o progresso da instalação.', + installStarting: 'Preparando a instalação…', + installCancelling: 'Parando a instalação…', + installApplying: 'Aplicando configuração, aguarde…', + installCancelledShort: 'Cancelado', + installCancelled: 'Instalação cancelada; o plugin não está habilitado e os arquivos baixados podem permanecer', + installCancelUnconfirmed: 'A instalação não foi confirmada interrompida. Tente novamente o cancelamento ou aguarde o resultado da instalação. {reason}', + installEnableNow: 'Ativar agora', + installDetailsShow: 'Mostrar detalhes da instalação', + installDetailsHide: 'Ocultar detalhes de instalação', + installVersion: 'Versão {version}', + installSubjectPath: 'Diretório local', + installSubjectGit: 'Repositório Git', + installSubjectTarball: 'Tarball', + installLocation: 'Instala em {dir}', + installRetry: 'Tentar novamente', + installChangeRegistry: 'Alterar registro', + installAttempt: '{previous} não pôde entregar o pacote; tentando novamente através de {registry} (registro {index} de {total})', + installAttemptBadge: 'Tentativa {index} · {registry}', + installFailureNetwork: 'A conexão de rede falhou', + installFailureNetworkAll: 'Nenhum registro pôde ser acessado (tentativa: {registries}). Verifique as configurações de rede ou proxy ou altere o registro e tente novamente.', + installFailureNetworkHost: '{host} não pôde ser alcançado. Um endereço GitHub ou um link .tgz não é obtido através do registro: esta máquina deve acessá-lo diretamente ou através de um proxy. Se o plugin também for publicado no npm, insira o nome do pacote.', + installFailureNotFound: 'Nenhum plugin desse tipo foi encontrado', + installFailureNoMatchingVersion: 'Nenhuma versão corresponde à solicitação', + installFailureDiskFull: 'O disco está cheio; a instalação parou', + installFailurePermission: 'Sem permissão de gravação; o plugin não pode ser instalado', + installFailureBuildBlocked: 'Os scripts de instalação de uma dependência precisam da sua permissão antes que a instalação possa continuar', + installFailureBuildBlockedManual: 'scripts de instalação bloqueados por pnpm; permita-os em permitBuilds em pnpm-workspace.yaml e tente novamente', + installFailureIntegrity: 'O pacote baixado falhou na verificação de integridade', + installFailureTimeout: 'A instalação expirou', + installFailurePnpmMissing: 'pnpm não foi encontrado, então nada pode ser instalado', + installFailureGeneric: 'Algo deu errado durante a instalação; os detalhes dizem o que', + terminalCommandLine: 'Linha de comando {n}', + terminalRunning: 'Correndo', + terminalFailed: 'Falha', + terminalDone: 'Concluído', + terminalCopy: 'Copiar', + terminalCopied: 'Copiado', + terminalNoOutput: 'Sem saída', + terminalCollapseAria: 'Recolher saída', + terminalCollapse: 'Recolher', + terminalExpandAria: 'Expanda as {n} linhas de saída restantes', + terminalExpand: '… mais {n} linhas', + terminalExitCode: 'código de saída {code}', + terminalSignal: 'sinal {signal}', + terminalNoExitCode: 'sem código de saída', + installDoneNothing: 'A instalação foi concluída sem nenhuma nova dependência.', + installDoneRestart: 'Instalado; reinicie DSH para carregá-lo. {reason}', + installDoneApproved: 'Instalar scripts permitidos para {names}', + installDoneOtherVersion: 'De acordo com a política de segurança da cadeia de fornecimento do pnpm (minimumReleaseAge), as versões publicadas mais recentemente do que a idade exigida não são instaladas automaticamente, portanto, esta instalação usou {installed} em vez da versão mais recente {version}. Uma versão recém-publicada não completou esse período de espera e pode conter códigos maliciosos ou defeitos não detectados. Se precisar de {version}, desinstale a versão atual e instale {exact} para solicitar essa versão.', + installApprovalTitle: 'Os scripts de instalação precisam de permissão', + installApprovalDescription: 'Esses pacotes possuem scripts de instalação que o pnpm não executou.', + installApprovalConsequence: 'Uma vez permitido, os scripts são executados aqui com suas permissões, e a permissão é salva neste perfil.', + installApprovalCaution: 'Permita apenas pacotes em que você confia.', + installApproveAndRetry: 'Permita esses scripts e tente novamente', + installClose: 'Concluído', + close: 'Fechar', + cancel: 'Cancelar', + confirmUninstallTitle: 'Desinstalar "{name}"?', + confirmUninstallDescription: 'O que ele fornece desaparece quando é desinstalado.', + confirmUninstall: 'Desinstalar', + failedEnable: 'Não foi possível ativar: {reason}', + failedDisable: 'Não foi possível desativar: {reason}', + failedUninstall: 'Não foi possível desinstalar: {reason}', + failedRowEnable: 'Não foi possível ativar o componente: {reason}', + failedRowDisable: 'Não foi possível desativar o componente: {reason}', + reasonManagementRequired: 'O gerenciamento de plug-ins precisa disso; ele não pode ser desligado ou desinstalado.', + reasonUnaddressable: 'O patch de perfil não pode resolver este problema exclusivamente.', + reasonUnknownPlugin: 'Não existe tal plugin.', + reasonInvalidSpec: 'Insira um nome ou endereço de pacote válido.', + reasonAlreadyInstalled: 'Este pacote já está instalado; desinstale-o antes de instalar outra versão.', + reasonAmbiguousInstall: 'Qual pacote foi instalado não pode ser informado a partir da mudança de dependência.', + reasonNotBundle: 'Este pacote não declara nenhum pacote, portanto não pode ser gerenciado como um plugin.', + reasonNotRemovable: 'Este pacote não pertence ao perfil ou o gerenciamento do plugin precisa dele.', + reasonStopProfile: 'Este perfil é executado sem HMR; pare e desinstale o pacote com o plugin dsh.', + reasonBundleInUse: 'Outras configurações ainda usam os componentes deste pacote configurável; desligue-os primeiro.', + reasonStaleApproval: 'As aprovações de script pendentes foram alteradas; instale novamente para atualizá-los.', + reasonIncompatibleVersion: '{plugin} é incompatível com DSH {runtime} (requer {requirements}); executá-lo pode causar travamentos ou perda de dados.', + reasonIncompatibleVersionUnnamed: 'Este plug-in é incompatível com a versão DSH em execução; executá-lo pode causar travamentos ou perda de dados.', + reasonIncompatibleInstall: 'Instale uma versão de plug-in compatível com este DSH.', + reasonIncompatibleInstalled: 'Desinstale-o e instale uma versão compatível com este DSH.', + reasonOperationError: 'O Host relatou um erro.', + detailTitle: 'Detalhes', + detailLoading: 'Lendo detalhes', + detailTooLarge: 'Os detalhes excedem o limite de tamanho e não foram carregados.', + detailNetwork: 'Não foi possível acessar a fonte dos detalhes.', + detailInvalid: 'O plugin declara um arquivo de detalhes inválido.', + detailFailed: 'Não foi possível ler os detalhes.', + detailFootnotes: 'Notas de rodapé', +} satisfies Record diff --git a/packages/client/ui-plugin-market/locale/de.json b/packages/client/ui-plugin-market/locale/de.json new file mode 100644 index 0000000000..4e9729f5f3 --- /dev/null +++ b/packages/client/ui-plugin-market/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Plugin-Erkennung", + "description": "Durchsuchen Sie konfigurierte Plugin-Marktindizes und installieren Sie deren Pakete." + } +} diff --git a/packages/client/ui-plugin-market/locale/es.json b/packages/client/ui-plugin-market/locale/es.json new file mode 100644 index 0000000000..1a06daea54 --- /dev/null +++ b/packages/client/ui-plugin-market/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Descubrimiento de complementos", + "description": "Explore los índices de mercado de complementos configurados e instale sus paquetes." + } +} diff --git a/packages/client/ui-plugin-market/locale/fr.json b/packages/client/ui-plugin-market/locale/fr.json new file mode 100644 index 0000000000..bb4051a0a9 --- /dev/null +++ b/packages/client/ui-plugin-market/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Découverte de plugins", + "description": "Parcourez les index de marché des plugins configurés et installez leurs packages." + } +} diff --git a/packages/client/ui-plugin-market/locale/pt.json b/packages/client/ui-plugin-market/locale/pt.json new file mode 100644 index 0000000000..bc5066ef59 --- /dev/null +++ b/packages/client/ui-plugin-market/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Descoberta de plug-ins", + "description": "Navegue pelos índices de mercado de plugins configurados e instale seus pacotes." + } +} diff --git a/packages/client/ui-plugin-market/locale/ru.json b/packages/client/ui-plugin-market/locale/ru.json new file mode 100644 index 0000000000..c9e5188009 --- /dev/null +++ b/packages/client/ui-plugin-market/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Открытие плагина", + "description": "Просмотрите настроенные рыночные индексы плагинов и установите их пакеты." + } +} diff --git a/packages/client/ui-plugin-market/src/client/index.ts b/packages/client/ui-plugin-market/src/client/index.ts index c1aab2c746..36aed35a01 100644 --- a/packages/client/ui-plugin-market/src/client/index.ts +++ b/packages/client/ui-plugin-market/src/client/index.ts @@ -12,7 +12,7 @@ import type {} from '@deepseek-ai/dsh-plugin-manager/types' import type {} from '@deepseek-ai/dsh-plugin-market/types' import type {} from '@deepseek-ai/dsh-client-ui-plugin-manager/client' import { DiscoverSection } from './DiscoverSection.tsx' -import { en, ja, zh, type PluginMarketLocaleKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh, type PluginMarketLocaleKey } from './locales.ts' import { DiscoverController } from './market-store.ts' export type { DiscoverFace, DiscoverState } from './market-store.ts' @@ -36,7 +36,7 @@ export const inject = ['slots', 'locale', 'remote', 'remote.pluginMarket', 'remo * @param ctx - the browser plugin context. */ export function apply(ctx: ClientContext): void { - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-plugin-market: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-plugin-market: dictionaries') const controller = new DiscoverController(ctx, () => document.baseURI) ctx.effect(() => () => { controller.dispose() }, 'ui-plugin-market: controller') ctx.effect(() => { diff --git a/packages/client/ui-plugin-market/src/client/locales.ts b/packages/client/ui-plugin-market/src/client/locales.ts index 20aada6cae..ec3d23c658 100644 --- a/packages/client/ui-plugin-market/src/client/locales.ts +++ b/packages/client/ui-plugin-market/src/client/locales.ts @@ -275,3 +275,458 @@ export const ja = { 'detailFailed': '詳細を読み取れませんでした。', 'footnotes': '脚注', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + title: 'Descubrir', + refresh: 'Actualizar', + loading: 'leyendo el índice', + retry: 'Reintentar', + close: 'Cerrar', + cancel: 'Cancelar', + emptyTitle: 'Aún no hay mercados de complementos', + emptyDescription: 'Agregue un índice del mercado de complementos para explorar e instalar sus complementos aquí.', + addFirstSource: 'Agregar fuente de índice', + sourcesFailed: 'No se pudieron leer las fuentes del índice.', + manageSources: 'Administrar fuentes de índice...', + marketMenu: 'Cambiar el mercado de complementos, actualmente {market}', + sourcesTitle: 'Fuentes del índice', + sourcesDescription: 'Un mercado de complementos se publica como la URL de un archivo de índice. Discover explora los índices enumerados aquí.', + sourcesLabel: 'Fuentes de índice agregadas', + sourceUrl: 'URL del índice', + sourcePlaceholder: 'https://example.com/index.json', + addSource: 'Añadir', + removeSource: 'Quitar', + removeSourceNamed: 'Quitar {url}', + sourcesTrust: 'Los índices provienen de terceros. Agregue solo fuentes en las que confíe: sus complementos se ejecutan con sus permisos una vez instalados.', + sourceInvalid: 'Utilice una dirección http o https sin nombre de usuario, contraseña o fragmento #.', + sourceDuplicate: 'Esta fuente de índice ya está agregada.', + sourceUnavailable: 'Las fuentes del índice no se pueden guardar aquí.', + sourceFailed: 'No se pudieron guardar las fuentes del índice.', + readFailed: 'No se pudo leer este índice.', + readInvalid: 'Este índice no tiene un formato válido.', + readChanged: 'Este índice cambió durante la carga.', + search: 'Complementos de búsqueda', + filter: 'Etiquetas', + filterCount: 'Etiquetas · {count}', + sortBy: 'Tipo: {sort}', + sortRelevance: 'mejor partido', + sortDefault: 'Orden predeterminado', + sortPublished: 'Fecha de publicación', + switchToAscending: 'Orden ascendente', + switchToDescending: 'Orden descendente', + categoriesLabel: 'Categorías', + allCategories: 'Todos', + emptyIndex: 'Este índice no incluye complementos.', + noMatches: 'Ningún complemento coincide.', + showMore: 'Mostrar más', + entryMeta: '{version} · {date}', + entryMetaAuthor: '{version} · {author} · {date}', + openEntry: 'Ver {name}', + install: 'Instalar', + installTitle: 'Instalar {name}', + installVersionTitle: 'Instalar {name} {version}', + openInstalled: 'Ver {name} en Instalado', + statusInstalled: 'Instalado', + statusUpdate: 'Actualización disponible', + statusProvided: 'Proporcionado por DSH', + incompatible: 'Esta versión no es compatible con DSH {runtime} en ejecución; requiere DSH {range}.', + noCompatibleVersion: 'Ninguna versión es compatible con DSH {runtime}', + exempted: 'Esta versión no es compatible con DSH en ejecución, pero usted establece una exención de compatibilidad para ella.', + backToList: 'Descubrir', + factSource: 'Fuente', + factPackage: 'Paquete', + factRegistry: 'Registro', + factRepository: 'Repositorio', + factCommit: 'comprometerse', + factDirectory: 'Directorio', + factPublished: 'Publicado', + factAuthor: 'Autor', + factHomepage: 'Página de inicio', + factSourceCode: 'código fuente', + factCategory: 'Categoría', + factLabels: 'Etiquetas', + factMarket: 'Mercado de complementos', + versionsTitle: 'Versiones', + versionsLabel: 'Versiones de {name}', + versionDefault: 'Recomendado', + versionInstalled: 'Instalado', + versionIncompatible: 'incompatible', + versionExempted: 'exento', + versionPrerelease: 'Presentación', + confirmTitle: '¿Instalar "{name}"?', + installTrust: 'Los complementos se ejecutan en esta máquina con sus permisos. Asegúrate de confiar en el origen de este.', + detailTitle: 'Detalles', + detailLoading: 'Detalles de lectura', + detailTooLarge: 'Los detalles o su repositorio exceden el límite de tamaño y no se cargaron.', + detailNetwork: 'No se pudo llegar a la fuente de los detalles.', + detailDenied: 'No se pudo acceder al repositorio de detalles. Verifique sus credenciales de Git.', + detailGitUnavailable: 'Los detalles están en un repositorio que debe leerse con Git y Git no se pudo ejecutar. Instale Git y vuelva a intentarlo.', + detailInvalid: 'El complemento declara un archivo de detalles no válido.', + detailFailed: 'No se pudieron leer los detalles.', + footnotes: 'Notas a pie de página', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + title: 'Découvrez', + refresh: 'Actualiser', + loading: "Lire l'index", + retry: 'Réessayer', + close: 'Fermer', + cancel: 'Annuler', + emptyTitle: 'Pas encore de marché de plugins', + emptyDescription: 'Ajoutez un index du marché des plugins pour parcourir et installer ses plugins ici.', + addFirstSource: "Ajouter une source d'index", + sourcesFailed: "Impossible de lire les sources de l'index.", + manageSources: "Gérer les sources d'index…", + marketMenu: 'Marché des plugins Switch, actuellement {market}', + sourcesTitle: "Sources d'index", + sourcesDescription: "Un marché de plugins est publié sous la forme de l'URL d'un fichier d'index. Discover parcourt les index répertoriés ici.", + sourcesLabel: "Sources d'index ajoutées", + sourceUrl: "URL de l'index", + sourcePlaceholder: 'https://example.com/index.json', + addSource: 'Ajouter', + removeSource: 'Supprimer', + removeSourceNamed: 'Supprimer {url}', + sourcesTrust: "Les index proviennent de tiers. Ajoutez uniquement des sources auxquelles vous faites confiance : leurs plugins s'exécutent avec vos autorisations une fois installés.", + sourceInvalid: "Utilisez une adresse http ou https sans nom d'utilisateur, mot de passe ou fragment #.", + sourceDuplicate: "Cette source d'index est déjà ajoutée.", + sourceUnavailable: "Les sources d'index ne peuvent pas être enregistrées ici.", + sourceFailed: "Impossible d'enregistrer les sources de l'index.", + readFailed: 'Impossible de lire cet index.', + readInvalid: "Cet index n'est pas dans un format valide.", + readChanged: 'Cet index a changé lors du chargement.', + search: 'Plugins de recherche', + filter: 'Étiquettes', + filterCount: 'Étiquettes · {count}', + sortBy: 'Trier : {sort}', + sortRelevance: 'Meilleure correspondance', + sortDefault: 'Ordre par défaut', + sortPublished: 'Date de publication', + switchToAscending: 'Trier par ordre croissant', + switchToDescending: 'Trier par ordre décroissant', + categoriesLabel: 'Catégories', + allCategories: 'Tout', + emptyIndex: 'Cet index ne répertorie aucun plugin.', + noMatches: 'Aucun plugin ne correspond.', + showMore: 'Afficher plus', + entryMeta: '{version} · {date}', + entryMetaAuthor: '{version} · {author} · {date}', + openEntry: 'Voir {name}', + install: 'Installer', + installTitle: 'Installer {name}', + installVersionTitle: 'Installer {name} {version}', + openInstalled: 'Afficher {name} dans Installé', + statusInstalled: 'Installé', + statusUpdate: 'Mise à jour disponible', + statusProvided: 'Fourni par DSH', + incompatible: "Cette version n'est pas compatible avec le DSH {runtime} en cours d'exécution ; cela nécessite DSH {range}.", + noCompatibleVersion: "Aucune version n'est compatible avec DSH {runtime}", + exempted: "Cette version n'est pas compatible avec le DSH en cours d'exécution, mais vous avez défini une exemption de compatibilité pour celui-ci.", + backToList: 'Découvrez', + factSource: 'Source', + factPackage: 'Forfait', + factRegistry: 'Registre', + factRepository: 'Référentiel', + factCommit: "S'engager", + factDirectory: 'Annuaire', + factPublished: 'Publié', + factAuthor: 'Auteur', + factHomepage: "Page d'accueil", + factSourceCode: 'Code source', + factCategory: 'Catégorie', + factLabels: 'Étiquettes', + factMarket: 'Marché des plugins', + versionsTitle: 'Versions', + versionsLabel: 'Versions de {name}', + versionDefault: 'Recommandé', + versionInstalled: 'Installé', + versionIncompatible: 'Incompatible', + versionExempted: 'Exonéré', + versionPrerelease: 'Avant-première', + confirmTitle: 'Installer « {name} » ?', + installTrust: "Les plugins s'exécutent sur cette machine avec vos autorisations. Assurez-vous de faire confiance à l'origine de celui-ci.", + detailTitle: 'Détails', + detailLoading: 'Détails de lecture', + detailTooLarge: "Les détails ou leur référentiel dépassent la limite de taille et n'ont pas été chargés.", + detailNetwork: "Impossible d'atteindre la source des détails.", + detailDenied: "Impossible d'accéder au référentiel des détails. Vérifiez vos informations d'identification Git.", + detailGitUnavailable: "Les détails se trouvent dans un référentiel qui doit être lu avec Git, et Git n'a pas pu s'exécuter. Installez Git, puis réessayez.", + detailInvalid: 'Le plugin déclare un fichier de détails invalide.', + detailFailed: 'Impossible de lire les détails.', + footnotes: 'Notes de bas de page', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + title: 'Entdecken', + refresh: 'Aktualisieren', + loading: 'Den Index lesen', + retry: 'Erneut versuchen', + close: 'Schließen', + cancel: 'Abbrechen', + emptyTitle: 'Noch keine Plugin-Märkte', + emptyDescription: 'Fügen Sie hier einen Plugin-Marktindex hinzu, um die Plugins zu durchsuchen und zu installieren.', + addFirstSource: 'Indexquelle hinzufügen', + sourcesFailed: 'Die Indexquellen konnten nicht gelesen werden.', + manageSources: 'Indexquellen verwalten…', + marketMenu: 'Switch-Plugin-Markt, derzeit {market}', + sourcesTitle: 'Indexquellen', + sourcesDescription: 'Ein Plugin-Markt wird als URL einer Indexdatei veröffentlicht. Discover durchsucht die hier aufgeführten Indizes.', + sourcesLabel: 'Indexquellen hinzugefügt', + sourceUrl: 'Index-URL', + sourcePlaceholder: 'https://example.com/index.json', + addSource: 'Hinzufügen', + removeSource: 'Entfernen', + removeSourceNamed: 'Entfernen Sie {url}', + sourcesTrust: 'Indizes stammen von Dritten. Fügen Sie nur Quellen hinzu, denen Sie vertrauen: Ihre Plugins werden nach der Installation mit Ihren Berechtigungen ausgeführt.', + sourceInvalid: 'Verwenden Sie eine http- oder https-Adresse ohne Benutzernamen, Passwort oder #-Fragment.', + sourceDuplicate: 'Diese Indexquelle wurde bereits hinzugefügt.', + sourceUnavailable: 'Indexquellen können hier nicht gespeichert werden.', + sourceFailed: 'Die Indexquellen konnten nicht gespeichert werden.', + readFailed: 'Dieser Index konnte nicht gelesen werden.', + readInvalid: 'Dieser Index hat kein gültiges Format.', + readChanged: 'Dieser Index hat sich beim Laden geändert.', + search: 'Such-Plugins', + filter: 'Etiketten', + filterCount: 'Etiketten · {count}', + sortBy: 'Sortierung: {sort}', + sortRelevance: 'Beste Übereinstimmung', + sortDefault: 'Standardreihenfolge', + sortPublished: 'Veröffentlichungsdatum', + switchToAscending: 'Aufsteigend sortieren', + switchToDescending: 'Absteigend sortieren', + categoriesLabel: 'Kategorien', + allCategories: 'Alle', + emptyIndex: 'Dieser Index listet keine Plugins auf.', + noMatches: 'Es stimmen keine Plugins überein.', + showMore: 'Mehr anzeigen', + entryMeta: '{version} · {date}', + entryMetaAuthor: '{version} · {author} · {date}', + openEntry: 'Siehe {name}', + install: 'Installieren', + installTitle: 'Installieren Sie {name}', + installVersionTitle: 'Installieren Sie {name} {version}', + openInstalled: '{name} unter „Installiert“ anzeigen', + statusInstalled: 'Installiert', + statusUpdate: 'Update verfügbar', + statusProvided: 'Bereitgestellt von DSH', + incompatible: 'Diese Version ist nicht mit dem laufenden DSH {runtime} kompatibel; es erfordert DSH {range}.', + noCompatibleVersion: 'Keine Version ist mit DSH {runtime} kompatibel', + exempted: 'Diese Version ist nicht mit der laufenden Version DSH kompatibel, Sie haben jedoch eine Kompatibilitätsausnahme dafür festgelegt.', + backToList: 'Entdecken', + factSource: 'Quelle', + factPackage: 'Paket', + factRegistry: 'Registrierung', + factRepository: 'Repository', + factCommit: 'Begehen', + factDirectory: 'Verzeichnis', + factPublished: 'Veröffentlicht', + factAuthor: 'Autor', + factHomepage: 'Homepage', + factSourceCode: 'Quellcode', + factCategory: 'Kategorie', + factLabels: 'Etiketten', + factMarket: 'Plugin-Markt', + versionsTitle: 'Versionen', + versionsLabel: 'Versionen von {name}', + versionDefault: 'Empfohlen', + versionInstalled: 'Installiert', + versionIncompatible: 'Inkompatibel', + versionExempted: 'Ausgenommen', + versionPrerelease: 'Vorabversion', + confirmTitle: '„{name}“ installieren?', + installTrust: 'Plugins werden mit Ihren Berechtigungen auf diesem Computer ausgeführt. Stellen Sie sicher, dass Sie darauf vertrauen, woher dieser kommt.', + detailTitle: 'Details', + detailLoading: 'Details lesen', + detailTooLarge: 'Die Details oder ihr Repository überschreiten die Größenbeschränkung und wurden nicht geladen.', + detailNetwork: 'Die Quelle der Details konnte nicht erreicht werden.', + detailDenied: 'Auf das Repository mit den Details konnte nicht zugegriffen werden. Überprüfen Sie Ihre Git-Anmeldeinformationen.', + detailGitUnavailable: 'Die Details befinden sich in einem Repository, das mit Git gelesen werden muss, und Git konnte nicht ausgeführt werden. Installieren Sie Git und versuchen Sie es erneut.', + detailInvalid: 'Das Plugin deklariert eine ungültige Detaildatei.', + detailFailed: 'Die Details konnten nicht gelesen werden.', + footnotes: 'Fußnoten', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + title: 'Откройте для себя', + refresh: 'Обновить', + loading: 'Чтение индекса', + retry: 'Повторить', + close: 'Закрыть', + cancel: 'Отмена', + emptyTitle: 'Рынка плагинов пока нет', + emptyDescription: 'Добавьте индекс рынка плагинов, чтобы просматривать и устанавливать здесь плагины.', + addFirstSource: 'Добавить источник индекса', + sourcesFailed: 'Не удалось прочитать исходники индекса.', + manageSources: 'Управление источниками индексов…', + marketMenu: 'Переключить рынок плагинов, в настоящее время {market}', + sourcesTitle: 'Источники индекса', + sourcesDescription: 'Рынок плагинов публикуется как URL-адрес одного индексного файла. Discover просматривает перечисленные здесь индексы.', + sourcesLabel: 'Добавлены источники индекса', + sourceUrl: 'URL-адрес индекса', + sourcePlaceholder: 'https://example.com/index.json', + addSource: 'Добавить', + removeSource: 'Удалить', + removeSourceNamed: 'Удалить {url}', + sourcesTrust: 'Индексы поступают от третьих лиц. Добавляйте только те источники, которым вы доверяете: их плагины запускаются с вашими разрешениями после установки.', + sourceInvalid: 'Используйте адрес http или https без имени пользователя, пароля или фрагмента #.', + sourceDuplicate: 'Этот источник индекса уже добавлен.', + sourceUnavailable: 'Источники индекса здесь сохранить нельзя.', + sourceFailed: 'Не удалось сохранить источники индекса.', + readFailed: 'Не удалось прочитать этот индекс.', + readInvalid: 'Этот индекс имеет недопустимый формат.', + readChanged: 'Этот индекс менялся при загрузке.', + search: 'Поиск плагинов', + filter: 'Этикетки', + filterCount: 'Этикетки · {count}', + sortBy: 'Сортировать: {sort}', + sortRelevance: 'Лучший матч', + sortDefault: 'Порядок по умолчанию', + sortPublished: 'Дата публикации', + switchToAscending: 'Сортировать по возрастанию', + switchToDescending: 'Сортировать по убыванию', + categoriesLabel: 'Категории', + allCategories: 'Все', + emptyIndex: 'В этом индексе нет плагинов.', + noMatches: 'Никакие плагины не подходят.', + showMore: 'Показать больше', + entryMeta: '{version} · {date}', + entryMetaAuthor: '{version} · {author} · {date}', + openEntry: 'Посмотреть {name}', + install: 'Установить', + installTitle: 'Установить {name}', + installVersionTitle: 'Установить {name} {version}', + openInstalled: 'Посмотреть {name} в списке «Установлено»', + statusInstalled: 'Установлено', + statusUpdate: 'Доступно обновление', + statusProvided: 'Предоставлено DSH', + incompatible: 'Эта версия несовместима с работающим DSH {runtime}; для этого требуется DSH {range}.', + noCompatibleVersion: 'Ни одна версия не совместима с DSH {runtime}.', + exempted: 'Эта версия несовместима с работающим DSH, но вы установили для нее исключение совместимости.', + backToList: 'Откройте для себя', + factSource: 'Источник', + factPackage: 'Пакет', + factRegistry: 'Реестр', + factRepository: 'Репозиторий', + factCommit: 'Зафиксировать', + factDirectory: 'Каталог', + factPublished: 'Опубликовано', + factAuthor: 'Автор', + factHomepage: 'Домашняя страница', + factSourceCode: 'Исходный код', + factCategory: 'Категория', + factLabels: 'Этикетки', + factMarket: 'Рынок плагинов', + versionsTitle: 'Версии', + versionsLabel: 'Версии {name}', + versionDefault: 'Рекомендуется', + versionInstalled: 'Установлено', + versionIncompatible: 'Несовместимый', + versionExempted: 'освобожден', + versionPrerelease: 'Пререлиз', + confirmTitle: 'Установить "{name}"?', + installTrust: 'Плагины запускаются на этом компьютере с вашего разрешения. Убедитесь, что вы доверяете источнику этого сообщения.', + detailTitle: 'Подробности', + detailLoading: 'Читаем подробности', + detailTooLarge: 'Детали или их репозиторий превышают предельный размер и не были загружены.', + detailNetwork: 'До источника подробностей добраться не удалось.', + detailDenied: 'Не удалось получить доступ к хранилищу реквизитов. Проверьте свои учетные данные Git.', + detailGitUnavailable: 'Подробности находятся в репозитории, который необходимо прочитать с помощью Git, и Git не удалось запустить. Установите Git и повторите попытку.', + detailInvalid: 'Плагин объявляет неверный файл сведений.', + detailFailed: 'Подробности прочитать не удалось.', + footnotes: 'Сноски', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + title: 'Descubra', + refresh: 'Atualizar', + loading: 'Lendo o índice', + retry: 'Tentar novamente', + close: 'Fechar', + cancel: 'Cancelar', + emptyTitle: 'Ainda não há mercados de plugins', + emptyDescription: 'Adicione um índice de mercado de plugins para navegar e instalar seus plugins aqui.', + addFirstSource: 'Adicionar fonte de índice', + sourcesFailed: 'Não foi possível ler as fontes do índice.', + manageSources: 'Gerenciar fontes de índice…', + marketMenu: 'Mudar de mercado de plug-ins, atualmente {market}', + sourcesTitle: 'Fontes de índice', + sourcesDescription: 'Um mercado de plugins é publicado como a URL de um arquivo de índice. O Discover navega nos índices listados aqui.', + sourcesLabel: 'Fontes de índice adicionadas', + sourceUrl: 'URL do índice', + sourcePlaceholder: 'https://example.com/index.json', + addSource: 'Adicionar', + removeSource: 'Remover', + removeSourceNamed: 'Remover {url}', + sourcesTrust: 'Os índices vêm de terceiros. Adicione apenas fontes em que você confia: seus plug-ins são executados com suas permissões, uma vez instalados.', + sourceInvalid: 'Use um endereço http ou https sem nome de usuário, senha ou fragmento #.', + sourceDuplicate: 'Esta fonte de índice já foi adicionada.', + sourceUnavailable: 'As fontes do índice não podem ser salvas aqui.', + sourceFailed: 'Não foi possível salvar as fontes do índice.', + readFailed: 'Não foi possível ler este índice.', + readInvalid: 'Este índice não está em um formato válido.', + readChanged: 'Este índice mudou durante o carregamento.', + search: 'Plug-ins de pesquisa', + filter: 'Etiquetas', + filterCount: 'Marcadores · {count}', + sortBy: 'Classificar: {sort}', + sortRelevance: 'Melhor correspondência', + sortDefault: 'Ordem padrão', + sortPublished: 'Data de publicação', + switchToAscending: 'Classificar em ordem crescente', + switchToDescending: 'Classificar em ordem decrescente', + categoriesLabel: 'Categorias', + allCategories: 'Todos', + emptyIndex: 'Este índice não lista plug-ins.', + noMatches: 'Nenhum plug-in corresponde.', + showMore: 'Mostrar mais', + entryMeta: '{version} · {date}', + entryMetaAuthor: '{version} · {author} · {date}', + openEntry: 'Ver {name}', + install: 'Instalar', + installTitle: 'Instalar {name}', + installVersionTitle: 'Instalar {name} {version}', + openInstalled: 'Ver {name} em Instalado', + statusInstalled: 'Instalado', + statusUpdate: 'Atualização disponível', + statusProvided: 'Fornecido por DSH', + incompatible: 'Esta versão não é compatível com o DSH {runtime} em execução; requer DSH {range}.', + noCompatibleVersion: 'Nenhuma versão é compatível com DSH {runtime}', + exempted: 'Esta versão não é compatível com o DSH em execução, mas você definiu uma isenção de compatibilidade para ela.', + backToList: 'Descubra', + factSource: 'Fonte', + factPackage: 'Pacote', + factRegistry: 'Registro', + factRepository: 'Repositório', + factCommit: 'Confirmar', + factDirectory: 'Diretório', + factPublished: 'Publicado', + factAuthor: 'Autor', + factHomepage: 'Página inicial', + factSourceCode: 'Código fonte', + factCategory: 'Categoria', + factLabels: 'Etiquetas', + factMarket: 'Mercado de plug-ins', + versionsTitle: 'Versões', + versionsLabel: 'Versões de {name}', + versionDefault: 'Recomendado', + versionInstalled: 'Instalado', + versionIncompatible: 'Incompatível', + versionExempted: 'Isento', + versionPrerelease: 'Pré-lançamento', + confirmTitle: 'Instalar "{name}"?', + installTrust: 'Os plug-ins são executados nesta máquina com suas permissões. Certifique-se de confiar de onde este vem.', + detailTitle: 'Detalhes', + detailLoading: 'Lendo detalhes', + detailTooLarge: 'Os detalhes ou seu repositório excedem o limite de tamanho e não foram carregados.', + detailNetwork: 'Não foi possível acessar a fonte dos detalhes.', + detailDenied: 'Não foi possível acessar o repositório dos detalhes. Verifique suas credenciais do Git.', + detailGitUnavailable: 'Os detalhes estão em um repositório que deve ser lido com o Git, e o Git não pôde ser executado. Instale o Git e tente novamente.', + detailInvalid: 'O plugin declara um arquivo de detalhes inválido.', + detailFailed: 'Não foi possível ler os detalhes.', + footnotes: 'Notas de rodapé', +} satisfies Record diff --git a/packages/client/ui-reference/locale/de.json b/packages/client/ui-reference/locale/de.json new file mode 100644 index 0000000000..caffa08eac --- /dev/null +++ b/packages/client/ui-reference/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Datei- und Sitzungsreferenzschnittstelle", + "description": "Verweisen Sie auf Dateien oder andere Sitzungen über @ im Eingabefeld." + } +} diff --git a/packages/client/ui-reference/locale/es.json b/packages/client/ui-reference/locale/es.json new file mode 100644 index 0000000000..c82ce82b70 --- /dev/null +++ b/packages/client/ui-reference/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de referencia de archivos y sesiones", + "description": "Archivos de referencia u otras sesiones a través de @ en el cuadro de entrada." + } +} diff --git a/packages/client/ui-reference/locale/fr.json b/packages/client/ui-reference/locale/fr.json new file mode 100644 index 0000000000..392efe7eb4 --- /dev/null +++ b/packages/client/ui-reference/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de référence de fichiers et de sessions", + "description": "Référencez des fichiers ou d'autres sessions via @ dans la zone de saisie." + } +} diff --git a/packages/client/ui-reference/locale/pt.json b/packages/client/ui-reference/locale/pt.json new file mode 100644 index 0000000000..25bd646b1e --- /dev/null +++ b/packages/client/ui-reference/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de referência de arquivo e sessão", + "description": "Faça referência a arquivos ou outras sessões via @ na caixa de entrada." + } +} diff --git a/packages/client/ui-reference/locale/ru.json b/packages/client/ui-reference/locale/ru.json new file mode 100644 index 0000000000..80c1d5d22f --- /dev/null +++ b/packages/client/ui-reference/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Справочный интерфейс файлов и сеансов", + "description": "Ссылайтесь на файлы или другие сеансы через @ в поле ввода." + } +} diff --git a/packages/client/ui-reference/src/client/index.ts b/packages/client/ui-reference/src/client/index.ts index 4cfd6e8677..31e06bb0b8 100644 --- a/packages/client/ui-reference/src/client/index.ts +++ b/packages/client/ui-reference/src/client/index.ts @@ -33,7 +33,7 @@ import { formatFileMention } from '@deepseek-ai/dsh-file-reference/grammar' import type { FileReferenceCandidate } from '@deepseek-ai/dsh-file-reference/types' import type { SessionReferenceMentionCandidate } from '@deepseek-ai/dsh-session-reference/types' import { abbreviateHomePath, fileAddressFor } from '@deepseek-ai/dsh-util-workspace-path' -import { en, ja, NS, zh, type ReferenceKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, NS, zh, type ReferenceKey } from './locales.ts' declare module '@deepseek-ai/dsh-api-session-controller/client' { interface SessionReferenceSourceMap { @@ -53,7 +53,7 @@ export const inject = [ * @param ctx - client root context. */ export function apply(ctx: ClientContext): void { - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-reference: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-reference: dictionaries') const t = ctx.locale.bind(NS) const sessions = ctx.get('sessions') as ISessions ctx.uiConversation.userText.register(fileReferenceRule) diff --git a/packages/client/ui-reference/src/client/locales.ts b/packages/client/ui-reference/src/client/locales.ts index af8e37175a..a742c82eca 100644 --- a/packages/client/ui-reference/src/client/locales.ts +++ b/packages/client/ui-reference/src/client/locales.ts @@ -77,3 +77,98 @@ export const ja = { 'time.months': '{n}か月', 'time.years': '{n}年', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'section.files': 'Archivos y carpetas', + 'section.subagents': 'Subagentes', + 'section.sessions': 'Sesiones', + 'candidate.noCwd': '(sin cwd)', + 'crumb.root': 'Espacio de trabajo', + 'fileOpen.title': 'No se pudo abrir el archivo', + 'fileOpen.failed': 'No se pudo abrir "{path}". Inténtalo de nuevo o cierra este mensaje.', + 'fileOpen.close': 'Cerrar', + 'fileOpen.retry': 'Reintentar', + 'time.now': 'ahora', + 'time.minutes': '{n}min', + 'time.hours': '{n}h', + 'time.days': '{n}d', + 'time.months': '{n}mo', + 'time.years': '{n}y', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'section.files': 'Fichiers et dossiers', + 'section.subagents': 'Sous-agents', + 'section.sessions': 'Séances', + 'candidate.noCwd': '(pas de cwd)', + 'crumb.root': 'Espace de travail', + 'fileOpen.title': "Impossible d'ouvrir le fichier", + 'fileOpen.failed': "Impossible d'ouvrir \"{path}\". Réessayez ou fermez ce message.", + 'fileOpen.close': 'Fermer', + 'fileOpen.retry': 'Réessayer', + 'time.now': 'maintenant', + 'time.minutes': '{n}min', + 'time.hours': '{n}h', + 'time.days': '{n}d', + 'time.months': '{n}mo', + 'time.years': '{n}y', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'section.files': 'Dateien und Ordner', + 'section.subagents': 'Subagenten', + 'section.sessions': 'Sitzungen', + 'candidate.noCwd': '(kein CWD)', + 'crumb.root': 'Arbeitsbereich', + 'fileOpen.title': 'Datei konnte nicht geöffnet werden', + 'fileOpen.failed': '„{path}“ konnte nicht geöffnet werden. Versuchen Sie es erneut oder schließen Sie diese Nachricht.', + 'fileOpen.close': 'Schließen', + 'fileOpen.retry': 'Erneut versuchen', + 'time.now': 'jetzt', + 'time.minutes': '{n}min', + 'time.hours': '{n}h', + 'time.days': '{n}d', + 'time.months': '{n}mo', + 'time.years': '{n}y', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'section.files': 'Файлы и папки', + 'section.subagents': 'Субагенты', + 'section.sessions': 'Сессии', + 'candidate.noCwd': '(без КДВ)', + 'crumb.root': 'Рабочая область', + 'fileOpen.title': 'Не удалось открыть файл', + 'fileOpen.failed': 'Не удалось открыть «{path}». Попробуйте еще раз или закройте это сообщение.', + 'fileOpen.close': 'Закрыть', + 'fileOpen.retry': 'Повторить', + 'time.now': 'сейчас', + 'time.minutes': '{n}мин', + 'time.hours': '{n}h', + 'time.days': '{n}d', + 'time.months': '{n}mo', + 'time.years': '{n}y', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'section.files': 'Arquivos e pastas', + 'section.subagents': 'Subagentes', + 'section.sessions': 'Sessões', + 'candidate.noCwd': '(sem cwd)', + 'crumb.root': 'Espaço de trabalho', + 'fileOpen.title': 'Não foi possível abrir o arquivo', + 'fileOpen.failed': 'Não foi possível abrir “{path}”. Tente novamente ou feche esta mensagem.', + 'fileOpen.close': 'Fechar', + 'fileOpen.retry': 'Tentar novamente', + 'time.now': 'agora', + 'time.minutes': '{n}min', + 'time.hours': '{n}h', + 'time.days': '{n}d', + 'time.months': '{n} mês', + 'time.years': '{n}s', +} satisfies Record diff --git a/packages/client/ui-renderer/locale/de.json b/packages/client/ui-renderer/locale/de.json new file mode 100644 index 0000000000..d913a630cf --- /dev/null +++ b/packages/client/ui-renderer/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Schnittstellen-Rendering", + "description": "Integrieren Sie die von jedem Plug-In bereitgestellten Schnittstellenkomponenten in die Anwendung." + } +} diff --git a/packages/client/ui-renderer/locale/es.json b/packages/client/ui-renderer/locale/es.json new file mode 100644 index 0000000000..74b778c2c5 --- /dev/null +++ b/packages/client/ui-renderer/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Representación de interfaz", + "description": "Ensamble los componentes de la interfaz proporcionados por cada complemento en la aplicación." + } +} diff --git a/packages/client/ui-renderer/locale/fr.json b/packages/client/ui-renderer/locale/fr.json new file mode 100644 index 0000000000..40968cbcdf --- /dev/null +++ b/packages/client/ui-renderer/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Rendu d'interface", + "description": "Assemblez les composants d’interface fournis par chaque plug-in dans l’application." + } +} diff --git a/packages/client/ui-renderer/locale/pt.json b/packages/client/ui-renderer/locale/pt.json new file mode 100644 index 0000000000..b5d9f75753 --- /dev/null +++ b/packages/client/ui-renderer/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Renderização de interface", + "description": "Monte os componentes de interface fornecidos por cada plug-in no aplicativo." + } +} diff --git a/packages/client/ui-renderer/locale/ru.json b/packages/client/ui-renderer/locale/ru.json new file mode 100644 index 0000000000..09d2f66a5b --- /dev/null +++ b/packages/client/ui-renderer/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Рендеринг интерфейса", + "description": "Соберите в приложение компоненты интерфейса, предоставляемые каждым плагином." + } +} diff --git a/packages/client/ui-schedule/locale/de.json b/packages/client/ui-schedule/locale/de.json new file mode 100644 index 0000000000..d3a3f03e6b --- /dev/null +++ b/packages/client/ui-schedule/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Aufgabenschnittstelle", + "description": "Die Seite „Automatisierungsaufgaben“ in der Seitenleiste sowie Aufgabenkarten und Erinnerungsmarkierungen in Sitzungen." + } +} diff --git a/packages/client/ui-schedule/locale/es.json b/packages/client/ui-schedule/locale/es.json new file mode 100644 index 0000000000..360c54c06c --- /dev/null +++ b/packages/client/ui-schedule/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de tareas", + "description": "La página de tareas de automatización en la barra lateral, además de tarjetas de tareas y marcas de recordatorio en las sesiones." + } +} diff --git a/packages/client/ui-schedule/locale/fr.json b/packages/client/ui-schedule/locale/fr.json new file mode 100644 index 0000000000..98209dca10 --- /dev/null +++ b/packages/client/ui-schedule/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface des tâches", + "description": "La page Tâches d'automatisation dans la barre latérale, ainsi que les fiches de tâches et les marques de rappel dans les sessions." + } +} diff --git a/packages/client/ui-schedule/locale/pt.json b/packages/client/ui-schedule/locale/pt.json new file mode 100644 index 0000000000..05e228e1cb --- /dev/null +++ b/packages/client/ui-schedule/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de tarefas", + "description": "A página de tarefas de automação na barra lateral, além de cartões de tarefas e lembretes nas sessões." + } +} diff --git a/packages/client/ui-schedule/locale/ru.json b/packages/client/ui-schedule/locale/ru.json new file mode 100644 index 0000000000..6abb8e9b65 --- /dev/null +++ b/packages/client/ui-schedule/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Интерфейс задачи", + "description": "Страница задач автоматизации на боковой панели, а также карточки задач и отметки напоминаний в сеансах." + } +} diff --git a/packages/client/ui-schedule/src/client/frequency-locales.ts b/packages/client/ui-schedule/src/client/frequency-locales.ts index d09bd39d30..0c2ad0e963 100644 --- a/packages/client/ui-schedule/src/client/frequency-locales.ts +++ b/packages/client/ui-schedule/src/client/frequency-locales.ts @@ -183,3 +183,293 @@ export const frequencyJa = { 'relative.future': '{value}{unit}後', 'relative.overdue': '{value}{unit}超過', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const frequencyEs = { + 'time.locale': 'en', + 'time.utcPrefix': 'UTC', + 'frequency.daily': 'Diariamente en {time} ({timeZone})', + 'frequency.dailyLocal': 'Diariamente en {time}', + 'frequency.weekly': 'Semanalmente en {weekdays} en {time} ({timeZone})', + 'frequency.weeklyLocal': 'Semanalmente en {weekdays} en {time}', + 'frequency.cron': 'Cron {expression} ({timeZone})', + 'frequency.cronLocal': 'Cron {expression}', + 'frequency.cronRule': '{rule} ({timeZone})', + 'cron.list.join': ', ', + 'cron.part.join': ' ', + 'cron.weekday.name': '{weekday}', + 'cron.weekday.range': '{from}–{to}', + 'cron.months': ' en {months}', + 'cron.day.every': 'Todos los días{months}', + 'cron.day.weekdays': '{weekdays}{months}', + 'cron.day.monthDays': 'Día {days} de cada mes{months}', + 'cron.day.both': 'Día {days} de cada mes o {weekdays}{months}', + 'cron.day.bothStarred': 'Día {days} de cada mes y {weekdays}{months}', + 'cron.hours.range': '{from}–{to}', + 'cron.hours.list': '{hours}', + 'cron.time.everyMinute': 'cada minuto', + 'cron.time.everyMinutes': 'Cada minutos {step}', + 'cron.time.joinedEveryMinute': 'cada minuto', + 'cron.time.joinedEveryMinutes': 'cada {step} minutos', + 'cron.time.everyHour': 'cada hora', + 'cron.time.joinedEveryHour': 'cada hora', + 'cron.time.everyNHours': 'Cada horas {count}', + 'cron.time.joinedEveryNHours': 'cada horas {count}', + 'cron.time.hourlyAt': 'Cada hora al minuto {minutes}', + 'cron.time.joinedHourlyAt': 'cada hora al minuto {minutes}', + 'cron.time.hoursEveryMinute': 'cada minuto durante las horas {hours}', + 'cron.time.hoursEveryMinutes': 'cada {step} minutos durante las horas {hours}', + 'cron.time.at': 'en {times}', + 'cron.time.hoursAt': 'al minuto {minutes} de horas {hours}', + 'frequency.weekday.join': ', ', + 'frequency.weekday.1': 'lun', + 'frequency.weekday.2': 'mar', + 'frequency.weekday.3': 'mié', + 'frequency.weekday.4': 'jueves', + 'frequency.weekday.5': 'viernes', + 'frequency.weekday.6': 'sábado', + 'frequency.weekday.7': 'sol', + 'unit.day.one': 'dia', + 'unit.day.other': 'dias', + 'unit.hour.one': 'hora', + 'unit.hour.other': 'horas', + 'unit.minute.one': 'minuto', + 'unit.minute.other': 'minutos', + 'unit.second.one': 'segundo', + 'unit.second.other': 'segundos', + 'relative.now': 'Vencimiento ahora', + 'relative.future': 'en {value} {unit}', + 'relative.overdue': '{value} {unit} vencido', +} satisfies typeof frequencyEn + +/** French dictionary, checked against the English keys. */ +export const frequencyFr = { + 'time.locale': 'en', + 'time.utcPrefix': 'UTC', + 'frequency.daily': 'Tous les jours à {time} ({timeZone})', + 'frequency.dailyLocal': 'Tous les jours à {time}', + 'frequency.weekly': 'Hebdomadaire sur {weekdays} à {time} ({timeZone})', + 'frequency.weeklyLocal': 'Hebdomadaire sur {weekdays} à {time}', + 'frequency.cron': 'Cron {expression} ({timeZone})', + 'frequency.cronLocal': 'Cron {expression}', + 'frequency.cronRule': '{rule} ({timeZone})', + 'cron.list.join': ', ', + 'cron.part.join': ' ', + 'cron.weekday.name': '{weekday}', + 'cron.weekday.range': '{from}–{to}', + 'cron.months': ' dans {months}', + 'cron.day.every': 'Chaque jour{months}', + 'cron.day.weekdays': '{weekdays}{months}', + 'cron.day.monthDays': 'Jour {days} de chaque mois{months}', + 'cron.day.both': 'Jour {days} de chaque mois ou {weekdays}{months}', + 'cron.day.bothStarred': 'Jour {days} de chaque mois et {weekdays}{months}', + 'cron.hours.range': '{from}–{to}', + 'cron.hours.list': '{hours}', + 'cron.time.everyMinute': 'Chaque minute', + 'cron.time.everyMinutes': 'Toutes les minutes {step}', + 'cron.time.joinedEveryMinute': 'chaque minute', + 'cron.time.joinedEveryMinutes': 'toutes les minutes {step}', + 'cron.time.everyHour': 'Toutes les heures', + 'cron.time.joinedEveryHour': 'toutes les heures', + 'cron.time.everyNHours': 'Toutes les heures {count}', + 'cron.time.joinedEveryNHours': 'toutes les heures {count}', + 'cron.time.hourlyAt': 'Toutes les heures à la minute {minutes}', + 'cron.time.joinedHourlyAt': 'toutes les heures à la minute {minutes}', + 'cron.time.hoursEveryMinute': 'toutes les minutes pendant les heures {hours}', + 'cron.time.hoursEveryMinutes': 'toutes les minutes {step} pendant les heures {hours}', + 'cron.time.at': 'chez {times}', + 'cron.time.hoursAt': 'à la minute {minutes} des heures {hours}', + 'frequency.weekday.join': ', ', + 'frequency.weekday.1': 'lundi', + 'frequency.weekday.2': 'mar.', + 'frequency.weekday.3': 'mer', + 'frequency.weekday.4': 'jeu.', + 'frequency.weekday.5': 'vendredi', + 'frequency.weekday.6': 'Samedi', + 'frequency.weekday.7': 'Soleil', + 'unit.day.one': 'jour', + 'unit.day.other': 'jours', + 'unit.hour.one': 'heure', + 'unit.hour.other': 'heures', + 'unit.minute.one': 'minute', + 'unit.minute.other': 'minutes', + 'unit.second.one': 'seconde', + 'unit.second.other': 'secondes', + 'relative.now': 'À rendre maintenant', + 'relative.future': 'dans {value} {unit}', + 'relative.overdue': '{value} {unit} en retard', +} satisfies typeof frequencyEn + +/** German dictionary, checked against the English keys. */ +export const frequencyDe = { + 'time.locale': 'en', + 'time.utcPrefix': 'UTC', + 'frequency.daily': 'Täglich um {time} ({timeZone})', + 'frequency.dailyLocal': 'Täglich um {time}', + 'frequency.weekly': 'Wöchentlich auf {weekdays} um {time} ({timeZone})', + 'frequency.weeklyLocal': 'Wöchentlich auf {weekdays} und {time}', + 'frequency.cron': 'Cron {expression} ({timeZone})', + 'frequency.cronLocal': 'Cron {expression}', + 'frequency.cronRule': '{rule} ({timeZone})', + 'cron.list.join': ', ', + 'cron.part.join': ' ', + 'cron.weekday.name': '{weekday}', + 'cron.weekday.range': '{from}–{to}', + 'cron.months': ' in {months}', + 'cron.day.every': 'Jeden Tag{months}', + 'cron.day.weekdays': '{weekdays}{months}', + 'cron.day.monthDays': 'Tag {days} jedes Monats{months}', + 'cron.day.both': 'Tag {days} eines jeden Monats oder {weekdays}{months}', + 'cron.day.bothStarred': 'Tag {days} jedes Monats und {weekdays}{months}', + 'cron.hours.range': '{from}–{to}', + 'cron.hours.list': '{hours}', + 'cron.time.everyMinute': 'Jede Minute', + 'cron.time.everyMinutes': 'Alle {step} Minuten', + 'cron.time.joinedEveryMinute': 'jede Minute', + 'cron.time.joinedEveryMinutes': 'alle {step} Minuten', + 'cron.time.everyHour': 'Jede Stunde', + 'cron.time.joinedEveryHour': 'jede Stunde', + 'cron.time.everyNHours': 'Alle {count} Stunden', + 'cron.time.joinedEveryNHours': 'alle {count} Stunden', + 'cron.time.hourlyAt': 'Jede Stunde im Minutentakt {minutes}', + 'cron.time.joinedHourlyAt': 'jede Stunde im Minutentakt {minutes}', + 'cron.time.hoursEveryMinute': 'jede Minute während der Stunden {hours}', + 'cron.time.hoursEveryMinutes': 'alle {step} Minuten während der Stunden {hours}', + 'cron.time.at': 'bei {times}', + 'cron.time.hoursAt': 'zur Minute {minutes} der Stunden {hours}', + 'frequency.weekday.join': ', ', + 'frequency.weekday.1': 'Mo', + 'frequency.weekday.2': 'Di', + 'frequency.weekday.3': 'Mi', + 'frequency.weekday.4': 'Do', + 'frequency.weekday.5': 'Fr', + 'frequency.weekday.6': 'Sa', + 'frequency.weekday.7': 'Sonne', + 'unit.day.one': 'Tag', + 'unit.day.other': 'Tage', + 'unit.hour.one': 'Stunde', + 'unit.hour.other': 'Stunden', + 'unit.minute.one': 'Minute', + 'unit.minute.other': 'Minuten', + 'unit.second.one': 'zweitens', + 'unit.second.other': 'Sekunden', + 'relative.now': 'Jetzt fällig', + 'relative.future': 'in {value} {unit}', + 'relative.overdue': '{value} {unit} überfällig', +} satisfies typeof frequencyEn + +/** Russian dictionary, checked against the English keys. */ +export const frequencyRu = { + 'time.locale': 'en', + 'time.utcPrefix': 'UTC', + 'frequency.daily': 'Ежедневно по адресу {time} ({timeZone})', + 'frequency.dailyLocal': 'Ежедневно в {time}', + 'frequency.weekly': 'Еженедельно на {weekdays} по адресу {time} ({timeZone})', + 'frequency.weeklyLocal': 'Еженедельно на {weekdays} по адресу {time}', + 'frequency.cron': 'Крон {expression} ({timeZone})', + 'frequency.cronLocal': 'Крон {expression}', + 'frequency.cronRule': '{rule} ({timeZone})', + 'cron.list.join': ', ', + 'cron.part.join': ' ', + 'cron.weekday.name': '{weekday}', + 'cron.weekday.range': '{from} – {to}', + 'cron.months': ' в {months}', + 'cron.day.every': 'Каждый день{months}', + 'cron.day.weekdays': '{weekdays}{months}', + 'cron.day.monthDays': 'День {days} каждого месяца{months}', + 'cron.day.both': 'День {days} каждого месяца или {weekdays}{months}.', + 'cron.day.bothStarred': 'День {days} каждого месяца и {weekdays}{months}.', + 'cron.hours.range': '{from} – {to}', + 'cron.hours.list': '{hours}', + 'cron.time.everyMinute': 'Каждую минуту', + 'cron.time.everyMinutes': 'Каждые {step} минут', + 'cron.time.joinedEveryMinute': 'каждую минуту', + 'cron.time.joinedEveryMinutes': 'каждые {step} минут', + 'cron.time.everyHour': 'Каждый час', + 'cron.time.joinedEveryHour': 'каждый час', + 'cron.time.everyNHours': 'Каждые {count} часов', + 'cron.time.joinedEveryNHours': 'каждые {count} часов', + 'cron.time.hourlyAt': 'Каждый час в минуту {minutes}', + 'cron.time.joinedHourlyAt': 'каждый час в минуту {minutes}', + 'cron.time.hoursEveryMinute': 'каждую минуту в течение часов {hours}', + 'cron.time.hoursEveryMinutes': 'каждые {step} минуты в течение часов {hours}', + 'cron.time.at': 'в {times}', + 'cron.time.hoursAt': 'в минуту {minutes} часов {hours}', + 'frequency.weekday.join': ', ', + 'frequency.weekday.1': 'Пн.', + 'frequency.weekday.2': 'Вт', + 'frequency.weekday.3': 'ср.', + 'frequency.weekday.4': 'Чт', + 'frequency.weekday.5': 'Пт', + 'frequency.weekday.6': 'Суббота', + 'frequency.weekday.7': 'Солнце', + 'unit.day.one': 'день', + 'unit.day.other': 'дни', + 'unit.hour.one': 'час', + 'unit.hour.other': 'часы', + 'unit.minute.one': 'минута', + 'unit.minute.other': 'минуты', + 'unit.second.one': 'второй', + 'unit.second.other': 'секунды', + 'relative.now': 'Срок оплаты сейчас', + 'relative.future': 'в {value} {unit}', + 'relative.overdue': '{value} {unit} просрочен', +} satisfies typeof frequencyEn + +/** Portuguese dictionary, checked against the English keys. */ +export const frequencyPt = { + 'time.locale': 'en', + 'time.utcPrefix': 'UTC', + 'frequency.daily': 'Diariamente às {time} ({timeZone})', + 'frequency.dailyLocal': 'Diariamente às {time}', + 'frequency.weekly': 'Semanalmente em {weekdays} às {time} ({timeZone})', + 'frequency.weeklyLocal': 'Semanalmente em {weekdays} às {time}', + 'frequency.cron': 'Cron {expression} ({timeZone})', + 'frequency.cronLocal': 'Cron {expression}', + 'frequency.cronRule': '{rule} ({timeZone})', + 'cron.list.join': ', ', + 'cron.part.join': ' ', + 'cron.weekday.name': '{weekday}', + 'cron.weekday.range': '{from}–{to}', + 'cron.months': ' em {months}', + 'cron.day.every': 'Todos os dias{months}', + 'cron.day.weekdays': '{weekdays}{months}', + 'cron.day.monthDays': 'Dia {days} de cada mês{months}', + 'cron.day.both': 'Dia {days} de cada mês ou {weekdays}{months}', + 'cron.day.bothStarred': 'Dia {days} de cada mês e {weekdays}{months}', + 'cron.hours.range': '{from}–{to}', + 'cron.hours.list': '{hours}', + 'cron.time.everyMinute': 'Cada minuto', + 'cron.time.everyMinutes': 'A cada {step} minutos', + 'cron.time.joinedEveryMinute': 'cada minuto', + 'cron.time.joinedEveryMinutes': 'a cada {step} minutos', + 'cron.time.everyHour': 'A cada hora', + 'cron.time.joinedEveryHour': 'a cada hora', + 'cron.time.everyNHours': 'A cada {count} horas', + 'cron.time.joinedEveryNHours': 'a cada {count} horas', + 'cron.time.hourlyAt': 'A cada hora, minuto {minutes}', + 'cron.time.joinedHourlyAt': 'a cada hora por minuto {minutes}', + 'cron.time.hoursEveryMinute': 'a cada minuto durante horas {hours}', + 'cron.time.hoursEveryMinutes': 'a cada {step} minutos durante horas {hours}', + 'cron.time.at': 'em {times}', + 'cron.time.hoursAt': 'no minuto {minutes} das horas {hours}', + 'frequency.weekday.join': ', ', + 'frequency.weekday.1': 'segunda-feira', + 'frequency.weekday.2': 'Terça', + 'frequency.weekday.3': 'Quarta', + 'frequency.weekday.4': 'Qui', + 'frequency.weekday.5': 'Sexta-feira', + 'frequency.weekday.6': 'Sábado', + 'frequency.weekday.7': 'Sol', + 'unit.day.one': 'dia', + 'unit.day.other': 'dias', + 'unit.hour.one': 'hora', + 'unit.hour.other': 'horas', + 'unit.minute.one': 'minuto', + 'unit.minute.other': 'minutos', + 'unit.second.one': 'segundo', + 'unit.second.other': 'segundos', + 'relative.now': 'Vencimento agora', + 'relative.future': 'em {value} {unit}', + 'relative.overdue': '{value} {unit} atrasado', +} satisfies typeof frequencyEn diff --git a/packages/client/ui-schedule/src/client/index.ts b/packages/client/ui-schedule/src/client/index.ts index 8c6dcb3c5f..a83f1fbf42 100644 --- a/packages/client/ui-schedule/src/client/index.ts +++ b/packages/client/ui-schedule/src/client/index.ts @@ -59,8 +59,8 @@ import { TaskManagerPage, type TaskManagerInjected } from './TaskManagerPage.tsx import type { TaskDetailInjected } from './TaskDetail.tsx' import { TaskManagerIcon } from './TaskManagerIcon.tsx' import { sessionLinkState } from './session-link.ts' -import { en, ja, NS, zh, type ScheduleCatalogKey } from './locales.ts' -import { en as managerEn, ja as managerJa, zh as managerZh, type TaskManagerKey } from './task-manager-locales.ts' +import { en, ja, es, fr, de, ru, pt, NS, zh, type ScheduleCatalogKey } from './locales.ts' +import { en as managerEn, ja as managerJa, es as managerEs, fr as managerFr, de as managerDe, ru as managerRu, pt as managerPt, zh as managerZh, type TaskManagerKey } from './task-manager-locales.ts' const MANAGER_NS = 'schedule.manager' const PANEL_ID = 'schedules' as MainPanelId @@ -87,8 +87,17 @@ export const inject = [ * @param ctx - browser services used by these contributions. */ export function apply(ctx: ClientContext): void { - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-schedule: dictionaries') - const managerDictionaries = { zh: managerZh, en: managerEn, ja: managerJa } + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-schedule: dictionaries') + const managerDictionaries = { + zh: managerZh, + en: managerEn, + ja: managerJa, + es: managerEs, + fr: managerFr, + de: managerDe, + ru: managerRu, + pt: managerPt, + } ctx.effect(() => ctx.locale.register(MANAGER_NS, managerDictionaries), 'ui-schedule: manager dictionaries') const t = ctx.locale.bind(MANAGER_NS) ctx.effect(() => ctx.sidebarRightTabs.register(scheduleTaskDefinition(t)), 'ui-schedule: task tab type') diff --git a/packages/client/ui-schedule/src/client/locales.ts b/packages/client/ui-schedule/src/client/locales.ts index ff04c31ce4..1ded1fa0c6 100644 --- a/packages/client/ui-schedule/src/client/locales.ts +++ b/packages/client/ui-schedule/src/client/locales.ts @@ -2,7 +2,7 @@ * `schedule.catalog` namespace dictionaries: the Session header catalog and the * Sidebar row mark with its hover-card task section. */ -import { frequencyEn, frequencyJa, frequencyZh } from './frequency-locales.ts' +import { frequencyEn, frequencyJa, frequencyEs, frequencyFr, frequencyDe, frequencyRu, frequencyPt, frequencyZh } from './frequency-locales.ts' /** Dictionary namespace owned by this plugin. */ export const NS = 'schedule.catalog' @@ -72,3 +72,108 @@ export const ja = { 'mark.aria': 'スケジュールされたタスク {count}件', 'hover.more': '他 {count}件', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'trigger.label': 'Recordatorios', + 'list.loading': 'Cargando recordatorios…', + 'list.error': 'No se pudieron cargar los recordatorios.', + 'list.retry': 'Reintentar', + 'delete.action': 'Eliminar', + 'delete.pending': 'Eliminando…', + 'delete.label': 'Eliminar recordatorio: {title}', + 'list.open': 'Abrir detalles del recordatorio: {title}', + 'trigger.one': 'Recordatorio de {count}', + 'trigger.other': 'Recordatorios de {count}', + 'list.aria': 'Recordatorios activos', + 'list.nextRun': 'Próxima ejecución', + 'frequency.once': 'una vez', + 'frequency.every': 'Cada {value} {unit}', + ...frequencyEs, + 'mark.aria': 'Tareas programadas {count}', + 'hover.more': '{count} más', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'trigger.label': 'Rappels', + 'list.loading': 'Chargement des rappels…', + 'list.error': 'Impossible de charger les rappels.', + 'list.retry': 'Réessayer', + 'delete.action': 'Supprimer', + 'delete.pending': 'Suppression…', + 'delete.label': 'Supprimer le rappel : {title}', + 'list.open': 'Détails du rappel ouvert : {title}', + 'trigger.one': 'Rappel {count}', + 'trigger.other': 'Rappels {count}', + 'list.aria': 'Rappels actifs', + 'list.nextRun': 'Prochaine exécution', + 'frequency.once': 'Une fois', + 'frequency.every': 'Chaque {value} {unit}', + ...frequencyFr, + 'mark.aria': 'Tâches planifiées {count}', + 'hover.more': '{count} plus', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'trigger.label': 'Erinnerungen', + 'list.loading': 'Erinnerungen werden geladen…', + 'list.error': 'Erinnerungen konnten nicht geladen werden.', + 'list.retry': 'Erneut versuchen', + 'delete.action': 'Löschen', + 'delete.pending': 'Löschen…', + 'delete.label': 'Erinnerung löschen: {title}', + 'list.open': 'Offene Erinnerungsdetails: {title}', + 'trigger.one': '{count} Erinnerung', + 'trigger.other': '{count} Erinnerungen', + 'list.aria': 'Aktive Erinnerungen', + 'list.nextRun': 'Nächster Lauf', + 'frequency.once': 'Einmal', + 'frequency.every': 'Jeder {value} {unit}', + ...frequencyDe, + 'mark.aria': '{count} geplante Aufgaben', + 'hover.more': '{count} mehr', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'trigger.label': 'Напоминания', + 'list.loading': 'Загрузка напоминаний…', + 'list.error': 'Не удалось загрузить напоминания.', + 'list.retry': 'Повторить', + 'delete.action': 'Удалить', + 'delete.pending': 'Удаление…', + 'delete.label': 'Удалить напоминание: {title}', + 'list.open': 'Открыть детали напоминания: {title}.', + 'trigger.one': '{count} напоминание', + 'trigger.other': '{count} напоминания', + 'list.aria': 'Активные напоминания', + 'list.nextRun': 'Следующий запуск', + 'frequency.once': 'Однажды', + 'frequency.every': 'Каждый {value} {unit}', + ...frequencyRu, + 'mark.aria': '{count} запланированные задачи', + 'hover.more': '{count} подробнее', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'trigger.label': 'Lembretes', + 'list.loading': 'Carregando lembretes…', + 'list.error': 'Não foi possível carregar os lembretes.', + 'list.retry': 'Tentar novamente', + 'delete.action': 'Excluir', + 'delete.pending': 'Excluindo…', + 'delete.label': 'Excluir lembrete: {title}', + 'list.open': 'Detalhes do lembrete aberto: {title}', + 'trigger.one': '{count} lembrete', + 'trigger.other': '{count} lembretes', + 'list.aria': 'Lembretes ativos', + 'list.nextRun': 'Próxima execução', + 'frequency.once': 'Uma vez', + 'frequency.every': 'A cada {value} {unit}', + ...frequencyPt, + 'mark.aria': '{count} tarefas agendadas', + 'hover.more': '{count} mais', +} satisfies Record diff --git a/packages/client/ui-schedule/src/client/task-manager-locales.ts b/packages/client/ui-schedule/src/client/task-manager-locales.ts index 7917d8dbb5..2cd2aa0080 100644 --- a/packages/client/ui-schedule/src/client/task-manager-locales.ts +++ b/packages/client/ui-schedule/src/client/task-manager-locales.ts @@ -1,5 +1,5 @@ /** Copy for the retained-reminder task manager's `schedule.manager` namespace. */ -import { frequencyEn, frequencyJa, frequencyZh } from './frequency-locales.ts' +import { frequencyEn, frequencyJa, frequencyEs, frequencyFr, frequencyDe, frequencyRu, frequencyPt, frequencyZh } from './frequency-locales.ts' /** English task-manager dictionary and key domain. */ export const en = { @@ -422,3 +422,708 @@ export const ja = { 'card.deleted': '削除済み', 'tool.invoked': '{name} を実行しました', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'panel': 'Tareas de automatización', + 'title': 'Tareas de automatización', + 'new.action': 'Nuevo', + 'list.label': 'Catálogo de tareas', + 'list.nextPrefix': 'Próxima hora prevista: ', + 'list.loading': 'Cargando tareas…', + 'list.error': 'No se pudieron cargar las tareas.', + 'list.retry': 'Reintentar', + 'list.empty': 'Aún no hay tareas. Las tareas creadas en tus sesiones aparecen aquí.', + 'list.emptyInactive': 'Sin tareas de automatización inactivas', + 'list.noMatches': 'No hay tareas coincidentes', + 'search.label': 'Tareas de búsqueda', + 'search.placeholder': 'Tareas de automatización de búsqueda', + 'search.clear': 'Borrar búsqueda', + 'empty.action': 'Nueva tarea de automatización', + 'statusFilter.label': 'Estado de la tarea', + 'statusFilter.all': 'Todos', + 'status.active': 'Habilitado', + 'status.inactive': 'Inactivo', + 'detail.label': 'Detalles de la tarea', + 'detail.close': 'Cerrar detalles', + 'detail.more': 'Acciones de tareas de automatización', + 'detail.nextRun': 'Próxima ejecución', + 'detail.tabs': 'Vistas de detalles de tareas', + 'detail.rule': 'Reglas', + 'detail.records': 'Registros', + 'delivery.empty': 'No hay registro de entrega disponible', + 'delivery.loading': 'Cargando registros de entrega…', + 'delivery.error': 'No se pudieron cargar los registros de entrega.', + 'delivery.notFound': 'Esta tarea ya no está disponible.', + 'delivery.cursorError': 'Se actualizaron los registros.', + 'delivery.retry': 'Reintentar', + 'delivery.refresh': 'Actualizar', + 'delivery.loadMore': 'Cargar más', + 'delivery.expand': 'Expandir', + 'delivery.collapse': 'Contraer', + 'delivery.pruned': 'Se han borrado los registros de entrega anteriores.', + 'delivery.retention': 'Reglas de retención', + 'delivery.retentionBounds': 'Cada tarea mantiene registros de entrega hasta {records} de los últimos días {days}.', + 'delivery.retentionExplanation': 'Cuando se guarda un nuevo registro, los registros más antiguos que estén fuera de estos límites se borran automáticamente. Borrar registros no detiene la tarea.', + 'detail.name': 'Nombre de la tarea de automatización', + 'detail.instruction': 'Instrucción de tarea de automatización', + 'detail.status': 'Estado', + 'detail.next': 'Próxima hora programada', + 'detail.frequency': 'Frecuencia', + 'detail.id': 'ID de tarea', + 'detail.session': 'Sesión vinculada', + 'detail.openSession': 'Sesión vinculada: abrir sesión original', + 'detail.openSessionTitle': 'Sesión vinculada {title}: abrir sesión original', + 'detail.sessionLoading': 'Cargando información de la sesión original.', + 'detail.sessionArchived': 'La sesión original está archivada.', + 'detail.sessionUnavailable': 'La sesión original no está disponible.', + 'detail.missing': 'Tarea no disponible. Es posible que haya sido eliminado.', + 'delivery.label': 'Registro de entrega guardado', + 'frequency.once': 'una vez', + 'frequency.every': 'Cada {value} {unit}', + ...frequencyEs, + 'timing.date': 'Fecha', + 'timing.time': 'tiempo', + 'timing.hour': 'Hora', + 'timing.minute': 'Minuto', + 'timing.second': 'segundo', + 'timing.prevMonth': 'Mes anterior', + 'timing.nextMonth': 'El próximo mes', + 'timing.zone': 'Zona horaria', + 'timing.zoneSearch': 'Buscar por desplazamiento UTC, ID de IANA o ciudad', + 'timing.zoneNoResults': 'No hay zonas horarias coincidentes', + 'timing.interval': 'Repetir cada', + 'timing.intervalIncrease': 'aumentar el intervalo', + 'timing.intervalDecrease': 'Intervalo de disminución', + 'timing.unit.hour': 'horas', + 'timing.unit.minute': 'minutos', + 'timing.unit.second': 'segundos', + 'timing.intervalHint.hour': 'Al menos 1 hora. El intervalo cuenta desde la creación de la tarea o el último cambio de regla y es independiente de las zonas horarias.', + 'timing.intervalHint.minute': 'Al menos 1 minuto. El intervalo cuenta desde la creación de la tarea o el último cambio de regla y es independiente de las zonas horarias.', + 'timing.intervalHint.second': 'Al menos 60 segundos. El intervalo cuenta desde la creación de la tarea o el último cambio de regla y es independiente de las zonas horarias.', + 'timing.zoneNoStored': 'Una tarea única almacena sólo su momento objetivo, no una zona horaria. La fecha y la hora se interpretan en la zona horaria seleccionada.', + 'timing.inactive': 'Las tareas inactivas son de solo lectura. Su sincronización no se puede editar.', + 'timing.conflict': 'Esta tarea cambió mientras estabas editando. Su borrador se conserva. ' + + 'Cancele y vuelva a abrir después de actualizar para editar la regla más reciente.', + 'timing.notFound': 'Esta tarea ya no está disponible. Su borrador se conserva; cancelar para cerrar el editor.', + 'timing.subagentSession': 'Esta sesión pertenece a un subagente, que nunca recibe recordatorios entregados.', + 'timing.invalid': 'Ingrese una fecha y hora válidas, o verifique los campos de tiempo.', + 'timing.invalidZone': 'Ingrese una zona horaria IANA válida, por ejemplo Asia/Shanghai.', + 'timing.notFuture': 'Elija una fecha y hora en el futuro.', + 'timing.invalidInterval': 'Introduzca un intervalo de al menos 1 minuto.', + 'timing.invalidInterval.hour': 'Introduzca un intervalo de al menos 1 hora.', + 'timing.invalidInterval.minute': 'Introduzca un intervalo de al menos 1 minuto.', + 'timing.invalidInterval.second': 'Introduzca un intervalo de al menos 60 segundos.', + 'timing.error': 'No se pudo confirmar la actualización del tiempo. Su borrador se conserva. Verifique la tarea antes de volver a intentarlo.', + 'rule.title': 'tiempo de ejecución', + 'rule.repeat': 'repetir', + 'rule.weekday': 'Día laborable', + 'rule.weekdayOption': 'Día laborable {weekday}', + 'rule.unsaved': 'Cambios no guardados', + 'rule.save': 'Guardar cambios', + 'rule.saving': 'Guardando…', + 'rule.cancel': 'Cancelar', + 'rule.invalidTitle': 'Introduzca un nombre de tarea de como máximo 120 caracteres.', + 'rule.invalidPrompt': 'Introduzca una instrucción de tarea.', + 'rule.once': 'una vez', + 'rule.everyMinutes': 'Cada N minutos', + 'rule.everyHours': 'Cada N horas', + 'rule.everySeconds': 'Cada N segundos', + 'rule.daily': 'todos los dias', + 'rule.weekdays': 'lunes a viernes', + 'rule.weekly': 'Semanal', + 'rule.cron': 'personalizado', + 'rule.cronLabel': 'expresión cron', + 'rule.cronInvalid': 'Ingrese una expresión cron de cinco campos, por ejemplo 0 9 * * 1-5.', + 'cronForm.frequency': 'Frecuencia', + 'cronForm.monthly': 'Mensual', + 'cronForm.weekly': 'Semanal', + 'cronForm.daily': 'todos los dias', + 'cronForm.dates': 'en fechas', + 'cronForm.dateOption': 'Día {day}', + 'cronForm.atMinute': 'al minuto', + 'cronForm.minuteIncrease': 'aumentar minuto', + 'cronForm.minuteDecrease': 'Disminuir minuto', + 'rule.zone.system': ' (sistema)', + 'rule.error.conflict': 'Esta tarea cambió antes de que se guardara la actualización. La fila muestra la regla guardada; intentar otra vez.', + 'rule.error.notFound': 'Esta tarea ya no está disponible.', + 'rule.error.unknown': 'No se pudo confirmar la actualización de la regla. La fila muestra la regla guardada.', + 'delete.action': 'Eliminar tarea', + 'delete.title': '¿Eliminar esta tarea?', + 'delete.description': 'Esto evita que la tarea se active y la elimina junto con sus registros de entrega guardados. ' + + 'La sesión original y sus mensajes permanecen; los mensajes en cola no se retiran.', + 'delete.confirm': 'Confirmar eliminación', + 'delete.cancel': 'Cancelar', + 'delete.close': 'Cerrar confirmación de eliminación', + 'delete.pending': 'Eliminando…', + 'toast.deleted': 'Tarea eliminada.', + 'toast.deleteFailed': 'No se pudo eliminar la tarea.', + 'card.open': 'Abrir', + 'card.openLabel': 'Abrir detalles de la tarea: {title}', + 'card.deleted': 'Eliminado', + 'tool.invoked': 'Invocado {name}', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'panel': "Tâches d'automatisation", + 'title': "Tâches d'automatisation", + 'new.action': 'Nouveau', + 'list.label': 'Catalogue de tâches', + 'list.nextPrefix': 'Prochaine heure programmée : ', + 'list.loading': 'Chargement des tâches…', + 'list.error': 'Impossible de charger les tâches.', + 'list.retry': 'Réessayer', + 'list.empty': "Aucune tâche pour l'instant. Les tâches créées dans vos sessions apparaissent ici.", + 'list.emptyInactive': "Aucune tâche d'automatisation inactive", + 'list.noMatches': 'Aucune tâche correspondante', + 'search.label': 'Tâches de recherche', + 'search.placeholder': "Tâches d'automatisation de la recherche", + 'search.clear': 'Effacer la recherche', + 'empty.action': "Nouvelle tâche d'automatisation", + 'statusFilter.label': 'Statut de la tâche', + 'statusFilter.all': 'Tout', + 'status.active': 'Activé', + 'status.inactive': 'Inactif', + 'detail.label': 'Détails de la tâche', + 'detail.close': 'Fermer les détails', + 'detail.more': "Actions des tâches d'automatisation", + 'detail.nextRun': 'Prochaine exécution', + 'detail.tabs': 'Vues détaillées des tâches', + 'detail.rule': 'Règles', + 'detail.records': 'Enregistrements', + 'delivery.empty': 'Aucun historique de livraison disponible', + 'delivery.loading': 'Chargement des enregistrements de livraison…', + 'delivery.error': 'Impossible de charger les enregistrements de livraison.', + 'delivery.notFound': "Cette tâche n'est plus disponible.", + 'delivery.cursorError': 'Les dossiers ont été mis à jour.', + 'delivery.retry': 'Réessayer', + 'delivery.refresh': 'Actualiser', + 'delivery.loadMore': 'Charger plus', + 'delivery.expand': 'Développer', + 'delivery.collapse': 'Réduire', + 'delivery.pruned': 'Les enregistrements de livraison antérieurs ont été effacés', + 'delivery.retention': 'Règles de conservation', + 'delivery.retentionBounds': "Chaque tâche conserve jusqu'à {records} enregistrements de livraison des derniers jours {days}.", + 'delivery.retentionExplanation': "Lorsqu'un nouvel enregistrement est enregistré, les enregistrements plus anciens en dehors de ces limites sont automatiquement effacés. La suppression des enregistrements n'arrête pas la tâche.", + 'detail.name': "Nom de la tâche d'automatisation", + 'detail.instruction': "Instruction de tâche d'automatisation", + 'detail.status': 'Statut', + 'detail.next': 'Prochaine heure programmée', + 'detail.frequency': 'Fréquence', + 'detail.id': 'ID de tâche', + 'detail.session': 'Séance liée', + 'detail.openSession': 'Session liée : ouvrir la session originale', + 'detail.openSessionTitle': 'Session liée {title} : ouvrir la session originale', + 'detail.sessionLoading': 'Chargement des informations de session originales.', + 'detail.sessionArchived': 'La session originale est archivée.', + 'detail.sessionUnavailable': "La session originale n'est pas disponible.", + 'detail.missing': 'Tâche indisponible. Il a peut-être été supprimé.', + 'delivery.label': 'Dossier de livraison enregistré', + 'frequency.once': 'Une fois', + 'frequency.every': 'Chaque {value} {unit}', + ...frequencyFr, + 'timing.date': 'Date', + 'timing.time': 'Temps', + 'timing.hour': 'Heure', + 'timing.minute': 'Minutes', + 'timing.second': 'Deuxième', + 'timing.prevMonth': 'Mois précédent', + 'timing.nextMonth': 'Le mois prochain', + 'timing.zone': 'Fuseau horaire', + 'timing.zoneSearch': 'Recherche par décalage UTC, ID IANA ou ville', + 'timing.zoneNoResults': 'Aucun fuseau horaire correspondant', + 'timing.interval': 'Répétez tous les', + 'timing.intervalIncrease': "Augmenter l'intervalle", + 'timing.intervalDecrease': "Diminuer l'intervalle", + 'timing.unit.hour': 'heures', + 'timing.unit.minute': 'minutes', + 'timing.unit.second': 'secondes', + 'timing.intervalHint.hour': "Au moins 1 heure. L'intervalle compte à partir de la création de la tâche ou du dernier changement de règle et est indépendant des fuseaux horaires.", + 'timing.intervalHint.minute': "Au moins 1 minute. L'intervalle compte à partir de la création de la tâche ou du dernier changement de règle et est indépendant des fuseaux horaires.", + 'timing.intervalHint.second': "Au moins 60 secondes. L'intervalle compte à partir de la création de la tâche ou du dernier changement de règle et est indépendant des fuseaux horaires.", + 'timing.zoneNoStored': "Une tâche ponctuelle stocke uniquement son moment cible, pas un fuseau horaire. La date et l'heure sont interprétées dans le fuseau horaire sélectionné.", + 'timing.inactive': 'Les tâches inactives sont en lecture seule. Leur timing ne peut pas être modifié.', + 'timing.conflict': 'Cette tâche a changé pendant que vous effectuiez la modification. Votre brouillon est conservé. ' + + "Annulez et rouvrez après l'actualisation pour modifier la dernière règle.", + 'timing.notFound': "Cette tâche n'est plus disponible. Votre brouillon est conservé ; annuler pour fermer l'éditeur.", + 'timing.subagentSession': 'Cette session appartient à un sous-agent, qui ne reçoit jamais de rappels délivrés.', + 'timing.invalid': 'Entrez une date et une heure valides ou vérifiez les champs de synchronisation.', + 'timing.invalidZone': 'Saisissez un fuseau horaire IANA valide, par exemple Asie/Shanghai.', + 'timing.notFuture': 'Choisissez une date et une heure dans le futur.', + 'timing.invalidInterval': "Entrez un intervalle d'au moins 1 minute.", + 'timing.invalidInterval.hour': "Entrez un intervalle d'au moins 1 heure.", + 'timing.invalidInterval.minute': "Entrez un intervalle d'au moins 1 minute.", + 'timing.invalidInterval.second': "Entrez un intervalle d'au moins 60 secondes.", + 'timing.error': 'Impossible de confirmer la mise à jour du timing. Votre brouillon est conservé. Vérifiez la tâche avant de réessayer.', + 'rule.title': "Temps d'exécution", + 'rule.repeat': 'Répéter', + 'rule.weekday': 'Jour de la semaine', + 'rule.weekdayOption': 'Jour de la semaine {weekday}', + 'rule.unsaved': 'Modifications non enregistrées', + 'rule.save': 'Enregistrer les modifications', + 'rule.saving': 'Sauvegarde…', + 'rule.cancel': 'Annuler', + 'rule.invalidTitle': 'Saisissez un nom de tâche comportant au maximum 120 caractères.', + 'rule.invalidPrompt': 'Entrez une instruction de tâche.', + 'rule.once': 'Une fois', + 'rule.everyMinutes': 'Toutes les N minutes', + 'rule.everyHours': 'Toutes les N heures', + 'rule.everySeconds': 'Toutes les N secondes', + 'rule.daily': 'Chaque jour', + 'rule.weekdays': 'Du lundi au vendredi', + 'rule.weekly': 'Hebdomadaire', + 'rule.cron': 'Personnalisé', + 'rule.cronLabel': 'Expression Cron', + 'rule.cronInvalid': 'Entrez une expression cron à cinq champs, par exemple 0 9 * * 1-5.', + 'cronForm.frequency': 'Fréquence', + 'cronForm.monthly': 'Mensuel', + 'cronForm.weekly': 'Hebdomadaire', + 'cronForm.daily': 'Chaque jour', + 'cronForm.dates': 'Aux dates', + 'cronForm.dateOption': 'Jour {day}', + 'cronForm.atMinute': 'À la minute', + 'cronForm.minuteIncrease': 'Augmenter les minutes', + 'cronForm.minuteDecrease': 'Diminuer les minutes', + 'rule.zone.system': ' (système)', + 'rule.error.conflict': "Cette tâche a changé avant l'enregistrement de la mise à jour. La ligne affiche la règle enregistrée ; essayer à nouveau.", + 'rule.error.notFound': "Cette tâche n'est plus disponible.", + 'rule.error.unknown': 'Impossible de confirmer la mise à jour de la règle. La ligne affiche la règle enregistrée.', + 'delete.action': 'Supprimer la tâche', + 'delete.title': 'Supprimer cette tâche ?', + 'delete.description': 'Cela empêche le déclenchement de la tâche et la supprime ainsi que ses enregistrements de livraison enregistrés. ' + + "La session d'origine et ses messages restent conservés ; les messages en file d'attente ne sont pas retirés.", + 'delete.confirm': 'Confirmer la suppression', + 'delete.cancel': 'Annuler', + 'delete.close': 'Fermer la confirmation de suppression', + 'delete.pending': 'Suppression…', + 'toast.deleted': 'Tâche supprimée.', + 'toast.deleteFailed': 'Impossible de supprimer la tâche.', + 'card.open': 'Ouvrir', + 'card.openLabel': 'Détails de la tâche ouverte : {title}', + 'card.deleted': 'Supprimé', + 'tool.invoked': '{name} invoqué', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'panel': 'Automatisierungsaufgaben', + 'title': 'Automatisierungsaufgaben', + 'new.action': 'Neu', + 'list.label': 'Aufgabenkatalog', + 'list.nextPrefix': 'Nächste geplante Zeit: ', + 'list.loading': 'Aufgaben werden geladen…', + 'list.error': 'Aufgaben konnten nicht geladen werden.', + 'list.retry': 'Erneut versuchen', + 'list.empty': 'Noch keine Aufgaben. Hier werden die in Ihren Sitzungen erstellten Aufgaben angezeigt.', + 'list.emptyInactive': 'Keine inaktiven Automatisierungsaufgaben', + 'list.noMatches': 'Keine passenden Aufgaben', + 'search.label': 'Suchaufgaben', + 'search.placeholder': 'Suchautomatisierungsaufgaben', + 'search.clear': 'Suche löschen', + 'empty.action': 'Neue Automatisierungsaufgabe', + 'statusFilter.label': 'Aufgabenstatus', + 'statusFilter.all': 'Alle', + 'status.active': 'Aktiviert', + 'status.inactive': 'Inaktiv', + 'detail.label': 'Aufgabendetails', + 'detail.close': 'Details schließen', + 'detail.more': 'Aktionen der Automatisierungsaufgabe', + 'detail.nextRun': 'Nächster Lauf', + 'detail.tabs': 'Aufgabendetailansichten', + 'detail.rule': 'Regeln', + 'detail.records': 'Aufzeichnungen', + 'delivery.empty': 'Kein Lieferprotokoll verfügbar', + 'delivery.loading': 'Lieferdatensätze werden geladen…', + 'delivery.error': 'Lieferdatensätze konnten nicht geladen werden.', + 'delivery.notFound': 'Diese Aufgabe ist nicht mehr verfügbar.', + 'delivery.cursorError': 'Die Datensätze wurden aktualisiert.', + 'delivery.retry': 'Erneut versuchen', + 'delivery.refresh': 'Aktualisieren', + 'delivery.loadMore': 'Mehr laden', + 'delivery.expand': 'Ausklappen', + 'delivery.collapse': 'Einklappen', + 'delivery.pruned': 'Frühere Lieferaufzeichnungen wurden gelöscht', + 'delivery.retention': 'Aufbewahrungsregeln', + 'delivery.retentionBounds': 'Jede Aufgabe verwaltet bis zu {records}-Lieferaufzeichnungen der letzten {days}-Tage.', + 'delivery.retentionExplanation': 'Wenn ein neuer Datensatz gespeichert wird, werden ältere Datensätze außerhalb dieser Grenzen automatisch gelöscht. Durch das Löschen von Datensätzen wird die Aufgabe nicht gestoppt.', + 'detail.name': 'Name der Automatisierungsaufgabe', + 'detail.instruction': 'Anleitung zur Automatisierungsaufgabe', + 'detail.status': 'Status', + 'detail.next': 'Nächste geplante Zeit', + 'detail.frequency': 'Häufigkeit', + 'detail.id': 'Aufgaben-ID', + 'detail.session': 'Verknüpfte Sitzung', + 'detail.openSession': 'Verknüpfte Sitzung: Originalsitzung öffnen', + 'detail.openSessionTitle': 'Verknüpfte Sitzung {title}: Originalsitzung öffnen', + 'detail.sessionLoading': 'Laden der ursprünglichen Sitzungsinformationen.', + 'detail.sessionArchived': 'Die ursprüngliche Sitzung wird archiviert.', + 'detail.sessionUnavailable': 'Die ursprüngliche Sitzung ist nicht verfügbar.', + 'detail.missing': 'Aufgabe nicht verfügbar. Möglicherweise wurde es gelöscht.', + 'delivery.label': 'Lieferdatensatz gespeichert', + 'frequency.once': 'Einmal', + 'frequency.every': 'Jeder {value} {unit}', + ...frequencyDe, + 'timing.date': 'Datum', + 'timing.time': 'Zeit', + 'timing.hour': 'Stunde', + 'timing.minute': 'Minute', + 'timing.second': 'Zweitens', + 'timing.prevMonth': 'Vorheriger Monat', + 'timing.nextMonth': 'Nächsten Monat', + 'timing.zone': 'Zeitzone', + 'timing.zoneSearch': 'Suche nach UTC-Offset, IANA-ID oder Stadt', + 'timing.zoneNoResults': 'Keine passenden Zeitzonen', + 'timing.interval': 'Wiederholen Sie alle', + 'timing.intervalIncrease': 'Intervall erhöhen', + 'timing.intervalDecrease': 'Intervall verringern', + 'timing.unit.hour': 'Stunden', + 'timing.unit.minute': 'Minuten', + 'timing.unit.second': 'Sekunden', + 'timing.intervalHint.hour': 'Mindestens 1 Stunde. Das Intervall zählt ab der Aufgabenerstellung oder der letzten Regeländerung und ist unabhängig von Zeitzonen.', + 'timing.intervalHint.minute': 'Mindestens 1 Minute. Das Intervall zählt ab der Aufgabenerstellung oder der letzten Regeländerung und ist unabhängig von Zeitzonen.', + 'timing.intervalHint.second': 'Mindestens 60 Sekunden. Das Intervall zählt ab der Aufgabenerstellung oder der letzten Regeländerung und ist unabhängig von Zeitzonen.', + 'timing.zoneNoStored': 'Eine einmalige Aufgabe speichert nur ihren Zielzeitpunkt, keine Zeitzone. Datum und Uhrzeit werden in der gewählten Zeitzone interpretiert.', + 'timing.inactive': 'Inaktive Aufgaben sind schreibgeschützt. Ihr Timing kann nicht bearbeitet werden.', + 'timing.conflict': 'Diese Aufgabe hat sich während der Bearbeitung geändert. Ihr Entwurf bleibt erhalten. ' + + 'Abbrechen und nach der Aktualisierung erneut öffnen, um die neueste Regel zu bearbeiten.', + 'timing.notFound': 'Diese Aufgabe ist nicht mehr verfügbar. Ihr Entwurf bleibt erhalten; Abbrechen, um den Editor zu schließen.', + 'timing.subagentSession': 'Diese Sitzung gehört einem Subagenten, der niemals zugestellte Erinnerungen erhält.', + 'timing.invalid': 'Geben Sie ein gültiges Datum und eine gültige Uhrzeit ein oder überprüfen Sie die Zeitfelder.', + 'timing.invalidZone': 'Geben Sie eine gültige IANA-Zeitzone ein, zum Beispiel Asien/Shanghai.', + 'timing.notFuture': 'Wählen Sie ein Datum und eine Uhrzeit in der Zukunft.', + 'timing.invalidInterval': 'Geben Sie ein Intervall von mindestens 1 Minute ein.', + 'timing.invalidInterval.hour': 'Geben Sie ein Intervall von mindestens 1 Stunde ein.', + 'timing.invalidInterval.minute': 'Geben Sie ein Intervall von mindestens 1 Minute ein.', + 'timing.invalidInterval.second': 'Geben Sie ein Intervall von mindestens 60 Sekunden ein.', + 'timing.error': 'Das Timing-Update konnte nicht bestätigt werden. Ihr Entwurf bleibt erhalten. Überprüfen Sie die Aufgabe, bevor Sie es erneut versuchen.', + 'rule.title': 'Laufzeit', + 'rule.repeat': 'Wiederholen', + 'rule.weekday': 'Wochentag', + 'rule.weekdayOption': 'Wochentag {weekday}', + 'rule.unsaved': 'Nicht gespeicherte Änderungen', + 'rule.save': 'Änderungen speichern', + 'rule.saving': 'Sparen…', + 'rule.cancel': 'Abbrechen', + 'rule.invalidTitle': 'Geben Sie einen Aufgabennamen mit maximal 120 Zeichen ein.', + 'rule.invalidPrompt': 'Geben Sie eine Aufgabenanweisung ein.', + 'rule.once': 'Einmal', + 'rule.everyMinutes': 'Alle N Minuten', + 'rule.everyHours': 'Alle N Stunden', + 'rule.everySeconds': 'Alle N Sekunden', + 'rule.daily': 'Jeden Tag', + 'rule.weekdays': 'Montag bis Freitag', + 'rule.weekly': 'Wöchentlich', + 'rule.cron': 'Benutzerdefiniert', + 'rule.cronLabel': 'Cron-Ausdruck', + 'rule.cronInvalid': 'Geben Sie einen Cron-Ausdruck mit fünf Feldern ein, zum Beispiel 0 9 * * 1-5.', + 'cronForm.frequency': 'Häufigkeit', + 'cronForm.monthly': 'Monatlich', + 'cronForm.weekly': 'Wöchentlich', + 'cronForm.daily': 'Jeden Tag', + 'cronForm.dates': 'An Terminen', + 'cronForm.dateOption': 'Tag {day}', + 'cronForm.atMinute': 'Im Moment', + 'cronForm.minuteIncrease': 'Minute erhöhen', + 'cronForm.minuteDecrease': 'Minute verringern', + 'rule.zone.system': ' (System)', + 'rule.error.conflict': 'Diese Aufgabe wurde vor dem Speichern des Updates geändert. Die Zeile zeigt die gespeicherte Regel; versuchen Sie es erneut.', + 'rule.error.notFound': 'Diese Aufgabe ist nicht mehr verfügbar.', + 'rule.error.unknown': 'Die Regelaktualisierung konnte nicht bestätigt werden. Die Zeile zeigt die gespeicherte Regel.', + 'delete.action': 'Aufgabe löschen', + 'delete.title': 'Diese Aufgabe löschen?', + 'delete.description': 'Dadurch wird verhindert, dass die Aufgabe ausgelöst wird, und sie wird zusammen mit den gespeicherten Lieferdatensätzen gelöscht. ' + + 'Die ursprüngliche Sitzung und ihre Nachrichten bleiben erhalten; Nachrichten in der Warteschlange werden nicht zurückgezogen.', + 'delete.confirm': 'Bestätigen Sie den Löschvorgang', + 'delete.cancel': 'Abbrechen', + 'delete.close': 'Löschbestätigung schließen', + 'delete.pending': 'Löschen…', + 'toast.deleted': 'Aufgabe gelöscht.', + 'toast.deleteFailed': 'Die Aufgabe konnte nicht gelöscht werden.', + 'card.open': 'Öffnen', + 'card.openLabel': 'Aufgabendetails öffnen: {title}', + 'card.deleted': 'Gelöscht', + 'tool.invoked': '{name} aufgerufen', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'panel': 'Задачи автоматизации', + 'title': 'Задачи автоматизации', + 'new.action': 'Новый', + 'list.label': 'Каталог задач', + 'list.nextPrefix': 'Следующее запланированное время: ', + 'list.loading': 'Загрузка задач…', + 'list.error': 'Не удалось загрузить задачи.', + 'list.retry': 'Повторить', + 'list.empty': 'Заданий пока нет. Здесь отображаются задачи, созданные в ваших сеансах.', + 'list.emptyInactive': 'Нет неактивных задач автоматизации', + 'list.noMatches': 'Нет подходящих задач', + 'search.label': 'Поиск задач', + 'search.placeholder': 'Задачи автоматизации поиска', + 'search.clear': 'Очистить поиск', + 'empty.action': 'Новая задача автоматизации', + 'statusFilter.label': 'Статус задачи', + 'statusFilter.all': 'Все', + 'status.active': 'Включено', + 'status.inactive': 'Неактивный', + 'detail.label': 'Подробности задачи', + 'detail.close': 'Закрыть детали', + 'detail.more': 'Действия задачи автоматизации', + 'detail.nextRun': 'Следующий запуск', + 'detail.tabs': 'Просмотр сведений о задаче', + 'detail.rule': 'Правила', + 'detail.records': 'Рекорды', + 'delivery.empty': 'Нет записи о доставке', + 'delivery.loading': 'Загрузка записей о доставке…', + 'delivery.error': 'Не удалось загрузить записи о доставке.', + 'delivery.notFound': 'Эта задача больше не доступна.', + 'delivery.cursorError': 'Записи обновлены.', + 'delivery.retry': 'Повторить', + 'delivery.refresh': 'Обновить', + 'delivery.loadMore': 'Загрузить больше', + 'delivery.expand': 'Развернуть', + 'delivery.collapse': 'Свернуть', + 'delivery.pruned': 'Записи о предыдущих поставках удалены.', + 'delivery.retention': 'Правила хранения', + 'delivery.retentionBounds': 'Каждая задача сохраняет записи о доставке до {records} за последние дни {days}.', + 'delivery.retentionExplanation': 'При сохранении новой записи более старые записи, выходящие за эти пределы, автоматически удаляются. Очистка записей не останавливает выполнение задачи.', + 'detail.name': 'Название задачи автоматизации', + 'detail.instruction': 'Инструкция по задаче автоматизации', + 'detail.status': 'Статус', + 'detail.next': 'Следующее запланированное время', + 'detail.frequency': 'Частота', + 'detail.id': 'Идентификатор задачи', + 'detail.session': 'Связанный сеанс', + 'detail.openSession': 'Связанный сеанс: открыть исходный сеанс.', + 'detail.openSessionTitle': 'Связанный сеанс {title}: открыть исходный сеанс.', + 'detail.sessionLoading': 'Загрузка исходной информации о сеансе.', + 'detail.sessionArchived': 'Исходный сеанс архивируется.', + 'detail.sessionUnavailable': 'Исходный сеанс недоступен.', + 'detail.missing': 'Задача недоступна. Возможно, оно было удалено.', + 'delivery.label': 'Сохраненная запись о доставке', + 'frequency.once': 'Однажды', + 'frequency.every': 'Каждый {value} {unit}', + ...frequencyRu, + 'timing.date': 'Дата', + 'timing.time': 'Время', + 'timing.hour': 'Час', + 'timing.minute': 'минута', + 'timing.second': 'Второй', + 'timing.prevMonth': 'Предыдущий месяц', + 'timing.nextMonth': 'В следующем месяце', + 'timing.zone': 'Часовой пояс', + 'timing.zoneSearch': 'Поиск по смещению UTC, идентификатору IANA или городу.', + 'timing.zoneNoResults': 'Нет подходящих часовых поясов', + 'timing.interval': 'Повторяйте каждые', + 'timing.intervalIncrease': 'Увеличить интервал', + 'timing.intervalDecrease': 'Уменьшить интервал', + 'timing.unit.hour': 'часы', + 'timing.unit.minute': 'минуты', + 'timing.unit.second': 'секунды', + 'timing.intervalHint.hour': 'Минимум 1 час. Интервал отсчитывается с момента создания задачи или последнего изменения правила и не зависит от часовых поясов.', + 'timing.intervalHint.minute': 'Минимум 1 минута. Интервал отсчитывается с момента создания задачи или последнего изменения правила и не зависит от часовых поясов.', + 'timing.intervalHint.second': 'Минимум 60 секунд. Интервал отсчитывается с момента создания задачи или последнего изменения правила и не зависит от часовых поясов.', + 'timing.zoneNoStored': 'Одноразовая задача сохраняет только целевой момент, а не часовой пояс. Дата и время интерпретируются в выбранном часовом поясе.', + 'timing.inactive': 'Неактивные задачи доступны только для чтения. Их время не может быть отредактировано.', + 'timing.conflict': 'Эта задача изменилась во время редактирования. Ваш черновик сохранен. ' + + 'Отмените и снова откройте после обновления, чтобы изменить последнее правило.', + 'timing.notFound': 'Эта задача больше не доступна. Ваш черновик сохраняется; отмените, чтобы закрыть редактор.', + 'timing.subagentSession': 'Этот сеанс принадлежит субагенту, который никогда не получает напоминания.', + 'timing.invalid': 'Введите действительные дату и время или проверьте поля времени.', + 'timing.invalidZone': 'Введите действительный часовой пояс IANA, например Азия/Шанхай.', + 'timing.notFuture': 'Выберите дату и время в будущем.', + 'timing.invalidInterval': 'Введите интервал не менее 1 минуты.', + 'timing.invalidInterval.hour': 'Введите интервал не менее 1 часа.', + 'timing.invalidInterval.minute': 'Введите интервал не менее 1 минуты.', + 'timing.invalidInterval.second': 'Введите интервал не менее 60 секунд.', + 'timing.error': 'Не удалось подтвердить обновление времени. Ваш черновик сохранен. Проверьте задачу, прежде чем повторить попытку.', + 'rule.title': 'Время выполнения', + 'rule.repeat': 'Повторить', + 'rule.weekday': 'Будний день', + 'rule.weekdayOption': 'День недели {weekday}', + 'rule.unsaved': 'Несохраненные изменения', + 'rule.save': 'Сохранить изменения', + 'rule.saving': 'Сохранение…', + 'rule.cancel': 'Отмена', + 'rule.invalidTitle': 'Введите имя задачи длиной не более 120 символов.', + 'rule.invalidPrompt': 'Введите инструкцию задачи.', + 'rule.once': 'Однажды', + 'rule.everyMinutes': 'Каждые N минут', + 'rule.everyHours': 'Каждые N часов', + 'rule.everySeconds': 'Каждые N секунд', + 'rule.daily': 'Каждый день', + 'rule.weekdays': 'С понедельника по пятницу', + 'rule.weekly': 'Еженедельно', + 'rule.cron': 'Пользовательский', + 'rule.cronLabel': 'Выражение Cron', + 'rule.cronInvalid': 'Введите выражение cron из пяти полей, например 0 9 * * 1-5.', + 'cronForm.frequency': 'Частота', + 'cronForm.monthly': 'Ежемесячно', + 'cronForm.weekly': 'Еженедельно', + 'cronForm.daily': 'Каждый день', + 'cronForm.dates': 'По датам', + 'cronForm.dateOption': 'День {day}', + 'cronForm.atMinute': 'В минуту', + 'cronForm.minuteIncrease': 'Увеличить минуту', + 'cronForm.minuteDecrease': 'Уменьшить минуту', + 'rule.zone.system': ' (система)', + 'rule.error.conflict': 'Эта задача изменилась до сохранения обновления. В строке отображается сохраненное правило; Попробуйте еще раз.', + 'rule.error.notFound': 'Эта задача больше не доступна.', + 'rule.error.unknown': 'Не удалось подтвердить обновление правила. В строке отображается сохраненное правило.', + 'delete.action': 'Удалить задачу', + 'delete.title': 'Удалить эту задачу?', + 'delete.description': 'Это останавливает запуск задачи и удаляет ее вместе с сохраненными записями о доставке. ' + + 'Исходный сеанс и его сообщения остаются; сообщения в очереди не изымаются.', + 'delete.confirm': 'Подтвердить удаление', + 'delete.cancel': 'Отмена', + 'delete.close': 'Закрыть подтверждение удаления', + 'delete.pending': 'Удаление…', + 'toast.deleted': 'Задача удалена.', + 'toast.deleteFailed': 'Не удалось удалить задачу.', + 'card.open': 'Открыть', + 'card.openLabel': 'Открыть сведения о задаче: {title}.', + 'card.deleted': 'Удалено', + 'tool.invoked': 'Вызван {name}', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'panel': 'Tarefas de automação', + 'title': 'Tarefas de automação', + 'new.action': 'Novo', + 'list.label': 'Catálogo de tarefas', + 'list.nextPrefix': 'Próximo horário agendado: ', + 'list.loading': 'Carregando tarefas…', + 'list.error': 'Não foi possível carregar tarefas.', + 'list.retry': 'Tentar novamente', + 'list.empty': 'Nenhuma tarefa ainda. As tarefas criadas nas suas sessões aparecem aqui.', + 'list.emptyInactive': 'Nenhuma tarefa de automação inativa', + 'list.noMatches': 'Nenhuma tarefa correspondente', + 'search.label': 'Tarefas de pesquisa', + 'search.placeholder': 'Tarefas de automação de pesquisa', + 'search.clear': 'Limpar pesquisa', + 'empty.action': 'Nova tarefa de automação', + 'statusFilter.label': 'Status da tarefa', + 'statusFilter.all': 'Todos', + 'status.active': 'Habilitado', + 'status.inactive': 'Inativo', + 'detail.label': 'Detalhes da tarefa', + 'detail.close': 'Fechar detalhes', + 'detail.more': 'Ações de tarefas de automação', + 'detail.nextRun': 'Próxima execução', + 'detail.tabs': 'Visualizações de detalhes da tarefa', + 'detail.rule': 'Regras', + 'detail.records': 'Registros', + 'delivery.empty': 'Nenhum registro de entrega disponível', + 'delivery.loading': 'Carregando registros de entrega…', + 'delivery.error': 'Não foi possível carregar os registros de entrega.', + 'delivery.notFound': 'Esta tarefa não está mais disponível.', + 'delivery.cursorError': 'Os registros foram atualizados.', + 'delivery.retry': 'Tentar novamente', + 'delivery.refresh': 'Atualizar', + 'delivery.loadMore': 'Carregar mais', + 'delivery.expand': 'Expandir', + 'delivery.collapse': 'Recolher', + 'delivery.pruned': 'Registros de entrega anteriores foram apagados', + 'delivery.retention': 'Regras de retenção', + 'delivery.retentionBounds': 'Cada tarefa mantém até {records} registros de entrega dos últimos {days} dias.', + 'delivery.retentionExplanation': 'Quando um novo registro é salvo, os registros mais antigos fora desses limites são apagados automaticamente. A limpeza de registros não interrompe a tarefa.', + 'detail.name': 'Nome da tarefa de automação', + 'detail.instruction': 'Instrução de tarefa de automação', + 'detail.status': 'Estado', + 'detail.next': 'Próximo horário agendado', + 'detail.frequency': 'Frequência', + 'detail.id': 'ID da tarefa', + 'detail.session': 'Sessão vinculada', + 'detail.openSession': 'Sessão vinculada: sessão original aberta', + 'detail.openSessionTitle': 'Sessão vinculada {title}: sessão original aberta', + 'detail.sessionLoading': 'Carregando informações originais da sessão.', + 'detail.sessionArchived': 'A sessão original é arquivada.', + 'detail.sessionUnavailable': 'A sessão original não está disponível.', + 'detail.missing': 'Tarefa indisponível. Pode ter sido excluído.', + 'delivery.label': 'Registro de entrega salvo', + 'frequency.once': 'Uma vez', + 'frequency.every': 'A cada {value} {unit}', + ...frequencyPt, + 'timing.date': 'Data', + 'timing.time': 'Hora', + 'timing.hour': 'Hora', + 'timing.minute': 'Minuto', + 'timing.second': 'Segundo', + 'timing.prevMonth': 'Mês anterior', + 'timing.nextMonth': 'No próximo mês', + 'timing.zone': 'Fuso horário', + 'timing.zoneSearch': 'Pesquise por deslocamento UTC, ID IANA ou cidade', + 'timing.zoneNoResults': 'Nenhum fuso horário correspondente', + 'timing.interval': 'Repita cada', + 'timing.intervalIncrease': 'Aumentar intervalo', + 'timing.intervalDecrease': 'Diminuir intervalo', + 'timing.unit.hour': 'horas', + 'timing.unit.minute': 'minutos', + 'timing.unit.second': 'segundos', + 'timing.intervalHint.hour': 'Pelo menos 1 hora. O intervalo conta a partir da criação da tarefa ou da última alteração de regra e é independente dos fusos horários.', + 'timing.intervalHint.minute': 'Pelo menos 1 minuto. O intervalo conta a partir da criação da tarefa ou da última alteração de regra e é independente dos fusos horários.', + 'timing.intervalHint.second': 'Pelo menos 60 segundos. O intervalo conta a partir da criação da tarefa ou da última alteração de regra e é independente dos fusos horários.', + 'timing.zoneNoStored': 'Uma tarefa única armazena apenas o momento alvo, não um fuso horário. A data e a hora são interpretadas no fuso horário selecionado.', + 'timing.inactive': 'As tarefas inativas são somente leitura. O tempo deles não pode ser editado.', + 'timing.conflict': 'Esta tarefa mudou enquanto você estava editando. Seu rascunho foi mantido. ' + + 'Cancele e reabra após a atualização para editar a regra mais recente.', + 'timing.notFound': 'Esta tarefa não está mais disponível. Seu rascunho foi retido; cancelar para fechar o editor.', + 'timing.subagentSession': 'Esta sessão pertence a um subagente, que nunca recebe lembretes entregues.', + 'timing.invalid': 'Insira uma data e hora válidas ou verifique os campos de horário.', + 'timing.invalidZone': 'Insira um fuso horário IANA válido, por exemplo Ásia/Xangai.', + 'timing.notFuture': 'Escolha uma data e hora no futuro.', + 'timing.invalidInterval': 'Insira um intervalo de pelo menos 1 minuto.', + 'timing.invalidInterval.hour': 'Insira um intervalo de pelo menos 1 hora.', + 'timing.invalidInterval.minute': 'Insira um intervalo de pelo menos 1 minuto.', + 'timing.invalidInterval.second': 'Insira um intervalo de pelo menos 60 segundos.', + 'timing.error': 'Não foi possível confirmar a atualização de tempo. Seu rascunho foi mantido. Verifique a tarefa antes de tentar novamente.', + 'rule.title': 'Tempo de execução', + 'rule.repeat': 'Repetir', + 'rule.weekday': 'Dia da semana', + 'rule.weekdayOption': 'Dia da semana {weekday}', + 'rule.unsaved': 'Alterações não salvas', + 'rule.save': 'Salvar alterações', + 'rule.saving': 'Salvando…', + 'rule.cancel': 'Cancelar', + 'rule.invalidTitle': 'Insira um nome de tarefa com no máximo 120 caracteres.', + 'rule.invalidPrompt': 'Insira uma instrução de tarefa.', + 'rule.once': 'Uma vez', + 'rule.everyMinutes': 'A cada N minutos', + 'rule.everyHours': 'A cada N horas', + 'rule.everySeconds': 'A cada N segundos', + 'rule.daily': 'Todos os dias', + 'rule.weekdays': 'Segunda a sexta', + 'rule.weekly': 'Semanalmente', + 'rule.cron': 'Personalizado', + 'rule.cronLabel': 'Expressão Cron', + 'rule.cronInvalid': 'Insira uma expressão cron de cinco campos, por exemplo 0 9 * * 1-5.', + 'cronForm.frequency': 'Frequência', + 'cronForm.monthly': 'Mensalmente', + 'cronForm.weekly': 'Semanalmente', + 'cronForm.daily': 'Todos os dias', + 'cronForm.dates': 'Em datas', + 'cronForm.dateOption': 'Dia {day}', + 'cronForm.atMinute': 'No minuto', + 'cronForm.minuteIncrease': 'Aumentar minuto', + 'cronForm.minuteDecrease': 'Diminuir minuto', + 'rule.zone.system': ' (sistema)', + 'rule.error.conflict': 'Esta tarefa foi alterada antes da atualização ser salva. A linha mostra a regra salva; tente novamente.', + 'rule.error.notFound': 'Esta tarefa não está mais disponível.', + 'rule.error.unknown': 'Não foi possível confirmar a atualização da regra. A linha mostra a regra salva.', + 'delete.action': 'Excluir tarefa', + 'delete.title': 'Excluir esta tarefa?', + 'delete.description': 'Isso interrompe o acionamento da tarefa e a exclui junto com seus registros de entrega salvos. ' + + 'A sessão original e suas mensagens permanecem; mensagens enfileiradas não são retiradas.', + 'delete.confirm': 'Confirmar exclusão', + 'delete.cancel': 'Cancelar', + 'delete.close': 'Fechar confirmação de exclusão', + 'delete.pending': 'Excluindo…', + 'toast.deleted': 'Tarefa excluída.', + 'toast.deleteFailed': 'Não foi possível excluir a tarefa.', + 'card.open': 'Abrir', + 'card.openLabel': 'Detalhes da tarefa aberta: {title}', + 'card.deleted': 'Excluído', + 'tool.invoked': 'Invocado {name}', +} satisfies Record diff --git a/packages/client/ui-secret-mask/locale/de.json b/packages/client/ui-secret-mask/locale/de.json new file mode 100644 index 0000000000..e75c2392f5 --- /dev/null +++ b/packages/client/ui-secret-mask/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Maskierung von Anmeldeinformationen", + "description": "Maskiert erkannte Schlüssel, Token und Passwörter in gesendeten Nachrichten." + } +} diff --git a/packages/client/ui-secret-mask/locale/es.json b/packages/client/ui-secret-mask/locale/es.json new file mode 100644 index 0000000000..91672e7f75 --- /dev/null +++ b/packages/client/ui-secret-mask/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Enmascaramiento de credenciales", + "description": "Enmascara claves, tokens y contraseñas reconocidas en los mensajes enviados." + } +} diff --git a/packages/client/ui-secret-mask/locale/fr.json b/packages/client/ui-secret-mask/locale/fr.json new file mode 100644 index 0000000000..f174fb8bd1 --- /dev/null +++ b/packages/client/ui-secret-mask/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Masquage des informations d'identification", + "description": "Masque les clés, jetons et mots de passe reconnus dans les messages envoyés." + } +} diff --git a/packages/client/ui-secret-mask/locale/pt.json b/packages/client/ui-secret-mask/locale/pt.json new file mode 100644 index 0000000000..4f6910096c --- /dev/null +++ b/packages/client/ui-secret-mask/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Mascaramento de credenciais", + "description": "Mascara chaves, tokens e senhas reconhecidas em mensagens enviadas." + } +} diff --git a/packages/client/ui-secret-mask/locale/ru.json b/packages/client/ui-secret-mask/locale/ru.json new file mode 100644 index 0000000000..0f9d26af72 --- /dev/null +++ b/packages/client/ui-secret-mask/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Маскирование учетных данных", + "description": "Маскирует распознанные ключи, токены и пароли в отправленных сообщениях." + } +} diff --git a/packages/client/ui-secret-mask/src/client/index.ts b/packages/client/ui-secret-mask/src/client/index.ts index 4346d37bf2..91f02986f6 100644 --- a/packages/client/ui-secret-mask/src/client/index.ts +++ b/packages/client/ui-secret-mask/src/client/index.ts @@ -15,7 +15,7 @@ import type {} from '@deepseek-ai/dsh-client-ui-conversation/client' import { SecretText } from './SecretText.tsx' import { createSecretRule } from './secret-rule.ts' export type {} from './secret-rule.ts' -import { en, ja, NS, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, NS, zh } from './locales.ts' /** Required services: the copy, the node renderer registry, and the UserText rule registry. */ export const inject = ['locale', 'slots', 'uiConversation'] @@ -25,7 +25,7 @@ export const inject = ['locale', 'slots', 'uiConversation'] * @param ctx - client root context. */ export function apply(ctx: ClientContext): void { - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-secret-mask: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-secret-mask: dictionaries') ctx.uiConversation.userText.register(createSecretRule()) ctx.slots.inject('conversation.user.text.node', () => ctx.slots.register({ name: 'conversation.user.text.node', key: 'secret', priority: 100, locale: NS, diff --git a/packages/client/ui-secret-mask/src/client/locales.ts b/packages/client/ui-secret-mask/src/client/locales.ts index 7bf3c0915b..2034471fe6 100644 --- a/packages/client/ui-secret-mask/src/client/locales.ts +++ b/packages/client/ui-secret-mask/src/client/locales.ts @@ -32,3 +32,33 @@ export const ja = { 'secret.reveal': 'シークレットを表示', 'secret.hide': 'シークレットを隠す', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'secret.reveal': 'Mostrar secreto', + 'secret.hide': 'Ocultar secreto', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'secret.reveal': 'Afficher le secret', + 'secret.hide': 'Cacher le secret', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'secret.reveal': 'Geheimnis zeigen', + 'secret.hide': 'Geheimnis verbergen', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'secret.reveal': 'Показать секрет', + 'secret.hide': 'Скрыть секрет', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'secret.reveal': 'Mostrar segredo', + 'secret.hide': 'Ocultar segredo', +} satisfies Record diff --git a/packages/client/ui-session/locale/de.json b/packages/client/ui-session/locale/de.json new file mode 100644 index 0000000000..cae002c97b --- /dev/null +++ b/packages/client/ui-session/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Verbindung zur Sitzungsschnittstelle", + "description": "Verbinden Sie Sitzungssteuerung und Status mit React-Schnittstellenkomponenten." + } +} diff --git a/packages/client/ui-session/locale/es.json b/packages/client/ui-session/locale/es.json new file mode 100644 index 0000000000..0febc1d178 --- /dev/null +++ b/packages/client/ui-session/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Conexión de interfaz de sesión", + "description": "Conecte el control y el estado de la sesión a los componentes de la interfaz de React." + } +} diff --git a/packages/client/ui-session/locale/fr.json b/packages/client/ui-session/locale/fr.json new file mode 100644 index 0000000000..e4622ab45d --- /dev/null +++ b/packages/client/ui-session/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Connexion à l'interface de session", + "description": "Connectez le contrôle de session et l’état aux composants de l’interface React." + } +} diff --git a/packages/client/ui-session/locale/pt.json b/packages/client/ui-session/locale/pt.json new file mode 100644 index 0000000000..c5a9625131 --- /dev/null +++ b/packages/client/ui-session/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Conexão de interface de sessão", + "description": "Conecte o controle e o estado da sessão aos componentes da interface React." + } +} diff --git a/packages/client/ui-session/locale/ru.json b/packages/client/ui-session/locale/ru.json new file mode 100644 index 0000000000..c4df84e0a3 --- /dev/null +++ b/packages/client/ui-session/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Подключение интерфейса сеанса", + "description": "Подключите управление сеансом и состояние к компонентам интерфейса React." + } +} diff --git a/packages/client/ui-settings-account/locale/de.json b/packages/client/ui-settings-account/locale/de.json new file mode 100644 index 0000000000..1f7c9a6c99 --- /dev/null +++ b/packages/client/ui-settings-account/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Benutzeroberfläche für Kontoeinstellungen", + "description": "Melden Sie sich an, um DeepSeek zu verwalten und die Abrechnungsseite der Plattform zu öffnen." + } +} diff --git a/packages/client/ui-settings-account/locale/es.json b/packages/client/ui-settings-account/locale/es.json new file mode 100644 index 0000000000..de8904f3d3 --- /dev/null +++ b/packages/client/ui-settings-account/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de configuración de cuenta", + "description": "Inicie sesión para administrar DeepSeek y abra la página de facturación de la plataforma." + } +} diff --git a/packages/client/ui-settings-account/locale/fr.json b/packages/client/ui-settings-account/locale/fr.json new file mode 100644 index 0000000000..6b64e79108 --- /dev/null +++ b/packages/client/ui-settings-account/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de configuration du compte", + "description": "Connectez-vous pour gérer DeepSeek et ouvrez la page de facturation de la plateforme." + } +} diff --git a/packages/client/ui-settings-account/locale/pt.json b/packages/client/ui-settings-account/locale/pt.json new file mode 100644 index 0000000000..8a4619488e --- /dev/null +++ b/packages/client/ui-settings-account/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de configuração de conta", + "description": "Faça login para gerenciar DeepSeek e abra a página de faturamento da plataforma." + } +} diff --git a/packages/client/ui-settings-account/locale/ru.json b/packages/client/ui-settings-account/locale/ru.json new file mode 100644 index 0000000000..a1b2fddd9b --- /dev/null +++ b/packages/client/ui-settings-account/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Интерфейс настройки учетной записи", + "description": "Войдите в систему для управления DeepSeek и откройте страницу выставления счетов платформы." + } +} diff --git a/packages/client/ui-settings-account/src/client/index.ts b/packages/client/ui-settings-account/src/client/index.ts index b70e5097a1..45f13a1b97 100644 --- a/packages/client/ui-settings-account/src/client/index.ts +++ b/packages/client/ui-settings-account/src/client/index.ts @@ -24,7 +24,7 @@ import { createPlatformPages, type PlatformPages } from './platform-pages.ts' import { AccountSection, type AccountSnapshot, type AccountSectionInjected } from './AccountSection.tsx' import { createBonusNoticeController } from './bonus-notices.ts' import { accountClientMetadata } from './client-metadata.ts' -import { en, ja, zh, type AccountKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh, type AccountKey } from './locales.ts' import { AccountQuotaNotice, type AccountQuotaNoticeInjected } from './AccountQuotaNotice.tsx' import { DESKTOP_ONBOARDING_NAMESPACE, type OnboardingSettings } from '../onboarding-settings.ts' import { DesktopOnboardingController } from './onboarding-state.ts' @@ -46,7 +46,7 @@ export const inject = ['slots', 'locale', 'remote', 'remote.account', 'remote.se /** Register account UI in Desktop and plain Web clients. @param ctx - client plugin context. */ export function apply(ctx: Context): void { const desktop = 'dshDesktop' in globalThis - ctx.effect(() => ctx.locale.register('settings.account', { en, zh, ja }), 'account: dictionaries') + ctx.effect(() => ctx.locale.register('settings.account', { en, zh, ja, es, fr, de, ru, pt }), 'account: dictionaries') const t = ctx.locale.bind('settings.account') const page = globalThis as Partial> const config = ContactConfig(page[CONTACT_CONFIG_GLOBAL] ?? {}) diff --git a/packages/client/ui-settings-account/src/client/locales.ts b/packages/client/ui-settings-account/src/client/locales.ts index 5244c0743f..5449776e41 100644 --- a/packages/client/ui-settings-account/src/client/locales.ts +++ b/packages/client/ui-settings-account/src/client/locales.ts @@ -1,5 +1,5 @@ /** Account settings copy, owned by the account feature. */ -import { onboardingZh, onboardingEn, onboardingJa } from './locales/onboarding.ts' +import { onboardingZh, onboardingEn, onboardingJa, onboardingEs, onboardingFr, onboardingDe, onboardingRu, onboardingPt } from './locales/onboarding.ts' /** English account dictionary. */ export const en = { @@ -131,3 +131,178 @@ export const ja = { 'quotaTopUp': 'チャージ', 'bonusNoticeTitle': 'ボーナスが付与されました', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + modelSignInRequired: 'Modelo no disponible. Por favor inicia sesión y vuelve a intentarlo.', + sessionExpired: 'Has cerrado sesión en tu cuenta, inicia sesión nuevamente.', + ...onboardingEs, + close: 'Cerrar', addApiKey: 'Agregar clave API', retry: 'Iniciar sesión nuevamente', + loginTitle: 'empezar', loginDescription: 'Inicie sesión en su cuenta DeepSeek o agregue una clave API para comenzar. Sus proyectos y archivos se almacenan localmente.', + browserTitle: 'Esperando iniciar sesión', browserPrompt: '¿La página no se abrió automáticamente? ', copyLink: 'Copiar enlace de inicio de sesión', copiedLink: 'Enlace copiado', copyFailed: 'Copia fallida', + browserDescription: ', luego ábrelo en tu navegador para terminar de iniciar sesión.', + timeoutTitle: 'Se agotó el tiempo de inicio de sesión', timeoutDescription: 'Inicia sesión nuevamente para continuar.', + failureTitle: 'No se pudo iniciar sesión', + platformFailed: 'No se pudo completar la operación. Intentar otra vez.', platformRetry: 'Reintentar', + loading: 'Cargando…', backToHarness: 'Volver a DeepSeek Harness', + settings: 'Configuración', contactUs: 'Comentarios', menu: 'Menú de cuenta', + nav: 'cuenta', signedIn: 'Iniciado sesión en DeepSeek', signedOut: 'No iniciado sesión', + signIn: 'Iniciar sesión', signOut: 'Cerrar sesión', + signOutUnknownDescription: 'No se pudieron verificar las tareas en ejecución. Cerrar sesión puede interrumpir las tareas que utilizan esta cuenta. ¿Cerrar sesión ahora?', + signOutDescription: 'Cerrar sesión no eliminará ningún dato. Puede iniciar sesión en esta cuenta nuevamente.', + signOutRunningDescription: 'Las tareas se están ejecutando actualmente. Cerrar sesión los interrumpirá. ¿Cerrar sesión ahora?', cancel: 'Cancelar', open: 'Abrir navegador', + initializing: 'Iniciando sesión...', waiting: 'Continuar en tu navegador', + completing: 'Completando el inicio de sesión…', expired: 'Iniciar sesión caducado. Intentar otra vez.', + failed: 'No se pudo completar la operación. Intentar otra vez.', + noResponse: 'Algo salió mal. Verifique su conexión de red e inténtelo nuevamente.', + settingsSignedOutTitle: 'No has iniciado sesión en DeepSeek Harness', + settingsSignedOutDescription: 'Inicie sesión en DeepSeek Harness para obtener su clave API dedicada', + signInDescription: 'Utilice su cuenta DeepSeek para comenzar.', + profileUnavailable: 'Los detalles de la cuenta aún no están disponibles.', + balance: 'Saldo recargado', bonusBalance: 'Saldo concedido', balanceUnavailable: 'Ver en plataforma', balanceSignedOut: 'Inicia sesión para ver', + accountInfo: 'Más información de la cuenta', more: 'Más', usage: 'Ver uso', topUp: 'Recargar', + quotaTitle: 'No hay saldo disponible', + quotaDescription: 'DeepSeek Harness no puede iniciar una nueva tarea con esta cuenta cuando no hay saldo disponible. ¿Quieres recargar? También puedes recargar más tarde en Configuración → Cuenta.', + quotaTopUp: 'Recargar', + bonusNoticeTitle: 'Bono acreditado', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + modelSignInRequired: 'Modèle indisponible. Veuillez vous connecter et réessayer.', + sessionExpired: 'Vous vous êtes déconnecté de votre compte, veuillez vous reconnecter.', + ...onboardingFr, + close: 'Fermer', addApiKey: 'Ajouter une clé API', retry: 'Connectez-vous à nouveau', + loginTitle: 'Commencez', loginDescription: 'Connectez-vous à votre compte DeepSeek ou ajoutez une clé API pour commencer. Vos projets et fichiers sont stockés localement.', + browserTitle: 'En attente de connexion', browserPrompt: "La page ne s'est pas ouverte automatiquement ? ", copyLink: 'Copier le lien de connexion', copiedLink: 'Lien copié', copyFailed: 'Échec de la copie', + browserDescription: ', puis ouvrez-le dans votre navigateur pour terminer la connexion.', + timeoutTitle: 'La connexion a expiré', timeoutDescription: 'Connectez-vous à nouveau pour continuer.', + failureTitle: 'Impossible de se connecter', + platformFailed: "Impossible de terminer l'opération. Essayer à nouveau.", platformRetry: 'Réessayer', + loading: 'Chargement…', backToHarness: 'Retour à DeepSeek Harness', + settings: 'Paramètres', contactUs: 'Commentaires', menu: 'Menu du compte', + nav: 'Compte', signedIn: 'Connecté à DeepSeek', signedOut: 'Non connecté', + signIn: 'Connectez-vous', signOut: 'Se déconnecter', + signOutUnknownDescription: "Impossible de vérifier les tâches en cours d'exécution. La déconnexion peut interrompre les tâches utilisant ce compte. Se déconnecter maintenant ?", + signOutDescription: 'La déconnexion ne supprimera aucune donnée. Vous pouvez vous reconnecter à ce compte.', + signOutRunningDescription: "Les tâches sont actuellement en cours d'exécution. La déconnexion les interrompra. Se déconnecter maintenant ?", cancel: 'Annuler', open: 'Ouvrir le navigateur', + initializing: 'Début de la connexion…', waiting: 'Continuez dans votre navigateur', + completing: 'Connexion terminée…', expired: 'Connexion expirée. Essayer à nouveau.', + failed: "Impossible de terminer l'opération. Essayer à nouveau.", + noResponse: "Quelque chose s'est mal passé. Veuillez vérifier votre connexion réseau et réessayer.", + settingsSignedOutTitle: "Vous n'êtes pas connecté à DeepSeek Harness", + settingsSignedOutDescription: 'Connectez-vous à DeepSeek Harness pour obtenir votre clé API dédiée', + signInDescription: 'Utilisez votre compte DeepSeek pour commencer.', + profileUnavailable: 'Les détails du compte ne sont pas encore disponibles.', + balance: 'Solde rechargé', bonusBalance: 'Solde accordé', balanceUnavailable: 'Afficher sur la plateforme', balanceSignedOut: 'Connectez-vous pour voir', + accountInfo: "Plus d'informations sur le compte", more: 'Plus', usage: "Afficher l'utilisation", topUp: 'Recharger', + quotaTitle: 'Aucun solde disponible', + quotaDescription: "DeepSeek Harness ne peut pas démarrer une nouvelle tâche avec ce compte lorsqu'aucun solde n'est disponible. Souhaitez-vous recharger ? Vous pouvez également recharger plus tard dans Paramètres → Compte.", + quotaTopUp: 'Recharger', + bonusNoticeTitle: 'Bonus crédité', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + modelSignInRequired: 'Modell nicht verfügbar. Bitte melden Sie sich an und versuchen Sie es erneut.', + sessionExpired: 'Sie haben sich von Ihrem Konto abgemeldet. Bitte melden Sie sich erneut an.', + ...onboardingDe, + close: 'Schließen', addApiKey: 'Fügen Sie den API-Schlüssel hinzu', retry: 'Melden Sie sich erneut an', + loginTitle: 'Fangen Sie an', loginDescription: 'Melden Sie sich bei Ihrem DeepSeek-Konto an oder fügen Sie einen API-Schlüssel hinzu, um loszulegen. Ihre Projekte und Dateien werden lokal gespeichert.', + browserTitle: 'Warten auf die Anmeldung', browserPrompt: 'Seite wurde nicht automatisch geöffnet? ', copyLink: 'Anmeldelink kopieren', copiedLink: 'Link kopiert', copyFailed: 'Das Kopieren ist fehlgeschlagen', + browserDescription: ', und öffnen Sie es dann in Ihrem Browser, um die Anmeldung abzuschließen.', + timeoutTitle: 'Zeitüberschreitung bei der Anmeldung', timeoutDescription: 'Melden Sie sich erneut an, um fortzufahren.', + failureTitle: 'Konnte mich nicht anmelden', + platformFailed: 'Der Vorgang konnte nicht abgeschlossen werden. Versuchen Sie es erneut.', platformRetry: 'Erneut versuchen', + loading: 'Laden…', backToHarness: 'Zurück zu DeepSeek Harness', + settings: 'Einstellungen', contactUs: 'Rückmeldung', menu: 'Kontomenü', + nav: 'Konto', signedIn: 'Angemeldet bei DeepSeek', signedOut: 'Nicht angemeldet', + signIn: 'Melden Sie sich an', signOut: 'Abmelden', + signOutUnknownDescription: 'Laufende Aufgaben konnten nicht überprüft werden. Durch das Abmelden werden möglicherweise Aufgaben mit diesem Konto unterbrochen. Jetzt abmelden?', + signOutDescription: 'Durch das Abmelden werden keine Daten gelöscht. Sie können sich erneut bei diesem Konto anmelden.', + signOutRunningDescription: 'Derzeit werden Aufgaben ausgeführt. Durch das Abmelden werden sie unterbrochen. Jetzt abmelden?', cancel: 'Abbrechen', open: 'Browser öffnen', + initializing: 'Anmeldung beginnt…', waiting: 'Fahren Sie in Ihrem Browser fort', + completing: 'Anmeldung wird abgeschlossen…', expired: 'Anmeldung abgelaufen. Versuchen Sie es erneut.', + failed: 'Der Vorgang konnte nicht abgeschlossen werden. Versuchen Sie es erneut.', + noResponse: 'Etwas ist schief gelaufen. Bitte überprüfen Sie Ihre Netzwerkverbindung und versuchen Sie es erneut.', + settingsSignedOutTitle: 'Sie sind nicht bei DeepSeek Harness angemeldet', + settingsSignedOutDescription: 'Melden Sie sich bei DeepSeek Harness an, um Ihren dedizierten API-Schlüssel zu erhalten', + signInDescription: 'Verwenden Sie Ihr DeepSeek-Konto, um loszulegen.', + profileUnavailable: 'Kontodaten sind noch nicht verfügbar.', + balance: 'Aufgeladenes Guthaben', bonusBalance: 'Gewährte Balance', balanceUnavailable: 'Auf der Plattform ansehen', balanceSignedOut: 'Melden Sie sich an, um es anzuzeigen', + accountInfo: 'Weitere Kontoinformationen', more: 'Mehr', usage: 'Nutzung anzeigen', topUp: 'Auffüllen', + quotaTitle: 'Kein Guthaben verfügbar', + quotaDescription: 'DeepSeek Harness kann mit diesem Konto keine neue Aufgabe starten, wenn kein Guthaben verfügbar ist. Möchten Sie aufladen? Sie können das Guthaben auch später unter Einstellungen → Konto aufladen.', + quotaTopUp: 'Auffüllen', + bonusNoticeTitle: 'Bonus gutgeschrieben', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + modelSignInRequired: 'Модель недоступна. Пожалуйста, войдите в систему и повторите попытку.', + sessionExpired: 'Вы вышли из своей учетной записи, пожалуйста, войдите снова.', + ...onboardingRu, + close: 'Закрыть', addApiKey: 'Добавить ключ API', retry: 'Войдите снова', + loginTitle: 'Начать', loginDescription: 'Войдите в свою учетную запись DeepSeek или добавьте ключ API, чтобы начать. Ваши проекты и файлы хранятся локально.', + browserTitle: 'Ожидание входа в систему', browserPrompt: 'Страница не открылась автоматически? ', copyLink: 'Скопировать ссылку для входа', copiedLink: 'Ссылка скопирована', copyFailed: 'Не удалось скопировать', + browserDescription: ', затем откройте его в браузере, чтобы завершить вход.', + timeoutTitle: 'Время входа в систему истекло', timeoutDescription: 'Войдите еще раз, чтобы продолжить.', + failureTitle: 'Не удалось войти в систему', + platformFailed: 'Не удалось завершить операцию. Попробуйте еще раз.', platformRetry: 'Повторить', + loading: 'Загрузка…', backToHarness: 'Вернуться к DeepSeek Harness', + settings: 'Настройки', contactUs: 'Обратная связь', menu: 'Меню аккаунта', + nav: 'Аккаунт', signedIn: 'Вошёл в DeepSeek', signedOut: 'Не авторизован', + signIn: 'Войти', signOut: 'Выйти', + signOutUnknownDescription: 'Не удалось проверить запущенные задачи. Выход из системы может прервать выполнение задач с использованием этой учетной записи. Выйти сейчас?', + signOutDescription: 'Выход из системы не приведет к удалению данных. Вы можете снова войти в эту учетную запись.', + signOutRunningDescription: 'Задачи в настоящее время выполняются. Выход из системы прервет их. Выйти сейчас?', cancel: 'Отмена', open: 'Открыть браузер', + initializing: 'Начинаем вход…', waiting: 'Продолжить в браузере', + completing: 'Завершение входа…', expired: 'Срок действия входа истек. Попробуйте еще раз.', + failed: 'Не удалось завершить операцию. Попробуйте еще раз.', + noResponse: 'Что-то пошло не так. Пожалуйста, проверьте сетевое соединение и повторите попытку.', + settingsSignedOutTitle: 'Вы не вошли в DeepSeek Harness.', + settingsSignedOutDescription: 'Войдите в DeepSeek Harness, чтобы получить специальный ключ API.', + signInDescription: 'Используйте свою учетную запись DeepSeek, чтобы начать.', + profileUnavailable: 'Детали аккаунта пока недоступны.', + balance: 'Пополненный баланс', bonusBalance: 'Предоставленный баланс', balanceUnavailable: 'Посмотреть на платформе', balanceSignedOut: 'Войдите, чтобы просмотреть', + accountInfo: 'Дополнительная информация об аккаунте', more: 'Ещё', usage: 'Посмотреть использование', topUp: 'Пополнить', + quotaTitle: 'Нет доступного баланса', + quotaDescription: 'DeepSeek Harness не может запустить новую задачу с этой учетной записью, если на ней нет баланса. Хотите пополнить счет? Вы также можете пополнить счет позже в «Настройки» → «Аккаунт».', + quotaTopUp: 'Пополнить', + bonusNoticeTitle: 'Бонус начислен', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + modelSignInRequired: 'Modelo indisponível. Faça login e tente novamente.', + sessionExpired: 'Você saiu da sua conta, faça login novamente.', + ...onboardingPt, + close: 'Fechar', addApiKey: 'Adicionar chave API', retry: 'Faça login novamente', + loginTitle: 'Comece', loginDescription: 'Faça login em sua conta DeepSeek ou adicione uma chave API para começar. Seus projetos e arquivos são armazenados localmente.', + browserTitle: 'Aguardando login', browserPrompt: 'A página não abriu automaticamente? ', copyLink: 'Copiar link de login', copiedLink: 'Link copiado', copyFailed: 'Falha na cópia', + browserDescription: 'e abra-o no navegador para concluir o login.', + timeoutTitle: 'O tempo limite de login expirou', timeoutDescription: 'Faça login novamente para continuar.', + failureTitle: 'Não foi possível fazer login', + platformFailed: 'Não foi possível concluir a operação. Tente novamente.', platformRetry: 'Tentar novamente', + loading: 'Carregando…', backToHarness: 'Voltar para DeepSeek Harness', + settings: 'Configurações', contactUs: 'Comentários', menu: 'Menu da conta', + nav: 'Conta', signedIn: 'Conectado em DeepSeek', signedOut: 'Não conectado', + signIn: 'Faça login', signOut: 'Sair', + signOutUnknownDescription: 'Não foi possível verificar as tarefas em execução. Sair pode interromper tarefas usando esta conta. Sair agora?', + signOutDescription: 'Sair não excluirá nenhum dado. Você pode fazer login nesta conta novamente.', + signOutRunningDescription: 'As tarefas estão em execução no momento. Sair irá interrompê-los. Sair agora?', cancel: 'Cancelar', open: 'Abra o navegador', + initializing: 'Iniciando login…', waiting: 'Continue no seu navegador', + completing: 'Concluindo login…', expired: 'O login expirou. Tente novamente.', + failed: 'Não foi possível concluir a operação. Tente novamente.', + noResponse: 'Algo deu errado. Verifique sua conexão de rede e tente novamente.', + settingsSignedOutTitle: 'Você não está conectado a DeepSeek Harness', + settingsSignedOutDescription: 'Faça login em DeepSeek Harness para obter sua chave API dedicada', + signInDescription: 'Use sua conta DeepSeek para começar.', + profileUnavailable: 'Os detalhes da conta ainda não estão disponíveis.', + balance: 'Saldo reabastecido', bonusBalance: 'Saldo concedido', balanceUnavailable: 'Ver na plataforma', balanceSignedOut: 'Faça login para ver', + accountInfo: 'Mais informações da conta', more: 'Mais', usage: 'Ver uso', topUp: 'Recarregar', + quotaTitle: 'Nenhum saldo disponível', + quotaDescription: 'DeepSeek Harness não pode iniciar uma nova tarefa com esta conta quando não houver saldo disponível. Você gostaria de recarregar? Você também pode recarregar mais tarde em Configurações → Conta.', + quotaTopUp: 'Recarregar', + bonusNoticeTitle: 'Bônus creditado', +} satisfies Record diff --git a/packages/client/ui-settings-account/src/client/locales/onboarding.ts b/packages/client/ui-settings-account/src/client/locales/onboarding.ts index 977837e933..2fbf063a28 100644 --- a/packages/client/ui-settings-account/src/client/locales/onboarding.ts +++ b/packages/client/ui-settings-account/src/client/locales/onboarding.ts @@ -126,3 +126,218 @@ export const onboardingJa = { 'onboardingRetry': '再試行', 'onboardingLoading': '設定を読み込んでいます…', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const onboardingEs = { + onboardingArtworkLocale: 'en', + onboardingWelcome: 'Bienvenido a', + onboardingBrand: 'DeepSeek Harness', + onboardingIntroduction: 'DeepSeek Harness funciona en una carpeta local y utiliza herramientas para leer y escribir archivos en su computadora. Puede ayudarle a investigar y organizar información, crear documentos y hojas de cálculo, escribir código, solucionar problemas y más.', + onboardingStart: 'empezar', + onboardingCredit: 'Añadir créditos', + onboardingCreditDescription: 'DeepSeek Harness cobra créditos en función de los tokens utilizados por los modelos y herramientas. Agregue créditos por adelantado para mantener sus tareas ejecutándose sin interrupciones. Su saldo solo se utiliza mientras el agente está trabajando en una tarea.', + onboardingTopUp: 'Añadir créditos', + onboardingLater: 'Siguiente', + onboardingFundedTopUp: 'Añadir créditos', + onboardingPurposePrefix: '¿En qué quieres que ', + onboardingPurposeSuffix: ' te ayude?', + onboardingPurposeDescription: 'Adaptaremos la interfaz y las herramientas para que se adapten a su forma de trabajar.', + onboardingOffice: 'Oficina y trabajo creativo', + onboardingOfficeDescription: 'Edite documentos, organice datos, cree presentaciones y más', + onboardingDevelopment: 'Codificación y desarrollo', + onboardingDevelopmentDescription: 'Edite código, depure problemas, ejecute comandos, administre archivos de proyectos y más', + onboardingContinue: 'Continuar', + onboardingProcess: '¿Cuántos detalles te gustaría ver?', + onboardingProcessDescription: 'Esto solo cambia cómo se muestra el progreso, no lo que puede hacer DeepSeek Harness.', + onboardingCompact: 'Sólo resultados', + onboardingCompactDescription: 'Vea solo los resultados en una interfaz limpia y sencilla', + onboardingStandard: 'Detalles clave', + onboardingStandardDescription: 'Centrarse en los resultados, mostrando solo los pasos y acciones más importantes.', + onboardingDetailed: 'Detalles completos', + onboardingDetailedDescription: 'Vea el proceso completo para facilitar la depuración y la resolución de problemas', + onboardingEnter: 'Abrir aplicación', + onboardingBack: 'Atrás', + onboardingSkip: 'Saltar', + onboardingSkipTitle: '¿Saltar configuración?', + onboardingSkipDescription: 'Puede cambiar cómo se muestran el progreso, el rendimiento y el uso, o habilitar las herramientas de codificación, en cualquier momento en Configuración → General.', + onboardingKeepSetting: 'Continuar con la configuración', + onboardingNoCreditTitle: '¿Omitir agregar créditos?', + onboardingNoCreditDescription: 'DeepSeek Harness no puede iniciar nuevas tareas sin créditos. Puede agregarlos más tarde en Configuración → Cuenta.', + onboardingUnderstood: 'Lo tengo', + onboardingGoTopUp: 'Añadir créditos', + onboardingSaveFailed: 'No se pudo guardar la configuración. Intentar otra vez.', + onboardingRetry: 'Reintentar', + onboardingLoading: 'Cargando configuración…', +} satisfies typeof onboardingEn + +/** French dictionary, checked against the English keys. */ +export const onboardingFr = { + onboardingArtworkLocale: 'en', + onboardingWelcome: 'Bienvenue à', + onboardingBrand: 'DeepSeek Harness', + onboardingIntroduction: 'DeepSeek Harness fonctionne dans un dossier local et utilise des outils pour lire et écrire des fichiers sur votre ordinateur. Il peut vous aider à rechercher et à organiser des informations, à créer des documents et des feuilles de calcul, à écrire du code, à résoudre des problèmes, etc.', + onboardingStart: 'Commencez', + onboardingCredit: 'Ajouter des crédits', + onboardingCreditDescription: "DeepSeek Harness facture des crédits en fonction des jetons utilisés par les modèles et les outils. Ajoutez des crédits à l'avance pour que vos tâches continuent de s'exécuter sans interruption. Votre solde n'est utilisé que lorsque l'agent travaille sur une tâche.", + onboardingTopUp: 'Ajouter des crédits', + onboardingLater: 'Suivant', + onboardingFundedTopUp: 'Ajouter des crédits', + onboardingPurposePrefix: 'Que souhaitez-vous que ', + onboardingPurposeSuffix: ' fasse pour vous ?', + onboardingPurposeDescription: 'Nous adapterons l’interface et les outils à votre façon de travailler.', + onboardingOffice: 'Bureau et travail créatif', + onboardingOfficeDescription: 'Modifiez des documents, organisez des données, créez des présentations et bien plus encore', + onboardingDevelopment: 'Codage et développement', + onboardingDevelopmentDescription: 'Modifiez le code, déboguez les problèmes, exécutez des commandes, gérez les fichiers de projet, etc.', + onboardingContinue: 'Continuer', + onboardingProcess: 'Combien de détails aimeriez-vous voir ?', + onboardingProcessDescription: 'Cela change uniquement la façon dont la progression est affichée, pas ce que DeepSeek Harness peut faire.', + onboardingCompact: 'Résultats uniquement', + onboardingCompactDescription: 'Visualisez uniquement les résultats dans une interface claire et simple', + onboardingStandard: 'Détails clés', + onboardingStandardDescription: 'Concentrez-vous sur les résultats, en affichant uniquement les étapes et actions les plus importantes.', + onboardingDetailed: 'Tous les détails', + onboardingDetailedDescription: 'Consultez le processus complet pour faciliter le débogage et le dépannage', + onboardingEnter: "Ouvrir l'application", + onboardingBack: 'Retour', + onboardingSkip: 'Sauter', + onboardingSkipTitle: 'Ignorer la configuration ?', + onboardingSkipDescription: "Vous pouvez modifier la façon dont la progression, les performances et l'utilisation sont affichées, ou activer les outils de codage, à tout moment dans Paramètres → Général.", + onboardingKeepSetting: 'Continuer la configuration', + onboardingNoCreditTitle: "Ignorer l'ajout de crédits ?", + onboardingNoCreditDescription: 'DeepSeek Harness ne peut pas démarrer de nouvelles tâches sans crédits. Vous pourrez les ajouter plus tard dans Paramètres → Compte.', + onboardingUnderstood: "Je l'ai compris", + onboardingGoTopUp: 'Ajouter des crédits', + onboardingSaveFailed: "Impossible d'enregistrer les paramètres. Essayer à nouveau.", + onboardingRetry: 'Réessayer', + onboardingLoading: 'Chargement des paramètres…', +} satisfies typeof onboardingEn + +/** German dictionary, checked against the English keys. */ +export const onboardingDe = { + onboardingArtworkLocale: 'en', + onboardingWelcome: 'Willkommen bei', + onboardingBrand: 'DeepSeek Harness', + onboardingIntroduction: 'DeepSeek Harness arbeitet in einem lokalen Ordner und verwendet Tools zum Lesen und Schreiben von Dateien auf Ihrem Computer. Es kann Ihnen dabei helfen, Informationen zu recherchieren und zu organisieren, Dokumente und Tabellenkalkulationen zu erstellen, Code zu schreiben, Probleme zu beheben und vieles mehr.', + onboardingStart: 'Fangen Sie an', + onboardingCredit: 'Credits hinzufügen', + onboardingCreditDescription: 'DeepSeek Harness berechnet Credits basierend auf den von Modellen und Tools verwendeten Token. Fügen Sie Credits im Voraus hinzu, damit Ihre Aufgaben ohne Unterbrechung ausgeführt werden können. Ihr Guthaben wird nur verwendet, während der Agent an einer Aufgabe arbeitet.', + onboardingTopUp: 'Credits hinzufügen', + onboardingLater: 'Weiter', + onboardingFundedTopUp: 'Credits hinzufügen', + onboardingPurposePrefix: 'Wobei soll ', + onboardingPurposeSuffix: ' Ihnen helfen?', + onboardingPurposeDescription: 'Wir passen die Benutzeroberfläche und die Tools an Ihre Arbeitsweise an.', + onboardingOffice: 'Büro & kreative Arbeit', + onboardingOfficeDescription: 'Bearbeiten Sie Dokumente, organisieren Sie Daten, erstellen Sie Präsentationen und mehr', + onboardingDevelopment: 'Codierung und Entwicklung', + onboardingDevelopmentDescription: 'Bearbeiten Sie Code, debuggen Sie Probleme, führen Sie Befehle aus, verwalten Sie Projektdateien und mehr', + onboardingContinue: 'Weiter', + onboardingProcess: 'Wie viele Details möchten Sie sehen?', + onboardingProcessDescription: 'Dies ändert nur die Art und Weise, wie der Fortschritt angezeigt wird, nicht jedoch, was DeepSeek Harness tun kann.', + onboardingCompact: 'Nur Ergebnisse', + onboardingCompactDescription: 'Sehen Sie nur die Ergebnisse in einer übersichtlichen, einfachen Benutzeroberfläche', + onboardingStandard: 'Wichtige Details', + onboardingStandardDescription: 'Konzentrieren Sie sich auf die Ergebnisse und zeigen Sie nur die wichtigsten Schritte und Aktionen', + onboardingDetailed: 'Ausführliche Informationen', + onboardingDetailedDescription: 'Sehen Sie sich den vollständigen Prozess an, um das Debuggen und die Fehlerbehebung zu vereinfachen', + onboardingEnter: 'App öffnen', + onboardingBack: 'Zurück', + onboardingSkip: 'Überspringen', + onboardingSkipTitle: 'Einrichtung überspringen?', + onboardingSkipDescription: 'Sie können jederzeit unter Einstellungen → Allgemein ändern, wie Fortschritt, Leistung und Nutzung angezeigt werden, oder Codierungstools aktivieren.', + onboardingKeepSetting: 'Setzen Sie die Einrichtung fort', + onboardingNoCreditTitle: 'Hinzufügen von Credits überspringen?', + onboardingNoCreditDescription: 'DeepSeek Harness kann ohne Credits keine neuen Aufgaben starten. Sie können sie später unter Einstellungen → Konto hinzufügen.', + onboardingUnderstood: 'Verstanden', + onboardingGoTopUp: 'Credits hinzufügen', + onboardingSaveFailed: 'Die Einstellungen konnten nicht gespeichert werden. Versuchen Sie es erneut.', + onboardingRetry: 'Erneut versuchen', + onboardingLoading: 'Einstellungen werden geladen…', +} satisfies typeof onboardingEn + +/** Russian dictionary, checked against the English keys. */ +export const onboardingRu = { + onboardingArtworkLocale: 'en', + onboardingWelcome: 'Добро пожаловать в', + onboardingBrand: 'DeepSeek Harness', + onboardingIntroduction: 'DeepSeek Harness работает в локальной папке и использует инструменты для чтения и записи файлов на вашем компьютере. Он может помочь вам исследовать и систематизировать информацию, создавать документы и таблицы, писать код, устранять неполадки и многое другое.', + onboardingStart: 'Начать', + onboardingCredit: 'Добавить кредиты', + onboardingCreditDescription: 'DeepSeek Harness взимает кредиты на основе токенов, используемых моделями и инструментами. Добавляйте кредиты заранее, чтобы ваши задачи выполнялись без перебоев. Ваш баланс используется только пока агент работает над задачей.', + onboardingTopUp: 'Добавить кредиты', + onboardingLater: 'Далее', + onboardingFundedTopUp: 'Добавить кредиты', + onboardingPurposePrefix: 'С чем ', + onboardingPurposeSuffix: ' должен вам помочь?', + onboardingPurposeDescription: 'Мы адаптируем интерфейс и инструменты под ваш стиль работы.', + onboardingOffice: 'Офис и творческая работа', + onboardingOfficeDescription: 'Редактируйте документы, систематизируйте данные, создавайте презентации и многое другое.', + onboardingDevelopment: 'Кодирование и разработка', + onboardingDevelopmentDescription: 'Редактируйте код, устраняйте проблемы, запускайте команды, управляйте файлами проекта и многое другое.', + onboardingContinue: 'Продолжить', + onboardingProcess: 'Насколько подробно показывать процесс работы?', + onboardingProcessDescription: 'Это меняет только способ отображения прогресса, а не возможности DeepSeek Harness.', + onboardingCompact: 'Только результаты', + onboardingCompactDescription: 'Смотрите только результаты в понятном и простом интерфейсе', + onboardingStandard: 'Ключевые детали', + onboardingStandardDescription: 'Сосредоточьтесь на результатах, показывая только самые важные шаги и действия.', + onboardingDetailed: 'Полная информация', + onboardingDetailedDescription: 'Ознакомьтесь с полным процессом для упрощения отладки и устранения неполадок.', + onboardingEnter: 'Открыть приложение', + onboardingBack: 'Назад', + onboardingSkip: 'Пропустить', + onboardingSkipTitle: 'Пропустить настройку?', + onboardingSkipDescription: 'Вы можете изменить способ отображения прогресса, производительности и использования или включить инструменты программирования в любое время в «Настройки» → «Основные».', + onboardingKeepSetting: 'Продолжить настройку', + onboardingNoCreditTitle: 'Пропустить добавление кредитов?', + onboardingNoCreditDescription: 'DeepSeek Harness не может начинать новые задачи без кредитов. Вы можете добавить их позже в «Настройки» → «Аккаунт».', + onboardingUnderstood: 'понял', + onboardingGoTopUp: 'Добавить кредиты', + onboardingSaveFailed: 'Не удалось сохранить настройки. Попробуйте еще раз.', + onboardingRetry: 'Повторить', + onboardingLoading: 'Загрузка настроек…', +} satisfies typeof onboardingEn + +/** Portuguese dictionary, checked against the English keys. */ +export const onboardingPt = { + onboardingArtworkLocale: 'en', + onboardingWelcome: 'Bem-vindo ao', + onboardingBrand: 'DeepSeek Harness', + onboardingIntroduction: 'DeepSeek Harness funciona em uma pasta local e usa ferramentas para ler e gravar arquivos no seu computador. Ele pode ajudá-lo a pesquisar e organizar informações, criar documentos e planilhas, escrever códigos, solucionar problemas e muito mais.', + onboardingStart: 'Comece', + onboardingCredit: 'Adicionar créditos', + onboardingCreditDescription: 'DeepSeek Harness cobra créditos com base nos tokens usados pelos modelos e ferramentas. Adicione créditos antecipadamente para manter suas tarefas funcionando sem interrupção. Seu saldo só é usado enquanto o agente está trabalhando em uma tarefa.', + onboardingTopUp: 'Adicionar créditos', + onboardingLater: 'Próximo', + onboardingFundedTopUp: 'Adicionar créditos', + onboardingPurposePrefix: 'Em que você quer que ', + onboardingPurposeSuffix: ' ajude?', + onboardingPurposeDescription: 'Adaptaremos a interface e as ferramentas à sua maneira de trabalhar.', + onboardingOffice: 'Escritório e trabalho criativo', + onboardingOfficeDescription: 'Edite documentos, organize dados, crie apresentações e muito mais', + onboardingDevelopment: 'Codificação e desenvolvimento', + onboardingDevelopmentDescription: 'Edite código, depure problemas, execute comandos, gerencie arquivos de projeto e muito mais', + onboardingContinue: 'Continuar', + onboardingProcess: 'Quantos detalhes você gostaria de ver?', + onboardingProcessDescription: 'Isso altera apenas a forma como o progresso é mostrado, e não o que DeepSeek Harness pode fazer.', + onboardingCompact: 'Somente resultados', + onboardingCompactDescription: 'Veja apenas os resultados em uma interface limpa e simples', + onboardingStandard: 'Detalhes principais', + onboardingStandardDescription: 'Foco nos resultados, mostrando apenas as etapas e ações mais importantes', + onboardingDetailed: 'Detalhes completos', + onboardingDetailedDescription: 'Veja o processo completo para depuração e solução de problemas mais fáceis', + onboardingEnter: 'Abrir aplicativo', + onboardingBack: 'Voltar', + onboardingSkip: 'Pular', + onboardingSkipTitle: 'Ignorar configuração?', + onboardingSkipDescription: 'Você pode alterar a forma como o progresso, o desempenho e o uso são exibidos ou ativar as ferramentas de codificação a qualquer momento em Configurações → Geral.', + onboardingKeepSetting: 'Continuar configuração', + onboardingNoCreditTitle: 'Pular a adição de créditos?', + onboardingNoCreditDescription: 'DeepSeek Harness não pode iniciar novas tarefas sem créditos. Você pode adicioná-los posteriormente em Configurações → Conta.', + onboardingUnderstood: 'Entendi', + onboardingGoTopUp: 'Adicionar créditos', + onboardingSaveFailed: 'Não foi possível salvar as configurações. Tente novamente.', + onboardingRetry: 'Tentar novamente', + onboardingLoading: 'Carregando configurações…', +} satisfies typeof onboardingEn diff --git a/packages/client/ui-settings-agent-loop/locale/de.json b/packages/client/ui-settings-agent-loop/locale/de.json new file mode 100644 index 0000000000..10d2a14a6b --- /dev/null +++ b/packages/client/ui-settings-agent-loop/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Einstellungen für die Ausführung des Agenten", + "description": "Konfigurieren Sie die maximale Anzahl an Werkzeugaufrufen, die gleichzeitig ausgeführt werden können." + } +} diff --git a/packages/client/ui-settings-agent-loop/locale/es.json b/packages/client/ui-settings-agent-loop/locale/es.json new file mode 100644 index 0000000000..816970df3b --- /dev/null +++ b/packages/client/ui-settings-agent-loop/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Configuración de ejecución del agente", + "description": "Configure el número máximo de llamadas a herramientas que se pueden ejecutar simultáneamente." + } +} diff --git a/packages/client/ui-settings-agent-loop/locale/fr.json b/packages/client/ui-settings-agent-loop/locale/fr.json new file mode 100644 index 0000000000..0ac781ec2b --- /dev/null +++ b/packages/client/ui-settings-agent-loop/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Paramètres d'exécution de l'agent", + "description": "Configurez le nombre maximum d'appels d'outils pouvant être exécutés simultanément." + } +} diff --git a/packages/client/ui-settings-agent-loop/locale/pt.json b/packages/client/ui-settings-agent-loop/locale/pt.json new file mode 100644 index 0000000000..72655d1257 --- /dev/null +++ b/packages/client/ui-settings-agent-loop/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Configurações de execução do agente", + "description": "Configure o número máximo de chamadas de ferramenta que podem ser executadas simultaneamente." + } +} diff --git a/packages/client/ui-settings-agent-loop/locale/ru.json b/packages/client/ui-settings-agent-loop/locale/ru.json new file mode 100644 index 0000000000..d07509407c --- /dev/null +++ b/packages/client/ui-settings-agent-loop/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Настройки запуска агента", + "description": "Настройте максимальное количество вызовов инструментов, которые могут выполняться одновременно." + } +} diff --git a/packages/client/ui-settings-agent-loop/src/client/index.ts b/packages/client/ui-settings-agent-loop/src/client/index.ts index 29ebe0e132..1e5e796bc3 100644 --- a/packages/client/ui-settings-agent-loop/src/client/index.ts +++ b/packages/client/ui-settings-agent-loop/src/client/index.ts @@ -16,7 +16,7 @@ import type {} from '@deepseek-ai/dsh-client-ui-renderer/client' import type { Context as ClientContext } from '@deepseek-ai/cordis' import { AgentLoopCard } from './AgentLoopCard.tsx' import { AGENT_LOOP_NS, AgentLoopCardController } from './agent-loop-card-controller.ts' -import { en, ja, zh, type AgentLoopSettingsLocaleKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh, type AgentLoopSettingsLocaleKey } from './locales.ts' export type { AgentLoopCardProps } from './AgentLoopCard.tsx' export type { AgentLoopCardFace, AgentLoopCardState, AgentLoopSettings } from './agent-loop-card-controller.ts' @@ -40,8 +40,8 @@ export const inject = ['slots', 'locale', 'configForms'] * @param ctx - the browser plugin context. */ export function apply(ctx: ClientContext): void { + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-settings-agent-loop: dictionaries') const t = ctx.locale.bind(NS) - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-settings-agent-loop: dictionaries') const card = new AgentLoopCardController(ctx.configForms.get(AGENT_LOOP_NS)) ctx.effect(() => () => { card.dispose() }, 'ui-settings-agent-loop: form subscription') ctx.effect(() => ctx.configForms.whileServed([AGENT_LOOP_NS], () => ctx.slots.inject('plugins.item', () => ctx.slots.register({ diff --git a/packages/client/ui-settings-agent-loop/src/client/locales.ts b/packages/client/ui-settings-agent-loop/src/client/locales.ts index e00a191c35..40b097d049 100644 --- a/packages/client/ui-settings-agent-loop/src/client/locales.ts +++ b/packages/client/ui-settings-agent-loop/src/client/locales.ts @@ -64,3 +64,83 @@ export const ja = { 'saveFailed': 'デプロイがこれらの値を受け付けませんでした。修正のために残されています。', 'invalidNumber': '数値を入力するか、空欄のままにするとデフォルトが使用されます。', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + title: 'Bucle de agente', + description: 'Controle cómo el Agente distribuye las llamadas a la herramienta.', + maxParallel: 'Llamadas a herramientas paralelas', + maxParallelHint: 'Límite superior de llamadas seguras en paralelo que se ejecutan al mismo tiempo en un solo paso.', + overridden: 'Anulado', + reset: 'Restablecer los valores predeterminados', + readOnly: 'Esta implementación almacena configuraciones de solo lectura.', + unavailable: 'Este complemento no está cargado, por lo que no se puede configurar en este momento.', + save: 'Guardar', + saving: 'Guardando…', + saveFailed: 'El despliegue no aceptó estos valores; quedaron para que usted los corrigiera.', + invalidNumber: 'Ingrese un número o déjelo en blanco para usar el valor predeterminado.', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + title: "Boucle d'agent", + description: "Contrôlez la manière dont l'agent distribue les appels d'outil.", + maxParallel: "Appels d'outils parallèles", + maxParallelHint: 'Limite supérieure des appels parallèles sécurisés exécutés simultanément en une seule étape.', + overridden: 'Remplacé', + reset: 'Réinitialiser aux valeurs par défaut', + readOnly: 'Ce déploiement stocke les paramètres en lecture seule.', + unavailable: "Ce plugin n'est pas chargé, il ne peut donc pas être configuré pour le moment.", + save: 'Enregistrer', + saving: 'Sauvegarde…', + saveFailed: "Le déploiement n'a pas accepté ces valeurs ; ils vous ont été laissés à corriger.", + invalidNumber: 'Entrez un numéro ou laissez ce champ vide pour utiliser la valeur par défaut.', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + title: 'Agentenschleife', + description: 'Steuern Sie, wie der Agent Toolaufrufe verteilt.', + maxParallel: 'Parallele Werkzeugaufrufe', + maxParallelHint: 'Obergrenze für parallelsichere Aufrufe, die gleichzeitig innerhalb eines Schritts ausgeführt werden.', + overridden: 'Überschrieben', + reset: 'Auf Standard zurücksetzen', + readOnly: 'Diese Bereitstellung speichert Einstellungen schreibgeschützt.', + unavailable: 'Dieses Plugin ist nicht geladen und kann daher derzeit nicht konfiguriert werden.', + save: 'Speichern', + saving: 'Sparen…', + saveFailed: 'Die Bereitstellung hat diese Werte nicht akzeptiert. Sie mussten sie korrigieren.', + invalidNumber: 'Geben Sie eine Zahl ein oder lassen Sie das Feld leer, um den Standardwert zu verwenden.', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + title: 'Цикл агента', + description: 'Управляйте тем, как агент распределяет вызовы инструментов.', + maxParallel: 'Параллельные вызовы инструментов', + maxParallelHint: 'Верхняя граница параллельных безопасных вызовов, выполняемых одновременно в течение одного шага.', + overridden: 'Переопределено', + reset: 'Сбросить настройки по умолчанию', + readOnly: 'В этом развертывании параметры сохраняются только для чтения.', + unavailable: 'Этот плагин не загружен, поэтому его невозможно настроить прямо сейчас.', + save: 'Сохранить', + saving: 'Сохранение…', + saveFailed: 'Развертывание не приняло эти значения; их оставили вам на исправление.', + invalidNumber: 'Введите число или оставьте поле пустым, чтобы использовать значение по умолчанию.', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + title: 'Loop de agente', + description: 'Controle como o Agente despacha chamadas de ferramenta.', + maxParallel: 'Chamadas de ferramentas paralelas', + maxParallelHint: 'Limite superior em chamadas paralelas seguras executadas ao mesmo tempo em uma etapa.', + overridden: 'Substituído', + reset: 'Redefinir para o padrão', + readOnly: 'Esta implantação armazena configurações somente leitura.', + unavailable: 'Este plugin não está carregado, portanto não pode ser configurado agora.', + save: 'Salvar', + saving: 'Salvando…', + saveFailed: 'A implantação não aceitou esses valores; eles foram deixados para você corrigir.', + invalidNumber: 'Insira um número ou deixe em branco para usar o padrão.', +} satisfies Record diff --git a/packages/client/ui-settings-general/locale/de.json b/packages/client/ui-settings-general/locale/de.json new file mode 100644 index 0000000000..e2d9ba29cd --- /dev/null +++ b/packages/client/ui-settings-general/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Allgemeine Einstellungen und Willkommenstipps", + "description": "Bietet allgemeine Einstellungen, Einstellungsfenster zum Verfassen von Texten und Tipps für die erstmalige Verwendung." + } +} diff --git a/packages/client/ui-settings-general/locale/es.json b/packages/client/ui-settings-general/locale/es.json new file mode 100644 index 0000000000..2910fb258d --- /dev/null +++ b/packages/client/ui-settings-general/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Configuración general y consejos de bienvenida", + "description": "Proporciona configuraciones generales, configuración de redacción de ventanas y consejos para el primer uso." + } +} diff --git a/packages/client/ui-settings-general/locale/fr.json b/packages/client/ui-settings-general/locale/fr.json new file mode 100644 index 0000000000..7114398623 --- /dev/null +++ b/packages/client/ui-settings-general/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Paramètres généraux et conseils de bienvenue", + "description": "Fournit des paramètres généraux, la configuration de la rédaction de la fenêtre et des conseils pour la première utilisation." + } +} diff --git a/packages/client/ui-settings-general/locale/pt.json b/packages/client/ui-settings-general/locale/pt.json new file mode 100644 index 0000000000..2ab4067b6f --- /dev/null +++ b/packages/client/ui-settings-general/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Configurações gerais e dicas de boas-vindas", + "description": "Fornece configurações gerais, configuração de direitos autorais de janela e dicas de uso pela primeira vez." + } +} diff --git a/packages/client/ui-settings-general/locale/ru.json b/packages/client/ui-settings-general/locale/ru.json new file mode 100644 index 0000000000..8755a8fd82 --- /dev/null +++ b/packages/client/ui-settings-general/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Общие настройки и приветственные советы", + "description": "Содержит общие настройки, настройки окна копирайтинга и советы по первому использованию." + } +} diff --git a/packages/client/ui-settings-general/src/client/index.ts b/packages/client/ui-settings-general/src/client/index.ts index 180df12f10..0d85892813 100644 --- a/packages/client/ui-settings-general/src/client/index.ts +++ b/packages/client/ui-settings-general/src/client/index.ts @@ -44,7 +44,7 @@ import { SettingsDocumentAction } from './SettingsDocumentAction.tsx' import type { SettingsDocumentActionInjected } from './SettingsDocumentAction.tsx' import { SettingsDocumentStore } from './settings-document-store.ts' import { HostReleasePrompt, type HostReleasePromptInjected } from './HostReleasePrompt.tsx' -import { en, ja, zh, type SettingsKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh, type SettingsKey } from './locales.ts' export type { CloseLabelProps, HeaderContentProps, TriggerContentProps, @@ -99,7 +99,7 @@ export function apply(ctx: ClientContext): void { ctx.slots.inject('settings.general.item', () => ctx.slots.register({ name: 'settings.general.item', id: 'current-version', order: 100, locale: NS, }, CurrentVersionRow)) - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-settings-general: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-settings-general: dictionaries') const connection = ctx.get('connection') as ConnectionHandle const carrier = (globalThis as typeof globalThis & { dshDesktop?: { protocolVersion: number; updates?: DesktopUpdateBridge } }).dshDesktop const desktopUpdate = new DesktopUpdateSource(carrier?.protocolVersion === 1 ? carrier.updates : undefined) diff --git a/packages/client/ui-settings-general/src/client/locales.ts b/packages/client/ui-settings-general/src/client/locales.ts index 8fddbcf24a..4b73f96a49 100644 --- a/packages/client/ui-settings-general/src/client/locales.ts +++ b/packages/client/ui-settings-general/src/client/locales.ts @@ -140,3 +140,233 @@ export const ja = { 'hostRelease.reload': '再読み込みして新しいバージョンを読み込む', 'hostRelease.later': '後で', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'trigger': 'Configuración', + 'shortcut.open': 'Abrir configuración', + 'desktop.update.available': 'Actualizar', + 'desktop.update.checking': 'Buscando actualizaciones...', + 'desktop.update.progress': '{percent}%', + 'desktop.update.verifying': 'Verificando archivos de actualización...', + 'desktop.update.installing': 'Preparándose para reiniciar…', + 'desktop.update.ready': 'Instalar y reiniciar', + 'desktop.update.retry': 'Reintentar actualización', + 'desktop.update.versionDetail': '{label}: {version}', + 'desktop.update.downloadDetail': 'Descargando la actualización: {percent}%\nVersión de destino: {version}', + 'desktop.update.checkFailed': 'No se pudo buscar actualizaciones. Inténtelo de nuevo más tarde.', + 'desktop.update.downloadFailed': 'No se pudo descargar la actualización. Por favor inténtalo de nuevo.', + 'desktop.update.installFailed': 'No se pudo instalar la actualización. Inténtelo de nuevo más tarde.', + 'desktop.update.checkNetworkFailed': 'No se pudo buscar actualizaciones. Comprueba tu conexión y vuelve a intentarlo.', + 'desktop.update.downloadNetworkFailed': 'No se pudo descargar la actualización. Comprueba tu conexión y vuelve a intentarlo.', + 'desktop.update.installNetworkFailed': 'No se pudo instalar la actualización. Comprueba tu conexión y vuelve a intentarlo.', + 'desktop.update.fullscreenTimeout': 'No se pudo salir de la pantalla completa. Salga de la pantalla completa y luego vuelva a intentar la actualización.', + 'desktop.update.stopFailed': 'No se pudieron detener las tareas de forma segura. La actualización no se ha instalado. Inténtelo de nuevo más tarde.', + 'desktop.update.tasksChanged': 'Han comenzado nuevas tareas. Confirme nuevamente para detener las tareas y actualizar.', + 'desktop.update.tasksUnavailable': 'El estado de la tarea no está disponible. Intente actualizar nuevamente cuando el espacio de trabajo esté listo.', + 'title': 'Configuración', + 'close': 'Cerrar', + 'openDocument': 'Abrir archivo de configuración', + 'openDocument.error': 'No se pudo abrir el archivo de configuración', + 'general.nav': 'General', + 'general.currentVersion': 'Versión actual: {version}', + 'developerTools.title': 'Mostrar vista de codificación', + 'developerTools.error': 'No se pudo guardar. Por favor inténtalo de nuevo.', + 'developerTools.description': 'Muestra la trayectoria, las diferencias de código y todos los ajustes preestablecidos del agente.', + 'connection.error': 'desconectado', + 'connection.connecting': 'Reconectando', + 'connection.connected': 'Conectado', + 'connection.reconnect': 'Desconectado, vuelve a conectarte ahora', + 'connection.restart': 'Reconectándonos, reconectándonos ahora', + 'hostRelease.title': 'La versión del servicio cambió', + 'hostRelease.description': 'La versión del servicio cambió. Esta página detuvo las actualizaciones en vivo; recargar para cargar la nueva versión.', + 'hostRelease.service': 'Servicio', + 'hostRelease.page': 'Página', + 'hostRelease.unknown': 'Desconocido', + 'hostRelease.reload': 'Recargar para cargar la nueva versión.', + 'hostRelease.later': 'Ahora no', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'trigger': 'Paramètres', + 'shortcut.open': 'Ouvrir les paramètres', + 'desktop.update.available': 'Mise à jour', + 'desktop.update.checking': 'Vérification des mises à jour…', + 'desktop.update.progress': '{percent}%', + 'desktop.update.verifying': 'Vérification des fichiers de mise à jour…', + 'desktop.update.installing': 'Préparation du redémarrage…', + 'desktop.update.ready': 'Installer et redémarrer', + 'desktop.update.retry': 'Réessayez la mise à jour', + 'desktop.update.versionDetail': '{label} : {version}', + 'desktop.update.downloadDetail': 'Téléchargement de la mise à jour : {percent}%\nVersion cible : {version}', + 'desktop.update.checkFailed': 'Impossible de vérifier les mises à jour. Veuillez réessayer plus tard.', + 'desktop.update.downloadFailed': 'Impossible de télécharger la mise à jour. Veuillez réessayer.', + 'desktop.update.installFailed': "Impossible d'installer la mise à jour. Veuillez réessayer plus tard.", + 'desktop.update.checkNetworkFailed': 'Impossible de vérifier les mises à jour. Vérifiez votre connexion et réessayez.', + 'desktop.update.downloadNetworkFailed': 'Impossible de télécharger la mise à jour. Vérifiez votre connexion et réessayez.', + 'desktop.update.installNetworkFailed': "Impossible d'installer la mise à jour. Vérifiez votre connexion et réessayez.", + 'desktop.update.fullscreenTimeout': 'Impossible de quitter le mode plein écran. Quittez le mode plein écran, puis réessayez la mise à jour.', + 'desktop.update.stopFailed': "Impossible d'arrêter les tâches en toute sécurité. La mise à jour n'a pas été installée. Veuillez réessayer plus tard.", + 'desktop.update.tasksChanged': 'De nouvelles tâches ont commencé. Confirmez à nouveau pour arrêter les tâches et mettre à jour.', + 'desktop.update.tasksUnavailable': "L'état de la tâche n'est pas disponible. Essayez à nouveau de mettre à jour lorsque l'espace de travail est prêt.", + 'title': 'Paramètres', + 'close': 'Fermer', + 'openDocument': 'Ouvrir le fichier de configuration', + 'openDocument.error': "Impossible d'ouvrir le fichier de configuration", + 'general.nav': 'Général', + 'general.currentVersion': 'Version actuelle : {version}', + 'developerTools.title': 'Afficher la vue de codage', + 'developerTools.error': "Impossible d'enregistrer. Veuillez réessayer.", + 'developerTools.description': "Affiche la trajectoire, les différences de code et tous les préréglages d'agent", + 'connection.error': 'Déconnecté', + 'connection.connecting': 'Reconnexion', + 'connection.connected': 'Connecté', + 'connection.reconnect': 'Déconnecté, reconnectez-vous maintenant', + 'connection.restart': 'Reconnexion, reconnectez-vous maintenant', + 'hostRelease.title': 'La version du service a été modifiée', + 'hostRelease.description': 'La version du service a changé. Cette page a suspendu les mises à jour en direct ; recharger pour charger la nouvelle version.', + 'hostRelease.service': 'Service', + 'hostRelease.page': 'Pages', + 'hostRelease.unknown': 'Inconnu', + 'hostRelease.reload': 'Recharger pour charger la nouvelle version', + 'hostRelease.later': 'Pas maintenant', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'trigger': 'Einstellungen', + 'shortcut.open': 'Einstellungen öffnen', + 'desktop.update.available': 'Aktualisieren', + 'desktop.update.checking': 'Suche nach Updates…', + 'desktop.update.progress': '{percent}%', + 'desktop.update.verifying': 'Aktualisierungsdateien werden überprüft…', + 'desktop.update.installing': 'Neustart wird vorbereitet…', + 'desktop.update.ready': 'Installieren und neu starten', + 'desktop.update.retry': 'Update erneut versuchen', + 'desktop.update.versionDetail': '{label}: {version}', + 'desktop.update.downloadDetail': 'Update wird heruntergeladen: {percent}%\nZielversion: {version}', + 'desktop.update.checkFailed': 'Es konnte nicht nach Updates gesucht werden. Bitte versuchen Sie es später noch einmal.', + 'desktop.update.downloadFailed': 'Das Update konnte nicht heruntergeladen werden. Bitte versuchen Sie es erneut.', + 'desktop.update.installFailed': 'Das Update konnte nicht installiert werden. Bitte versuchen Sie es später noch einmal.', + 'desktop.update.checkNetworkFailed': 'Es konnte nicht nach Updates gesucht werden. Überprüfen Sie Ihre Verbindung und versuchen Sie es erneut.', + 'desktop.update.downloadNetworkFailed': 'Das Update konnte nicht heruntergeladen werden. Überprüfen Sie Ihre Verbindung und versuchen Sie es erneut.', + 'desktop.update.installNetworkFailed': 'Das Update konnte nicht installiert werden. Überprüfen Sie Ihre Verbindung und versuchen Sie es erneut.', + 'desktop.update.fullscreenTimeout': 'Der Vollbildmodus konnte nicht beendet werden. Beenden Sie den Vollbildmodus und versuchen Sie dann erneut, das Update durchzuführen.', + 'desktop.update.stopFailed': 'Die Aufgaben konnten nicht sicher gestoppt werden. Das Update wurde nicht installiert. Bitte versuchen Sie es später noch einmal.', + 'desktop.update.tasksChanged': 'Neue Aufgaben haben begonnen. Bestätigen Sie erneut, um die Aufgaben zu stoppen und zu aktualisieren.', + 'desktop.update.tasksUnavailable': 'Der Aufgabenstatus ist nicht verfügbar. Versuchen Sie erneut, die Aktualisierung durchzuführen, wenn der Arbeitsbereich bereit ist.', + 'title': 'Einstellungen', + 'close': 'Schließen', + 'openDocument': 'Konfigurationsdatei öffnen', + 'openDocument.error': 'Die Konfigurationsdatei konnte nicht geöffnet werden', + 'general.nav': 'Allgemein', + 'general.currentVersion': 'Aktuelle Version: {version}', + 'developerTools.title': 'Codieransicht anzeigen', + 'developerTools.error': 'Konnte nicht gespeichert werden. Bitte versuchen Sie es erneut.', + 'developerTools.description': 'Zeigt Flugbahn, Codeunterschiede und alle Agentenvoreinstellungen an', + 'connection.error': 'Nicht verbunden', + 'connection.connecting': 'Wieder verbinden', + 'connection.connected': 'Verbunden', + 'connection.reconnect': 'Verbindung getrennt, jetzt erneut verbinden', + 'connection.restart': 'Verbindung wiederherstellen, jetzt erneut verbinden', + 'hostRelease.title': 'Dienstversion geändert', + 'hostRelease.description': 'Die Dienstversion hat sich geändert. Diese Seite hat Live-Updates angehalten. Neu laden, um die neue Version zu laden.', + 'hostRelease.service': 'Service', + 'hostRelease.page': 'Seite', + 'hostRelease.unknown': 'Unbekannt', + 'hostRelease.reload': 'Neu laden, um die neue Version zu laden', + 'hostRelease.later': 'Nicht jetzt', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'trigger': 'Настройки', + 'shortcut.open': 'Открыть настройки', + 'desktop.update.available': 'Обновить', + 'desktop.update.checking': 'Проверка обновлений…', + 'desktop.update.progress': '{percent}%', + 'desktop.update.verifying': 'Проверка файлов обновлений…', + 'desktop.update.installing': 'Подготовка к перезапуску…', + 'desktop.update.ready': 'Установить и перезапустить', + 'desktop.update.retry': 'Повторить обновление', + 'desktop.update.versionDetail': '{label}: {version}', + 'desktop.update.downloadDetail': 'Загрузка обновления: {percent}%\n Целевая версия: {version}', + 'desktop.update.checkFailed': 'Не удалось проверить наличие обновлений. Пожалуйста, повторите попытку позже.', + 'desktop.update.downloadFailed': 'Не удалось загрузить обновление. Пожалуйста, попробуйте еще раз.', + 'desktop.update.installFailed': 'Не удалось установить обновление. Пожалуйста, повторите попытку позже.', + 'desktop.update.checkNetworkFailed': 'Не удалось проверить наличие обновлений. Проверьте подключение и повторите попытку.', + 'desktop.update.downloadNetworkFailed': 'Не удалось загрузить обновление. Проверьте подключение и повторите попытку.', + 'desktop.update.installNetworkFailed': 'Не удалось установить обновление. Проверьте подключение и повторите попытку.', + 'desktop.update.fullscreenTimeout': 'Не удалось выйти из полноэкранного режима. Выйдите из полноэкранного режима и повторите попытку обновления.', + 'desktop.update.stopFailed': 'Не удалось безопасно остановить задачи. Обновление не установлено. Пожалуйста, повторите попытку позже.', + 'desktop.update.tasksChanged': 'Начались новые задачи. Подтвердите еще раз, чтобы остановить выполнение задач и выполнить обновление.', + 'desktop.update.tasksUnavailable': 'Статус задачи недоступен. Попробуйте обновить еще раз, когда рабочая область будет готова.', + 'title': 'Настройки', + 'close': 'Закрыть', + 'openDocument': 'Открыть файл конфигурации', + 'openDocument.error': 'Не удалось открыть файл конфигурации', + 'general.nav': 'Общие', + 'general.currentVersion': 'Текущая версия: {version}.', + 'developerTools.title': 'Показать представление кодирования', + 'developerTools.error': 'Не удалось сохранить. Пожалуйста, попробуйте еще раз.', + 'developerTools.description': 'Показывает траекторию, различия в коде и все настройки агента.', + 'connection.error': 'Отключено', + 'connection.connecting': 'Повторное подключение', + 'connection.connected': 'Подключено', + 'connection.reconnect': 'Соединение отключено, подключитесь снова сейчас', + 'connection.restart': 'Повторное подключение, повторное подключение сейчас', + 'hostRelease.title': 'Версия сервиса изменена', + 'hostRelease.description': 'Версия сервиса изменилась. На этой странице приостановлены текущие обновления; перезагрузите, чтобы загрузить новую версию.', + 'hostRelease.service': 'Сервис', + 'hostRelease.page': 'Страница', + 'hostRelease.unknown': 'Неизвестно', + 'hostRelease.reload': 'Перезагрузите, чтобы загрузить новую версию', + 'hostRelease.later': 'Не сейчас', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'trigger': 'Configurações', + 'shortcut.open': 'Abrir configurações', + 'desktop.update.available': 'Atualizar', + 'desktop.update.checking': 'Verificando atualizações…', + 'desktop.update.progress': '{percent}%', + 'desktop.update.verifying': 'Verificando arquivos de atualização…', + 'desktop.update.installing': 'Preparando para reiniciar…', + 'desktop.update.ready': 'Instalar e reiniciar', + 'desktop.update.retry': 'Tentar atualizar novamente', + 'desktop.update.versionDetail': '{label}: {version}', + 'desktop.update.downloadDetail': 'Fazendo download da atualização: {percent}%\nVersão de destino: {version}', + 'desktop.update.checkFailed': 'Não foi possível verificar se há atualizações. Por favor, tente novamente mais tarde.', + 'desktop.update.downloadFailed': 'Não foi possível baixar a atualização. Por favor, tente novamente.', + 'desktop.update.installFailed': 'Não foi possível instalar a atualização. Por favor, tente novamente mais tarde.', + 'desktop.update.checkNetworkFailed': 'Não foi possível verificar se há atualizações. Verifique sua conexão e tente novamente.', + 'desktop.update.downloadNetworkFailed': 'Não foi possível baixar a atualização. Verifique sua conexão e tente novamente.', + 'desktop.update.installNetworkFailed': 'Não foi possível instalar a atualização. Verifique sua conexão e tente novamente.', + 'desktop.update.fullscreenTimeout': 'Não foi possível sair da tela cheia. Saia da tela inteira e tente atualizar novamente.', + 'desktop.update.stopFailed': 'Não foi possível interromper as tarefas com segurança. A atualização não foi instalada. Por favor, tente novamente mais tarde.', + 'desktop.update.tasksChanged': 'Novas tarefas foram iniciadas. Confirme novamente para interromper as tarefas e atualizar.', + 'desktop.update.tasksUnavailable': 'O status da tarefa não está disponível. Tente atualizar novamente quando o espaço de trabalho estiver pronto.', + 'title': 'Configurações', + 'close': 'Fechar', + 'openDocument': 'Abra o arquivo de configuração', + 'openDocument.error': 'Não foi possível abrir o arquivo de configuração', + 'general.nav': 'Geral', + 'general.currentVersion': 'Versão atual: {version}', + 'developerTools.title': 'Mostrar visualização de codificação', + 'developerTools.error': 'Não foi possível salvar. Por favor, tente novamente.', + 'developerTools.description': 'Mostra trajetória, diferenças de código e todas as predefinições do agente', + 'connection.error': 'Desconectado', + 'connection.connecting': 'Reconectando', + 'connection.connected': 'Conectado', + 'connection.reconnect': 'Desconectado, reconecte agora', + 'connection.restart': 'Reconectando, reconecte agora', + 'hostRelease.title': 'Versão do serviço alterada', + 'hostRelease.description': 'A versão do serviço mudou. Esta página pausou as atualizações ao vivo; reload para carregar a nova versão.', + 'hostRelease.service': 'Serviço', + 'hostRelease.page': 'Página', + 'hostRelease.unknown': 'Desconhecido', + 'hostRelease.reload': 'Recarregue para carregar a nova versão', + 'hostRelease.later': 'Agora não', +} satisfies Record diff --git a/packages/client/ui-settings-models/locale/de.json b/packages/client/ui-settings-models/locale/de.json new file mode 100644 index 0000000000..e37303da3b --- /dev/null +++ b/packages/client/ui-settings-models/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Modelleinstellungsschnittstelle", + "description": "Verwalten Sie Modelldienste und ihre Zugriffskonfigurationen und stellen Sie relevante Anleitungen bereit." + } +} diff --git a/packages/client/ui-settings-models/locale/es.json b/packages/client/ui-settings-models/locale/es.json new file mode 100644 index 0000000000..46272e2878 --- /dev/null +++ b/packages/client/ui-settings-models/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de configuración del modelo", + "description": "Administre los servicios modelo y sus configuraciones de acceso, y proporcione orientación relevante." + } +} diff --git a/packages/client/ui-settings-models/locale/fr.json b/packages/client/ui-settings-models/locale/fr.json new file mode 100644 index 0000000000..66fe99de82 --- /dev/null +++ b/packages/client/ui-settings-models/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de configuration du modèle", + "description": "Gérez les services modèles et leurs configurations d'accès, et fournissez des conseils pertinents." + } +} diff --git a/packages/client/ui-settings-models/locale/pt.json b/packages/client/ui-settings-models/locale/pt.json new file mode 100644 index 0000000000..bcbc2971af --- /dev/null +++ b/packages/client/ui-settings-models/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de configuração de modelo", + "description": "Gerencie serviços de modelo e suas configurações de acesso e forneça orientações relevantes." + } +} diff --git a/packages/client/ui-settings-models/locale/ru.json b/packages/client/ui-settings-models/locale/ru.json new file mode 100644 index 0000000000..cb419aea1a --- /dev/null +++ b/packages/client/ui-settings-models/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Интерфейс настройки модели", + "description": "Управляйте сервисами моделей и конфигурациями доступа к ним, а также предоставляйте соответствующие рекомендации." + } +} diff --git a/packages/client/ui-settings-models/src/client/index.ts b/packages/client/ui-settings-models/src/client/index.ts index 37ad6919fe..d0b61802a5 100644 --- a/packages/client/ui-settings-models/src/client/index.ts +++ b/packages/client/ui-settings-models/src/client/index.ts @@ -26,7 +26,7 @@ import { WelcomeNoticeStore } from './welcome-store.ts' import { ModelsSettingsStore } from './store.ts' import { createModelsOperations } from './operations.ts' import { createSettingsSchemaOperations } from './schema-operations.ts' -import { en, ja, zh, type ModelsKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh, type ModelsKey } from './locales.ts' import { WELCOME_NOTICE_SETTINGS_NAMESPACE } from '../onboarding-copy.ts' import { Config, ONBOARDING_CONFIG_GLOBAL } from '../onboarding-config.ts' @@ -80,7 +80,7 @@ export function apply(ctx: ClientContext): void { const payload = page[ONBOARDING_CONFIG_GLOBAL] const configured = Config(payload === undefined ? {} : payload) const credentialOnboarding = configured.credentialOnboarding && !('dshDesktop' in globalThis) - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-settings-models: copy dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-settings-models: copy dictionaries') const schema = createSettingsSchemaOperations(ctx.settingsSchema) // Bound once here, where the Remote namespaces are declared in this plugin's diff --git a/packages/client/ui-settings-models/src/client/locales.ts b/packages/client/ui-settings-models/src/client/locales.ts index d1bf8aceb3..b17bcb3f11 100644 --- a/packages/client/ui-settings-models/src/client/locales.ts +++ b/packages/client/ui-settings-models/src/client/locales.ts @@ -425,3 +425,708 @@ export const ja = { 'onboardingSaving': '保存中…', 'keyRequired': '続けるにはAPIキーを入力してください。', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + nav: 'Modelos', + deepSeekAccount: 'Cuenta DeepSeek', + title: 'Modelos', + intro: 'Ingrese sus claves API para usar modelos de los siguientes proveedores.', + edit: 'Editar', + editProvider: 'Editar {provider}', + remove: 'Eliminar', + removeProvider: 'Eliminar {provider}', + deleteTitle: '¿Eliminar {provider}?', + deleteDescription: 'Al eliminar {provider} se elimina su configuración. Cualquier credencial que utilice se administra en otro lugar y se conservará.', + deleteDescriptionWithCredential: 'Al eliminar {provider} se elimina su configuración y la clave API almacenada.', + deleteConfirm: 'Eliminar {provider}', + deleting: 'Eliminando {provider}…', + add: 'Agregar proveedor de modelo', + addMode: 'como agregar', + addCatalog: 'Proveedor de modelos externo', + addCustom: 'Modelo personalizado API', + addCatalogHint: 'Elija OpenAI, Anthropic, Kimi u otro proveedor del catálogo integrado e ingrese su clave API.', + addCustomHint: 'Conecte un repetidor, un servidor autohospedado o cualquier otro punto final compatible con OpenAI o Anthropic mediante su URL base, protocolo y modelos.', + addCatalogExhausted: 'Cada proveedor de catálogo ya está configurado.', + addCustomUnavailable: 'No hay ningún protocolo API disponible para declarar.', + provider: 'Proveedor', + close: 'Cerrar', + cancel: 'Cancelar', + apply: 'Aplicar', + applying: 'Aplicando…', + savedProvider: 'Guardado {provider}.', + credentialConfigured: 'Clave API configurada', + credentialMissing: 'Falta la clave API', + accountSignedIn: 'Iniciado sesión', + readOnly: 'El documento de configuración es de solo lectura en esta implementación.', + loadFailed: 'Error al cargar el directorio de proveedores', + conflict: 'Alguien más cambió esta configuración mientras esta tarjeta estaba abierta. Ciérrelo y vuelva a abrirlo para editar los valores actuales.', + retry: 'Reintentar', + keyInput: 'Tecla API', + keyReveal: 'Mostrar secreto', + keyHide: 'Ocultar secreto', + keyPlaceholder: 'Ingrese su clave API', + keyPlaceholderFallback: 'Déjelo en blanco para usar env como autenticación ({hint})', + keyPlaceholderSaved: 'Déjelo en blanco para usar las credenciales guardadas', + keyFallbackMissing: 'No se detectó la variable de entorno. Ingrese una clave API o configure {hint} en su entorno.', + keyFallbackDetected: 'Se detectó var env. ({hint})', + keyFallbackDetectedHidden: 'Se detectó var env.', + keyFallbackUnchecked: 'El estado de la credencial ambiental no ha sido confirmado.', + keyHelp: 'Las credenciales guardadas se utilizan primero. Las alternativas de entorno se muestran aquí, en orden: {env}. Las fuentes son el entorno de inicio, $cwd/.env, luego $DSH_HOME/.env.', + authHelp: 'Detalles de autenticación', + customized: 'Configuraciones personalizadas', + baseUrl: 'URL base', + baseUrlDefault: 'Sin punto final predeterminado', + baseUrlEnvironment: 'Configuración del punto final del proveedor: {env}', + baseUrlConfigured: 'Punto final configurado por el proveedor', + baseUrlPlaceholder: '{url}', + deepSeekBaseUrl: 'https://api.deepseek.com/anthropic (Uso predeterminado DEEPSEEK_BASE_URL)', + deepSeekEndpointHint: 'Utilice un punto final API compatible con Anthropic Messages.', + models: 'Modelos', + modelsInherited: 'Usando los valores predeterminados del adaptador', + modelsCustomized: 'Catálogo de modelos personalizado', + resetModels: 'Restaurar valores predeterminados', + model: 'modelo', + modelId: 'ID del modelo', + modelName: 'Nombre para mostrar', + modelNamePlaceholder: 'Utiliza el ID del modelo cuando está vacío', + contextWindow: 'ventana contextual', + contextWindowPlaceholder: 'Utiliza el proveedor predeterminado', + maxTokens: 'Fichas de salida máxima', + maxTokensPlaceholder: 'Utiliza el proveedor predeterminado', + modelAdvanced: 'Opciones de modelo', + modelInputTypes: 'Tipos de entrada', + modelInputText: 'Texto', + modelInputImage: 'Imagen', + modelReasoning: 'Niveles de razonamiento', + modelReasoningLevel: 'Nivel', + modelReasoningValue: 'Valor API', + modelReasoningHelp: 'Acerca de los niveles de razonamiento', + modelReasoningHelpText: 'El valor de la API se envía en el campo de esfuerzo de razonamiento de la solicitud, como reasoning_effort de OpenAI. De forma predeterminada se usa el nombre del nivel; si la documentación de la API del proveedor del modelo especifica otro valor, úselo. Desactivado deshabilita el razonamiento y no necesita un valor; cualquier valor ya guardado en la configuración se conserva y se envía.', + modelReasoningNeedsLevel: 'Agregue al menos un nivel además de Desactivado o desactive los niveles de razonamiento.', + modelReasoningValueRequired: 'Cada nivel además de Off necesita un valor API y ningún valor puede estar vacío.', + modelReasoningAdd: 'Agregar nivel', + modelReasoningRemove: 'Eliminar nivel', + modelReasoningOffValuePlaceholder: 'Desactiva el razonamiento', + addModel: 'Agregar modelo', + removeModel: 'Eliminar modelo', + reorderModel: 'Reordenar modelo', + reorderModelHelp: 'Arrastre para reordenar o use las teclas de flecha hacia arriba y hacia abajo.', + modelsEmpty: 'No se mostrará ningún modelo en el selector. Las identificaciones que no figuran en la lista aún se pueden enviar directamente.', + keyBlank: 'Ingrese la clave API, o deje el campo vacío para conservar la almacenada.', + keyBlankNew: 'Ingrese la clave API o deje el campo vacío si este proveedor se autentica de otra manera.', + keyIllegalCharacters: 'Esta clave API no tiene un formato válido. Por favor compruébalo.', + modelIdRequired: 'Se requiere identificación del modelo.', + modelIdDuplicate: 'El ID del modelo debe ser único.', + modelNameInvalid: 'El nombre para mostrar no puede estar vacío.', + modelContextInvalid: 'La ventana de contexto debe tener un recuento positivo, como 131072, 256K o 1M.', + modelMaxTokensInvalid: 'Los tokens de salida máxima deben tener un recuento positivo, como 8192, 64K o 1M.', + advancedHint: 'Otros campos se encuentran en cordis.patch.yml; edite esa sección directamente.', + modelCapacityInvalid: 'Una capacidad debe ser un número, opcionalmente con el sufijo K o M.', + modelDuplicate: 'Cada ID de modelo puede aparecer una vez.', + fetchModels: 'Buscar modelos disponibles', + fetching: 'Preguntando al proveedor...', + fetchNeedsBaseUrl: 'Ingrese primero la URL base y luego busque.', + fetchEmpty: 'El proveedor no enumeró ningún modelo. Agréguelos a mano.', + fetchTitle: 'Elige modelos', + fetchDescription: 'Estos son los modelos que tiene disponibles este proveedor. Los modelos comprobados componen la lista.', + fetchSearch: 'Buscar modelos', + fetchNoMatches: 'No hay modelos coincidentes.', + fetchSelectAll: 'Seleccionar todo', + fetchDeselectAll: 'Deseleccionar todo', + fetchAdopt: 'Lista de actualización', + fetchKeepOne: 'Mantenga al menos un modelo controlado.', + customTag: 'personalizado', + customRoute: 'ID del proveedor', + customRouteHint: 'Identificador en minúscula, que comienza con una letra, que nombra de forma exclusiva a este proveedor en las solicitudes y como su nombre de credencial.', + customRouteInvalid: 'Comience con una letra minúscula; luego letras minúsculas, dígitos y guiones.', + customRouteTaken: 'Un proveedor ya utiliza esta identificación.', + customDisplayName: 'Nombre para mostrar', + customApi: 'Protocolo API', + customApiUnset: 'No seleccionado', + protocolOpenAiCompletions: 'Finalizaciones del chat OpenAI', + protocolOpenAiResponses: 'Respuestas de OpenAI', + protocolAnthropicMessages: 'Mensajes antrópicos', + customNeedsBaseUrl: 'Un proveedor personalizado necesita una URL base.', + customBaseUrlInvalid: 'Ingrese una URL HTTP o HTTPS válida.', + customNeedsModels: 'Un proveedor personalizado necesita al menos un modelo.', + customBaseUrlPlaceholder: 'https://gateway.example/v1', + customAnthropicBaseUrlPlaceholder: 'https://gateway.example', + settingsPathUnresolvable: 'ruta de configuración irresoluble', + create: 'Crear proveedor', + creating: 'Creando…', + welcomeTitle: 'Aviso previo', + welcomeBody: 'DeepSeek Harness 0.2 aún está en versión preliminar y muchas áreas necesitan mejoras y refinamientos continuos. Agradecemos los comentarios y sugerencias de todos los desarrolladores y usuarios. La nueva aplicación de escritorio ahora está dirigida a una amplia gama de usuarios, mientras que las funciones avanzadas relacionadas con los desarrolladores se pueden habilitar en la configuración. Se espera que las características del producto y las API de complementos de DeepSeek Harness continúen con una rápida iteración y evolución, y se estabilicen gradualmente con el tiempo.\n\nEsperamos explorar los límites de la inteligencia junto con usuarios y desarrolladores de todo el mundo, basándose en una infraestructura de código abierto, reutilizable y componible. Invitamos a todos a dar vida a sus ideas con DeepSeek Harness y participar en la comunidad para enriquecer el ecosistema de complementos.', + welcomeContinue: 'Continuar', + welcomeError: 'El reconocimiento no se pudo guardar. Por favor inténtalo de nuevo.', + onboardingTitle: 'Agregue una clave API para comenzar', + onboardingDescription: 'Configure el proveedor oficial DeepSeek para comenzar a construir.', + onboardingLater: 'Configurar más tarde', + onboardingSave: 'Guardar y continuar', + onboardingSaving: 'Guardando…', + keyRequired: 'Ingrese una clave API para continuar.', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + nav: 'Modèles', + deepSeekAccount: 'Compte DeepSeek', + title: 'Modèles', + intro: 'Entrez vos clés API pour utiliser les modèles des fournisseurs suivants.', + edit: 'Modifier', + editProvider: 'Modifier {provider}', + remove: 'Supprimer', + removeProvider: 'Supprimer {provider}', + deleteTitle: 'Supprimer {provider} ?', + deleteDescription: "La suppression de {provider} supprime sa configuration. Tout identifiant qu'il utilise est géré ailleurs et sera conservé.", + deleteDescriptionWithCredential: 'La suppression de {provider} supprime sa configuration et la clé API stockée.', + deleteConfirm: 'Supprimer {provider}', + deleting: 'Suppression de {provider}…', + add: 'Ajouter un fournisseur de modèles', + addMode: 'Comment ajouter', + addCatalog: 'Fournisseur de modèles tiers', + addCustom: 'Modèle personnalisé API', + addCatalogHint: 'Choisissez OpenAI, Anthropic, Kimi ou un autre fournisseur dans le catalogue intégré et entrez sa clé API.', + addCustomHint: 'Connectez un relais, un serveur auto-hébergé ou tout autre point de terminaison compatible OpenAI ou Anthropic par son URL de base, son protocole et ses modèles.', + addCatalogExhausted: 'Chaque fournisseur de catalogue est déjà configuré.', + addCustomUnavailable: "Aucun protocole API n'est disponible à déclarer.", + provider: 'Fournisseur', + close: 'Fermer', + cancel: 'Annuler', + apply: 'Postuler', + applying: 'Candidature…', + savedProvider: '{provider} enregistré.', + credentialConfigured: 'Clé API configurée', + credentialMissing: 'Clé API manquante', + accountSignedIn: 'Connecté', + readOnly: 'Le document de paramètres est en lecture seule dans ce déploiement.', + loadFailed: 'Le chargement du répertoire du fournisseur a échoué', + conflict: "Quelqu'un d'autre a modifié ces paramètres alors que cette carte était ouverte. Fermez-le et rouvrez-le pour modifier les valeurs actuelles.", + retry: 'Réessayer', + keyInput: 'Clé API', + keyReveal: 'Afficher le secret', + keyHide: 'Cacher le secret', + keyPlaceholder: 'Entrez votre clé API', + keyPlaceholderFallback: 'Laissez vide pour utiliser env comme authentification ({hint})', + keyPlaceholderSaved: "Laissez vide pour utiliser les informations d'identification enregistrées", + keyFallbackMissing: "Var d'environnement non détectée. Entrez une clé API ou configurez {hint} dans votre environnement.", + keyFallbackDetected: "Var d'environnement détectée. ({hint})", + keyFallbackDetectedHidden: "Var d'environnement détectée.", + keyFallbackUnchecked: 'Le statut des qualifications en environnement n’a pas été confirmé.', + keyHelp: "Les informations d'identification enregistrées sont utilisées en premier. Solutions de secours d’environnement affichées ici, dans l’ordre : {env}. Les sources sont l'environnement de lancement, $cwd/.env, puis $DSH_HOME/.env.", + authHelp: "Détails d'authentification", + customized: 'Paramètres personnalisés', + baseUrl: 'URL de base', + baseUrlDefault: 'Aucun point de terminaison par défaut', + baseUrlEnvironment: 'Configuration du point de terminaison du fournisseur : {env}', + baseUrlConfigured: 'Point de terminaison configuré par le fournisseur', + baseUrlPlaceholder: '{url}', + deepSeekBaseUrl: 'https://api.deepseek.com/anthropic (par défaut, DEEPSEEK_BASE_URL est utilisé)', + deepSeekEndpointHint: 'Utilisez un point de terminaison API compatible avec Anthropic Messages.', + models: 'Modèles', + modelsInherited: "Utilisation des valeurs par défaut de l'adaptateur", + modelsCustomized: 'Catalogue de modèles personnalisés', + resetModels: 'Restaurer les valeurs par défaut', + model: 'Modèle', + modelId: 'ID du modèle', + modelName: "Nom d'affichage", + modelNamePlaceholder: "Utilise l'ID du modèle lorsqu'il est vide", + contextWindow: 'Fenêtre contextuelle', + contextWindowPlaceholder: 'Utilise la valeur par défaut du fournisseur', + maxTokens: 'Jetons de sortie maximum', + maxTokensPlaceholder: 'Utilise la valeur par défaut du fournisseur', + modelAdvanced: 'Options de modèle', + modelInputTypes: "Types d'entrée", + modelInputText: 'Texte', + modelInputImage: 'Images', + modelReasoning: 'Niveaux de raisonnement', + modelReasoningLevel: 'Niveau', + modelReasoningValue: 'Valeur API', + modelReasoningHelp: 'À propos des niveaux de raisonnement', + modelReasoningHelpText: 'La valeur API est envoyée dans le champ d’effort de raisonnement de la requête, comme reasoning_effort chez OpenAI. Par défaut, elle correspond au nom du niveau ; si la documentation API du fournisseur du modèle indique une autre valeur, utilisez-la. Désactivé coupe le raisonnement et ne nécessite aucune valeur ; toute valeur déjà enregistrée dans la configuration est conservée et envoyée.', + modelReasoningNeedsLevel: 'Ajoutez au moins un niveau en plus de Désactivé ou désactivez les niveaux de raisonnement.', + modelReasoningValueRequired: 'Chaque niveau autre que Off nécessite une valeur API et aucune valeur ne peut être vide.', + modelReasoningAdd: 'Ajouter un niveau', + modelReasoningRemove: 'Supprimer le niveau', + modelReasoningOffValuePlaceholder: 'Désactive le raisonnement', + addModel: 'Ajouter un modèle', + removeModel: 'Supprimer le modèle', + reorderModel: 'Réorganiser le modèle', + reorderModelHelp: 'Faites glisser pour réorganiser ou utilisez les touches fléchées haut et bas.', + modelsEmpty: 'Aucun modèle ne sera affiché dans le sélecteur. Les identifiants non répertoriés peuvent toujours être envoyés directement.', + keyBlank: 'Saisissez la clé API, ou laissez le champ vide pour conserver celle stockée.', + keyBlankNew: "Saisissez la clé API ou laissez le champ vide si ce fournisseur s'authentifie d'une autre manière.", + keyIllegalCharacters: "Cette clé API n'est pas dans un format valide. Veuillez le vérifier.", + modelIdRequired: 'L’ID du modèle est requis.', + modelIdDuplicate: "L'ID du modèle doit être unique.", + modelNameInvalid: 'Le nom d’affichage ne peut pas être vide.', + modelContextInvalid: 'La fenêtre contextuelle doit être un nombre positif, comme 131072, 256 Ko ou 1 M.', + modelMaxTokensInvalid: 'Le nombre maximum de jetons de sortie doit être un nombre positif, comme 8 192, 64 Ko ou 1 M.', + advancedHint: "D'autres champs se trouvent dans cordis.patch.yml ; modifiez cette section directement.", + modelCapacityInvalid: 'Une capacité doit être un nombre, éventuellement suivi du suffixe K ou M.', + modelDuplicate: 'Chaque ID de modèle peut apparaître une fois.', + fetchModels: 'Récupérer les modèles disponibles', + fetching: 'Demander au fournisseur…', + fetchNeedsBaseUrl: "Entrez d'abord l'URL de base, puis récupérez-la.", + fetchEmpty: 'Le fournisseur n’a répertorié aucun modèle. Ajoutez-les à la main.', + fetchTitle: 'Choisir des modèles', + fetchDescription: 'Ce sont les modèles disponibles chez ce fournisseur. Les modèles cochés constituent la liste.', + fetchSearch: 'Rechercher des modèles', + fetchNoMatches: 'Aucun modèle correspondant.', + fetchSelectAll: 'Tout sélectionner', + fetchDeselectAll: 'Tout désélectionner', + fetchAdopt: 'Mettre à jour la liste', + fetchKeepOne: 'Gardez au moins un modèle coché.', + customTag: 'Personnalisé', + customRoute: 'Identifiant du fournisseur', + customRouteHint: "Identifiant minuscule, commençant par une lettre, qui nomme de manière unique ce fournisseur dans les demandes et comme nom d'identification.", + customRouteInvalid: 'Commencez par une lettre minuscule ; puis des lettres minuscules, des chiffres et des tirets.', + customRouteTaken: 'Un fournisseur utilise déjà cet identifiant.', + customDisplayName: "Nom d'affichage", + customApi: 'Protocole API', + customApiUnset: 'Non sélectionné', + protocolOpenAiCompletions: 'Achèvements du chat OpenAI', + protocolOpenAiResponses: 'Réponses OpenAI', + protocolAnthropicMessages: 'Messages anthropiques', + customNeedsBaseUrl: "Un fournisseur personnalisé a besoin d'une URL de base.", + customBaseUrlInvalid: 'Saisissez une URL HTTP ou HTTPS valide.', + customNeedsModels: "Un fournisseur personnalisé a besoin d'au moins un modèle.", + customBaseUrlPlaceholder: 'https://gateway.example/v1', + customAnthropicBaseUrlPlaceholder: 'https://gateway.example', + settingsPathUnresolvable: 'chemin des paramètres insolubles', + create: 'Créer un fournisseur', + creating: 'Création…', + welcomeTitle: "Avis d'aperçu", + welcomeBody: "DeepSeek Harness 0.2 est toujours en version préliminaire et de nombreux domaines nécessitent une amélioration et un perfectionnement continus. Nous apprécions les commentaires et suggestions de tous les développeurs et utilisateurs. La nouvelle application de bureau cible désormais un large éventail d'utilisateurs, tandis que les fonctionnalités avancées liées aux développeurs peuvent être activées dans les paramètres. Les fonctionnalités du produit et les API de plug-in de DeepSeek Harness devraient poursuivre leurs itérations et leur évolution rapides, et se stabiliseront progressivement au fil du temps. \n\nNous sommes impatients d'explorer les limites de l'intelligence avec les utilisateurs et les développeurs du monde entier, en nous appuyant sur une infrastructure open source, réutilisable et composable. Nous invitons chacun à donner vie à ses idées avec DeepSeek Harness et à participer à la communauté pour enrichir l'écosystème des plugins.", + welcomeContinue: 'Continuer', + welcomeError: "L'accusé de réception n'a pas pu être enregistré. Veuillez réessayer.", + onboardingTitle: 'Ajoutez une clé API pour commencer', + onboardingDescription: 'Configurez le fournisseur officiel DeepSeek pour commencer la construction.', + onboardingLater: 'Configurer plus tard', + onboardingSave: 'Enregistrer et continuer', + onboardingSaving: 'Sauvegarde…', + keyRequired: 'Entrez une clé API pour continuer.', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + nav: 'Modelle', + deepSeekAccount: 'DeepSeek-Konto', + title: 'Modelle', + intro: 'Geben Sie Ihre API-Schlüssel ein, um Modelle der folgenden Anbieter zu verwenden.', + edit: 'Bearbeiten', + editProvider: 'Bearbeiten Sie {provider}', + remove: 'Löschen', + removeProvider: 'Löschen Sie {provider}', + deleteTitle: '{provider} löschen?', + deleteDescription: 'Durch das Löschen von {provider} wird seine Konfiguration entfernt. Alle verwendeten Anmeldeinformationen werden an anderer Stelle verwaltet und aufbewahrt.', + deleteDescriptionWithCredential: 'Durch das Löschen von {provider} werden seine Konfiguration und der gespeicherte API-Schlüssel entfernt.', + deleteConfirm: 'Löschen Sie {provider}', + deleting: '{provider} wird gelöscht…', + add: 'Modellanbieter hinzufügen', + addMode: 'So fügen Sie hinzu', + addCatalog: 'Drittanbieter von Modellen', + addCustom: 'Kundenspezifisches Modell API', + addCatalogHint: 'Wählen Sie OpenAI, Anthropic, Kimi oder einen anderen Anbieter aus dem integrierten Katalog aus und geben Sie den Schlüssel API ein.', + addCustomHint: 'Verbinden Sie ein Relay, einen selbst gehosteten Server oder einen anderen OpenAI- oder Anthropic-kompatiblen Endpunkt über seine Basis-URL, sein Protokoll und seine Modelle.', + addCatalogExhausted: 'Jeder Kataloganbieter ist bereits konfiguriert.', + addCustomUnavailable: 'Es ist kein API-Protokoll zur Deklaration verfügbar.', + provider: 'Anbieter', + close: 'Schließen', + cancel: 'Abbrechen', + apply: 'Bewerben', + applying: 'Bewerben…', + savedProvider: 'Gespeichert {provider}.', + credentialConfigured: 'API-Schlüssel konfiguriert', + credentialMissing: 'API-Schlüssel fehlt', + accountSignedIn: 'Angemeldet', + readOnly: 'Das Einstellungsdokument ist in dieser Bereitstellung schreibgeschützt.', + loadFailed: 'Das Laden des Anbieterverzeichnisses ist fehlgeschlagen', + conflict: 'Jemand anderes hat diese Einstellungen geändert, während diese Karte geöffnet war. Schließen Sie es und öffnen Sie es erneut, um die aktuellen Werte zu bearbeiten.', + retry: 'Erneut versuchen', + keyInput: 'API-Schlüssel', + keyReveal: 'Geheimnis zeigen', + keyHide: 'Geheimnis verbergen', + keyPlaceholder: 'Geben Sie Ihren API-Schlüssel ein', + keyPlaceholderFallback: 'Lassen Sie das Feld leer, um env als Authentifizierung zu verwenden ({hint})', + keyPlaceholderSaved: 'Lassen Sie das Feld leer, um gespeicherte Anmeldeinformationen zu verwenden', + keyFallbackMissing: 'Umgebungsvariable nicht erkannt. Geben Sie einen API-Schlüssel ein oder konfigurieren Sie {hint} in Ihrer Umgebung.', + keyFallbackDetected: 'Umgebungsvariable erkannt. ({hint})', + keyFallbackDetectedHidden: 'Umgebungsvariable erkannt.', + keyFallbackUnchecked: 'Der Status der Umweltberechtigung wurde nicht bestätigt.', + keyHelp: 'Gespeicherte Anmeldeinformationen werden zuerst verwendet. Hier werden Umgebungs-Fallbacks in der Reihenfolge angezeigt: {env}. Quellen sind die Startumgebung, $cwd/.env und dann $DSH_HOME/.env.', + authHelp: 'Authentifizierungsdetails', + customized: 'Benutzerdefinierte Einstellungen', + baseUrl: 'Basis-URL', + baseUrlDefault: 'Kein Standardendpunkt', + baseUrlEnvironment: 'Konfiguration des Anbieterendpunkts: {env}', + baseUrlConfigured: 'Vom Anbieter konfigurierter Endpunkt', + baseUrlPlaceholder: '{url}', + deepSeekBaseUrl: 'https://api.deepseek.com/anthropic (Standardmäßig wird DEEPSEEK_BASE_URL verwendet)', + deepSeekEndpointHint: 'Verwenden Sie einen API-Endpunkt, der mit Anthropic Messages kompatibel ist.', + models: 'Modelle', + modelsInherited: 'Verwendung der Adapterstandards', + modelsCustomized: 'Maßgeschneiderter Modellkatalog', + resetModels: 'Standardeinstellungen wiederherstellen', + model: 'Modell', + modelId: 'Modell-ID', + modelName: 'Anzeigename', + modelNamePlaceholder: 'Verwendet die Modell-ID, wenn sie leer ist', + contextWindow: 'Kontextfenster', + contextWindowPlaceholder: 'Verwendet die Standardeinstellung des Anbieters', + maxTokens: 'Maximale Anzahl ausgegebener Token', + maxTokensPlaceholder: 'Verwendet die Standardeinstellung des Anbieters', + modelAdvanced: 'Modelloptionen', + modelInputTypes: 'Eingabetypen', + modelInputText: 'Text', + modelInputImage: 'Bild', + modelReasoning: 'Argumentationsebenen', + modelReasoningLevel: 'Ebene', + modelReasoningValue: 'API-Wert', + modelReasoningHelp: 'Über Argumentationsebenen', + modelReasoningHelpText: 'Der API-Wert wird im Feld für den Denkaufwand der Anfrage gesendet, etwa reasoning_effort bei OpenAI. Standardmäßig wird der Stufenname verwendet; gibt die API-Dokumentation des Modellanbieters einen anderen Wert vor, verwenden Sie diesen. Aus deaktiviert das Denken und benötigt keinen Wert; ein bereits konfigurierter Wert bleibt erhalten und wird gesendet.', + modelReasoningNeedsLevel: 'Fügen Sie neben „Aus“ mindestens eine Ebene hinzu oder deaktivieren Sie die Argumentationsebenen.', + modelReasoningValueRequired: 'Jede Ebene außer Off benötigt einen API-Wert und kein Wert darf leer sein.', + modelReasoningAdd: 'Ebene hinzufügen', + modelReasoningRemove: 'Ebene löschen', + modelReasoningOffValuePlaceholder: 'Schaltet das Denken aus', + addModel: 'Modell hinzufügen', + removeModel: 'Modell löschen', + reorderModel: 'Modell neu anordnen', + reorderModelHelp: 'Ziehen Sie, um die Reihenfolge neu anzuordnen, oder verwenden Sie die Aufwärts- und Abwärtspfeiltasten.', + modelsEmpty: 'Im Selektor werden keine Modelle angezeigt. Nicht gelistete Ausweise können weiterhin direkt versendet werden.', + keyBlank: 'Geben Sie den Schlüssel API ein oder lassen Sie das Feld leer, um den gespeicherten Schlüssel beizubehalten.', + keyBlankNew: 'Geben Sie den API-Schlüssel ein oder lassen Sie das Feld leer, wenn dieser Anbieter auf andere Weise authentifiziert.', + keyIllegalCharacters: 'Dieser API-Schlüssel hat kein gültiges Format. Bitte überprüfen Sie es.', + modelIdRequired: 'Modell-ID ist erforderlich.', + modelIdDuplicate: 'Die Modell-ID muss eindeutig sein.', + modelNameInvalid: 'Der Anzeigename darf nicht leer sein.', + modelContextInvalid: 'Das Kontextfenster muss eine positive Zahl sein, z. B. 131072, 256 KB oder 1 Mio.', + modelMaxTokensInvalid: 'Die maximale Anzahl an Ausgabetokens muss eine positive Zahl sein, z. B. 8192, 64 KB oder 1 Mio.', + advancedHint: 'Andere Felder befinden sich in cordis.patch.yml; Bearbeiten Sie diesen Abschnitt direkt.', + modelCapacityInvalid: 'Eine Kapazität muss eine Zahl sein, optional mit dem Suffix K oder M.', + modelDuplicate: 'Jede Modell-ID darf einmal vorkommen.', + fetchModels: 'Verfügbare Modelle abrufen', + fetching: 'Den Anbieter fragen...', + fetchNeedsBaseUrl: 'Geben Sie zuerst die Basis-URL ein und rufen Sie sie dann ab.', + fetchEmpty: 'Der Anbieter listete keine Modelle auf. Fügen Sie sie von Hand hinzu.', + fetchTitle: 'Wählen Sie Modelle', + fetchDescription: 'Dies sind die Modelle, die dieser Anbieter zur Verfügung hat. Geprüfte Modelle bilden die Liste.', + fetchSearch: 'Modelle suchen', + fetchNoMatches: 'Keine passenden Modelle.', + fetchSelectAll: 'Alles auswählen', + fetchDeselectAll: 'Alle abwählen', + fetchAdopt: 'Liste aktualisieren', + fetchKeepOne: 'Lassen Sie mindestens ein Modell überprüft.', + customTag: 'Benutzerdefiniert', + customRoute: 'Anbieter-ID', + customRouteHint: 'Bezeichner in Kleinbuchstaben, beginnend mit einem Buchstaben, der diesen Anbieter in Anfragen und als Anmeldeinformationsname eindeutig benennt.', + customRouteInvalid: 'Beginnen Sie mit einem Kleinbuchstaben; dann Kleinbuchstaben, Ziffern und Bindestriche.', + customRouteTaken: 'Ein Anbieter verwendet diese ID bereits.', + customDisplayName: 'Anzeigename', + customApi: 'API-Protokoll', + customApiUnset: 'Nicht ausgewählt', + protocolOpenAiCompletions: 'OpenAI-Chat-Abschlüsse', + protocolOpenAiResponses: 'OpenAI-Antworten', + protocolAnthropicMessages: 'Anthropische Botschaften', + customNeedsBaseUrl: 'Ein benutzerdefinierter Anbieter benötigt eine Basis-URL.', + customBaseUrlInvalid: 'Geben Sie eine gültige HTTP- oder HTTPS-URL ein.', + customNeedsModels: 'Ein benutzerdefinierter Anbieter benötigt mindestens ein Modell.', + customBaseUrlPlaceholder: 'https://gateway.example/v1', + customAnthropicBaseUrlPlaceholder: 'https://gateway.example', + settingsPathUnresolvable: 'Unauflösbarer Einstellungspfad', + create: 'Anbieter erstellen', + creating: 'Erstellen…', + welcomeTitle: 'Vorschauhinweis', + welcomeBody: 'DeepSeek Harness 0.2 befindet sich noch in der Vorschau und viele Bereiche müssen weiter verbessert und verfeinert werden. Wir freuen uns über Feedback und Vorschläge aller Entwickler und Benutzer. Die neue Desktop-App richtet sich nun an ein breites Nutzerspektrum, während entwicklerbezogene erweiterte Funktionen in den Einstellungen aktiviert werden können. Es wird erwartet, dass die Produktfunktionen und Plugin-APIs von DeepSeek Harness ihre schnelle Iteration und Weiterentwicklung fortsetzen und sich im Laufe der Zeit allmählich stabilisieren. Wir heißen jeden willkommen, seine Ideen mit DeepSeek Harness zum Leben zu erwecken und sich an der Community zu beteiligen, um das Plugin-Ökosystem zu bereichern.', + welcomeContinue: 'Weiter', + welcomeError: 'Die Bestätigung konnte nicht gespeichert werden. Bitte versuchen Sie es erneut.', + onboardingTitle: 'Fügen Sie einen API-Schlüssel hinzu, um loszulegen', + onboardingDescription: 'Konfigurieren Sie den offiziellen DeepSeek-Anbieter, um mit der Erstellung zu beginnen.', + onboardingLater: 'Später konfigurieren', + onboardingSave: 'Speichern und fortfahren', + onboardingSaving: 'Sparen…', + keyRequired: 'Geben Sie einen API-Schlüssel ein, um fortzufahren.', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + nav: 'Модели', + deepSeekAccount: 'DeepSeek Аккаунт', + title: 'Модели', + intro: 'Введите ключи API, чтобы использовать модели следующих поставщиков.', + edit: 'Редактировать', + editProvider: 'Редактировать {provider}', + remove: 'Удалить', + removeProvider: 'Удалить {provider}', + deleteTitle: 'Удалить {provider}?', + deleteDescription: 'Удаление {provider} удаляет его конфигурацию. Любые учетные данные, которые он использует, управляются где-то еще и будут сохранены.', + deleteDescriptionWithCredential: 'Удаление {provider} удаляет его конфигурацию и сохраненный ключ API.', + deleteConfirm: 'Удалить {provider}', + deleting: 'Удаление {provider}…', + add: 'Добавить поставщика моделей', + addMode: 'Как добавить', + addCatalog: 'Сторонний поставщик моделей', + addCustom: 'Пользовательская модель API', + addCatalogHint: 'Выберите OpenAI, Anthropic, Kimi или другого провайдера из встроенного каталога и введите его ключ API.', + addCustomHint: 'Подключите реле, автономный сервер или любую другую конечную точку, совместимую с OpenAI или Anthropic, по ее базовому URL-адресу, протоколу и модели.', + addCatalogExhausted: 'Каждый поставщик каталога уже настроен.', + addCustomUnavailable: 'Протокол API недоступен для объявления.', + provider: 'Поставщик', + close: 'Закрыть', + cancel: 'Отмена', + apply: 'Применить', + applying: 'Применение…', + savedProvider: 'Сохранено {provider}.', + credentialConfigured: 'Ключ API настроен', + credentialMissing: 'Ключ API отсутствует', + accountSignedIn: 'Вошёл в систему', + readOnly: 'В этом развертывании документ настроек доступен только для чтения.', + loadFailed: 'Не удалось загрузить каталог поставщика', + conflict: 'Кто-то другой изменил эти настройки, пока эта карточка была открыта. Закройте его и откройте снова, чтобы редактировать текущие значения.', + retry: 'Повторить', + keyInput: 'Ключ API', + keyReveal: 'Показать секрет', + keyHide: 'Скрыть секрет', + keyPlaceholder: 'Введите свой ключ API', + keyPlaceholderFallback: 'Оставьте пустым, чтобы использовать env в качестве аутентификации ({hint})', + keyPlaceholderSaved: 'Оставьте поле пустым, чтобы использовать сохраненные учетные данные.', + keyFallbackMissing: 'Переменная Env не обнаружена. Введите ключ API или настройте {hint} в своей среде.', + keyFallbackDetected: 'Обнаружена переменная Env. ({hint})', + keyFallbackDetectedHidden: 'Обнаружена переменная Env.', + keyFallbackUnchecked: 'Статус экологической сертификации не подтвержден.', + keyHelp: 'Сохраненные учетные данные используются в первую очередь. Здесь показаны резервные варианты среды в порядке: {env}. Источниками являются среда запуска, $cwd/.env, затем $DSH_HOME/.env.', + authHelp: 'Детали аутентификации', + customized: 'Индивидуальные настройки', + baseUrl: 'Базовый URL', + baseUrlDefault: 'Нет конечной точки по умолчанию', + baseUrlEnvironment: 'Конфигурация конечной точки поставщика: {env}.', + baseUrlConfigured: 'Конечная точка, настроенная поставщиком', + baseUrlPlaceholder: '{url}', + deepSeekBaseUrl: 'https://api.deepseek.com/anthropic (по умолчанию используется DEEPSEEK_BASE_URL)', + deepSeekEndpointHint: 'Используйте конечную точку API, совместимую с антропными сообщениями.', + models: 'Модели', + modelsInherited: 'Использование настроек адаптера по умолчанию', + modelsCustomized: 'Индивидуальный каталог моделей', + resetModels: 'Восстановить настройки по умолчанию', + model: 'Модель', + modelId: 'Идентификатор модели', + modelName: 'Отображаемое имя', + modelNamePlaceholder: 'Использует идентификатор модели, когда он пуст', + contextWindow: 'Контекстное окно', + contextWindowPlaceholder: 'Использует поставщика по умолчанию', + maxTokens: 'Максимальное количество выходных токенов', + maxTokensPlaceholder: 'Использует поставщика по умолчанию', + modelAdvanced: 'Варианты модели', + modelInputTypes: 'Типы ввода', + modelInputText: 'Текст', + modelInputImage: 'Изображение', + modelReasoning: 'Уровни рассуждения', + modelReasoningLevel: 'Уровень', + modelReasoningValue: 'Значение API', + modelReasoningHelp: 'Об уровнях рассуждения', + modelReasoningHelpText: 'Значение API передаётся в поле уровня рассуждений запроса, например reasoning_effort у OpenAI. По умолчанию используется название уровня; если документация API поставщика модели указывает другое значение, используйте его. Выкл. отключает рассуждения и не требует значения; уже записанное в конфигурации значение сохраняется и отправляется.', + modelReasoningNeedsLevel: 'Добавьте хотя бы один уровень помимо «Выкл.» или отключите уровни рассуждения.', + modelReasoningValueRequired: 'Для каждого уровня, кроме Off, требуется значение API, и ни одно значение не может быть пустым.', + modelReasoningAdd: 'Добавить уровень', + modelReasoningRemove: 'Удалить уровень', + modelReasoningOffValuePlaceholder: 'Отключает рассуждения', + addModel: 'Добавить модель', + removeModel: 'Удалить модель', + reorderModel: 'Изменить порядок модели', + reorderModelHelp: 'Перетащите, чтобы изменить порядок, или используйте клавиши со стрелками вверх и вниз.', + modelsEmpty: 'В селекторе не будут показаны модели. Неуказанные идентификаторы по-прежнему можно отправлять напрямую.', + keyBlank: 'Введите ключ API или оставьте поле пустым, чтобы сохранить сохраненный.', + keyBlankNew: 'Введите ключ API или оставьте поле пустым, если этот провайдер выполняет аутентификацию другим способом.', + keyIllegalCharacters: 'Этот ключ API имеет недопустимый формат. Пожалуйста, проверьте это.', + modelIdRequired: 'Требуется идентификатор модели.', + modelIdDuplicate: 'Идентификатор модели должен быть уникальным.', + modelNameInvalid: 'Отображаемое имя не может быть пустым.', + modelContextInvalid: 'Контекстное окно должно иметь положительное значение, например 131072, 256 КБ или 1 М.', + modelMaxTokensInvalid: 'Максимальное количество выходных токенов должно иметь положительное значение, например 8192, 64 КБ или 1 М.', + advancedHint: 'Остальные поля находятся в файле cordis.patch.yml; отредактируйте этот раздел напрямую.', + modelCapacityInvalid: 'Емкость должна быть числом, возможно с суффиксом K или M.', + modelDuplicate: 'Каждый идентификатор модели может появиться один раз.', + fetchModels: 'Получить доступные модели', + fetching: 'Спросил у провайдера...', + fetchNeedsBaseUrl: 'Сначала введите базовый URL-адрес, а затем извлеките его.', + fetchEmpty: 'Поставщик не указал моделей. Добавьте их вручную.', + fetchTitle: 'Выберите модели', + fetchDescription: 'Это модели, доступные у этого поставщика. Проверенные модели составляют список.', + fetchSearch: 'Поиск моделей', + fetchNoMatches: 'Нет подходящих моделей.', + fetchSelectAll: 'Выбрать все', + fetchDeselectAll: 'Отменить выбор всех', + fetchAdopt: 'Обновить список', + fetchKeepOne: 'Проверьте хотя бы одну модель.', + customTag: 'Пользовательский', + customRoute: 'Идентификатор поставщика', + customRouteHint: 'Идентификатор в нижнем регистре, начинающийся с буквы, который уникально называет этого поставщика в запросах и в качестве его учетного имени.', + customRouteInvalid: 'Начните со строчной буквы; затем строчные буквы, цифры и тире.', + customRouteTaken: 'Поставщик уже использует этот идентификатор.', + customDisplayName: 'Отображаемое имя', + customApi: 'Протокол API', + customApiUnset: 'Не выбрано', + protocolOpenAiCompletions: 'Завершения чата OpenAI', + protocolOpenAiResponses: 'Ответы OpenAI', + protocolAnthropicMessages: 'Антропные сообщения', + customNeedsBaseUrl: 'Пользовательскому поставщику нужен базовый URL-адрес.', + customBaseUrlInvalid: 'Введите действительный URL-адрес HTTP или HTTPS.', + customNeedsModels: 'Пользовательскому поставщику нужна хотя бы одна модель.', + customBaseUrlPlaceholder: 'https://gateway.example/v1', + customAnthropicBaseUrlPlaceholder: 'https://gateway.example', + settingsPathUnresolvable: 'неразрешимый путь настроек', + create: 'Создать поставщика', + creating: 'Создание…', + welcomeTitle: 'Уведомление о предварительном просмотре', + welcomeBody: 'DeepSeek Harness 0.2 все еще находится в предварительной версии, и многие области нуждаются в дальнейшем улучшении и доработке. Мы приветствуем отзывы и предложения от всех разработчиков и пользователей. Новое настольное приложение теперь ориентировано на широкий круг пользователей, а расширенные функции, связанные с разработчиком, можно включить в настройках. Ожидается, что функции продукта DeepSeek Harness и API-интерфейсы плагинов будут продолжать быстро меняться и развиваться и со временем будут постепенно стабилизироваться. \n\nМы надеемся изучить пределы интеллекта вместе с пользователями и разработчиками по всему миру, опираясь на многоразовую и компонуемую инфраструктуру с открытым исходным кодом. Мы приглашаем всех воплотить свои идеи в жизнь с помощью DeepSeek Harness и принять участие в сообществе, чтобы обогатить экосистему плагинов.', + welcomeContinue: 'Продолжить', + welcomeError: 'Не удалось сохранить подтверждение. Пожалуйста, попробуйте еще раз.', + onboardingTitle: 'Добавьте ключ API, чтобы начать работу.', + onboardingDescription: 'Настройте официального поставщика DeepSeek, чтобы начать сборку.', + onboardingLater: 'Настроить позже', + onboardingSave: 'Сохранить и продолжить', + onboardingSaving: 'Сохранение…', + keyRequired: 'Введите ключ API, чтобы продолжить.', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + nav: 'Modelos', + deepSeekAccount: 'DeepSeek Conta', + title: 'Modelos', + intro: 'Insira suas chaves API para usar modelos dos seguintes fornecedores.', + edit: 'Editar', + editProvider: 'Editar {provider}', + remove: 'Excluir', + removeProvider: 'Excluir {provider}', + deleteTitle: 'Excluir {provider}?', + deleteDescription: 'Excluir {provider} remove sua configuração. Qualquer credencial usada é gerenciada em outro lugar e será mantida.', + deleteDescriptionWithCredential: 'A exclusão de {provider} remove sua configuração e a chave API armazenada.', + deleteConfirm: 'Excluir {provider}', + deleting: 'Excluindo {provider}…', + add: 'Adicionar provedor de modelo', + addMode: 'Como adicionar', + addCatalog: 'Provedor de modelo terceirizado', + addCustom: 'Modelo personalizado API', + addCatalogHint: 'Escolha OpenAI, Anthropic, Kimi ou outro provedor no catálogo integrado e insira sua chave API.', + addCustomHint: 'Conecte um retransmissor, um servidor auto-hospedado ou qualquer outro endpoint compatível com OpenAI ou Anthropic por meio de URL, protocolo e modelos básicos.', + addCatalogExhausted: 'Cada provedor de catálogo já está configurado.', + addCustomUnavailable: 'Nenhum protocolo API está disponível para declaração.', + provider: 'Provedor', + close: 'Fechar', + cancel: 'Cancelar', + apply: 'Aplicar', + applying: 'Aplicando…', + savedProvider: 'Salvo {provider}.', + credentialConfigured: 'API chave configurada', + credentialMissing: 'API chave faltando', + accountSignedIn: 'Conectado', + readOnly: 'O documento de configurações é somente leitura nesta implantação.', + loadFailed: 'Falha ao carregar o diretório do provedor', + conflict: 'Outra pessoa alterou essas configurações enquanto este cartão estava aberto. Feche-o e abra-o novamente para editar os valores atuais.', + retry: 'Tentar novamente', + keyInput: 'API chave', + keyReveal: 'Mostrar segredo', + keyHide: 'Ocultar segredo', + keyPlaceholder: 'Insira sua chave API', + keyPlaceholderFallback: 'Deixe em branco para usar env como autenticação ({hint})', + keyPlaceholderSaved: 'Deixe em branco para usar credenciais salvas', + keyFallbackMissing: 'Env var não detectado. Insira uma chave API ou configure {hint} em seu ambiente.', + keyFallbackDetected: 'Variável de ambiente detectada. ({hint})', + keyFallbackDetectedHidden: 'Variável de ambiente detectada.', + keyFallbackUnchecked: 'O status da credencial ambiental não foi confirmado.', + keyHelp: 'As credenciais salvas são usadas primeiro. Fallbacks de ambiente mostrados aqui, em ordem: {env}. As fontes são o ambiente de inicialização, $cwd/.env e, em seguida, $DSH_HOME/.env.', + authHelp: 'Detalhes de autenticação', + customized: 'Configurações personalizadas', + baseUrl: 'URL base', + baseUrlDefault: 'Nenhum endpoint padrão', + baseUrlEnvironment: 'Configuração do endpoint do provedor: {env}', + baseUrlConfigured: 'Endpoint configurado pelo provedor', + baseUrlPlaceholder: '{url}', + deepSeekBaseUrl: 'https://api.deepseek.com/anthropic (padrão para usar DEEPSEEK_BASE_URL)', + deepSeekEndpointHint: 'Use um endpoint API compatível com Anthropic Messages.', + models: 'Modelos', + modelsInherited: 'Usando os padrões do adaptador', + modelsCustomized: 'Catálogo de modelos personalizados', + resetModels: 'Restaurar padrões', + model: 'Modelo', + modelId: 'ID do modelo', + modelName: 'Nome de exibição', + modelNamePlaceholder: 'Usa o ID do modelo quando vazio', + contextWindow: 'Janela de contexto', + contextWindowPlaceholder: 'Usa o padrão do provedor', + maxTokens: 'Máximo de tokens de saída', + maxTokensPlaceholder: 'Usa o padrão do provedor', + modelAdvanced: 'Opções de modelo', + modelInputTypes: 'Tipos de entrada', + modelInputText: 'Texto', + modelInputImage: 'Imagem', + modelReasoning: 'Níveis de raciocínio', + modelReasoningLevel: 'Nível', + modelReasoningValue: 'valor API', + modelReasoningHelp: 'Sobre níveis de raciocínio', + modelReasoningHelpText: 'O valor da API é enviado no campo de esforço de raciocínio da solicitação, como reasoning_effort da OpenAI. Por padrão, usa-se o nome do nível; se a documentação da API do provedor do modelo especificar outro valor, use-o. Desativado desliga o raciocínio e não exige valor; qualquer valor já salvo na configuração é mantido e enviado.', + modelReasoningNeedsLevel: 'Adicione pelo menos um nível além de Desativado ou desative os níveis de raciocínio.', + modelReasoningValueRequired: 'Cada nível além de Desligado precisa de um valor API e nenhum valor pode ficar vazio.', + modelReasoningAdd: 'Adicionar nível', + modelReasoningRemove: 'Excluir nível', + modelReasoningOffValuePlaceholder: 'Desativa o raciocínio', + addModel: 'Adicionar modelo', + removeModel: 'Excluir modelo', + reorderModel: 'Reordenar modelo', + reorderModelHelp: 'Arraste para reordenar ou use as teclas de seta para cima e para baixo.', + modelsEmpty: 'Nenhum modelo será mostrado no seletor. IDs não listados ainda podem ser enviados diretamente.', + keyBlank: 'Insira a chave API ou deixe o campo vazio para manter a chave armazenada.', + keyBlankNew: 'Insira a chave API ou deixe o campo vazio se este provedor autenticar de outra forma.', + keyIllegalCharacters: 'Esta chave API não está em um formato válido. Por favor, verifique.', + modelIdRequired: 'O ID do modelo é obrigatório.', + modelIdDuplicate: 'O ID do modelo deve ser exclusivo.', + modelNameInvalid: 'O nome de exibição não pode ficar vazio.', + modelContextInvalid: 'A janela de contexto deve ter uma contagem positiva, como 131072, 256K ou 1M.', + modelMaxTokensInvalid: 'Os tokens de saída máximos devem ter uma contagem positiva, como 8192, 64K ou 1M.', + advancedHint: 'Outros campos residem em cordis.patch.yml; edite essa seção diretamente.', + modelCapacityInvalid: 'Uma capacidade deve ser um número, opcionalmente com o sufixo K ou M.', + modelDuplicate: 'Cada ID de modelo pode aparecer uma vez.', + fetchModels: 'Buscar modelos disponíveis', + fetching: 'Perguntando ao provedor…', + fetchNeedsBaseUrl: 'Insira o URL base primeiro e depois busque.', + fetchEmpty: 'O fornecedor não listou nenhum modelo. Adicione-os manualmente.', + fetchTitle: 'Escolha modelos', + fetchDescription: 'Estes são os modelos que este fornecedor tem disponíveis. Os modelos verificados compõem a lista.', + fetchSearch: 'Pesquisar modelos', + fetchNoMatches: 'Não há modelos correspondentes.', + fetchSelectAll: 'Selecionar tudo', + fetchDeselectAll: 'Desmarcar tudo', + fetchAdopt: 'Lista de atualização', + fetchKeepOne: 'Mantenha pelo menos um modelo verificado.', + customTag: 'Personalizado', + customRoute: 'ID do provedor', + customRouteHint: 'Identificador minúsculo, começando com uma letra, que nomeia exclusivamente esse provedor nas solicitações e como seu nome de credencial.', + customRouteInvalid: 'Comece com uma letra minúscula; em seguida, letras minúsculas, dígitos e travessões.', + customRouteTaken: 'Um provedor já usa esse ID.', + customDisplayName: 'Nome de exibição', + customApi: 'API protocolo', + customApiUnset: 'Não selecionado', + protocolOpenAiCompletions: 'Conclusões do bate-papo OpenAI', + protocolOpenAiResponses: 'Respostas OpenAI', + protocolAnthropicMessages: 'Mensagens Antrópicas', + customNeedsBaseUrl: 'Um provedor personalizado precisa de um URL base.', + customBaseUrlInvalid: 'Insira um URL HTTP ou HTTPS válido.', + customNeedsModels: 'Um provedor personalizado precisa de pelo menos um modelo.', + customBaseUrlPlaceholder: 'https://gateway.example/v1', + customAnthropicBaseUrlPlaceholder: 'https://gateway.example', + settingsPathUnresolvable: 'caminho de configurações insolúveis', + create: 'Criar provedor', + creating: 'Criando…', + welcomeTitle: 'Aviso de visualização', + welcomeBody: 'DeepSeek Harness 0.2 ainda está em versão prévia e muitas áreas precisam de melhorias e refinamentos contínuos. Agradecemos comentários e sugestões de todos os desenvolvedores e usuários. O novo aplicativo de desktop agora é direcionado a uma ampla gama de usuários, enquanto recursos avançados relacionados ao desenvolvedor podem ser habilitados nas configurações. Espera-se que os recursos do produto e as APIs de plug-in do DeepSeek Harness continuem com rápida iteração e evolução e se estabilizem gradualmente ao longo do tempo.\n\nEsperamos explorar os limites da inteligência junto com usuários e desenvolvedores em todo o mundo, desenvolvendo uma infraestrutura de código aberto, reutilizável e combinável. Convidamos todos a dar vida às suas ideias com DeepSeek Harness e participar da comunidade para enriquecer o ecossistema de plug-ins.', + welcomeContinue: 'Continuar', + welcomeError: 'A confirmação não pôde ser salva. Por favor, tente novamente.', + onboardingTitle: 'Adicione uma chave API para começar', + onboardingDescription: 'Configure o provedor DeepSeek oficial para começar a compilar.', + onboardingLater: 'Configurar mais tarde', + onboardingSave: 'Salvar e continuar', + onboardingSaving: 'Salvando…', + keyRequired: 'Insira uma tecla API para continuar.', +} satisfies Record diff --git a/packages/client/ui-settings-plugin-inventory/locale/de.json b/packages/client/ui-settings-plugin-inventory/locale/de.json new file mode 100644 index 0000000000..e949caba64 --- /dev/null +++ b/packages/client/ui-settings-plugin-inventory/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Integrierte Plug-in-Listenschnittstelle", + "description": "Überprüfen Sie in den Einstellungen die globalen Plug-Ins und Plug-Ins, die von jedem Agenten verwendet werden." + } +} diff --git a/packages/client/ui-settings-plugin-inventory/locale/es.json b/packages/client/ui-settings-plugin-inventory/locale/es.json new file mode 100644 index 0000000000..32ef114ca5 --- /dev/null +++ b/packages/client/ui-settings-plugin-inventory/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de lista de complementos incorporada", + "description": "Verifique los complementos globales y los complementos utilizados por cada Agente en la configuración." + } +} diff --git a/packages/client/ui-settings-plugin-inventory/locale/fr.json b/packages/client/ui-settings-plugin-inventory/locale/fr.json new file mode 100644 index 0000000000..a83279a5dc --- /dev/null +++ b/packages/client/ui-settings-plugin-inventory/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de liste de plug-ins intégrée", + "description": "Vérifiez les plug-ins globaux et les plug-ins utilisés par chaque Agent dans les paramètres." + } +} diff --git a/packages/client/ui-settings-plugin-inventory/locale/pt.json b/packages/client/ui-settings-plugin-inventory/locale/pt.json new file mode 100644 index 0000000000..c82847e91e --- /dev/null +++ b/packages/client/ui-settings-plugin-inventory/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de lista de plug-ins integrada", + "description": "Verifique os plug-ins globais e plug-ins usados por cada Agente nas configurações." + } +} diff --git a/packages/client/ui-settings-plugin-inventory/locale/ru.json b/packages/client/ui-settings-plugin-inventory/locale/ru.json new file mode 100644 index 0000000000..4d1b1aae31 --- /dev/null +++ b/packages/client/ui-settings-plugin-inventory/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Встроенный интерфейс списка плагинов", + "description": "Проверьте в настройках глобальные плагины и плагины, используемые каждым Агентом." + } +} diff --git a/packages/client/ui-settings-plugin-inventory/src/client/index.ts b/packages/client/ui-settings-plugin-inventory/src/client/index.ts index 2532d406cd..acb324117a 100644 --- a/packages/client/ui-settings-plugin-inventory/src/client/index.ts +++ b/packages/client/ui-settings-plugin-inventory/src/client/index.ts @@ -11,7 +11,7 @@ import type {} from '@deepseek-ai/dsh-client-ui-agent-preset/client' // Inline-safe shared fold: shipped ids map to dictionary keys in one home. import { presetDisplayText } from '@deepseek-ai/dsh-agent-preset-registry/display' import { PluginInventorySettingsTab, type PluginInventorySettingsTabInjected } from './PluginInventorySettingsTab.tsx' -import { en, ja, zh, type PluginInventoryLocaleKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh, type PluginInventoryLocaleKey } from './locales.ts' export type { PluginInventorySettingsTabInjected, PluginInventorySettingsTabProps } from './PluginInventorySettingsTab.tsx' export type { PluginInventoryLocaleKey } from './locales.ts' @@ -31,7 +31,7 @@ export const inject = ['slots', 'locale', 'remote', 'remote.pluginInventory', 'm /** Contribute the lazy inventory tab to the Plugins settings section. */ export function apply(ctx: ClientContext): void { - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-settings-plugin-inventory: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-settings-plugin-inventory: dictionaries') const t = ctx.locale.bind(NS) const list: PluginInventorySettingsTabInjected['list'] = async () => { diff --git a/packages/client/ui-settings-plugin-inventory/src/client/locales.ts b/packages/client/ui-settings-plugin-inventory/src/client/locales.ts index 391896bcc0..d0d7480472 100644 --- a/packages/client/ui-settings-plugin-inventory/src/client/locales.ts +++ b/packages/client/ui-settings-plugin-inventory/src/client/locales.ts @@ -125,3 +125,208 @@ export const ja = { 'failed': '起動に失敗', 'unloading': 'アンロード中', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + tab: 'Lista de complementos', + loading: 'Leyendo complementos…', + clientSyncing: 'Sincronizando complementos en esta página…', + clientSyncFailed: 'Algunos complementos no se pudieron sincronizar en esta página. La habilitación del host no ha cambiado.', + clientSyncRetry: 'Reintentar esta página', + error: 'Los complementos no están disponibles temporalmente.', + metadataError: 'Error de metadatos del paquete: {error}', + retry: 'Reintentar', + search: 'Complementos de búsqueda', + empty: 'No hay complementos disponibles.', + emptySearch: 'No hay complementos coincidentes.', + presetTitle: 'Complementos de sesión', + presetSubtitle: 'Compuesto por sesión por ajustes preestablecidos de agente', + switcherLabel: 'Elija el agente preestablecido para inspeccionar', + presetOptionDefault: '{name} (predeterminado)', + presetOptionBroken: '{name} (no se pudo cargar)', + globalTitle: 'Complementos globales', + globalSubtitle: 'Compartido por el sistema y cada sesión.', + presetProvidedDetail: 'Discapacitados a nivel mundial; Los ajustes preestablecidos del agente lo proporcionan por sesión.', + enabledIn: 'Habilitado en', + matchesInOtherPresets: '{count} más coincidencias en otros ajustes preestablecidos: ', + enabledTag: 'Habilitado', + disabledTag: 'Discapacitado', + conditionalTag: 'Condicional', + presetEnabledTag: 'A través de ajustes preestablecidos', + failedTag: 'Fallido', + moduleLabel: 'Módulo', + fromPreset: 'De', + condition: 'Deshabilitado cuando', + configuration: 'Configuración', + runtime: 'Estado', + unobserved: 'no corriendo', + pending: 'Esperando dependencias', + loadingPhase: 'Cargando', + active: 'corriendo', + failed: 'No se pudo iniciar', + unloading: 'Descarga', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + tab: 'Liste des plugins', + loading: 'Plugins de lecture…', + clientSyncing: 'Synchronisation des plugins sur cette page…', + clientSyncFailed: "Certains plugins n'ont pas pu se synchroniser sur cette page. L'activation de l'hôte est inchangée.", + clientSyncRetry: 'Réessayez cette page', + error: 'Les plugins sont temporairement indisponibles.', + metadataError: 'Erreur de métadonnées du package : {error}', + retry: 'Réessayer', + search: 'Plugins de recherche', + empty: "Aucun plugin n'est disponible.", + emptySearch: 'Aucun plugin correspondant.', + presetTitle: 'Plugins de sessions', + presetSubtitle: "Composé par session par préréglages d'agent", + switcherLabel: "Choisissez le préréglage d'agent à inspecter", + presetOptionDefault: '{name} (par défaut)', + presetOptionBroken: '{name} (échec du chargement)', + globalTitle: 'Plugins globaux', + globalSubtitle: 'Partagé par le système et à chaque session', + presetProvidedDetail: "Handicapé à l'échelle mondiale ; les préréglages d'agent le fournissent par session", + enabledIn: 'Activé dans', + matchesInOtherPresets: "{count} plus de correspondances dans d'autres préréglages : ", + enabledTag: 'Activé', + disabledTag: 'Désactivé', + conditionalTag: 'Conditionnel', + presetEnabledTag: 'Via les préréglages', + failedTag: 'Échec', + moduleLabel: 'Module', + fromPreset: 'De', + condition: 'Désactivé quand', + configuration: 'Configuration', + runtime: 'Statut', + unobserved: 'Ne fonctionne pas', + pending: 'En attente de dépendances', + loadingPhase: 'Chargement', + active: 'Courir', + failed: 'Échec du démarrage', + unloading: 'Déchargement', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + tab: 'Plugin-Liste', + loading: 'Plugins lesen…', + clientSyncing: 'Plugins auf dieser Seite werden synchronisiert…', + clientSyncFailed: 'Einige Plugins konnten auf dieser Seite nicht synchronisiert werden. Die Host-Aktivierung bleibt unverändert.', + clientSyncRetry: 'Versuchen Sie es erneut mit dieser Seite', + error: 'Plugins sind vorübergehend nicht verfügbar.', + metadataError: 'Paketmetadatenfehler: {error}', + retry: 'Erneut versuchen', + search: 'Such-Plugins', + empty: 'Es sind keine Plugins verfügbar.', + emptySearch: 'Keine passenden Plugins.', + presetTitle: 'Sitzungs-Plugins', + presetSubtitle: 'Zusammengestellt pro Sitzung nach Agentenvoreinstellungen', + switcherLabel: 'Wählen Sie die zu überprüfende Agentenvoreinstellung aus', + presetOptionDefault: '{name} (Standard)', + presetOptionBroken: '{name} (Laden fehlgeschlagen)', + globalTitle: 'Globale Plugins', + globalSubtitle: 'Wird vom System und jeder Sitzung geteilt', + presetProvidedDetail: 'Weltweit deaktiviert; Agentenvoreinstellungen stellen es pro Sitzung bereit', + enabledIn: 'Aktiviert in', + matchesInOtherPresets: '{count} weitere Übereinstimmungen in anderen Voreinstellungen: ', + enabledTag: 'Aktiviert', + disabledTag: 'Deaktiviert', + conditionalTag: 'Bedingt', + presetEnabledTag: 'Über Voreinstellungen', + failedTag: 'Fehlgeschlagen', + moduleLabel: 'Modul', + fromPreset: 'Von', + condition: 'Deaktiviert, wenn', + configuration: 'Konfiguration', + runtime: 'Status', + unobserved: 'Läuft nicht', + pending: 'Warten auf Abhängigkeiten', + loadingPhase: 'Laden', + active: 'Laufen', + failed: 'Start fehlgeschlagen', + unloading: 'Entladen', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + tab: 'Список плагинов', + loading: 'Чтение плагинов…', + clientSyncing: 'Синхронизация плагинов на этой странице…', + clientSyncFailed: 'Некоторые плагины не смогли синхронизироваться на этой странице. Включение хоста не изменилось.', + clientSyncRetry: 'Повторить эту страницу', + error: 'Плагины временно недоступны.', + metadataError: 'Ошибка метаданных пакета: {error}.', + retry: 'Повторить', + search: 'Поиск плагинов', + empty: 'Нет доступных плагинов.', + emptySearch: 'Нет подходящих плагинов.', + presetTitle: 'Плагины сеансов', + presetSubtitle: 'Составляется за сеанс с помощью предустановок агента', + switcherLabel: 'Выберите предустановку агента для проверки', + presetOptionDefault: '{name} (по умолчанию)', + presetOptionBroken: '{name} (не удалось загрузить)', + globalTitle: 'Глобальные плагины', + globalSubtitle: 'Совместно используется системой и каждым сеансом', + presetProvidedDetail: 'Отключено глобально; предустановки агента предусматривают это за сеанс', + enabledIn: 'Включено в', + matchesInOtherPresets: '{count} больше совпадений в других пресетах: ', + enabledTag: 'Включено', + disabledTag: 'Отключено', + conditionalTag: 'Условный', + presetEnabledTag: 'Через пресеты', + failedTag: 'Не удалось', + moduleLabel: 'Модуль', + fromPreset: 'От', + condition: 'Отключено, когда', + configuration: 'Конфигурация', + runtime: 'Статус', + unobserved: 'Не работает', + pending: 'Ожидание зависимостей', + loadingPhase: 'Загрузка', + active: 'Бег', + failed: 'Не удалось запустить', + unloading: 'Разгрузка', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + tab: 'Lista de plug-ins', + loading: 'Lendo plug-ins…', + clientSyncing: 'Sincronizando plug-ins nesta página…', + clientSyncFailed: 'Alguns plug-ins não puderam ser sincronizados nesta página. A ativação do host permanece inalterada.', + clientSyncRetry: 'Tente esta página novamente', + error: 'Os plug-ins estão temporariamente indisponíveis.', + metadataError: 'Erro de metadados do pacote: {error}', + retry: 'Tentar novamente', + search: 'Plug-ins de pesquisa', + empty: 'Nenhum plug-in está disponível.', + emptySearch: 'Nenhum plug-in correspondente.', + presetTitle: 'Plug-ins de sessão', + presetSubtitle: 'Composto por sessão por predefinições de agente', + switcherLabel: 'Escolha a predefinição do agente para inspecionar', + presetOptionDefault: '{name} (padrão)', + presetOptionBroken: '{name} (falha ao carregar)', + globalTitle: 'Plug-ins globais', + globalSubtitle: 'Compartilhado pelo sistema e por cada sessão', + presetProvidedDetail: 'Desativado globalmente; predefinições de agente fornecem isso por sessão', + enabledIn: 'Habilitado em', + matchesInOtherPresets: '{count} mais correspondências em outras predefinições: ', + enabledTag: 'Habilitado', + disabledTag: 'Desativado', + conditionalTag: 'Condicional', + presetEnabledTag: 'Por meio de predefinições', + failedTag: 'Falha', + moduleLabel: 'Módulo', + fromPreset: 'De', + condition: 'Desativado quando', + configuration: 'Configuração', + runtime: 'Estado', + unobserved: 'Não está em execução', + pending: 'Esperando por dependências', + loadingPhase: 'Carregando', + active: 'Correndo', + failed: 'Falha ao iniciar', + unloading: 'Descarregando', +} satisfies Record diff --git a/packages/client/ui-settings-plugins/locale/de.json b/packages/client/ui-settings-plugins/locale/de.json new file mode 100644 index 0000000000..9b3e3dbeb2 --- /dev/null +++ b/packages/client/ui-settings-plugins/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Integrierter Plug-in-Einstellungseingang", + "description": "Bietet den integrierten Plug-in-Eingang und seine Funktionsregisterkarte in den Einstellungen." + } +} diff --git a/packages/client/ui-settings-plugins/locale/es.json b/packages/client/ui-settings-plugins/locale/es.json new file mode 100644 index 0000000000..f06cce9794 --- /dev/null +++ b/packages/client/ui-settings-plugins/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Entrada de configuración de complementos incorporados", + "description": "Proporciona la entrada del complemento integrado y su pestaña de función en la configuración." + } +} diff --git a/packages/client/ui-settings-plugins/locale/fr.json b/packages/client/ui-settings-plugins/locale/fr.json new file mode 100644 index 0000000000..762ba220ef --- /dev/null +++ b/packages/client/ui-settings-plugins/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Entrée des paramètres du plug-in intégré", + "description": "Fournit l'entrée du plug-in intégré et sa page à onglet de fonction dans les paramètres." + } +} diff --git a/packages/client/ui-settings-plugins/locale/pt.json b/packages/client/ui-settings-plugins/locale/pt.json new file mode 100644 index 0000000000..4af280898e --- /dev/null +++ b/packages/client/ui-settings-plugins/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Entrada de configurações de plug-in integradas", + "description": "Fornece a entrada do plug-in integrada e sua guia de função nas configurações." + } +} diff --git a/packages/client/ui-settings-plugins/locale/ru.json b/packages/client/ui-settings-plugins/locale/ru.json new file mode 100644 index 0000000000..4fdd139aa0 --- /dev/null +++ b/packages/client/ui-settings-plugins/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Вход в настройки встроенного плагина", + "description": "Обеспечивает вход встроенного плагина и вкладку его функций в настройках." + } +} diff --git a/packages/client/ui-settings-plugins/src/client/index.ts b/packages/client/ui-settings-plugins/src/client/index.ts index 4897b7c503..b9db73a850 100644 --- a/packages/client/ui-settings-plugins/src/client/index.ts +++ b/packages/client/ui-settings-plugins/src/client/index.ts @@ -18,7 +18,7 @@ import type { Context as ClientContext } from '@deepseek-ai/cordis' import { resolveSlotLabel } from '@deepseek-ai/dsh-client-ui-slots' import { PluginsSettingsSection } from './PluginsSettingsSection.tsx' import type { PluginsSettingsSectionInjected, PluginsSettingsTabEntry } from './PluginsSettingsSection.tsx' -import { en, ja, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh } from './locales.ts' export type { PluginsSettingsSectionInjected, PluginsSettingsSectionProps } from './PluginsSettingsSection.tsx' @@ -34,7 +34,7 @@ export const inject = ['slots', 'locale'] */ export function apply(ctx: ClientContext): void { const t = ctx.locale.bind(NS) - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-settings-plugins: section dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-settings-plugins: section dictionaries') let tabsVersion = -1 let tabsRevision = -1 diff --git a/packages/client/ui-settings-plugins/src/client/locales.ts b/packages/client/ui-settings-plugins/src/client/locales.ts index 9d32663ee5..723b596309 100644 --- a/packages/client/ui-settings-plugins/src/client/locales.ts +++ b/packages/client/ui-settings-plugins/src/client/locales.ts @@ -29,3 +29,48 @@ export const ja = { 'tabs': 'プラグインビュー', 'empty': 'このデプロイメントにはプラグインビューがありません。', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + nav: 'Complementos integrados', + title: 'Complementos integrados', + intro: 'Inspeccione los complementos que incluye esta implementación.', + tabs: 'Vistas de complementos', + empty: 'Esta implementación no expone vistas de complementos.', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + nav: 'Plugins intégrés', + title: 'Plugins intégrés', + intro: 'Inspectez les plugins fournis par ce déploiement.', + tabs: 'Vues des plugins', + empty: "Ce déploiement n'expose aucune vue de plugin.", +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + nav: 'Integrierte Plugins', + title: 'Integrierte Plugins', + intro: 'Überprüfen Sie die Plugins, die mit dieser Bereitstellung geliefert werden.', + tabs: 'Plugin-Ansichten', + empty: 'Diese Bereitstellung stellt keine Plugin-Ansichten bereit.', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + nav: 'Встроенные плагины', + title: 'Встроенные плагины', + intro: 'Проверьте плагины, поставляемые в этом развертывании.', + tabs: 'Просмотры плагинов', + empty: 'Это развертывание не предоставляет никаких представлений плагинов.', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + nav: 'Plug-ins integrados', + title: 'Plug-ins integrados', + intro: 'Inspecione os plug-ins fornecidos por esta implantação.', + tabs: 'Visualizações de plug-in', + empty: 'Esta implantação não expõe visualizações de plug-ins.', +} satisfies Record diff --git a/packages/client/ui-settings-session-log/locale/de.json b/packages/client/ui-settings-session-log/locale/de.json new file mode 100644 index 0000000000..4fcbe1e3dc --- /dev/null +++ b/packages/client/ui-settings-session-log/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Einstellungen zum Hochladen des Sitzungsprotokolls", + "description": "Legt fest, ob Sitzungsprotokolle mit DeepSeekAnfragen des offiziellen Modells API hochgeladen werden." + } +} diff --git a/packages/client/ui-settings-session-log/locale/es.json b/packages/client/ui-settings-session-log/locale/es.json new file mode 100644 index 0000000000..58eedd3600 --- /dev/null +++ b/packages/client/ui-settings-session-log/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Configuración de carga del registro de sesión", + "description": "Establece si los registros de sesión se cargan con las solicitudes del DeepSeekmodelo oficial API." + } +} diff --git a/packages/client/ui-settings-session-log/locale/fr.json b/packages/client/ui-settings-session-log/locale/fr.json new file mode 100644 index 0000000000..eaf0616333 --- /dev/null +++ b/packages/client/ui-settings-session-log/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Paramètres de téléchargement du journal de session", + "description": "Définit si les journaux de session sont téléchargés avec les requêtes DeepSeek de modèle officiel API." + } +} diff --git a/packages/client/ui-settings-session-log/locale/pt.json b/packages/client/ui-settings-session-log/locale/pt.json new file mode 100644 index 0000000000..cfe80f4cc6 --- /dev/null +++ b/packages/client/ui-settings-session-log/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Configurações de upload de log de sessão", + "description": "Define se os logs de sessão serão carregados com solicitações de DeepSeekmodelo oficialAPI." + } +} diff --git a/packages/client/ui-settings-session-log/locale/ru.json b/packages/client/ui-settings-session-log/locale/ru.json new file mode 100644 index 0000000000..acba5b0b17 --- /dev/null +++ b/packages/client/ui-settings-session-log/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Настройки загрузки журнала сеанса", + "description": "Определяет, загружаются ли журналы сеансов с запросами DeepSeek официальной модели API." + } +} diff --git a/packages/client/ui-settings-session-log/src/client/index.ts b/packages/client/ui-settings-session-log/src/client/index.ts index 6e749043cb..c959d1a64d 100644 --- a/packages/client/ui-settings-session-log/src/client/index.ts +++ b/packages/client/ui-settings-session-log/src/client/index.ts @@ -6,7 +6,7 @@ import type {} from '@deepseek-ai/dsh-client-ui-layout/client' import type {} from '@deepseek-ai/dsh-client-ui-renderer/client' import { UploadPreference, type UploadSettings } from './upload-preference.ts' import { UploadRow, UploadToast, type UploadInjected } from './UploadRow.tsx' -import { en, ja, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh } from './locales.ts' declare module '@deepseek-ai/dsh-client-ui-slots' { interface LocaleNamespaceMap { @@ -25,7 +25,7 @@ export const inject = ['slots', 'locale', 'configForms'] export function apply(ctx: Context): void { const locale = 'settings.sessionLog' const namespace = 'session-log-deepseek' - ctx.effect(() => ctx.locale.register(locale, { en, zh, ja })) + ctx.effect(() => ctx.locale.register(locale, { en, zh, ja, es, fr, de, ru, pt })) const form = ctx.configForms.get(namespace) const preference = new UploadPreference(form) const face = (): UploadInjected => ({ diff --git a/packages/client/ui-settings-session-log/src/client/locales.ts b/packages/client/ui-settings-session-log/src/client/locales.ts index 99b1d2f815..aeb0d22bbd 100644 --- a/packages/client/ui-settings-session-log/src/client/locales.ts +++ b/packages/client/ui-settings-session-log/src/client/locales.ts @@ -21,3 +21,43 @@ export const ja = { 'saved': '設定を保存しました', 'failed': '設定を保存できませんでした', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + title: 'Cargar registro de sesión cuando utilice el modelo oficial API', + description: 'Ayude a mejorar los modelos y productos DeepSeek.', + saved: 'Preferencia guardada', + failed: 'No se pudo guardar la preferencia', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + title: "Téléchargez le journal de session lors de l'utilisation du modèle officiel API", + description: 'Aidez à améliorer les modèles et produits DeepSeek.', + saved: 'Préférence enregistrée', + failed: "Impossible d'enregistrer la préférence", +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + title: 'Laden Sie das Sitzungsprotokoll hoch, wenn Sie das offizielle Modell API verwenden', + description: 'Helfen Sie mit, DeepSeek-Modelle und -Produkte zu verbessern.', + saved: 'Präferenz gespeichert', + failed: 'Präferenz konnte nicht gespeichert werden', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + title: 'Загрузить журнал сеансов при использовании официальной модели API', + description: 'Помогите улучшить модели и продукты DeepSeek.', + saved: 'Предпочтение сохранено.', + failed: 'Не удалось сохранить предпочтения.', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + title: 'Carregar log de sessão ao usar o modelo oficial API', + description: 'Ajude a melhorar DeepSeek modelos e produtos.', + saved: 'Preferência salva', + failed: 'Não foi possível salvar a preferência', +} satisfies Record diff --git a/packages/client/ui-settings-shell/locale/de.json b/packages/client/ui-settings-shell/locale/de.json new file mode 100644 index 0000000000..74ac0a1feb --- /dev/null +++ b/packages/client/ui-settings-shell/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Einstellungen zur Befehlsausführung", + "description": "Konfigurieren Sie das Zeitlimit für die Befehlsausführung und die Begrenzung der Ausgabelänge." + } +} diff --git a/packages/client/ui-settings-shell/locale/es.json b/packages/client/ui-settings-shell/locale/es.json new file mode 100644 index 0000000000..ea799af8ec --- /dev/null +++ b/packages/client/ui-settings-shell/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Configuración de ejecución de comandos", + "description": "Configure el tiempo de espera de ejecución del comando y el límite de longitud de salida." + } +} diff --git a/packages/client/ui-settings-shell/locale/fr.json b/packages/client/ui-settings-shell/locale/fr.json new file mode 100644 index 0000000000..d1afc02893 --- /dev/null +++ b/packages/client/ui-settings-shell/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Paramètres d'exécution des commandes", + "description": "Configurez le délai d'expiration de l'exécution de la commande et la limite de longueur de sortie." + } +} diff --git a/packages/client/ui-settings-shell/locale/pt.json b/packages/client/ui-settings-shell/locale/pt.json new file mode 100644 index 0000000000..929cead7d8 --- /dev/null +++ b/packages/client/ui-settings-shell/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Configurações de execução de comando", + "description": "Configure o tempo limite de execução do comando e o limite de comprimento de saída." + } +} diff --git a/packages/client/ui-settings-shell/locale/ru.json b/packages/client/ui-settings-shell/locale/ru.json new file mode 100644 index 0000000000..9d95f4b7a2 --- /dev/null +++ b/packages/client/ui-settings-shell/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Настройки выполнения команд", + "description": "Настройте тайм-аут выполнения команды и ограничение длины вывода." + } +} diff --git a/packages/client/ui-settings-shell/src/client/index.ts b/packages/client/ui-settings-shell/src/client/index.ts index 55f69d6b09..a20afd04de 100644 --- a/packages/client/ui-settings-shell/src/client/index.ts +++ b/packages/client/ui-settings-shell/src/client/index.ts @@ -17,7 +17,7 @@ import type {} from '@deepseek-ai/dsh-client-ui-renderer/client' import type { Context as ClientContext } from '@deepseek-ai/cordis' import { ShellCard } from './ShellCard.tsx' import { BASH_NS, PWSH_NS, ShellCardController } from './shell-card-controller.ts' -import { en, ja, zh, type ShellSettingsLocaleKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh, type ShellSettingsLocaleKey } from './locales.ts' export type { ShellCardProps } from './ShellCard.tsx' export type { ShellCardFace, ShellCardState, ShellSettings } from './shell-card-controller.ts' @@ -42,7 +42,7 @@ export const inject = ['slots', 'locale', 'configForms'] */ export function apply(ctx: ClientContext): void { const t = ctx.locale.bind(NS) - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-settings-shell: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-settings-shell: dictionaries') // The base bundle composes exactly one shell executor per platform; the page binds the served one. const bash = new ShellCardController(ctx.configForms.get(BASH_NS)) const pwsh = new ShellCardController(ctx.configForms.get(PWSH_NS)) diff --git a/packages/client/ui-settings-shell/src/client/locales.ts b/packages/client/ui-settings-shell/src/client/locales.ts index 74980e77fc..e7025c7d80 100644 --- a/packages/client/ui-settings-shell/src/client/locales.ts +++ b/packages/client/ui-settings-shell/src/client/locales.ts @@ -71,3 +71,93 @@ export const ja = { 'saveFailed': 'デプロイがこれらの値を受け付けませんでした。修正のため残されています。', 'invalidNumber': '数値を入力するか、空欄のままにするとデフォルトが使用されます。', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + title: 'Concha', + description: 'Limite cuánto tiempo puede ejecutarse cada comando y cuánto puede generar.', + timeoutMs: 'Tiempo de espera del comando (ms)', + timeoutMsHint: 'Cuánto tiempo puede ejecutarse un comando antes de finalizar.', + maxOutputBytes: 'Límite de salida por flujo (bytes)', + maxOutputBytesHint: 'La salida más allá de esto se transfiere a un archivo temporal en lugar de perderse.', + overridden: 'Anulado', + reset: 'Restablecer los valores predeterminados', + readOnly: 'Esta implementación almacena configuraciones de solo lectura.', + unavailable: 'Este complemento no está cargado, por lo que no se puede configurar en este momento.', + save: 'Guardar', + saving: 'Guardando…', + saveFailed: 'El despliegue no aceptó estos valores; quedaron para que usted los corrigiera.', + invalidNumber: 'Ingrese un número o déjelo en blanco para usar el valor predeterminado.', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + title: 'Coquille', + description: "Limitez la durée d'exécution de chaque commande et le volume de résultats qu'elle peut générer.", + timeoutMs: "Délai d'expiration de la commande (ms)", + timeoutMsHint: "Combien de temps une commande peut s'exécuter avant d'être terminée.", + maxOutputBytes: 'Limite de sortie par flux (octets)', + maxOutputBytesHint: "La sortie au-delà de cela se déverse dans un fichier temporaire plutôt que d'être perdue.", + overridden: 'Remplacé', + reset: 'Réinitialiser aux valeurs par défaut', + readOnly: 'Ce déploiement stocke les paramètres en lecture seule.', + unavailable: "Ce plugin n'est pas chargé, il ne peut donc pas être configuré pour le moment.", + save: 'Enregistrer', + saving: 'Sauvegarde…', + saveFailed: "Le déploiement n'a pas accepté ces valeurs ; ils vous ont été laissés à corriger.", + invalidNumber: 'Entrez un numéro ou laissez ce champ vide pour utiliser la valeur par défaut.', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + title: 'Muschel', + description: 'Begrenzen Sie, wie lange jeder Befehl ausgeführt werden darf und wie viel er ausgeben darf.', + timeoutMs: 'Befehls-Timeout (ms)', + timeoutMsHint: 'Wie lange ein Befehl ausgeführt werden darf, bevor er beendet wird.', + maxOutputBytes: 'Ausgabeobergrenze pro Stream (Byte)', + maxOutputBytesHint: 'Darüber hinausgehende Ausgaben werden in eine temporäre Datei übertragen und gehen nicht verloren.', + overridden: 'Überschrieben', + reset: 'Auf Standard zurücksetzen', + readOnly: 'Diese Bereitstellung speichert Einstellungen schreibgeschützt.', + unavailable: 'Dieses Plugin ist nicht geladen und kann daher derzeit nicht konfiguriert werden.', + save: 'Speichern', + saving: 'Sparen…', + saveFailed: 'Die Bereitstellung hat diese Werte nicht akzeptiert. Sie mussten sie korrigieren.', + invalidNumber: 'Geben Sie eine Zahl ein oder lassen Sie das Feld leer, um den Standardwert zu verwenden.', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + title: 'Ракушка', + description: 'Ограничьте продолжительность выполнения каждой команды и объем вывода.', + timeoutMs: 'Таймаут команды (мс)', + timeoutMsHint: 'Как долго может выполняться одна команда до ее завершения.', + maxOutputBytes: 'Ограничение вывода на поток (байты)', + maxOutputBytesHint: 'Вывод, выходящий за пределы этого, сохраняется во временный файл, а не теряется.', + overridden: 'Переопределено', + reset: 'Сбросить настройки по умолчанию', + readOnly: 'В этом развертывании параметры сохраняются только для чтения.', + unavailable: 'Этот плагин не загружен, поэтому его невозможно настроить прямо сейчас.', + save: 'Сохранить', + saving: 'Сохранение…', + saveFailed: 'Развертывание не приняло эти значения; их оставили вам на исправление.', + invalidNumber: 'Введите число или оставьте поле пустым, чтобы использовать значение по умолчанию.', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + title: 'Concha', + description: 'Limite quanto tempo cada comando pode ser executado e quanto ele pode gerar.', + timeoutMs: 'Tempo limite do comando (ms)', + timeoutMsHint: 'Quanto tempo um comando pode ser executado antes de ser encerrado.', + maxOutputBytes: 'Limite de saída por stream (bytes)', + maxOutputBytesHint: 'A saída além disso é transferida para um arquivo temporário em vez de ser perdida.', + overridden: 'Substituído', + reset: 'Redefinir para o padrão', + readOnly: 'Esta implantação armazena configurações somente leitura.', + unavailable: 'Este plugin não está carregado, portanto não pode ser configurado agora.', + save: 'Salvar', + saving: 'Salvando…', + saveFailed: 'A implantação não aceitou esses valores; eles foram deixados para você corrigir.', + invalidNumber: 'Insira um número ou deixe em branco para usar o padrão.', +} satisfies Record diff --git a/packages/client/ui-settings-subagent/locale/de.json b/packages/client/ui-settings-subagent/locale/de.json new file mode 100644 index 0000000000..ecce9cc69e --- /dev/null +++ b/packages/client/ui-settings-subagent/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Subagenteneinstellungen", + "description": "Konfigurieren Sie die Delegationstiefe, die Anzahl der Parallelitäten und optionale Modelle." + } +} diff --git a/packages/client/ui-settings-subagent/locale/es.json b/packages/client/ui-settings-subagent/locale/es.json new file mode 100644 index 0000000000..3323c6f124 --- /dev/null +++ b/packages/client/ui-settings-subagent/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Configuración de subagente", + "description": "Configure la profundidad de la delegación, el número de simultaneidades y modelos opcionales." + } +} diff --git a/packages/client/ui-settings-subagent/locale/fr.json b/packages/client/ui-settings-subagent/locale/fr.json new file mode 100644 index 0000000000..aec77b780f --- /dev/null +++ b/packages/client/ui-settings-subagent/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Paramètres du sous-agent", + "description": "Configurez la profondeur de la délégation, le nombre de simultanéités et les modèles facultatifs." + } +} diff --git a/packages/client/ui-settings-subagent/locale/pt.json b/packages/client/ui-settings-subagent/locale/pt.json new file mode 100644 index 0000000000..00b8568382 --- /dev/null +++ b/packages/client/ui-settings-subagent/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Configurações do subagente", + "description": "Configure a profundidade da delegação, o número de simultaneidades e os modelos opcionais." + } +} diff --git a/packages/client/ui-settings-subagent/locale/ru.json b/packages/client/ui-settings-subagent/locale/ru.json new file mode 100644 index 0000000000..7c74680dd0 --- /dev/null +++ b/packages/client/ui-settings-subagent/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Настройки субагента", + "description": "Настройте глубину делегирования, количество параллелизма и дополнительные модели." + } +} diff --git a/packages/client/ui-settings-subagent/src/client/index.ts b/packages/client/ui-settings-subagent/src/client/index.ts index 42811181ee..107e206b5b 100644 --- a/packages/client/ui-settings-subagent/src/client/index.ts +++ b/packages/client/ui-settings-subagent/src/client/index.ts @@ -23,7 +23,7 @@ import { SubagentLimitsCardController } from './subagent-limits-card-controller. import { SUBAGENT_MODEL_SELECTION_NS, SubagentModelSelectionCardController, } from './subagent-model-selection-card-controller.ts' -import { en, ja, zh, type SubagentSettingsLocaleKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh, type SubagentSettingsLocaleKey } from './locales.ts' export type { SubagentCardProps } from './SubagentCard.tsx' export type { SubagentCardFace } from './subagent-card-controller.ts' @@ -58,7 +58,7 @@ export const inject = ['slots', 'locale', 'remote', 'remote.session', 'configFor */ export function apply(ctx: ClientContext): void { const t = ctx.locale.bind(NS) - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-settings-subagent: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-settings-subagent: dictionaries') const limits = new SubagentLimitsCardController(ctx.configForms.get(SUBAGENT_NS)) ctx.effect(() => () => { limits.dispose() }, 'ui-settings-subagent: limits form subscription') const models = new SubagentModelSelectionCardController( diff --git a/packages/client/ui-settings-subagent/src/client/locales.ts b/packages/client/ui-settings-subagent/src/client/locales.ts index d92185f3dd..c33f16f00d 100644 --- a/packages/client/ui-settings-subagent/src/client/locales.ts +++ b/packages/client/ui-settings-subagent/src/client/locales.ts @@ -146,3 +146,198 @@ export const ja = { 'subagentModelSelectionConflict': '設定が別の場所で変更されました。下書きを破棄して再試行してください。', 'subagentModelSelectionOff': 'サブエージェントは設定済みのデフォルトを使用するか、親エージェントのモデルを継承します。保存済みのモデル選択は保持されます。', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + overridden: 'Anulado', + reset: 'Restablecer los valores predeterminados', + readOnly: 'Esta implementación almacena configuraciones de solo lectura.', + unavailable: 'Este complemento no está cargado, por lo que no se puede configurar en este momento.', + save: 'Guardar', + saving: 'Guardando…', + saveFailed: 'El despliegue no aceptó estos valores; quedaron para que usted los corrigiera.', + subagentTitle: 'Subagente', + subagentDescription: 'Establezca la profundidad, el recuento y los modelos de recursividad del subagente.', + subagentLimitsTitle: 'Límites', + subagentMaxDepth: 'Profundidad máxima de recursividad', + subagentDepthHelpLabel: 'Acerca de la profundidad máxima de recursividad', + subagentDepthHelp: 'Limita cuántos niveles de Subagentes puede crear un Agente.', + subagentDepthZero: 'Deshabilitar subagentes', + subagentDepthOne: 'Sólo el Agente principal puede crear Subagentes', + subagentDepthOverride: 'Si una herramienta define su propia profundidad de recursividad máxima, esa configuración tiene prioridad.', + subagentMaxActive: 'Límite de paralelismo de subagente', + subagentCapacityHelpLabel: 'Acerca del límite de paralelismo del subagente', + subagentCapacityHelp: 'Total de subagentes activos bajo el mismo agente principal, en todos los niveles de recursividad. El Agente principal está excluido. Las nuevas solicitudes de inicio se rechazan cuando se alcanza el límite.', + subagentDepthInvalid: 'Introduzca un número entero de 0 o más.', + subagentCapacityInvalid: 'Introduzca un número entero de 1 o más.', + subagentModelSelectionTitle: 'Selección de modelo', + subagentModelSelectionToggle: 'Permitir a los agentes elegir modelos para Subagentes', + subagentModelSelectionChoose: 'Cuando está habilitado, los agentes pueden elegir un proveedor, modelo y esfuerzo de razonamiento para cada subagente entre los modelos autorizados a continuación. Aplica sólo para sesiones nuevas.', + subagentModelSelectionAllowed: 'Los agentes modelos pueden elegir', + subagentModelSelectionLoading: 'Cargando modelos…', + subagentModelSelectionLoadFailed: 'No se pudieron cargar los modelos.', + subagentModelSelectionRetry: 'Reintentar', + subagentModelSelectionPartial: 'No se pudieron cargar algunos proveedores de modelos; Las opciones guardadas siguen siendo extraíbles.', + subagentModelSelectionUnavailable: 'Actualmente no disponible', + subagentModelSelectionUnavailableGroup: 'Guardado pero actualmente no disponible', + subagentModelSelectionEmpty: 'Ningún proveedor de modelos anuncia actualmente un modelo.', + subagentModelSelectionRequired: 'Seleccione al menos un modelo antes de guardar.', + subagentModelSelectionConflict: 'La configuración cambió en otros lugares. Descarta tu borrador y vuelve a intentarlo.', + subagentModelSelectionOff: 'Los subagentes utilizan valores predeterminados configurados o heredan el modelo del agente principal. Las opciones de modelo guardadas se conservan.', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + overridden: 'Remplacé', + reset: 'Réinitialiser aux valeurs par défaut', + readOnly: 'Ce déploiement stocke les paramètres en lecture seule.', + unavailable: "Ce plugin n'est pas chargé, il ne peut donc pas être configuré pour le moment.", + save: 'Enregistrer', + saving: 'Sauvegarde…', + saveFailed: "Le déploiement n'a pas accepté ces valeurs ; ils vous ont été laissés à corriger.", + subagentTitle: 'Sous-agent', + subagentDescription: 'Définissez la profondeur, le nombre et les modèles de récursion du sous-agent.', + subagentLimitsTitle: 'Limites', + subagentMaxDepth: 'Profondeur de récursion maximale', + subagentDepthHelpLabel: 'À propos de la profondeur de récursion maximale', + subagentDepthHelp: "Limite le nombre de niveaux de sous-agents qu'un agent peut créer.", + subagentDepthZero: 'Désactiver les sous-agents', + subagentDepthOne: "Seul l'agent principal peut créer des sous-agents", + subagentDepthOverride: 'Si un outil définit sa propre profondeur de récursion maximale, ce paramètre est prioritaire.', + subagentMaxActive: 'Limite de parallélisme des sous-agents', + subagentCapacityHelpLabel: 'À propos de la limite de parallélisme des sous-agents', + subagentCapacityHelp: "Total des sous-agents actifs sous le même agent principal, à tous les niveaux de récursion. L'Agent principal est exclu. Les nouvelles demandes de démarrage sont rejetées lorsque la limite est atteinte.", + subagentDepthInvalid: 'Entrez un nombre entier de 0 ou plus.', + subagentCapacityInvalid: 'Entrez un nombre entier de 1 ou plus.', + subagentModelSelectionTitle: 'Sélection du modèle', + subagentModelSelectionToggle: 'Autoriser les agents à choisir des modèles pour les sous-agents', + subagentModelSelectionChoose: "Lorsque cette option est activée, les agents peuvent choisir un fournisseur, un modèle et un effort de raisonnement pour chaque sous-agent parmi les modèles autorisés ci-dessous. S'applique uniquement aux nouvelles sessions.", + subagentModelSelectionAllowed: 'Les agents modèles peuvent choisir', + subagentModelSelectionLoading: 'Chargement des modèles…', + subagentModelSelectionLoadFailed: "Les modèles n'ont pas pu être chargés.", + subagentModelSelectionRetry: 'Réessayer', + subagentModelSelectionPartial: "Certains fournisseurs de modèles n'ont pas pu être chargés ; les choix enregistrés restent amovibles.", + subagentModelSelectionUnavailable: 'Actuellement indisponible', + subagentModelSelectionUnavailableGroup: 'Enregistré mais actuellement indisponible', + subagentModelSelectionEmpty: "Aucun fournisseur de modèles n'annonce actuellement un modèle.", + subagentModelSelectionRequired: 'Sélectionnez au moins un modèle avant de sauvegarder.', + subagentModelSelectionConflict: 'Paramètres modifiés ailleurs. Supprimez votre brouillon et réessayez.', + subagentModelSelectionOff: "Les sous-agents utilisent les valeurs par défaut configurées ou héritent du modèle de l'agent parent. Les choix de modèles enregistrés sont conservés.", +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + overridden: 'Überschrieben', + reset: 'Auf Standard zurücksetzen', + readOnly: 'Diese Bereitstellung speichert Einstellungen schreibgeschützt.', + unavailable: 'Dieses Plugin ist nicht geladen und kann daher derzeit nicht konfiguriert werden.', + save: 'Speichern', + saving: 'Sparen…', + saveFailed: 'Die Bereitstellung hat diese Werte nicht akzeptiert. Sie mussten sie korrigieren.', + subagentTitle: 'Subagent', + subagentDescription: 'Legen Sie die Rekursionstiefe, Anzahl und Modelle des Subagenten fest.', + subagentLimitsTitle: 'Grenzen', + subagentMaxDepth: 'Maximale Rekursionstiefe', + subagentDepthHelpLabel: 'Über maximale Rekursionstiefe', + subagentDepthHelp: 'Begrenzt die Anzahl der Ebenen von Subagenten, die ein Agent erstellen kann.', + subagentDepthZero: 'Subagenten deaktivieren', + subagentDepthOne: 'Nur der Hauptagent kann Unteragenten erstellen', + subagentDepthOverride: 'Wenn ein Werkzeug seine eigene maximale Rekursionstiefe definiert, hat diese Einstellung Vorrang.', + subagentMaxActive: 'Grenzwert für die Parallelität des Subagenten', + subagentCapacityHelpLabel: 'Informationen zum Subagenten-Parallelitätslimit', + subagentCapacityHelp: 'Gesamtzahl der Live-Subagenten unter demselben Hauptagenten, über alle Rekursionsebenen hinweg. Der Hauptvertreter ist ausgeschlossen. Neue Startanfragen werden abgelehnt, wenn das Limit erreicht ist.', + subagentDepthInvalid: 'Geben Sie eine ganze Zahl von 0 oder mehr ein.', + subagentCapacityInvalid: 'Geben Sie eine ganze Zahl von 1 oder mehr ein.', + subagentModelSelectionTitle: 'Modellauswahl', + subagentModelSelectionToggle: 'Erlauben Sie Agenten, Modelle für Subagenten auszuwählen', + subagentModelSelectionChoose: 'Wenn diese Option aktiviert ist, können Agenten aus den unten aufgeführten autorisierten Modellen einen Anbieter, ein Modell und einen Argumentationsaufwand für jeden Subagenten auswählen. Gilt nur für neue Sitzungen.', + subagentModelSelectionAllowed: 'Modelagenten können wählen', + subagentModelSelectionLoading: 'Modelle werden geladen…', + subagentModelSelectionLoadFailed: 'Modelle konnten nicht geladen werden.', + subagentModelSelectionRetry: 'Erneut versuchen', + subagentModelSelectionPartial: 'Einige Modellanbieter konnten nicht geladen werden; Gespeicherte Auswahlmöglichkeiten bleiben entfernbar.', + subagentModelSelectionUnavailable: 'Derzeit nicht verfügbar', + subagentModelSelectionUnavailableGroup: 'Gespeichert, aber derzeit nicht verfügbar', + subagentModelSelectionEmpty: 'Derzeit bewirbt kein Modelanbieter ein Model.', + subagentModelSelectionRequired: 'Wählen Sie vor dem Speichern mindestens ein Modell aus.', + subagentModelSelectionConflict: 'Einstellungen wurden an anderer Stelle geändert. Verwerfen Sie Ihren Entwurf und versuchen Sie es erneut.', + subagentModelSelectionOff: 'Subagenten verwenden konfigurierte Standardwerte oder erben das Modell des übergeordneten Agenten. Gespeicherte Modellauswahlen bleiben erhalten.', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + overridden: 'Переопределено', + reset: 'Сбросить настройки по умолчанию', + readOnly: 'В этом развертывании параметры сохраняются только для чтения.', + unavailable: 'Этот плагин не загружен, поэтому его невозможно настроить прямо сейчас.', + save: 'Сохранить', + saving: 'Сохранение…', + saveFailed: 'Развертывание не приняло эти значения; их оставили вам на исправление.', + subagentTitle: 'Субагент', + subagentDescription: 'Установите глубину рекурсии субагента, количество и модели.', + subagentLimitsTitle: 'Пределы', + subagentMaxDepth: 'Максимальная глубина рекурсии', + subagentDepthHelpLabel: 'О максимальной глубине рекурсии', + subagentDepthHelp: 'Ограничивает количество уровней субагентов, которые может создать агент.', + subagentDepthZero: 'Отключить субагенты', + subagentDepthOne: 'Только главный агент может создавать субагентов.', + subagentDepthOverride: 'Если инструмент определяет собственную максимальную глубину рекурсии, этот параметр имеет приоритет.', + subagentMaxActive: 'Предел параллелизма субагентов', + subagentCapacityHelpLabel: 'О пределе параллелизма субагентов', + subagentCapacityHelp: 'Общее количество действующих субагентов под одним и тем же основным агентом на всех уровнях рекурсии. Главный Агент исключен. Новые запросы на запуск отклоняются при достижении предела.', + subagentDepthInvalid: 'Введите целое число от 0 или более.', + subagentCapacityInvalid: 'Введите целое число от 1 или более.', + subagentModelSelectionTitle: 'Выбор модели', + subagentModelSelectionToggle: 'Разрешить агентам выбирать модели для субагентов', + subagentModelSelectionChoose: 'Если этот параметр включен, агенты могут выбирать поставщика, модель и усилия по обоснованию для каждого субагента из авторизованных моделей, указанных ниже. Применяется только к новым сеансам.', + subagentModelSelectionAllowed: 'Модели агенты могут выбирать', + subagentModelSelectionLoading: 'Загрузка моделей…', + subagentModelSelectionLoadFailed: 'Не удалось загрузить модели.', + subagentModelSelectionRetry: 'Повторить', + subagentModelSelectionPartial: 'Некоторые поставщики моделей не удалось загрузить; сохраненные варианты остаются съемными.', + subagentModelSelectionUnavailable: 'В настоящее время недоступен', + subagentModelSelectionUnavailableGroup: 'Сохранено, но сейчас недоступно', + subagentModelSelectionEmpty: 'Ни один поставщик моделей в настоящее время не рекламирует модель.', + subagentModelSelectionRequired: 'Прежде чем сохранить, выберите хотя бы одну модель.', + subagentModelSelectionConflict: 'Настройки изменены в другом месте. Отмените черновик и повторите попытку.', + subagentModelSelectionOff: 'Субагенты используют настроенные значения по умолчанию или наследуют модель родительского агента. Сохраненные варианты моделей сохраняются.', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + overridden: 'Substituído', + reset: 'Redefinir para o padrão', + readOnly: 'Esta implantação armazena configurações somente leitura.', + unavailable: 'Este plugin não está carregado, portanto não pode ser configurado agora.', + save: 'Salvar', + saving: 'Salvando…', + saveFailed: 'A implantação não aceitou esses valores; eles foram deixados para você corrigir.', + subagentTitle: 'Subagente', + subagentDescription: 'Defina a profundidade, a contagem e os modelos de recursão do subagente.', + subagentLimitsTitle: 'Limites', + subagentMaxDepth: 'Profundidade máxima de recursão', + subagentDepthHelpLabel: 'Sobre a profundidade máxima de recursão', + subagentDepthHelp: 'Limita quantos níveis de Subagentes um Agente pode criar.', + subagentDepthZero: 'Desabilitar subagentes', + subagentDepthOne: 'Somente o Agente principal pode criar Subagentes', + subagentDepthOverride: 'Se uma ferramenta definir sua própria profundidade máxima de recursão, essa configuração terá precedência.', + subagentMaxActive: 'Limite de paralelismo de subagentes', + subagentCapacityHelpLabel: 'Sobre o limite de paralelismo do subagente', + subagentCapacityHelp: 'Total de subagentes ativos sob o mesmo agente principal, em todos os níveis de recursão. O Agente principal é excluído. Novas solicitações de início serão rejeitadas quando o limite for atingido.', + subagentDepthInvalid: 'Insira um número inteiro de 0 ou mais.', + subagentCapacityInvalid: 'Insira um número inteiro de 1 ou mais.', + subagentModelSelectionTitle: 'Seleção de modelo', + subagentModelSelectionToggle: 'Permitir que os agentes escolham modelos para subagentes', + subagentModelSelectionChoose: 'Quando ativado, os agentes podem escolher um provedor, um modelo e um esforço de raciocínio para cada subagente dentre os modelos autorizados abaixo. Aplica-se apenas a novas sessões.', + subagentModelSelectionAllowed: 'Os agentes de modelos podem escolher', + subagentModelSelectionLoading: 'Carregando modelos…', + subagentModelSelectionLoadFailed: 'Não foi possível carregar os modelos.', + subagentModelSelectionRetry: 'Tentar novamente', + subagentModelSelectionPartial: 'Alguns provedores de modelo não puderam ser carregados; as escolhas salvas permanecem removíveis.', + subagentModelSelectionUnavailable: 'Atualmente indisponível', + subagentModelSelectionUnavailableGroup: 'Salvo, mas atualmente indisponível', + subagentModelSelectionEmpty: 'Atualmente, nenhum fornecedor de modelos anuncia um modelo.', + subagentModelSelectionRequired: 'Selecione pelo menos um modelo antes de salvar.', + subagentModelSelectionConflict: 'Configurações alteradas em outro lugar. Descarte seu rascunho e tente novamente.', + subagentModelSelectionOff: 'Os subagentes usam padrões configurados ou herdam o modelo do agente pai. As opções de modelo salvas são mantidas.', +} satisfies Record diff --git a/packages/client/ui-settings-web-search/locale/de.json b/packages/client/ui-settings-web-search/locale/de.json new file mode 100644 index 0000000000..5aa238488d --- /dev/null +++ b/packages/client/ui-settings-web-search/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Einstellungen für die Websuche", + "description": "Konfigurieren Sie den Schlüssel, die Dienstadresse und das Anforderungsbudget für die DeepSeek-Websuche." + } +} diff --git a/packages/client/ui-settings-web-search/locale/es.json b/packages/client/ui-settings-web-search/locale/es.json new file mode 100644 index 0000000000..1e1d3f5e7b --- /dev/null +++ b/packages/client/ui-settings-web-search/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Configuración de búsqueda web", + "description": "Configure la clave, la dirección del servicio y solicite el presupuesto para la búsqueda web DeepSeek." + } +} diff --git a/packages/client/ui-settings-web-search/locale/fr.json b/packages/client/ui-settings-web-search/locale/fr.json new file mode 100644 index 0000000000..6c20e4212a --- /dev/null +++ b/packages/client/ui-settings-web-search/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Paramètres de recherche sur le Web", + "description": "Configurez la clé, l'adresse du service et le budget de demande pour la recherche sur le Web DeepSeek." + } +} diff --git a/packages/client/ui-settings-web-search/locale/pt.json b/packages/client/ui-settings-web-search/locale/pt.json new file mode 100644 index 0000000000..ce7d68d86c --- /dev/null +++ b/packages/client/ui-settings-web-search/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Configurações de pesquisa na web", + "description": "Configure a chave, o endereço do serviço e solicite o orçamento para DeepSeek pesquisa na web." + } +} diff --git a/packages/client/ui-settings-web-search/locale/ru.json b/packages/client/ui-settings-web-search/locale/ru.json new file mode 100644 index 0000000000..b8bd1cd774 --- /dev/null +++ b/packages/client/ui-settings-web-search/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Настройки веб-поиска", + "description": "Настройте ключ, адрес службы и бюджет запроса для веб-поиска DeepSeek." + } +} diff --git a/packages/client/ui-settings-web-search/src/client/index.ts b/packages/client/ui-settings-web-search/src/client/index.ts index 461237a165..b4ed1c6779 100644 --- a/packages/client/ui-settings-web-search/src/client/index.ts +++ b/packages/client/ui-settings-web-search/src/client/index.ts @@ -22,7 +22,7 @@ import type {} from '@deepseek-ai/dsh-api-remotes/client' import type { Context as ClientContext } from '@deepseek-ai/cordis' import { WebSearchCard } from './WebSearchCard.tsx' import { WEB_API_NS, WEB_NS, WEB_SEARCH_NS, WebSearchCardController } from './web-search-card-controller.ts' -import { en, ja, zh, type WebSearchSettingsLocaleKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh, type WebSearchSettingsLocaleKey } from './locales.ts' export type { WebSearchCardProps } from './WebSearchCard.tsx' export type { @@ -49,7 +49,7 @@ export const inject = ['slots', 'locale', 'remote', 'remote.credentials', 'confi */ export function apply(ctx: ClientContext): void { const t = ctx.locale.bind(NS) - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-settings-web-search: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-settings-web-search: dictionaries') const card = new WebSearchCardController({ web: ctx.configForms.get(WEB_NS), messages: ctx.configForms.get(WEB_SEARCH_NS), api: ctx.configForms.get(WEB_API_NS), }, ctx) diff --git a/packages/client/ui-settings-web-search/src/client/locales.ts b/packages/client/ui-settings-web-search/src/client/locales.ts index 65d21ae8f0..83c1574a59 100644 --- a/packages/client/ui-settings-web-search/src/client/locales.ts +++ b/packages/client/ui-settings-web-search/src/client/locales.ts @@ -111,3 +111,158 @@ export const ja = { 'invalidNumber': '数値を入力するか、デフォルトを使用するには空欄にしてください。', 'invalidCount': '1〜50 の整数を入力するか、デフォルトを使用するには空欄にしてください。', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + title: 'búsqueda web', + description: 'Configure el proveedor de búsqueda DeepSeek.', + useSearchApi: 'Utilice la nueva búsqueda web API', + useSearchApiHint: 'Desactivado de forma predeterminada: la búsqueda se ejecuta a través de Mensajes DeepSeek. Para conocer las características y los precios del nuevo Web Search API, consulte el ', + searchGuide: 'Guía de búsqueda y recuperación', + searchGuideUrl: 'https://api-docs.deepseek.com/guides/search', + apiKey: 'Tecla API', + apiKeyHint: 'Almacenado fuera del archivo de configuración. Déjelo en blanco para conservar la clave actual.', + apiKeySet: 'Se configura una clave.', + apiKeyUnset: 'No hay ninguna clave configurada; solo se pueden buscar conversaciones que utilicen un modelo de cuenta DeepSeek, a través del punto final predeterminado.', + baseUrl: 'Mensajes API URL base', + baseUrlHint: 'Incluya el prefijo API, como https://api.deepseek.com/anthropic/v1.. El proveedor agrega /messages. Déjelo en blanco para restaurar el valor predeterminado.', + searchApiBaseUrl: 'Buscar/obtener URL base API', + searchApiBaseUrlHint: 'Incluya el prefijo API, como https://api.deepseek.com/v1/tools.. El proveedor agrega /search o /fetch. Déjelo en blanco para restaurar el valor predeterminado.', + maxUses: 'Búsquedas máximas por solicitud', + maxUsesHint: 'Cuántas búsquedas puede ejecutar el modelo auxiliar dentro de una solicitud de Mensajes. Aplica sólo para Mensajes API.', + count: 'Resultados por búsqueda', + countHint: 'Resultados devueltos por consulta: un número entero del 1 al 50, valor predeterminado 10. Esto controla el recuento de resultados, no las llamadas de búsqueda. web_search no guarda más fuentes que su propio límite de resultados.', + overridden: 'Anulado', + reset: 'Restablecer los valores predeterminados', + readOnly: 'Esta implementación almacena configuraciones de solo lectura.', + unavailable: 'Este complemento no está cargado, por lo que no se puede configurar en este momento.', + save: 'Guardar', + saving: 'Guardando…', + saveFailed: 'El despliegue no aceptó estos valores; quedaron para que usted los corrigiera.', + invalidNumber: 'Ingrese un número o déjelo en blanco para usar el valor predeterminado.', + invalidCount: 'Ingrese un número entero del 1 al 50 o déjelo en blanco para usar el valor predeterminado.', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + title: 'Recherche sur le Web', + description: 'Configurez le moteur de recherche DeepSeek.', + useSearchApi: 'Utilisez la nouvelle recherche Web API', + useSearchApiHint: "Désactivé par défaut : la recherche s'effectue dans les messages DeepSeek. Pour connaître les fonctionnalités et les tarifs du nouveau Web Search API, consultez le ", + searchGuide: 'Guide de recherche et de récupération', + searchGuideUrl: 'https://api-docs.deepseek.com/guides/search', + apiKey: 'Clé API', + apiKeyHint: 'Stocké en dehors du fichier de paramètres. Laissez vide pour conserver la clé actuelle.', + apiKeySet: 'Une clé est configurée.', + apiKeyUnset: "Aucune clé n'est configurée ; seules les conversations utilisant un modèle de compte DeepSeek peuvent effectuer une recherche, via le point de terminaison par défaut.", + baseUrl: 'URL de base des messages API', + baseUrlHint: 'Incluez le préfixe API, tel que https://api.deepseek.com/anthropic/v1.. Le fournisseur ajoute /messages. Laissez vide pour restaurer la valeur par défaut.', + searchApiBaseUrl: "Rechercher/récupérer l'URL de base de API", + searchApiBaseUrlHint: 'Incluez le préfixe API, tel que https://api.deepseek.com/v1/tools.. Le fournisseur ajoute /search ou /fetch. Laissez vide pour restaurer la valeur par défaut.', + maxUses: 'Nombre maximum de recherches par requête', + maxUsesHint: "Combien de recherches le modèle auxiliaire peut exécuter dans une requête de messages. S'applique uniquement aux messages API.", + count: 'Résultats par recherche', + countHint: 'Résultats renvoyés par requête : un nombre entier de 1 à 50, 10 par défaut. Cela contrôle le nombre de résultats, pas les appels de recherche. web_search ne conserve pas plus de sources que sa propre limite de résultats.', + overridden: 'Remplacé', + reset: 'Réinitialiser aux valeurs par défaut', + readOnly: 'Ce déploiement stocke les paramètres en lecture seule.', + unavailable: "Ce plugin n'est pas chargé, il ne peut donc pas être configuré pour le moment.", + save: 'Enregistrer', + saving: 'Sauvegarde…', + saveFailed: "Le déploiement n'a pas accepté ces valeurs ; ils vous ont été laissés à corriger.", + invalidNumber: 'Entrez un numéro ou laissez ce champ vide pour utiliser la valeur par défaut.', + invalidCount: 'Entrez un nombre entier compris entre 1 et 50 ou laissez vide pour utiliser la valeur par défaut.', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + title: 'Websuche', + description: 'Richten Sie den Suchanbieter DeepSeek ein.', + useSearchApi: 'Nutzen Sie die neue Websuche API', + useSearchApiHint: 'Standardmäßig deaktiviert: Die Suche erfolgt über DeepSeek-Nachrichten. Informationen zu den Funktionen und Preisen der neuen Websuche API finden Sie im ', + searchGuide: 'Leitfaden zum Suchen und Abrufen', + searchGuideUrl: 'https://api-docs.deepseek.com/guides/search', + apiKey: 'API-Schlüssel', + apiKeyHint: 'Außerhalb der Einstellungsdatei gespeichert. Lassen Sie das Feld leer, um den aktuellen Schlüssel beizubehalten.', + apiKeySet: 'Ein Schlüssel ist konfiguriert.', + apiKeyUnset: 'Es ist kein Schlüssel konfiguriert; Nur Konversationen, die ein DeepSeek-Kontomodell verwenden, können über den Standardendpunkt suchen.', + baseUrl: 'Nachrichten API Basis-URL', + baseUrlHint: 'Fügen Sie das Präfix API ein, z. B. https://api.deepseek.com/anthropic/v1.. Der Anbieter hängt /messages an. Lassen Sie das Feld leer, um die Standardeinstellung wiederherzustellen.', + searchApiBaseUrl: 'Suchen/Abrufen der API-Basis-URL', + searchApiBaseUrlHint: 'Fügen Sie das Präfix API ein, z. B. https://api.deepseek.com/v1/tools.. Der Anbieter hängt /search oder /fetch an. Lassen Sie das Feld leer, um die Standardeinstellung wiederherzustellen.', + maxUses: 'Maximale Anzahl an Suchanfragen pro Anfrage', + maxUsesHint: 'Wie viele Suchvorgänge das Hilfsmodell innerhalb einer Nachrichtenanforderung ausführen darf. Gilt nur für die Nachrichten API.', + count: 'Ergebnisse pro Suche', + countHint: 'Pro Abfrage zurückgegebene Ergebnisse: eine Ganzzahl von 1 bis 50, Standard 10. Dies steuert die Ergebnisanzahl, nicht Suchaufrufe. web_search behält nicht mehr Quellen als sein eigenes Ergebnislimit.', + overridden: 'Überschrieben', + reset: 'Auf Standard zurücksetzen', + readOnly: 'Diese Bereitstellung speichert Einstellungen schreibgeschützt.', + unavailable: 'Dieses Plugin ist nicht geladen und kann daher derzeit nicht konfiguriert werden.', + save: 'Speichern', + saving: 'Sparen…', + saveFailed: 'Die Bereitstellung hat diese Werte nicht akzeptiert. Sie mussten sie korrigieren.', + invalidNumber: 'Geben Sie eine Zahl ein oder lassen Sie das Feld leer, um den Standardwert zu verwenden.', + invalidCount: 'Geben Sie eine Ganzzahl zwischen 1 und 50 ein oder lassen Sie das Feld leer, um den Standardwert zu verwenden.', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + title: 'Веб-поиск', + description: 'Настройте поисковую систему DeepSeek.', + useSearchApi: 'Используйте новый веб-поиск API', + useSearchApiHint: 'По умолчанию отключено: поиск осуществляется по сообщениям DeepSeek. Информацию о новых функциях и ценах веб-поиска API см. ', + searchGuide: 'Руководство по поиску и получению', + searchGuideUrl: 'https://api-docs.deepseek.com/guides/search', + apiKey: 'Ключ API', + apiKeyHint: 'Хранится вне файла настроек. Оставьте пустым, чтобы сохранить текущий ключ.', + apiKeySet: 'Ключ настроен.', + apiKeyUnset: 'Ключ не настроен; только разговоры, использующие модель учетной записи DeepSeek, могут выполнять поиск через конечную точку по умолчанию.', + baseUrl: 'Базовый URL-адрес сообщений API', + baseUrlHint: 'Включите префикс API, например https://api.deepseek.com/anthropic/v1.. Поставщик добавляет /messages. Оставьте пустым, чтобы восстановить значение по умолчанию.', + searchApiBaseUrl: 'Найдите/получите базовый URL-адрес API', + searchApiBaseUrlHint: 'Включите префикс API, например https://api.deepseek.com/v1/tools.. Поставщик добавляет /search или /fetch. Оставьте пустым, чтобы восстановить значение по умолчанию.', + maxUses: 'Максимальное количество запросов на запрос', + maxUsesHint: 'Сколько поисков вспомогательная модель может выполнить в рамках одного запроса сообщений. Применяется только к сообщениям API.', + count: 'Результаты по поиску', + countHint: 'Результаты, возвращаемые по запросу: целое число от 1 до 50, по умолчанию 10. Это контролирует количество результатов, а не поисковые вызовы. web_search хранит не больше источников, чем его собственный лимит результатов.', + overridden: 'Переопределено', + reset: 'Сбросить настройки по умолчанию', + readOnly: 'В этом развертывании параметры сохраняются только для чтения.', + unavailable: 'Этот плагин не загружен, поэтому его невозможно настроить прямо сейчас.', + save: 'Сохранить', + saving: 'Сохранение…', + saveFailed: 'Развертывание не приняло эти значения; их оставили вам на исправление.', + invalidNumber: 'Введите число или оставьте поле пустым, чтобы использовать значение по умолчанию.', + invalidCount: 'Введите целое число от 1 до 50 или оставьте поле пустым, чтобы использовать значение по умолчанию.', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + title: 'Pesquisa na web', + description: 'Configure o provedor de pesquisa DeepSeek.', + useSearchApi: 'Use a nova Pesquisa na Web API', + useSearchApiHint: 'Desativado por padrão: a pesquisa é executada em DeepSeek Mensagens. Para conhecer os recursos e preços da nova Pesquisa na Web API, consulte o ', + searchGuide: 'Guia de pesquisa e busca', + searchGuideUrl: 'https://api-docs.deepseek.com/guides/search', + apiKey: 'API chave', + apiKeyHint: 'Armazenado fora do arquivo de configurações. Deixe em branco para manter a chave atual.', + apiKeySet: 'Uma chave está configurada.', + apiKeyUnset: 'Nenhuma chave está configurada; somente conversas que usam um modelo de conta DeepSeek podem pesquisar, por meio do endpoint padrão.', + baseUrl: 'URL base de mensagens API', + baseUrlHint: 'Inclua o prefixo API, como https://api.deepseek.com/anthropic/v1. O provedor anexa /messages. Deixe em branco para restaurar o padrão.', + searchApiBaseUrl: 'Pesquisar/buscar API URL base', + searchApiBaseUrlHint: 'Inclua o prefixo API, como https://api.deepseek.com/v1/tools. O provedor anexa /search ou /fetch. Deixe em branco para restaurar o padrão.', + maxUses: 'Máximo de pesquisas por solicitação', + maxUsesHint: 'Quantas pesquisas o modelo auxiliar pode executar em uma solicitação de Mensagens. Aplica-se somente às Mensagens API.', + count: 'Resultados por pesquisa', + countHint: 'Resultados retornados por consulta: um número inteiro de 1 a 50, padrão 10. Isso controla a contagem de resultados, não as chamadas de pesquisa. web_search não mantém mais fontes do que seu próprio limite de resultados.', + overridden: 'Substituído', + reset: 'Redefinir para o padrão', + readOnly: 'Esta implantação armazena configurações somente leitura.', + unavailable: 'Este plugin não está carregado, portanto não pode ser configurado agora.', + save: 'Salvar', + saving: 'Salvando…', + saveFailed: 'A implantação não aceitou esses valores; eles foram deixados para você corrigir.', + invalidNumber: 'Insira um número ou deixe em branco para usar o padrão.', + invalidCount: 'Insira um número inteiro de 1 a 50 ou deixe em branco para usar o padrão.', +} satisfies Record diff --git a/packages/client/ui-settings/locale/de.json b/packages/client/ui-settings/locale/de.json new file mode 100644 index 0000000000..c0a32190bd --- /dev/null +++ b/packages/client/ui-settings/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Schnittstellenrahmen festlegen", + "description": "Stellt das Grundformular und den Plug-in-Erweiterungsspeicherort der Einstellungsseite bereit." + } +} diff --git a/packages/client/ui-settings/locale/es.json b/packages/client/ui-settings/locale/es.json new file mode 100644 index 0000000000..f703fc3c6e --- /dev/null +++ b/packages/client/ui-settings/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Establecer marco de interfaz", + "description": "Proporciona el formulario básico y la ubicación de la extensión del complemento de la página de configuración." + } +} diff --git a/packages/client/ui-settings/locale/fr.json b/packages/client/ui-settings/locale/fr.json new file mode 100644 index 0000000000..4e500b24d0 --- /dev/null +++ b/packages/client/ui-settings/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Définir le cadre de l'interface", + "description": "Fournit le formulaire de base et l’emplacement de l’extension du plug-in de la page des paramètres." + } +} diff --git a/packages/client/ui-settings/locale/pt.json b/packages/client/ui-settings/locale/pt.json new file mode 100644 index 0000000000..4aebe79237 --- /dev/null +++ b/packages/client/ui-settings/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Definir quadro de interface", + "description": "Fornece o formulário básico e a localização da extensão do plug-in da página de configurações." + } +} diff --git a/packages/client/ui-settings/locale/ru.json b/packages/client/ui-settings/locale/ru.json new file mode 100644 index 0000000000..bd60ab3572 --- /dev/null +++ b/packages/client/ui-settings/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Установить фрейм интерфейса", + "description": "Предоставляет базовую форму и расположение расширения подключаемого модуля на странице настроек." + } +} diff --git a/packages/client/ui-shortcuts/locale/de.json b/packages/client/ui-shortcuts/locale/de.json new file mode 100644 index 0000000000..f6fef238f7 --- /dev/null +++ b/packages/client/ui-shortcuts/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Schnittstelle zum Festlegen von Tastenkombinationen", + "description": "Tastaturkürzel anzeigen, eingeben und ändern." + } +} diff --git a/packages/client/ui-shortcuts/locale/es.json b/packages/client/ui-shortcuts/locale/es.json new file mode 100644 index 0000000000..e01ec944f6 --- /dev/null +++ b/packages/client/ui-shortcuts/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de configuración de teclas de acceso directo", + "description": "Ver, ingresar y modificar atajos de teclado." + } +} diff --git a/packages/client/ui-shortcuts/locale/fr.json b/packages/client/ui-shortcuts/locale/fr.json new file mode 100644 index 0000000000..bbaa18731d --- /dev/null +++ b/packages/client/ui-shortcuts/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de configuration des touches de raccourci", + "description": "Afficher, saisir et modifier les raccourcis clavier." + } +} diff --git a/packages/client/ui-shortcuts/locale/pt.json b/packages/client/ui-shortcuts/locale/pt.json new file mode 100644 index 0000000000..85767dbdff --- /dev/null +++ b/packages/client/ui-shortcuts/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de configuração de teclas de atalho", + "description": "Visualize, insira e modifique atalhos de teclado." + } +} diff --git a/packages/client/ui-shortcuts/locale/ru.json b/packages/client/ui-shortcuts/locale/ru.json new file mode 100644 index 0000000000..b9152041ee --- /dev/null +++ b/packages/client/ui-shortcuts/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Интерфейс настройки сочетаний клавиш", + "description": "Просмотр, ввод и изменение сочетаний клавиш." + } +} diff --git a/packages/client/ui-shortcuts/src/client/index.ts b/packages/client/ui-shortcuts/src/client/index.ts index 9e0d508833..1de049aec6 100644 --- a/packages/client/ui-shortcuts/src/client/index.ts +++ b/packages/client/ui-shortcuts/src/client/index.ts @@ -8,7 +8,7 @@ import type {} from '@deepseek-ai/dsh-client-ui-layout/client' import type {} from '@deepseek-ai/dsh-client-ui-settings/client' import { createShortcutsStore } from './store.ts' import { ShortcutReference, ShortcutsRow } from './Reference.tsx' -import { en, ja, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh } from './locales.ts' import { fixedCommands } from './fixed.ts' declare module '@deepseek-ai/dsh-client-ui-slots' { @@ -26,7 +26,7 @@ export const inject = ['shortcuts', 'locale', 'slots'] * @param ctx - plugin-owned client context. */ export function apply(ctx: Context): void { - ctx.effect(() => ctx.locale.register('shortcuts', { zh, en, ja }), 'shortcuts: dictionaries') + ctx.effect(() => ctx.locale.register('shortcuts', { zh, en, ja, es, fr, de, ru, pt }), 'shortcuts: dictionaries') const t = ctx.locale.bind('shortcuts') const handle = createShortcutsStore() const instance = handle.create() diff --git a/packages/client/ui-shortcuts/src/client/locales.ts b/packages/client/ui-shortcuts/src/client/locales.ts index e96e4457da..f0eb8bbf06 100644 --- a/packages/client/ui-shortcuts/src/client/locales.ts +++ b/packages/client/ui-shortcuts/src/client/locales.ts @@ -128,3 +128,183 @@ export const ja = { 'select': 'メニュー項目を選択', 'dismiss': 'メニューまたは最上位ダイアログを閉じる', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'edit-label': 'Editar acceso directo para {command}', + record: 'Presione un atajo', 'record-help': 'Suelta las teclas para guardar. La pestaña se mueve entre acciones; Esc se cancela.', + 'web-help': 'Combinaciones de navegador: Mod+/, Mod+Shift+, Mod+Shift+... Mod es Comando en Mac y Ctrl en otros lugares.', + 'unsupported-key': 'Esta clave no es compatible.', reserved: 'Esta combinación está reservada para acciones de edición de texto o del sistema.', + 'modifier-required': 'Incluya Comando, Ctrl o Alt en la combinación.', + 'too-many-keys': 'Mantenga presionadas como máximo dos teclas no modificadoras. Suelta las teclas para volver a intentarlo.', + 'macos-web-help': 'Utilice Comando+/, Comando+, Comando+barra invertida, Control+comillas invertidas, Comando+Opción+tecla o Comando+Mayús+tecla. También se admiten combinaciones con tres o cuatro modificadores distintos. Es posible que los accesos directos del navegador o del sistema no lleguen a la página.', + 'windows-web-help': 'Utilice Ctrl+/, Ctrl+, Ctrl+Alt+tecla o Ctrl+Shift+tecla. También se admiten combinaciones con tres o cuatro modificadores distintos. Es posible que los accesos directos del navegador o del sistema no lleguen a la página.', + 'unsupported-browser': 'Este navegador aún no admite esta combinación.', conflict: 'Ya utilizado por “{commands}”', + saved: 'Modificado', clear: 'Quitar', 'retry-save': 'Reintentar guardar', reset: 'Restaurar valor predeterminado', + 'reset-all': 'Restaurar todos los valores predeterminados', 'modified-count': '{count} personalizado', + 'reset-title': '¿Restaurar todos los atajos predeterminados?', + 'reset-description': 'Restaure los accesos directos predeterminados para esta plataforma. Se restaurarán todos los accesos directos modificados o eliminados. Otras plataformas no se ven afectadas.', + cancel: 'Cancelar', 'reset-saved': 'Accesos directos predeterminados restaurados', + 'close-confirmation': 'Cerrar confirmación', 'reset-failed': 'No se pudieron restaurar los valores predeterminados. Tus atajos no han cambiado. Vuelva a intentarlo.', + review: 'He revisado la última configuración.', + stale: 'La configuración de accesos directos o los comandos disponibles cambiaron. Revise los enlaces más recientes antes de guardar.', + 'write-failed': 'No se pudo guardar. Se conservan sus atajos anteriores y el borrador actual. Vuelva a intentarlo.', + 'not-ready': 'Los atajos no están listos. Por favor inténtalo de nuevo.', + read: 'No se pudo leer {location}. Verifique los permisos de acceso, luego {reload}.', + invalid: 'La configuración de acceso directo en {location} está dañada. Haga una copia de seguridad y repare esta configuración, luego {reload}.', + future: 'La configuración de acceso directo en {location} fue creada por una versión más reciente. Actualice el arnés e inténtelo de nuevo.', + 'web-document': 'la entrada de almacenamiento local de este sitio dsh.keybindings.v1', 'desktop-document': 'datos de usuario/bindings.json', + 'web-reload': 'recargar la pagina', 'desktop-reload': 'reiniciar el arnés', + 'using-defaults': 'Los enlaces predeterminados están activos.', 'using-accepted': 'Los últimos enlaces leídos correctamente permanecen activos.', + 'native-failed': 'No se pudo proteger la grabación de claves del escritorio. Salga de la grabación y vuelva a intentarlo.', + 'global-hint': 'Abierto desde cualquier lugar', 'clear-search': 'Borrar búsqueda', + title: 'Atajos de teclado', open: 'Abrir atajos de teclado', settings: 'Atajos de teclado', view: 'Editar atajos', + description: 'Ver y editar atajos disponibles y acciones de entrada', search: 'Buscar atajos', close: 'Cerrar atajos de teclado', + application: 'Solicitud', input: 'Entrada de mensaje', menus: 'Menús y cuadros de diálogo', approval: 'Área de aprobación', unbound: 'Sin atajos', + empty: 'No hay atajos coincidentes', + move: 'Mover selección de menú', select: 'Seleccionar elemento del menú', dismiss: 'Cerrar menú o cuadro de diálogo superior', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'edit-label': 'Modifier le raccourci pour {command}', + record: 'Appuyez sur un raccourci', 'record-help': "Relâchez les touches pour enregistrer. L'onglet se déplace entre les actions ; Esc annule.", + 'web-help': 'Combinaisons de navigateur : Mod+/, Mod+Shift+,, Mod+Shift+.. Mod est Command sur Mac et Ctrl ailleurs.', + 'unsupported-key': "Cette clé n'est pas prise en charge.", reserved: "Cette combinaison est réservée aux actions système ou d'édition de texte.", + 'modifier-required': 'Incluez Commande, Ctrl ou Alt dans la combinaison.', + 'too-many-keys': 'Tenez au plus deux clés non modificatrices. Relâchez les touches pour réessayer.', + 'macos-web-help': 'Utilisez Command+/, Command+,, Command+Backslash, Control+Backquote, Command+Option+key ou Command+Shift+key. Les combinaisons avec trois ou quatre modificateurs distincts sont également prises en charge. Les raccourcis du navigateur ou du système peuvent ne pas atteindre la page.', + 'windows-web-help': 'Utilisez Ctrl+/, Ctrl+,, Ctrl+Alt+touche ou Ctrl+Shift+touche. Les combinaisons avec trois ou quatre modificateurs distincts sont également prises en charge. Les raccourcis du navigateur ou du système peuvent ne pas atteindre la page.', + 'unsupported-browser': 'Ce navigateur ne prend pas encore en charge cette combinaison.', conflict: 'Déjà utilisé par « {commands} »', + saved: 'Modifié', clear: 'Supprimer', 'retry-save': "Réessayez d'enregistrer", reset: 'Restaurer les valeurs par défaut', + 'reset-all': 'Restaurer tous les paramètres par défaut', 'modified-count': '{count} personnalisé', + 'reset-title': 'Restaurer tous les raccourcis par défaut ?', + 'reset-description': 'Restaurez les raccourcis par défaut pour cette plateforme. Tous les raccourcis modifiés ou supprimés seront restaurés. Les autres plateformes ne sont pas affectées.', + cancel: 'Annuler', 'reset-saved': 'Raccourcis par défaut restaurés', + 'close-confirmation': 'Fermer la confirmation', 'reset-failed': 'Impossible de restaurer les valeurs par défaut. Vos raccourcis restent inchangés. Veuillez réessayer.', + review: "J'ai examiné la dernière configuration", + stale: 'La configuration des raccourcis ou les commandes disponibles ont été modifiées. Vérifiez les dernières liaisons avant de les enregistrer.', + 'write-failed': "Impossible d'enregistrer. Vos raccourcis précédents et votre brouillon actuel sont conservés. Veuillez réessayer.", + 'not-ready': 'Les raccourcis ne sont pas prêts. Veuillez réessayer.', + read: "Impossible de lire {location}. Vérifiez les autorisations d'accès, puis {reload}.", + invalid: 'La configuration des raccourcis dans {location} est endommagée. Sauvegardez et réparez cette configuration, puis {reload}.', + future: 'La configuration des raccourcis dans {location} a été créée par une version plus récente. Mettez à niveau le harnais et réessayez.', + 'web-document': "l'entrée localStorage de ce site dsh.keybindings.v1", 'desktop-document': 'userData/keybindings.json', + 'web-reload': 'recharger la page', 'desktop-reload': 'redémarrer le harnais', + 'using-defaults': 'Les liaisons par défaut sont actives.', 'using-accepted': 'Les dernières liaisons lues avec succès restent actives.', + 'native-failed': "Impossible de protéger l'enregistrement des clés du bureau. Quittez l'enregistrement et réessayez.", + 'global-hint': "Ouvert de n'importe où", 'clear-search': 'Effacer la recherche', + title: 'Raccourcis clavier', open: 'Ouvrir les raccourcis clavier', settings: 'Raccourcis clavier', view: 'Modifier les raccourcis', + description: 'Afficher et modifier les raccourcis et les actions de saisie disponibles', search: 'Raccourcis de recherche', close: 'Fermer les raccourcis clavier', + application: 'Demande', input: 'Saisie des messages', menus: 'Menus et boîtes de dialogue', approval: "Zone d'approbation", unbound: 'Pas de raccourci', + empty: 'Aucun raccourci correspondant', + move: 'Déplacer la sélection du menu', select: 'Sélectionner un élément de menu', dismiss: 'Fermer le menu ou la boîte de dialogue supérieure', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'edit-label': 'Verknüpfung für {command} bearbeiten', + record: 'Drücken Sie eine Verknüpfung', 'record-help': 'Lassen Sie die Tasten los, um zu speichern. Tab bewegt sich zwischen Aktionen; Esc bricht ab.', + 'web-help': 'Browserkombinationen: Mod+/, Mod+Umschalt+,, Mod+Umschalt+.. Mod ist Befehl auf dem Mac und Strg anderswo.', + 'unsupported-key': 'Dieser Schlüssel wird nicht unterstützt.', reserved: 'Diese Kombination ist für System- oder Textbearbeitungsaktionen reserviert.', + 'modifier-required': 'Fügen Sie Befehl, Strg oder Alt in die Kombination ein.', + 'too-many-keys': 'Halten Sie höchstens zwei nicht modifizierbare Tasten gedrückt. Lassen Sie die Tasten los, um es erneut zu versuchen.', + 'macos-web-help': 'Verwenden Sie Befehl+/, Befehl+,, Befehl+Backslash, Strg+Backquote, Befehl+Wahl+Taste oder Befehl+Umschalt+Taste. Kombinationen mit drei oder vier unterschiedlichen Modifikatoren werden ebenfalls unterstützt. Browser- oder Systemverknüpfungen erreichen die Seite möglicherweise nicht.', + 'windows-web-help': 'Verwenden Sie Strg+/, Strg+,, Strg+Alt+Taste oder Strg+Umschalt+Taste. Kombinationen mit drei oder vier unterschiedlichen Modifikatoren werden ebenfalls unterstützt. Browser- oder Systemverknüpfungen erreichen die Seite möglicherweise nicht.', + 'unsupported-browser': 'Dieser Browser unterstützt diese Kombination noch nicht.', conflict: 'Bereits verwendet von „{commands}“', + saved: 'Geändert', clear: 'Entfernen', 'retry-save': 'Speichern Sie erneut', reset: 'Standard wiederherstellen', + 'reset-all': 'Alle Standardeinstellungen wiederherstellen', 'modified-count': '{count} angepasst', + 'reset-title': 'Alle Standardverknüpfungen wiederherstellen?', + 'reset-description': 'Stellen Sie die Standardverknüpfungen für diese Plattform wieder her. Alle geänderten oder entfernten Verknüpfungen werden wiederhergestellt. Andere Plattformen sind davon nicht betroffen.', + cancel: 'Abbrechen', 'reset-saved': 'Standardverknüpfungen wiederhergestellt', + 'close-confirmation': 'Bestätigung schließen', 'reset-failed': 'Die Standardeinstellungen konnten nicht wiederhergestellt werden. Ihre Verknüpfungen bleiben unverändert. Bitte versuchen Sie es erneut.', + review: 'Ich habe die neueste Konfiguration überprüft', + stale: 'Verknüpfungskonfiguration oder verfügbare Befehle geändert. Überprüfen Sie vor dem Speichern die neuesten Bindungen.', + 'write-failed': 'Konnte nicht gespeichert werden. Ihre vorherigen Verknüpfungen und Ihr aktueller Entwurf bleiben erhalten. Bitte versuchen Sie es erneut.', + 'not-ready': 'Verknüpfungen sind nicht bereit. Bitte versuchen Sie es erneut.', + read: '{location} konnte nicht gelesen werden. Zugriffsberechtigungen prüfen, dann {reload}.', + invalid: 'Die Verknüpfungskonfiguration in {location} ist beschädigt. Sichern und reparieren Sie diese Konfiguration, dann {reload}.', + future: 'Die Verknüpfungskonfiguration in {location} wurde von einer neueren Version erstellt. Aktualisieren Sie Harness und versuchen Sie es erneut.', + 'web-document': 'Der localStorage-Eintrag dieser Site dsh.keybindings.v1', 'desktop-document': 'userData/keybindings.json', + 'web-reload': 'Laden Sie die Seite neu', 'desktop-reload': 'Starten Sie Harness neu', + 'using-defaults': 'Standardbindungen sind aktiv.', 'using-accepted': 'Die zuletzt erfolgreich gelesenen Bindungen bleiben aktiv.', + 'native-failed': 'Die Desktop-Schlüsselaufzeichnung konnte nicht geschützt werden. Beenden Sie die Aufnahme und versuchen Sie es erneut.', + 'global-hint': 'Von überall aus öffnen', 'clear-search': 'Suche löschen', + title: 'Tastaturkürzel', open: 'Öffnen Sie Tastaturkürzel', settings: 'Tastaturkürzel', view: 'Verknüpfungen bearbeiten', + description: 'Verfügbare Verknüpfungen und Eingabeaktionen anzeigen und bearbeiten', search: 'Suchverknüpfungen', close: 'Tastaturkürzel schließen', + application: 'Bewerbung', input: 'Nachrichteneingabe', menus: 'Menüs und Dialoge', approval: 'Genehmigungsbereich', unbound: 'Keine Abkürzung', + empty: 'Keine passenden Verknüpfungen', + move: 'Menüauswahl verschieben', select: 'Menüpunkt auswählen', dismiss: 'Menü oder oberen Dialog schließen', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'edit-label': 'Изменить ярлык для {command}', + record: 'Нажмите ярлык', 'record-help': 'Отпустите клавиши для сохранения. Tab перемещается между действиями; Esc отменяет.', + 'web-help': 'Комбинации браузера: Mod+/, Mod+Shift+, Mod+Shift+.. Mod — это команда на Mac, а в других местах — Ctrl.', + 'unsupported-key': 'Этот ключ не поддерживается.', reserved: 'Эта комбинация зарезервирована для системных действий или действий по редактированию текста.', + 'modifier-required': 'Включите в комбинацию Command, Ctrl или Alt.', + 'too-many-keys': 'Удерживайте не более двух немодифицирующих клавиш. Отпустите клавиши, чтобы повторить попытку.', + 'macos-web-help': 'Используйте Command+/, Command+,, Command+обратная косая черта, Control+обратная кавычка, Command+Option+клавиша или Command+Shift+клавиша. Также поддерживаются комбинации с тремя или четырьмя различными модификаторами. Ярлыки браузера или системы могут не доходить до страницы.', + 'windows-web-help': 'Используйте Ctrl+/, Ctrl+, Ctrl+Alt+клавиша или Ctrl+Shift+клавиша. Также поддерживаются комбинации с тремя или четырьмя различными модификаторами. Ярлыки браузера или системы могут не доходить до страницы.', + 'unsupported-browser': 'Этот браузер пока не поддерживает эту комбинацию.', conflict: 'Уже используется «{commands}»', + saved: 'Модифицированный', clear: 'Удалить', 'retry-save': 'Повторить попытку сохранения', reset: 'Восстановить настройки по умолчанию', + 'reset-all': 'Восстановить все настройки по умолчанию', 'modified-count': '{count} по индивидуальному заказу', + 'reset-title': 'Восстановить все ярлыки по умолчанию?', + 'reset-description': 'Восстановите ярлыки по умолчанию для этой платформы. Все измененные или удаленные ярлыки будут восстановлены. Другие платформы не затронуты.', + cancel: 'Отмена', 'reset-saved': 'Ярлыки по умолчанию восстановлены.', + 'close-confirmation': 'Закрыть подтверждение', 'reset-failed': 'Не удалось восстановить настройки по умолчанию. Ваши ярлыки не изменились. Пожалуйста, повторите попытку.', + review: 'Я рассмотрел последнюю конфигурацию', + stale: 'Конфигурация ярлыка или доступные команды изменены. Перед сохранением просмотрите последние привязки.', + 'write-failed': 'Не удалось сохранить. Ваши предыдущие ярлыки и текущий черновик сохраняются. Пожалуйста, повторите попытку.', + 'not-ready': 'Ярлыки не готовы. Пожалуйста, попробуйте еще раз.', + read: 'Не удалось прочитать {location}. Проверьте права доступа, затем {reload}.', + invalid: 'Конфигурация ярлыка в {location} повреждена. Создайте резервную копию и исправьте эту конфигурацию, затем {reload}.', + future: 'Конфигурация ярлыка в {location} была создана более новой версией. Обновите Harness и повторите попытку.', + 'web-document': 'запись localStorage этого сайта dsh.keybindings.v1', 'desktop-document': 'userData/keybindings.json', + 'web-reload': 'перезагрузить страницу', 'desktop-reload': 'перезапустить Harness', + 'using-defaults': 'Привязки по умолчанию активны.', 'using-accepted': 'Последние успешно прочитанные привязки остаются активными.', + 'native-failed': 'Не удалось защитить запись клавиш рабочего стола. Выйдите из записи и повторите попытку.', + 'global-hint': 'Открыто из любого места', 'clear-search': 'Очистить поиск', + title: 'Сочетания клавиш', open: 'Открытие сочетаний клавиш', settings: 'Сочетания клавиш', view: 'Редактировать ярлыки', + description: 'Просмотр и редактирование доступных ярлыков и действий ввода', search: 'Поиск ярлыков', close: 'Закрыть сочетания клавиш', + application: 'Приложение', input: 'Ввод сообщения', menus: 'Меню и диалоги', approval: 'Область утверждения', unbound: 'Нет ярлыка', + empty: 'Нет подходящих ярлыков', + move: 'Переместить выбор меню', select: 'Выберите пункт меню', dismiss: 'Закрыть меню или верхний диалог', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'edit-label': 'Editar atalho para {command}', + record: 'Pressione um atalho', 'record-help': 'Solte as teclas para salvar. A guia se move entre as ações; Esc cancela.', + 'web-help': 'Combinações de navegador: Mod+/, Mod+Shift+,, Mod+Shift+.. Mod é Command no Mac e Ctrl em outros lugares.', + 'unsupported-key': 'Esta chave não é suportada.', reserved: 'Esta combinação é reservada para ações de sistema ou edição de texto.', + 'modifier-required': 'Inclua Command, Ctrl ou Alt na combinação.', + 'too-many-keys': 'Segure no máximo duas teclas não modificadoras. Solte as teclas para tentar novamente.', + 'macos-web-help': 'Use Command+/, Command+,, Command+Barra invertida, Control+Backquote, Command+Option+key ou Command+Shift+key. Combinações com três ou quatro modificadores distintos também são suportadas. Os atalhos do navegador ou do sistema podem não chegar à página.', + 'windows-web-help': 'Use Ctrl+/, Ctrl+,, Ctrl+Alt+tecla ou Ctrl+Shift+tecla. Combinações com três ou quatro modificadores distintos também são suportadas. Os atalhos do navegador ou do sistema podem não chegar à página.', + 'unsupported-browser': 'Este navegador ainda não suporta esta combinação.', conflict: 'Já usado por “{commands}”', + saved: 'Modificado', clear: 'Remover', 'retry-save': 'Tentar salvar novamente', reset: 'Restaurar padrão', + 'reset-all': 'Restaurar todos os padrões', 'modified-count': '{count} personalizado', + 'reset-title': 'Restaurar todos os atalhos padrão?', + 'reset-description': 'Restaure os atalhos padrão desta plataforma. Todos os atalhos modificados ou removidos serão restaurados. Outras plataformas não são afetadas.', + cancel: 'Cancelar', 'reset-saved': 'Atalhos padrão restaurados', + 'close-confirmation': 'Fechar confirmação', 'reset-failed': 'Não foi possível restaurar os padrões. Seus atalhos permanecem inalterados. Por favor, tente novamente.', + review: 'Eu revisei a configuração mais recente', + stale: 'Configuração de atalhos ou comandos disponíveis alterados. Revise as ligações mais recentes antes de salvar.', + 'write-failed': 'Não foi possível salvar. Seus atalhos anteriores e o rascunho atual serão preservados. Por favor, tente novamente.', + 'not-ready': 'Os atalhos não estão prontos. Por favor, tente novamente.', + read: 'Não foi possível ler {location}. Verifique as permissões de acesso e depois {reload}.', + invalid: 'A configuração do atalho em {location} está danificada. Faça backup e repare esta configuração e então {reload}.', + future: 'A configuração do atalho em {location} foi criada por uma versão mais recente. Atualize o Harness e tente novamente.', + 'web-document': 'a entrada localStorage deste site dsh.keybindings.v1', 'desktop-document': 'userData/keybindings.json', + 'web-reload': 'recarregar a página', 'desktop-reload': 'reinicie o chicote', + 'using-defaults': 'As ligações padrão estão ativas.', 'using-accepted': 'As últimas ligações lidas com sucesso permanecem ativas.', + 'native-failed': 'Não foi possível proteger a gravação de teclas da área de trabalho. Saia da gravação e tente novamente.', + 'global-hint': 'Abra de qualquer lugar', 'clear-search': 'Limpar pesquisa', + title: 'Atalhos de teclado', open: 'Abra atalhos de teclado', settings: 'Atalhos de teclado', view: 'Editar atalhos', + description: 'Visualize e edite atalhos e ações de entrada disponíveis', search: 'Atalhos de pesquisa', close: 'Fechar atalhos de teclado', + application: 'Aplicação', input: 'Entrada de mensagem', menus: 'Menus e caixas de diálogo', approval: 'Área de aprovação', unbound: 'Sem atalho', + empty: 'Nenhum atalho correspondente', + move: 'Mover seleção de menu', select: 'Selecione o item do menu', dismiss: 'Fechar menu ou caixa de diálogo superior', +} satisfies Record diff --git a/packages/client/ui-sidebar-browser/locale/de.json b/packages/client/ui-sidebar-browser/locale/de.json new file mode 100644 index 0000000000..0e2de49b34 --- /dev/null +++ b/packages/client/ui-sidebar-browser/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Browser-Panel", + "description": "Öffnen und durchsuchen Sie Webseiten im rechten Bereich." + } +} diff --git a/packages/client/ui-sidebar-browser/locale/es.json b/packages/client/ui-sidebar-browser/locale/es.json new file mode 100644 index 0000000000..aab1b5b129 --- /dev/null +++ b/packages/client/ui-sidebar-browser/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "panel del navegador", + "description": "Abra y explore páginas web en el panel derecho." + } +} diff --git a/packages/client/ui-sidebar-browser/locale/fr.json b/packages/client/ui-sidebar-browser/locale/fr.json new file mode 100644 index 0000000000..1d11175a16 --- /dev/null +++ b/packages/client/ui-sidebar-browser/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "panneau de navigateur", + "description": "Ouvrez et parcourez les pages Web dans le panneau de droite." + } +} diff --git a/packages/client/ui-sidebar-browser/locale/pt.json b/packages/client/ui-sidebar-browser/locale/pt.json new file mode 100644 index 0000000000..88074aa070 --- /dev/null +++ b/packages/client/ui-sidebar-browser/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "painel do navegador", + "description": "Abra e navegue nas páginas da web no painel direito." + } +} diff --git a/packages/client/ui-sidebar-browser/locale/ru.json b/packages/client/ui-sidebar-browser/locale/ru.json new file mode 100644 index 0000000000..5ef851d55d --- /dev/null +++ b/packages/client/ui-sidebar-browser/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "панель браузера", + "description": "Открывайте и просматривайте веб-страницы на правой панели." + } +} diff --git a/packages/client/ui-sidebar-browser/src/client/index.ts b/packages/client/ui-sidebar-browser/src/client/index.ts index e3ac92a9db..29219212bc 100644 --- a/packages/client/ui-sidebar-browser/src/client/index.ts +++ b/packages/client/ui-sidebar-browser/src/client/index.ts @@ -16,7 +16,7 @@ import type { DesktopBrowserBridge } from '../types.ts' import { browserWorkspace } from './electron/workspace.ts' import type { BrowserPageFactory } from './browser/BrowserPage.ts' import { BROWSER_ID, browserDefinition } from './definition.tsx' -import { en, ja, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh } from './locales.ts' import { createBrowserStore } from './browser/store.ts' export type { BrowserBodyProps } from './view/BrowserBody.tsx' @@ -70,7 +70,7 @@ export function apply(ctx: Context): void { dshDesktop?: { readonly protocolVersion: number; readonly browser?: DesktopBrowserBridge } }).dshDesktop const desktop = carrier?.protocolVersion === 1 ? carrier.browser : undefined - ctx.effect(() => ctx.locale.register(namespace, { zh, en, ja }), 'ui-sidebar-browser.copy') + ctx.effect(() => ctx.locale.register(namespace, { zh, en, ja, es, fr, de, ru, pt }), 'ui-sidebar-browser.copy') ctx.effect(() => ctx.sidebarRightTabs.register({ ...browserDefinition(t), keepMounted: desktop !== undefined }), 'ui-sidebar-browser.type') const installFrames = (scope: Context, factory: (sessionId: BrowserBodyProps['sessionId']) => BrowserPageFactory): void => { const controllers = new Map() diff --git a/packages/client/ui-sidebar-browser/src/client/locales.ts b/packages/client/ui-sidebar-browser/src/client/locales.ts index a5222248ae..fad29893e0 100644 --- a/packages/client/ui-sidebar-browser/src/client/locales.ts +++ b/packages/client/ui-sidebar-browser/src/client/locales.ts @@ -97,3 +97,153 @@ export const ja = { 'load.failed.detail': 'ページの読み込みに失敗しました({code}): {description}', 'address.unknown': 'ページが遷移しました。このキャリアは新しいURLを読み取れません。', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'type.label': 'Navegador', + 'guide.title': 'Navegador', + 'guide.description': 'Navegar por páginas web', + 'shortcut.noSession': 'Primero abra una sesión', + 'address.placeholder': 'Ingrese una dirección HTTP(S)', + 'address.changed': 'URL cambiada', + back: 'Atrás', + forward: 'Adelante', + reload: 'recargar', + go: 'ir', + external: 'Abrir en el navegador del sistema', + 'sandbox.disable': 'Deshabilitar restricciones de zona de pruebas', + 'sandbox.enable': 'Restaurar restricciones de zona de pruebas', + 'sandbox.warning': 'Las restricciones de la zona de pruebas están deshabilitadas; la página puede navegar por la aplicación de nivel superior y usar descargas, cuadros de diálogo modales y bloqueos de entrada.', + start: 'Ingrese una dirección HTTP(S) para comenzar a navegar', + loading: 'Abriendo…', + 'restore.previous': 'Abierto previamente', + 'restore.action': 'Restaurar página', + 'error.empty': 'Introduzca una dirección.', + 'error.invalid': 'Esa dirección no es válida o es demasiado larga.', + 'error.protocol': 'Sólo se admiten las direcciones HTTP y HTTPS; utilice la vista previa del documento para archivos locales.', + 'error.credentials': 'Las direcciones no pueden contener un nombre de usuario o contraseña.', + 'error.application-origin': 'El navegador integrado no puede abrir la aplicación DSH.', + 'load.failed': 'La página no se pudo cargar; recargarlo o abrirlo en el navegador del sistema.', + 'load.failed.detail': 'Error al cargar la página ({code}): {description}', + 'address.unknown': 'La página navegó; este operador no puede leer su nueva URL.', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'type.label': 'Navigateur', + 'guide.title': 'Navigateur', + 'guide.description': 'Parcourir les pages Web', + 'shortcut.noSession': "Ouvrir d'abord une session", + 'address.placeholder': 'Saisissez une adresse HTTP(S)', + 'address.changed': 'URL modifiée', + back: 'Retour', + forward: 'En avant', + reload: 'Recharger', + go: 'Allez', + external: 'Ouvrir dans le navigateur système', + 'sandbox.disable': 'Désactiver les restrictions du bac à sable', + 'sandbox.enable': 'Restaurer les restrictions du bac à sable', + 'sandbox.warning': "Les restrictions du bac à sable sont désactivées ; la page peut naviguer dans l'application de niveau supérieur et utiliser les téléchargements, les boîtes de dialogue modales et les verrous de saisie.", + start: 'Entrez une adresse HTTP(S) pour commencer la navigation', + loading: 'Ouverture…', + 'restore.previous': 'Déjà ouvert', + 'restore.action': 'Page de restauration', + 'error.empty': 'Entrez une adresse.', + 'error.invalid': "Cette adresse n'est pas valide ou est trop longue.", + 'error.protocol': "Seules les adresses HTTP et HTTPS sont prises en charge ; utilisez l'aperçu du document pour les fichiers locaux.", + 'error.credentials': "Les adresses ne peuvent pas contenir de nom d'utilisateur ou de mot de passe.", + 'error.application-origin': "Le navigateur intégré ne peut pas ouvrir l'application DSH elle-même.", + 'load.failed': "La page n'a pas pu se charger ; rechargez-le ou ouvrez-le dans le navigateur système.", + 'load.failed.detail': 'Échec du chargement de la page ({code}) : {description}', + 'address.unknown': 'La page parcourue ; cet opérateur ne peut pas lire sa nouvelle URL.', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'type.label': 'Browser', + 'guide.title': 'Browser', + 'guide.description': 'Durchsuchen Sie Webseiten', + 'shortcut.noSession': 'Öffnen Sie zunächst eine Sitzung', + 'address.placeholder': 'Geben Sie eine HTTP(S)-Adresse ein', + 'address.changed': 'URL geändert', + back: 'Zurück', + forward: 'Vorwärts', + reload: 'Neu laden', + go: 'Geh', + external: 'Im Systembrowser öffnen', + 'sandbox.disable': 'Sandbox-Einschränkungen deaktivieren', + 'sandbox.enable': 'Sandbox-Einschränkungen wiederherstellen', + 'sandbox.warning': 'Sandbox-Einschränkungen sind deaktiviert; Die Seite kann durch die App der obersten Ebene navigieren und Downloads, modale Dialoge und Eingabesperren verwenden.', + start: 'Geben Sie eine HTTP(S)-Adresse ein, um mit dem Surfen zu beginnen', + loading: 'Eröffnung…', + 'restore.previous': 'Zuvor geöffnet', + 'restore.action': 'Seite wiederherstellen', + 'error.empty': 'Geben Sie eine Adresse ein.', + 'error.invalid': 'Diese Adresse ist ungültig oder zu lang.', + 'error.protocol': 'Es werden nur die Adressen HTTP und HTTPS unterstützt. Verwenden Sie die Dokumentvorschau für lokale Dateien.', + 'error.credentials': 'Adressen dürfen weder einen Benutzernamen noch ein Passwort enthalten.', + 'error.application-origin': 'Der eingebettete Browser kann die DSH-Anwendung selbst nicht öffnen.', + 'load.failed': 'Die Seite konnte nicht geladen werden; neu laden oder im Systembrowser öffnen.', + 'load.failed.detail': 'Laden der Seite fehlgeschlagen ({code}): {description}', + 'address.unknown': 'Die Seite wurde navigiert; Dieser Netzbetreiber kann seine neue URL nicht lesen.', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'type.label': 'Браузер', + 'guide.title': 'Браузер', + 'guide.description': 'Просмотр веб-страниц', + 'shortcut.noSession': 'Сначала откройте сеанс', + 'address.placeholder': 'Введите адрес HTTP(S)', + 'address.changed': 'URL-адрес изменен', + back: 'Назад', + forward: 'Вперед', + reload: 'Перезагрузить', + go: 'Иди', + external: 'Открыть в системном браузере', + 'sandbox.disable': 'Отключить ограничения песочницы', + 'sandbox.enable': 'Восстановить ограничения песочницы', + 'sandbox.warning': 'Ограничения песочницы отключены; страница может перемещаться по приложению верхнего уровня и использовать загрузки, модальные диалоговые окна и блокировки ввода.', + start: 'Введите адрес HTTP(S), чтобы начать просмотр.', + loading: 'Открытие…', + 'restore.previous': 'Ранее открыто', + 'restore.action': 'Восстановить страницу', + 'error.empty': 'Введите адрес.', + 'error.invalid': 'Этот адрес недействителен или слишком длинный.', + 'error.protocol': 'Поддерживаются только адреса HTTP и HTTPS; используйте предварительный просмотр документа для локальных файлов.', + 'error.credentials': 'Адреса не могут содержать имя пользователя или пароль.', + 'error.application-origin': 'Встроенный браузер не может открыть само приложение DSH.', + 'load.failed': 'Страница не может загрузиться; перезагрузите или откройте его в системном браузере.', + 'load.failed.detail': 'Ошибка загрузки страницы ({code}): {description}', + 'address.unknown': 'Страница перемещалась; этот оператор связи не может прочитать свой новый URL-адрес.', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'type.label': 'Navegador', + 'guide.title': 'Navegador', + 'guide.description': 'Navegar em páginas da web', + 'shortcut.noSession': 'Abra uma sessão primeiro', + 'address.placeholder': 'Insira um endereço HTTP(S)', + 'address.changed': 'URL alterado', + back: 'Voltar', + forward: 'Avançar', + reload: 'Recarregar', + go: 'Vá', + external: 'Abrir no navegador do sistema', + 'sandbox.disable': 'Desativar restrições de sandbox', + 'sandbox.enable': 'Restaurar restrições de sandbox', + 'sandbox.warning': 'As restrições do sandbox estão desativadas; a página pode navegar no aplicativo de nível superior e usar downloads, caixas de diálogo modais e bloqueios de entrada.', + start: 'Insira um endereço HTTP(S) para começar a navegar', + loading: 'Abrindo…', + 'restore.previous': 'Aberto anteriormente', + 'restore.action': 'Restaurar página', + 'error.empty': 'Insira um endereço.', + 'error.invalid': 'Esse endereço é inválido ou muito longo.', + 'error.protocol': 'Somente endereços HTTP e HTTPS são suportados; use a visualização do documento para arquivos locais.', + 'error.credentials': 'Os endereços não podem conter um nome de usuário ou senha.', + 'error.application-origin': 'O navegador incorporado não pode abrir o aplicativo DSH sozinho.', + 'load.failed': 'A página não pôde carregar; recarregue ou abra-o no navegador do sistema.', + 'load.failed.detail': 'Falha no carregamento da página ({code}): {description}', + 'address.unknown': 'A página navegada; esta operadora não consegue ler seu novo URL.', +} satisfies Record diff --git a/packages/client/ui-sidebar-documentpreview/locale/de.json b/packages/client/ui-sidebar-documentpreview/locale/de.json new file mode 100644 index 0000000000..076c2d117b --- /dev/null +++ b/packages/client/ui-sidebar-documentpreview/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Dokumentvorschaufenster", + "description": "Vorschau von Dateien wie Dokumenten, Tabellen, Codes, Bildern und Webseiten im rechten Bereich." + } +} diff --git a/packages/client/ui-sidebar-documentpreview/locale/es.json b/packages/client/ui-sidebar-documentpreview/locale/es.json new file mode 100644 index 0000000000..67b4b65fb1 --- /dev/null +++ b/packages/client/ui-sidebar-documentpreview/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Panel de vista previa del documento", + "description": "Obtenga una vista previa de archivos como documentos, tablas, códigos, imágenes y páginas web en el panel derecho." + } +} diff --git a/packages/client/ui-sidebar-documentpreview/locale/fr.json b/packages/client/ui-sidebar-documentpreview/locale/fr.json new file mode 100644 index 0000000000..c06734b675 --- /dev/null +++ b/packages/client/ui-sidebar-documentpreview/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Panneau d'aperçu du document", + "description": "Prévisualisez les fichiers tels que les documents, les tableaux, les codes, les images et les pages Web sur le panneau de droite." + } +} diff --git a/packages/client/ui-sidebar-documentpreview/locale/pt.json b/packages/client/ui-sidebar-documentpreview/locale/pt.json new file mode 100644 index 0000000000..a2dc23158d --- /dev/null +++ b/packages/client/ui-sidebar-documentpreview/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Painel de visualização do documento", + "description": "Visualize arquivos como documentos, tabelas, códigos, imagens e páginas da web no painel direito." + } +} diff --git a/packages/client/ui-sidebar-documentpreview/locale/ru.json b/packages/client/ui-sidebar-documentpreview/locale/ru.json new file mode 100644 index 0000000000..42277eca20 --- /dev/null +++ b/packages/client/ui-sidebar-documentpreview/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Панель предварительного просмотра документа", + "description": "Предварительный просмотр файлов, таких как документы, таблицы, коды, изображения и веб-страницы, на правой панели." + } +} diff --git a/packages/client/ui-sidebar-documentpreview/src/client/code/index.ts b/packages/client/ui-sidebar-documentpreview/src/client/code/index.ts index 3008802e74..eeceda36c4 100644 --- a/packages/client/ui-sidebar-documentpreview/src/client/code/index.ts +++ b/packages/client/ui-sidebar-documentpreview/src/client/code/index.ts @@ -3,14 +3,14 @@ import type { Context } from '@deepseek-ai/cordis' import { CODE_HIGHLIGHT_EXTENSIONS } from '@deepseek-ai/dsh-client-ui-primitives' import type {} from '../index.ts' import { CodeBody } from './CodeBody.tsx' -import { en, ja, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh } from './locales.ts' const ID = '@deepseek-ai/dsh-client-ui-sidebar-documentpreview/code' const NS = 'sidebarCodePreview' /** @param ctx - owning plugin context. Register localized metadata and the matching keyed document body. */ export function apply(ctx: Context): void { - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja })) + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt })) const t = ctx.locale.bind(NS) ctx.effect(() => ctx.documentPreviews.register({ id: ID, diff --git a/packages/client/ui-sidebar-documentpreview/src/client/code/locales.ts b/packages/client/ui-sidebar-documentpreview/src/client/code/locales.ts index 0173b40bff..04f2e115ed 100644 --- a/packages/client/ui-sidebar-documentpreview/src/client/code/locales.ts +++ b/packages/client/ui-sidebar-documentpreview/src/client/code/locales.ts @@ -28,3 +28,38 @@ export const ja = { 'copy': 'コピー', 'copied': 'コピーしました', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + title: 'Código', + copy: 'Copiar', + copied: 'Copiado', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + title: 'Coder', + copy: 'Copier', + copied: 'Copié', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + title: 'Code', + copy: 'Kopieren', + copied: 'Kopiert', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + title: 'Код', + copy: 'Копировать', + copied: 'Скопировано', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + title: 'Código', + copy: 'Copiar', + copied: 'Copiado', +} satisfies Record diff --git a/packages/client/ui-sidebar-documentpreview/src/client/excel/index.ts b/packages/client/ui-sidebar-documentpreview/src/client/excel/index.ts index 4a2771723f..28a2336475 100644 --- a/packages/client/ui-sidebar-documentpreview/src/client/excel/index.ts +++ b/packages/client/ui-sidebar-documentpreview/src/client/excel/index.ts @@ -3,7 +3,7 @@ import type { Context } from '@deepseek-ai/cordis' import type {} from '../index.ts' import type { Config } from '../../config.ts' import { LazyExcelBody } from './LazyExcelBody.tsx' -import { en, ja, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh } from './locales.ts' /** * Register the browser Excel viewer and its lifecycle-owned slot. @@ -12,7 +12,7 @@ import { en, ja, zh } from './locales.ts' */ export function apply(ctx: Context, limits: Config['excel']): void { const id = '@deepseek-ai/dsh-client-ui-sidebar-documentpreview/excel' - ctx.effect(() => ctx.locale.register('sidebarExcel', { zh, en, ja })) + ctx.effect(() => ctx.locale.register('sidebarExcel', { zh, en, ja, es, fr, de, ru, pt })) const t = ctx.locale.bind('sidebarExcel') ctx.effect(() => ctx.documentPreviews.register({ id, extensions: ['xlsx', 'xls', 'csv', 'tsv'], binaryExtensions: ['xlsx', 'xls'], priority: 'builtin', diff --git a/packages/client/ui-sidebar-documentpreview/src/client/excel/locales.ts b/packages/client/ui-sidebar-documentpreview/src/client/excel/locales.ts index 2a448c0660..c45ad60880 100644 --- a/packages/client/ui-sidebar-documentpreview/src/client/excel/locales.ts +++ b/packages/client/ui-sidebar-documentpreview/src/client/excel/locales.ts @@ -50,3 +50,63 @@ export const ja = { 'featureSeparator': '、', 'retry': '再試行', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + title: 'Hoja de cálculo', language: 'en', loading: 'Representando documento...', + invalid: 'Esta hoja de cálculo no se pudo abrir. Comprueba su formato, contenidos o protección con contraseña.', + tooLarge: 'Este libro excede el límite de tamaño de vista previa.', timeout: 'Se agotó el tiempo de apertura de este libro. Pruebe con un archivo más pequeño.', + encoding: 'Esta codificación de texto no se pudo leer. Guarde el archivo como UTF-8 o UTF-16 con una lista de materiales y vuelva a intentarlo.', + formulaWarning: 'Este libro contiene fórmulas. Los resultados mostrados pueden faltar o ser inexactos.', + unsupportedNotice: 'Esta vista previa no es compatible con {features} en este libro. Ábralo en una aplicación del sistema para disfrutar de la experiencia completa.', + charts: 'gráficos', images: 'imágenes', shapes: 'formas', conditionalFormatting: 'formato condicional', featureSeparator: ', ', + retry: 'Reintentar', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + title: 'Feuille de calcul', language: 'en', loading: 'Rendu du document...', + invalid: "Cette feuille de calcul n'a pas pu être ouverte. Vérifiez son format, son contenu ou sa protection par mot de passe.", + tooLarge: "Ce classeur dépasse la limite de taille d'aperçu.", timeout: "L'ouverture de ce classeur a expiré. Essayez un fichier plus petit.", + encoding: "Cet encodage de texte n'a pas pu être lu. Enregistrez le fichier au format UTF-8 ou UTF-16 avec une nomenclature et réessayez.", + formulaWarning: 'Ce classeur contient des formules. Les résultats affichés peuvent être manquants ou inexacts.', + unsupportedNotice: 'Cet aperçu ne prend pas en charge {features} dans ce classeur. Ouvrez-le dans une application système pour une expérience complète.', + charts: 'graphiques', images: 'photos', shapes: 'formes', conditionalFormatting: 'mise en forme conditionnelle', featureSeparator: ', ', + retry: 'Réessayer', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + title: 'Tabellenkalkulation', language: 'en', loading: 'Dokument wird gerendert...', + invalid: 'Diese Tabelle konnte nicht geöffnet werden. Überprüfen Sie Format, Inhalt oder Passwortschutz.', + tooLarge: 'Diese Arbeitsmappe überschreitet die Größenbeschränkung für die Vorschau.', timeout: 'Beim Öffnen dieser Arbeitsmappe ist eine Zeitüberschreitung aufgetreten. Versuchen Sie es mit einer kleineren Datei.', + encoding: 'Diese Textkodierung konnte nicht gelesen werden. Speichern Sie die Datei als UTF-8 oder UTF-16 mit einer Stückliste und versuchen Sie es erneut.', + formulaWarning: 'Diese Arbeitsmappe enthält Formeln. Die angezeigten Ergebnisse fehlen möglicherweise oder sind ungenau.', + unsupportedNotice: 'Diese Vorschau unterstützt {features} in dieser Arbeitsmappe nicht. Öffnen Sie es in einer Systemanwendung, um das volle Erlebnis zu genießen.', + charts: 'Diagramme', images: 'Bilder', shapes: 'Formen', conditionalFormatting: 'bedingte Formatierung', featureSeparator: ', ', + retry: 'Erneut versuchen', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + title: 'электронная таблица', language: 'en', loading: 'Оформление документа...', + invalid: 'Эту таблицу невозможно открыть. Проверьте его формат, содержимое или защиту паролем.', + tooLarge: 'Размер этой книги превышает ограничение на размер предварительного просмотра.', timeout: 'Время открытия этой книги истекло. Попробуйте файл меньшего размера.', + encoding: 'Эту текстовую кодировку невозможно прочитать. Сохраните файл как UTF-8 или UTF-16 со спецификацией и повторите попытку.', + formulaWarning: 'В этой рабочей тетради есть формулы. Отображаемые результаты могут отсутствовать или быть неточными.', + unsupportedNotice: 'Эта предварительная версия не поддерживает {features} в этой книге. Откройте его в системном приложении, чтобы получить полную информацию.', + charts: 'графики', images: 'изображения', shapes: 'формы', conditionalFormatting: 'условное форматирование', featureSeparator: ', ', + retry: 'Повторить', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + title: 'Planilha', language: 'en', loading: 'Renderizando documento...', + invalid: 'Não foi possível abrir esta planilha. Verifique seu formato, conteúdo ou proteção por senha.', + tooLarge: 'Esta pasta de trabalho excede o limite de tamanho de visualização.', timeout: 'A abertura desta pasta de trabalho expirou. Experimente um arquivo menor.', + encoding: 'Esta codificação de texto não pôde ser lida. Salve o arquivo como UTF-8 ou UTF-16 com uma BOM e tente novamente.', + formulaWarning: 'Esta pasta de trabalho contém fórmulas. Os resultados exibidos podem estar ausentes ou imprecisos.', + unsupportedNotice: 'Esta visualização não oferece suporte a {features} nesta pasta de trabalho. Abra-o em um aplicativo do sistema para ter uma experiência completa.', + charts: 'gráficos', images: 'imagens', shapes: 'formas', conditionalFormatting: 'formatação condicional', featureSeparator: ', ', + retry: 'Tentar novamente', +} satisfies Record diff --git a/packages/client/ui-sidebar-documentpreview/src/client/html/index.ts b/packages/client/ui-sidebar-documentpreview/src/client/html/index.ts index 056efb2de9..a731edabdf 100644 --- a/packages/client/ui-sidebar-documentpreview/src/client/html/index.ts +++ b/packages/client/ui-sidebar-documentpreview/src/client/html/index.ts @@ -6,7 +6,7 @@ import { hostFileOf } from '../rpc.ts' import { HtmlBody } from './HtmlBody.tsx' import type { HtmlBodyInjected } from './HtmlBody.tsx' import type {} from '@deepseek-ai/dsh-client-ui-settings/client' -import { en, ja, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh } from './locales.ts' /** HTML implementation identity, shared by metadata and the keyed slot. */ export const HTML_BODY_ID = '@deepseek-ai/dsh-client-ui-sidebar-documentpreview/html' @@ -26,7 +26,7 @@ export function htmlBodyDefinition(title: () => string): DocumentPreviewDefiniti */ export function apply(ctx: Context): void { const t = ctx.locale.bind('documentHtml') - ctx.effect(() => ctx.locale.register('documentHtml', { zh, en, ja })) + ctx.effect(() => ctx.locale.register('documentHtml', { zh, en, ja, es, fr, de, ru, pt })) ctx.effect(() => ctx.documentPreviews.register(htmlBodyDefinition(() => t('title')))) ctx.effect(() => ctx.slots.inject('sidebar.right.tab.document', () => ctx.slots.register( { diff --git a/packages/client/ui-sidebar-documentpreview/src/client/html/locales.ts b/packages/client/ui-sidebar-documentpreview/src/client/html/locales.ts index 1617bd42d7..1751249d3b 100644 --- a/packages/client/ui-sidebar-documentpreview/src/client/html/locales.ts +++ b/packages/client/ui-sidebar-documentpreview/src/client/html/locales.ts @@ -31,3 +31,43 @@ export const ja = { 'loading': 'ドキュメントをレンダリング中...', 'failed': 'このHTMLドキュメントをプレビューできませんでした。', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + title: 'HTML', + frame: 'Vista previa del documento HTML', + loading: 'Representando documento...', + failed: 'No se pudo obtener una vista previa de este documento HTML.', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + title: 'HTML', + frame: 'Aperçu du document HTML', + loading: 'Rendu du document...', + failed: "Ce document HTML n'a pas pu être prévisualisé.", +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + title: 'HTML', + frame: 'Vorschau des HTML-Dokuments', + loading: 'Dokument wird gerendert...', + failed: 'Dieses HTML-Dokument konnte nicht in der Vorschau angezeigt werden.', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + title: 'HTML', + frame: 'Предварительный просмотр HTML-документа', + loading: 'Оформление документа...', + failed: 'Этот HTML-документ не удалось просмотреть.', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + title: 'HTML', + frame: 'Pré-visualização do documento HTML', + loading: 'Renderizando documento...', + failed: 'Este documento HTML não pôde ser visualizado.', +} satisfies Record diff --git a/packages/client/ui-sidebar-documentpreview/src/client/image/index.ts b/packages/client/ui-sidebar-documentpreview/src/client/image/index.ts index 014598add0..a123cff8ae 100644 --- a/packages/client/ui-sidebar-documentpreview/src/client/image/index.ts +++ b/packages/client/ui-sidebar-documentpreview/src/client/image/index.ts @@ -8,7 +8,7 @@ import type { DocumentPreviewDefinition } from '../document/registry.ts' import { retainDocumentTabs } from '../document/tab-lifetime.ts' import { createZoomStore, type ZoomStore } from '../zoom/store.ts' import { ImageBody, type ImageBodyInjected } from './ImageBody.tsx' -import { en, ja, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh } from './locales.ts' /** Image implementation identity, shared by metadata and the keyed slot. */ export const IMAGE_BODY_ID = '@deepseek-ai/dsh-client-ui-sidebar-documentpreview/image' @@ -42,7 +42,7 @@ export function imageBodyDefinition(title: () => string): DocumentPreviewDefinit */ export function apply(ctx: Context): void { const t = ctx.locale.bind('sidebarImage') - ctx.effect(() => ctx.locale.register('sidebarImage', { zh, en, ja }), 'document-image: dictionaries') + ctx.effect(() => ctx.locale.register('sidebarImage', { zh, en, ja, es, fr, de, ru, pt }), 'document-image: dictionaries') ctx.effect(() => ctx.documentPreviews.register(imageBodyDefinition(() => t('title'))), 'document-image: metadata') const store = createZoomStore() const retainTab = retainDocumentTabs(ctx) diff --git a/packages/client/ui-sidebar-documentpreview/src/client/image/locales.ts b/packages/client/ui-sidebar-documentpreview/src/client/image/locales.ts index 852635dcca..605e6d9e88 100644 --- a/packages/client/ui-sidebar-documentpreview/src/client/image/locales.ts +++ b/packages/client/ui-sidebar-documentpreview/src/client/image/locales.ts @@ -1,4 +1,4 @@ -import { zoomEn, zoomJa, zoomZh } from '../zoom/locales.ts' +import { zoomEn, zoomJa, zoomEs, zoomFr, zoomDe, zoomRu, zoomPt, zoomZh } from '../zoom/locales.ts' /** Locale-owned image renderer labels and status text. */ export const zh = { @@ -39,3 +39,53 @@ export const ja = { 'failed': 'この画像を表示できませんでした。', 'unsupported': '画像プレビューには完全なファイル内容が必要です。', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + ...zoomEs, + title: 'Imagen', + preview: 'Vista previa de la imagen: {name}', + loading: 'Representando documento...', + failed: 'Esta imagen no se pudo mostrar.', + unsupported: 'La vista previa de la imagen requiere el contenido completo del archivo.', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + ...zoomFr, + title: 'Images', + preview: "Aperçu de l'image : {name}", + loading: 'Rendu du document...', + failed: "Cette image n'a pas pu être affichée.", + unsupported: "L'aperçu de l'image nécessite le contenu complet du fichier.", +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + ...zoomDe, + title: 'Bild', + preview: 'Bildvorschau: {name}', + loading: 'Dokument wird gerendert...', + failed: 'Dieses Bild konnte nicht angezeigt werden.', + unsupported: 'Für die Bildvorschau ist der vollständige Dateiinhalt erforderlich.', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + ...zoomRu, + title: 'Изображение', + preview: 'Предварительный просмотр изображения: {name}', + loading: 'Оформление документа...', + failed: 'Это изображение не может быть отображено.', + unsupported: 'Для предварительного просмотра изображения требуется полное содержимое файла.', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + ...zoomPt, + title: 'Imagem', + preview: 'Visualização da imagem: {name}', + loading: 'Renderizando documento...', + failed: 'Esta imagem não pôde ser exibida.', + unsupported: 'A visualização da imagem requer o conteúdo completo do arquivo.', +} satisfies Record diff --git a/packages/client/ui-sidebar-documentpreview/src/client/index.ts b/packages/client/ui-sidebar-documentpreview/src/client/index.ts index 1da0150e46..670ba33d6e 100644 --- a/packages/client/ui-sidebar-documentpreview/src/client/index.ts +++ b/packages/client/ui-sidebar-documentpreview/src/client/index.ts @@ -27,7 +27,7 @@ import { TEXTPREVIEW_ID, textDefinition } from './definition.ts' import { textFace } from './face.ts' import { createReadPage } from './rpc.ts' import { createTextStore } from './store.ts' -import { en, ja, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh } from './locales.ts' import { DocumentPreviewRegistry } from './document/registry.ts' import { documentTabInfoFactory } from './document/contract.ts' import { apply as registerText } from './text/index.ts' @@ -91,7 +91,7 @@ export function apply(ctx: ClientContext): void { const disposePreviews = ctx.reflect.provide('documentPreviews', previews) ctx.effect(() => disposePreviews) ctx.effect(() => ctx.sidebarRightTabs.register(textDefinition()), 'ui-sidebar-documentpreview: text type') - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-sidebar-documentpreview: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-sidebar-documentpreview: dictionaries') const store = createTextStore() const face = textFace( diff --git a/packages/client/ui-sidebar-documentpreview/src/client/locales.ts b/packages/client/ui-sidebar-documentpreview/src/client/locales.ts index 400118427e..fa99836610 100644 --- a/packages/client/ui-sidebar-documentpreview/src/client/locales.ts +++ b/packages/client/ui-sidebar-documentpreview/src/client/locales.ts @@ -86,3 +86,133 @@ export const ja = { 'error.unavailable': '読み込みに失敗しました: {message}', 'retry': '再試行', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + loading: 'Representando documento...', + loadMore: 'Cargar más', + changed: 'El archivo ha cambiado, mostrando el contenido anterior.', + reloadNow: 'recargar', + reload: 'Leer el archivo nuevamente', + autoRefresh: 'Actualización automática', + 'autoRefresh.enable': 'Habilitar actualización automática', + 'autoRefresh.disable': 'Deshabilitar la actualización automática', + 'wrap.enable': 'Activar ajuste de línea', + 'wrap.disable': 'Desactivar ajuste de línea', + 'wrap.aria': 'Ajuste de línea', + openWith: 'abrir con', + 'viewer.text': 'Texto sin formato', + resourceUnavailable: 'El servicio de recursos de archivos no está disponible.', + rendererUnavailable: 'La vista previa de {name} no está disponible.', + unsupportedFile: 'La vista previa aún no está disponible para este tipo de archivo.', + 'error.notFound': 'Archivo no encontrado. Es posible que se haya movido o eliminado.', + 'error.tooLarge': 'Esta página excede el límite {limit} y no se puede leer.', + 'error.notText': 'La vista previa aún no está disponible para este tipo de archivo.', + 'error.notRegularFile': 'No es un archivo normal, no hay nada que mostrar.', + 'error.unavailable': 'Error de lectura: {message}', + retry: 'Reintentar', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + loading: 'Rendu du document...', + loadMore: 'Charger plus', + changed: 'Le fichier a changé, affichant le contenu précédent.', + reloadNow: 'Recharger', + reload: 'Relisez le fichier', + autoRefresh: 'Actualisation automatique', + 'autoRefresh.enable': "Activer l'actualisation automatique", + 'autoRefresh.disable': "Désactiver l'actualisation automatique", + 'wrap.enable': 'Activer le retour à la ligne', + 'wrap.disable': 'Désactiver le retour à la ligne', + 'wrap.aria': 'Retour à la ligne', + openWith: 'Ouvrir avec', + 'viewer.text': 'Texte brut', + resourceUnavailable: "Le service de ressources de fichiers n'est pas disponible.", + rendererUnavailable: "L'aperçu {name} n'est pas disponible.", + unsupportedFile: "L'aperçu n'est pas encore disponible pour ce type de fichier.", + 'error.notFound': 'Fichier introuvable. Il a peut-être été déplacé ou supprimé.', + 'error.tooLarge': 'Cette page dépasse la limite {limit} et ne peut pas être lue.', + 'error.notText': "L'aperçu n'est pas encore disponible pour ce type de fichier.", + 'error.notRegularFile': "Ce n'est pas un fichier normal, rien à afficher.", + 'error.unavailable': 'Échec de lecture : {message}', + retry: 'Réessayer', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + loading: 'Dokument wird gerendert...', + loadMore: 'Mehr laden', + changed: 'Die Datei wurde geändert und zeigt den vorherigen Inhalt an.', + reloadNow: 'Neu laden', + reload: 'Lesen Sie die Datei noch einmal', + autoRefresh: 'Automatische Aktualisierung', + 'autoRefresh.enable': 'Aktivieren Sie die automatische Aktualisierung', + 'autoRefresh.disable': 'Deaktivieren Sie die automatische Aktualisierung', + 'wrap.enable': 'Aktivieren Sie den Zeilenumbruch', + 'wrap.disable': 'Schalten Sie den Zeilenumbruch aus', + 'wrap.aria': 'Zeilenumbruch', + openWith: 'Öffnen mit', + 'viewer.text': 'Klartext', + resourceUnavailable: 'Der Dateiressourcendienst ist nicht verfügbar.', + rendererUnavailable: 'Die {name}-Vorschau ist nicht verfügbar.', + unsupportedFile: 'Für diesen Dateityp ist noch keine Vorschau verfügbar.', + 'error.notFound': 'Datei nicht gefunden. Möglicherweise wurde es verschoben oder gelöscht.', + 'error.tooLarge': 'Diese Seite überschreitet das {limit}-Limit und kann nicht gelesen werden.', + 'error.notText': 'Für diesen Dateityp ist noch keine Vorschau verfügbar.', + 'error.notRegularFile': 'Keine normale Datei, nichts zum Anzeigen.', + 'error.unavailable': 'Lesen fehlgeschlagen: {message}', + retry: 'Erneut versuchen', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + loading: 'Оформление документа...', + loadMore: 'Загрузить больше', + changed: 'Файл изменился, показывая предыдущее содержимое.', + reloadNow: 'Перезагрузить', + reload: 'Прочтите файл еще раз', + autoRefresh: 'Автоматическое обновление', + 'autoRefresh.enable': 'Включить автоматическое обновление', + 'autoRefresh.disable': 'Отключить автоматическое обновление', + 'wrap.enable': 'Включить перенос строк', + 'wrap.disable': 'Отключить перенос строк', + 'wrap.aria': 'Перенос строки', + openWith: 'Открыть с помощью', + 'viewer.text': 'Обычный текст', + resourceUnavailable: 'Служба файловых ресурсов недоступна.', + rendererUnavailable: 'Предварительный просмотр {name} недоступен.', + unsupportedFile: 'Предварительный просмотр для этого типа файлов пока недоступен.', + 'error.notFound': 'Файл не найден. Возможно, оно было перемещено или удалено.', + 'error.tooLarge': 'Эта страница превышает лимит {limit} и не может быть прочитана.', + 'error.notText': 'Предварительный просмотр для этого типа файлов пока недоступен.', + 'error.notRegularFile': 'Не обычный файл, отображать нечего.', + 'error.unavailable': 'Не удалось прочитать: {message}.', + retry: 'Повторить', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + loading: 'Renderizando documento...', + loadMore: 'Carregar mais', + changed: 'O arquivo foi alterado, mostrando o conteúdo anterior.', + reloadNow: 'Recarregar', + reload: 'Leia o arquivo novamente', + autoRefresh: 'Atualização automática', + 'autoRefresh.enable': 'Ativar atualização automática', + 'autoRefresh.disable': 'Desativar atualização automática', + 'wrap.enable': 'Ativar quebra de linha', + 'wrap.disable': 'Desativar quebra de linha', + 'wrap.aria': 'Quebra de linha', + openWith: 'Abrir com', + 'viewer.text': 'Texto simples', + resourceUnavailable: 'O serviço de recurso de arquivo não está disponível.', + rendererUnavailable: 'A visualização {name} não está disponível.', + unsupportedFile: 'A visualização ainda não está disponível para este tipo de arquivo.', + 'error.notFound': 'Arquivo não encontrado. Pode ter sido movido ou excluído.', + 'error.tooLarge': 'Esta página excede o limite de {limit} e não pode ser lida.', + 'error.notText': 'A visualização ainda não está disponível para este tipo de arquivo.', + 'error.notRegularFile': 'Não é um arquivo normal, nada para exibir.', + 'error.unavailable': 'Falha na leitura: {message}', + retry: 'Tentar novamente', +} satisfies Record diff --git a/packages/client/ui-sidebar-documentpreview/src/client/markdown/index.ts b/packages/client/ui-sidebar-documentpreview/src/client/markdown/index.ts index a3d68990c0..2412dda05d 100644 --- a/packages/client/ui-sidebar-documentpreview/src/client/markdown/index.ts +++ b/packages/client/ui-sidebar-documentpreview/src/client/markdown/index.ts @@ -3,7 +3,7 @@ import type { Context } from '@deepseek-ai/cordis' import type {} from '../index.ts' import type { DocumentPreviewDefinition } from '../document/registry.ts' import { MarkdownBody } from './MarkdownBody.tsx' -import { en, ja, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh } from './locales.ts' /** Implementation identity shared by metadata and the document slot. */ export const MARKDOWN_BODY_ID = '@deepseek-ai/dsh-client-ui-sidebar-documentpreview/markdown' @@ -23,7 +23,7 @@ export function markdownDefinition(title: () => string): DocumentPreviewDefiniti */ export function apply(ctx: Context): void { const t = ctx.locale.bind('documentMarkdown') - ctx.effect(() => ctx.locale.register('documentMarkdown', { zh, en, ja }), 'document-markdown: dictionaries') + ctx.effect(() => ctx.locale.register('documentMarkdown', { zh, en, ja, es, fr, de, ru, pt }), 'document-markdown: dictionaries') ctx.effect(() => ctx.documentPreviews.register(markdownDefinition(() => t('viewer.label'))), 'document-markdown: metadata') ctx.effect(() => ctx.slots.inject('sidebar.right.tab.document', () => ctx.slots.register( { name: 'sidebar.right.tab.document', key: MARKDOWN_BODY_ID, locale: 'documentMarkdown' }, MarkdownBody, diff --git a/packages/client/ui-sidebar-documentpreview/src/client/markdown/locales.ts b/packages/client/ui-sidebar-documentpreview/src/client/markdown/locales.ts index 41554ace8b..4405800591 100644 --- a/packages/client/ui-sidebar-documentpreview/src/client/markdown/locales.ts +++ b/packages/client/ui-sidebar-documentpreview/src/client/markdown/locales.ts @@ -31,3 +31,43 @@ export const ja = { 'code.copied': 'コピーしました', 'footnotes': '脚注', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'viewer.label': 'Markdown', + 'code.copy': 'Copiar', + 'code.copied': 'Copiado', + 'footnotes': 'Notas a pie de página', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'viewer.label': 'Markdown', + 'code.copy': 'Copier', + 'code.copied': 'Copié', + 'footnotes': 'Notes de bas de page', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'viewer.label': 'Markdown', + 'code.copy': 'Kopieren', + 'code.copied': 'Kopiert', + 'footnotes': 'Fußnoten', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'viewer.label': 'Markdown', + 'code.copy': 'Копировать', + 'code.copied': 'Скопировано', + 'footnotes': 'Сноски', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'viewer.label': 'Markdown', + 'code.copy': 'Copiar', + 'code.copied': 'Copiado', + 'footnotes': 'Notas de rodapé', +} satisfies Record diff --git a/packages/client/ui-sidebar-documentpreview/src/client/office/index.ts b/packages/client/ui-sidebar-documentpreview/src/client/office/index.ts index 350585f7ed..832787aaf2 100644 --- a/packages/client/ui-sidebar-documentpreview/src/client/office/index.ts +++ b/packages/client/ui-sidebar-documentpreview/src/client/office/index.ts @@ -7,7 +7,7 @@ import type {} from '@deepseek-ai/dsh-client-locale/client' import type {} from '@deepseek-ai/dsh-api-workspace-files/remote' import { failureLine } from '../failure-line.ts' import { documentTabInfoFactory } from '../document/contract.ts' -import { en, ja, zh, type OfficePreviewKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh, type OfficePreviewKey } from './locales.ts' import { OfficePreviewCache, type ReadOfficeBytes, type ReadOfficeDocument } from './cache.ts' import { pdfBodyRegistration } from '../pdf/index.ts' import { LazyPdfBody } from '../pdf/LazyPdfBody.tsx' @@ -31,7 +31,7 @@ declare module '@deepseek-ai/dsh-client-ui-slots' { export function apply(ctx: Context, config: Config['office']): void { const id = '@deepseek-ai/dsh-client-ui-sidebar-documentpreview/office' const extensions = ['doc', 'docx', 'ppt', 'pptx'] - ctx.effect(() => ctx.locale.register('sidebarOffice', { zh, en, ja })) + ctx.effect(() => ctx.locale.register('sidebarOffice', { zh, en, ja, es, fr, de, ru, pt })) const t = ctx.locale.bind('sidebarOffice') const unavailable: ReadOfficeDocument = (_file, signal) => { signal.throwIfAborted() diff --git a/packages/client/ui-sidebar-documentpreview/src/client/office/locales.ts b/packages/client/ui-sidebar-documentpreview/src/client/office/locales.ts index fbab4f4913..5c224c81e4 100644 --- a/packages/client/ui-sidebar-documentpreview/src/client/office/locales.ts +++ b/packages/client/ui-sidebar-documentpreview/src/client/office/locales.ts @@ -57,3 +57,98 @@ export const ja = { 'busy': 'Office プレビューは混雑しています。しばらくしてから再試行してください。', 'changed': '読み込み中にファイルが変更されました。プレビューを開き直してください。', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + title: 'documento de oficina', + loading: 'Representando documento...', + retry: 'Reintentar', + viewMissingFonts: 'Fuentes faltantes: {count}. Haga clic para ver.', + missingFontsTitle: 'Fuentes faltantes', + missingFontsDescription: 'Estas fuentes no están disponibles para esta vista previa. El texto y el diseño pueden diferir del documento original.', + missingFontsCount: 'Fuentes: {count}', + closeDetails: 'Cerrar detalles de fuente', + unavailable: 'Las vistas previas de Office no están disponibles. Habilite el servicio de vista previa de documentos en la computadora que ejecuta DeepSeek Harness.', + invalid: 'No se puede obtener una vista previa de este archivo de Office. Puede que esté dañado, protegido con contraseña o que tenga la extensión incorrecta.', + tooLarge: 'El archivo de Office o el PDF convertido supera el límite de tamaño de vista previa. Reduzca el tamaño del archivo o ajuste la configuración de vista previa.', + failed: 'La conversión de Office no produjo un PDF utilizable. Verifique el archivo e inténtelo nuevamente.', + timeout: 'Se agotó el tiempo de espera para la conversión de Office. Intentar otra vez.', + busy: 'La vista previa de Office está ocupada. Vuelve a intentarlo en breve.', + changed: 'El archivo cambió mientras se leía. Vuelva a abrir la vista previa.', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + title: 'Document de bureau', + loading: 'Rendu du document...', + retry: 'Réessayer', + viewMissingFonts: 'Polices manquantes : {count}. Cliquez pour voir.', + missingFontsTitle: 'Polices manquantes', + missingFontsDescription: 'Ces polices ne sont pas disponibles pour cet aperçu. Le texte et la mise en page peuvent différer du document original.', + missingFontsCount: 'Polices : {count}', + closeDetails: 'Fermer les détails de la police', + unavailable: "Les aperçus Office ne sont pas disponibles. Activez le service de prévisualisation des documents sur l'ordinateur exécutant DeepSeek Harness.", + invalid: 'Ce fichier Office ne peut pas être prévisualisé. Il peut être endommagé, protégé par mot de passe ou avoir une extension incorrecte.', + tooLarge: "Le fichier Office ou le PDF converti dépasse la limite de taille d'aperçu. Réduisez la taille du fichier ou ajustez la configuration de l’aperçu.", + failed: "La conversion Office n'a pas produit de PDF utilisable. Vérifiez le fichier et réessayez.", + timeout: 'La conversion du bureau a expiré. Essayer à nouveau.', + busy: 'L’aperçu Office est occupé. Réessayez sous peu.', + changed: "Le fichier a changé lors de sa lecture. Rouvrez l'aperçu.", +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + title: 'Office-Dokument', + loading: 'Dokument wird gerendert...', + retry: 'Erneut versuchen', + viewMissingFonts: 'Fehlende Schriftarten: {count}. Klicken Sie zum Anzeigen.', + missingFontsTitle: 'Fehlende Schriftarten', + missingFontsDescription: 'Diese Schriftarten sind für diese Vorschau nicht verfügbar. Text und Layout können vom Originaldokument abweichen.', + missingFontsCount: 'Schriftarten: {count}', + closeDetails: 'Schriftartdetails schließen', + unavailable: 'Office-Vorschauen sind nicht verfügbar. Aktivieren Sie den Dokumentvorschaudienst auf dem Computer, auf dem DeepSeek Harness ausgeführt wird.', + invalid: 'Diese Office-Datei kann nicht in der Vorschau angezeigt werden. Möglicherweise ist es beschädigt, passwortgeschützt oder hat die falsche Erweiterung.', + tooLarge: 'Die Office-Datei oder das konvertierte PDF überschreitet die Größenbeschränkung für die Vorschau. Reduzieren Sie die Dateigröße oder passen Sie die Vorschaukonfiguration an.', + failed: 'Die Office-Konvertierung ergab kein brauchbares PDF. Überprüfen Sie die Datei und versuchen Sie es erneut.', + timeout: 'Zeitüberschreitung bei der Office-Konvertierung. Versuchen Sie es erneut.', + busy: 'Die Office-Vorschau ist beschäftigt. Versuchen Sie es in Kürze noch einmal.', + changed: 'Die Datei wurde beim Lesen geändert. Öffnen Sie die Vorschau erneut.', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + title: 'Офисный документ', + loading: 'Оформление документа...', + retry: 'Повторить', + viewMissingFonts: 'Отсутствуют шрифты: {count}. Нажмите, чтобы просмотреть.', + missingFontsTitle: 'Отсутствуют шрифты', + missingFontsDescription: 'Эти шрифты недоступны для этой предварительной версии. Текст и оформление могут отличаться от исходного документа.', + missingFontsCount: 'Шрифты: {count}', + closeDetails: 'Закрыть сведения о шрифте', + unavailable: 'Предварительные версии Office недоступны. Включите службу предварительного просмотра документов на компьютере под управлением DeepSeek Harness.', + invalid: 'Этот файл Office нельзя просмотреть. Возможно, он поврежден, защищен паролем или имеет неправильное расширение.', + tooLarge: 'Размер файла Office или преобразованного PDF-файла превышает ограничение на размер предварительного просмотра. Уменьшите размер файла или настройте конфигурацию предварительного просмотра.', + failed: 'Преобразование Office не привело к созданию пригодного для использования PDF-файла. Проверьте файл и повторите попытку.', + timeout: 'Время преобразования Office истекло. Попробуйте еще раз.', + busy: 'Предварительная версия Office занята. Повторите попытку через некоторое время.', + changed: 'Файл изменился во время чтения. Снова откройте предварительный просмотр.', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + title: 'Documento de escritório', + loading: 'Renderizando documento...', + retry: 'Tentar novamente', + viewMissingFonts: 'Fontes ausentes: {count}. Clique para visualizar.', + missingFontsTitle: 'Fontes ausentes', + missingFontsDescription: 'Essas fontes não estão disponíveis para esta visualização. O texto e o layout podem diferir do documento original.', + missingFontsCount: 'Fontes: {count}', + closeDetails: 'Fechar detalhes da fonte', + unavailable: 'As visualizações do Office não estão disponíveis. Ative o serviço de visualização de documentos no computador que executa DeepSeek Harness.', + invalid: 'Este arquivo do Office não pode ser visualizado. Ele pode estar danificado, protegido por senha ou ter a extensão errada.', + tooLarge: 'O arquivo Office ou PDF convertido excede o limite de tamanho de visualização. Reduza o tamanho do arquivo ou ajuste a configuração de visualização.', + failed: 'A conversão do Office não produziu um PDF utilizável. Verifique o arquivo e tente novamente.', + timeout: 'A conversão do Office expirou. Tente novamente.', + busy: 'A visualização do Office está ocupada. Tente novamente em breve.', + changed: 'O arquivo foi alterado durante a leitura. Reabra a visualização.', +} satisfies Record diff --git a/packages/client/ui-sidebar-documentpreview/src/client/pdf/index.ts b/packages/client/ui-sidebar-documentpreview/src/client/pdf/index.ts index ee099bb22a..c49e52b683 100644 --- a/packages/client/ui-sidebar-documentpreview/src/client/pdf/index.ts +++ b/packages/client/ui-sidebar-documentpreview/src/client/pdf/index.ts @@ -9,7 +9,7 @@ import type { BoundActions } from '@deepseek-ai/dsh-client-store' import type { SessionId } from '@deepseek-ai/dsh-session/types' import { createPdfStore, type PdfStore } from './store.ts' import { ZoomViewport, zoomSurfaceClass } from '../zoom/ZoomViewport.tsx' -import { en, ja, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh } from './locales.ts' /** PDF metadata and keyed body share this package-local implementation identity. */ export const PDF_BODY_ID = '@deepseek-ai/dsh-client-ui-sidebar-documentpreview/pdf' @@ -25,7 +25,7 @@ export function pdfBodyDefinition(title: () => string): DocumentPreviewDefinitio /** @param ctx - context carrying the locale, document registry, and slot registry. */ export function apply(ctx: Context): void { - ctx.effect(() => ctx.locale.register('sidebarPdf', { zh, en, ja })) + ctx.effect(() => ctx.locale.register('sidebarPdf', { zh, en, ja, es, fr, de, ru, pt })) const t = ctx.locale.bind('sidebarPdf') ctx.effect(() => ctx.documentPreviews.register(pdfBodyDefinition(() => t('title')))) const presentation = pdfBodyRegistration(ctx) diff --git a/packages/client/ui-sidebar-documentpreview/src/client/pdf/locales.ts b/packages/client/ui-sidebar-documentpreview/src/client/pdf/locales.ts index e9de97b4d3..55722d8888 100644 --- a/packages/client/ui-sidebar-documentpreview/src/client/pdf/locales.ts +++ b/packages/client/ui-sidebar-documentpreview/src/client/pdf/locales.ts @@ -1,4 +1,4 @@ -import { zoomEn, zoomJa, zoomZh } from '../zoom/locales.ts' +import { zoomEn, zoomJa, zoomEs, zoomFr, zoomDe, zoomRu, zoomPt, zoomZh } from '../zoom/locales.ts' /** Copy owned by the PDF renderer. */ export const zh = { @@ -51,3 +51,73 @@ export const ja = { 'unsupported': 'PDFのプレビューには完全なファイル内容が必要です。', 'retry': '再試行', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + ...zoomEs, + title: 'PDF', + pageImage: 'Página PDF {page}', + loading: 'Representando documento...', + rendering: 'Página de renderizado...', + failed: 'No se puede mostrar PDF: {message}', + password: 'Este PDF requiere una contraseña; No se admiten vistas previas protegidas con contraseña.', + workerFailed: 'El proceso de renderizado de PDF no pudo continuar. Vuelva a intentarlo.', + unsupported: 'La vista previa de PDF requiere el contenido completo del archivo.', + retry: 'Reintentar', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + ...zoomFr, + title: 'PDF', + pageImage: 'Page PDF {page}', + loading: 'Rendu du document...', + rendering: 'Page de rendu…', + failed: "Impossible d'afficher le PDF : {message}", + password: 'Ce PDF nécessite un mot de passe ; les aperçus protégés par mot de passe ne sont pas pris en charge.', + workerFailed: "Le processus de rendu PDF n'a pas pu continuer. Veuillez réessayer.", + unsupported: "L'aperçu PDF nécessite le contenu complet du fichier.", + retry: 'Réessayer', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + ...zoomDe, + title: 'PDF', + pageImage: 'PDF-Seite {page}', + loading: 'Dokument wird gerendert...', + rendering: 'Rendering-Seite…', + failed: 'PDF kann nicht angezeigt werden: {message}', + password: 'Für dieses PDF ist ein Passwort erforderlich. Passwortgeschützte Vorschauen werden nicht unterstützt.', + workerFailed: 'Der PDF-Rendering-Prozess konnte nicht fortgesetzt werden. Bitte versuchen Sie es erneut.', + unsupported: 'Für die PDF-Vorschau ist der vollständige Dateiinhalt erforderlich.', + retry: 'Erneut versuchen', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + ...zoomRu, + title: 'PDF', + pageImage: 'PDF-страница {page}', + loading: 'Оформление документа...', + rendering: 'Отображение страницы…', + failed: 'Невозможно отобразить PDF: {message}', + password: 'Для этого PDF-файла требуется пароль; предварительный просмотр, защищенный паролем, не поддерживается.', + workerFailed: 'Процесс рендеринга PDF не может быть продолжен. Пожалуйста, повторите попытку.', + unsupported: 'Для предварительного просмотра PDF требуется полное содержимое файла.', + retry: 'Повторить', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + ...zoomPt, + title: 'PDF', + pageImage: 'Página PDF {page}', + loading: 'Renderizando documento...', + rendering: 'Página de renderização…', + failed: 'Não é possível exibir PDF: {message}', + password: 'Este PDF requer uma senha; visualizações protegidas por senha não são suportadas.', + workerFailed: 'O processo de renderização do PDF não pôde continuar. Por favor, tente novamente.', + unsupported: 'A visualização do PDF requer o conteúdo completo do arquivo.', + retry: 'Tentar novamente', +} satisfies Record diff --git a/packages/client/ui-sidebar-documentpreview/src/client/zoom/locales.ts b/packages/client/ui-sidebar-documentpreview/src/client/zoom/locales.ts index ce263fccfd..6edb1573b4 100644 --- a/packages/client/ui-sidebar-documentpreview/src/client/zoom/locales.ts +++ b/packages/client/ui-sidebar-documentpreview/src/client/zoom/locales.ts @@ -30,3 +30,53 @@ export const zoomJa = { 'zoomFitWidth': '幅に合わせる', 'zoomValue': '{percent}%', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const zoomEs = { + zoomControls: 'Controles de zoom', + zoomMenu: 'Elige zoom', + zoomOut: 'alejar', + zoomIn: 'Acercar', + zoomFitWidth: 'Ancho de ajuste', + zoomValue: '{percent}%', +} satisfies typeof zoomEn + +/** French dictionary, checked against the English keys. */ +export const zoomFr = { + zoomControls: 'Commandes de zoom', + zoomMenu: 'Choisissez le zoom', + zoomOut: 'Zoom arrière', + zoomIn: 'Zoomer', + zoomFitWidth: 'Ajuster la largeur', + zoomValue: '{percent}%', +} satisfies typeof zoomEn + +/** German dictionary, checked against the English keys. */ +export const zoomDe = { + zoomControls: 'Zoom-Steuerelemente', + zoomMenu: 'Wählen Sie Zoom', + zoomOut: 'Herauszoomen', + zoomIn: 'Vergrößern', + zoomFitWidth: 'Breite anpassen', + zoomValue: '{percent}%', +} satisfies typeof zoomEn + +/** Russian dictionary, checked against the English keys. */ +export const zoomRu = { + zoomControls: 'Элементы управления масштабированием', + zoomMenu: 'Выберите масштаб', + zoomOut: 'Уменьшить масштаб', + zoomIn: 'Увеличить масштаб', + zoomFitWidth: 'Подходит по ширине', + zoomValue: '{percent}%', +} satisfies typeof zoomEn + +/** Portuguese dictionary, checked against the English keys. */ +export const zoomPt = { + zoomControls: 'Controles de zoom', + zoomMenu: 'Escolha o zoom', + zoomOut: 'Diminuir zoom', + zoomIn: 'Ampliar', + zoomFitWidth: 'Ajustar largura', + zoomValue: '{percent}%', +} satisfies typeof zoomEn diff --git a/packages/client/ui-sidebar-files/locale/de.json b/packages/client/ui-sidebar-files/locale/de.json new file mode 100644 index 0000000000..996a4a4a75 --- /dev/null +++ b/packages/client/ui-sidebar-files/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Bedienfeld zum Durchsuchen von Dateien", + "description": "Durchsuchen Sie das Arbeitsbereichsverzeichnis und öffnen Sie die Datei im rechten Bereich." + } +} diff --git a/packages/client/ui-sidebar-files/locale/es.json b/packages/client/ui-sidebar-files/locale/es.json new file mode 100644 index 0000000000..d50b1818de --- /dev/null +++ b/packages/client/ui-sidebar-files/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Panel de exploración de archivos", + "description": "Explore el directorio del espacio de trabajo y abra el archivo en el panel derecho." + } +} diff --git a/packages/client/ui-sidebar-files/locale/fr.json b/packages/client/ui-sidebar-files/locale/fr.json new file mode 100644 index 0000000000..7d3f2a9917 --- /dev/null +++ b/packages/client/ui-sidebar-files/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Panneau de navigation dans les fichiers", + "description": "Parcourez le répertoire de l'espace de travail et ouvrez le fichier dans le panneau de droite." + } +} diff --git a/packages/client/ui-sidebar-files/locale/pt.json b/packages/client/ui-sidebar-files/locale/pt.json new file mode 100644 index 0000000000..27cf88ec0d --- /dev/null +++ b/packages/client/ui-sidebar-files/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Painel de navegação de arquivos", + "description": "Navegue no diretório do espaço de trabalho e abra o arquivo no painel direito." + } +} diff --git a/packages/client/ui-sidebar-files/locale/ru.json b/packages/client/ui-sidebar-files/locale/ru.json new file mode 100644 index 0000000000..8376a67afe --- /dev/null +++ b/packages/client/ui-sidebar-files/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Панель просмотра файлов", + "description": "Просмотрите каталог рабочей области и откройте файл на правой панели." + } +} diff --git a/packages/client/ui-sidebar-files/src/client/index.ts b/packages/client/ui-sidebar-files/src/client/index.ts index 0b140c0e4e..0a03f63f3d 100644 --- a/packages/client/ui-sidebar-files/src/client/index.ts +++ b/packages/client/ui-sidebar-files/src/client/index.ts @@ -20,7 +20,7 @@ import { FILES_ID, filesDefinition } from './definition.tsx' import { createList, createWatch, filesFace } from './face.ts' import { FilesBody } from './FilesBody.tsx' import { FilesTitle } from './FilesTitle.tsx' -import { en, ja, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh } from './locales.ts' import { createFilesStore } from './store.ts' export type { SidebarFilesKey } from './locales.ts' @@ -79,7 +79,7 @@ export function apply(ctx: ClientContext): void { }), 'ui-sidebar-files: shortcut') }) ctx.effect(() => ctx.sidebarRightTabs.register(filesDefinition(t)), 'ui-sidebar-files: files type') - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-sidebar-files: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-sidebar-files: dictionaries') const store = createFilesStore() const inject = filesFace(createList(ctx.remote), createWatch(ctx.remote)) diff --git a/packages/client/ui-sidebar-files/src/client/locales.ts b/packages/client/ui-sidebar-files/src/client/locales.ts index 69bf81f8ce..f646b7ea74 100644 --- a/packages/client/ui-sidebar-files/src/client/locales.ts +++ b/packages/client/ui-sidebar-files/src/client/locales.ts @@ -83,3 +83,108 @@ export const ja = { 'error.notDirectory': 'それはディレクトリではありません。', 'error.unavailable': '読み取りに失敗しました: {message}', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'shortcut.noSession': 'Seleccione una sesión primero', + 'type.label': 'Archivos', + 'guide.title': 'Archivos de espacio de trabajo', + 'guide.description': 'Explorar archivos en el espacio de trabajo de esta sesión', + loading: 'Leyendo…', + empty: 'directorio vacio', + truncated: 'Demasiadas entradas y solo se muestran algunas de ellas.', + noWorkspace: 'Esta sesión no tiene ningún directorio de espacio de trabajo.', + reload: 'recargar', + autoRefresh: 'Actualización automática', + 'autoRefresh.enable': 'Habilitar actualización automática', + 'autoRefresh.disable': 'Deshabilitar la actualización automática', + 'entry.other': 'No es un archivo ni un directorio, por lo que no se puede abrir.', + 'error.notFound': 'Ese directorio desapareció. Es posible que se haya movido o eliminado.', + 'error.outsideWorkspace': 'Ese directorio está fuera del espacio de trabajo, por lo que la barra lateral no lo leerá.', + 'error.notDirectory': 'Eso no es un directorio.', + 'error.unavailable': 'Error de lectura: {message}', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'shortcut.noSession': "Sélectionnez d'abord une session", + 'type.label': 'Fichiers', + 'guide.title': "Fichiers de l'espace de travail", + 'guide.description': "Parcourir les fichiers dans l'espace de travail de cette session", + loading: 'Lecture…', + empty: 'Répertoire vide', + truncated: "Trop d'entrées, n'en affichant que certaines.", + noWorkspace: "Cette session n'a pas de répertoire d'espace de travail.", + reload: 'Recharger', + autoRefresh: 'Actualisation automatique', + 'autoRefresh.enable': "Activer l'actualisation automatique", + 'autoRefresh.disable': "Désactiver l'actualisation automatique", + 'entry.other': "Il ne s'agit pas d'un fichier ou d'un répertoire, il ne peut donc pas être ouvert.", + 'error.notFound': 'Ce répertoire a disparu. Il a peut-être été déplacé ou supprimé.', + 'error.outsideWorkspace': 'Ce répertoire se trouve en dehors de l’espace de travail, donc la barre latérale ne le lira pas.', + 'error.notDirectory': "Ce n'est pas un répertoire.", + 'error.unavailable': 'Échec de lecture : {message}', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'shortcut.noSession': 'Wählen Sie zunächst eine Sitzung aus', + 'type.label': 'Dateien', + 'guide.title': 'Arbeitsbereichsdateien', + 'guide.description': 'Durchsuchen Sie die Dateien im Arbeitsbereich dieser Sitzung', + loading: 'Lesen…', + empty: 'Leeres Verzeichnis', + truncated: 'Zu viele Einträge, es werden nur einige davon angezeigt.', + noWorkspace: 'Diese Sitzung hat kein Arbeitsbereichsverzeichnis.', + reload: 'Neu laden', + autoRefresh: 'Automatische Aktualisierung', + 'autoRefresh.enable': 'Aktivieren Sie die automatische Aktualisierung', + 'autoRefresh.disable': 'Deaktivieren Sie die automatische Aktualisierung', + 'entry.other': 'Keine Datei oder kein Verzeichnis, daher kann sie nicht geöffnet werden.', + 'error.notFound': 'Dieses Verzeichnis ist weg. Möglicherweise wurde es verschoben oder gelöscht.', + 'error.outsideWorkspace': 'Dieses Verzeichnis liegt außerhalb des Arbeitsbereichs und wird daher von der Seitenleiste nicht gelesen.', + 'error.notDirectory': 'Das ist kein Verzeichnis.', + 'error.unavailable': 'Lesen fehlgeschlagen: {message}', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'shortcut.noSession': 'Сначала выберите сеанс', + 'type.label': 'Файлы', + 'guide.title': 'Файлы рабочей области', + 'guide.description': 'Просмотр файлов в рабочей области этого сеанса', + loading: 'Чтение…', + empty: 'Пустой каталог', + truncated: 'Слишком много записей, показаны только некоторые из них.', + noWorkspace: 'В этом сеансе нет каталога рабочей области.', + reload: 'Перезагрузить', + autoRefresh: 'Автоматическое обновление', + 'autoRefresh.enable': 'Включить автоматическое обновление', + 'autoRefresh.disable': 'Отключить автоматическое обновление', + 'entry.other': 'Это не файл и не каталог, поэтому его нельзя открыть.', + 'error.notFound': 'Этот каталог исчез. Возможно, оно было перемещено или удалено.', + 'error.outsideWorkspace': 'Этот каталог находится за пределами рабочей области, поэтому боковая панель его не читает.', + 'error.notDirectory': 'Это не каталог.', + 'error.unavailable': 'Не удалось прочитать: {message}.', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'shortcut.noSession': 'Selecione uma sessão primeiro', + 'type.label': 'Arquivos', + 'guide.title': 'Arquivos do espaço de trabalho', + 'guide.description': 'Procure arquivos no espaço de trabalho desta sessão', + loading: 'Lendo…', + empty: 'Diretório vazio', + truncated: 'Muitas entradas, mostrando apenas algumas delas.', + noWorkspace: 'Esta sessão não possui diretório de espaço de trabalho.', + reload: 'Recarregar', + autoRefresh: 'Atualização automática', + 'autoRefresh.enable': 'Ativar atualização automática', + 'autoRefresh.disable': 'Desativar atualização automática', + 'entry.other': 'Não é um arquivo ou diretório, portanto não pode ser aberto.', + 'error.notFound': 'Esse diretório desapareceu. Pode ter sido movido ou excluído.', + 'error.outsideWorkspace': 'Esse diretório está fora da área de trabalho, portanto a barra lateral não o lerá.', + 'error.notDirectory': 'Isso não é um diretório.', + 'error.unavailable': 'Falha na leitura: {message}', +} satisfies Record diff --git a/packages/client/ui-sidebar-right/locale/de.json b/packages/client/ui-sidebar-right/locale/de.json new file mode 100644 index 0000000000..e94663c445 --- /dev/null +++ b/packages/client/ui-sidebar-right/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "rechtes Panel", + "description": "Verwalten Sie den Erweiterungsstatus, den Inhalt und die Navigation des rechten Bereichs." + } +} diff --git a/packages/client/ui-sidebar-right/locale/es.json b/packages/client/ui-sidebar-right/locale/es.json new file mode 100644 index 0000000000..a7d89d3719 --- /dev/null +++ b/packages/client/ui-sidebar-right/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "panel derecho", + "description": "Administre el estado de expansión, el contenido y la navegación del panel derecho." + } +} diff --git a/packages/client/ui-sidebar-right/locale/fr.json b/packages/client/ui-sidebar-right/locale/fr.json new file mode 100644 index 0000000000..39057044ef --- /dev/null +++ b/packages/client/ui-sidebar-right/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "panneau droit", + "description": "Gérez l'état d'expansion, le contenu et la navigation du panneau de droite." + } +} diff --git a/packages/client/ui-sidebar-right/locale/pt.json b/packages/client/ui-sidebar-right/locale/pt.json new file mode 100644 index 0000000000..53a65eeae1 --- /dev/null +++ b/packages/client/ui-sidebar-right/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "painel direito", + "description": "Gerencie o estado da expansão, o conteúdo e a navegação do painel direito." + } +} diff --git a/packages/client/ui-sidebar-right/locale/ru.json b/packages/client/ui-sidebar-right/locale/ru.json new file mode 100644 index 0000000000..cf55dfcadd --- /dev/null +++ b/packages/client/ui-sidebar-right/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "правая панель", + "description": "Управляйте состоянием расширения, содержимым и навигацией правой панели." + } +} diff --git a/packages/client/ui-sidebar-right/src/client/index.ts b/packages/client/ui-sidebar-right/src/client/index.ts index cb6a2f6e3f..99b800b6c8 100644 --- a/packages/client/ui-sidebar-right/src/client/index.ts +++ b/packages/client/ui-sidebar-right/src/client/index.ts @@ -42,7 +42,7 @@ import { SidebarSessionViews } from './session-views.ts' import { createSidebarRightController, type SidebarRightController } from './service.ts' import { SidebarRightTabRegistry } from './tab-registry.ts' import { createSidebarRightStore } from './stores.ts' -import { en, ja, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh } from './locales.ts' import { GUIDE_ID, guideDefinition } from './tabs/guide/definition.ts' import { createGuidePins } from './tabs/guide/guide-pins.ts' import { guideTabInfoFactory, tabInfoFactory } from './tab-info.ts' @@ -161,7 +161,7 @@ export function apply(ctx: ClientContext): void { void disposeRegistry() }, 'ui-sidebar-right: service faces') - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-sidebar-right: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-sidebar-right: dictionaries') ctx.effect(() => registerSidebarShortcuts(ctx.shortcuts, controller, t, () => { void ctx.shortcuts.closeWindow().catch((error: unknown) => { console.error('Window close failed', error) }) }), 'ui-sidebar-right: shortcuts') diff --git a/packages/client/ui-sidebar-right/src/client/locales.ts b/packages/client/ui-sidebar-right/src/client/locales.ts index f6b70b8a88..1f4b190402 100644 --- a/packages/client/ui-sidebar-right/src/client/locales.ts +++ b/packages/client/ui-sidebar-right/src/client/locales.ts @@ -125,3 +125,198 @@ export const ja = { 'tab.guide.more': 'その他のツール', 'tab.unavailable': 'この種類のコンテンツを表示できるものはまだありません。', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'command.close': 'Cerrar la página o ventana actual', + 'command.refresh': 'Actualizar la página actual', + 'command.noRefresh': 'Esta página no se puede actualizar', + 'command.toggle': 'Alternar barra lateral derecha', + 'command.fullscreen': 'Alternar panel de pantalla completa', + 'command.noSession': 'Seleccione una sesión primero', + 'command.noFocus': 'Enfoque primero un panel de la barra lateral derecha', + 'command.stale': 'La página cambió; enfocarlo de nuevo', + 'command.collapsed': 'Expande primero la barra lateral derecha', + 'command.float': 'Esta acción no está disponible en un panel flotante', + 'command.empty': 'Abra una página primero', + 'command.budget': 'Dos paneles es el límite', + 'command.width': 'No hay suficiente ancho para dividir, ampliar la barra lateral', + 'chrome.expand': 'Abrir barra lateral', + 'chrome.expandAria': 'Abrir barra lateral derecha', + 'chrome.collapse': 'Contraer barra lateral', + 'chrome.collapseAria': 'Contraer barra lateral derecha', + 'chrome.toFullscreen': 'Pantalla completa', + 'chrome.exitFullscreen': 'Salir de pantalla completa', + 'dock.emptyPane': 'Panel vacío', + 'dock.splitPane': 'dividir', + 'dock.splitPaneDisabled': 'Dos paneles es el límite', + 'dock.splitPaneNarrow': 'No hay suficiente ancho para dividir, ampliar la barra lateral', + 'dock.closeTab': 'Cerrar', + 'dock.addTab': 'Nueva pestaña', + 'dock.dockFloat': 'Enviar de vuelta a la barra lateral', + 'dock.closeFloat': 'Cerrar', + 'dock.drop.center': 'Muévete aquí', + 'dock.drop.left': 'Agregar división izquierda', + 'dock.drop.right': 'Agregar división a la derecha', + 'dock.drop.top': 'Agregar división superior', + 'dock.drop.bottom': 'Agregar división inferior', + 'tab.guide.title': 'Empezar', + 'tab.guide.more': 'Más herramientas', + 'tab.unavailable': 'Nada aquí puede ver este tipo de contenido todavía.', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'command.close': 'Fermer la page ou la fenêtre actuelle', + 'command.refresh': 'Actualiser la page actuelle', + 'command.noRefresh': 'Cette page ne peut pas être actualisée', + 'command.toggle': 'Basculer la barre latérale droite', + 'command.fullscreen': 'Basculer le panneau en plein écran', + 'command.noSession': "Sélectionnez d'abord une session", + 'command.noFocus': "Concentrer d'abord un volet de la barre latérale droite", + 'command.stale': 'La page a changé ; concentre-le à nouveau', + 'command.collapsed': "Développez d'abord la barre latérale droite", + 'command.float': "Cette action n'est pas disponible dans un panneau flottant", + 'command.empty': "Ouvrir d'abord une page", + 'command.budget': 'Deux panneaux sont la limite', + 'command.width': 'Pas assez de largeur pour diviser, élargir la barre latérale', + 'chrome.expand': 'Ouvrir la barre latérale', + 'chrome.expandAria': 'Ouvrir la barre latérale droite', + 'chrome.collapse': 'Réduire la barre latérale', + 'chrome.collapseAria': 'Réduire la barre latérale droite', + 'chrome.toFullscreen': 'Plein écran', + 'chrome.exitFullscreen': 'Quitter le plein écran', + 'dock.emptyPane': 'Volet vide', + 'dock.splitPane': 'Diviser', + 'dock.splitPaneDisabled': 'Deux panneaux sont la limite', + 'dock.splitPaneNarrow': 'Pas assez de largeur pour diviser, élargir la barre latérale', + 'dock.closeTab': 'Fermer', + 'dock.addTab': 'Nouvel onglet', + 'dock.dockFloat': 'Renvoyer à la barre latérale', + 'dock.closeFloat': 'Fermer', + 'dock.drop.center': 'Déplacez-vous ici', + 'dock.drop.left': 'Ajouter une division à gauche', + 'dock.drop.right': 'Ajouter une division à droite', + 'dock.drop.top': 'Ajouter une division supérieure', + 'dock.drop.bottom': 'Ajouter une division inférieure', + 'tab.guide.title': 'Commencer', + 'tab.guide.more': "Plus d'outils", + 'tab.unavailable': 'Rien ici ne peut encore afficher ce type de contenu.', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'command.close': 'Aktuelle Seite oder Fenster schließen', + 'command.refresh': 'Aktuelle Seite aktualisieren', + 'command.noRefresh': 'Diese Seite kann nicht aktualisiert werden', + 'command.toggle': 'Rechte Seitenleiste umschalten', + 'command.fullscreen': 'Panel-Vollbild umschalten', + 'command.noSession': 'Wählen Sie zunächst eine Sitzung aus', + 'command.noFocus': 'Fokussieren Sie zuerst einen rechten Seitenleistenbereich', + 'command.stale': 'Die Seite hat sich geändert; Konzentrieren Sie es erneut', + 'command.collapsed': 'Erweitern Sie zunächst die rechte Seitenleiste', + 'command.float': 'Diese Aktion ist in einem schwebenden Panel nicht verfügbar', + 'command.empty': 'Öffnen Sie zunächst eine Seite', + 'command.budget': 'Zwei Scheiben sind die Grenze', + 'command.width': 'Die Breite reicht nicht aus, um die Seitenleiste zu teilen. Verbreitern Sie die Seitenleiste', + 'chrome.expand': 'Seitenleiste öffnen', + 'chrome.expandAria': 'Rechte Seitenleiste öffnen', + 'chrome.collapse': 'Seitenleiste einklappen', + 'chrome.collapseAria': 'Rechte Seitenleiste einklappen', + 'chrome.toFullscreen': 'Vollbild', + 'chrome.exitFullscreen': 'Beenden Sie den Vollbildmodus', + 'dock.emptyPane': 'Leerer Bereich', + 'dock.splitPane': 'Geteilt', + 'dock.splitPaneDisabled': 'Zwei Scheiben sind die Grenze', + 'dock.splitPaneNarrow': 'Die Breite reicht nicht aus, um die Seitenleiste zu teilen. Verbreitern Sie die Seitenleiste', + 'dock.closeTab': 'Schließen', + 'dock.addTab': 'Neuer Tab', + 'dock.dockFloat': 'Zurück zur Seitenleiste senden', + 'dock.closeFloat': 'Schließen', + 'dock.drop.center': 'Bewegen Sie sich hierher', + 'dock.drop.left': 'Linke Teilung hinzufügen', + 'dock.drop.right': 'Rechte Teilung hinzufügen', + 'dock.drop.top': 'Oberen Split hinzufügen', + 'dock.drop.bottom': 'Untere Teilung hinzufügen', + 'tab.guide.title': 'Starten', + 'tab.guide.more': 'Weitere Werkzeuge', + 'tab.unavailable': 'Diese Art von Inhalten kann hier noch nicht angezeigt werden.', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'command.close': 'Закрыть текущую страницу или окно', + 'command.refresh': 'Обновить текущую страницу', + 'command.noRefresh': 'Эту страницу невозможно обновить', + 'command.toggle': 'Переключить правую боковую панель', + 'command.fullscreen': 'Переключить панель в полноэкранный режим', + 'command.noSession': 'Сначала выберите сеанс', + 'command.noFocus': 'Сначала сфокусируйтесь на правой боковой панели', + 'command.stale': 'Страница изменилась; сосредоточься еще раз', + 'command.collapsed': 'Сначала разверните правую боковую панель', + 'command.float': 'Это действие недоступно на плавающей панели.', + 'command.empty': 'Сначала откройте страницу', + 'command.budget': 'Две панели — это предел', + 'command.width': 'Недостаточно ширины для разделения, расширьте боковую панель', + 'chrome.expand': 'Открыть боковую панель', + 'chrome.expandAria': 'Открыть правую боковую панель', + 'chrome.collapse': 'Свернуть боковую панель', + 'chrome.collapseAria': 'Свернуть правую боковую панель', + 'chrome.toFullscreen': 'Полноэкранный режим', + 'chrome.exitFullscreen': 'Выйти из полноэкранного режима', + 'dock.emptyPane': 'Пустая панель', + 'dock.splitPane': 'Сплит', + 'dock.splitPaneDisabled': 'Две панели — это предел', + 'dock.splitPaneNarrow': 'Недостаточно ширины для разделения, расширьте боковую панель', + 'dock.closeTab': 'Закрыть', + 'dock.addTab': 'Новая вкладка', + 'dock.dockFloat': 'Отправить обратно на боковую панель', + 'dock.closeFloat': 'Закрыть', + 'dock.drop.center': 'Переместитесь сюда', + 'dock.drop.left': 'Добавить левый сплит', + 'dock.drop.right': 'Добавить правое разделение', + 'dock.drop.top': 'Добавить верхнее разделение', + 'dock.drop.bottom': 'Добавить нижний разрез', + 'tab.guide.title': 'Старт', + 'tab.guide.more': 'Дополнительные инструменты', + 'tab.unavailable': 'Ничто здесь пока не может просматривать такой контент.', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'command.close': 'Fechar a página ou janela atual', + 'command.refresh': 'Atualizar página atual', + 'command.noRefresh': 'Esta página não pode ser atualizada', + 'command.toggle': 'Alternar barra lateral direita', + 'command.fullscreen': 'Alternar painel para tela cheia', + 'command.noSession': 'Selecione uma sessão primeiro', + 'command.noFocus': 'Foque primeiro um painel da barra lateral direita', + 'command.stale': 'A página mudou; concentre-se novamente', + 'command.collapsed': 'Expanda a barra lateral direita primeiro', + 'command.float': 'Esta ação não está disponível em um painel flutuante', + 'command.empty': 'Abra uma página primeiro', + 'command.budget': 'Dois painéis é o limite', + 'command.width': 'Largura insuficiente para dividir. Amplie a barra lateral', + 'chrome.expand': 'Abrir barra lateral', + 'chrome.expandAria': 'Abrir barra lateral direita', + 'chrome.collapse': 'Recolher barra lateral', + 'chrome.collapseAria': 'Recolher barra lateral direita', + 'chrome.toFullscreen': 'Tela cheia', + 'chrome.exitFullscreen': 'Sair da tela cheia', + 'dock.emptyPane': 'Painel vazio', + 'dock.splitPane': 'Dividir', + 'dock.splitPaneDisabled': 'Dois painéis é o limite', + 'dock.splitPaneNarrow': 'Largura insuficiente para dividir. Amplie a barra lateral', + 'dock.closeTab': 'Fechar', + 'dock.addTab': 'Nova guia', + 'dock.dockFloat': 'Enviar de volta para a barra lateral', + 'dock.closeFloat': 'Fechar', + 'dock.drop.center': 'Mova-se aqui', + 'dock.drop.left': 'Adicionar divisão à esquerda', + 'dock.drop.right': 'Adicionar divisão à direita', + 'dock.drop.top': 'Adicionar divisão superior', + 'dock.drop.bottom': 'Adicionar divisão inferior', + 'tab.guide.title': 'Começar', + 'tab.guide.more': 'Mais ferramentas', + 'tab.unavailable': 'Nada aqui pode visualizar esse tipo de conteúdo ainda.', +} satisfies Record diff --git a/packages/client/ui-sidebar-terminal/locale/de.json b/packages/client/ui-sidebar-terminal/locale/de.json new file mode 100644 index 0000000000..bd4022653e --- /dev/null +++ b/packages/client/ui-sidebar-terminal/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Anschlussfeld", + "description": "Verwenden Sie das interaktive Befehlsterminal im rechten Bereich." + } +} diff --git a/packages/client/ui-sidebar-terminal/locale/es.json b/packages/client/ui-sidebar-terminal/locale/es.json new file mode 100644 index 0000000000..4e2351855e --- /dev/null +++ b/packages/client/ui-sidebar-terminal/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "panel de terminales", + "description": "Utilice la terminal de comando interactiva en el panel derecho." + } +} diff --git a/packages/client/ui-sidebar-terminal/locale/fr.json b/packages/client/ui-sidebar-terminal/locale/fr.json new file mode 100644 index 0000000000..a6b35dd180 --- /dev/null +++ b/packages/client/ui-sidebar-terminal/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "panneau à bornes", + "description": "Utilisez le terminal de commande interactif dans le panneau de droite." + } +} diff --git a/packages/client/ui-sidebar-terminal/locale/pt.json b/packages/client/ui-sidebar-terminal/locale/pt.json new file mode 100644 index 0000000000..373527231e --- /dev/null +++ b/packages/client/ui-sidebar-terminal/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "painel de terminais", + "description": "Use o terminal de comando interativo no painel direito." + } +} diff --git a/packages/client/ui-sidebar-terminal/locale/ru.json b/packages/client/ui-sidebar-terminal/locale/ru.json new file mode 100644 index 0000000000..8eaf7dd35e --- /dev/null +++ b/packages/client/ui-sidebar-terminal/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "терминальная панель", + "description": "Используйте интерактивный командный терминал на правой панели." + } +} diff --git a/packages/client/ui-sidebar-terminal/src/client/index.ts b/packages/client/ui-sidebar-terminal/src/client/index.ts index e355b4844c..0390d3f7b2 100644 --- a/packages/client/ui-sidebar-terminal/src/client/index.ts +++ b/packages/client/ui-sidebar-terminal/src/client/index.ts @@ -17,7 +17,7 @@ import { TerminalTitle } from './TerminalTitle.tsx' // import { TerminalRecovery, type TerminalRecoveryInjected } from './TerminalRecovery.tsx' // import { TerminalCleanup, type TerminalCleanupInjected } from './TerminalCleanup.tsx' import type { TerminalBodyInjected, TerminalInjected } from './face.ts' -import { en, ja, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh } from './locales.ts' /** Services needed by the terminal's two sidebar seats. */ export const inject = ['slots', 'locale', 'sidebarRight', 'sidebarRightTabs', 'webTerminals', 'theme', 'shortcuts'] @@ -67,7 +67,7 @@ export function apply(ctx: Context): void { return { status: 'handled', run: () => { ctx.sidebarRight.openTabFromTarget('terminal', target) } } }, }), 'ui-sidebar-terminal: shortcut') - ctx.effect(() => ctx.locale.register(namespace, { zh, en, ja }), 'ui-sidebar-terminal.copy') + ctx.effect(() => ctx.locale.register(namespace, { zh, en, ja, es, fr, de, ru, pt }), 'ui-sidebar-terminal.copy') ctx.effect(() => ctx.sidebarRightTabs.register({ id, kind: 'terminal', multiple: true, priority: 'builtin', title: () => t('title'), guide: [{ id: 'new', order: 20, title: () => t('new'), description: () => t('description'), icon: PluginArtworkTerminal }], diff --git a/packages/client/ui-sidebar-terminal/src/client/locales.ts b/packages/client/ui-sidebar-terminal/src/client/locales.ts index 7c822d6216..28059f5876 100644 --- a/packages/client/ui-sidebar-terminal/src/client/locales.ts +++ b/packages/client/ui-sidebar-terminal/src/client/locales.ts @@ -74,3 +74,93 @@ export const ja = { 'invalidOutput': 'ターミナル画面を受信できませんでした。再接続して復元してください。', 'terminalLimit': 'ターミナルの上限に達しました。未使用のターミナルを閉じて再試行してください。終了したターミナルも上限に含まれます。', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'shortcut.noSession': 'Seleccione una sesión primero', + recoveryFailed: 'Falló la recuperación del terminal: {message}', retryRecovery: 'Reintentar la recuperación del terminal', + shell: 'Elige concha', shellLoading: 'Cargando proyectiles…', shellEmpty: 'No hay conchas disponibles', description: 'Ejecutar comandos en el espacio de trabajo de sesión', + title: 'terminales', new: 'Nueva terminal', loading: 'Entorno de terminal de lectura...', creating: 'Empezando…', + connecting: 'Conectando…', disconnected: 'Desconectado.', reconnect: 'Reconectar', + readonly: 'Esta vista es de sólo lectura.', control: 'toma el control', + closed: 'Terminal cerrada.', exited: 'Proceso cerrado ({code})', failed: 'Error de terminal: {message}', + rename: 'Nombre del terminal', unavailable: 'No disponible', retry: 'Reintentar', + cleanupFailed: 'No se pudo finalizar el terminal “{title}”: {message}', + missingTerminal: 'Esta terminal ya no existe. Abra una nueva terminal.', + inputFull: 'El búfer de entrada está lleno. Vuelve a conectarte y vuelve a intentarlo.', + attachmentEnded: 'La conexión del terminal terminó. Vuelva a conectarse para continuar.', + invalidOutput: 'No se pudo recibir la pantalla del terminal. Vuelva a conectarse para recuperarlo.', + terminalLimit: 'Se ha alcanzado el límite terminal. Cierre los terminales no utilizados y vuelva a intentarlo. Las terminales salidas también cuentan para el límite.', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'shortcut.noSession': "Sélectionnez d'abord une session", + recoveryFailed: 'Échec de la récupération du terminal : {message}', retryRecovery: 'Réessayez la récupération du terminal', + shell: 'Choisissez la coque', shellLoading: 'Chargement des obus…', shellEmpty: 'Aucune coquille disponible', description: 'Exécuter des commandes dans l’espace de travail de la session', + title: 'Borne', new: 'Nouvelle borne', loading: 'Environnement du terminal de lecture…', creating: 'Commencer…', + connecting: 'Connexion…', disconnected: 'Déconnecté.', reconnect: 'Reconnecter', + readonly: 'Cette vue est en lecture seule.', control: 'Prenez le contrôle', + closed: 'Borne fermée.', exited: 'Processus terminé ({code})', failed: 'Erreur de terminal : {message}', + rename: 'Nom du terminal', unavailable: 'Indisponible', retry: 'Réessayer', + cleanupFailed: "Le terminal « {title} » n'a pas pu être terminé : {message}", + missingTerminal: "Ce terminal n'existe plus. Ouvrez un nouveau terminal.", + inputFull: "Le tampon d'entrée est plein. Reconnectez-vous et réessayez.", + attachmentEnded: 'La connexion du terminal est terminée. Reconnectez-vous pour continuer.', + invalidOutput: "L'écran du terminal n'a pas pu être reçu. Reconnectez-vous pour le récupérer.", + terminalLimit: 'La limite terminale a été atteinte. Fermez les terminaux inutilisés et réessayez. Les terminaux sortis comptent également dans la limite.', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'shortcut.noSession': 'Wählen Sie zunächst eine Sitzung aus', + recoveryFailed: 'Terminalwiederherstellung fehlgeschlagen: {message}', retryRecovery: 'Versuchen Sie die Terminalwiederherstellung erneut', + shell: 'Wählen Sie Shell', shellLoading: 'Granaten werden geladen…', shellEmpty: 'Keine Muscheln verfügbar', description: 'Führen Sie Befehle im Sitzungsarbeitsbereich aus', + title: 'Terminal', new: 'Neues Terminal', loading: 'Terminalumgebung lesen…', creating: 'Beginnend mit …', + connecting: 'Verbinden…', disconnected: 'Nicht verbunden.', reconnect: 'Wieder verbinden', + readonly: 'Diese Ansicht ist schreibgeschützt.', control: 'Übernehmen Sie die Kontrolle', + closed: 'Terminal geschlossen.', exited: 'Prozess beendet ({code})', failed: 'Terminalfehler: {message}', + rename: 'Terminalname', unavailable: 'Nicht verfügbar', retry: 'Erneut versuchen', + cleanupFailed: 'Terminal „{title}“ konnte nicht beendet werden: {message}', + missingTerminal: 'Dieses Terminal existiert nicht mehr. Öffnen Sie ein neues Terminal.', + inputFull: 'Der Eingabepuffer ist voll. Stellen Sie die Verbindung wieder her und versuchen Sie es erneut.', + attachmentEnded: 'Die Terminalverbindung wurde beendet. Stellen Sie die Verbindung wieder her, um fortzufahren.', + invalidOutput: 'Der Terminalbildschirm konnte nicht empfangen werden. Stellen Sie die Verbindung wieder her, um es wiederherzustellen.', + terminalLimit: 'Das Endlimit wurde erreicht. Schließen Sie nicht verwendete Terminals und versuchen Sie es erneut. Auch verlassene Terminals werden auf das Limit angerechnet.', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'shortcut.noSession': 'Сначала выберите сеанс', + recoveryFailed: 'Восстановление терминала не удалось: {message}', retryRecovery: 'Повторить попытку восстановления терминала', + shell: 'Выбрать оболочку', shellLoading: 'Загрузка снарядов…', shellEmpty: 'Нет доступных ракушек', description: 'Запуск команд в рабочей области сеанса', + title: 'Терминал', new: 'Новый терминал', loading: 'Чтение среды терминала…', creating: 'Начало…', + connecting: 'Подключение…', disconnected: 'Отключено.', reconnect: 'Восстановить соединение', + readonly: 'Это представление доступно только для чтения.', control: 'Возьмите под свой контроль', + closed: 'Терминал закрыт.', exited: 'Процесс завершен ({code})', failed: 'Ошибка терминала: {message}', + rename: 'Имя терминала', unavailable: 'Недоступно', retry: 'Повторить', + cleanupFailed: 'Терминал «{title}» не удалось завершить: {message}', + missingTerminal: 'Этого терминала больше не существует. Откройте новый терминал.', + inputFull: 'Входной буфер заполнен. Подключитесь и повторите попытку.', + attachmentEnded: 'Терминальное соединение завершилось. Подключитесь повторно, чтобы продолжить.', + invalidOutput: 'Не удалось получить экран терминала. Повторно подключитесь, чтобы восстановить его.', + terminalLimit: 'Достигнут лимит терминала. Закройте неиспользуемые терминалы и повторите попытку. Вышедшие терминалы также учитываются в лимите.', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'shortcut.noSession': 'Selecione uma sessão primeiro', + recoveryFailed: 'Falha na recuperação do terminal: {message}', retryRecovery: 'Tentar novamente a recuperação do terminal', + shell: 'Escolha a concha', shellLoading: 'Carregando conchas…', shellEmpty: 'Não há conchas disponíveis', description: 'Execute comandos no espaço de trabalho Sessão', + title: 'Terminais', new: 'Novo terminal', loading: 'Lendo o ambiente do terminal…', creating: 'Começando…', + connecting: 'Conectando…', disconnected: 'Desconectado.', reconnect: 'Reconectar', + readonly: 'Esta visualização é somente leitura.', control: 'Assuma o controle', + closed: 'Terminal fechado.', exited: 'Processo encerrado ({code})', failed: 'Erro de terminal: {message}', + rename: 'Nome do terminal', unavailable: 'Indisponível', retry: 'Tentar novamente', + cleanupFailed: 'O terminal “{title}” não pôde ser finalizado: {message}', + missingTerminal: 'Este terminal não existe mais. Abra um novo terminal.', + inputFull: 'O buffer de entrada está cheio. Reconecte e tente novamente.', + attachmentEnded: 'A conexão do terminal terminou. Reconecte para continuar.', + invalidOutput: 'A tela do terminal não pôde ser recebida. Reconecte para recuperá-lo.', + terminalLimit: 'O limite terminal foi atingido. Feche os terminais não utilizados e tente novamente. Os terminais encerrados também contam para o limite.', +} satisfies Record diff --git a/packages/client/ui-sidebar/locale/de.json b/packages/client/ui-sidebar/locale/de.json new file mode 100644 index 0000000000..b48c3793d0 --- /dev/null +++ b/packages/client/ui-sidebar/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Konversationsseitenleiste", + "description": "Konversationsliste anzeigen, Such-, Gruppierungs- und Statusaufforderungen bereitstellen." + } +} diff --git a/packages/client/ui-sidebar/locale/es.json b/packages/client/ui-sidebar/locale/es.json new file mode 100644 index 0000000000..48de49b659 --- /dev/null +++ b/packages/client/ui-sidebar/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Barra lateral de conversación", + "description": "Muestre la lista de conversaciones, proporcione indicaciones de búsqueda, agrupación y estado." + } +} diff --git a/packages/client/ui-sidebar/locale/fr.json b/packages/client/ui-sidebar/locale/fr.json new file mode 100644 index 0000000000..0dd77b45eb --- /dev/null +++ b/packages/client/ui-sidebar/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Barre latérale des conversations", + "description": "Affichez la liste des conversations, fournissez des invites de recherche, de regroupement et d’état." + } +} diff --git a/packages/client/ui-sidebar/locale/pt.json b/packages/client/ui-sidebar/locale/pt.json new file mode 100644 index 0000000000..dafc152209 --- /dev/null +++ b/packages/client/ui-sidebar/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Barra lateral de conversa", + "description": "Exibir lista de conversas, fornecer prompts de pesquisa, agrupamento e status." + } +} diff --git a/packages/client/ui-sidebar/locale/ru.json b/packages/client/ui-sidebar/locale/ru.json new file mode 100644 index 0000000000..a9df979adc --- /dev/null +++ b/packages/client/ui-sidebar/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Боковая панель беседы", + "description": "Отобразить список разговоров, предоставить поиск, группировку и подсказки о статусе." + } +} diff --git a/packages/client/ui-sidebar/src/client/index.ts b/packages/client/ui-sidebar/src/client/index.ts index 8b7c75f043..f45c249e8f 100644 --- a/packages/client/ui-sidebar/src/client/index.ts +++ b/packages/client/ui-sidebar/src/client/index.ts @@ -14,7 +14,7 @@ import type { SidebarPanelMetadata, SidebarRootInjected } from './contract/slots import { createPanelPins } from './panel-pins.ts' import { HeaderLeadingControls } from './HeaderLeadingControls.tsx' import { SidebarRoot } from './SidebarRoot.tsx' -import { en, ja, zh, type SidebarKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh, type SidebarKey } from './locales.ts' export type { SidebarBrandMarkOwnerProps, SidebarBrandNameOwnerProps, SidebarFooterActionOwnerProps, @@ -45,7 +45,7 @@ export const inject = ['slots', 'layout', 'uiWorkspace', 'locale', 'shortcuts'] */ export function apply(ctx: ClientContext): void { const workspaceNavigation = ctx.get('uiWorkspace') as unknown as WorkspaceNavigation - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-sidebar: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-sidebar: dictionaries') const panels = createSnapshotStore([]) const syncPanels = (): void => { const next = ctx.slots.entriesOfSlot('sidebar.panellist').map(({ options }) => { diff --git a/packages/client/ui-sidebar/src/client/locales.ts b/packages/client/ui-sidebar/src/client/locales.ts index a4505397a0..bfb56e2a3e 100644 --- a/packages/client/ui-sidebar/src/client/locales.ts +++ b/packages/client/ui-sidebar/src/client/locales.ts @@ -35,3 +35,58 @@ export const ja = { 'panels.more': 'その他', 'version.copied': 'バージョンをコピーしました', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'session.new': 'Nueva sesión', + 'session.new.label': 'Nueva sesión', + 'toggle.open': 'Abrir barra lateral', + 'toggle.collapse': 'Contraer barra lateral', + 'panels.label': 'Paneles globales', + 'panels.more': 'Más', + 'version.copied': 'Versión copiada', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'session.new': 'Nouvelle séance', + 'session.new.label': 'Nouvelle séance', + 'toggle.open': 'Ouvrir la barre latérale', + 'toggle.collapse': 'Réduire la barre latérale', + 'panels.label': 'Panels mondiaux', + 'panels.more': 'Plus', + 'version.copied': 'Version copiée', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'session.new': 'Neue Sitzung', + 'session.new.label': 'Neue Sitzung', + 'toggle.open': 'Seitenleiste öffnen', + 'toggle.collapse': 'Seitenleiste einklappen', + 'panels.label': 'Globale Panels', + 'panels.more': 'Mehr', + 'version.copied': 'Version kopiert', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'session.new': 'Новая сессия', + 'session.new.label': 'Новая сессия', + 'toggle.open': 'Открыть боковую панель', + 'toggle.collapse': 'Свернуть боковую панель', + 'panels.label': 'Глобальные панели', + 'panels.more': 'Ещё', + 'version.copied': 'Версия скопирована', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'session.new': 'Nova sessão', + 'session.new.label': 'Nova sessão', + 'toggle.open': 'Abrir barra lateral', + 'toggle.collapse': 'Recolher barra lateral', + 'panels.label': 'Painéis globais', + 'panels.more': 'Mais', + 'version.copied': 'Versão copiada', +} satisfies Record diff --git a/packages/client/ui-skill/locale/de.json b/packages/client/ui-skill/locale/de.json new file mode 100644 index 0000000000..3c2bcc04bb --- /dev/null +++ b/packages/client/ui-skill/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Referenz und Anzeige der Fertigkeiten", + "description": "Stellt Fertigkeitsreferenzen und Fertigkeitsaufrufanzeigen in Sitzungen bereit." + } +} diff --git a/packages/client/ui-skill/locale/es.json b/packages/client/ui-skill/locale/es.json new file mode 100644 index 0000000000..1e9055f12c --- /dev/null +++ b/packages/client/ui-skill/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Referencia y visualización de habilidades.", + "description": "Proporciona referencias de habilidades y visualizaciones de invocación de habilidades en las sesiones." + } +} diff --git a/packages/client/ui-skill/locale/fr.json b/packages/client/ui-skill/locale/fr.json new file mode 100644 index 0000000000..2404a96e66 --- /dev/null +++ b/packages/client/ui-skill/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Référence et affichage des compétences", + "description": "Fournit des références de compétences et des affichages d’invocation de compétences dans les sessions." + } +} diff --git a/packages/client/ui-skill/locale/pt.json b/packages/client/ui-skill/locale/pt.json new file mode 100644 index 0000000000..e4763a6ba6 --- /dev/null +++ b/packages/client/ui-skill/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Referência e exibição de habilidades", + "description": "Fornece referências de habilidades e exibições de invocação de habilidades nas sessões." + } +} diff --git a/packages/client/ui-skill/locale/ru.json b/packages/client/ui-skill/locale/ru.json new file mode 100644 index 0000000000..68d9539f50 --- /dev/null +++ b/packages/client/ui-skill/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Справочник и отображение навыков", + "description": "Предоставляет ссылки на навыки и отображение вызовов навыков в сеансах." + } +} diff --git a/packages/client/ui-skill/src/client/index.ts b/packages/client/ui-skill/src/client/index.ts index 0356035c26..db9b746dba 100644 --- a/packages/client/ui-skill/src/client/index.ts +++ b/packages/client/ui-skill/src/client/index.ts @@ -52,7 +52,7 @@ import { SkillRow } from './SkillRow.tsx' import { SkillReference, type SkillReferenceInjected } from './SkillReference.tsx' import { skillReferenceRule } from './user-text-rules.ts' export type {} from './user-text-rules.ts' -import { en, ja, NS, zh, type SkillKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, NS, zh, type SkillKey } from './locales.ts' declare module '@deepseek-ai/dsh-api-session-controller/client' { interface SessionReferenceSourceMap { @@ -84,7 +84,7 @@ export const inject = ['inputTriggers', 'sessions', 'slots', 'locale', 'remote', * @param ctx - client root context. */ export function apply(ctx: ClientContext): void { - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-skill: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-skill: dictionaries') ctx.uiConversation.userText.register(skillReferenceRule) ctx.slots.inject('tool.call.toolview', () => ctx.slots.register( { name: 'tool.call.toolview', key: 'skill', locale: NS }, diff --git a/packages/client/ui-skill/src/client/locales.ts b/packages/client/ui-skill/src/client/locales.ts index be188303d6..4100aec6f0 100644 --- a/packages/client/ui-skill/src/client/locales.ts +++ b/packages/client/ui-skill/src/client/locales.ts @@ -41,3 +41,63 @@ export const ja = { 'row.inspect': '詳細を確認', 'menu.userOnly': 'ユーザー専用', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'row.title': 'Habilidad', + 'row.running': 'Habilidad de carga', + 'row.preparing': 'Preparándose para cargar una habilidad', + 'row.failed': 'La carga de habilidades falló', + 'row.stopped': 'Carga de habilidades detenida', + 'row.instructions': 'Instrucciones', + 'row.inspect': 'inspeccionar', + 'menu.userOnly': 'solo usuario', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'row.title': 'Compétence', + 'row.running': 'Compétence de chargement', + 'row.preparing': 'Préparation du chargement d’une compétence', + 'row.failed': 'Échec du chargement des compétences', + 'row.stopped': 'Chargement de compétences arrêté', + 'row.instructions': 'Instructions', + 'row.inspect': 'Inspecter', + 'menu.userOnly': 'utilisateur uniquement', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'row.title': 'Geschicklichkeit', + 'row.running': 'Ladefähigkeit', + 'row.preparing': 'Das Laden eines Skills wird vorbereitet', + 'row.failed': 'Das Laden des Skills ist fehlgeschlagen', + 'row.stopped': 'Das Laden der Fertigkeiten wurde gestoppt', + 'row.instructions': 'Anweisungen', + 'row.inspect': 'Inspizieren', + 'menu.userOnly': 'Nur für Benutzer', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'row.title': 'Навык', + 'row.running': 'Навык загрузки', + 'row.preparing': 'Подготовка к загрузке навыка', + 'row.failed': 'Не удалось загрузить навык', + 'row.stopped': 'Загрузка навыков остановлена', + 'row.instructions': 'Инструкции', + 'row.inspect': 'Осмотреть', + 'menu.userOnly': 'только для пользователей', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'row.title': 'Habilidade', + 'row.running': 'Habilidade de carregamento', + 'row.preparing': 'Preparando-se para carregar uma habilidade', + 'row.failed': 'Falha no carregamento da habilidade', + 'row.stopped': 'Carga de habilidade interrompida', + 'row.instructions': 'Instruções', + 'row.inspect': 'Inspecionar', + 'menu.userOnly': 'somente usuário', +} satisfies Record diff --git a/packages/client/ui-subagent/locale/de.json b/packages/client/ui-subagent/locale/de.json new file mode 100644 index 0000000000..5d03994ab8 --- /dev/null +++ b/packages/client/ui-subagent/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Subagenten-Konversationsschnittstelle", + "description": "Sehen Sie sich Unterhaltungen untergeordneter Agenten an und springen Sie zu ihnen, mit Unterstützung für fortgesetzte Unterhaltungen und @quotes." + } +} diff --git a/packages/client/ui-subagent/locale/es.json b/packages/client/ui-subagent/locale/es.json new file mode 100644 index 0000000000..85dc3ba25f --- /dev/null +++ b/packages/client/ui-subagent/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz conversacional de subagente", + "description": "Vea y salte a conversaciones de agentes secundarios, con soporte para conversaciones continuas y @quotes." + } +} diff --git a/packages/client/ui-subagent/locale/fr.json b/packages/client/ui-subagent/locale/fr.json new file mode 100644 index 0000000000..353bd27b22 --- /dev/null +++ b/packages/client/ui-subagent/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface conversationnelle du sous-agent", + "description": "Affichez et accédez aux conversations des agents enfants, avec prise en charge des conversations continues et des @quotes." + } +} diff --git a/packages/client/ui-subagent/locale/pt.json b/packages/client/ui-subagent/locale/pt.json new file mode 100644 index 0000000000..80fbe76051 --- /dev/null +++ b/packages/client/ui-subagent/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de conversação do subagente", + "description": "Visualize e acesse conversas de agentes filhos, com suporte para conversas contínuas e @quotes." + } +} diff --git a/packages/client/ui-subagent/locale/ru.json b/packages/client/ui-subagent/locale/ru.json new file mode 100644 index 0000000000..c76c162aff --- /dev/null +++ b/packages/client/ui-subagent/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Диалоговый интерфейс субагента", + "description": "Просматривайте разговоры дочерних агентов и переходите к ним с поддержкой продолжения разговоров и @quotes." + } +} diff --git a/packages/client/ui-subagent/src/client/index.ts b/packages/client/ui-subagent/src/client/index.ts index 51f052672e..117b0b0605 100644 --- a/packages/client/ui-subagent/src/client/index.ts +++ b/packages/client/ui-subagent/src/client/index.ts @@ -14,7 +14,7 @@ import type {} from '@deepseek-ai/dsh-client-ui-renderer/client' import type {} from '@deepseek-ai/dsh-client-ui-session/client' import type {} from '@deepseek-ai/dsh-client-ui-sidebar-right/client' import type {} from '@deepseek-ai/dsh-client-ui-workspace/client' -import { en, ja, NS, zh, type SubagentKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, NS, zh, type SubagentKey } from './locales.ts' declare module '@deepseek-ai/dsh-client-ui-slots' { interface LocaleNamespaceMap { @@ -53,7 +53,7 @@ function selectReadOnlySubagent(owner: ComposerChainProps): SubagentReadOnlyMatc * @param ctx - client root context. */ export function apply(ctx: ClientContext): void { - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-subagent: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-subagent: dictionaries') ctx.inject(['resources', 'sidebarRightTabs'], (scope) => { registerSidebarChat(scope, ctx.locale.bind(NS)) }) diff --git a/packages/client/ui-subagent/src/client/locales.ts b/packages/client/ui-subagent/src/client/locales.ts index 9cd5f6d30e..4a611cbc77 100644 --- a/packages/client/ui-subagent/src/client/locales.ts +++ b/packages/client/ui-subagent/src/client/locales.ts @@ -140,3 +140,228 @@ export const ja = { 'readonly.oneShot.body': '単発タスクは追加のメッセージを受け付けません。ここで実行記録の全体を確認できます。', 'readonly.body': '親セッションがオフラインです。再度開いてメッセージの送信を続けてください。', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'duration.seconds': '{seconds}s', + 'duration.minutes': '{minutes}m {seconds}s', + 'duration.hours': '{hours}h {minutes}m {seconds}s', + 'duration.days': '{days}d', + 'duration.daysHours': '{days}d {hours}h', + 'duration.months': '~{months}mo', + 'duration.monthsDays': '~{months}mo {days}d', + 'duration.years': '~{years}y', + 'duration.yearsMonths': '~{years}y {months}mo', + 'duration.exactDays': '{days}d {hours}h {minutes}m {seconds}s', + 'duration.exactTitle': 'Duración total activa: {duration}', + 'tokens.thousand': '{value}K', + 'tokens.million': '{value}M', + 'tokens.total': 'Tok {value}', + 'loading.label': 'Cargando subagentes…', + 'load.error': 'No se pueden cargar subagentes', + 'catalog.migrationRequired': 'Migración requerida', + 'retry': 'Reintentar', + 'mode.external': 'tarea externa', + 'mode.oneShot': 'un solo disparo', + 'mode.continuable': 'continuable', + 'mode.unknown': 'modo desconocido', + 'readonly.unknown.body': 'Lea la sesión secundaria para determinar si se puede continuar.', + 'activity.running': 'corriendo', + 'activity.completed': 'completado', + 'activity.inactive': 'no corriendo', + 'branch.collapse': 'Contraer descendientes de {label}', + 'branch.expand': 'Ampliar descendientes de {label}', + 'count.total.one': 'Subagente {count}', + 'count.total.other': 'Subagentes {count}', + 'count.running.one': 'Subagente {count} ejecutándose', + 'count.running.other': 'Subagentes {count} ejecutándose', + 'switcher.aria': 'Cambiar subagente: {title}', + 'tree.aria': 'Sesiones de subagente', + 'open.sidebar': 'Abrir en la barra lateral', + 'open.sidebar.aria': 'Abra {label} en la barra lateral', + 'sidebar.chat': 'Charla', + 'readonly.oneShot.title': 'Registro de subagente de una sola vez', + 'readonly.title': 'Este subagente es de solo lectura por ahora', + 'readonly.oneShot.body': 'Las tareas únicas no aceptan seguimientos; revise el registro de ejecución completo aquí.', + 'readonly.body': 'La sesión para padres está fuera de línea; Vuelva a abrirlo para continuar enviando mensajes.', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'duration.seconds': '{seconds}s', + 'duration.minutes': '{minutes}m {seconds}s', + 'duration.hours': '{hours}h {minutes}m {seconds}s', + 'duration.days': '{days}d', + 'duration.daysHours': '{days}d {hours}h', + 'duration.months': '~{months}mo', + 'duration.monthsDays': '~{months}mo {days}d', + 'duration.years': '~{years}y', + 'duration.yearsMonths': '~{years}y {months}mo', + 'duration.exactDays': '{days}d {hours}h {minutes}m {seconds}s', + 'duration.exactTitle': "Durée totale d'activité : {duration}", + 'tokens.thousand': '{value}K', + 'tokens.million': '{value}M', + 'tokens.total': 'Jeton {value}', + 'loading.label': 'Chargement des sous-agents…', + 'load.error': 'Impossible de charger les sous-agents', + 'catalog.migrationRequired': 'Migration requise', + 'retry': 'Réessayer', + 'mode.external': 'Tâche externe', + 'mode.oneShot': 'un coup', + 'mode.continuable': 'continu', + 'mode.unknown': 'mode inconnu', + 'readonly.unknown.body': 'Lisez la séance enfant pour déterminer si elle peut être poursuivie.', + 'activity.running': 'courir', + 'activity.completed': 'terminé', + 'activity.inactive': 'ne fonctionne pas', + 'branch.collapse': 'Réduire les descendants de {label}', + 'branch.expand': 'Développer les descendants de {label}', + 'count.total.one': 'Sous-agent {count}', + 'count.total.other': 'Sous-agents {count}', + 'count.running.one': "Sous-agent {count} en cours d'exécution", + 'count.running.other': "Sous-agents {count} en cours d'exécution", + 'switcher.aria': 'Changer de sous-agent : {title}', + 'tree.aria': 'Sessions de sous-agents', + 'open.sidebar': 'Ouvrir dans la barre latérale', + 'open.sidebar.aria': 'Ouvrir {label} dans la barre latérale', + 'sidebar.chat': 'Discuter', + 'readonly.oneShot.title': 'Enregistrement de sous-agent unique', + 'readonly.title': 'Ce sous-agent est actuellement en lecture seule', + 'readonly.oneShot.body': 'Les tâches ponctuelles n’acceptent pas de messages de suivi ; consultez leur journal d’exécution complet ici.', + 'readonly.body': 'La session parente est hors ligne ; rouvrez-la pour continuer à envoyer des messages.', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'duration.seconds': '{seconds}s', + 'duration.minutes': '{minutes}m {seconds}s', + 'duration.hours': '{hours}h {minutes}m {seconds}s', + 'duration.days': '{days}d', + 'duration.daysHours': '{days}d {hours}h', + 'duration.months': '~{months}mo', + 'duration.monthsDays': '~{months}mo {days}d', + 'duration.years': '~{years}y', + 'duration.yearsMonths': '~{years}y {months}mo', + 'duration.exactDays': '{days}d {hours}h {minutes}m {seconds}s', + 'duration.exactTitle': 'Gesamte aktive Dauer: {duration}', + 'tokens.thousand': '{value}K', + 'tokens.million': '{value}M', + 'tokens.total': '{value}-Token', + 'loading.label': 'Subagenten werden geladen…', + 'load.error': 'Subagenten können nicht geladen werden', + 'catalog.migrationRequired': 'Migration erforderlich', + 'retry': 'Erneut versuchen', + 'mode.external': 'Externe Aufgabe', + 'mode.oneShot': 'One-Shot', + 'mode.continuable': 'fortsetzbar', + 'mode.unknown': 'Unbekannter Modus', + 'readonly.unknown.body': 'Lesen Sie die untergeordnete Sitzung, um festzustellen, ob sie fortgesetzt werden kann.', + 'activity.running': 'laufen', + 'activity.completed': 'abgeschlossen', + 'activity.inactive': 'läuft nicht', + 'branch.collapse': '{label}-Nachkommen reduzieren', + 'branch.expand': 'Erweitern Sie {label}-Nachkommen', + 'count.total.one': '{count}-Subagent', + 'count.total.other': '{count}-Subagenten', + 'count.running.one': '{count}-Subagent läuft', + 'count.running.other': '{count} Subagenten laufen', + 'switcher.aria': 'Subagent wechseln: {title}', + 'tree.aria': 'Subagentensitzungen', + 'open.sidebar': 'In der Seitenleiste öffnen', + 'open.sidebar.aria': 'Öffnen Sie {label} in der Seitenleiste', + 'sidebar.chat': 'Chatten', + 'readonly.oneShot.title': 'Einmaliger Subagentendatensatz', + 'readonly.title': 'Dieser Subagent ist derzeit schreibgeschützt', + 'readonly.oneShot.body': 'Einmalige Aufgaben akzeptieren keine Folgeaufgaben; Sehen Sie sich hier den vollständigen Ausführungsbericht an.', + 'readonly.body': 'Die übergeordnete Sitzung ist offline. Öffnen Sie es erneut, um weiterhin Nachrichten zu senden.', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'duration.seconds': '{seconds}s', + 'duration.minutes': '{minutes}m {seconds}s', + 'duration.hours': '{hours}h {minutes}m {seconds}s', + 'duration.days': '{days}d', + 'duration.daysHours': '{days}d {hours}h', + 'duration.months': '~{months}mo', + 'duration.monthsDays': '~{months}mo {days}d', + 'duration.years': '~{years}y', + 'duration.yearsMonths': '~{years}y {months}mo', + 'duration.exactDays': '{days}d {hours}h {minutes}m {seconds}s', + 'duration.exactTitle': 'Общая активная продолжительность: {duration}', + 'tokens.thousand': '{value}K', + 'tokens.million': '{value}M', + 'tokens.total': '{value} ток', + 'loading.label': 'Загрузка субагентов…', + 'load.error': 'Невозможно загрузить субагенты', + 'catalog.migrationRequired': 'Требуется миграция', + 'retry': 'Повторить', + 'mode.external': 'Внешняя задача', + 'mode.oneShot': 'одноразовый', + 'mode.continuable': 'продолжаемый', + 'mode.unknown': 'неизвестный режим', + 'readonly.unknown.body': 'Прочтите дочерний сеанс, чтобы определить, можно ли его продолжить.', + 'activity.running': 'бег', + 'activity.completed': 'завершено', + 'activity.inactive': 'не работает', + 'branch.collapse': 'Свернуть потомков {label}', + 'branch.expand': 'Развернуть потомков {label}', + 'count.total.one': 'Субагент {count}', + 'count.total.other': 'Субагенты {count}', + 'count.running.one': 'Субагент {count} работает', + 'count.running.other': 'Субагенты {count} работают', + 'switcher.aria': 'Переключить субагент: {title}', + 'tree.aria': 'Сеансы субагента', + 'open.sidebar': 'Открыть в боковой панели', + 'open.sidebar.aria': 'Откройте {label} на боковой панели.', + 'sidebar.chat': 'Чат', + 'readonly.oneShot.title': 'Разовая запись субагента', + 'readonly.title': 'Этот субагент пока доступен только для чтения.', + 'readonly.oneShot.body': 'Одноразовые задачи не допускают последующих действий; просмотреть полную запись выполнения можно здесь.', + 'readonly.body': 'Родительский сеанс находится в автономном режиме; откройте его повторно, чтобы продолжить отправку сообщений.', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'duration.seconds': '{seconds}s', + 'duration.minutes': '{minutes}m {seconds}s', + 'duration.hours': '{hours}h {minutes}m {seconds}s', + 'duration.days': '{days}d', + 'duration.daysHours': '{days}d {hours}h', + 'duration.months': '~{months} mês', + 'duration.monthsDays': '~{months}mês {days}d', + 'duration.years': '~{years}y', + 'duration.yearsMonths': '~{years}a {months}mês', + 'duration.exactDays': '{days}d {hours}h {minutes}m {seconds}s', + 'duration.exactTitle': 'Duração total ativa: {duration}', + 'tokens.thousand': '{value}K', + 'tokens.million': '{value}M', + 'tokens.total': '{value} valor', + 'loading.label': 'Carregando subagentes…', + 'load.error': 'Não foi possível carregar subagentes', + 'catalog.migrationRequired': 'Migração necessária', + 'retry': 'Tentar novamente', + 'mode.external': 'Tarefa externa', + 'mode.oneShot': 'tiro único', + 'mode.continuable': 'continuável', + 'mode.unknown': 'modo desconhecido', + 'readonly.unknown.body': 'Leia a sessão secundária para determinar se ela pode continuar.', + 'activity.running': 'correndo', + 'activity.completed': 'concluído', + 'activity.inactive': 'não está funcionando', + 'branch.collapse': 'Recolher {label} descendentes', + 'branch.expand': 'Expandir {label} descendentes', + 'count.total.one': '{count} subagente', + 'count.total.other': '{count} subagentes', + 'count.running.one': '{count} subagente em execução', + 'count.running.other': '{count} subagentes em execução', + 'switcher.aria': 'Alternar subagente: {title}', + 'tree.aria': 'Sessões de subagente', + 'open.sidebar': 'Abrir na barra lateral', + 'open.sidebar.aria': 'Abra {label} na barra lateral', + 'sidebar.chat': 'Bate-papo', + 'readonly.oneShot.title': 'Registro de subagente único', + 'readonly.title': 'Este subagente é somente leitura por enquanto', + 'readonly.oneShot.body': 'Tarefas únicas não aceitam acompanhamentos; revise o registro completo da execução aqui.', + 'readonly.body': 'A sessão pai está offline; reabra-o para continuar enviando mensagens.', +} satisfies Record diff --git a/packages/client/ui-theme/locale/de.json b/packages/client/ui-theme/locale/de.json new file mode 100644 index 0000000000..dc5c7ad008 --- /dev/null +++ b/packages/client/ui-theme/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Schnittstellenthema", + "description": "Bietet helle, dunkle und systembezogene Themeneinstellungen." + } +} diff --git a/packages/client/ui-theme/locale/es.json b/packages/client/ui-theme/locale/es.json new file mode 100644 index 0000000000..db2f55b5d8 --- /dev/null +++ b/packages/client/ui-theme/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Tema de interfaz", + "description": "Proporciona configuraciones de temas claros, oscuros y que siguen el sistema." + } +} diff --git a/packages/client/ui-theme/locale/fr.json b/packages/client/ui-theme/locale/fr.json new file mode 100644 index 0000000000..3ce1c36dc0 --- /dev/null +++ b/packages/client/ui-theme/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Thème de l'interface", + "description": "Fournit des paramètres de thème clair, sombre et suivant le système." + } +} diff --git a/packages/client/ui-theme/locale/pt.json b/packages/client/ui-theme/locale/pt.json new file mode 100644 index 0000000000..8cdd9e51cb --- /dev/null +++ b/packages/client/ui-theme/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Tema de interface", + "description": "Fornece configurações de tema claro, escuro e de acordo com o sistema." + } +} diff --git a/packages/client/ui-theme/locale/ru.json b/packages/client/ui-theme/locale/ru.json new file mode 100644 index 0000000000..de4dfcc5f3 --- /dev/null +++ b/packages/client/ui-theme/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Тема интерфейса", + "description": "Обеспечивает светлые, темные и системные настройки темы." + } +} diff --git a/packages/client/ui-theme/src/client/index.ts b/packages/client/ui-theme/src/client/index.ts index 0618c8a17e..a020fc35ae 100644 --- a/packages/client/ui-theme/src/client/index.ts +++ b/packages/client/ui-theme/src/client/index.ts @@ -27,7 +27,7 @@ import { createAppearanceRowStore, createFontRowStore } from './settings-store.t import { ICON_SYMBOLS, type IconSymbolId } from '@deepseek-ai/dsh-client-ui-primitives' import { installIconSprite, type IconReplacements } from './icon-sprite.ts' import { installThemeStyles } from './styles.ts' -import { en, ja, zh, type ThemeKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh, type ThemeKey } from './locales.ts' import { DEFAULT_FONT_SIZES, DEFAULT_PREFERENCE, FONT_FAMILY_FIELDS, FONT_ROLES, FONT_SIZE_SPECS, fontFamilyVariable, isFontSize, isThemePreference, normalizeFontFamily, sectionFontSizes, @@ -595,7 +595,7 @@ export const inject = ['slots', 'locale', 'remote', 'configForms'] */ export function apply(ctx: ClientContext): void { installThemeStyles(ctx) - ctx.effect(() => ctx.locale.register(SETTINGS_NS, { zh, en, ja }), 'ui-theme: settings row dictionaries') + ctx.effect(() => ctx.locale.register(SETTINGS_NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-theme: settings row dictionaries') const host = ctx.configForms.get(THEME_SETTINGS_NAMESPACE) const theme = new ThemeRuntime(ctx, host) ctx.provide('theme', theme) diff --git a/packages/client/ui-theme/src/client/locales.ts b/packages/client/ui-theme/src/client/locales.ts index b34cab3e2b..11767efb12 100644 --- a/packages/client/ui-theme/src/client/locales.ts +++ b/packages/client/ui-theme/src/client/locales.ts @@ -89,3 +89,148 @@ export const ja = { 'fontFamily.placeholder': 'デフォルト', 'fontSize.more': 'その他のフォント設定', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'appearance.title': 'Apariencia', + 'appearance.light': 'Luz', + 'appearance.dark': 'oscuro', + 'appearance.system': 'Sistema', + 'fontSize.text.title': 'Tamaño de fuente', + 'fontSize.text.description': 'Sólo afecta al contenido de la conversación.', + 'fontSize.text.increase': 'Aumentar el tamaño de fuente', + 'fontSize.text.decrease': 'Disminuir el tamaño de fuente', + 'fontSize.code.title': 'Tamaño de fuente del código', + 'fontSize.code.description': 'Se utiliza para bloques de código, código en línea y salida de herramientas.', + 'fontSize.code.increase': 'Aumentar el tamaño de fuente del código', + 'fontSize.code.decrease': 'Disminuir el tamaño de fuente del código', + 'fontSize.terminal.title': 'Tamaño de fuente del terminal', + 'fontSize.terminal.description': 'Utilizado para el terminal de la barra lateral.', + 'fontSize.terminal.increase': 'Aumentar el tamaño de fuente del terminal', + 'fontSize.terminal.decrease': 'Disminuir el tamaño de fuente del terminal', + 'fontSize.unit': 'píxeles', + 'fontFamily.text.title': 'Fuente de texto', + 'fontFamily.text.description': 'Se utiliza para la interfaz y el texto de la conversación. Separe las fuentes con comas; dejar vacío por defecto', + 'fontFamily.code.title': 'Fuente de código', + 'fontFamily.code.description': 'Se utiliza para bloques de código, código en línea y salida de herramientas. Separe las fuentes con comas; dejar vacío por defecto', + 'fontFamily.terminal.title': 'Fuente terminal', + 'fontFamily.terminal.description': 'Se utiliza para el terminal de la barra lateral. Separe las fuentes con comas; dejar vacío por defecto', + 'fontFamily.placeholder': 'Predeterminado', + 'fontSize.more': 'Más configuraciones de fuente', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'appearance.title': 'Apparence', + 'appearance.light': 'Lumière', + 'appearance.dark': 'Sombre', + 'appearance.system': 'Système', + 'fontSize.text.title': 'Taille de la police', + 'fontSize.text.description': 'Affecte uniquement le contenu de la conversation', + 'fontSize.text.increase': 'Augmenter la taille de la police', + 'fontSize.text.decrease': 'Diminuer la taille de la police', + 'fontSize.code.title': 'Taille de la police du code', + 'fontSize.code.description': "Utilisé pour les blocs de code, le code en ligne et la sortie de l'outil", + 'fontSize.code.increase': 'Augmenter la taille de la police du code', + 'fontSize.code.decrease': 'Diminuer la taille de la police du code', + 'fontSize.terminal.title': 'Taille de la police du terminal', + 'fontSize.terminal.description': 'Utilisé pour le terminal de la barre latérale', + 'fontSize.terminal.increase': 'Augmenter la taille de la police du terminal', + 'fontSize.terminal.decrease': 'Diminuer la taille de la police du terminal', + 'fontSize.unit': 'px', + 'fontFamily.text.title': 'Police du texte', + 'fontFamily.text.description': "Utilisé pour l'interface et le texte de la conversation. Séparez les polices par des virgules ; laisser vide pour la valeur par défaut", + 'fontFamily.code.title': 'Police de code', + 'fontFamily.code.description': "Utilisé pour les blocs de code, le code en ligne et la sortie de l'outil. Séparez les polices par des virgules ; laisser vide pour la valeur par défaut", + 'fontFamily.terminal.title': 'Police du terminal', + 'fontFamily.terminal.description': 'Utilisé pour le terminal de la barre latérale. Séparez les polices par des virgules ; laisser vide pour la valeur par défaut', + 'fontFamily.placeholder': 'Par défaut', + 'fontSize.more': 'Plus de paramètres de police', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'appearance.title': 'Aussehen', + 'appearance.light': 'Licht', + 'appearance.dark': 'Dunkel', + 'appearance.system': 'System', + 'fontSize.text.title': 'Schriftgröße', + 'fontSize.text.description': 'Betrifft nur Konversationsinhalte', + 'fontSize.text.increase': 'Schriftgröße erhöhen', + 'fontSize.text.decrease': 'Schriftgröße verringern', + 'fontSize.code.title': 'Code-Schriftgröße', + 'fontSize.code.description': 'Wird für Codeblöcke, Inline-Code und Tool-Ausgabe verwendet', + 'fontSize.code.increase': 'Erhöhen Sie die Schriftgröße des Codes', + 'fontSize.code.decrease': 'Verringern Sie die Schriftgröße des Codes', + 'fontSize.terminal.title': 'Terminal-Schriftgröße', + 'fontSize.terminal.description': 'Wird für das Sidebar-Terminal verwendet', + 'fontSize.terminal.increase': 'Erhöhen Sie die Schriftgröße des Terminals', + 'fontSize.terminal.decrease': 'Verringern Sie die Schriftgröße des Terminals', + 'fontSize.unit': 'px', + 'fontFamily.text.title': 'Textschriftart', + 'fontFamily.text.description': 'Wird für die Benutzeroberfläche und den Konversationstext verwendet. Trennen Sie Schriftarten durch Kommas. Für die Standardeinstellung leer lassen', + 'fontFamily.code.title': 'Codeschriftart', + 'fontFamily.code.description': 'Wird für Codeblöcke, Inline-Code und Tool-Ausgabe verwendet. Trennen Sie Schriftarten durch Kommas. Für die Standardeinstellung leer lassen', + 'fontFamily.terminal.title': 'Terminal-Schriftart', + 'fontFamily.terminal.description': 'Wird für das Sidebar-Terminal verwendet. Trennen Sie Schriftarten durch Kommas. Für die Standardeinstellung leer lassen', + 'fontFamily.placeholder': 'Standard', + 'fontSize.more': 'Weitere Schriftarteinstellungen', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'appearance.title': 'Внешний вид', + 'appearance.light': 'Свет', + 'appearance.dark': 'Темный', + 'appearance.system': 'Система', + 'fontSize.text.title': 'Размер шрифта', + 'fontSize.text.description': 'Влияет только на содержание разговора', + 'fontSize.text.increase': 'Увеличить размер шрифта', + 'fontSize.text.decrease': 'Уменьшить размер шрифта', + 'fontSize.code.title': 'Размер шрифта кода', + 'fontSize.code.description': 'Используется для блоков кода, встроенного кода и выходных данных инструмента.', + 'fontSize.code.increase': 'Увеличить размер шрифта кода', + 'fontSize.code.decrease': 'Уменьшить размер шрифта кода', + 'fontSize.terminal.title': 'Размер шрифта терминала', + 'fontSize.terminal.description': 'Используется для терминала боковой панели', + 'fontSize.terminal.increase': 'Увеличьте размер шрифта терминала', + 'fontSize.terminal.decrease': 'Уменьшить размер шрифта терминала', + 'fontSize.unit': 'пикселей', + 'fontFamily.text.title': 'Текстовый шрифт', + 'fontFamily.text.description': 'Используется для интерфейса и текста разговора. Разделяйте шрифты запятыми; оставьте пустым по умолчанию', + 'fontFamily.code.title': 'Шрифт кода', + 'fontFamily.code.description': 'Используется для блоков кода, встроенного кода и выходных данных инструмента. Разделяйте шрифты запятыми; оставьте пустым по умолчанию', + 'fontFamily.terminal.title': 'Шрифт терминала', + 'fontFamily.terminal.description': 'Используется для терминала боковой панели. Разделяйте шрифты запятыми; оставьте пустым по умолчанию', + 'fontFamily.placeholder': 'По умолчанию', + 'fontSize.more': 'Дополнительные настройки шрифта', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'appearance.title': 'Aparência', + 'appearance.light': 'Luz', + 'appearance.dark': 'Escuro', + 'appearance.system': 'Sistema', + 'fontSize.text.title': 'Tamanho da fonte', + 'fontSize.text.description': 'Afeta apenas o conteúdo da conversa', + 'fontSize.text.increase': 'Aumentar o tamanho da fonte', + 'fontSize.text.decrease': 'Diminuir o tamanho da fonte', + 'fontSize.code.title': 'Tamanho da fonte do código', + 'fontSize.code.description': 'Usado para blocos de código, código embutido e saída de ferramenta', + 'fontSize.code.increase': 'Aumentar o tamanho da fonte do código', + 'fontSize.code.decrease': 'Diminuir o tamanho da fonte do código', + 'fontSize.terminal.title': 'Tamanho da fonte do terminal', + 'fontSize.terminal.description': 'Usado para o terminal da barra lateral', + 'fontSize.terminal.increase': 'Aumentar o tamanho da fonte do terminal', + 'fontSize.terminal.decrease': 'Diminuir o tamanho da fonte do terminal', + 'fontSize.unit': 'pixels', + 'fontFamily.text.title': 'Fonte do texto', + 'fontFamily.text.description': 'Usado para interface e texto de conversa. Separe as fontes com vírgulas; deixe em branco para o padrão', + 'fontFamily.code.title': 'Fonte do código', + 'fontFamily.code.description': 'Usado para blocos de código, código embutido e saída de ferramenta. Separe as fontes com vírgulas; deixe em branco para o padrão', + 'fontFamily.terminal.title': 'Fonte terminal', + 'fontFamily.terminal.description': 'Usado para o terminal da barra lateral. Separe as fontes com vírgulas; deixe em branco para o padrão', + 'fontFamily.placeholder': 'Padrão', + 'fontSize.more': 'Mais configurações de fonte', +} satisfies Record diff --git a/packages/client/ui-tool/locale/de.json b/packages/client/ui-tool/locale/de.json new file mode 100644 index 0000000000..88a7b7e402 --- /dev/null +++ b/packages/client/ui-tool/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Anzeige des Werkzeugaufrufs", + "description": "Zeigt den Werkzeugaufrufprozess, verschachtelte Beziehungen und die Ergebnisschnittstelle jedes Werkzeugs an." + } +} diff --git a/packages/client/ui-tool/locale/es.json b/packages/client/ui-tool/locale/es.json new file mode 100644 index 0000000000..4798ae5cde --- /dev/null +++ b/packages/client/ui-tool/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Visualización de llamada de herramienta", + "description": "Muestra el proceso de llamada de herramientas, las relaciones anidadas y la interfaz de resultados de cada herramienta." + } +} diff --git a/packages/client/ui-tool/locale/fr.json b/packages/client/ui-tool/locale/fr.json new file mode 100644 index 0000000000..1728e08a11 --- /dev/null +++ b/packages/client/ui-tool/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Affichage des appels d'outils", + "description": "Affiche le processus d'appel de l'outil, les relations imbriquées et l'interface de résultat de chaque outil." + } +} diff --git a/packages/client/ui-tool/locale/pt.json b/packages/client/ui-tool/locale/pt.json new file mode 100644 index 0000000000..2500088c1b --- /dev/null +++ b/packages/client/ui-tool/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Exibição de chamada de ferramenta", + "description": "Mostra o processo de chamada da ferramenta, os relacionamentos aninhados e a interface de resultados de cada ferramenta." + } +} diff --git a/packages/client/ui-tool/locale/ru.json b/packages/client/ui-tool/locale/ru.json new file mode 100644 index 0000000000..dc1d297b73 --- /dev/null +++ b/packages/client/ui-tool/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Отображение вызова инструмента", + "description": "Показывает процесс вызова инструмента, вложенные связи и интерфейс результатов каждого инструмента." + } +} diff --git a/packages/client/ui-trajectory/locale/de.json b/packages/client/ui-trajectory/locale/de.json new file mode 100644 index 0000000000..a66a480012 --- /dev/null +++ b/packages/client/ui-trajectory/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Laufstrecke", + "description": "Sehen Sie sich laufende Aufzeichnungen wie Nachrichten, Werkzeugaufrufe, Zeitverbrauch und Token pro Runde an." + } +} diff --git a/packages/client/ui-trajectory/locale/es.json b/packages/client/ui-trajectory/locale/es.json new file mode 100644 index 0000000000..284dc23629 --- /dev/null +++ b/packages/client/ui-trajectory/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "pista de atletismo", + "description": "Vea registros en ejecución como mensajes, llamadas de herramientas, consumo de tiempo y tokens por ronda." + } +} diff --git a/packages/client/ui-trajectory/locale/fr.json b/packages/client/ui-trajectory/locale/fr.json new file mode 100644 index 0000000000..f61bd8a755 --- /dev/null +++ b/packages/client/ui-trajectory/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Piste de course", + "description": "Affichez les enregistrements en cours tels que les messages, les appels d'outils, la consommation de temps et les jetons par tour." + } +} diff --git a/packages/client/ui-trajectory/locale/pt.json b/packages/client/ui-trajectory/locale/pt.json new file mode 100644 index 0000000000..385830662e --- /dev/null +++ b/packages/client/ui-trajectory/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Pista de corrida", + "description": "Visualize registros em execução, como mensagens, chamadas de ferramentas, consumo de tempo e tokens por rodada." + } +} diff --git a/packages/client/ui-trajectory/locale/ru.json b/packages/client/ui-trajectory/locale/ru.json new file mode 100644 index 0000000000..049a1bae20 --- /dev/null +++ b/packages/client/ui-trajectory/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Беговая дорожка", + "description": "Просматривайте текущие записи, такие как сообщения, вызовы инструментов, затраты времени и токены, по раундам." + } +} diff --git a/packages/client/ui-trajectory/src/client/index.ts b/packages/client/ui-trajectory/src/client/index.ts index 05975721ad..5f33f9b806 100644 --- a/packages/client/ui-trajectory/src/client/index.ts +++ b/packages/client/ui-trajectory/src/client/index.ts @@ -16,7 +16,7 @@ import type {} from '@deepseek-ai/dsh-client-ui-renderer/client' import type {} from '@deepseek-ai/dsh-client-ui-session/client' import { createTrajectoryDurationStore } from './duration-store.ts' import { createTrajectoryStringWrappingStore } from './string-wrapping-store.ts' -import { en, ja, NS, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, NS, zh } from './locales.ts' import { registerTrajectoryAssistantDefinition } from './trajectory-assistant-definition.ts' import { registerTrajectoryCompactionDefinitions } from './trajectory-compaction-definition.ts' import { registerTrajectoryMessageDefinitions } from './trajectory-message-definitions.ts' @@ -59,7 +59,7 @@ export function apply(ctx: Context): void { } return source } - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-trajectory: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-trajectory: dictionaries') // Registration-time text (the view tab label) reads through the bound // translate as a thunk, so it follows the active locale without // re-registration. diff --git a/packages/client/ui-trajectory/src/client/locales.ts b/packages/client/ui-trajectory/src/client/locales.ts index 3dc996d556..7128f43815 100644 --- a/packages/client/ui-trajectory/src/client/locales.ts +++ b/packages/client/ui-trajectory/src/client/locales.ts @@ -604,3 +604,983 @@ export const ja = { 'layout.systemPromptAndToolsUpdated': 'システムプロンプトとツールを更新', 'layout.compactionInterrupted': '圧縮は完了前に中断されました。', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'view.trajectory': 'Trayectoria', + 'toolbar.aria': 'Barra de herramientas de trayectoria', + 'toolbar.duration': 'Duración', + 'toolbar.useActualDuration': 'Usar duración real', + 'toolbar.useEqualWidth': 'Utilice operaciones de igual ancho', + 'toolbar.actualTime': 'tiempo real', + 'toolbar.turns': 'Turnos', + 'toolbar.expandTurns': 'Expandir turnos', + 'toolbar.collapseTurns': 'Contraer turnos', + 'toolbar.calls': 'llamadas', + 'toolbar.expandCalls': 'Ampliar llamadas', + 'toolbar.collapseCalls': 'Contraer llamadas', + 'toolbar.search': 'Trayectoria de búsqueda', + 'toolbar.searchPlaceholder': 'Buscar', + 'kind.system': 'SISTEMA', + 'kind.user': 'USUARIO', + 'kind.context': 'CONTEXTO', + 'kind.compacted': 'COMPACTADO', + 'kind.message': 'Mensaje', + 'kind.assistant': 'ASISTENTE', + 'kind.tool': 'HERRAMIENTA', + 'kind.subtool': 'SUBHERRAMIENTA', + 'kind.sub': 'Subtítulo', + 'column.input': 'Entrada', + 'column.output': 'Salida', + 'column.think': 'pensar', + 'column.time': 'tiempo', + 'column.model': 'modelo', + 'column.tools': 'Herramientas', + 'turn.label': 'Turno {turn}', + 'section.betweenTurns': 'Entre turnos', + 'group.message': 'Mensaje', + 'group.step': 'Paso {step}', + 'group.compaction': 'Compactación {seq}', + 'status.failed': 'Fallido', + 'status.pending': 'Pendiente', + 'status.completed': 'Completado', + 'timing.notAvailable': 'No disponible', + 'timing.notRecorded': 'No registrado', + 'timing.stepStartUnavailable': 'Inicio de paso no disponible', + 'timing.firstTokenUnavailable': 'Primer token no disponible', + 'timing.usageUnavailable': 'Uso no disponible', + 'timing.outputTokensUnavailable': 'Tokens de salida no disponibles', + 'timing.durationTooShort': 'Duración demasiado corta', + 'timing.showLocalTime': 'Mostrar hora local', + 'timing.showUnixTimestamp': 'Mostrar marca de tiempo de Unix', + 'timing.started': 'iniciado', + 'timing.totalDuration': 'Duración total', + 'timing.ttft': 'TTFT', + 'timing.generation': 'Generación', + 'timing.throughput': 'Rendimiento', + 'timing.duration': 'Duración', + 'timing.source': 'fuente de tiempo', + 'timing.sessionTimestamps': 'Marcas de tiempo de sesión', + 'timing.sessionTimestampsRunning': 'Marcas de tiempo de sesión (en ejecución)', + 'timing.request': 'Solicitar tiempo', + 'unit.milliseconds': '{value} ms', + 'unit.seconds': '{value}', + 'unit.tokens': 'Tok {value}', + 'unit.tokensPerSecond': '{value} tok/s', + 'usage.tokens': 'Fichas', + 'usage.reasoning': 'Razonamiento', + 'usage.content': 'Contenido', + 'usage.notReported': 'Uso no reportado', + 'usage.input': 'Entrada', + 'usage.cached': 'En caché', + 'usage.cacheCreated': 'Caché creada', + 'usage.other': 'Otro', + 'usage.output': 'Salida', + 'usage.thisRequest': 'Esta solicitud', + 'usage.sessionCumulative': 'Sesión acumulativa', + 'options.notRecorded': 'Opciones no registradas', + 'options.json': 'Solicitar opciones JSON', + 'source.unknown': 'Desconocido', + 'source.user': 'Usuario', + 'source.plugin': 'Complemento', + 'source.pluginNamed': 'Complemento · {plugin}', + 'source.goal': 'Objetivo', + 'source.goalRound': 'Gol · Ronda {round}', + 'source.notRecorded': 'Fuente no registrada', + 'source.messageJson': 'Fuente del mensaje JSON', + 'tab.summary': 'Resumen', + 'tab.rawOutput': 'Salida bruta', + 'tab.preview': 'Vista previa', + 'tab.raw': 'crudo', + 'tab.source': 'Fuente', + 'tab.payload': 'Carga útil', + 'tab.result': 'Resultado', + 'tab.schema': 'esquema', + 'tab.timing': 'Sincronización', + 'tab.diff': 'diferencia', + 'tab.systemPrompt': 'Aviso del sistema', + 'tab.tools': 'Herramientas', + 'tab.options': 'Opciones', + 'tab.usage': 'Uso', + 'record.toolCallOnly': '(solo llamada de herramienta)', + 'record.noContent': 'Sin contenido', + 'record.noPayload': 'Ninguna carga útil capturada', + 'record.noResult': 'Ningún resultado capturado', + 'record.noOutput': 'Sin salida', + 'record.schemaUnavailable': 'Esquema no disponible', + 'record.parameters': 'Parámetros', + 'record.resultJson': 'Resultado JSON', + 'record.json': 'JSON', + 'record.parametersJson': 'parámetros JSON', + 'record.namedParametersJson': 'Parámetros de {name} JSON', + 'record.payloadJson': 'Carga útil JSON', + 'record.outputJson': 'Resultado JSON', + 'record.thinking': 'Pensando', + 'record.wrapLines': 'Ajustar líneas', + 'code.source': 'Código', + 'code.output': 'Salida', + 'code.copySource': 'Copiar código', + 'code.copyOutput': 'Copiar salida', + 'code.originalJson': 'Originales JSON.', + 'code.running': 'Corriendo…', + 'record.systemPromptMissing': 'No hay mensaje del sistema en esta solicitud', + 'record.toolsMissing': 'No hay herramientas en esta solicitud', + 'record.systemPrompt': 'Aviso del sistema', + 'record.tools': 'Herramientas', + 'block.openSummary': 'Resumen de llamadas a la herramienta Open Block #{index}', + 'block.openSummaryTitle': 'Resumen de llamada de herramienta abierta', + 'block.label': 'Bloque #{index} {type}', + 'history.loadingTrajectory': 'Cargando trayectoria…', + 'history.loadingEarlier': 'Cargando historial anterior…', + 'history.loadingEarlierAria': 'Cargando historial anterior…', + 'history.loadEarlier': 'Cargar historial anterior', + 'history.clickToLoadEarlier': 'Haga clic para cargar el historial anterior', + 'request.label': 'Solicitud #{request}', + 'request.labelCompaction': 'Solicitud #{request} · Compactación', + 'request.compaction': 'Compactación · {section}', + 'request.compactionPurpose': 'Compactación', + 'request.retryProgress': '{retry} de {maximum}', + 'request.collapsedSummary': 'Resumen de {kind} contraído, {summary}', + 'request.collapsedTurn': 'turno', + 'request.collapsedAssistant': 'asistente', + 'request.rowAria': '{request}{kind}, {content}', + 'request.rowPrefix': 'Solicitar {request}, ', + 'request.rowAriaCompaction': 'Solicitar {request}, compactación', + 'request.noContent': 'sin contenido', + 'summary.toolCalls.one': 'Llamada a la herramienta {count}', + 'summary.toolCalls.other': 'Llamadas a herramientas {count}', + 'summary.steps.one': 'Paso {count}', + 'summary.steps.other': 'Pasos {count}', + 'details.event': 'Detalles del evento', + 'details.resize': 'Cambiar el tamaño de los detalles del evento', + 'details.resizeTitle': 'Arrastre para cambiar el tamaño. Haga doble clic para restablecer.', + 'details.close': 'Cerrar detalles', + 'details.status': 'Estado', + 'details.purpose': 'Propósito', + 'details.provider': 'Proveedor', + 'details.model': 'modelo', + 'details.toolCalls': 'Llamadas a herramientas', + 'details.subtoolCalls': 'Llamadas a subherramientas', + 'details.error': 'error', + 'details.lastAttemptError': 'Error del último intento', + 'details.failure.auth': 'La clave API no es válida', + 'details.retry': 'Reintentar', + 'details.retryDelay': 'Retraso de reintento', + 'details.result': 'Resultado', + 'details.compacted': 'compactado', + 'details.assistantMessage': 'Mensaje del asistente', + 'details.source': 'Fuente', + 'details.hierarchy': 'Jerarquía', + 'details.toolCall': 'Llamada de herramienta', + 'timeline.aria': 'Cronología de la trayectoria', + 'timeline.overviewAria': 'Descripción general de la línea de tiempo; arrastre horizontalmente para enfocar eventos', + 'timeline.noTimingData': 'Sin datos de tiempo', + 'timeline.total': 'Total {duration}', + 'timeline.started': 'Iniciado {time}', + 'timeline.ttftDecoding': 'TTFT {ttft} · Decodificación {decoding}', + 'layout.compacting': 'Contexto de compactación…', + 'layout.compactionFailed': 'Falló la compactación', + 'layout.compacted': 'Contexto compactado', + 'layout.toolCallOnly': 'Sólo llamada de herramienta', + 'attachment.list': 'Adjuntos', + 'attachment.imageName': 'Imagen {index}', + 'layout.imageCount': 'Imágenes ×{count}', + 'layout.fileAttachments': 'Archivos ×{count}', + 'layout.initialSystemPrompt': 'Aviso inicial del sistema', + 'layout.systemPromptUpdated': 'Aviso del sistema actualizado', + 'layout.toolsUpdated': 'Herramientas actualizadas', + 'layout.toolAdded': 'Herramienta agregada: {name}', + 'layout.toolRemoved': 'Herramienta eliminada: {name}', + 'layout.toolUpdateNotice': 'Herramientas actualizadas', + 'layout.toolsAdded': 'Añadido: {names}', + 'layout.toolsAddedCount': '{count} añadido', + 'layout.toolsChanged': '{added} agregado, {removed} eliminado', + 'layout.toolsRemoved': 'Eliminado: {names}', + 'layout.toolsRemovedCount': '{count} eliminado', + 'layout.systemPromptAndToolsUpdated': 'Aviso del sistema y herramientas actualizadas', + 'layout.compactionInterrupted': 'La compactación se interrumpió antes de finalizar.', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'view.trajectory': 'Trajectory', + 'toolbar.aria': 'Barre d’outils du parcours', + 'toolbar.duration': 'Durée', + 'toolbar.useActualDuration': 'Utiliser la durée réelle', + 'toolbar.useEqualWidth': 'Utiliser des opérations de largeur égale', + 'toolbar.actualTime': 'Temps réel', + 'toolbar.turns': 'Tours', + 'toolbar.expandTurns': 'Développer les tours', + 'toolbar.collapseTurns': 'Réduire les tours', + 'toolbar.calls': 'Appels', + 'toolbar.expandCalls': 'Développer les appels', + 'toolbar.collapseCalls': 'Réduire les appels', + 'toolbar.search': 'Rechercher dans le parcours', + 'toolbar.searchPlaceholder': 'Rechercher', + 'kind.system': 'SYSTÈME', + 'kind.user': 'UTILISATEUR', + 'kind.context': 'CONTEXTE', + 'kind.compacted': 'COMPACTÉ', + 'kind.message': 'Message', + 'kind.assistant': 'ASSISTANT', + 'kind.tool': 'OUTIL', + 'kind.subtool': 'SOUS-OUTIL', + 'kind.sub': 'Sous', + 'column.input': 'Entrée', + 'column.output': 'Sortie', + 'column.think': 'Pensez', + 'column.time': 'Temps', + 'column.model': 'Modèle', + 'column.tools': 'Outils', + 'turn.label': 'Tour {turn}', + 'section.betweenTurns': 'Entre les tours', + 'group.message': 'Message', + 'group.step': 'Étape {step}', + 'group.compaction': 'Compactage {seq}', + 'status.failed': 'Échec', + 'status.pending': 'En attente', + 'status.completed': 'Terminé', + 'timing.notAvailable': 'Non disponible', + 'timing.notRecorded': 'Non enregistré', + 'timing.stepStartUnavailable': 'Démarrage par étapes indisponible', + 'timing.firstTokenUnavailable': 'Premier jeton indisponible', + 'timing.usageUnavailable': 'Utilisation indisponible', + 'timing.outputTokensUnavailable': 'Jetons de sortie indisponibles', + 'timing.durationTooShort': 'Durée trop courte', + 'timing.showLocalTime': "Afficher l'heure locale", + 'timing.showUnixTimestamp': "Afficher l'horodatage Unix", + 'timing.started': 'Commencé', + 'timing.totalDuration': 'Durée totale', + 'timing.ttft': 'TTFT', + 'timing.generation': 'Génération', + 'timing.throughput': 'Débit', + 'timing.duration': 'Durée', + 'timing.source': 'Source de synchronisation', + 'timing.sessionTimestamps': 'Horodatage des sessions', + 'timing.sessionTimestampsRunning': "Horodatages de session (en cours d'exécution)", + 'timing.request': 'Calendrier de la demande', + 'unit.milliseconds': '{value} ms', + 'unit.seconds': '{value}s', + 'unit.tokens': 'Jeton {value}', + 'unit.tokensPerSecond': '{value} jetons/s', + 'usage.tokens': 'Jetons', + 'usage.reasoning': 'Raisonnement', + 'usage.content': 'Contenu', + 'usage.notReported': 'Utilisation non signalée', + 'usage.input': 'Entrée', + 'usage.cached': 'En cache', + 'usage.cacheCreated': 'Cache créé', + 'usage.other': 'Autre', + 'usage.output': 'Sortie', + 'usage.thisRequest': 'Cette demande', + 'usage.sessionCumulative': 'Session cumulée', + 'options.notRecorded': 'Options non enregistrées', + 'options.json': 'Options de demande JSON', + 'source.unknown': 'Inconnu', + 'source.user': 'Utilisateur', + 'source.plugin': 'Plugin', + 'source.pluginNamed': 'Plugin · {plugin}', + 'source.goal': 'Objectif', + 'source.goalRound': 'Objectif · Tour {round}', + 'source.notRecorded': 'Source non enregistrée', + 'source.messageJson': 'Origine du message JSON', + 'tab.summary': 'Résumé', + 'tab.rawOutput': 'Sortie brute', + 'tab.preview': 'Aperçu', + 'tab.raw': 'Brut', + 'tab.source': 'Source', + 'tab.payload': 'Charge utile', + 'tab.result': 'Résultat', + 'tab.schema': 'Schéma', + 'tab.timing': 'Calendrier', + 'tab.diff': 'Différence', + 'tab.systemPrompt': 'Invite système', + 'tab.tools': 'Outils', + 'tab.options': 'Possibilités', + 'tab.usage': 'Utilisation', + 'record.toolCallOnly': "(appel d'outil uniquement)", + 'record.noContent': 'Aucun contenu', + 'record.noPayload': 'Aucune charge utile capturée', + 'record.noResult': 'Aucun résultat capturé', + 'record.noOutput': 'Aucune sortie', + 'record.schemaUnavailable': 'Schéma indisponible', + 'record.parameters': 'Paramètres', + 'record.resultJson': 'Résultat JSON', + 'record.json': 'JSON', + 'record.parametersJson': 'paramètres JSON', + 'record.namedParametersJson': 'Paramètres {name} JSON', + 'record.payloadJson': 'Charge utile JSON', + 'record.outputJson': 'Résultat JSON', + 'record.thinking': 'Penser', + 'record.wrapLines': 'Activer le retour à la ligne', + 'code.source': 'Coder', + 'code.output': 'Sortie', + 'code.copySource': 'Copier le code', + 'code.copyOutput': 'Copier la sortie', + 'code.originalJson': 'JSON d’origine', + 'code.running': 'Courir…', + 'record.systemPromptMissing': 'Aucune invite système dans cette requête', + 'record.toolsMissing': 'Aucun outil dans cette demande', + 'record.systemPrompt': 'Invite système', + 'record.tools': 'Outils', + 'block.openSummary': "Résumé de l'appel de l'outil Open Block #{index}", + 'block.openSummaryTitle': "Résumé de l'appel d'outil ouvert", + 'block.label': 'Bloc #{index} {type}', + 'history.loadingTrajectory': 'Chargement de la trajectoire…', + 'history.loadingEarlier': "Chargement de l'historique antérieur…", + 'history.loadingEarlierAria': "Chargement de l'historique antérieur…", + 'history.loadEarlier': "Charger l'historique antérieur", + 'history.clickToLoadEarlier': "Cliquez pour charger l'historique précédent", + 'request.label': 'Demande #{request}', + 'request.labelCompaction': 'Demande #{request} · Compactage', + 'request.compaction': 'Compactage · {section}', + 'request.compactionPurpose': 'Compactage', + 'request.retryProgress': '{retry} ou {maximum}', + 'request.collapsedSummary': 'Résumé {kind} réduit, {summary}', + 'request.collapsedTurn': 'tour', + 'request.collapsedAssistant': 'assistant', + 'request.rowAria': '{request}{kind}, {content}', + 'request.rowPrefix': 'Demande {request}, ', + 'request.rowAriaCompaction': 'Demande {request}, compactage', + 'request.noContent': 'pas de contenu', + 'summary.toolCalls.one': "Appel d'outil {count}", + 'summary.toolCalls.other': "Appels d'outil {count}", + 'summary.steps.one': 'Étape {count}', + 'summary.steps.other': 'Étapes {count}', + 'details.event': "Détails de l'événement", + 'details.resize': "Redimensionner les détails de l'événement", + 'details.resizeTitle': 'Faites glisser pour redimensionner. Double-cliquez pour réinitialiser.', + 'details.close': 'Fermer les détails', + 'details.status': 'Statut', + 'details.purpose': 'Objectif', + 'details.provider': 'Fournisseur', + 'details.model': 'Modèle', + 'details.toolCalls': "Appels d'outils", + 'details.subtoolCalls': 'Appels de sous-outils', + 'details.error': 'Erreur', + 'details.lastAttemptError': 'Erreur de dernière tentative', + 'details.failure.auth': "La clé API n'est pas valide", + 'details.retry': 'Réessayer', + 'details.retryDelay': 'Délai de nouvelle tentative', + 'details.result': 'Résultat', + 'details.compacted': 'Compacté', + 'details.assistantMessage': "Message de l'assistant", + 'details.source': 'Source', + 'details.hierarchy': 'Hiérarchie', + 'details.toolCall': "Appel d'outil", + 'timeline.aria': 'Chronologie de la trajectoire', + 'timeline.overviewAria': 'Aperçu de la chronologie ; faites glisser horizontalement pour concentrer les événements', + 'timeline.noTimingData': 'Aucune donnée de synchronisation', + 'timeline.total': 'Total {duration}', + 'timeline.started': 'Démarré {time}', + 'timeline.ttftDecoding': 'TTFT {ttft} · Décodage {decoding}', + 'layout.compacting': 'Contexte de compactage…', + 'layout.compactionFailed': 'Échec du compactage', + 'layout.compacted': 'Contexte compacté', + 'layout.toolCallOnly': "Appel d'outil uniquement", + 'attachment.list': 'Pièces jointes', + 'attachment.imageName': 'Image {index}', + 'layout.imageCount': 'Images ×{count}', + 'layout.fileAttachments': 'Fichiers ×{count}', + 'layout.initialSystemPrompt': 'Invite système initiale', + 'layout.systemPromptUpdated': 'Invite système mise à jour', + 'layout.toolsUpdated': 'Outils mis à jour', + 'layout.toolAdded': 'Outil ajouté : {name}', + 'layout.toolRemoved': 'Outil supprimé : {name}', + 'layout.toolUpdateNotice': 'Outils mis à jour', + 'layout.toolsAdded': 'Ajouté : {names}', + 'layout.toolsAddedCount': '{count} ajouté', + 'layout.toolsChanged': '{added} ajouté, {removed} supprimé', + 'layout.toolsRemoved': 'Supprimé : {names}', + 'layout.toolsRemovedCount': '{count} supprimé', + 'layout.systemPromptAndToolsUpdated': 'Invite système et outils mis à jour', + 'layout.compactionInterrupted': 'Le compactage a été interrompu avant la fin.', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'view.trajectory': 'Flugbahn', + 'toolbar.aria': 'Symbolleiste „Flugbahn“.', + 'toolbar.duration': 'Dauer', + 'toolbar.useActualDuration': 'Verwenden Sie die tatsächliche Dauer', + 'toolbar.useEqualWidth': 'Verwenden Sie Operationen gleicher Breite', + 'toolbar.actualTime': 'Tatsächliche Zeit', + 'toolbar.turns': 'Runden', + 'toolbar.expandTurns': 'Runden ausklappen', + 'toolbar.collapseTurns': 'Runden einklappen', + 'toolbar.calls': 'Aufrufe', + 'toolbar.expandCalls': 'Aufrufe erweitern', + 'toolbar.collapseCalls': 'Aufrufe reduzieren', + 'toolbar.search': 'Suchbahn', + 'toolbar.searchPlaceholder': 'Suchen', + 'kind.system': 'SYSTEM', + 'kind.user': 'BENUTZER', + 'kind.context': 'KONTEXT', + 'kind.compacted': 'KOMPRIMIERT', + 'kind.message': 'Nachricht', + 'kind.assistant': 'ASSISTENT', + 'kind.tool': 'WERKZEUG', + 'kind.subtool': 'UNTERWERKZEUG', + 'kind.sub': 'Sub', + 'column.input': 'Eingabe', + 'column.output': 'Ausgabe', + 'column.think': 'Denken Sie nach', + 'column.time': 'Zeit', + 'column.model': 'Modell', + 'column.tools': 'Werkzeuge', + 'turn.label': 'Runde {turn}', + 'section.betweenTurns': 'Zwischen den Runden', + 'group.message': 'Nachricht', + 'group.step': 'Schritt {step}', + 'group.compaction': 'Verdichtung {seq}', + 'status.failed': 'Fehlgeschlagen', + 'status.pending': 'Ausstehend', + 'status.completed': 'Abgeschlossen', + 'timing.notAvailable': 'Nicht verfügbar', + 'timing.notRecorded': 'Nicht aufgezeichnet', + 'timing.stepStartUnavailable': 'Schrittstart nicht verfügbar', + 'timing.firstTokenUnavailable': 'Erstes Token nicht verfügbar', + 'timing.usageUnavailable': 'Nutzung nicht verfügbar', + 'timing.outputTokensUnavailable': 'Ausgabetoken nicht verfügbar', + 'timing.durationTooShort': 'Dauer zu kurz', + 'timing.showLocalTime': 'Ortszeit anzeigen', + 'timing.showUnixTimestamp': 'Unix-Zeitstempel anzeigen', + 'timing.started': 'Begonnen', + 'timing.totalDuration': 'Gesamtdauer', + 'timing.ttft': 'TTFT', + 'timing.generation': 'Generation', + 'timing.throughput': 'Durchsatz', + 'timing.duration': 'Dauer', + 'timing.source': 'Timing-Quelle', + 'timing.sessionTimestamps': 'Sitzungszeitstempel', + 'timing.sessionTimestampsRunning': 'Sitzungszeitstempel (laufend)', + 'timing.request': 'Anfragezeitpunkt', + 'unit.milliseconds': '{value} ms', + 'unit.seconds': '{value} s', + 'unit.tokens': '{value}-Token', + 'unit.tokensPerSecond': '{value} tok/s', + 'usage.tokens': 'Token', + 'usage.reasoning': 'Begründung', + 'usage.content': 'Inhalt', + 'usage.notReported': 'Nutzung nicht gemeldet', + 'usage.input': 'Eingabe', + 'usage.cached': 'Zwischengespeichert', + 'usage.cacheCreated': 'Cache erstellt', + 'usage.other': 'Andere', + 'usage.output': 'Ausgabe', + 'usage.thisRequest': 'Diese Anfrage', + 'usage.sessionCumulative': 'Sitzung kumulativ', + 'options.notRecorded': 'Optionen nicht aufgezeichnet', + 'options.json': 'Anfrageoptionen JSON', + 'source.unknown': 'Unbekannt', + 'source.user': 'Benutzer', + 'source.plugin': 'Plugin', + 'source.pluginNamed': 'Plugin · {plugin}', + 'source.goal': 'Ziel', + 'source.goalRound': 'Ziel · Runde {round}', + 'source.notRecorded': 'Quelle nicht erfasst', + 'source.messageJson': 'Nachrichtenquelle JSON', + 'tab.summary': 'Zusammenfassung', + 'tab.rawOutput': 'Rohausgabe', + 'tab.preview': 'Vorschau', + 'tab.raw': 'Roh', + 'tab.source': 'Quelle', + 'tab.payload': 'Nutzlast', + 'tab.result': 'Ergebnis', + 'tab.schema': 'Schema', + 'tab.timing': 'Timing', + 'tab.diff': 'Diff', + 'tab.systemPrompt': 'Systemaufforderung', + 'tab.tools': 'Werkzeuge', + 'tab.options': 'Optionen', + 'tab.usage': 'Nutzung', + 'record.toolCallOnly': '(nur Werkzeugaufruf)', + 'record.noContent': 'Kein Inhalt', + 'record.noPayload': 'Keine Nutzlast erfasst', + 'record.noResult': 'Kein Ergebnis erfasst', + 'record.noOutput': 'Keine Ausgabe', + 'record.schemaUnavailable': 'Schema nicht verfügbar', + 'record.parameters': 'Parameter', + 'record.resultJson': 'Ergebnis JSON', + 'record.json': 'JSON', + 'record.parametersJson': 'Parameter JSON', + 'record.namedParametersJson': '{name} Parameter JSON', + 'record.payloadJson': 'Nutzlast JSON', + 'record.outputJson': 'Ergebnis JSON', + 'record.thinking': 'Denken', + 'record.wrapLines': 'Zeilen umbrechen', + 'code.source': 'Code', + 'code.output': 'Ausgabe', + 'code.copySource': 'Code kopieren', + 'code.copyOutput': 'Ausgabe kopieren', + 'code.originalJson': 'Original JSON', + 'code.running': 'Laufen…', + 'record.systemPromptMissing': 'In dieser Anfrage gibt es keine Systemaufforderung', + 'record.toolsMissing': 'In dieser Anfrage sind keine Werkzeuge enthalten', + 'record.systemPrompt': 'Systemaufforderung', + 'record.tools': 'Werkzeuge', + 'block.openSummary': 'Zusammenfassung des Toolaufrufs „Block #{index} öffnen“.', + 'block.openSummaryTitle': 'Zusammenfassung des Tool-Aufrufs öffnen', + 'block.label': 'Block #{index} {type}', + 'history.loadingTrajectory': 'Flugbahn wird geladen…', + 'history.loadingEarlier': 'Früherer Verlauf wird geladen…', + 'history.loadingEarlierAria': 'Früherer Verlauf wird geladen…', + 'history.loadEarlier': 'Früheren Verlauf laden', + 'history.clickToLoadEarlier': 'Klicken Sie hier, um den früheren Verlauf zu laden', + 'request.label': 'Fordern Sie #{request} an', + 'request.labelCompaction': 'Anfrage #{request} · Komprimierung', + 'request.compaction': 'Verdichtung · {section}', + 'request.compactionPurpose': 'Verdichtung', + 'request.retryProgress': '{retry} von {maximum}', + 'request.collapsedSummary': 'Reduzierte {kind}-Zusammenfassung, {summary}', + 'request.collapsedTurn': 'Runde', + 'request.collapsedAssistant': 'Assistent', + 'request.rowAria': '{request}{kind}, {content}', + 'request.rowPrefix': 'Anfrage {request}, ', + 'request.rowAriaCompaction': 'Anfrage {request}, Verdichtung', + 'request.noContent': 'kein Inhalt', + 'summary.toolCalls.one': 'Werkzeugaufruf {count}', + 'summary.toolCalls.other': '{count} Toolaufrufe', + 'summary.steps.one': '{count} Schritt', + 'summary.steps.other': '{count} Schritte', + 'details.event': 'Veranstaltungsdetails', + 'details.resize': 'Ändern Sie die Größe der Veranstaltungsdetails', + 'details.resizeTitle': 'Ziehen Sie, um die Größe zu ändern. Zum Zurücksetzen doppelklicken.', + 'details.close': 'Details schließen', + 'details.status': 'Status', + 'details.purpose': 'Zweck', + 'details.provider': 'Anbieter', + 'details.model': 'Modell', + 'details.toolCalls': 'Werkzeugaufrufe', + 'details.subtoolCalls': 'Subtool-Aufrufe', + 'details.error': 'Fehler', + 'details.lastAttemptError': 'Fehler beim letzten Versuch', + 'details.failure.auth': 'Der API-Schlüssel ist ungültig', + 'details.retry': 'Erneut versuchen', + 'details.retryDelay': 'Wiederholungsverzögerung', + 'details.result': 'Ergebnis', + 'details.compacted': 'Verdichtet', + 'details.assistantMessage': 'Assistentennachricht', + 'details.source': 'Quelle', + 'details.hierarchy': 'Hierarchie', + 'details.toolCall': 'Werkzeugaufruf', + 'timeline.aria': 'Zeitleiste der Flugbahn', + 'timeline.overviewAria': 'Zeitleistenübersicht; Ziehen Sie horizontal, um Ereignisse zu fokussieren', + 'timeline.noTimingData': 'Keine Zeitdaten', + 'timeline.total': 'Insgesamt {duration}', + 'timeline.started': '{time} gestartet', + 'timeline.ttftDecoding': 'TTFT {ttft} · Dekodierung {decoding}', + 'layout.compacting': 'Kontext verdichten…', + 'layout.compactionFailed': 'Die Komprimierung ist fehlgeschlagen', + 'layout.compacted': 'Kontext verdichtet', + 'layout.toolCallOnly': 'Nur Werkzeugaufruf', + 'attachment.list': 'Anhänge', + 'attachment.imageName': 'Bild {index}', + 'layout.imageCount': 'Bilder ×{count}', + 'layout.fileAttachments': 'Dateien ×{count}', + 'layout.initialSystemPrompt': 'Erste Systemaufforderung', + 'layout.systemPromptUpdated': 'Systemaufforderung aktualisiert', + 'layout.toolsUpdated': 'Werkzeuge aktualisiert', + 'layout.toolAdded': 'Tool hinzugefügt: {name}', + 'layout.toolRemoved': 'Entferntes Werkzeug: {name}', + 'layout.toolUpdateNotice': 'Werkzeuge aktualisiert', + 'layout.toolsAdded': 'Hinzugefügt: {names}', + 'layout.toolsAddedCount': '{count} hinzugefügt', + 'layout.toolsChanged': '{added} hinzugefügt, {removed} entfernt', + 'layout.toolsRemoved': 'Entfernt: {names}', + 'layout.toolsRemovedCount': '{count} entfernt', + 'layout.systemPromptAndToolsUpdated': 'Systemaufforderung und Tools aktualisiert', + 'layout.compactionInterrupted': 'Die Verdichtung wurde vor der Fertigstellung unterbrochen.', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'view.trajectory': 'Траектория', + 'toolbar.aria': 'Панель инструментов траектории', + 'toolbar.duration': 'Продолжительность', + 'toolbar.useActualDuration': 'Использовать фактическую продолжительность', + 'toolbar.useEqualWidth': 'Используйте операции равной ширины', + 'toolbar.actualTime': 'Фактическое время', + 'toolbar.turns': 'Ходы', + 'toolbar.expandTurns': 'Развернуть ходы', + 'toolbar.collapseTurns': 'Свернуть ходы', + 'toolbar.calls': 'Звонки', + 'toolbar.expandCalls': 'Развернуть вызовы', + 'toolbar.collapseCalls': 'Свернуть вызовы', + 'toolbar.search': 'Траектория поиска', + 'toolbar.searchPlaceholder': 'Поиск', + 'kind.system': 'СИСТЕМА', + 'kind.user': 'ПОЛЬЗОВАТЕЛЬ', + 'kind.context': 'КОНТЕКСТ', + 'kind.compacted': 'СЖАТО', + 'kind.message': 'Сообщение', + 'kind.assistant': 'АССИСТЕНТ', + 'kind.tool': 'ИНСТРУМЕНТ', + 'kind.subtool': 'ВЛОЖЕННЫЙ ИНСТРУМЕНТ', + 'kind.sub': 'Саб', + 'column.input': 'Ввод', + 'column.output': 'Выход', + 'column.think': 'Подумайте', + 'column.time': 'Время', + 'column.model': 'Модель', + 'column.tools': 'Инструменты', + 'turn.label': 'Ход {turn}', + 'section.betweenTurns': 'Между ходами', + 'group.message': 'Сообщение', + 'group.step': 'Шаг {step}', + 'group.compaction': 'Уплотнение {seq}', + 'status.failed': 'Не удалось', + 'status.pending': 'Ожидается', + 'status.completed': 'Завершено', + 'timing.notAvailable': 'Недоступно', + 'timing.notRecorded': 'Не записано', + 'timing.stepStartUnavailable': 'Начало шага недоступно', + 'timing.firstTokenUnavailable': 'Первый токен недоступен', + 'timing.usageUnavailable': 'Использование недоступно', + 'timing.outputTokensUnavailable': 'Выходные токены недоступны.', + 'timing.durationTooShort': 'Продолжительность слишком коротка', + 'timing.showLocalTime': 'Показать местное время', + 'timing.showUnixTimestamp': 'Показать временную метку Unix', + 'timing.started': 'Началось', + 'timing.totalDuration': 'Общая продолжительность', + 'timing.ttft': 'TTFT', + 'timing.generation': 'Поколение', + 'timing.throughput': 'Пропускная способность', + 'timing.duration': 'Продолжительность', + 'timing.source': 'Источник синхронизации', + 'timing.sessionTimestamps': 'Временные метки сеанса', + 'timing.sessionTimestampsRunning': 'Временные метки сеанса (работает)', + 'timing.request': 'Запрос времени', + 'unit.milliseconds': '{value} мс', + 'unit.seconds': '{value} с', + 'unit.tokens': '{value} ток', + 'unit.tokensPerSecond': '{value} ток/с', + 'usage.tokens': 'Токены', + 'usage.reasoning': 'Рассуждение', + 'usage.content': 'Содержание', + 'usage.notReported': 'Об использовании не сообщается', + 'usage.input': 'Ввод', + 'usage.cached': 'Кэшированный', + 'usage.cacheCreated': 'Кэш создан', + 'usage.other': 'Другое', + 'usage.output': 'Выход', + 'usage.thisRequest': 'Этот запрос', + 'usage.sessionCumulative': 'Совокупный сеанс', + 'options.notRecorded': 'Опции не записаны', + 'options.json': 'Варианты запроса JSON', + 'source.unknown': 'Неизвестно', + 'source.user': 'Пользователь', + 'source.plugin': 'Плагин', + 'source.pluginNamed': 'Плагин · {plugin}', + 'source.goal': 'Цель', + 'source.goalRound': 'Гол · Раунд {round}', + 'source.notRecorded': 'Источник не записан', + 'source.messageJson': 'Источник сообщения JSON', + 'tab.summary': 'Резюме', + 'tab.rawOutput': 'Необработанный вывод', + 'tab.preview': 'Предварительный просмотр', + 'tab.raw': 'сырой', + 'tab.source': 'Источник', + 'tab.payload': 'Полезная нагрузка', + 'tab.result': 'Результат', + 'tab.schema': 'Схема', + 'tab.timing': 'Тайминг', + 'tab.diff': 'Разница', + 'tab.systemPrompt': 'Системная подсказка', + 'tab.tools': 'Инструменты', + 'tab.options': 'Опции', + 'tab.usage': 'Использование', + 'record.toolCallOnly': '(только вызов инструмента)', + 'record.noContent': 'Нет контента', + 'record.noPayload': 'Полезная нагрузка не захвачена', + 'record.noResult': 'Результат не зафиксирован', + 'record.noOutput': 'Нет вывода', + 'record.schemaUnavailable': 'Схема недоступна', + 'record.parameters': 'Параметры', + 'record.resultJson': 'Результат JSON', + 'record.json': 'JSON', + 'record.parametersJson': 'параметры JSON', + 'record.namedParametersJson': '{name} параметры JSON', + 'record.payloadJson': 'Полезная нагрузка JSON', + 'record.outputJson': 'Результат JSON', + 'record.thinking': 'мышление', + 'record.wrapLines': 'Переносить строки', + 'code.source': 'Код', + 'code.output': 'Выход', + 'code.copySource': 'Скопировать код', + 'code.copyOutput': 'Копировать вывод', + 'code.originalJson': 'Исходный JSON', + 'code.running': 'Бег…', + 'record.systemPromptMissing': 'В этом запросе нет системного запроса', + 'record.toolsMissing': 'В этом запросе нет инструментов', + 'record.systemPrompt': 'Системная подсказка', + 'record.tools': 'Инструменты', + 'block.openSummary': 'Открыть сводку вызовов инструментов для блока №{index}', + 'block.openSummaryTitle': 'Открыть сводку вызовов инструментов', + 'block.label': 'Блок №{index} {type}', + 'history.loadingTrajectory': 'Загрузка траектории…', + 'history.loadingEarlier': 'Загрузка более ранней истории…', + 'history.loadingEarlierAria': 'Загрузка более ранней истории…', + 'history.loadEarlier': 'Загрузить предыдущую историю', + 'history.clickToLoadEarlier': 'Нажмите, чтобы загрузить предыдущую историю', + 'request.label': 'Запрос № {request}', + 'request.labelCompaction': 'Запрос №{request} · Сжатие', + 'request.compaction': 'Уплотнение · {section}', + 'request.compactionPurpose': 'Уплотнение', + 'request.retryProgress': '{retry} из {maximum}', + 'request.collapsedSummary': 'Свернутая сводка {kind}, {summary}', + 'request.collapsedTurn': 'ход', + 'request.collapsedAssistant': 'помощник', + 'request.rowAria': '{request}{kind}, {content}', + 'request.rowPrefix': 'Запрос {request}, ', + 'request.rowAriaCompaction': 'Запрос {request}, уплотнение', + 'request.noContent': 'нет содержания', + 'summary.toolCalls.one': '{count} вызов инструмента', + 'summary.toolCalls.other': '{count} вызовов инструментов', + 'summary.steps.one': '{count} шаг', + 'summary.steps.other': '{count} шагов', + 'details.event': 'Подробности мероприятия', + 'details.resize': 'Изменить размер сведений о мероприятии', + 'details.resizeTitle': 'Перетащите, чтобы изменить размер. Дважды щелкните для сброса.', + 'details.close': 'Закрыть детали', + 'details.status': 'Статус', + 'details.purpose': 'Цель', + 'details.provider': 'Поставщик', + 'details.model': 'Модель', + 'details.toolCalls': 'Вызовы инструментов', + 'details.subtoolCalls': 'Вызовы подинструментов', + 'details.error': 'Ошибка', + 'details.lastAttemptError': 'Ошибка последней попытки', + 'details.failure.auth': 'Ключ API недействителен.', + 'details.retry': 'Повторить', + 'details.retryDelay': 'Задержка повтора', + 'details.result': 'Результат', + 'details.compacted': 'Уплотненный', + 'details.assistantMessage': 'Сообщение помощника', + 'details.source': 'Источник', + 'details.hierarchy': 'Иерархия', + 'details.toolCall': 'Вызов инструмента', + 'timeline.aria': 'Хронология траектории', + 'timeline.overviewAria': 'Обзор временной шкалы; перетащите горизонтально, чтобы сфокусировать события', + 'timeline.noTimingData': 'Нет данных о времени', + 'timeline.total': 'Всего {duration}', + 'timeline.started': 'Запустил {time}', + 'timeline.ttftDecoding': 'TTFT {ttft} · Декодирование {decoding}', + 'layout.compacting': 'Сжатие контекста…', + 'layout.compactionFailed': 'Сжатие не удалось', + 'layout.compacted': 'Контекст сжат', + 'layout.toolCallOnly': 'Только вызов инструмента', + 'attachment.list': 'Вложения', + 'attachment.imageName': 'Изображение {index}', + 'layout.imageCount': 'Изображения ×{count}', + 'layout.fileAttachments': 'Файлы ×{count}', + 'layout.initialSystemPrompt': 'Начальная системная подсказка', + 'layout.systemPromptUpdated': 'Системная подсказка обновлена', + 'layout.toolsUpdated': 'Инструменты обновлены', + 'layout.toolAdded': 'Добавлен инструмент: {name}.', + 'layout.toolRemoved': 'Инструмент удален: {name}.', + 'layout.toolUpdateNotice': 'Инструменты обновлены', + 'layout.toolsAdded': 'Добавлено: {names}', + 'layout.toolsAddedCount': '{count} добавлен', + 'layout.toolsChanged': '{added} добавлен, {removed} удален.', + 'layout.toolsRemoved': 'Удалено: {names}.', + 'layout.toolsRemovedCount': '{count} удален.', + 'layout.systemPromptAndToolsUpdated': 'Системная подсказка и инструменты обновлены', + 'layout.compactionInterrupted': 'Уплотнение было прервано до завершения.', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'view.trajectory': 'Trajetória', + 'toolbar.aria': 'Barra de ferramentas Trajetória', + 'toolbar.duration': 'Duração', + 'toolbar.useActualDuration': 'Usar a duração real', + 'toolbar.useEqualWidth': 'Use operações de largura igual', + 'toolbar.actualTime': 'Hora real', + 'toolbar.turns': 'Turnos', + 'toolbar.expandTurns': 'Expandir turnos', + 'toolbar.collapseTurns': 'Recolher turnos', + 'toolbar.calls': 'Chamadas', + 'toolbar.expandCalls': 'Expandir chamadas', + 'toolbar.collapseCalls': 'Recolher chamadas', + 'toolbar.search': 'Trajetória de pesquisa', + 'toolbar.searchPlaceholder': 'Pesquisar', + 'kind.system': 'SISTEMA', + 'kind.user': 'USUÁRIO', + 'kind.context': 'CONTEXTO', + 'kind.compacted': 'COMPACTADO', + 'kind.message': 'Mensagem', + 'kind.assistant': 'ASSISTENTE', + 'kind.tool': 'FERRAMENTA', + 'kind.subtool': 'SUBFERRAMENTA', + 'kind.sub': 'Sub', + 'column.input': 'Entrada', + 'column.output': 'Saída', + 'column.think': 'Pense', + 'column.time': 'Hora', + 'column.model': 'Modelo', + 'column.tools': 'Ferramentas', + 'turn.label': 'Turno {turn}', + 'section.betweenTurns': 'Entre turnos', + 'group.message': 'Mensagem', + 'group.step': 'Etapa {step}', + 'group.compaction': 'Compactação {seq}', + 'status.failed': 'Falha', + 'status.pending': 'Pendente', + 'status.completed': 'Concluído', + 'timing.notAvailable': 'Não disponível', + 'timing.notRecorded': 'Não gravado', + 'timing.stepStartUnavailable': 'Início da etapa indisponível', + 'timing.firstTokenUnavailable': 'Primeiro token indisponível', + 'timing.usageUnavailable': 'Uso indisponível', + 'timing.outputTokensUnavailable': 'Tokens de saída indisponíveis', + 'timing.durationTooShort': 'Duração muito curta', + 'timing.showLocalTime': 'Mostrar hora local', + 'timing.showUnixTimestamp': 'Mostrar carimbo de data/hora Unix', + 'timing.started': 'Iniciado', + 'timing.totalDuration': 'Duração total', + 'timing.ttft': 'TTFT', + 'timing.generation': 'Geração', + 'timing.throughput': 'Taxa de transferência', + 'timing.duration': 'Duração', + 'timing.source': 'Fonte de tempo', + 'timing.sessionTimestamps': 'Carimbos de data e hora da sessão', + 'timing.sessionTimestampsRunning': 'Carimbos de data/hora da sessão (em execução)', + 'timing.request': 'Tempo de solicitação', + 'unit.milliseconds': '{value} ms', + 'unit.seconds': '{value} segundos', + 'unit.tokens': '{value} valor', + 'unit.tokensPerSecond': '{value} tok/s', + 'usage.tokens': 'Fichas', + 'usage.reasoning': 'Raciocínio', + 'usage.content': 'Conteúdo', + 'usage.notReported': 'Uso não relatado', + 'usage.input': 'Entrada', + 'usage.cached': 'Em cache', + 'usage.cacheCreated': 'Cache criado', + 'usage.other': 'Outro', + 'usage.output': 'Saída', + 'usage.thisRequest': 'Este pedido', + 'usage.sessionCumulative': 'Sessão cumulativa', + 'options.notRecorded': 'Opções não registradas', + 'options.json': 'Opções de solicitação JSON', + 'source.unknown': 'Desconhecido', + 'source.user': 'Usuário', + 'source.plugin': 'Plug-in', + 'source.pluginNamed': 'Plug-in · {plugin}', + 'source.goal': 'Objetivo', + 'source.goalRound': 'Meta · Rodada {round}', + 'source.notRecorded': 'Fonte não registrada', + 'source.messageJson': 'Fonte da mensagem JSON', + 'tab.summary': 'Resumo', + 'tab.rawOutput': 'Saída Bruta', + 'tab.preview': 'Visualização', + 'tab.raw': 'Cru', + 'tab.source': 'Fonte', + 'tab.payload': 'Carga útil', + 'tab.result': 'Resultado', + 'tab.schema': 'Esquema', + 'tab.timing': 'Tempo', + 'tab.diff': 'Diferença', + 'tab.systemPrompt': 'Alerta do sistema', + 'tab.tools': 'Ferramentas', + 'tab.options': 'Opções', + 'tab.usage': 'Uso', + 'record.toolCallOnly': '(somente chamada de ferramenta)', + 'record.noContent': 'Sem conteúdo', + 'record.noPayload': 'Nenhuma carga capturada', + 'record.noResult': 'Nenhum resultado capturado', + 'record.noOutput': 'Sem saída', + 'record.schemaUnavailable': 'Esquema indisponível', + 'record.parameters': 'Parâmetros', + 'record.resultJson': 'Resultado JSON', + 'record.json': 'JSON', + 'record.parametersJson': 'parâmetros JSON', + 'record.namedParametersJson': '{name} parâmetros JSON', + 'record.payloadJson': 'Carga útil JSON', + 'record.outputJson': 'Resultado JSON', + 'record.thinking': 'Pensando', + 'record.wrapLines': 'Quebrar linhas', + 'code.source': 'Código', + 'code.output': 'Saída', + 'code.copySource': 'Copiar código', + 'code.copyOutput': 'Copiar saída', + 'code.originalJson': 'JSON original', + 'code.running': 'Correndo…', + 'record.systemPromptMissing': 'Nenhum prompt do sistema nesta solicitação', + 'record.toolsMissing': 'Nenhuma ferramenta nesta solicitação', + 'record.systemPrompt': 'Alerta do sistema', + 'record.tools': 'Ferramentas', + 'block.openSummary': 'Resumo da chamada da ferramenta do bloco aberto #{index}', + 'block.openSummaryTitle': 'Resumo de chamada de ferramenta aberta', + 'block.label': 'Bloco nº{index} {type}', + 'history.loadingTrajectory': 'Carregando trajetória…', + 'history.loadingEarlier': 'Carregando histórico anterior…', + 'history.loadingEarlierAria': 'Carregando histórico anterior…', + 'history.loadEarlier': 'Carregar histórico anterior', + 'history.clickToLoadEarlier': 'Clique para carregar o histórico anterior', + 'request.label': 'Solicitação nº{request}', + 'request.labelCompaction': 'Solicitação nº{request} · Compactação', + 'request.compaction': 'Compactação · {section}', + 'request.compactionPurpose': 'Compactação', + 'request.retryProgress': '{retry} de {maximum}', + 'request.collapsedSummary': 'Resumo {kind} recolhido, {summary}', + 'request.collapsedTurn': 'turno', + 'request.collapsedAssistant': 'assistente', + 'request.rowAria': '{request}{kind}, {content}', + 'request.rowPrefix': 'Solicitação {request}, ', + 'request.rowAriaCompaction': 'Solicitação {request}, compactação', + 'request.noContent': 'sem conteúdo', + 'summary.toolCalls.one': '{count} chamada de ferramenta', + 'summary.toolCalls.other': '{count} chamadas de ferramenta', + 'summary.steps.one': '{count} etapa', + 'summary.steps.other': '{count} etapas', + 'details.event': 'Detalhes do evento', + 'details.resize': 'Redimensionar detalhes do evento', + 'details.resizeTitle': 'Arraste para redimensionar. Clique duas vezes para redefinir.', + 'details.close': 'Fechar detalhes', + 'details.status': 'Estado', + 'details.purpose': 'Objetivo', + 'details.provider': 'Provedor', + 'details.model': 'Modelo', + 'details.toolCalls': 'Chamadas de ferramentas', + 'details.subtoolCalls': 'Chamadas de subferramenta', + 'details.error': 'Erro', + 'details.lastAttemptError': 'Erro na última tentativa', + 'details.failure.auth': 'A chave API é inválida', + 'details.retry': 'Tentar novamente', + 'details.retryDelay': 'Atraso na nova tentativa', + 'details.result': 'Resultado', + 'details.compacted': 'Compactado', + 'details.assistantMessage': 'Mensagem do assistente', + 'details.source': 'Fonte', + 'details.hierarchy': 'Hierarquia', + 'details.toolCall': 'Chamada de ferramenta', + 'timeline.aria': 'Linha do tempo da trajetória', + 'timeline.overviewAria': 'Visão geral da linha do tempo; arraste horizontalmente para focar eventos', + 'timeline.noTimingData': 'Sem dados de tempo', + 'timeline.total': 'Total {duration}', + 'timeline.started': 'Iniciado {time}', + 'timeline.ttftDecoding': 'TTFT {ttft} · Decodificação {decoding}', + 'layout.compacting': 'Contexto compactado…', + 'layout.compactionFailed': 'Falha na compactação', + 'layout.compacted': 'Contexto compactado', + 'layout.toolCallOnly': 'Somente chamada de ferramenta', + 'attachment.list': 'Anexos', + 'attachment.imageName': 'Imagem {index}', + 'layout.imageCount': 'Imagens ×{count}', + 'layout.fileAttachments': 'Arquivos ×{count}', + 'layout.initialSystemPrompt': 'Prompt inicial do sistema', + 'layout.systemPromptUpdated': 'Prompt do sistema atualizado', + 'layout.toolsUpdated': 'Ferramentas atualizadas', + 'layout.toolAdded': 'Ferramenta adicionada: {name}', + 'layout.toolRemoved': 'Ferramenta removida: {name}', + 'layout.toolUpdateNotice': 'Ferramentas atualizadas', + 'layout.toolsAdded': 'Adicionado: {names}', + 'layout.toolsAddedCount': '{count} adicionado', + 'layout.toolsChanged': '{added} adicionado, {removed} removido', + 'layout.toolsRemoved': 'Removido: {names}', + 'layout.toolsRemovedCount': '{count} removido', + 'layout.systemPromptAndToolsUpdated': 'Prompt do sistema e ferramentas atualizadas', + 'layout.compactionInterrupted': 'A compactação foi interrompida antes da conclusão.', +} satisfies Record diff --git a/packages/client/ui-user-questions/locale/de.json b/packages/client/ui-user-questions/locale/de.json new file mode 100644 index 0000000000..363d951575 --- /dev/null +++ b/packages/client/ui-user-questions/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Benutzeroberfläche für Fragen und Antworten", + "description": "Präsentieren Sie die Fragen der KI, planen Sie Bewertungsanfragen in einem Gespräch und sammeln Sie Benutzerantworten." + } +} diff --git a/packages/client/ui-user-questions/locale/es.json b/packages/client/ui-user-questions/locale/es.json new file mode 100644 index 0000000000..d6574488e9 --- /dev/null +++ b/packages/client/ui-user-questions/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de preguntas y respuestas del usuario", + "description": "Presente las preguntas de la IA, programe solicitudes de revisión en una conversación y recopile las respuestas de los usuarios." + } +} diff --git a/packages/client/ui-user-questions/locale/fr.json b/packages/client/ui-user-questions/locale/fr.json new file mode 100644 index 0000000000..b8fcde16e9 --- /dev/null +++ b/packages/client/ui-user-questions/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de questions et réponses utilisateur", + "description": "Présentez les questions de l'IA et planifiez les demandes de révision dans une conversation, et collectez les réponses des utilisateurs." + } +} diff --git a/packages/client/ui-user-questions/locale/pt.json b/packages/client/ui-user-questions/locale/pt.json new file mode 100644 index 0000000000..0e14cc5897 --- /dev/null +++ b/packages/client/ui-user-questions/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de perguntas e respostas do usuário", + "description": "Apresente as perguntas da IA, agende solicitações de revisão em uma conversa e colete as respostas dos usuários." + } +} diff --git a/packages/client/ui-user-questions/locale/ru.json b/packages/client/ui-user-questions/locale/ru.json new file mode 100644 index 0000000000..dcaf1ef773 --- /dev/null +++ b/packages/client/ui-user-questions/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Пользовательский интерфейс вопросов и ответов", + "description": "Задавайте вопросы ИИ и планируйте запросы на проверку в беседе, а также собирайте ответы пользователей." + } +} diff --git a/packages/client/ui-user-questions/src/client/index.ts b/packages/client/ui-user-questions/src/client/index.ts index 618cb599af..0f8255d6f9 100644 --- a/packages/client/ui-user-questions/src/client/index.ts +++ b/packages/client/ui-user-questions/src/client/index.ts @@ -30,7 +30,7 @@ import { createQuestionDraftStore } from './draft-store.ts' import { QuestionComposer } from './QuestionComposer.tsx' import { answeredQuestionDefinition, questionReplyDefinition } from './question-reply.ts' import { QuestionReplyView } from './QuestionReplyView.tsx' -import { en, ja, zh, type QuestionKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh, type QuestionKey } from './locales.ts' export type { PendingQuestion, PlanReview, QuestionAnswer, QuestionComposerProps, QuestionWait, @@ -366,7 +366,7 @@ function publishContinuedQuestions(ctx: ClientContext, cards: QuestionCards): () * @param ctx - client root context. */ export function apply(ctx: ClientContext): void { - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-user-questions: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-user-questions: dictionaries') const questionDraftStore = createQuestionDraftStore() const registerPendingInteraction = ctx.uiSession.registerPendingInteraction( pending => pending.kind === 'plan-review' ? 2 : 1, diff --git a/packages/client/ui-user-questions/src/client/locales.ts b/packages/client/ui-user-questions/src/client/locales.ts index 719e4ecd0b..4a968bbf51 100644 --- a/packages/client/ui-user-questions/src/client/locales.ts +++ b/packages/client/ui-user-questions/src/client/locales.ts @@ -107,3 +107,178 @@ export const ja = { 'plan.decline': '拒否', 'plan.discuss': '変更を依頼', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'error.incomplete': 'Por favor complete esta pregunta primero.', + 'error.unanswered': 'Seleccione una opción o ingrese una respuesta personalizada.', + 'error.unavailable': 'No se puede enviar en este momento; Inténtalo de nuevo en un momento.', + 'error.resubmit': 'La respuesta no llegó antes de que continuara el trabajo; enviarlo de nuevo.', + 'status.sent': 'Respuesta enviada; el panel no pudo cerrarse.', + 'wait.takeTime': 'tómate el tiempo', + 'wait.countdown': 'Continuando en {seconds}s', + 'wait.paused': 'En pausa · {seconds} restantes', + 'wait.held': 'Esperando hasta que respondas', + 'wait.continued': 'El trabajo continúa; aún puedes responder', + 'review.status': 'Respondido', + 'review.skipped': 'Esta pregunta fue omitida.', + 'reply.label': 'Preguntas y respuestas', + 'reply.answerLabel': 'Respuesta: ', + 'reply.skipped': 'Saltado', + 'nav.prev': 'Pregunta anterior', + 'nav.next': 'Siguiente pregunta', + 'nav.minimize': 'Contraer la tarjeta de preguntas', + 'nav.maximize': 'Ampliar la tarjeta de preguntas', + 'nav.cancel': 'Descartar todas las preguntas', + 'nav.close': 'Cierre el panel; vuelva a abrirlo desde la llamada de la herramienta', + 'text.expand': 'Expandir', + 'text.collapse': 'Contraer', + 'option.recommended': 'Recomendado', + 'custom.placeholder': 'Escribe tu respuesta', + 'action.skip': 'Saltar', + 'action.next': 'Siguiente', + 'plan.header': 'Revisión del plan', + 'plan.approve': 'Aprobar', + 'plan.decline': 'Rechazar', + 'plan.discuss': 'Solicitar cambios', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'error.incomplete': "Veuillez d'abord répondre à cette question.", + 'error.unanswered': 'Veuillez sélectionner une option ou saisir une réponse personnalisée.', + 'error.unavailable': 'Impossible de soumettre pour le moment ; réessayez dans un instant.', + 'error.resubmit': 'La réponse n’est pas arrivée avant la poursuite des travaux ; soumettez-le à nouveau.', + 'status.sent': "Réponse envoyée ; le panneau n'a pas pu se fermer.", + 'wait.takeTime': 'Prends le temps', + 'wait.countdown': 'Poursuite dans {seconds} s', + 'wait.paused': 'En pause · {seconds} restants', + 'wait.held': 'En attente de votre réponse', + 'wait.continued': "Le travail s'est poursuivi — vous pouvez toujours répondre", + 'review.status': 'Répondu', + 'review.skipped': 'Cette question a été ignorée.', + 'reply.label': 'Questions et réponses', + 'reply.answerLabel': 'Réponse : ', + 'reply.skipped': 'Skipped', + 'nav.prev': 'Question précédente', + 'nav.next': 'Question suivante', + 'nav.minimize': 'Réduire la fiche de questions', + 'nav.maximize': 'Développer la carte de question', + 'nav.cancel': 'Ignorer toutes les questions', + 'nav.close': "Fermez le panneau - rouvrez-le à partir de l'appel de l'outil", + 'text.expand': 'Développer', + 'text.collapse': 'Réduire', + 'option.recommended': 'Recommandé', + 'custom.placeholder': 'Saisissez votre réponse', + 'action.skip': 'Sauter', + 'action.next': 'Suivant', + 'plan.header': 'Révision des plans', + 'plan.approve': 'Approuver', + 'plan.decline': 'Refuser', + 'plan.discuss': 'Demander des modifications', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'error.incomplete': 'Bitte füllen Sie zunächst diese Frage aus.', + 'error.unanswered': 'Bitte wählen Sie eine Option aus oder geben Sie eine benutzerdefinierte Antwort ein.', + 'error.unavailable': 'Kann momentan nicht eingereicht werden; Versuchen Sie es gleich noch einmal.', + 'error.resubmit': 'Die Antwort kam erst, als die Arbeiten weitergingen; reichen Sie es erneut ein.', + 'status.sent': 'Antwort gesendet; Das Panel konnte nicht geschlossen werden.', + 'wait.takeTime': 'Nehmen Sie sich Zeit', + 'wait.countdown': 'Fortsetzung in {seconds}s', + 'wait.paused': 'Angehalten · Verbleibende {seconds}s', + 'wait.held': 'Ich warte, bis du antwortest', + 'wait.continued': 'Die Arbeit ging weiter – Sie können immer noch antworten', + 'review.status': 'Beantwortet', + 'review.skipped': 'Diese Frage wurde übersprungen.', + 'reply.label': 'Fragen und Antworten', + 'reply.answerLabel': 'Antwort: ', + 'reply.skipped': 'Übersprungen', + 'nav.prev': 'Vorherige Frage', + 'nav.next': 'Nächste Frage', + 'nav.minimize': 'Reduzieren Sie die Fragenkarte', + 'nav.maximize': 'Erweitern Sie die Fragenkarte', + 'nav.cancel': 'Alle Fragen ablehnen', + 'nav.close': 'Schließen Sie das Panel – öffnen Sie es erneut über den Tool-Aufruf', + 'text.expand': 'Ausklappen', + 'text.collapse': 'Einklappen', + 'option.recommended': 'Empfohlen', + 'custom.placeholder': 'Geben Sie Ihre Antwort ein', + 'action.skip': 'Überspringen', + 'action.next': 'Weiter', + 'plan.header': 'Planüberprüfung', + 'plan.approve': 'Genehmigen', + 'plan.decline': 'Ablehnen', + 'plan.discuss': 'Fordern Sie Änderungen an', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'error.incomplete': 'Пожалуйста, сначала ответьте на этот вопрос.', + 'error.unanswered': 'Пожалуйста, выберите вариант или введите собственный ответ.', + 'error.unavailable': 'Невозможно отправить прямо сейчас; попробуйте еще раз через минуту.', + 'error.resubmit': 'Ответ не пришел до продолжения работы; отправьте его еще раз.', + 'status.sent': 'Ответ отправлен; панель не могла закрыться.', + 'wait.takeTime': 'Найдите время', + 'wait.countdown': 'Продолжение в {seconds}s', + 'wait.paused': 'Приостановлено · Осталось {seconds}', + 'wait.held': 'Жду, пока ты ответишь', + 'wait.continued': 'Работа продолжается — вы еще можете ответить', + 'review.status': 'Ответил', + 'review.skipped': 'Этот вопрос был пропущен.', + 'reply.label': 'Вопросы и ответы', + 'reply.answerLabel': 'Ответ: ', + 'reply.skipped': 'Пропущено', + 'nav.prev': 'Предыдущий вопрос', + 'nav.next': 'Следующий вопрос', + 'nav.minimize': 'Свернуть карточку с вопросом', + 'nav.maximize': 'Развернуть карточку с вопросом', + 'nav.cancel': 'Отклонить все вопросы', + 'nav.close': 'Закрыть панель — открыть ее снова из вызова инструмента', + 'text.expand': 'Развернуть', + 'text.collapse': 'Свернуть', + 'option.recommended': 'Рекомендуется', + 'custom.placeholder': 'Введите ответ', + 'action.skip': 'Пропустить', + 'action.next': 'Далее', + 'plan.header': 'Обзор плана', + 'plan.approve': 'Утвердить', + 'plan.decline': 'Отказаться', + 'plan.discuss': 'Запросить изменения', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'error.incomplete': 'Por favor, responda esta pergunta primeiro.', + 'error.unanswered': 'Selecione uma opção ou insira uma resposta personalizada.', + 'error.unavailable': 'Não é possível enviar agora; tente novamente em um momento.', + 'error.resubmit': 'A resposta não chegou antes da continuação do trabalho; envie-o novamente.', + 'status.sent': 'Resposta enviada; o painel não pôde fechar.', + 'wait.takeTime': 'Reserve um tempo', + 'wait.countdown': 'Continuando em {seconds}s', + 'wait.paused': 'Pausado · {seconds}s restantes', + 'wait.held': 'Esperando até você responder', + 'wait.continued': 'O trabalho continuou – você ainda pode responder', + 'review.status': 'Respondido', + 'review.skipped': 'Esta questão foi ignorada.', + 'reply.label': 'Perguntas e respostas', + 'reply.answerLabel': 'Resposta: ', + 'reply.skipped': 'Ignorado', + 'nav.prev': 'Pergunta anterior', + 'nav.next': 'Próxima pergunta', + 'nav.minimize': 'Recolher o cartão de perguntas', + 'nav.maximize': 'Expanda o cartão de perguntas', + 'nav.cancel': 'Dispense todas as perguntas', + 'nav.close': 'Feche o painel – reabra-o na chamada da ferramenta', + 'text.expand': 'Expandir', + 'text.collapse': 'Recolher', + 'option.recommended': 'Recomendado', + 'custom.placeholder': 'Digite sua resposta', + 'action.skip': 'Pular', + 'action.next': 'Próximo', + 'plan.header': 'Revisão do plano', + 'plan.approve': 'Aprovar', + 'plan.decline': 'Recusar', + 'plan.discuss': 'Solicitar alterações', +} satisfies Record diff --git a/packages/client/ui-workflow-run/locale/de.json b/packages/client/ui-workflow-run/locale/de.json new file mode 100644 index 0000000000..7023c7a420 --- /dev/null +++ b/packages/client/ui-workflow-run/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Anzeige der Workflow-Ausführung", + "description": "Zeigen Sie Workflow-Ausführungsdatensätze und ihre Mitgliedsdetails in der Sitzung an." + } +} diff --git a/packages/client/ui-workflow-run/locale/es.json b/packages/client/ui-workflow-run/locale/es.json new file mode 100644 index 0000000000..866a8b82a1 --- /dev/null +++ b/packages/client/ui-workflow-run/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Visualización de ejecución del flujo de trabajo", + "description": "Muestre registros de ejecución de flujo de trabajo y los detalles de sus miembros en la sesión." + } +} diff --git a/packages/client/ui-workflow-run/locale/fr.json b/packages/client/ui-workflow-run/locale/fr.json new file mode 100644 index 0000000000..34d095b8bf --- /dev/null +++ b/packages/client/ui-workflow-run/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Affichage de l'exécution du workflow", + "description": "Affichez les enregistrements d'exécution de flux de travail et les détails de leurs membres dans la session." + } +} diff --git a/packages/client/ui-workflow-run/locale/pt.json b/packages/client/ui-workflow-run/locale/pt.json new file mode 100644 index 0000000000..403aca3a74 --- /dev/null +++ b/packages/client/ui-workflow-run/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Exibição de execução de fluxo de trabalho", + "description": "Exiba registros de execução de fluxo de trabalho e detalhes de seus membros na sessão." + } +} diff --git a/packages/client/ui-workflow-run/locale/ru.json b/packages/client/ui-workflow-run/locale/ru.json new file mode 100644 index 0000000000..dd7ede4381 --- /dev/null +++ b/packages/client/ui-workflow-run/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Отображение выполнения рабочего процесса", + "description": "Отображение записей выполнения рабочего процесса и сведений об их участниках в сеансе." + } +} diff --git a/packages/client/ui-workflow-run/src/client/index.ts b/packages/client/ui-workflow-run/src/client/index.ts index b3da13c944..648dbd1f46 100644 --- a/packages/client/ui-workflow-run/src/client/index.ts +++ b/packages/client/ui-workflow-run/src/client/index.ts @@ -9,7 +9,7 @@ import type {} from '@deepseek-ai/dsh-client-ui-renderer/client' import type {} from '@deepseek-ai/dsh-client-ui-session/client' import type {} from '@deepseek-ai/dsh-client-ui-workspace/client' import { WorkflowRunPanel, type WorkflowRunInjected } from './WorkflowRunPanel.tsx' -import { en, ja, NS, type WorkflowRunKey, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, NS, type WorkflowRunKey, zh } from './locales.ts' import { workflowRunDefinition } from './workflow-definition.ts' declare module '@deepseek-ai/dsh-client-ui-slots' { @@ -25,7 +25,7 @@ export const inject = ['uiConversation', 'uiWorkspace', 'slots', 'sessions', 'lo /** Register the workflow Definition, dictionary, and keyed Chat renderer. */ export function apply(ctx: ClientContext): void { ctx.uiConversation.events.register(workflowRunDefinition) - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-workflow-run: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-workflow-run: dictionaries') ctx.slots.inject('conversation.chat.node', () => ctx.slots.register({ name: 'conversation.chat.node', key: 'workflow-run', diff --git a/packages/client/ui-workflow-run/src/client/locales.ts b/packages/client/ui-workflow-run/src/client/locales.ts index 8243740ca8..ad0224ecc7 100644 --- a/packages/client/ui-workflow-run/src/client/locales.ts +++ b/packages/client/ui-workflow-run/src/client/locales.ts @@ -71,3 +71,113 @@ export const ja = { 'status.cancelled': 'キャンセル', 'status.interrupted': '中断', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'run.title': '{name}', + 'run.members.one': 'Miembro de {count}', + 'run.members.other': 'Miembros de {count}', + 'run.empty': 'Ningún miembro comenzó', + 'phase.unassigned': 'sin fases', + 'phase.empty': 'Nombre de fase vacío', + 'statusCount.running': 'Ejecutando {count}', + 'statusCount.completed': 'Completado {count}', + 'statusCount.failed': 'Error {count}', + 'statusCount.cancelled': 'Cancelado {count}', + 'statusCount.interrupted': 'Interrumpido {count}', + 'member.empty': 'Nombre de miembro vacío', + 'member.open': 'Abrir {name}', + 'status.running': 'corriendo', + 'status.completed': 'Completado', + 'status.failed': 'Fallido', + 'status.cancelled': 'Cancelado', + 'status.interrupted': 'interrumpido', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'run.title': '{name}', + 'run.members.one': 'Membre {count}', + 'run.members.other': 'Membres {count}', + 'run.empty': "Aucun membre n'a commencé", + 'phase.unassigned': 'Sans phase', + 'phase.empty': 'Nom de phase vide', + 'statusCount.running': 'Exécution de {count}', + 'statusCount.completed': 'Terminé {count}', + 'statusCount.failed': 'Échec du {count}', + 'statusCount.cancelled': 'Annulé {count}', + 'statusCount.interrupted': '{count} interrompu', + 'member.empty': 'Nom du membre vide', + 'member.open': 'Ouvrir {name}', + 'status.running': 'Courir', + 'status.completed': 'Terminé', + 'status.failed': 'Échec', + 'status.cancelled': 'Annulé', + 'status.interrupted': 'Interrompu', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'run.title': '{name}', + 'run.members.one': '{count}-Mitglied', + 'run.members.other': '{count}-Mitglieder', + 'run.empty': 'Keine Mitglieder gestartet', + 'phase.unassigned': 'Unphasiert', + 'phase.empty': 'Leerer Phasenname', + 'statusCount.running': 'Ausführen von {count}', + 'statusCount.completed': '{count} abgeschlossen', + 'statusCount.failed': 'Fehlgeschlagen {count}', + 'statusCount.cancelled': 'Storniert {count}', + 'statusCount.interrupted': 'Unterbrochen {count}', + 'member.empty': 'Leerer Mitgliedsname', + 'member.open': 'Öffnen Sie {name}', + 'status.running': 'Laufen', + 'status.completed': 'Abgeschlossen', + 'status.failed': 'Fehlgeschlagen', + 'status.cancelled': 'Abgesagt', + 'status.interrupted': 'Unterbrochen', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'run.title': '{name}', + 'run.members.one': 'Участник {count}', + 'run.members.other': 'Участники {count}', + 'run.empty': 'Ни один из участников не стартовал', + 'phase.unassigned': 'Нефазированный', + 'phase.empty': 'Пустое имя фазы', + 'statusCount.running': 'Запуск {count}', + 'statusCount.completed': 'Завершено {count}', + 'statusCount.failed': 'Ошибка {count}', + 'statusCount.cancelled': 'Отменено {count}', + 'statusCount.interrupted': 'Прервано {count}', + 'member.empty': 'Пустое имя участника', + 'member.open': 'Открыть {name}', + 'status.running': 'Бег', + 'status.completed': 'Завершено', + 'status.failed': 'Не удалось', + 'status.cancelled': 'Отменено', + 'status.interrupted': 'Прерванный', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'run.title': '{name}', + 'run.members.one': '{count} membro', + 'run.members.other': '{count} membros', + 'run.empty': 'Nenhum membro começou', + 'phase.unassigned': 'Sem fases', + 'phase.empty': 'Nome da fase vazia', + 'statusCount.running': 'Executando {count}', + 'statusCount.completed': 'Concluído {count}', + 'statusCount.failed': 'Falha {count}', + 'statusCount.cancelled': 'Cancelado {count}', + 'statusCount.interrupted': 'Interrompido {count}', + 'member.empty': 'Nome de membro vazio', + 'member.open': 'Abra {name}', + 'status.running': 'Correndo', + 'status.completed': 'Concluído', + 'status.failed': 'Falha', + 'status.cancelled': 'Cancelado', + 'status.interrupted': 'Interrompido', +} satisfies Record diff --git a/packages/client/ui-workspace/locale/de.json b/packages/client/ui-workspace/locale/de.json new file mode 100644 index 0000000000..0d85597bbb --- /dev/null +++ b/packages/client/ui-workspace/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Schnittstelle zur Arbeitsbereichsauswahl", + "description": "Wählen Sie den Arbeitsbereich in der Seitenleiste und auf der Seite „Neue Sitzung“ aus." + } +} diff --git a/packages/client/ui-workspace/locale/es.json b/packages/client/ui-workspace/locale/es.json new file mode 100644 index 0000000000..761307af3f --- /dev/null +++ b/packages/client/ui-workspace/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de selección de espacio de trabajo", + "description": "Seleccione el espacio de trabajo en la barra lateral y en la página de nueva sesión." + } +} diff --git a/packages/client/ui-workspace/locale/fr.json b/packages/client/ui-workspace/locale/fr.json new file mode 100644 index 0000000000..7de0b3ed4f --- /dev/null +++ b/packages/client/ui-workspace/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de sélection d'espace de travail", + "description": "Sélectionnez l'espace de travail dans la barre latérale et la page de nouvelle session." + } +} diff --git a/packages/client/ui-workspace/locale/pt.json b/packages/client/ui-workspace/locale/pt.json new file mode 100644 index 0000000000..5fbce0a63a --- /dev/null +++ b/packages/client/ui-workspace/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de seleção de espaço de trabalho", + "description": "Selecione o espaço de trabalho na barra lateral e na página da nova sessão." + } +} diff --git a/packages/client/ui-workspace/locale/ru.json b/packages/client/ui-workspace/locale/ru.json new file mode 100644 index 0000000000..bfca23e851 --- /dev/null +++ b/packages/client/ui-workspace/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Интерфейс выбора рабочего пространства", + "description": "Выберите рабочую область на боковой панели и страницу нового сеанса." + } +} diff --git a/packages/client/ui-workspace/src/client/index.ts b/packages/client/ui-workspace/src/client/index.ts index 94199e9111..56985d0872 100644 --- a/packages/client/ui-workspace/src/client/index.ts +++ b/packages/client/ui-workspace/src/client/index.ts @@ -56,7 +56,7 @@ import { RowActionToast } from './session-actions/RowActionToast.tsx' import { registerToasts } from './toast/register.ts' import { SessionIdMenuItem } from './session-actions/SessionId.tsx' import { WorkspacePicker } from './WorkspacePicker.tsx' -import { en, ja, zh, type WorkspaceKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, zh, type WorkspaceKey } from './locales.ts' export type { StartSessionOptions, UiWorkspace } from './navigation.ts' export type { @@ -132,7 +132,7 @@ export function apply(ctx: Context): void { : ctx.remoteAccess.source('workspace', workspaceId, action), }, }) - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-workspace: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-workspace: dictionaries') const shortcutControls = createWorkspaceShortcutControls() const searchSessions: WorkspaceBrowserInjected['searchSessions'] = async (query, signal) => { diff --git a/packages/client/ui-workspace/src/client/locales.ts b/packages/client/ui-workspace/src/client/locales.ts index 938b893b40..305cd7eac2 100644 --- a/packages/client/ui-workspace/src/client/locales.ts +++ b/packages/client/ui-workspace/src/client/locales.ts @@ -375,3 +375,618 @@ export const ja = { 'time.years': '{n}年', 'time.ago': '{t}前', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'defaultWorkspace.failed': 'No se puede crear el espacio de trabajo predeterminado. Utilice Elegir espacio de trabajo para seleccionar una carpeta.', + 'draft.workspaceRequired': 'Elija un espacio de trabajo primero.', + 'draft.initializationFailed': 'No se pudo completar el borrador. Inténtelo de nuevo en breve.', + 'group.ungrouped': 'Desagrupados', + 'session.new': 'Nueva sesión', + 'session.untitled': 'Sin título', + 'shortcut.noSession': 'Seleccione una sesión primero', + 'shortcut.noPicker': 'Selector de directorio no disponible', + 'shortcut.directoryBusy': 'Seleccionar o agregar un espacio de trabajo', + 'shortcut.noCompletedTurn': 'Esta sesión no tiene turno completo', + 'shortcut.forkFailed': 'No se pudo bifurcar la sesión. Intentar otra vez.', + 'section.workspaces': 'Espacios de trabajo', + 'section.sessions': 'Sesiones', + 'viewOptions.label': 'Ver opciones', + 'groupBy.label': 'Agrupar por', + 'groupBy.workspace': 'Espacio de trabajo', + 'groupBy.workspaceTree': 'Árbol del espacio de trabajo', + 'groupBy.flat': 'en una lista', + 'orderBy.label': 'Ordenar por', + 'orderBy.manual': 'manuales', + 'orderBy.updated': 'Última actualización', + 'filterBy.label': 'Filtrar sesiones', + 'viewOptions.hideArchived': 'Ocultar archivado', + 'viewOptions.showArchived': 'Todas las conversaciones (mostrar archivadas)', + 'viewOptions.onlyArchived': 'Sólo archivado', + 'sessions.expand': 'Mostrar {n} más sesiones', + 'sessions.collapse': 'Mostrar menos', + 'empty.none': 'Aún no hay sesiones', + 'empty.noneArchived': 'Aún no hay sesiones archivadas', + 'empty.viewOthers': 'Ver otras sesiones', + 'empty.noMatches': 'No hay coincidencias', + 'workspace.add': 'Agregar espacio de trabajo', + 'search.sessions.aria': 'Sesiones de búsqueda', + 'search.placeholder': 'Buscar nombres de sesiones', + 'search.clear': 'Borrar búsqueda', + 'search.results.aria': 'Resultados de la búsqueda', + 'search.pending': 'Buscando el historial de sesiones…', + 'search.noMatches': 'No hay sesiones coincidentes', + 'search.hasMore': 'Mostrando los primeros resultados de {n}. Limita tu búsqueda.', + 'menu.addWorkspace': 'Agregar espacio de trabajo…', + 'picker.loading': 'Cargando espacios de trabajo…', + 'conflict.named': 'Ya existe un espacio de trabajo denominado "{name}".', + 'folderError.title': 'No se pudo abrir la carpeta', + 'folderError.retry': 'Elige de nuevo', + 'rename': 'Cambiar nombre', + 'rename.workspace.title': 'Cambiar nombre del espacio de trabajo', + 'rename.session.title': 'Cambiar nombre de sesión', + 'field.workspaceName': 'Nombre del espacio de trabajo', + 'field.sessionName': 'Nombre de la sesión', + 'delete.workspace': 'Eliminar espacio de trabajo', + 'delete.desc': 'Esto elimina "{name}" de la lista de espacios de trabajo. Se conservarán los registros de carpetas y sesiones. Sus sesiones aparecerán en Desagrupadas.', + 'delete.pending': 'Eliminando espacio de trabajo…', + 'menu.fork': 'Sesión de horquilla', + 'menu.archiveSession': 'Sesión de archivo', + 'menu.unarchiveSession': 'Desarchivar sesión', + 'menu.pinSession': 'Sesión de fijación', + 'menu.unpinSession': 'Desanclar sesión', + 'menu.sessionId': 'Copiar ID de sesión', + 'toast.sessionIdCopied': 'ID de sesión copiada', + 'toast.sessionIdCopyFailed': 'La copia falló. Intentar otra vez.', + 'row.archived': 'Archivado', + 'row.pinned': 'Fijado', + 'toast.archivedNotOpenable': 'Las sesiones archivadas no se pueden abrir. Desarchivarlo para verlo.', + 'toast.archived': 'Sesión archivada. tu puedes ', + 'toast.stoppedAndArchived': 'Sesión detenida y archivada. tu puedes ', + 'archive.confirm.title': '¿Detener y archivar esta sesión?', + 'archive.confirm.desc': '“{title}” todavía tiene trabajo en progreso. Archivarlo lo detiene primero; puedes restaurar la sesión más tarde desde el filtro “Todas las conversaciones (mostrar archivadas)” en la barra lateral, y el trabajo detenido no se reanudará por sí solo.', + 'archive.confirm.activity': 'Trabajo que será detenido', + 'archive.confirm.turn': 'El turno en curso', + 'archive.confirm.subagents.one': '{n} ejecutando subagente: {names}', + 'archive.confirm.subagents.other': '{n} ejecutando subagentes: {names}', + 'archive.confirm.jobs.one': 'Trabajo en segundo plano {n}: {names}', + 'archive.confirm.jobs.other': 'Trabajos en segundo plano {n}: {names}', + 'archive.confirm.schedules.one': 'Recordatorio programado {n}: {names}', + 'archive.confirm.schedules.other': '{n} recordatorios programados: {names}', + 'archive.confirm.other.one': '{n} otro elemento de trabajo ({kind})', + 'archive.confirm.other.other': '{n} otros elementos de trabajo ({kind})', + 'archive.confirm.listSeparator': ', ', + 'archive.confirm.action': 'Detener y archivar', + 'archive.confirm.pending': 'Deteniendo y archivando…', + 'toast.archivedUndo': 'deshacer', + 'toast.archivedOr': ' o ', + 'toast.archivedFilter': 'filtrar sesiones archivadas', + 'toast.pinFailed': 'Error en el pin. Vuelve a intentarlo más tarde.', + 'toast.unpinFailed': 'Error al desbloquear. Vuelve a intentarlo más tarde.', + 'toast.createFailed': 'Nueva sesión falló: {message}', + 'toast.forkRequiresOpen': 'Abra la sesión original para completar la migración antes de crear una rama.', + 'toast.openForkSource': 'Abrir sesión original', + 'sessions.count.one': 'Sesión {n}', + 'sessions.count.other': 'Sesiones {n}', + 'actions.workspace.aria': 'Acciones del espacio de trabajo para {name}', + 'actions.session.aria': 'Acciones de sesión para {name}', + 'actions.archive': 'Archivo', + 'actions.unarchive': 'Desarchivar', + 'actions.pin': 'Alfiler', + 'actions.unpin': 'Desanclar', + 'actions.newSession': 'Nueva sesión', + 'actions.newSession.aria': 'Nueva sesión en {name}', + 'status.running': 'corriendo', + 'status.subagentsRunning.one': 'Subagente {n} ejecutándose', + 'status.subagentsRunning.other': 'Subagentes {n} ejecutándose', + 'status.idle': 'inactivo', + 'status.waitingApproval': 'Esperando aprobación', + 'status.planReview': 'Plan pendiente de revisión', + 'status.waitingAnswer': 'esperando respuesta', + 'status.compact.approval': 'Aprobación', + 'status.compact.planReview': 'Revisión del plan', + 'status.compact.answer': 'respuesta', + 'status.completed': 'Completado', + 'hover.created': 'Creado {time}', + 'hover.copied': 'Copiado', + 'date.ymd': '{y}-{m}-{d}', + 'time.now': 'ahora', + 'time.minutes': '{n}min', + 'time.hours': '{n}h', + 'time.days': '{n}d', + 'time.months': '{n}mo', + 'time.years': '{n}y', + 'time.ago': 'Hace {t}', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'defaultWorkspace.failed': 'Impossible de créer un espace de travail par défaut. Utilisez Choisir un espace de travail pour sélectionner un dossier.', + 'draft.workspaceRequired': "Choisissez d'abord un espace de travail.", + 'draft.initializationFailed': 'Impossible de remplir le projet. Veuillez réessayer sous peu.', + 'group.ungrouped': 'Non groupé', + 'session.new': 'Nouvelle séance', + 'session.untitled': 'Sans titre', + 'shortcut.noSession': "Sélectionnez d'abord une session", + 'shortcut.noPicker': 'Sélecteur de répertoire indisponible', + 'shortcut.directoryBusy': "Sélection ou ajout d'un espace de travail", + 'shortcut.noCompletedTurn': "Cette session n'a pas de tour terminé", + 'shortcut.forkFailed': 'Impossible de bifurquer la session. Essayer à nouveau.', + 'section.workspaces': 'Espaces de travail', + 'section.sessions': 'Séances', + 'viewOptions.label': 'Afficher les options', + 'groupBy.label': 'Regrouper par', + 'groupBy.workspace': 'Espace de travail', + 'groupBy.workspaceTree': "Arborescence de l'espace de travail", + 'groupBy.flat': 'Dans une liste', + 'orderBy.label': 'Commander par', + 'orderBy.manual': 'Manuel', + 'orderBy.updated': 'Dernière mise à jour', + 'filterBy.label': 'Filtrer les sessions', + 'viewOptions.hideArchived': 'Masquer les archives', + 'viewOptions.showArchived': 'Toutes les conversations (afficher les archives)', + 'viewOptions.onlyArchived': 'Archivé uniquement', + 'sessions.expand': 'Afficher {n} plus de sessions', + 'sessions.collapse': 'Afficher moins', + 'empty.none': "Aucune séance pour l'instant", + 'empty.noneArchived': "Aucune session archivée pour l'instant", + 'empty.viewOthers': 'Voir les autres séances', + 'empty.noMatches': 'Aucune correspondance', + 'workspace.add': 'Ajouter un espace de travail', + 'search.sessions.aria': 'Sessions de recherche', + 'search.placeholder': 'Rechercher des noms de sessions', + 'search.clear': 'Effacer la recherche', + 'search.results.aria': 'Résultats de la recherche', + 'search.pending': "Recherche dans l'historique des sessions…", + 'search.noMatches': 'Aucune session correspondante', + 'search.hasMore': 'Affichage des premiers résultats {n}. Affinez votre recherche.', + 'menu.addWorkspace': 'Ajouter un espace de travail…', + 'picker.loading': 'Chargement des espaces de travail…', + 'conflict.named': 'Un espace de travail nommé « {name} » existe déjà.', + 'folderError.title': "Impossible d'ouvrir le dossier", + 'folderError.retry': 'Choisir à nouveau', + 'rename': 'Renommer', + 'rename.workspace.title': "Renommer l'espace de travail", + 'rename.session.title': 'Renommer la session', + 'field.workspaceName': "Nom de l'espace de travail", + 'field.sessionName': 'Nom de la séance', + 'delete.workspace': "Supprimer l'espace de travail", + 'delete.desc': 'Cela supprime « {name} » de la liste des espaces de travail. Les journaux de dossiers et de sessions seront conservés. Ses sessions apparaîtront sous Non groupées.', + 'delete.pending': "Suppression de l'espace de travail…", + 'menu.fork': 'Séance à la fourchette', + 'menu.archiveSession': "Séance d'archivage", + 'menu.unarchiveSession': 'Session de désarchivage', + 'menu.pinSession': "Session d'épinglage", + 'menu.unpinSession': 'Désépingler la session', + 'menu.sessionId': "Copier l'ID de session", + 'toast.sessionIdCopied': 'ID de session copié', + 'toast.sessionIdCopyFailed': 'La copie a échoué. Essayer à nouveau.', + 'row.archived': 'Archivé', + 'row.pinned': 'Épinglé', + 'toast.archivedNotOpenable': 'Les sessions archivées ne peuvent pas être ouvertes. Désarchivez-le pour le visualiser.', + 'toast.archived': 'Séance archivée. Vous pouvez ', + 'toast.stoppedAndArchived': 'Session arrêtée et archivée. Vous pouvez ', + 'archive.confirm.title': 'Arrêter et archiver cette session ?', + 'archive.confirm.desc': "« {title} » a encore des travaux en cours. L'archivage l'arrête en premier ; vous pouvez restaurer la session plus tard à partir du filtre « Toutes les conversations (afficher les archives) » dans la barre latérale, et le travail arrêté ne reprendra pas de lui-même.", + 'archive.confirm.activity': 'Travaux qui seront arrêtés', + 'archive.confirm.turn': 'Le tour en cours', + 'archive.confirm.subagents.one': "Sous-agent en cours d'exécution {n} : {names}", + 'archive.confirm.subagents.other': '{n} exécutant des sous-agents : {names}', + 'archive.confirm.jobs.one': 'Travail en arrière-plan {n} : {names}', + 'archive.confirm.jobs.other': 'Travaux en arrière-plan {n} : {names}', + 'archive.confirm.schedules.one': 'Rappel programmé {n} : {names}', + 'archive.confirm.schedules.other': 'Rappels programmés {n} : {names}', + 'archive.confirm.other.one': '{n} autre élément de travail ({kind})', + 'archive.confirm.other.other': '{n} autres éléments de travail ({kind})', + 'archive.confirm.listSeparator': ', ', + 'archive.confirm.action': 'Arrêter et archiver', + 'archive.confirm.pending': 'Arrêt et archivage…', + 'toast.archivedUndo': 'annuler', + 'toast.archivedOr': ' ou ', + 'toast.archivedFilter': 'filtrer les sessions archivées', + 'toast.pinFailed': 'La broche a échoué. Réessayez plus tard.', + 'toast.unpinFailed': "Échec du retrait de l'épingle. Réessayez plus tard.", + 'toast.createFailed': 'Échec de la nouvelle session : {message}', + 'toast.forkRequiresOpen': "Ouvrez la session d'origine pour terminer la migration avant de créer une branche.", + 'toast.openForkSource': 'Ouvrir la session originale', + 'sessions.count.one': 'Séance {n}', + 'sessions.count.other': 'Séances {n}', + 'actions.workspace.aria': "Actions de l'espace de travail pour {name}", + 'actions.session.aria': 'Actions de session pour {name}', + 'actions.archive': 'Archiver', + 'actions.unarchive': 'Désarchiver', + 'actions.pin': 'Épingle', + 'actions.unpin': 'Désépingler', + 'actions.newSession': 'Nouvelle séance', + 'actions.newSession.aria': 'Nouvelle séance dans {name}', + 'status.running': 'Courir', + 'status.subagentsRunning.one': "Sous-agent {n} en cours d'exécution", + 'status.subagentsRunning.other': "Sous-agents {n} en cours d'exécution", + 'status.idle': 'Inactif', + 'status.waitingApproval': "En attente d'approbation", + 'status.planReview': "Plan en attente d'examen", + 'status.waitingAnswer': 'En attente de réponse', + 'status.compact.approval': 'Approbation', + 'status.compact.planReview': 'Révision des plans', + 'status.compact.answer': 'Réponse', + 'status.completed': 'Terminé', + 'hover.created': 'Créé {time}', + 'hover.copied': 'Copié', + 'date.ymd': '{y}-{m}-{d}', + 'time.now': 'maintenant', + 'time.minutes': '{n}min', + 'time.hours': '{n}h', + 'time.days': '{n}d', + 'time.months': '{n}mo', + 'time.years': '{n}y', + 'time.ago': 'Il y a {t}', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'defaultWorkspace.failed': 'Der Standardarbeitsbereich kann nicht erstellt werden. Verwenden Sie „Arbeitsbereich auswählen“, um einen Ordner auszuwählen.', + 'draft.workspaceRequired': 'Wählen Sie zunächst einen Arbeitsbereich.', + 'draft.initializationFailed': 'Der Entwurf konnte nicht ausgefüllt werden. Bitte versuchen Sie es in Kürze noch einmal.', + 'group.ungrouped': 'Nicht gruppiert', + 'session.new': 'Neue Sitzung', + 'session.untitled': 'Ohne Titel', + 'shortcut.noSession': 'Wählen Sie zunächst eine Sitzung aus', + 'shortcut.noPicker': 'Verzeichnisauswahl nicht verfügbar', + 'shortcut.directoryBusy': 'Auswählen oder Hinzufügen eines Arbeitsbereichs', + 'shortcut.noCompletedTurn': 'Diese Sitzung hat keine abgeschlossene Runde', + 'shortcut.forkFailed': 'Die Sitzung konnte nicht aufgeteilt werden. Versuchen Sie es erneut.', + 'section.workspaces': 'Arbeitsbereiche', + 'section.sessions': 'Sitzungen', + 'viewOptions.label': 'Optionen anzeigen', + 'groupBy.label': 'Gruppieren nach', + 'groupBy.workspace': 'WorkSpace', + 'groupBy.workspaceTree': 'Arbeitsbereichsbaum', + 'groupBy.flat': 'In einer Liste', + 'orderBy.label': 'Bestellen nach', + 'orderBy.manual': 'Handbuch', + 'orderBy.updated': 'Zuletzt aktualisiert', + 'filterBy.label': 'Sitzungen filtern', + 'viewOptions.hideArchived': 'Archiviert ausblenden', + 'viewOptions.showArchived': 'Alle Gespräche (archiviert anzeigen)', + 'viewOptions.onlyArchived': 'Nur archiviert', + 'sessions.expand': 'Weitere Sitzungen anzeigen {n}', + 'sessions.collapse': 'Weniger anzeigen', + 'empty.none': 'Noch keine Sitzungen', + 'empty.noneArchived': 'Noch keine archivierten Sitzungen', + 'empty.viewOthers': 'Andere Sitzungen anzeigen', + 'empty.noMatches': 'Keine Übereinstimmungen', + 'workspace.add': 'Arbeitsbereich hinzufügen', + 'search.sessions.aria': 'Suchsitzungen', + 'search.placeholder': 'Suchen Sie nach Sitzungsnamen', + 'search.clear': 'Suche löschen', + 'search.results.aria': 'Suchergebnisse', + 'search.pending': 'Sitzungsverlauf wird durchsucht…', + 'search.noMatches': 'Keine passenden Sitzungen', + 'search.hasMore': 'Zeigt die ersten {n}-Ergebnisse. Grenzen Sie Ihre Suche ein.', + 'menu.addWorkspace': 'Arbeitsbereich hinzufügen…', + 'picker.loading': 'Arbeitsbereiche werden geladen…', + 'conflict.named': 'Ein Arbeitsbereich mit dem Namen „{name}“ ist bereits vorhanden.', + 'folderError.title': 'Der Ordner konnte nicht geöffnet werden', + 'folderError.retry': 'Wählen Sie erneut', + 'rename': 'Umbenennen', + 'rename.workspace.title': 'Arbeitsbereich umbenennen', + 'rename.session.title': 'Sitzung umbenennen', + 'field.workspaceName': 'Name des Arbeitsbereichs', + 'field.sessionName': 'Sitzungsname', + 'delete.workspace': 'Arbeitsbereich löschen', + 'delete.desc': 'Dadurch wird „{name}“ aus der Arbeitsbereichsliste entfernt. Die Ordner- und Sitzungsprotokolle werden aufbewahrt. Seine Sitzungen werden unter „Nicht gruppiert“ angezeigt.', + 'delete.pending': 'Arbeitsbereich wird gelöscht…', + 'menu.fork': 'Fork-Sitzung', + 'menu.archiveSession': 'Archivsitzung', + 'menu.unarchiveSession': 'Sitzung dearchivieren', + 'menu.pinSession': 'Pin-Sitzung', + 'menu.unpinSession': 'Sitzung lösen', + 'menu.sessionId': 'Sitzungs-ID kopieren', + 'toast.sessionIdCopied': 'Sitzungs-ID kopiert', + 'toast.sessionIdCopyFailed': 'Der Kopiervorgang ist fehlgeschlagen. Versuchen Sie es erneut.', + 'row.archived': 'Archiviert', + 'row.pinned': 'Angepinnt', + 'toast.archivedNotOpenable': 'Archivierte Sitzungen können nicht geöffnet werden. Entpacken Sie es zur Ansicht.', + 'toast.archived': 'Sitzung archiviert. Du kannst ', + 'toast.stoppedAndArchived': 'Sitzung gestoppt und archiviert. Du kannst ', + 'archive.confirm.title': 'Diese Sitzung stoppen und archivieren?', + 'archive.confirm.desc': '„{title}“ ist noch in Arbeit. Die Archivierung stoppt es zunächst; Sie können die Sitzung später über den Filter „Alle Konversationen (archivierte anzeigen)“ in der Seitenleiste wiederherstellen, und die angehaltene Arbeit wird nicht von alleine fortgesetzt.', + 'archive.confirm.activity': 'Arbeiten, die gestoppt werden', + 'archive.confirm.turn': 'Die laufende Runde', + 'archive.confirm.subagents.one': '{n}, laufender Subagent: {names}', + 'archive.confirm.subagents.other': '{n}, auf dem Subagenten ausgeführt werden: {names}', + 'archive.confirm.jobs.one': '{n} Hintergrundjob: {names}', + 'archive.confirm.jobs.other': '{n} Hintergrundjobs: {names}', + 'archive.confirm.schedules.one': '{n} geplante Erinnerung: {names}', + 'archive.confirm.schedules.other': '{n} geplante Erinnerungen: {names}', + 'archive.confirm.other.one': '{n} sonstiger Arbeitsgegenstand ({kind})', + 'archive.confirm.other.other': '{n} sonstige Arbeiten ({kind})', + 'archive.confirm.listSeparator': ', ', + 'archive.confirm.action': 'Stoppen und archivieren', + 'archive.confirm.pending': 'Stoppen und archivieren…', + 'toast.archivedUndo': 'rückgängig machen', + 'toast.archivedOr': ' oder ', + 'toast.archivedFilter': 'Archivierte Sitzungen filtern', + 'toast.pinFailed': 'Pin ist fehlgeschlagen. Versuchen Sie es später noch einmal.', + 'toast.unpinFailed': 'Das Lösen der Fixierung ist fehlgeschlagen. Versuchen Sie es später noch einmal.', + 'toast.createFailed': 'Neue Sitzung fehlgeschlagen: {message}', + 'toast.forkRequiresOpen': 'Öffnen Sie die ursprüngliche Sitzung, um die Migration abzuschließen, bevor Sie einen Zweig erstellen.', + 'toast.openForkSource': 'Öffnen Sie die ursprüngliche Sitzung', + 'sessions.count.one': '{n}-Sitzung', + 'sessions.count.other': '{n}-Sitzungen', + 'actions.workspace.aria': 'Arbeitsbereichsaktionen für {name}', + 'actions.session.aria': 'Sitzungsaktionen für {name}', + 'actions.archive': 'Archiv', + 'actions.unarchive': 'Dearchivieren', + 'actions.pin': 'Pin', + 'actions.unpin': 'Lösen', + 'actions.newSession': 'Neue Sitzung', + 'actions.newSession.aria': 'Neue Sitzung in {name}', + 'status.running': 'Laufen', + 'status.subagentsRunning.one': '{n}-Subagent läuft', + 'status.subagentsRunning.other': '{n} Subagenten laufen', + 'status.idle': 'Leerlauf', + 'status.waitingApproval': 'Warten auf Genehmigung', + 'status.planReview': 'Plan wartet auf Überprüfung', + 'status.waitingAnswer': 'Warte auf Antwort', + 'status.compact.approval': 'Zustimmung', + 'status.compact.planReview': 'Planüberprüfung', + 'status.compact.answer': 'Antwort', + 'status.completed': 'Abgeschlossen', + 'hover.created': 'Erstellt {time}', + 'hover.copied': 'Kopiert', + 'date.ymd': '{y}-{m}-{d}', + 'time.now': 'jetzt', + 'time.minutes': '{n}min', + 'time.hours': '{n}h', + 'time.days': '{n}d', + 'time.months': '{n}mo', + 'time.years': '{n}y', + 'time.ago': 'Vor {t}', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'defaultWorkspace.failed': 'Невозможно создать рабочую область по умолчанию. Используйте «Выбрать рабочее пространство», чтобы выбрать папку.', + 'draft.workspaceRequired': 'Сначала выберите рабочее место.', + 'draft.initializationFailed': 'Не удалось заполнить черновик. Пожалуйста, повторите попытку в ближайшее время.', + 'group.ungrouped': 'Разгруппировано', + 'session.new': 'Новая сессия', + 'session.untitled': 'Без названия', + 'shortcut.noSession': 'Сначала выберите сеанс', + 'shortcut.noPicker': 'Выбор каталога недоступен.', + 'shortcut.directoryBusy': 'Выбор или добавление рабочего пространства', + 'shortcut.noCompletedTurn': 'В этой сессии нет завершенных ходов', + 'shortcut.forkFailed': 'Не удалось разветвить сеанс. Попробуйте еще раз.', + 'section.workspaces': 'Рабочие пространства', + 'section.sessions': 'Сессии', + 'viewOptions.label': 'Посмотреть варианты', + 'groupBy.label': 'Группировать по', + 'groupBy.workspace': 'Рабочее пространство', + 'groupBy.workspaceTree': 'Дерево рабочей области', + 'groupBy.flat': 'В одном списке', + 'orderBy.label': 'Заказать по', + 'orderBy.manual': 'Руководство', + 'orderBy.updated': 'Последнее обновление', + 'filterBy.label': 'Фильтровать сеансы', + 'viewOptions.hideArchived': 'Скрыть в архиве', + 'viewOptions.showArchived': 'Все разговоры (показать в архиве)', + 'viewOptions.onlyArchived': 'Только в архиве', + 'sessions.expand': 'Показать больше сеансов {n}', + 'sessions.collapse': 'Показать меньше', + 'empty.none': 'Сеансов пока нет', + 'empty.noneArchived': 'Архивированных сессий пока нет', + 'empty.viewOthers': 'Посмотреть другие сессии', + 'empty.noMatches': 'Нет совпадений', + 'workspace.add': 'Добавить рабочую область', + 'search.sessions.aria': 'Поиск сеансов', + 'search.placeholder': 'Поиск названий сеансов', + 'search.clear': 'Очистить поиск', + 'search.results.aria': 'Результаты поиска', + 'search.pending': 'Поиск истории сеансов…', + 'search.noMatches': 'Нет подходящих сеансов', + 'search.hasMore': 'Показаны первые результаты {n}. Сузьте область поиска.', + 'menu.addWorkspace': 'Добавить рабочее пространство…', + 'picker.loading': 'Загрузка рабочих областей…', + 'conflict.named': 'Рабочая область с именем «{name}» уже существует.', + 'folderError.title': 'Не удалось открыть папку', + 'folderError.retry': 'Выбрать еще раз', + 'rename': 'Переименовать', + 'rename.workspace.title': 'Переименовать рабочую область', + 'rename.session.title': 'Переименовать сеанс', + 'field.workspaceName': 'Имя рабочей области', + 'field.sessionName': 'Имя сеанса', + 'delete.workspace': 'Удалить рабочую область', + 'delete.desc': 'Это удалит «{name}» из списка рабочей области. Журналы папок и сеансов будут сохранены. Его сеансы появятся в разделе «Разгруппировано».', + 'delete.pending': 'Удаление рабочей области…', + 'menu.fork': 'Форк-сессия', + 'menu.archiveSession': 'Архив сеанса', + 'menu.unarchiveSession': 'Разархивировать сеанс', + 'menu.pinSession': 'Закрепить сеанс', + 'menu.unpinSession': 'Открепить сеанс', + 'menu.sessionId': 'Копировать идентификатор сеанса', + 'toast.sessionIdCopied': 'Идентификатор сеанса скопирован.', + 'toast.sessionIdCopyFailed': 'Копировать не удалось. Попробуйте еще раз.', + 'row.archived': 'В архиве', + 'row.pinned': 'Закреплено', + 'toast.archivedNotOpenable': 'Архивированные сеансы невозможно открыть. Разархивируйте его для просмотра.', + 'toast.archived': 'Сессия заархивирована. Вы можете ', + 'toast.stoppedAndArchived': 'Сеанс остановлен и заархивирован. Вы можете ', + 'archive.confirm.title': 'Остановить и заархивировать этот сеанс?', + 'archive.confirm.desc': 'Над «{title}» все еще ведется работа. Архивирование останавливает его первым; восстановить сессию можно позже из фильтра «Все разговоры (показать в архиве)» в боковой панели, при этом остановленная работа не возобновится сама по себе.', + 'archive.confirm.activity': 'Работа, которая будет остановлена', + 'archive.confirm.turn': 'Текущий ход', + 'archive.confirm.subagents.one': '{n} работающий субагент: {names}', + 'archive.confirm.subagents.other': '{n} работающие субагенты: {names}', + 'archive.confirm.jobs.one': '{n} фоновое задание: {names}', + 'archive.confirm.jobs.other': '{n} фоновые задания: {names}', + 'archive.confirm.schedules.one': 'Запланированное напоминание {n}: {names}', + 'archive.confirm.schedules.other': 'Запланированные напоминания {n}: {names}', + 'archive.confirm.other.one': '{n} другой элемент работы ({kind})', + 'archive.confirm.other.other': '{n} прочие работы ({kind})', + 'archive.confirm.listSeparator': ', ', + 'archive.confirm.action': 'Остановить и заархивировать', + 'archive.confirm.pending': 'Остановка и архивирование…', + 'toast.archivedUndo': 'отменить', + 'toast.archivedOr': ' или ', + 'toast.archivedFilter': 'фильтровать архивированные сеансы', + 'toast.pinFailed': 'Закрепить не удалось. Повторите попытку позже.', + 'toast.unpinFailed': 'Открепить не удалось. Повторите попытку позже.', + 'toast.createFailed': 'Не удалось создать новый сеанс: {message}.', + 'toast.forkRequiresOpen': 'Откройте исходный сеанс, чтобы завершить миграцию, прежде чем создавать ветку.', + 'toast.openForkSource': 'Открыть исходный сеанс', + 'sessions.count.one': 'Сеанс {n}', + 'sessions.count.other': 'Сессии {n}', + 'actions.workspace.aria': 'Действия рабочей области для {name}', + 'actions.session.aria': 'Действия сеанса для {name}', + 'actions.archive': 'Архив', + 'actions.unarchive': 'Разархивировать', + 'actions.pin': 'Пин-код', + 'actions.unpin': 'Открепить', + 'actions.newSession': 'Новая сессия', + 'actions.newSession.aria': 'Новая сессия в {name}', + 'status.running': 'Бег', + 'status.subagentsRunning.one': 'Субагент {n} работает', + 'status.subagentsRunning.other': 'Субагенты {n} работают', + 'status.idle': 'Простой', + 'status.waitingApproval': 'Ожидание одобрения', + 'status.planReview': 'План ожидает рассмотрения', + 'status.waitingAnswer': 'Ожидание ответа', + 'status.compact.approval': 'Одобрение', + 'status.compact.planReview': 'Обзор плана', + 'status.compact.answer': 'Ответ', + 'status.completed': 'Завершено', + 'hover.created': 'Создано {time}', + 'hover.copied': 'Скопировано', + 'date.ymd': '{y}-{m}-{d}', + 'time.now': 'сейчас', + 'time.minutes': '{n}мин', + 'time.hours': '{n}h', + 'time.days': '{n}d', + 'time.months': '{n}mo', + 'time.years': '{n}y', + 'time.ago': '{t} назад', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'defaultWorkspace.failed': 'Não foi possível criar o espaço de trabalho padrão. Use Escolher espaço de trabalho para selecionar uma pasta.', + 'draft.workspaceRequired': 'Escolha um espaço de trabalho primeiro.', + 'draft.initializationFailed': 'Não foi possível preencher o rascunho. Por favor, tente novamente em breve.', + 'group.ungrouped': 'Desagrupado', + 'session.new': 'Nova sessão', + 'session.untitled': 'Sem título', + 'shortcut.noSession': 'Selecione uma sessão primeiro', + 'shortcut.noPicker': 'Seletor de diretório indisponível', + 'shortcut.directoryBusy': 'Selecionando ou adicionando um espaço de trabalho', + 'shortcut.noCompletedTurn': 'Esta sessão não tem turno concluído', + 'shortcut.forkFailed': 'Não foi possível bifurcar a sessão. Tente novamente.', + 'section.workspaces': 'Espaços de trabalho', + 'section.sessions': 'Sessões', + 'viewOptions.label': 'Ver opções', + 'groupBy.label': 'Agrupar por', + 'groupBy.workspace': 'Espaço de trabalho', + 'groupBy.workspaceTree': 'Árvore do espaço de trabalho', + 'groupBy.flat': 'Em uma lista', + 'orderBy.label': 'Encomendar por', + 'orderBy.manual': 'Manuais', + 'orderBy.updated': 'Última atualização', + 'filterBy.label': 'Filtrar sessões', + 'viewOptions.hideArchived': 'Ocultar arquivado', + 'viewOptions.showArchived': 'Todas as conversas (mostrar arquivadas)', + 'viewOptions.onlyArchived': 'Somente arquivado', + 'sessions.expand': 'Mostrar mais {n} sessões', + 'sessions.collapse': 'Mostrar menos', + 'empty.none': 'Ainda não há sessões', + 'empty.noneArchived': 'Ainda não há sessões arquivadas', + 'empty.viewOthers': 'Ver outras sessões', + 'empty.noMatches': 'Nenhuma correspondência', + 'workspace.add': 'Adicionar espaço de trabalho', + 'search.sessions.aria': 'Sessões de pesquisa', + 'search.placeholder': 'Pesquisar nomes de sessões', + 'search.clear': 'Limpar pesquisa', + 'search.results.aria': 'Resultados da pesquisa', + 'search.pending': 'Pesquisando histórico da sessão…', + 'search.noMatches': 'Nenhuma sessão correspondente', + 'search.hasMore': 'Mostrando os primeiros {n} resultados. Restrinja sua pesquisa.', + 'menu.addWorkspace': 'Adicionar espaço de trabalho…', + 'picker.loading': 'Carregando áreas de trabalho…', + 'conflict.named': 'Já existe um espaço de trabalho chamado “{name}”.', + 'folderError.title': 'Não foi possível abrir a pasta', + 'folderError.retry': 'Escolha novamente', + 'rename': 'Renomear', + 'rename.workspace.title': 'Renomear espaço de trabalho', + 'rename.session.title': 'Renomear sessão', + 'field.workspaceName': 'Nome do espaço de trabalho', + 'field.sessionName': 'Nome da sessão', + 'delete.workspace': 'Excluir espaço de trabalho', + 'delete.desc': 'Isso remove “{name}” da lista de espaços de trabalho. A pasta e os logs de sessão serão mantidos. Suas sessões aparecerão em Desagrupado.', + 'delete.pending': 'Excluindo espaço de trabalho…', + 'menu.fork': 'Sessão de bifurcação', + 'menu.archiveSession': 'Sessão de arquivamento', + 'menu.unarchiveSession': 'Desarquivar sessão', + 'menu.pinSession': 'Fixar sessão', + 'menu.unpinSession': 'Liberar sessão', + 'menu.sessionId': 'Copiar ID da sessão', + 'toast.sessionIdCopied': 'ID da sessão copiado', + 'toast.sessionIdCopyFailed': 'Falha na cópia. Tente novamente.', + 'row.archived': 'Arquivado', + 'row.pinned': 'Fixado', + 'toast.archivedNotOpenable': 'As sessões arquivadas não podem ser abertas. Desarquive-o para visualizar.', + 'toast.archived': 'Sessão arquivada. Você pode ', + 'toast.stoppedAndArchived': 'Sessão interrompida e arquivada. Você pode ', + 'archive.confirm.title': 'Parar e arquivar esta sessão?', + 'archive.confirm.desc': '“{title}” ainda tem trabalho em andamento. O arquivamento interrompe primeiro; você pode restaurar a sessão posteriormente a partir do filtro “Todas as conversas (mostrar arquivadas)” na barra lateral, e o trabalho interrompido não será retomado por conta própria.', + 'archive.confirm.activity': 'Obra que será interrompida', + 'archive.confirm.turn': 'O turno em andamento', + 'archive.confirm.subagents.one': '{n} subagente em execução: {names}', + 'archive.confirm.subagents.other': '{n} executando subagentes: {names}', + 'archive.confirm.jobs.one': '{n} trabalho em segundo plano: {names}', + 'archive.confirm.jobs.other': '{n} trabalhos em segundo plano: {names}', + 'archive.confirm.schedules.one': '{n} lembrete programado: {names}', + 'archive.confirm.schedules.other': '{n} lembretes programados: {names}', + 'archive.confirm.other.one': '{n} outro item de trabalho ({kind})', + 'archive.confirm.other.other': '{n} outros itens de trabalho ({kind})', + 'archive.confirm.listSeparator': ', ', + 'archive.confirm.action': 'Pare e arquive', + 'archive.confirm.pending': 'Parando e arquivando…', + 'toast.archivedUndo': 'desfazer', + 'toast.archivedOr': ' ou ', + 'toast.archivedFilter': 'filtrar sessões arquivadas', + 'toast.pinFailed': 'Falha na fixação. Tente novamente mais tarde.', + 'toast.unpinFailed': 'Falha ao liberar. Tente novamente mais tarde.', + 'toast.createFailed': 'Falha na nova sessão: {message}', + 'toast.forkRequiresOpen': 'Abra a sessão original para concluir a migração antes de criar uma ramificação.', + 'toast.openForkSource': 'Abrir sessão original', + 'sessions.count.one': '{n} sessão', + 'sessions.count.other': '{n} sessões', + 'actions.workspace.aria': 'Ações do espaço de trabalho para {name}', + 'actions.session.aria': 'Ações de sessão para {name}', + 'actions.archive': 'Arquivo', + 'actions.unarchive': 'Desarquivar', + 'actions.pin': 'Fixar', + 'actions.unpin': 'Liberar', + 'actions.newSession': 'Nova sessão', + 'actions.newSession.aria': 'Nova sessão em {name}', + 'status.running': 'Correndo', + 'status.subagentsRunning.one': '{n} subagente em execução', + 'status.subagentsRunning.other': '{n} subagentes em execução', + 'status.idle': 'Inativo', + 'status.waitingApproval': 'Aguardando aprovação', + 'status.planReview': 'Plano aguardando revisão', + 'status.waitingAnswer': 'Esperando por resposta', + 'status.compact.approval': 'Aprovação', + 'status.compact.planReview': 'Revisão do plano', + 'status.compact.answer': 'Resposta', + 'status.completed': 'Concluído', + 'hover.created': 'Criado {time}', + 'hover.copied': 'Copiado', + 'date.ymd': '{y}-{m}-{d}', + 'time.now': 'agora', + 'time.minutes': '{n}min', + 'time.hours': '{n}h', + 'time.days': '{n}d', + 'time.months': '{n} mês', + 'time.years': '{n}s', + 'time.ago': '{t} atrás', +} satisfies Record diff --git a/packages/compaction/command-compact/locale/de.json b/packages/compaction/command-compact/locale/de.json new file mode 100644 index 0000000000..c6563c9965 --- /dev/null +++ b/packages/compaction/command-compact/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Befehl zur Kontextkomprimierung", + "description": "Lassen Sie den Benutzer den aktuellen Sitzungskontext durch einen Befehl aktiv komprimieren." + } +} diff --git a/packages/compaction/command-compact/locale/es.json b/packages/compaction/command-compact/locale/es.json new file mode 100644 index 0000000000..4944ef0608 --- /dev/null +++ b/packages/compaction/command-compact/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Comando de compresión de contexto", + "description": "Permita que el usuario comprima activamente el contexto de la sesión actual mediante un comando." + } +} diff --git a/packages/compaction/command-compact/locale/fr.json b/packages/compaction/command-compact/locale/fr.json new file mode 100644 index 0000000000..471f545f49 --- /dev/null +++ b/packages/compaction/command-compact/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Commande de compression de contexte", + "description": "Laissez l'utilisateur compresser activement le contexte de la session en cours via une commande." + } +} diff --git a/packages/compaction/command-compact/locale/pt.json b/packages/compaction/command-compact/locale/pt.json new file mode 100644 index 0000000000..b603c2c448 --- /dev/null +++ b/packages/compaction/command-compact/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Comando de compactação de contexto", + "description": "Deixe o usuário compactar ativamente o contexto da sessão atual por meio de um comando." + } +} diff --git a/packages/compaction/command-compact/locale/ru.json b/packages/compaction/command-compact/locale/ru.json new file mode 100644 index 0000000000..ba49dd940e --- /dev/null +++ b/packages/compaction/command-compact/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Команда сжатия контекста", + "description": "Позвольте пользователю активно сжимать контекст текущего сеанса с помощью команды." + } +} diff --git a/packages/compaction/compaction-basic/locale/de.json b/packages/compaction/compaction-basic/locale/de.json new file mode 100644 index 0000000000..bdb86bd6b9 --- /dev/null +++ b/packages/compaction/compaction-basic/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Kontextkomprimierung", + "description": "Verwenden Sie das Modell, um historische Inhalte zusammenzufassen, wenn der Kontext einen Schwellenwert erreicht." + } +} diff --git a/packages/compaction/compaction-basic/locale/es.json b/packages/compaction/compaction-basic/locale/es.json new file mode 100644 index 0000000000..39a8cfc10a --- /dev/null +++ b/packages/compaction/compaction-basic/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Compresión de contexto", + "description": "Utilice el modelo para resumir el contenido histórico cuando el contexto alcance un umbral." + } +} diff --git a/packages/compaction/compaction-basic/locale/fr.json b/packages/compaction/compaction-basic/locale/fr.json new file mode 100644 index 0000000000..eaa3823a6e --- /dev/null +++ b/packages/compaction/compaction-basic/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Compression du contexte", + "description": "Utilisez le modèle pour résumer le contenu historique lorsque le contexte atteint un seuil." + } +} diff --git a/packages/compaction/compaction-basic/locale/pt.json b/packages/compaction/compaction-basic/locale/pt.json new file mode 100644 index 0000000000..97097f9d64 --- /dev/null +++ b/packages/compaction/compaction-basic/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Compressão de contexto", + "description": "Use o modelo para resumir o conteúdo histórico quando o contexto atingir um limite." + } +} diff --git a/packages/compaction/compaction-basic/locale/ru.json b/packages/compaction/compaction-basic/locale/ru.json new file mode 100644 index 0000000000..df7199e208 --- /dev/null +++ b/packages/compaction/compaction-basic/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Сжатие контекста", + "description": "Используйте модель для обобщения исторического контента, когда контекст достигает порогового значения." + } +} diff --git a/packages/compaction/compaction-image-offload/locale/de.json b/packages/compaction/compaction-image-offload/locale/de.json new file mode 100644 index 0000000000..0044edbc12 --- /dev/null +++ b/packages/compaction/compaction-image-offload/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Historische Bilder deinstallieren", + "description": "Ersetzen Sie historische Bilder, die das Modellbildbudget überschreiten, durch Anhangsverweise und wiederholen Sie die Anfrage." + } +} diff --git a/packages/compaction/compaction-image-offload/locale/es.json b/packages/compaction/compaction-image-offload/locale/es.json new file mode 100644 index 0000000000..5e5ff39942 --- /dev/null +++ b/packages/compaction/compaction-image-offload/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Desinstalar imágenes históricas", + "description": "Reemplace las imágenes históricas que excedan el presupuesto de imagen del modelo con referencias de archivos adjuntos y vuelva a intentar la solicitud." + } +} diff --git a/packages/compaction/compaction-image-offload/locale/fr.json b/packages/compaction/compaction-image-offload/locale/fr.json new file mode 100644 index 0000000000..968f3f6f48 --- /dev/null +++ b/packages/compaction/compaction-image-offload/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Désinstaller les images historiques", + "description": "Remplacez les images historiques qui dépassent le budget de l'image du modèle par des références de pièces jointes et réessayez la demande." + } +} diff --git a/packages/compaction/compaction-image-offload/locale/pt.json b/packages/compaction/compaction-image-offload/locale/pt.json new file mode 100644 index 0000000000..cc7b7e9d26 --- /dev/null +++ b/packages/compaction/compaction-image-offload/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Desinstalar imagens históricas", + "description": "Substitua as imagens históricas que excedem o orçamento da imagem do modelo por referências de anexo e repita a solicitação." + } +} diff --git a/packages/compaction/compaction-image-offload/locale/ru.json b/packages/compaction/compaction-image-offload/locale/ru.json new file mode 100644 index 0000000000..d41d631d43 --- /dev/null +++ b/packages/compaction/compaction-image-offload/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Удалить исторические фотографии", + "description": "Замените исторические изображения, превышающие бюджет изображения модели, ссылками на вложения и повторите запрос." + } +} diff --git a/packages/compaction/compaction-tool-result-pruner/locale/de.json b/packages/compaction/compaction-tool-result-pruner/locale/de.json new file mode 100644 index 0000000000..c6be50c2bd --- /dev/null +++ b/packages/compaction/compaction-tool-result-pruner/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Optimierte Werkzeugergebnisse", + "description": "Wenn der Kontextdruck hoch ist, optimieren Sie die Ausgabe zu langer Tools und behalten Sie den ersten und letzten Inhalt bei." + } +} diff --git a/packages/compaction/compaction-tool-result-pruner/locale/es.json b/packages/compaction/compaction-tool-result-pruner/locale/es.json new file mode 100644 index 0000000000..ee6b08a577 --- /dev/null +++ b/packages/compaction/compaction-tool-result-pruner/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Resultados de herramientas optimizados", + "description": "Cuando la presión contextual es alta, optimice la salida de herramientas demasiado largas y conserve el primer y el último contenido." + } +} diff --git a/packages/compaction/compaction-tool-result-pruner/locale/fr.json b/packages/compaction/compaction-tool-result-pruner/locale/fr.json new file mode 100644 index 0000000000..193a7e6df2 --- /dev/null +++ b/packages/compaction/compaction-tool-result-pruner/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Résultats d'outils rationalisés", + "description": "Lorsque la pression contextuelle est élevée, rationalisez les sorties d’outils trop longues et conservez le premier et le dernier contenu." + } +} diff --git a/packages/compaction/compaction-tool-result-pruner/locale/pt.json b/packages/compaction/compaction-tool-result-pruner/locale/pt.json new file mode 100644 index 0000000000..2a1f248d24 --- /dev/null +++ b/packages/compaction/compaction-tool-result-pruner/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Resultados simplificados da ferramenta", + "description": "Quando a pressão contextual for alta, simplifique a produção excessivamente longa da ferramenta e retenha o primeiro e o último conteúdo." + } +} diff --git a/packages/compaction/compaction-tool-result-pruner/locale/ru.json b/packages/compaction/compaction-tool-result-pruner/locale/ru.json new file mode 100644 index 0000000000..adbc1a4561 --- /dev/null +++ b/packages/compaction/compaction-tool-result-pruner/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Оптимизированные результаты работы инструмента", + "description": "Когда контекстное давление велико, оптимизируйте слишком длинный вывод инструмента и сохраните первый и последний контент." + } +} diff --git a/packages/computer-use/computer-use/locale/de.json b/packages/computer-use/computer-use/locale/de.json new file mode 100644 index 0000000000..534384217e --- /dev/null +++ b/packages/computer-use/computer-use/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Register des Computeranbieters", + "description": "Registrieren Sie Computer Use-Anbieter namentlich, mit einem Anbieter pro Name." + } +} diff --git a/packages/computer-use/computer-use/locale/es.json b/packages/computer-use/computer-use/locale/es.json new file mode 100644 index 0000000000..88c207f51e --- /dev/null +++ b/packages/computer-use/computer-use/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Registro de proveedores de informática", + "description": "Registre proveedores Computer Use por nombre, con un proveedor por nombre." + } +} diff --git a/packages/computer-use/computer-use/locale/fr.json b/packages/computer-use/computer-use/locale/fr.json new file mode 100644 index 0000000000..5cc8937b4e --- /dev/null +++ b/packages/computer-use/computer-use/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Registre des fournisseurs d'ordinateurs", + "description": "Enregistrez les fournisseurs Computer Use par nom, avec un fournisseur par nom." + } +} diff --git a/packages/computer-use/computer-use/locale/pt.json b/packages/computer-use/computer-use/locale/pt.json new file mode 100644 index 0000000000..94376c80e2 --- /dev/null +++ b/packages/computer-use/computer-use/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Registro de provedor de computador", + "description": "Registre Computer Use provedores por nome, com um provedor por nome." + } +} diff --git a/packages/computer-use/computer-use/locale/ru.json b/packages/computer-use/computer-use/locale/ru.json new file mode 100644 index 0000000000..4c55c4e10c --- /dev/null +++ b/packages/computer-use/computer-use/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Реестр поставщиков компьютеров", + "description": "Зарегистрируйте Computer Use поставщиков по имени, по одному поставщику на имя." + } +} diff --git a/packages/context/agent-instructions/locale/de.json b/packages/context/agent-instructions/locale/de.json new file mode 100644 index 0000000000..7a6e811cce --- /dev/null +++ b/packages/context/agent-instructions/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Laden des Arbeitsbereichsbefehls", + "description": "Lesen Sie AGENTS.md, CLAUDE.md und andere Dateien, um Arbeitsbereichsregeln für AI bereitzustellen." + } +} diff --git a/packages/context/agent-instructions/locale/es.json b/packages/context/agent-instructions/locale/es.json new file mode 100644 index 0000000000..a713e4cf56 --- /dev/null +++ b/packages/context/agent-instructions/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Carga de comandos del espacio de trabajo", + "description": "Lea AGENTS.md, CLAUDE.md y otros archivos para proporcionar reglas de espacio de trabajo para la IA." + } +} diff --git a/packages/context/agent-instructions/locale/fr.json b/packages/context/agent-instructions/locale/fr.json new file mode 100644 index 0000000000..44765774e5 --- /dev/null +++ b/packages/context/agent-instructions/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Chargement des commandes de l'espace de travail", + "description": "Lisez AGENTS.md, CLAUDE.md et d'autres fichiers pour fournir des règles d'espace de travail pour l'IA." + } +} diff --git a/packages/context/agent-instructions/locale/pt.json b/packages/context/agent-instructions/locale/pt.json new file mode 100644 index 0000000000..91f0a68189 --- /dev/null +++ b/packages/context/agent-instructions/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Carregamento de comando do espaço de trabalho", + "description": "Leia AGENTS.md, CLAUDE.md e outros arquivos para fornecer regras de espaço de trabalho para IA." + } +} diff --git a/packages/context/agent-instructions/locale/ru.json b/packages/context/agent-instructions/locale/ru.json new file mode 100644 index 0000000000..f8934491ee --- /dev/null +++ b/packages/context/agent-instructions/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Загрузка команд рабочей области", + "description": "Прочтите AGENTS.md, CLAUDE.md и другие файлы, чтобы определить правила рабочей области для ИИ." + } +} diff --git a/packages/context/file-reference-local/locale/de.json b/packages/context/file-reference-local/locale/de.json new file mode 100644 index 0000000000..701f27a496 --- /dev/null +++ b/packages/context/file-reference-local/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "lokale Dateireferenz", + "description": "Bietet Such- und Referenzfunktionen für lokale Dateien." + } +} diff --git a/packages/context/file-reference-local/locale/es.json b/packages/context/file-reference-local/locale/es.json new file mode 100644 index 0000000000..da17d706e8 --- /dev/null +++ b/packages/context/file-reference-local/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "referencia de archivo local", + "description": "Proporciona capacidades de búsqueda y referencia para archivos locales." + } +} diff --git a/packages/context/file-reference-local/locale/fr.json b/packages/context/file-reference-local/locale/fr.json new file mode 100644 index 0000000000..1103738940 --- /dev/null +++ b/packages/context/file-reference-local/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "référence de fichier local", + "description": "Fournit des capacités de recherche et de référence pour les fichiers locaux." + } +} diff --git a/packages/context/file-reference-local/locale/pt.json b/packages/context/file-reference-local/locale/pt.json new file mode 100644 index 0000000000..d9686e4880 --- /dev/null +++ b/packages/context/file-reference-local/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "referência de arquivo local", + "description": "Fornece recursos de pesquisa e referência para arquivos locais." + } +} diff --git a/packages/context/file-reference-local/locale/ru.json b/packages/context/file-reference-local/locale/ru.json new file mode 100644 index 0000000000..a182e99097 --- /dev/null +++ b/packages/context/file-reference-local/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "ссылка на локальный файл", + "description": "Предоставляет возможности поиска и ссылки на локальные файлы." + } +} diff --git a/packages/context/harness-dev-context/locale/de.json b/packages/context/harness-dev-context/locale/de.json new file mode 100644 index 0000000000..e34c96239d --- /dev/null +++ b/packages/context/harness-dev-context/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Nutzen Sie den Entwicklungskontext", + "description": "Geben Sie dem Modell das Harness-Quellverzeichnis und die Web-URL, ohne die Systemeingabeaufforderung zu ändern." + } +} diff --git a/packages/context/harness-dev-context/locale/es.json b/packages/context/harness-dev-context/locale/es.json new file mode 100644 index 0000000000..3f120fb176 --- /dev/null +++ b/packages/context/harness-dev-context/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Aprovechar el contexto de desarrollo", + "description": "Proporcione al modelo el directorio de origen del arnés y la URL web sin cambiar el mensaje del sistema." + } +} diff --git a/packages/context/harness-dev-context/locale/fr.json b/packages/context/harness-dev-context/locale/fr.json new file mode 100644 index 0000000000..102926680c --- /dev/null +++ b/packages/context/harness-dev-context/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Exploiter le contexte de développement", + "description": "Donnez au modèle le répertoire source Harness et l'URL Web sans modifier son invite système." + } +} diff --git a/packages/context/harness-dev-context/locale/pt.json b/packages/context/harness-dev-context/locale/pt.json new file mode 100644 index 0000000000..2b9141123a --- /dev/null +++ b/packages/context/harness-dev-context/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Aproveite o contexto de desenvolvimento", + "description": "Forneça ao modelo o diretório de origem do Harness e o URL da Web sem alterar o prompt do sistema." + } +} diff --git a/packages/context/harness-dev-context/locale/ru.json b/packages/context/harness-dev-context/locale/ru.json new file mode 100644 index 0000000000..001c0b1251 --- /dev/null +++ b/packages/context/harness-dev-context/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Использование контекста развития", + "description": "Дайте модели исходный каталог Harness и URL-адрес веб-сайта, не изменяя системное приглашение." + } +} diff --git a/packages/context/session-reference/locale/de.json b/packages/context/session-reference/locale/de.json new file mode 100644 index 0000000000..44e0a16cb4 --- /dev/null +++ b/packages/context/session-reference/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sitzungsübergreifende Referenzen", + "description": "Stellt der KI einen schreibgeschützten Schnappschuss des Inhalts anderer Sitzungen zur Verfügung." + } +} diff --git a/packages/context/session-reference/locale/es.json b/packages/context/session-reference/locale/es.json new file mode 100644 index 0000000000..935dfcbcb3 --- /dev/null +++ b/packages/context/session-reference/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Referencias entre sesiones", + "description": "Proporciona a la IA una instantánea de solo lectura del contenido de otras sesiones." + } +} diff --git a/packages/context/session-reference/locale/fr.json b/packages/context/session-reference/locale/fr.json new file mode 100644 index 0000000000..b47bf36de2 --- /dev/null +++ b/packages/context/session-reference/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Références inter-sessions", + "description": "Fournit à l’IA un instantané en lecture seule du contenu des autres sessions." + } +} diff --git a/packages/context/session-reference/locale/pt.json b/packages/context/session-reference/locale/pt.json new file mode 100644 index 0000000000..613135decf --- /dev/null +++ b/packages/context/session-reference/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Referências entre sessões", + "description": "Fornece à IA um instantâneo somente leitura do conteúdo de outras sessões." + } +} diff --git a/packages/context/session-reference/locale/ru.json b/packages/context/session-reference/locale/ru.json new file mode 100644 index 0000000000..3ade885416 --- /dev/null +++ b/packages/context/session-reference/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Межсессионные ссылки", + "description": "Предоставляет ИИ снимок содержимого других сеансов, доступный только для чтения." + } +} diff --git a/packages/context/time-context/locale/de.json b/packages/context/time-context/locale/de.json new file mode 100644 index 0000000000..d7df3e00ce --- /dev/null +++ b/packages/context/time-context/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Zeitbewusstsein", + "description": "Teilt dem Modell bei jedem Schritt die aktuelle Uhrzeit, die Zeitzone des Browsers und die Zeit seit der vorherigen Nachricht mit." + } +} diff --git a/packages/context/time-context/locale/es.json b/packages/context/time-context/locale/es.json new file mode 100644 index 0000000000..281275e919 --- /dev/null +++ b/packages/context/time-context/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Conciencia del tiempo", + "description": "Le indica al modelo la hora actual, la zona horaria del navegador y la hora desde el mensaje anterior en cada paso." + } +} diff --git a/packages/context/time-context/locale/fr.json b/packages/context/time-context/locale/fr.json new file mode 100644 index 0000000000..26abbe6628 --- /dev/null +++ b/packages/context/time-context/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Conscience du temps", + "description": "Indique au modèle l'heure actuelle, le fuseau horaire du navigateur et l'heure écoulée depuis le message précédent à chaque étape." + } +} diff --git a/packages/context/time-context/locale/pt.json b/packages/context/time-context/locale/pt.json new file mode 100644 index 0000000000..06d48256e2 --- /dev/null +++ b/packages/context/time-context/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Consciência do tempo", + "description": "Informa ao modelo a hora atual, o fuso horário do navegador e o tempo desde a mensagem anterior em cada etapa." + } +} diff --git a/packages/context/time-context/locale/ru.json b/packages/context/time-context/locale/ru.json new file mode 100644 index 0000000000..8247654351 --- /dev/null +++ b/packages/context/time-context/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Осведомленность о времени", + "description": "На каждом шаге сообщает модели текущее время, часовой пояс браузера и время с момента предыдущего сообщения." + } +} diff --git a/packages/context/tmux-context/locale/de.json b/packages/context/tmux-context/locale/de.json new file mode 100644 index 0000000000..0d181e2692 --- /dev/null +++ b/packages/context/tmux-context/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "tmux-Kontext", + "description": "Speichern Sie bei Bedarf die tmux-Bereichs- und Fensterpositionen für jeden Schritt." + } +} diff --git a/packages/context/tmux-context/locale/es.json b/packages/context/tmux-context/locale/es.json new file mode 100644 index 0000000000..93664d1b33 --- /dev/null +++ b/packages/context/tmux-context/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "contexto tmux", + "description": "Guarde las ubicaciones de las ventanas y paneles tmux para cada paso cuando sea necesario." + } +} diff --git a/packages/context/tmux-context/locale/fr.json b/packages/context/tmux-context/locale/fr.json new file mode 100644 index 0000000000..7791998a86 --- /dev/null +++ b/packages/context/tmux-context/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "contexte tmux", + "description": "Enregistrez les emplacements du volet tmux et des fenêtres pour chaque étape si nécessaire." + } +} diff --git a/packages/context/tmux-context/locale/pt.json b/packages/context/tmux-context/locale/pt.json new file mode 100644 index 0000000000..5829153e8e --- /dev/null +++ b/packages/context/tmux-context/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "contexto tmux", + "description": "Salve os locais do painel e da janela do tmux para cada etapa, quando necessário." + } +} diff --git a/packages/context/tmux-context/locale/ru.json b/packages/context/tmux-context/locale/ru.json new file mode 100644 index 0000000000..8a161df7a6 --- /dev/null +++ b/packages/context/tmux-context/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "контекст tmux", + "description": "При необходимости сохраняйте расположение панели tmux и окон для каждого шага." + } +} diff --git a/packages/core/agent-default-model/locale/de.json b/packages/core/agent-default-model/locale/de.json new file mode 100644 index 0000000000..b79c700564 --- /dev/null +++ b/packages/core/agent-default-model/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Standardmodell", + "description": "Bietet eine Standardmodellauswahl für neue Agenten." + } +} diff --git a/packages/core/agent-default-model/locale/es.json b/packages/core/agent-default-model/locale/es.json new file mode 100644 index 0000000000..af4c8a86c0 --- /dev/null +++ b/packages/core/agent-default-model/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Modelo predeterminado", + "description": "Proporciona selección de modelo predeterminado para nuevos agentes." + } +} diff --git a/packages/core/agent-default-model/locale/fr.json b/packages/core/agent-default-model/locale/fr.json new file mode 100644 index 0000000000..2159533905 --- /dev/null +++ b/packages/core/agent-default-model/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Modèle par défaut", + "description": "Fournit une sélection de modèle par défaut pour les nouveaux agents." + } +} diff --git a/packages/core/agent-default-model/locale/pt.json b/packages/core/agent-default-model/locale/pt.json new file mode 100644 index 0000000000..12d140156d --- /dev/null +++ b/packages/core/agent-default-model/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Modelo padrão", + "description": "Fornece seleção de modelo padrão para novos agentes." + } +} diff --git a/packages/core/agent-default-model/locale/ru.json b/packages/core/agent-default-model/locale/ru.json new file mode 100644 index 0000000000..cc24d5b144 --- /dev/null +++ b/packages/core/agent-default-model/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Модель по умолчанию", + "description": "Обеспечивает выбор модели по умолчанию для новых агентов." + } +} diff --git a/packages/core/agent-loop/locale/de.json b/packages/core/agent-loop/locale/de.json new file mode 100644 index 0000000000..bb62da6911 --- /dev/null +++ b/packages/core/agent-loop/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Agenten-Ausführungsschleife", + "description": "Koordinieren Sie Modellanfragen, Toolaufrufe und Folgeschritte, um Agentenaufgaben voranzutreiben." + } +} diff --git a/packages/core/agent-loop/locale/es.json b/packages/core/agent-loop/locale/es.json new file mode 100644 index 0000000000..4433ae5c9f --- /dev/null +++ b/packages/core/agent-loop/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Bucle de ejecución del agente", + "description": "Coordine solicitudes de modelos, invocaciones de herramientas y pasos de seguimiento para avanzar en las tareas de los agentes." + } +} diff --git a/packages/core/agent-loop/locale/fr.json b/packages/core/agent-loop/locale/fr.json new file mode 100644 index 0000000000..2a2bd9cfe1 --- /dev/null +++ b/packages/core/agent-loop/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Boucle d'exécution de l'agent", + "description": "Coordonnez les demandes de modèles, les appels d’outils et les étapes de suivi pour faire avancer les tâches des agents." + } +} diff --git a/packages/core/agent-loop/locale/pt.json b/packages/core/agent-loop/locale/pt.json new file mode 100644 index 0000000000..94a4212d20 --- /dev/null +++ b/packages/core/agent-loop/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Loop de execução do agente", + "description": "Coordene solicitações de modelo, invocações de ferramentas e etapas de acompanhamento para avançar nas tarefas do agente." + } +} diff --git a/packages/core/agent-loop/locale/ru.json b/packages/core/agent-loop/locale/ru.json new file mode 100644 index 0000000000..3d9658aa58 --- /dev/null +++ b/packages/core/agent-loop/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Цикл выполнения агента", + "description": "Координируйте запросы моделей, вызовы инструментов и последующие шаги для выполнения задач агента." + } +} diff --git a/packages/core/agent-tool-presentation/locale/de.json b/packages/core/agent-tool-presentation/locale/de.json new file mode 100644 index 0000000000..72b3a37049 --- /dev/null +++ b/packages/core/agent-tool-presentation/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Tool-Aufrufmethode", + "description": "Wählen Sie den Agent aus, um das Tool über native Tools oder PTC-Code aufzurufen." + } +} diff --git a/packages/core/agent-tool-presentation/locale/es.json b/packages/core/agent-tool-presentation/locale/es.json new file mode 100644 index 0000000000..0d32a6fe21 --- /dev/null +++ b/packages/core/agent-tool-presentation/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Método de llamada de herramienta", + "description": "Seleccione el agente para invocar la herramienta a través de herramientas nativas o código PTC." + } +} diff --git a/packages/core/agent-tool-presentation/locale/fr.json b/packages/core/agent-tool-presentation/locale/fr.json new file mode 100644 index 0000000000..545401ae5f --- /dev/null +++ b/packages/core/agent-tool-presentation/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Méthode d'appel d'outil", + "description": "Sélectionnez l'agent pour appeler l'outil via des outils natifs ou du code PTC." + } +} diff --git a/packages/core/agent-tool-presentation/locale/pt.json b/packages/core/agent-tool-presentation/locale/pt.json new file mode 100644 index 0000000000..effdf61daa --- /dev/null +++ b/packages/core/agent-tool-presentation/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Método de chamada de ferramenta", + "description": "Selecione o agente para invocar a ferramenta por meio de ferramentas nativas ou código PTC." + } +} diff --git a/packages/core/agent-tool-presentation/locale/ru.json b/packages/core/agent-tool-presentation/locale/ru.json new file mode 100644 index 0000000000..bb0345c60a --- /dev/null +++ b/packages/core/agent-tool-presentation/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Метод вызова инструмента", + "description": "Выберите агент для вызова инструмента с помощью собственных инструментов или кода PTC." + } +} diff --git a/packages/core/agent/locale/de.json b/packages/core/agent/locale/de.json new file mode 100644 index 0000000000..ff00c84c39 --- /dev/null +++ b/packages/core/agent/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Agent", + "description": "Verwalten Sie Agenteninstanzen sowie deren laufenden Kontext und Ereignisse." + } +} diff --git a/packages/core/agent/locale/es.json b/packages/core/agent/locale/es.json new file mode 100644 index 0000000000..bf543e11aa --- /dev/null +++ b/packages/core/agent/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "agente", + "description": "Administre instancias de agentes y su contexto y eventos de ejecución." + } +} diff --git a/packages/core/agent/locale/fr.json b/packages/core/agent/locale/fr.json new file mode 100644 index 0000000000..a3dc7de26e --- /dev/null +++ b/packages/core/agent/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "agent", + "description": "Gérez les instances d'agent, leur contexte d'exécution et leurs événements." + } +} diff --git a/packages/core/agent/locale/pt.json b/packages/core/agent/locale/pt.json new file mode 100644 index 0000000000..c3eb79d40a --- /dev/null +++ b/packages/core/agent/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "agente", + "description": "Gerencie instâncias de agentes e seus contextos e eventos em execução." + } +} diff --git a/packages/core/agent/locale/ru.json b/packages/core/agent/locale/ru.json new file mode 100644 index 0000000000..48dfc8eed3 --- /dev/null +++ b/packages/core/agent/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "агент", + "description": "Управляйте экземплярами агентов, их рабочим контекстом и событиями." + } +} diff --git a/packages/core/session/locale/de.json b/packages/core/session/locale/de.json new file mode 100644 index 0000000000..52c3407da6 --- /dev/null +++ b/packages/core/session/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sitzung", + "description": "Protokollieren Sie Nachrichten, Toolaufrufe und führen Sie Ereignisse in einer Sitzung aus." + } +} diff --git a/packages/core/session/locale/es.json b/packages/core/session/locale/es.json new file mode 100644 index 0000000000..e3f9174905 --- /dev/null +++ b/packages/core/session/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "sesión", + "description": "Registre mensajes, llamadas de herramientas y ejecute eventos en una sesión." + } +} diff --git a/packages/core/session/locale/fr.json b/packages/core/session/locale/fr.json new file mode 100644 index 0000000000..d2b0866dc3 --- /dev/null +++ b/packages/core/session/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "séance", + "description": "Enregistrez les messages, les appels d'outils et exécutez des événements dans une session." + } +} diff --git a/packages/core/session/locale/pt.json b/packages/core/session/locale/pt.json new file mode 100644 index 0000000000..6499804abc --- /dev/null +++ b/packages/core/session/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "sessão", + "description": "Registrar mensagens, chamadas de ferramentas e executar eventos em uma sessão." + } +} diff --git a/packages/core/session/locale/ru.json b/packages/core/session/locale/ru.json new file mode 100644 index 0000000000..ea1cc45b11 --- /dev/null +++ b/packages/core/session/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "сессия", + "description": "Регистрируйте сообщения, вызовы инструментов и запускайте события в сеансе." + } +} diff --git a/packages/core/system-prompt/locale/de.json b/packages/core/system-prompt/locale/de.json new file mode 100644 index 0000000000..f0e712b2af --- /dev/null +++ b/packages/core/system-prompt/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Systemaufforderungswortzusammenstellung", + "description": "Fassen Sie den Wortinhalt der Systemaufforderung zusammen, der von jedem Plug-In bereitgestellt wird." + } +} diff --git a/packages/core/system-prompt/locale/es.json b/packages/core/system-prompt/locale/es.json new file mode 100644 index 0000000000..ae225def38 --- /dev/null +++ b/packages/core/system-prompt/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Conjunto de palabras del mensaje del sistema", + "description": "Resuma el contenido de las palabras del mensaje del sistema proporcionado por cada complemento." + } +} diff --git a/packages/core/system-prompt/locale/fr.json b/packages/core/system-prompt/locale/fr.json new file mode 100644 index 0000000000..d00e251ab5 --- /dev/null +++ b/packages/core/system-prompt/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Assemblage de mots d’invite système", + "description": "Résumez le contenu des mots d’invite système fournis par chaque plug-in." + } +} diff --git a/packages/core/system-prompt/locale/pt.json b/packages/core/system-prompt/locale/pt.json new file mode 100644 index 0000000000..9b6b4cbed8 --- /dev/null +++ b/packages/core/system-prompt/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Montagem de palavras de prompt do sistema", + "description": "Resuma o conteúdo do prompt do sistema fornecido por cada plug-in." + } +} diff --git a/packages/core/system-prompt/locale/ru.json b/packages/core/system-prompt/locale/ru.json new file mode 100644 index 0000000000..fd6b109101 --- /dev/null +++ b/packages/core/system-prompt/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Сборка слов системной подсказки", + "description": "Обобщите содержание слов системной подсказки, предоставляемое каждым подключаемым модулем." + } +} diff --git a/packages/core/tool-executor-native/locale/de.json b/packages/core/tool-executor-native/locale/de.json new file mode 100644 index 0000000000..1667c6d05a --- /dev/null +++ b/packages/core/tool-executor-native/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Native Tool-Ausführung", + "description": "Führt Modell-Tool-Aufrufe direkt aus." + } +} diff --git a/packages/core/tool-executor-native/locale/es.json b/packages/core/tool-executor-native/locale/es.json new file mode 100644 index 0000000000..88ee9cab99 --- /dev/null +++ b/packages/core/tool-executor-native/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ejecución de herramientas nativas", + "description": "Ejecuta llamadas a herramientas de modelo directamente." + } +} diff --git a/packages/core/tool-executor-native/locale/fr.json b/packages/core/tool-executor-native/locale/fr.json new file mode 100644 index 0000000000..57b5c6fabc --- /dev/null +++ b/packages/core/tool-executor-native/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Exécution d'outils natifs", + "description": "Exécute directement les appels de l’outil de modèle." + } +} diff --git a/packages/core/tool-executor-native/locale/pt.json b/packages/core/tool-executor-native/locale/pt.json new file mode 100644 index 0000000000..7830a29c8c --- /dev/null +++ b/packages/core/tool-executor-native/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Execução de ferramenta nativa", + "description": "Executa chamadas de ferramenta de modelo diretamente." + } +} diff --git a/packages/core/tool-executor-native/locale/ru.json b/packages/core/tool-executor-native/locale/ru.json new file mode 100644 index 0000000000..c8d00a0149 --- /dev/null +++ b/packages/core/tool-executor-native/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Исполнение собственного инструмента", + "description": "Выполняет вызовы инструментов модели напрямую." + } +} diff --git a/packages/core/tool-executor-ptc/locale/de.json b/packages/core/tool-executor-ptc/locale/de.json new file mode 100644 index 0000000000..9e1a4e6a95 --- /dev/null +++ b/packages/core/tool-executor-ptc/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "PTC Werkzeugausführung", + "description": "Führt Tools über run_code-Programme aus und generiert SDK-Bindungen." + } +} diff --git a/packages/core/tool-executor-ptc/locale/es.json b/packages/core/tool-executor-ptc/locale/es.json new file mode 100644 index 0000000000..e21cbb9f8b --- /dev/null +++ b/packages/core/tool-executor-ptc/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ejecución de la herramienta PTC", + "description": "Ejecuta herramientas a través de programas run_code y genera enlaces SDK." + } +} diff --git a/packages/core/tool-executor-ptc/locale/fr.json b/packages/core/tool-executor-ptc/locale/fr.json new file mode 100644 index 0000000000..69d02cea40 --- /dev/null +++ b/packages/core/tool-executor-ptc/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Exécution de l'outil PTC", + "description": "Exécute des outils via des programmes run_code et génère des liaisons SDK." + } +} diff --git a/packages/core/tool-executor-ptc/locale/pt.json b/packages/core/tool-executor-ptc/locale/pt.json new file mode 100644 index 0000000000..5ae360ee49 --- /dev/null +++ b/packages/core/tool-executor-ptc/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "PTC execução da ferramenta", + "description": "Executa ferramentas por meio de programas run_code e gera vinculações SDK." + } +} diff --git a/packages/core/tool-executor-ptc/locale/ru.json b/packages/core/tool-executor-ptc/locale/ru.json new file mode 100644 index 0000000000..29d0df4c58 --- /dev/null +++ b/packages/core/tool-executor-ptc/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "PTC выполнение инструмента", + "description": "Выполняет инструменты через программы run_code и генерирует привязки SDK." + } +} diff --git a/packages/core/tools/locale/de.json b/packages/core/tools/locale/de.json new file mode 100644 index 0000000000..3af3606a63 --- /dev/null +++ b/packages/core/tools/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Werkzeuge", + "description": "Verwalten Sie verfügbare Tools und deren Aufrufausführungsprozesse." + } +} diff --git a/packages/core/tools/locale/es.json b/packages/core/tools/locale/es.json new file mode 100644 index 0000000000..59ba250932 --- /dev/null +++ b/packages/core/tools/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "herramientas", + "description": "Gestionar las herramientas disponibles y sus procesos de ejecución de invocaciones." + } +} diff --git a/packages/core/tools/locale/fr.json b/packages/core/tools/locale/fr.json new file mode 100644 index 0000000000..2c63804f7d --- /dev/null +++ b/packages/core/tools/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "outils", + "description": "Gérez les outils disponibles et leurs processus d’exécution d’appels." + } +} diff --git a/packages/core/tools/locale/pt.json b/packages/core/tools/locale/pt.json new file mode 100644 index 0000000000..3621e8e5da --- /dev/null +++ b/packages/core/tools/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "ferramentas", + "description": "Gerencie as ferramentas disponíveis e seus processos de execução de invocação." + } +} diff --git a/packages/core/tools/locale/ru.json b/packages/core/tools/locale/ru.json new file mode 100644 index 0000000000..a337612e5e --- /dev/null +++ b/packages/core/tools/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "инструменты", + "description": "Управляйте доступными инструментами и процессами выполнения их вызовов." + } +} diff --git a/packages/credentials/authorization/locale/de.json b/packages/credentials/authorization/locale/de.json new file mode 100644 index 0000000000..15d3e38ba4 --- /dev/null +++ b/packages/credentials/authorization/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Autorisierung", + "description": "Organisationen verlangen die Beteiligung des Benutzers am Anmelde- und Anmeldedaten-Autorisierungsprozess." + } +} diff --git a/packages/credentials/authorization/locale/es.json b/packages/credentials/authorization/locale/es.json new file mode 100644 index 0000000000..e0d2992b5e --- /dev/null +++ b/packages/credentials/authorization/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "autorización", + "description": "Las organizaciones requieren la participación del usuario en el proceso de inicio de sesión y autorización de credenciales." + } +} diff --git a/packages/credentials/authorization/locale/fr.json b/packages/credentials/authorization/locale/fr.json new file mode 100644 index 0000000000..2e4fc50080 --- /dev/null +++ b/packages/credentials/authorization/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "autorisation", + "description": "Les organisations exigent la participation des utilisateurs au processus de connexion et d’autorisation des informations d’identification." + } +} diff --git a/packages/credentials/authorization/locale/pt.json b/packages/credentials/authorization/locale/pt.json new file mode 100644 index 0000000000..c465157682 --- /dev/null +++ b/packages/credentials/authorization/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "autorização", + "description": "As organizações exigem a participação do usuário no processo de login e autorização de credenciais." + } +} diff --git a/packages/credentials/authorization/locale/ru.json b/packages/credentials/authorization/locale/ru.json new file mode 100644 index 0000000000..6442c5ed91 --- /dev/null +++ b/packages/credentials/authorization/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "авторизация", + "description": "Организации требуют участия пользователя в процессе входа в систему и авторизации учетных данных." + } +} diff --git a/packages/credentials/credentials-local/locale/de.json b/packages/credentials/credentials-local/locale/de.json new file mode 100644 index 0000000000..0d5f4fc5fe --- /dev/null +++ b/packages/credentials/credentials-local/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Lokaler Speicher für Anmeldeinformationen", + "description": "Speichern Sie Anmeldeinformationen wie den Schlüssel API und lesen Sie Umgebungsvariablen und lokale Anmeldeinformationsdateien in der Reihenfolge ihrer Priorität." + } +} diff --git a/packages/credentials/credentials-local/locale/es.json b/packages/credentials/credentials-local/locale/es.json new file mode 100644 index 0000000000..4d7041d7d6 --- /dev/null +++ b/packages/credentials/credentials-local/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Almacenamiento de credenciales locales", + "description": "Guarde credenciales como la clave API y lea las variables de entorno y los archivos de credenciales locales en orden de prioridad." + } +} diff --git a/packages/credentials/credentials-local/locale/fr.json b/packages/credentials/credentials-local/locale/fr.json new file mode 100644 index 0000000000..19cd98d258 --- /dev/null +++ b/packages/credentials/credentials-local/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Stockage local des identifiants", + "description": "Enregistrez les informations d'identification telles que la clé API et lisez les variables d'environnement et les fichiers d'informations d'identification locales par ordre de priorité." + } +} diff --git a/packages/credentials/credentials-local/locale/pt.json b/packages/credentials/credentials-local/locale/pt.json new file mode 100644 index 0000000000..fcd1bd9a51 --- /dev/null +++ b/packages/credentials/credentials-local/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Armazenamento de credenciais locais", + "description": "Salve credenciais como a chave API e leia variáveis de ambiente e arquivos de credenciais locais em ordem de prioridade." + } +} diff --git a/packages/credentials/credentials-local/locale/ru.json b/packages/credentials/credentials-local/locale/ru.json new file mode 100644 index 0000000000..5f4102830a --- /dev/null +++ b/packages/credentials/credentials-local/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Локальное хранилище учетных данных", + "description": "Сохраните учетные данные, такие как ключ API, и прочитайте переменные среды и локальные файлы учетных данных в порядке приоритета." + } +} diff --git a/packages/credentials/deepseek-account-platform/locale/de.json b/packages/credentials/deepseek-account-platform/locale/de.json new file mode 100644 index 0000000000..edd924d206 --- /dev/null +++ b/packages/credentials/deepseek-account-platform/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Kontoanmeldung", + "description": "Schließen Sie die Anmeldeautorisierung für das DeepSeek-Konto über den Browser ab." + } +} diff --git a/packages/credentials/deepseek-account-platform/locale/es.json b/packages/credentials/deepseek-account-platform/locale/es.json new file mode 100644 index 0000000000..e5ce28e7cd --- /dev/null +++ b/packages/credentials/deepseek-account-platform/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek inicio de sesión de cuenta", + "description": "Complete la autorización de inicio de sesión de la cuenta DeepSeek a través del navegador." + } +} diff --git a/packages/credentials/deepseek-account-platform/locale/fr.json b/packages/credentials/deepseek-account-platform/locale/fr.json new file mode 100644 index 0000000000..e472dc67ec --- /dev/null +++ b/packages/credentials/deepseek-account-platform/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek connexion au compte", + "description": "Complétez l'autorisation de connexion au compte DeepSeek via le navigateur." + } +} diff --git a/packages/credentials/deepseek-account-platform/locale/pt.json b/packages/credentials/deepseek-account-platform/locale/pt.json new file mode 100644 index 0000000000..2653ad2013 --- /dev/null +++ b/packages/credentials/deepseek-account-platform/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek login da conta", + "description": "Conclua a autorização de login da conta DeepSeek através do navegador." + } +} diff --git a/packages/credentials/deepseek-account-platform/locale/ru.json b/packages/credentials/deepseek-account-platform/locale/ru.json new file mode 100644 index 0000000000..3d5fff9ff8 --- /dev/null +++ b/packages/credentials/deepseek-account-platform/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek вход в аккаунт", + "description": "Завершите авторизацию входа в учетную запись DeepSeek через браузер." + } +} diff --git a/packages/deliverables/deliverable-file-references/locale/de.json b/packages/deliverables/deliverable-file-references/locale/de.json new file mode 100644 index 0000000000..aac9344c51 --- /dev/null +++ b/packages/deliverables/deliverable-file-references/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Lieferbare Dateireferenzen", + "description": "Stellen Sie gemeinsame Modellanleitungen für Dateiverknüpfungen und Ergebnisse in allen Anwendungsumgebungen bereit." + } +} diff --git a/packages/deliverables/deliverable-file-references/locale/es.json b/packages/deliverables/deliverable-file-references/locale/es.json new file mode 100644 index 0000000000..9b8bd45ba8 --- /dev/null +++ b/packages/deliverables/deliverable-file-references/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Referencias de archivos entregables", + "description": "Proporcione orientación de modelo compartido para enlaces de archivos y entregables en entornos de aplicaciones." + } +} diff --git a/packages/deliverables/deliverable-file-references/locale/fr.json b/packages/deliverables/deliverable-file-references/locale/fr.json new file mode 100644 index 0000000000..75ed3b038e --- /dev/null +++ b/packages/deliverables/deliverable-file-references/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Références des fichiers livrables", + "description": "Fournissez des conseils de modèle partagé pour les liens de fichiers et les livrables dans les environnements d’application." + } +} diff --git a/packages/deliverables/deliverable-file-references/locale/pt.json b/packages/deliverables/deliverable-file-references/locale/pt.json new file mode 100644 index 0000000000..73c6f06736 --- /dev/null +++ b/packages/deliverables/deliverable-file-references/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Referências de arquivos entregáveis", + "description": "Forneça orientação de modelo compartilhado para links de arquivos e resultados em ambientes de aplicativos." + } +} diff --git a/packages/deliverables/deliverable-file-references/locale/ru.json b/packages/deliverables/deliverable-file-references/locale/ru.json new file mode 100644 index 0000000000..39494e5868 --- /dev/null +++ b/packages/deliverables/deliverable-file-references/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ссылки на доставляемые файлы", + "description": "Предоставьте руководство по общей модели для ссылок на файлы и результатов в различных средах приложений." + } +} diff --git a/packages/deliverables/tool-present/locale/de.json b/packages/deliverables/tool-present/locale/de.json new file mode 100644 index 0000000000..9c4095a246 --- /dev/null +++ b/packages/deliverables/tool-present/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Tool zur Dateiübermittlung", + "description": "Lassen Sie die KI in dieser Runde Arbeitsbereichsdateien deutlich als zu erbringende Leistungen kennzeichnen." + } +} diff --git a/packages/deliverables/tool-present/locale/es.json b/packages/deliverables/tool-present/locale/es.json new file mode 100644 index 0000000000..1b99d7083b --- /dev/null +++ b/packages/deliverables/tool-present/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "herramienta de entrega de archivos", + "description": "Dejemos que la IA marque claramente los archivos del espacio de trabajo como entregables en esta ronda." + } +} diff --git a/packages/deliverables/tool-present/locale/fr.json b/packages/deliverables/tool-present/locale/fr.json new file mode 100644 index 0000000000..59373241a1 --- /dev/null +++ b/packages/deliverables/tool-present/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outil de livraison de fichiers", + "description": "Laissez l’IA marquer clairement les fichiers de l’espace de travail comme livrables ce cycle-ci." + } +} diff --git a/packages/deliverables/tool-present/locale/pt.json b/packages/deliverables/tool-present/locale/pt.json new file mode 100644 index 0000000000..bce97776d9 --- /dev/null +++ b/packages/deliverables/tool-present/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramenta de entrega de arquivos", + "description": "Deixe a IA marcar claramente os arquivos do espaço de trabalho como resultados nesta rodada." + } +} diff --git a/packages/deliverables/tool-present/locale/ru.json b/packages/deliverables/tool-present/locale/ru.json new file mode 100644 index 0000000000..d6da55fd7a --- /dev/null +++ b/packages/deliverables/tool-present/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Инструмент доставки файлов", + "description": "Пусть в этом раунде ИИ четко отметит файлы рабочей области как результаты." + } +} diff --git a/packages/deliverables/workspace-changes/locale/de.json b/packages/deliverables/workspace-changes/locale/de.json new file mode 100644 index 0000000000..53d0359650 --- /dev/null +++ b/packages/deliverables/workspace-changes/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Änderungsverlauf des Arbeitsbereichs", + "description": "Zeichnen Sie Dateiänderungen in jeder Aufgabenrunde auf, um Datei für Datei zu vergleichen." + } +} diff --git a/packages/deliverables/workspace-changes/locale/es.json b/packages/deliverables/workspace-changes/locale/es.json new file mode 100644 index 0000000000..d09428c212 --- /dev/null +++ b/packages/deliverables/workspace-changes/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Historial de cambios en el espacio de trabajo", + "description": "Registre los cambios de archivos en cada ronda de tareas para comparar archivo por archivo." + } +} diff --git a/packages/deliverables/workspace-changes/locale/fr.json b/packages/deliverables/workspace-changes/locale/fr.json new file mode 100644 index 0000000000..d44c231a7a --- /dev/null +++ b/packages/deliverables/workspace-changes/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Historique des modifications de l'espace de travail", + "description": "Enregistrez les modifications apportées aux fichiers à chaque série de tâches pour une comparaison fichier par fichier." + } +} diff --git a/packages/deliverables/workspace-changes/locale/pt.json b/packages/deliverables/workspace-changes/locale/pt.json new file mode 100644 index 0000000000..6d8e74a908 --- /dev/null +++ b/packages/deliverables/workspace-changes/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Histórico de alterações do espaço de trabalho", + "description": "Registre as alterações nos arquivos em cada rodada de tarefas para comparação arquivo por arquivo." + } +} diff --git a/packages/deliverables/workspace-changes/locale/ru.json b/packages/deliverables/workspace-changes/locale/ru.json new file mode 100644 index 0000000000..b12ec1a9b2 --- /dev/null +++ b/packages/deliverables/workspace-changes/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "История изменений рабочей области", + "description": "Записывайте изменения файлов в каждом раунде задач для сравнения файлов по файлам." + } +} diff --git a/packages/document/office-to-pdf/locale/de.json b/packages/document/office-to-pdf/locale/de.json new file mode 100644 index 0000000000..cbcfec7db1 --- /dev/null +++ b/packages/document/office-to-pdf/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Office zu PDF", + "description": "Konvertieren Sie Dokumente wie Word, Excel und PowerPoint zur Vorschau in PDF." + } +} diff --git a/packages/document/office-to-pdf/locale/es.json b/packages/document/office-to-pdf/locale/es.json new file mode 100644 index 0000000000..5490b4c9e1 --- /dev/null +++ b/packages/document/office-to-pdf/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Oficina a PDF", + "description": "Convierta documentos como Word, Excel y PowerPoint a PDF para obtener una vista previa." + } +} diff --git a/packages/document/office-to-pdf/locale/fr.json b/packages/document/office-to-pdf/locale/fr.json new file mode 100644 index 0000000000..b70e479d75 --- /dev/null +++ b/packages/document/office-to-pdf/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Bureau en PDF", + "description": "Convertissez des documents tels que Word, Excel et PowerPoint en PDF pour un aperçu." + } +} diff --git a/packages/document/office-to-pdf/locale/pt.json b/packages/document/office-to-pdf/locale/pt.json new file mode 100644 index 0000000000..ca55632ba7 --- /dev/null +++ b/packages/document/office-to-pdf/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Escritório para PDF", + "description": "Converta documentos como Word, Excel e PowerPoint em PDF para visualização." + } +} diff --git a/packages/document/office-to-pdf/locale/ru.json b/packages/document/office-to-pdf/locale/ru.json new file mode 100644 index 0000000000..2082ca887d --- /dev/null +++ b/packages/document/office-to-pdf/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Офис в PDF", + "description": "Преобразуйте такие документы, как Word, Excel и PowerPoint, в PDF для предварительного просмотра." + } +} diff --git a/packages/experimental/agent-team-profile/locale/de.json b/packages/experimental/agent-team-profile/locale/de.json new file mode 100644 index 0000000000..07058805df --- /dev/null +++ b/packages/experimental/agent-team-profile/locale/de.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Agententeams", + "description": "Aktivieren Sie Teamzusammenarbeit, Teamtools, die Mitgliederliste und das gemeinsame Aufgabenboard.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/agent-team-profile/locale/es.json b/packages/experimental/agent-team-profile/locale/es.json new file mode 100644 index 0000000000..b094b4371b --- /dev/null +++ b/packages/experimental/agent-team-profile/locale/es.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Equipos de agentes", + "description": "Habilite la colaboración en equipo, las herramientas del equipo, la lista de miembros y el tablero de tareas compartido.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/agent-team-profile/locale/fr.json b/packages/experimental/agent-team-profile/locale/fr.json new file mode 100644 index 0000000000..a37e31344d --- /dev/null +++ b/packages/experimental/agent-team-profile/locale/fr.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Équipes d'agents", + "description": "Activez la collaboration en équipe, les outils d’équipe, la liste des membres et le tableau des tâches partagé.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/agent-team-profile/locale/pt.json b/packages/experimental/agent-team-profile/locale/pt.json new file mode 100644 index 0000000000..12b0894600 --- /dev/null +++ b/packages/experimental/agent-team-profile/locale/pt.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Equipes de agentes", + "description": "Habilite a colaboração em equipe, as ferramentas da equipe, a lista de membros e o quadro de tarefas compartilhado.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/agent-team-profile/locale/ru.json b/packages/experimental/agent-team-profile/locale/ru.json new file mode 100644 index 0000000000..828f0f7b3c --- /dev/null +++ b/packages/experimental/agent-team-profile/locale/ru.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Команды агентов", + "description": "Включите совместную работу в команде, инструменты группы, список участников и общую доску задач.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/agent-team/locale/de.json b/packages/experimental/agent-team/locale/de.json new file mode 100644 index 0000000000..1822ee3f21 --- /dev/null +++ b/packages/experimental/agent-team/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Teamzusammenarbeit", + "description": "Verwalten Sie Teammitglieder, Mitgliedernachrichten und gemeinsame Aufgaben." + } +} diff --git a/packages/experimental/agent-team/locale/es.json b/packages/experimental/agent-team/locale/es.json new file mode 100644 index 0000000000..7bed5c6282 --- /dev/null +++ b/packages/experimental/agent-team/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Colaboración en equipo", + "description": "Administre los miembros del equipo, los mensajes de los miembros y las tareas compartidas." + } +} diff --git a/packages/experimental/agent-team/locale/fr.json b/packages/experimental/agent-team/locale/fr.json new file mode 100644 index 0000000000..df95c9af80 --- /dev/null +++ b/packages/experimental/agent-team/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Collaboration en équipe", + "description": "Gérez les membres de l'équipe, les messages des membres et les tâches partagées." + } +} diff --git a/packages/experimental/agent-team/locale/pt.json b/packages/experimental/agent-team/locale/pt.json new file mode 100644 index 0000000000..5ee714778a --- /dev/null +++ b/packages/experimental/agent-team/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Colaboração em equipe", + "description": "Gerencie membros da equipe, mensagens de membros e tarefas compartilhadas." + } +} diff --git a/packages/experimental/agent-team/locale/ru.json b/packages/experimental/agent-team/locale/ru.json new file mode 100644 index 0000000000..cea628fa82 --- /dev/null +++ b/packages/experimental/agent-team/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Командное сотрудничество", + "description": "Управляйте членами команды, сообщениями участников и общими задачами." + } +} diff --git a/packages/experimental/api-speech-to-text/locale/de.json b/packages/experimental/api-speech-to-text/locale/de.json new file mode 100644 index 0000000000..5b3c8be0ab --- /dev/null +++ b/packages/experimental/api-speech-to-text/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sprachtranskription API", + "description": "Bereitstellung von Sprachtranskriptionen für Browser-Clients." + } +} diff --git a/packages/experimental/api-speech-to-text/locale/es.json b/packages/experimental/api-speech-to-text/locale/es.json new file mode 100644 index 0000000000..63f8474505 --- /dev/null +++ b/packages/experimental/api-speech-to-text/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Transcripción de voz API", + "description": "Proporcionar transcripción de voz para clientes de navegador." + } +} diff --git a/packages/experimental/api-speech-to-text/locale/fr.json b/packages/experimental/api-speech-to-text/locale/fr.json new file mode 100644 index 0000000000..757cdc6d2b --- /dev/null +++ b/packages/experimental/api-speech-to-text/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Transcription vocale API", + "description": "Fournir une transcription vocale pour les clients du navigateur." + } +} diff --git a/packages/experimental/api-speech-to-text/locale/pt.json b/packages/experimental/api-speech-to-text/locale/pt.json new file mode 100644 index 0000000000..b2b8172215 --- /dev/null +++ b/packages/experimental/api-speech-to-text/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Transcrição de fala API", + "description": "Fornece transcrição de fala para clientes de navegador." + } +} diff --git a/packages/experimental/api-speech-to-text/locale/ru.json b/packages/experimental/api-speech-to-text/locale/ru.json new file mode 100644 index 0000000000..92f969dc64 --- /dev/null +++ b/packages/experimental/api-speech-to-text/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Транскрипция речи API", + "description": "Обеспечьте транскрипцию речи для клиентов браузера." + } +} diff --git a/packages/experimental/auto-review/locale/de.json b/packages/experimental/auto-review/locale/de.json new file mode 100644 index 0000000000..457bddd8e4 --- /dev/null +++ b/packages/experimental/auto-review/locale/de.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Automatische Autorisierungsüberprüfung", + "description": "Fügen Sie einen Auto review-Berechtigungsmodus hinzu, der das Modell verwendet, um die Autorisierung vor jedem Toolaufruf zu bewerten.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/auto-review/locale/es.json b/packages/experimental/auto-review/locale/es.json new file mode 100644 index 0000000000..0ff73b015d --- /dev/null +++ b/packages/experimental/auto-review/locale/es.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Revisión de autorización automática", + "description": "Agregue un modo de permiso Auto review que utilice el modelo para evaluar la autorización antes de cada llamada a la herramienta.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/auto-review/locale/fr.json b/packages/experimental/auto-review/locale/fr.json new file mode 100644 index 0000000000..533cd20bf0 --- /dev/null +++ b/packages/experimental/auto-review/locale/fr.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Examen des autorisations automatiques", + "description": "Ajoutez un mode d'autorisation Auto review qui utilise le modèle pour évaluer l'autorisation avant chaque appel d'outil.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/auto-review/locale/pt.json b/packages/experimental/auto-review/locale/pt.json new file mode 100644 index 0000000000..6dd7e9ee7d --- /dev/null +++ b/packages/experimental/auto-review/locale/pt.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Revisão de autorização automática", + "description": "Adicione um modo de permissão Auto review que usa o modelo para avaliar a autorização antes de cada chamada de ferramenta.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/auto-review/locale/ru.json b/packages/experimental/auto-review/locale/ru.json new file mode 100644 index 0000000000..ddb103d129 --- /dev/null +++ b/packages/experimental/auto-review/locale/ru.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Проверка автоматической авторизации", + "description": "Добавьте режим разрешений Auto review, который использует модель для оценки авторизации перед каждым вызовом инструмента.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/auto-review/src/locales.ts b/packages/experimental/auto-review/src/locales.ts index 4a4dc5deff..df43559f1e 100644 --- a/packages/experimental/auto-review/src/locales.ts +++ b/packages/experimental/auto-review/src/locales.ts @@ -18,13 +18,52 @@ export const ja = { deniedWithReason: (reason: string): string => `自動認可レビューがこの呼び出しを拒否しました:${reason}`, } satisfies typeof en +/** Spanish dictionary, checked against the English keys. */ +export const es = { + denied: 'Auto review ha denegado esta llamada.', + deniedWithReason: (reason: string): string => `Auto review ha denegado esta llamada: ${reason}`, +} satisfies typeof en + +/** French dictionary, checked against the English keys. */ +export const fr = { + denied: 'Auto review a refusé cet appel.', + deniedWithReason: (reason: string): string => `Auto review a refusé cet appel : ${reason}`, +} satisfies typeof en + +/** German dictionary, checked against the English keys. */ +export const de = { + denied: 'Auto review hat diesen Aufruf abgelehnt.', + deniedWithReason: (reason: string): string => `Auto review hat diesen Aufruf abgelehnt: ${reason}`, +} satisfies typeof en + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + denied: 'Auto review отклонила этот вызов.', + deniedWithReason: (reason: string): string => `Auto review отклонила этот вызов: ${reason}`, +} satisfies typeof en + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + denied: 'Auto review negou esta chamada.', + deniedWithReason: (reason: string): string => `Auto review negou esta chamada: ${reason}`, +} satisfies typeof en + /** * Build all display translations without translating the reviewer's raw reason. * @param reason - optional reviewer explanation. * @returns text for the Client's localized-text resolver. */ -export function deniedDisplayReason(reason?: string): Record<'en' | 'zh' | 'ja', string> { +export function deniedDisplayReason(reason?: string): Record<'en' | 'zh' | 'ja' | 'es' | 'fr' | 'de' | 'ru' | 'pt', string> { return reason === undefined - ? { en: en.denied, zh: zh.denied, ja: ja.denied } - : { en: en.deniedWithReason(reason), zh: zh.deniedWithReason(reason), ja: ja.deniedWithReason(reason) } + ? { en: en.denied, zh: zh.denied, ja: ja.denied, es: es.denied, fr: fr.denied, de: de.denied, ru: ru.denied, pt: pt.denied } + : { + en: en.deniedWithReason(reason), + zh: zh.deniedWithReason(reason), + ja: ja.deniedWithReason(reason), + es: es.deniedWithReason(reason), + fr: fr.deniedWithReason(reason), + de: de.deniedWithReason(reason), + ru: ru.deniedWithReason(reason), + pt: pt.deniedWithReason(reason), + } } diff --git a/packages/experimental/auto-review/tests/auto-review.spec.ts b/packages/experimental/auto-review/tests/auto-review.spec.ts index 035ae3c923..20ab50c4c4 100644 --- a/packages/experimental/auto-review/tests/auto-review.spec.ts +++ b/packages/experimental/auto-review/tests/auto-review.spec.ts @@ -966,9 +966,16 @@ describe('native review request', () => { ? 'Auto review denied tool "probe"' : `Auto review denied tool "probe": ${item.expectedReason}`) expect(displayReasons.at(-1)).toEqual(item.expectedReason === undefined - ? { en: 'Auto review denied this call.', zh: 'Auto review 拒绝了此调用。', ja: '自動認可レビューがこの呼び出しを拒否しました。' } + ? { en: 'Auto review denied this call.', zh: 'Auto review 拒绝了此调用。', ja: '自動認可レビューがこの呼び出しを拒否しました。', + es: 'Auto review ha denegado esta llamada.', fr: 'Auto review a refusé cet appel.', + de: 'Auto review hat diesen Aufruf abgelehnt.', ru: 'Auto review отклонила этот вызов.', pt: 'Auto review negou esta chamada.' } : { en: `Auto review denied this call: ${item.expectedReason}`, zh: `Auto review 拒绝了此调用:${item.expectedReason}`, - ja: `自動認可レビューがこの呼び出しを拒否しました:${item.expectedReason}` }) + ja: `自動認可レビューがこの呼び出しを拒否しました:${item.expectedReason}`, + es: `Auto review ha denegado esta llamada: ${item.expectedReason}`, + fr: `Auto review a refusé cet appel : ${item.expectedReason}`, + de: `Auto review hat diesen Aufruf abgelehnt: ${item.expectedReason}`, + ru: `Auto review отклонила этот вызов: ${item.expectedReason}`, + pt: `Auto review negou esta chamada: ${item.expectedReason}` }) } expect(probe.runs()).toBe(2) diff --git a/packages/experimental/badge-skill-bundle/locale/de.json b/packages/experimental/badge-skill-bundle/locale/de.json new file mode 100644 index 0000000000..57c7bc3d08 --- /dev/null +++ b/packages/experimental/badge-skill-bundle/locale/de.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "DSH-Abzeichen-Fertigkeit", + "description": "Lassen Sie Agenten Dokumente, Pull-Requests und andere Ausgaben mit einem „powered by dsh“-Badge versehen.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/badge-skill-bundle/locale/es.json b/packages/experimental/badge-skill-bundle/locale/es.json new file mode 100644 index 0000000000..406e9f43c2 --- /dev/null +++ b/packages/experimental/badge-skill-bundle/locale/es.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Habilidad de insignia DSH", + "description": "Permita que los agentes agreguen una insignia \"con tecnología de dsh\" a documentos, solicitudes de extracción y otros resultados.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/badge-skill-bundle/locale/fr.json b/packages/experimental/badge-skill-bundle/locale/fr.json new file mode 100644 index 0000000000..2b173eea29 --- /dev/null +++ b/packages/experimental/badge-skill-bundle/locale/fr.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Compétence du badge DSH", + "description": "Laissez les agents ajouter un badge « propulsé par dsh » aux documents, demandes d'extraction et autres sorties.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/badge-skill-bundle/locale/pt.json b/packages/experimental/badge-skill-bundle/locale/pt.json new file mode 100644 index 0000000000..bc1d6fab6f --- /dev/null +++ b/packages/experimental/badge-skill-bundle/locale/pt.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "DSH habilidade de distintivo", + "description": "Permita que os agentes adicionem um selo “powered by dsh” a documentos, pull requests e outros resultados.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/badge-skill-bundle/locale/ru.json b/packages/experimental/badge-skill-bundle/locale/ru.json new file mode 100644 index 0000000000..14770f9816 --- /dev/null +++ b/packages/experimental/badge-skill-bundle/locale/ru.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "DSH значок навыка", + "description": "Позвольте агентам добавлять значок «Powered by dsh» к документам, запросам на включение и другим результатам.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/browser-use-chrome-devtools-mcp/locale/de.json b/packages/experimental/browser-use-chrome-devtools-mcp/locale/de.json new file mode 100644 index 0000000000..a81cfdba45 --- /dev/null +++ b/packages/experimental/browser-use-chrome-devtools-mcp/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Browsernutzung (Chrome DevTools)", + "description": "Lassen Sie das Modell Webseiten über Chrome DevTools MCP in einem gestarteten Chrome überprüfen und betreiben." + } +} diff --git a/packages/experimental/browser-use-chrome-devtools-mcp/locale/es.json b/packages/experimental/browser-use-chrome-devtools-mcp/locale/es.json new file mode 100644 index 0000000000..bf5a4aab96 --- /dev/null +++ b/packages/experimental/browser-use-chrome-devtools-mcp/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Uso del navegador (Chrome DevTools)", + "description": "Deje que el modelo inspeccione y opere páginas web a través de Chrome DevTools MCP en un Chrome iniciado." + } +} diff --git a/packages/experimental/browser-use-chrome-devtools-mcp/locale/fr.json b/packages/experimental/browser-use-chrome-devtools-mcp/locale/fr.json new file mode 100644 index 0000000000..9160ad625c --- /dev/null +++ b/packages/experimental/browser-use-chrome-devtools-mcp/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Utilisation du navigateur (Chrome DevTools)", + "description": "Laissez le modèle inspecter et exploiter les pages Web via Chrome DevTools MCP dans un Chrome lancé." + } +} diff --git a/packages/experimental/browser-use-chrome-devtools-mcp/locale/pt.json b/packages/experimental/browser-use-chrome-devtools-mcp/locale/pt.json new file mode 100644 index 0000000000..6670caf350 --- /dev/null +++ b/packages/experimental/browser-use-chrome-devtools-mcp/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Uso do navegador (Chrome DevTools)", + "description": "Deixe o modelo inspecionar e operar páginas da Web por meio do Chrome DevTools MCP em um Chrome iniciado." + } +} diff --git a/packages/experimental/browser-use-chrome-devtools-mcp/locale/ru.json b/packages/experimental/browser-use-chrome-devtools-mcp/locale/ru.json new file mode 100644 index 0000000000..4a3826074c --- /dev/null +++ b/packages/experimental/browser-use-chrome-devtools-mcp/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Использование браузера (Chrome DevTools)", + "description": "Позвольте модели проверять и управлять веб-страницами с помощью Chrome DevTools MCP в запущенном Chrome." + } +} diff --git a/packages/experimental/browser-use-playwright-mcp/locale/de.json b/packages/experimental/browser-use-playwright-mcp/locale/de.json new file mode 100644 index 0000000000..2d22818be0 --- /dev/null +++ b/packages/experimental/browser-use-playwright-mcp/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Browsernutzung (Dramatiker)", + "description": "Lassen Sie das Modell über Playwright MCP in einem gestarteten Chromium Webseiten durchsuchen und bedienen." + } +} diff --git a/packages/experimental/browser-use-playwright-mcp/locale/es.json b/packages/experimental/browser-use-playwright-mcp/locale/es.json new file mode 100644 index 0000000000..6230f676bd --- /dev/null +++ b/packages/experimental/browser-use-playwright-mcp/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Uso del navegador (Dramaturgo)", + "description": "Deje que el modelo navegue y opere páginas web a través de Playwright MCP en un Chromium iniciado." + } +} diff --git a/packages/experimental/browser-use-playwright-mcp/locale/fr.json b/packages/experimental/browser-use-playwright-mcp/locale/fr.json new file mode 100644 index 0000000000..f6371998c4 --- /dev/null +++ b/packages/experimental/browser-use-playwright-mcp/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Utilisation du navigateur (dramaturge)", + "description": "Laissez le modèle parcourir et exploiter des pages Web via Playwright MCP dans un Chromium lancé." + } +} diff --git a/packages/experimental/browser-use-playwright-mcp/locale/pt.json b/packages/experimental/browser-use-playwright-mcp/locale/pt.json new file mode 100644 index 0000000000..5041d561af --- /dev/null +++ b/packages/experimental/browser-use-playwright-mcp/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Uso do navegador (dramaturgo)", + "description": "Deixe o modelo navegar e operar páginas da web por meio do Playwright MCP em um Chromium iniciado." + } +} diff --git a/packages/experimental/browser-use-playwright-mcp/locale/ru.json b/packages/experimental/browser-use-playwright-mcp/locale/ru.json new file mode 100644 index 0000000000..2f641f4131 --- /dev/null +++ b/packages/experimental/browser-use-playwright-mcp/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Использование браузера (Драматург)", + "description": "Позвольте модели просматривать и управлять веб-страницами через Playwright MCP в запущенном Chromium." + } +} diff --git a/packages/experimental/browser-use-stagehand-native/locale/de.json b/packages/experimental/browser-use-stagehand-native/locale/de.json new file mode 100644 index 0000000000..640f98244e --- /dev/null +++ b/packages/experimental/browser-use-stagehand-native/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Stagehand-Browsertools", + "description": "Stellen Sie experimentelle Stagehand-Browsertools mithilfe eines separat konfigurierten nativen Modells bereit." + } +} diff --git a/packages/experimental/browser-use-stagehand-native/locale/es.json b/packages/experimental/browser-use-stagehand-native/locale/es.json new file mode 100644 index 0000000000..d62a23cabd --- /dev/null +++ b/packages/experimental/browser-use-stagehand-native/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramientas de navegador Stagehand", + "description": "Proporcione herramientas experimentales de navegador Stagehand utilizando un modelo nativo configurado por separado." + } +} diff --git a/packages/experimental/browser-use-stagehand-native/locale/fr.json b/packages/experimental/browser-use-stagehand-native/locale/fr.json new file mode 100644 index 0000000000..1818988034 --- /dev/null +++ b/packages/experimental/browser-use-stagehand-native/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outils de navigation Stagehand", + "description": "Fournissez des outils de navigation expérimentaux Stagehand à l’aide d’un modèle natif configuré séparément." + } +} diff --git a/packages/experimental/browser-use-stagehand-native/locale/pt.json b/packages/experimental/browser-use-stagehand-native/locale/pt.json new file mode 100644 index 0000000000..2094cf3d15 --- /dev/null +++ b/packages/experimental/browser-use-stagehand-native/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramentas de navegador para ajudantes de palco", + "description": "Forneça ferramentas experimentais de navegador Stagehand usando um modelo nativo configurado separadamente." + } +} diff --git a/packages/experimental/browser-use-stagehand-native/locale/ru.json b/packages/experimental/browser-use-stagehand-native/locale/ru.json new file mode 100644 index 0000000000..8ac48a94c7 --- /dev/null +++ b/packages/experimental/browser-use-stagehand-native/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Инструменты браузера Stagehand", + "description": "Предоставьте экспериментальные инструменты браузера Stagehand, используя отдельно настроенную собственную модель." + } +} diff --git a/packages/experimental/claude-code-mods/locale/de.json b/packages/experimental/claude-code-mods/locale/de.json new file mode 100644 index 0000000000..ee27e0225b --- /dev/null +++ b/packages/experimental/claude-code-mods/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Claude Code-Mods", + "description": "Laden Sie Claude Code-Verlängerungen und führen Sie ihre Haken durch die Harness-Verlängerungspunkte." + } +} diff --git a/packages/experimental/claude-code-mods/locale/es.json b/packages/experimental/claude-code-mods/locale/es.json new file mode 100644 index 0000000000..b2fa75ad23 --- /dev/null +++ b/packages/experimental/claude-code-mods/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Modificaciones Claude Code", + "description": "Cargue las extensiones Claude Code y pase sus ganchos a través de los puntos de extensión del arnés." + } +} diff --git a/packages/experimental/claude-code-mods/locale/fr.json b/packages/experimental/claude-code-mods/locale/fr.json new file mode 100644 index 0000000000..bec4fc8ea4 --- /dev/null +++ b/packages/experimental/claude-code-mods/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Mods Claude Code", + "description": "Chargez les extensions Claude Code et faites passer leurs crochets à travers les points d'extension du harnais." + } +} diff --git a/packages/experimental/claude-code-mods/locale/pt.json b/packages/experimental/claude-code-mods/locale/pt.json new file mode 100644 index 0000000000..d1fb2d9b07 --- /dev/null +++ b/packages/experimental/claude-code-mods/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Claude Code modificações", + "description": "Carregue Claude Code extensões e passe seus ganchos pelos pontos de extensão do chicote." + } +} diff --git a/packages/experimental/claude-code-mods/locale/ru.json b/packages/experimental/claude-code-mods/locale/ru.json new file mode 100644 index 0000000000..5d347cee67 --- /dev/null +++ b/packages/experimental/claude-code-mods/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Claude Code моды", + "description": "Загрузите расширения Claude Code и пропустите их перехваты через точки расширения Harness." + } +} diff --git a/packages/experimental/client-ui-agent-team/locale/de.json b/packages/experimental/client-ui-agent-team/locale/de.json new file mode 100644 index 0000000000..0d51f033bf --- /dev/null +++ b/packages/experimental/client-ui-agent-team/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Teampanel", + "description": "Zeigen Sie Teammitglieder und freigegebene Aufgaben an und navigieren Sie zu Mitgliedergesprächen." + } +} diff --git a/packages/experimental/client-ui-agent-team/locale/es.json b/packages/experimental/client-ui-agent-team/locale/es.json new file mode 100644 index 0000000000..378b5febee --- /dev/null +++ b/packages/experimental/client-ui-agent-team/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Panel de equipo", + "description": "Vea los miembros del equipo y las tareas compartidas, y navegue hasta las conversaciones de los miembros." + } +} diff --git a/packages/experimental/client-ui-agent-team/locale/fr.json b/packages/experimental/client-ui-agent-team/locale/fr.json new file mode 100644 index 0000000000..fde7d9a4d1 --- /dev/null +++ b/packages/experimental/client-ui-agent-team/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Panneau d'équipe", + "description": "Affichez les membres de l'équipe et les tâches partagées, et accédez aux conversations des membres." + } +} diff --git a/packages/experimental/client-ui-agent-team/locale/pt.json b/packages/experimental/client-ui-agent-team/locale/pt.json new file mode 100644 index 0000000000..8a7909fe18 --- /dev/null +++ b/packages/experimental/client-ui-agent-team/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Painel da equipe", + "description": "Veja os membros da equipe e as tarefas compartilhadas e navegue até as conversas dos membros." + } +} diff --git a/packages/experimental/client-ui-agent-team/locale/ru.json b/packages/experimental/client-ui-agent-team/locale/ru.json new file mode 100644 index 0000000000..91fd1e9567 --- /dev/null +++ b/packages/experimental/client-ui-agent-team/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Панель команды", + "description": "Просматривайте участников команды и общие задачи, а также переходите к беседам участников." + } +} diff --git a/packages/experimental/client-ui-agent-team/src/client/locales.ts b/packages/experimental/client-ui-agent-team/src/client/locales.ts index 5ba6255bac..f1ed57b9ee 100644 --- a/packages/experimental/client-ui-agent-team/src/client/locales.ts +++ b/packages/experimental/client-ui-agent-team/src/client/locales.ts @@ -92,3 +92,148 @@ export const ja = { 'status.in_progress': '進行中', 'status.completed': '完了', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + trigger: 'equipo de agentes', + loading: 'Cargando equipo…', + unavailable: 'El equipo no está disponible', + failure: 'Registro de equipo persistente no válido: {message}', + empty: 'Aún no hay tareas compartidas. Créelos a través de la conversación.', + roster: 'Miembros', + tasks: 'Tareas compartidas', + model: 'modelo', + open: 'Abrir conversación de miembros', + current: 'charla actual', + owner: 'propietario', + unowned: 'Sin dueño', + blockedBy: 'Bloqueado por', + writeScopes: 'Escribir alcances', + ready: 'Listo', + blocked: 'Bloqueado por dependencias', + 'task.expand': 'Mostrar más', + 'task.collapse': 'Mostrar menos', + 'memberStatus.running': 'corriendo', + 'memberStatus.inactive': 'Inactivo', + 'memberStatus.provisioning': 'Aprovisionamiento', + 'memberStatus.failed': 'Fallido', + 'status.pending': 'Pendiente', + 'status.in_progress': 'En progreso', + 'status.completed': 'Completado', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + trigger: "Équipe d'agents", + loading: "Chargement de l'équipe…", + unavailable: "L'équipe n'est pas disponible", + failure: "Enregistrement d'équipe persistant non valide : {message}", + empty: "Aucune tâche partagée pour l'instant. Créez-les à travers la conversation.", + roster: 'Membres', + tasks: 'Tâches partagées', + model: 'Modèle', + open: 'Conversation ouverte avec les membres', + current: 'Discussion actuelle', + owner: 'Propriétaire', + unowned: 'Sans propriétaire', + blockedBy: 'Bloqué par', + writeScopes: 'Écrire des étendues', + ready: 'Prêt', + blocked: 'Bloqué par les dépendances', + 'task.expand': 'Afficher plus', + 'task.collapse': 'Afficher moins', + 'memberStatus.running': 'Courir', + 'memberStatus.inactive': 'Inactif', + 'memberStatus.provisioning': 'Approvisionnement', + 'memberStatus.failed': 'Échec', + 'status.pending': 'En attente', + 'status.in_progress': 'En cours', + 'status.completed': 'Terminé', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + trigger: 'Agententeam', + loading: 'Team wird geladen…', + unavailable: 'Team ist nicht verfügbar', + failure: 'Ungültiger beibehaltener Teamdatensatz: {message}', + empty: 'Noch keine geteilten Aufgaben. Erstellen Sie sie durch das Gespräch.', + roster: 'Mitglieder', + tasks: 'Geteilte Aufgaben', + model: 'Modell', + open: 'Öffnen Sie die Mitgliederkonversation', + current: 'Aktueller Chat', + owner: 'Besitzer', + unowned: 'Unbesessen', + blockedBy: 'Blockiert von', + writeScopes: 'Bereiche schreiben', + ready: 'Bereit', + blocked: 'Blockiert durch Abhängigkeiten', + 'task.expand': 'Mehr anzeigen', + 'task.collapse': 'Weniger anzeigen', + 'memberStatus.running': 'Laufen', + 'memberStatus.inactive': 'Inaktiv', + 'memberStatus.provisioning': 'Bereitstellung', + 'memberStatus.failed': 'Fehlgeschlagen', + 'status.pending': 'Ausstehend', + 'status.in_progress': 'In Bearbeitung', + 'status.completed': 'Abgeschlossen', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + trigger: 'Команда агентов', + loading: 'Загрузка команды…', + unavailable: 'Команда недоступна', + failure: 'Неверный сохраненный командный рекорд: {message}.', + empty: 'Общие задачи пока отсутствуют. Создайте их посредством разговора.', + roster: 'Члены', + tasks: 'Общие задачи', + model: 'Модель', + open: 'Открыть беседу участников', + current: 'Текущий чат', + owner: 'Владелец', + unowned: 'Невладеющий', + blockedBy: 'Заблокировано', + writeScopes: 'Запись областей', + ready: 'Готово', + blocked: 'Заблокировано зависимостями', + 'task.expand': 'Показать больше', + 'task.collapse': 'Показать меньше', + 'memberStatus.running': 'Бег', + 'memberStatus.inactive': 'Неактивный', + 'memberStatus.provisioning': 'обеспечение', + 'memberStatus.failed': 'Не удалось', + 'status.pending': 'Ожидается', + 'status.in_progress': 'В процессе', + 'status.completed': 'Завершено', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + trigger: 'Equipe de agentes', + loading: 'Carregando equipe…', + unavailable: 'A equipe não está disponível', + failure: 'Registro de equipe persistente inválido: {message}', + empty: 'Ainda não há tarefas compartilhadas. Crie-os através da conversa.', + roster: 'Membros', + tasks: 'Tarefas compartilhadas', + model: 'Modelo', + open: 'Abrir conversa entre membros', + current: 'Bate-papo atual', + owner: 'Proprietário', + unowned: 'Sem dono', + blockedBy: 'Bloqueado por', + writeScopes: 'Escrever escopos', + ready: 'Pronto', + blocked: 'Bloqueado por dependências', + 'task.expand': 'Mostrar mais', + 'task.collapse': 'Mostrar menos', + 'memberStatus.running': 'Correndo', + 'memberStatus.inactive': 'Inativo', + 'memberStatus.provisioning': 'Provisionamento', + 'memberStatus.failed': 'Falha', + 'status.pending': 'Pendente', + 'status.in_progress': 'Em andamento', + 'status.completed': 'Concluído', +} satisfies Record diff --git a/packages/experimental/client-ui-agent-team/src/client/mount.ts b/packages/experimental/client-ui-agent-team/src/client/mount.ts index a3c044b596..c1e13c8cfa 100644 --- a/packages/experimental/client-ui-agent-team/src/client/mount.ts +++ b/packages/experimental/client-ui-agent-team/src/client/mount.ts @@ -8,7 +8,7 @@ import type {} from '@deepseek-ai/dsh-client-locale/client' import type {} from '@deepseek-ai/dsh-client-ui-renderer/client' import type {} from '@deepseek-ai/dsh-client-ui-workspace/client' import { TeamAction, type TeamActionInjected } from './TeamAction.tsx' -import { en, ja, NS, zh, type TeamKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, NS, zh, type TeamKey } from './locales.ts' declare module '@deepseek-ai/dsh-client-ui-slots' { interface LocaleNamespaceMap { @@ -27,7 +27,7 @@ export const inject = ['sessions', 'uiWorkspace', 'slots', 'locale'] * @param ctx - Client Context carrying the injected navigation, locale, slot, and Session services. */ export function registerAgentTeamUi(ctx: ClientContext): void { - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'client-ui-agent-team: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'client-ui-agent-team: dictionaries') const sessions = ctx.sessions const leadSessionId = (sessionId: SessionId): SessionId => { const address = sessions.binding(sessionId)?.session.getSnapshot().subagent?.address diff --git a/packages/experimental/client-ui-claude-code-mods/locale/de.json b/packages/experimental/client-ui-claude-code-mods/locale/de.json new file mode 100644 index 0000000000..fda7d714dd --- /dev/null +++ b/packages/experimental/client-ui-claude-code-mods/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Claude Code Mods-Schnittstelle", + "description": "Zeigen Sie den Erweiterungsbaum jeder Sitzung über dem Eingabefeld an und senden Sie Schaltflächenaktionen an den Erweiterungsdienst." + } +} diff --git a/packages/experimental/client-ui-claude-code-mods/locale/es.json b/packages/experimental/client-ui-claude-code-mods/locale/es.json new file mode 100644 index 0000000000..b8eadd3e26 --- /dev/null +++ b/packages/experimental/client-ui-claude-code-mods/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interfaz de modificaciones Claude Code", + "description": "Muestre el árbol de extensión de cada sesión encima del cuadro de entrada y envíe acciones de botones al servicio de extensión." + } +} diff --git a/packages/experimental/client-ui-claude-code-mods/locale/fr.json b/packages/experimental/client-ui-claude-code-mods/locale/fr.json new file mode 100644 index 0000000000..140a56a210 --- /dev/null +++ b/packages/experimental/client-ui-claude-code-mods/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Interface de mods Claude Code", + "description": "Affichez l'arborescence des extensions de chaque session au-dessus de la zone de saisie et envoyez les actions des boutons au service d'extension." + } +} diff --git a/packages/experimental/client-ui-claude-code-mods/locale/pt.json b/packages/experimental/client-ui-claude-code-mods/locale/pt.json new file mode 100644 index 0000000000..fad6e03f7c --- /dev/null +++ b/packages/experimental/client-ui-claude-code-mods/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Claude Code interface de mods", + "description": "Exiba a árvore de extensão de cada sessão acima da caixa de entrada e envie ações de botão para o serviço de extensão." + } +} diff --git a/packages/experimental/client-ui-claude-code-mods/locale/ru.json b/packages/experimental/client-ui-claude-code-mods/locale/ru.json new file mode 100644 index 0000000000..bdf1e5a1f9 --- /dev/null +++ b/packages/experimental/client-ui-claude-code-mods/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Claude Code интерфейс модов", + "description": "Отобразите дерево расширений каждого сеанса над полем ввода и отправьте действия кнопок в службу расширений." + } +} diff --git a/packages/experimental/client-ui-claude-code-mods/src/client/locales.ts b/packages/experimental/client-ui-claude-code-mods/src/client/locales.ts index 62e530c87e..781c856736 100644 --- a/packages/experimental/client-ui-claude-code-mods/src/client/locales.ts +++ b/packages/experimental/client-ui-claude-code-mods/src/client/locales.ts @@ -29,3 +29,43 @@ export const ja = { 'press.failed': 'ボタンが失敗しました: {message}', 'press.stale': 'そのボタンは以前の描画のものです。バンドは更新されました', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + band: 'Modificaciones Claude Code', + pressing: 'Trabajando…', + 'press.failed': 'El botón falló: {message}', + 'press.stale': 'Ese botón pertenecía a un dibujo anterior; la banda se ha renovado', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + band: 'Mods Claude Code', + pressing: 'Travailler…', + 'press.failed': 'Le bouton a échoué : {message}', + 'press.stale': "Ce bouton appartenait à un dessin antérieur ; le groupe s'est rafraîchi", +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + band: 'Claude Code-Mods', + pressing: 'Arbeiten…', + 'press.failed': 'Die Schaltfläche ist fehlgeschlagen: {message}', + 'press.stale': 'Dieser Knopf gehörte zu einer früheren Zeichnung; Die Band hat sich erfrischt', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + band: 'Claude Code моды', + pressing: 'Работаю…', + 'press.failed': 'Кнопка не удалась: {message}', + 'press.stale': 'Эта кнопка принадлежала более раннему рисунку; группа обновилась', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + band: 'Claude Code modificações', + pressing: 'Trabalhando…', + 'press.failed': 'O botão falhou: {message}', + 'press.stale': 'Esse botão pertencia a um desenho anterior; a banda se atualizou', +} satisfies Record diff --git a/packages/experimental/client-ui-claude-code-mods/src/client/mount.ts b/packages/experimental/client-ui-claude-code-mods/src/client/mount.ts index 498e4a2d28..4bf030cc77 100644 --- a/packages/experimental/client-ui-claude-code-mods/src/client/mount.ts +++ b/packages/experimental/client-ui-claude-code-mods/src/client/mount.ts @@ -11,7 +11,7 @@ import type { SurfaceSnapshot } from '@deepseek-ai/dsh-experimental-claude-code- import type { SessionId } from '@deepseek-ai/dsh-session/types' import type { TypertRemoteContribution } from '@deepseek-ai/dsh-typert-protocol' import { Band, type BandInjected } from './Band.tsx' -import { en, ja, NS, zh, type ModsBandKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, NS, zh, type ModsBandKey } from './locales.ts' declare module '@deepseek-ai/dsh-client-ui-slots' { interface LocaleNamespaceMap { @@ -75,7 +75,7 @@ function watchSession(ctx: Context, sessionId: SessionId, onEnd: () => void): { } function registerUi(ctx: Context): void { - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'client-ui-claude-code-mods: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'client-ui-claude-code-mods: dictionaries') const watches = new Map>() ctx.effect(() => () => { for (const watch of watches.values()) watch.dispose() diff --git a/packages/experimental/client-ui-cot-translation/locale/de.json b/packages/experimental/client-ui-cot-translation/locale/de.json new file mode 100644 index 0000000000..62b1c1a24b --- /dev/null +++ b/packages/experimental/client-ui-cot-translation/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Maschinelle Übersetzung der Argumentation", + "description": "Zeigen Sie mithilfe maschineller Übersetzung erweiterte Argumente in einer anderen Sprache an." + } +} diff --git a/packages/experimental/client-ui-cot-translation/locale/es.json b/packages/experimental/client-ui-cot-translation/locale/es.json new file mode 100644 index 0000000000..50cece4f3c --- /dev/null +++ b/packages/experimental/client-ui-cot-translation/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Traducción automática de razonamiento", + "description": "Muestre un razonamiento ampliado en otro idioma mediante la traducción automática." + } +} diff --git a/packages/experimental/client-ui-cot-translation/locale/fr.json b/packages/experimental/client-ui-cot-translation/locale/fr.json new file mode 100644 index 0000000000..61bc647450 --- /dev/null +++ b/packages/experimental/client-ui-cot-translation/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Traduction automatique du raisonnement", + "description": "Affichez un raisonnement développé dans une autre langue à l’aide de la traduction automatique." + } +} diff --git a/packages/experimental/client-ui-cot-translation/locale/pt.json b/packages/experimental/client-ui-cot-translation/locale/pt.json new file mode 100644 index 0000000000..433e8c3282 --- /dev/null +++ b/packages/experimental/client-ui-cot-translation/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Tradução automática de raciocínio", + "description": "Exiba o raciocínio expandido em outro idioma usando tradução automática." + } +} diff --git a/packages/experimental/client-ui-cot-translation/locale/ru.json b/packages/experimental/client-ui-cot-translation/locale/ru.json new file mode 100644 index 0000000000..1e04a7c94b --- /dev/null +++ b/packages/experimental/client-ui-cot-translation/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Машинный перевод рассуждений", + "description": "Отображение развернутых рассуждений на другом языке с помощью машинного перевода." + } +} diff --git a/packages/experimental/client-ui-cot-translation/src/client/locales.ts b/packages/experimental/client-ui-cot-translation/src/client/locales.ts index 94d5acd14e..8e3ef8230b 100644 --- a/packages/experimental/client-ui-cot-translation/src/client/locales.ts +++ b/packages/experimental/client-ui-cot-translation/src/client/locales.ts @@ -87,3 +87,93 @@ export const ja = { 'unwrap': '折り返しを解除', 'footnotes': '脚注', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + provider: 'Servicio de traducción', google: 'google', bing: 'Bing', + deepseekAccount: 'DeepSeek Flash — cuenta (pago)', deepseekOfficial: 'Flash DeepSeek: API oficial (de pago)', + providerUnavailableOption: '{provider} — no disponible', + providerUnavailable: 'Este proveedor no está disponible. Configura tu cuenta DeepSeek o proveedor oficial de API, o elige un servicio disponible.', + paidNotice: 'Cada fragmento no almacenado en caché envía una solicitud Flash DeepSeek paga por separado a través de la cuenta seleccionada o las credenciales oficiales de API. El razonamiento de reapertura reutiliza los resultados guardados; cambiar el proveedor, el idioma, el texto fuente o la configuración de la solicitud puede enviar una nueva solicitud paga.', + anonymousNotice: 'Bing y Google no necesitan inicio de sesión de traducción ni clave API. Sus puntos finales anónimos pueden rechazar o limitar solicitudes.', targetLanguage: 'Idioma de destino', + targetLanguageHint: 'auto sigue el idioma de la interfaz de usuario; Los códigos de idioma como zh, en y ja también funcionan.', + privacy: 'Se envía el razonamiento ampliado al servicio seleccionado. Puede contener código privado o detalles de la conversación.', + translation: 'Ver traducción', original: 'Ver original', retry: 'Reintentar', failed: 'La traducción falló. Mostrando el original.', + translating: 'Traducir razonamiento', invalidProvider: 'Elija un servicio de traducción.', invalidLanguage: 'Ingrese auto o un código de idioma, como zh, en o ja.', + overridden: 'Anulado', reset: 'Restablecer los valores predeterminados', + unavailable: 'Las preferencias de traducción no están disponibles.', readOnly: 'Esta implementación almacena configuraciones de solo lectura.', + saveFailed: 'El despliegue no aceptó estos valores; quedaron para que usted los corrigiera.', save: 'Guardar', saving: 'Guardando…', + copy: 'Copiar', copied: 'Copiado', codeTitle: 'Bloque de código', wrap: 'Ajustar líneas', unwrap: 'Desenvolver líneas', footnotes: 'Notas a pie de página', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + provider: 'Service de traduction', google: 'Google', bing: 'Bing', + deepseekAccount: 'DeepSeek Flash — compte (payant)', deepseekOfficial: 'DeepSeek Flash — API officiel (payant)', + providerUnavailableOption: '{provider} — indisponible', + providerUnavailable: "Ce fournisseur n'est pas disponible. Configurez votre compte DeepSeek ou votre fournisseur officiel API, ou choisissez un service disponible.", + paidNotice: "Chaque fragment non mis en cache envoie une demande Flash DeepSeek payante distincte via le compte sélectionné ou les informations d'identification officielles API. La réouverture du raisonnement réutilise les résultats enregistrés ; la modification du fournisseur, de la langue, du texte source ou des paramètres de la demande peut envoyer une nouvelle demande payante.", + anonymousNotice: "Bing et Google n'ont pas besoin de connexion de traduction ni de clé API. Leurs points de terminaison anonymes peuvent rejeter ou limiter les demandes.", targetLanguage: 'Langue cible', + targetLanguageHint: "auto suit la langue de l'interface utilisateur ; les codes de langue tels que zh, en et ja fonctionnent également.", + privacy: 'Le raisonnement étendu est envoyé au service sélectionné. Il peut contenir du code privé ou des détails de conversation.', + translation: 'Voir la traduction', original: "Voir l'original", retry: 'Réessayer', failed: "La traduction a échoué. Montrant l'original.", + translating: 'Traduire le raisonnement', invalidProvider: 'Choisissez un service de traduction.', invalidLanguage: 'Saisissez auto ou un code de langue, tel que zh, en ou ja.', + overridden: 'Remplacé', reset: 'Réinitialiser aux valeurs par défaut', + unavailable: 'Les préférences de traduction ne sont pas disponibles.', readOnly: 'Ce déploiement stocke les paramètres en lecture seule.', + saveFailed: "Le déploiement n'a pas accepté ces valeurs ; ils vous ont été laissés à corriger.", save: 'Enregistrer', saving: 'Sauvegarde…', + copy: 'Copier', copied: 'Copié', codeTitle: 'Bloc de code', wrap: 'Activer le retour à la ligne', unwrap: 'Dérouler les lignes', footnotes: 'Notes de bas de page', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + provider: 'Übersetzungsdienst', google: 'Google', bing: 'Bing', + deepseekAccount: 'DeepSeek Flash – Konto (kostenpflichtig)', deepseekOfficial: 'DeepSeek Flash – offizieller API (kostenpflichtig)', + providerUnavailableOption: '{provider} – nicht verfügbar', + providerUnavailable: 'Dieser Anbieter ist nicht verfügbar. Konfigurieren Sie Ihr DeepSeek-Konto oder Ihren offiziellen API-Anbieter oder wählen Sie einen verfügbaren Dienst.', + paidNotice: 'Jedes nicht zwischengespeicherte Fragment sendet eine separate kostenpflichtige DeepSeek-Flash-Anfrage über das ausgewählte Konto oder die offiziellen API-Anmeldeinformationen. Beim erneuten Öffnen der Argumentation werden gespeicherte Ergebnisse wiederverwendet. Wenn Sie den Anbieter, die Sprache, den Quelltext oder die Anfrageeinstellungen ändern, wird möglicherweise eine neue kostenpflichtige Anfrage gesendet.', + anonymousNotice: 'Für Bing und Google ist weder ein Übersetzungs-Login noch ein API-Schlüssel erforderlich. Ihre anonymen Endpunkte können Anfragen ablehnen oder einschränken.', targetLanguage: 'Zielsprache', + targetLanguageHint: 'folgt automatisch der UI-Sprache; Sprachcodes wie zh, en und ja funktionieren ebenfalls.', + privacy: 'Die erweiterte Begründung wird an den ausgewählten Dienst gesendet. Es kann private Code- oder Konversationsdetails enthalten.', + translation: 'Übersetzung ansehen', original: 'Original ansehen', retry: 'Erneut versuchen', failed: 'Die Übersetzung ist fehlgeschlagen. Zeigt das Original.', + translating: 'Argumentation übersetzen', invalidProvider: 'Wählen Sie einen Übersetzungsdienst.', invalidLanguage: 'Geben Sie auto oder einen Sprachcode ein, z. B. zh, en oder ja.', + overridden: 'Überschrieben', reset: 'Auf Standard zurücksetzen', + unavailable: 'Übersetzungseinstellungen sind nicht verfügbar.', readOnly: 'Diese Bereitstellung speichert Einstellungen schreibgeschützt.', + saveFailed: 'Die Bereitstellung hat diese Werte nicht akzeptiert. Sie mussten sie korrigieren.', save: 'Speichern', saving: 'Sparen…', + copy: 'Kopieren', copied: 'Kopiert', codeTitle: 'Codeblock', wrap: 'Zeilen umbrechen', unwrap: 'Zeilen abwickeln', footnotes: 'Fußnoten', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + provider: 'Услуги перевода', google: 'Гугл', bing: 'Бинг', + deepseekAccount: 'DeepSeek Flash — аккаунт (платный)', deepseekOfficial: 'DeepSeek Flash — официальный API (платный)', + providerUnavailableOption: '{provider} — недоступен', + providerUnavailable: 'Этот провайдер недоступен. Настройте свою учетную запись DeepSeek или официального провайдера API или выберите доступную услугу.', + paidNotice: 'Каждый некэшированный фрагмент отправляет отдельный платный запрос DeepSeek Flash через выбранную учетную запись или официальные учетные данные API. При повторном открытии рассуждений повторно используются сохраненные результаты; изменение провайдера, языка, исходного текста или настроек запроса может привести к отправке нового платного запроса.', + anonymousNotice: 'Bing и Google не требуют входа в систему для перевода или ключа API. Их анонимные конечные точки могут отклонять или ограничивать запросы.', targetLanguage: 'Целевой язык', + targetLanguageHint: 'автоматически следует языку пользовательского интерфейса; коды языков, такие как zh, en и ja, также работают.', + privacy: 'Развернутое обоснование отправляется в выбранную службу. Он может содержать личный код или детали разговора.', + translation: 'Посмотреть перевод', original: 'Посмотреть оригинал', retry: 'Повторить', failed: 'Перевод не удался. Показываю оригинал.', + translating: 'Перевод рассуждений', invalidProvider: 'Выберите услугу перевода.', invalidLanguage: 'Введите auto или код языка, например zh, en или ja.', + overridden: 'Переопределено', reset: 'Сбросить настройки по умолчанию', + unavailable: 'Настройки перевода недоступны.', readOnly: 'В этом развертывании параметры сохраняются только для чтения.', + saveFailed: 'Развертывание не приняло эти значения; их оставили вам на исправление.', save: 'Сохранить', saving: 'Сохранение…', + copy: 'Копировать', copied: 'Скопировано', codeTitle: 'Блок кода', wrap: 'Переносить строки', unwrap: 'Развернуть линии', footnotes: 'Сноски', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + provider: 'Serviço de tradução', google: 'Google', bing: 'Google', + deepseekAccount: 'DeepSeek Flash — conta (paga)', deepseekOfficial: 'DeepSeek Flash — oficial API (pago)', + providerUnavailableOption: '{provider} — indisponível', + providerUnavailable: 'Este provedor não está disponível. Configure sua conta DeepSeek ou provedor API oficial ou escolha um serviço disponível.', + paidNotice: 'Cada fragmento não armazenado em cache envia uma solicitação Flash DeepSeek paga separada por meio da conta selecionada ou das credenciais API oficiais. A reabertura do raciocínio reutiliza resultados salvos; alterar o provedor, o idioma, o texto fonte ou as configurações da solicitação pode enviar uma nova solicitação paga.', + anonymousNotice: 'O Bing e o Google não precisam de login de tradução ou chave API. Seus endpoints anônimos podem rejeitar ou limitar solicitações.', targetLanguage: 'Idioma alvo', + targetLanguageHint: 'auto segue o idioma da UI; códigos de idioma como zh, en e ja também funcionam.', + privacy: 'O raciocínio expandido é enviado ao serviço selecionado. Pode conter código privado ou detalhes da conversa.', + translation: 'Ver tradução', original: 'Ver original', retry: 'Tentar novamente', failed: 'A tradução falhou. Mostrando o original.', + translating: 'Traduzindo o raciocínio', invalidProvider: 'Escolha um serviço de tradução.', invalidLanguage: 'Insira auto ou um código de idioma, como zh, en ou ja.', + overridden: 'Substituído', reset: 'Redefinir para o padrão', + unavailable: 'As preferências de tradução não estão disponíveis.', readOnly: 'Esta implantação armazena configurações somente leitura.', + saveFailed: 'A implantação não aceitou esses valores; eles foram deixados para você corrigir.', save: 'Salvar', saving: 'Salvando…', + copy: 'Copiar', copied: 'Copiado', codeTitle: 'Bloco de código', wrap: 'Quebrar linhas', unwrap: 'Desembrulhar linhas', footnotes: 'Notas de rodapé', +} satisfies Record diff --git a/packages/experimental/client-ui-cot-translation/src/client/mount.ts b/packages/experimental/client-ui-cot-translation/src/client/mount.ts index 10e81f52fa..18b8e5b592 100644 --- a/packages/experimental/client-ui-cot-translation/src/client/mount.ts +++ b/packages/experimental/client-ui-cot-translation/src/client/mount.ts @@ -14,7 +14,7 @@ import type { CotTranslationPreferences, CotTranslationSnapshot } from '../prefe import { TranslationBody, type TranslationBodyInjected } from './TranslationBody.tsx' import { TranslationSettings } from './TranslationSettings.tsx' import { TranslationPreferencesForm } from './preferences-form.ts' -import { en, ja, NS, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, NS, zh } from './locales.ts' /** Services required to mount the optional Remote and UI contributions. */ export const inject = ['remote', 'slots', 'locale', 'configForms'] @@ -80,7 +80,7 @@ async function registerUi(ctx: Context, lifetime: AbortController): Promise('cot-translation') ctx.effect(() => scope.subscribe(invalidate)) - ctx.effect(() => ctx.locale.register(NS, { en, zh, ja })) + ctx.effect(() => ctx.locale.register(NS, { en, zh, ja, es, fr, de, ru, pt })) const form = new TranslationPreferencesForm(scope) ctx.effect(() => () => { form.dispose() }) const injected = (sessionId: SessionId): TranslationBodyInjected => ({ diff --git a/packages/experimental/client-ui-voice-input/locale/de.json b/packages/experimental/client-ui-voice-input/locale/de.json new file mode 100644 index 0000000000..e5ba1faab6 --- /dev/null +++ b/packages/experimental/client-ui-voice-input/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sprachaufzeichnung", + "description": "Zeichnen Sie Sprache auf und fügen Sie bearbeitbaren Text in den Gesprächsentwurf ein." + } +} diff --git a/packages/experimental/client-ui-voice-input/locale/es.json b/packages/experimental/client-ui-voice-input/locale/es.json new file mode 100644 index 0000000000..495a5b18be --- /dev/null +++ b/packages/experimental/client-ui-voice-input/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Grabación de voz", + "description": "Grabe discursos e inserte texto editable en el borrador de la conversación." + } +} diff --git a/packages/experimental/client-ui-voice-input/locale/fr.json b/packages/experimental/client-ui-voice-input/locale/fr.json new file mode 100644 index 0000000000..9ba1dd52cb --- /dev/null +++ b/packages/experimental/client-ui-voice-input/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Enregistrement vocal", + "description": "Enregistrez le discours et insérez du texte modifiable dans le brouillon de la conversation." + } +} diff --git a/packages/experimental/client-ui-voice-input/locale/pt.json b/packages/experimental/client-ui-voice-input/locale/pt.json new file mode 100644 index 0000000000..b602c429db --- /dev/null +++ b/packages/experimental/client-ui-voice-input/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Gravação de voz", + "description": "Grave a fala e insira texto editável no rascunho da conversa." + } +} diff --git a/packages/experimental/client-ui-voice-input/locale/ru.json b/packages/experimental/client-ui-voice-input/locale/ru.json new file mode 100644 index 0000000000..d7c14b7c94 --- /dev/null +++ b/packages/experimental/client-ui-voice-input/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Запись голоса", + "description": "Записывайте речь и вставляйте редактируемый текст в черновик беседы." + } +} diff --git a/packages/experimental/client-ui-voice-input/src/client/PreparationCard.tsx b/packages/experimental/client-ui-voice-input/src/client/PreparationCard.tsx index bdff8e4b85..f279d2bc99 100644 --- a/packages/experimental/client-ui-voice-input/src/client/PreparationCard.tsx +++ b/packages/experimental/client-ui-voice-input/src/client/PreparationCard.tsx @@ -140,7 +140,7 @@ export function VoicePreparation({ useSpeechReadiness, ...props }: Pick provider.id === catalog.selection.providerId) const languageNames: Readonly> = { - auto: props.t('auto'), zh: props.t('zh'), en: props.t('en'), yue: props.t('yue'), ja: props.t('ja'), ko: props.t('ko'), + auto: props.t('auto'), zh: props.t('zh'), en: props.t('en'), yue: props.t('yue'), ja: props.t('ja'), es: props.t('es'), fr: props.t('fr'), de: props.t('de'), ru: props.t('ru'), pt: props.t('pt'), ko: props.t('ko'), } return
{catalog &&
diff --git a/packages/experimental/client-ui-voice-input/src/client/locales.ts b/packages/experimental/client-ui-voice-input/src/client/locales.ts index e196e86d60..b97a84d3b1 100644 --- a/packages/experimental/client-ui-voice-input/src/client/locales.ts +++ b/packages/experimental/client-ui-voice-input/src/client/locales.ts @@ -90,7 +90,7 @@ export const zh = { inputLevel: '麦克风输入电平', deviceUnavailable: '不可用', deviceMissing: '麦克风不可用,请选择其他输入设备', - auto: '自动识别', zh: '中文', en: '英语', yue: '粤语', ja: '日语', ko: '韩语', + auto: '自动识别', zh: '中文', en: '英语', yue: '粤语', ja: '日语', es: '日语', fr: '日语', de: '日语', ru: '日语', pt: '日语', ko: '韩语', start: '开始录音', stop: '停止并识别', cancel: '取消', insert: '插入文字', loading: '正在读取识别服务…', requesting: '请允许使用麦克风…', recording: '正在录音…', interrupted: '录音中断,请重试。', @@ -194,7 +194,7 @@ export const en: Record = { inputLevel: 'Microphone input level', deviceUnavailable: 'Unavailable', deviceMissing: 'Microphone unavailable. Choose another input device.', - auto: 'Detect automatically', zh: 'Chinese', en: 'English', yue: 'Cantonese', ja: 'Japanese', ko: 'Korean', + auto: 'Detect automatically', zh: 'Chinese', en: 'English', yue: 'Cantonese', ja: 'Japanese', es: 'Japanese', fr: 'Japanese', de: 'Japanese', ru: 'Japanese', pt: 'Japanese', ko: 'Korean', start: 'Start recording', stop: 'Stop and transcribe', cancel: 'Cancel', insert: 'Insert text', loading: 'Loading recognition services…', requesting: 'Allow microphone access to continue…', recording: 'Recording…', interrupted: 'Recording was interrupted. Please try again.', @@ -307,7 +307,7 @@ export const ja = { 'zh': '中国語', 'en': '英語', 'yue': '広東語', - 'ja': '日本語', + 'ja': '日本語', es: '日本語', fr: '日本語', de: '日本語', ru: '日本語', pt: '日本語', 'ko': '韓国語', 'start': '録音を開始', 'stop': '停止して文字起こし', @@ -327,3 +327,508 @@ export const ja = { 'permission': 'マイクへのアクセスが無効になっています。ブラウザとシステムの設定で許可してください。', 'tooLarge': '録音がサービスの上限を超えています。短い録音をお試しください。', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + dictate: 'Dictar', + 'setupPrompt.title': 'Configurar la entrada de voz antes de grabar', + 'setupPrompt.body': 'La entrada de voz está habilitada. El primer uso requiere descargar y preparar modelos de reconocimiento local. Abra los detalles del complemento para revisar las estimaciones de espacio en disco, memoria y tiempo antes de comenzar la configuración.', + 'setupPrompt.later': 'Más tarde', + 'setupPrompt.open': 'Ir a configuración', + 'setupPrompt.trigger': 'Abrir configuración de entrada de voz', + 'setupPrompt.details': 'Abrir la configuración del complemento de voz', + 'setupPrompt.unavailableTitle': 'El reconocimiento de voz no está listo', + 'setupPrompt.unavailableBody': 'Abra los detalles del complemento de voz para verificar el estado del reconocimiento, el progreso de la preparación o los errores.', + 'setup.local': 'Los modelos locales se descargarán en la máquina que ejecuta DSH. No se requiere Python ni compilador.', + 'setup.disk': 'Espacio en disco', + 'setup.diskValue': 'Permitir aproximadamente {gb} GB para modelos, tiempo de ejecución y cachés de descarga', + 'setup.memory': 'Memoria', + 'setup.memoryValue': 'Aproximadamente {gb} GB con el modelo cargado; el reconocimiento puede utilizar más', + 'setup.time': 'Primera configuración', + 'setup.timeValue': 'Espere aproximadamente {min}–{max} minutos, dependiendo de la red y la máquina', + 'setup.estimateNote': 'Éstas son estimaciones; las redes lentas pueden tardar más. Las descargas se reutilizan; Los modelos inactivos liberan memoria de forma predeterminada.', + 'step.check': 'Consulta los recursos locales', + 'step.model': 'Preparar modelo de reconocimiento.', + 'step.vad': 'Preparar modelo de detección de voz.', + 'step.verify': 'Verificar archivos de modelo', + 'step.load': 'Cargar {name}', + 'stepStatus.pending': 'No iniciado', + 'stepStatus.running': 'En progreso', + 'stepStatus.complete': 'Completado', + 'stepStatus.failed': 'Fallido', + 'stepStatus.cancelled': 'Cancelado', + 'short.downloading': 'Descargando', + 'short.failed': 'Error de configuración', + retryRecording: 'Grabar de nuevo', + preparationSteps: 'Pasos de preparación', + 'prepare': 'Descargar y preparar', + 'retryPrepare': 'Reintentar la preparación', + 'cancelPrepare': 'Cancelar preparación', + 'downloadProgress': 'Descargar progreso', + 'downloadBytes': 'Descargar: {completed} / {total} MB, {percent}%', + 'downloadUnknown': 'Descargado {completed} MB', + 'elapsed': 'Esperando {seconds} segundos', + 'preparationFailed': 'Error de preparación: {message}', + 'download.network': 'No se puede descargar {resource}: falló la conexión al servicio de descarga.', + 'download.dns': 'No se puede descargar {resource}: no se pudo resolver la dirección de descarga.', + 'download.timeout': 'Se agotó el tiempo de descarga de {resource}.', + 'download.certificate': 'No se puede descargar {resource}: falló la verificación del certificado.', + 'download.http': 'No se puede descargar {resource}: el servicio de descarga devolvió HTTP {status}.', + 'download.integrity': 'La descarga de {resource} está incompleta o falló la verificación.', + 'download.storage': 'No se puede guardar {resource}: espacio en disco insuficiente o permiso de escritura.', + 'download.unknown': 'No se pudo preparar {resource}.', + 'downloadAdvice.network': 'Verifique que la máquina que ejecuta DSH pueda acceder a la fuente de descarga y sus servicios de descarga de modelos. Configure un proxy en esa máquina si es necesario y luego vuelva a intentarlo.', + 'downloadAdvice.dns': 'Verifique la configuración de DNS y proxy en la máquina que ejecuta DSH. Confirme que puede resolver el dominio de origen de la descarga y luego vuelva a intentarlo.', + 'downloadAdvice.timeout': 'Verifique la conexión de red o proxy en la máquina que ejecuta DSH y vuelva a intentarlo más tarde. Los archivos descargados verificados se conservan.', + 'downloadAdvice.certificate': 'Verifique el reloj del sistema, los certificados confiables y la configuración del proxy en la máquina que ejecuta DSH, luego vuelva a intentarlo.', + 'downloadAdvice.http': 'Confirme que la dirección de descarga esté disponible y que el proxy pueda comunicarse con el servicio de descarga, o vuelva a intentarlo más tarde.', + 'downloadAdvice.integrity': 'Vuelva a intentar la descarga. Se conservan otros archivos completos y verificados.', + 'downloadAdvice.storage': 'Verifique el espacio disponible en disco y el permiso de escritura para el directorio del modelo en la máquina que ejecuta DSH, luego vuelva a intentarlo.', + 'downloadAdvice.unknown': 'Verifique los permisos de red, espacio en disco y directorio de modelos en la máquina que ejecuta DSH, luego vuelva a intentarlo.', + downloadSource: 'Fuente de descarga: {source}', + sourceChoice: 'Fuente de descarga del modelo', + sourceAuto: 'Automático (recomendado)', + sourceHuggingFace: 'abrazando la cara', + sourceMirror: 'Espejo HF (espejo chino)', + sourceAutoHelp: 'Prefiere la primera fuente que respondió y prueba con otra si falla la descarga.', + sourceManualHelp: 'Descargue solo desde la fuente seleccionada. Los archivos descargados verificados se reutilizan.', + downloadCode: 'Código de error: {code}', + 'reconnecting': 'Conectándose al reconocimiento de voz...', + 'preparation.unprepared': 'El primer uso descarga los modelos de reconocimiento local.', + 'preparation.checking': 'Comprobando los recursos locales...', + 'preparation.loading': 'Cargando {name}…', + 'preparation.waking': 'Activando el reconocimiento de voz local...', + 'preparation.ready': 'El reconocimiento de voz local está listo.', + 'preparation.standby': 'Los recursos locales están preparados. La grabación despierta el reconocedor.', + 'preparation.cancelled': 'Preparación cancelada. Las descargas completadas se conservan.', + 'preparation.cancelling': 'Cancelando preparación…', + + cloudReady: 'El reconocimiento de voz en la nube está listo.', + discard: 'Descartar transcripción', + transcribingShort: 'Transcribiendo…', wakingShort: 'Despertando…', + provider: 'Servicio de reconocimiento', language: 'Idioma de reconocimiento', + inputDevice: 'Dispositivo de entrada', + systemMicrophone: 'Valor predeterminado del sistema', + systemMicrophoneNamed: 'Valor predeterminado del sistema ({name})', + unnamedSelectedMicrophone: 'micrófono', + unnamedMicrophone: 'Micrófono {number}', + inputLevel: 'Nivel de entrada del micrófono', + deviceUnavailable: 'No disponible', + deviceMissing: 'Micrófono no disponible. Elija otro dispositivo de entrada.', + auto: 'Detectar automáticamente', zh: 'chino', en: 'ingles', yue: 'cantonés', ja: 'japonés', es: 'japonés', fr: 'japonés', de: 'japonés', ru: 'japonés', pt: 'japonés', ko: 'coreano', + start: 'Empezar a grabar', stop: 'Detener y transcribir', cancel: 'Cancelar', insert: 'Insertar texto', + loading: 'Cargando servicios de reconocimiento…', requesting: 'Permitir el acceso al micrófono para continuar...', recording: 'Grabando…', + interrupted: 'La grabación fue interrumpida. Por favor inténtalo de nuevo.', + local: 'El audio se reconoce en la máquina que ejecuta DSH. Si es necesario descargar modelos, esa máquina debe poder acceder a la fuente seleccionada y sus servicios de archivos. Configure un proxy en esa máquina si es necesario.', + cloud: 'El audio se enviará al servicio en la nube seleccionado.', + empty: 'No se reconoce ningún discurso', cancelled: 'Entrada de voz cancelada.', + conflict: 'Tu borrador cambió. La transcripción se conserva y se puede insertar en el cursor actual.', + failed: 'Error en el reconocimiento de voz: {message}', + unavailable: 'Este navegador no puede grabar audio. Utilice un navegador compatible con micrófono.', + permission: 'El acceso al micrófono está deshabilitado. Permitirlo en la configuración del navegador y del sistema.', + tooLarge: 'La grabación excede el límite del servicio. Pruebe con una grabación más corta.', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + dictate: 'Dicter', + 'setupPrompt.title': "Configurer la saisie vocale avant l'enregistrement", + 'setupPrompt.body': "La saisie vocale est activée. La première utilisation nécessite le téléchargement et la préparation de modèles de reconnaissance locaux. Ouvrez les détails du plugin pour consulter les estimations d'espace disque, de mémoire et de temps avant de démarrer l'installation.", + 'setupPrompt.later': 'Plus tard', + 'setupPrompt.open': 'Aller à la configuration', + 'setupPrompt.trigger': 'Ouvrir la configuration de la saisie vocale', + 'setupPrompt.details': 'Ouvrir les paramètres du plugin vocal', + 'setupPrompt.unavailableTitle': "La reconnaissance vocale n'est pas prête", + 'setupPrompt.unavailableBody': "Ouvrez les détails du plug-in vocal pour vérifier l'état de reconnaissance, la progression de la préparation ou les erreurs.", + 'setup.local': "Les modèles locaux seront téléchargés sur la machine exécutant DSH. Aucun Python ou compilateur n'est requis.", + 'setup.disk': 'Espace disque', + 'setup.diskValue': "Autoriser environ {gb} Go pour les modèles, l'environnement d'exécution et les caches de téléchargement", + 'setup.memory': 'Mémoire', + 'setup.memoryValue': 'À propos de {gb} GB avec le modèle chargé ; la reconnaissance peut utiliser plus', + 'setup.time': 'Première configuration', + 'setup.timeValue': 'Prévoyez environ des minutes {min} à {max}, en fonction du réseau et de la machine.', + 'setup.estimateNote': 'Ce sont des estimations ; les réseaux lents peuvent prendre plus de temps. Les téléchargements sont réutilisés ; les modèles inactifs libèrent de la mémoire par défaut.', + 'step.check': 'Vérifiez les ressources locales', + 'step.model': 'Préparer le modèle de reconnaissance', + 'step.vad': 'Préparer le modèle de détection vocale', + 'step.verify': 'Vérifier les fichiers de modèle', + 'step.load': 'Charger {name}', + 'stepStatus.pending': 'Pas démarré', + 'stepStatus.running': 'En cours', + 'stepStatus.complete': 'Terminé', + 'stepStatus.failed': 'Échec', + 'stepStatus.cancelled': 'Annulé', + 'short.downloading': 'Téléchargement', + 'short.failed': "Échec de l'installation", + retryRecording: 'Enregistrer à nouveau', + preparationSteps: 'Étapes de préparation', + 'prepare': 'Téléchargez et préparez', + 'retryPrepare': 'Réessayer la préparation', + 'cancelPrepare': 'Annuler la préparation', + 'downloadProgress': 'Progression du téléchargement', + 'downloadBytes': 'Télécharger : {completed} / {total} MB, {percent}%', + 'downloadUnknown': 'Téléchargé {completed} MB', + 'elapsed': 'En attente de {seconds} secondes', + 'preparationFailed': 'Échec de la préparation : {message}', + 'download.network': 'Impossible de télécharger {resource} : la connexion au service de téléchargement a échoué.', + 'download.dns': "Impossible de télécharger {resource} : l'adresse de téléchargement n'a pas pu être résolue.", + 'download.timeout': 'Le téléchargement de {resource} a expiré.', + 'download.certificate': 'Impossible de télécharger {resource} : la vérification du certificat a échoué.', + 'download.http': 'Impossible de télécharger {resource} : le service de téléchargement a renvoyé HTTP {status}.', + 'download.integrity': 'Le téléchargement de {resource} est incomplet ou la vérification a échoué.', + 'download.storage': "Impossible d'enregistrer {resource} : espace disque ou autorisation d'écriture insuffisante.", + 'download.unknown': 'Impossible de préparer {resource}.', + 'downloadAdvice.network': 'Vérifiez que la machine exécutant DSH peut accéder à la source de téléchargement et à ses services de téléchargement de modèles. Configurez un proxy sur cette machine si nécessaire, puis réessayez.', + 'downloadAdvice.dns': "Vérifiez les paramètres DNS et proxy sur la machine exécutant DSH. Confirmez qu'il peut résoudre le domaine source de téléchargement, puis réessayez.", + 'downloadAdvice.timeout': 'Vérifiez la connexion réseau ou proxy sur la machine exécutant DSH, puis réessayez plus tard. Les fichiers téléchargés vérifiés sont conservés.', + 'downloadAdvice.certificate': "Vérifiez l'horloge système, les certificats de confiance et les paramètres de proxy sur la machine exécutant DSH, puis réessayez.", + 'downloadAdvice.http': "Confirmez que l'adresse de téléchargement est disponible et que le proxy peut accéder au service de téléchargement, ou réessayez plus tard.", + 'downloadAdvice.integrity': 'Réessayez le téléchargement. Les autres dossiers complétés et vérifiés sont conservés.', + 'downloadAdvice.storage': "Vérifiez l'espace disque disponible et les autorisations d'écriture pour le répertoire modèle sur la machine exécutant DSH, puis réessayez.", + 'downloadAdvice.unknown': "Vérifiez les autorisations du réseau, de l'espace disque et du répertoire modèle sur la machine exécutant DSH, puis réessayez.", + downloadSource: 'Source du téléchargement : {source}', + sourceChoice: 'Source de téléchargement du modèle', + sourceAuto: 'Automatique (recommandé)', + sourceHuggingFace: 'Visage câlin', + sourceMirror: 'Miroir HF (miroir chinois)', + sourceAutoHelp: 'Préférez la première source qui répond et essayez-en une autre si un téléchargement échoue.', + sourceManualHelp: 'Téléchargez uniquement à partir de la source sélectionnée. Les fichiers téléchargés vérifiés sont réutilisés.', + downloadCode: "Code d'erreur : {code}", + 'reconnecting': 'Connexion à la reconnaissance vocale…', + 'preparation.unprepared': 'La première utilisation télécharge les modèles de reconnaissance locaux.', + 'preparation.checking': 'Vérification des ressources locales…', + 'preparation.loading': 'Chargement de {name}…', + 'preparation.waking': 'Réveiller la reconnaissance vocale locale…', + 'preparation.ready': 'La reconnaissance vocale locale est prête.', + 'preparation.standby': "Des ressources locales sont préparées. L'enregistrement réveille le module de reconnaissance.", + 'preparation.cancelled': 'Préparation annulée. Les téléchargements terminés sont conservés.', + 'preparation.cancelling': 'Annulation de la préparation…', + + cloudReady: 'La reconnaissance vocale dans le cloud est prête.', + discard: 'Supprimer la transcription', + transcribingShort: 'Transcription…', wakingShort: 'Le réveil…', + provider: 'Service de reconnaissance', language: 'Langue de reconnaissance', + inputDevice: "Périphérique d'entrée", + systemMicrophone: 'Valeur par défaut du système', + systemMicrophoneNamed: 'Valeur par défaut du système ({name})', + unnamedSelectedMicrophone: 'Micro', + unnamedMicrophone: 'Micro {number}', + inputLevel: "Niveau d'entrée du microphone", + deviceUnavailable: 'Indisponible', + deviceMissing: "Micro indisponible. Choisissez un autre périphérique d'entrée.", + auto: 'Détecter automatiquement', zh: 'Chinois', en: 'Anglais', yue: 'Cantonais', ja: 'Japonais', es: 'Japonais', fr: 'Japonais', de: 'Japonais', ru: 'Japonais', pt: 'Japonais', ko: 'Coréen', + start: "Commencer l'enregistrement", stop: 'Arrêtez et transcrivez', cancel: 'Annuler', insert: 'Insérer du texte', + loading: 'Chargement des services de reconnaissance…', requesting: 'Autoriser l’accès au microphone pour continuer…', recording: 'Enregistrement…', + interrupted: "L'enregistrement a été interrompu. Veuillez réessayer.", + local: "L'audio est reconnu sur la machine exécutant DSH. Si les modèles doivent être téléchargés, cette machine doit pouvoir accéder à la source sélectionnée et à ses services de fichiers. Configurez un proxy sur cette machine si nécessaire.", + cloud: "L'audio sera envoyé au service cloud sélectionné.", + empty: 'Aucun discours reconnu', cancelled: 'Saisie vocale annulée.', + conflict: 'Votre brouillon a changé. La transcription est conservée et peut être insérée au niveau du curseur actuel.', + failed: 'Échec de la reconnaissance vocale : {message}', + unavailable: 'Ce navigateur ne peut pas enregistrer de son. Utilisez un navigateur prenant en charge le microphone.', + permission: "L'accès au microphone est désactivé. Autorisez-le dans les paramètres du navigateur et du système.", + tooLarge: "L'enregistrement dépasse la limite du service. Essayez un enregistrement plus court.", +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + dictate: 'Diktieren', + 'setupPrompt.title': 'Richten Sie vor der Aufnahme die Spracheingabe ein', + 'setupPrompt.body': 'Die Spracheingabe ist aktiviert. Für die erste Verwendung müssen lokale Erkennungsmodelle heruntergeladen und vorbereitet werden. Öffnen Sie die Plugin-Details, um die Schätzungen zu Speicherplatz, Speicher und Zeit zu überprüfen, bevor Sie mit der Einrichtung beginnen.', + 'setupPrompt.later': 'Später', + 'setupPrompt.open': 'Gehen Sie zum Setup', + 'setupPrompt.trigger': 'Öffnen Sie die Einrichtung der Spracheingabe', + 'setupPrompt.details': 'Öffnen Sie die Sprach-Plugin-Einstellungen', + 'setupPrompt.unavailableTitle': 'Die Spracherkennung ist noch nicht bereit', + 'setupPrompt.unavailableBody': 'Öffnen Sie die Details des Sprach-Plugins, um den Erkennungsstatus, den Vorbereitungsfortschritt oder Fehler zu überprüfen.', + 'setup.local': 'Lokale Modelle werden auf den Computer heruntergeladen, auf dem DSH ausgeführt wird. Es ist kein Python oder Compiler erforderlich.', + 'setup.disk': 'Speicherplatz', + 'setup.diskValue': 'Planen Sie etwa {gb} GB für Modelle, Laufzeit und Download-Caches ein', + 'setup.memory': 'Erinnerung', + 'setup.memoryValue': 'Über {gb} GB mit geladenem Modell; Anerkennung kann mehr gebrauchen', + 'setup.time': 'Erste Einrichtung', + 'setup.timeValue': 'Planen Sie je nach Netzwerk und Maschine etwa {min}–{max} Minuten ein', + 'setup.estimateNote': 'Es handelt sich hierbei um Schätzungen; Bei langsamen Netzwerken kann es länger dauern. Downloads werden wiederverwendet; Leerlaufmodelle geben standardmäßig Speicher frei.', + 'step.check': 'Überprüfen Sie lokale Ressourcen', + 'step.model': 'Erkennungsmodell vorbereiten', + 'step.vad': 'Bereiten Sie ein Spracherkennungsmodell vor', + 'step.verify': 'Modelldateien überprüfen', + 'step.load': 'Laden Sie {name}', + 'stepStatus.pending': 'Nicht gestartet', + 'stepStatus.running': 'In Bearbeitung', + 'stepStatus.complete': 'Abgeschlossen', + 'stepStatus.failed': 'Fehlgeschlagen', + 'stepStatus.cancelled': 'Abgesagt', + 'short.downloading': 'Herunterladen', + 'short.failed': 'Die Einrichtung ist fehlgeschlagen', + retryRecording: 'Nochmals aufnehmen', + preparationSteps: 'Vorbereitungsschritte', + 'prepare': 'Herunterladen und vorbereiten', + 'retryPrepare': 'Wiederholen Sie die Vorbereitung', + 'cancelPrepare': 'Vorbereitung abbrechen', + 'downloadProgress': 'Download-Fortschritt', + 'downloadBytes': 'Herunterladen: {completed} / {total} MB, {percent}%', + 'downloadUnknown': '{completed} MB heruntergeladen', + 'elapsed': 'Warten {seconds} Sekunden', + 'preparationFailed': 'Vorbereitung fehlgeschlagen: {message}', + 'download.network': '{resource} kann nicht heruntergeladen werden: Die Verbindung zum Download-Dienst ist fehlgeschlagen.', + 'download.dns': '{resource} kann nicht heruntergeladen werden: Die Download-Adresse konnte nicht aufgelöst werden.', + 'download.timeout': 'Beim Herunterladen von {resource} ist eine Zeitüberschreitung aufgetreten.', + 'download.certificate': '{resource} kann nicht heruntergeladen werden: Zertifikatüberprüfung fehlgeschlagen.', + 'download.http': '{resource} kann nicht heruntergeladen werden: Der Download-Dienst hat HTTP {status} zurückgegeben.', + 'download.integrity': 'Der Download von {resource} ist unvollständig oder die Überprüfung ist fehlgeschlagen.', + 'download.storage': '{resource} kann nicht gespeichert werden: nicht genügend Speicherplatz oder Schreibberechtigung.', + 'download.unknown': '{resource} konnte nicht vorbereitet werden.', + 'downloadAdvice.network': 'Überprüfen Sie, ob der Computer, auf dem DSH ausgeführt wird, die Download-Quelle und ihre Modell-Download-Dienste erreichen kann. Konfigurieren Sie bei Bedarf einen Proxy auf diesem Computer und versuchen Sie es dann erneut.', + 'downloadAdvice.dns': 'Überprüfen Sie die DNS- und Proxy-Einstellungen auf dem Computer, auf dem DSH ausgeführt wird. Bestätigen Sie, dass die Download-Quelldomäne aufgelöst werden kann, und versuchen Sie es dann erneut.', + 'downloadAdvice.timeout': 'Überprüfen Sie die Netzwerk- oder Proxy-Verbindung auf dem Computer, auf dem DSH ausgeführt wird, und versuchen Sie es später erneut. Verifizierte heruntergeladene Dateien bleiben erhalten.', + 'downloadAdvice.certificate': 'Überprüfen Sie die Systemuhr, vertrauenswürdige Zertifikate und Proxy-Einstellungen auf dem Computer, auf dem DSH ausgeführt wird, und versuchen Sie es dann erneut.', + 'downloadAdvice.http': 'Bestätigen Sie, dass die Download-Adresse verfügbar ist und der Proxy den Download-Dienst erreichen kann, oder versuchen Sie es später noch einmal.', + 'downloadAdvice.integrity': 'Versuchen Sie den Download erneut. Andere abgeschlossene und überprüfte Dateien bleiben erhalten.', + 'downloadAdvice.storage': 'Überprüfen Sie den verfügbaren Speicherplatz und die Schreibberechtigung für das Modellverzeichnis auf dem Computer, auf dem DSH ausgeführt wird, und versuchen Sie es dann erneut.', + 'downloadAdvice.unknown': 'Überprüfen Sie die Netzwerk-, Festplattenspeicher- und Modellverzeichnisberechtigungen auf dem Computer, auf dem DSH ausgeführt wird, und versuchen Sie es dann erneut.', + downloadSource: 'Download-Quelle: {source}', + sourceChoice: 'Modell-Downloadquelle', + sourceAuto: 'Automatisch (empfohlen)', + sourceHuggingFace: 'Umarmendes Gesicht', + sourceMirror: 'HF-Spiegel (China-Spiegel)', + sourceAutoHelp: 'Bevorzugen Sie die erste antwortende Quelle und versuchen Sie es mit einer anderen, wenn ein Download fehlschlägt.', + sourceManualHelp: 'Nur von der ausgewählten Quelle herunterladen. Verifizierte heruntergeladene Dateien werden wiederverwendet.', + downloadCode: 'Fehlercode: {code}', + 'reconnecting': 'Verbindung zur Spracherkennung herstellen…', + 'preparation.unprepared': 'Bei der ersten Verwendung werden die lokalen Erkennungsmodelle heruntergeladen.', + 'preparation.checking': 'Lokale Ressourcen prüfen…', + 'preparation.loading': 'Laden {name}…', + 'preparation.waking': 'Lokale Spracherkennung aktivieren…', + 'preparation.ready': 'Die lokale Spracherkennung ist bereit.', + 'preparation.standby': 'Lokale Ressourcen werden vorbereitet. Durch die Aufnahme wird der Erkenner aktiviert.', + 'preparation.cancelled': 'Vorbereitung abgebrochen. Abgeschlossene Downloads bleiben erhalten.', + 'preparation.cancelling': 'Vorbereitung abbrechen…', + + cloudReady: 'Die Cloud-Spracherkennung ist fertig.', + discard: 'Transkript verwerfen', + transcribingShort: 'Transkribieren…', wakingShort: 'Aufwachen…', + provider: 'Anerkennungsdienst', language: 'Erkennungssprache', + inputDevice: 'Eingabegerät', + systemMicrophone: 'Systemstandard', + systemMicrophoneNamed: 'Systemstandard ({name})', + unnamedSelectedMicrophone: 'Mikrofon', + unnamedMicrophone: 'Mikrofon {number}', + inputLevel: 'Mikrofoneingangspegel', + deviceUnavailable: 'Nicht verfügbar', + deviceMissing: 'Mikrofon nicht verfügbar. Wählen Sie ein anderes Eingabegerät.', + auto: 'Automatisch erkennen', zh: 'Chinesisch', en: 'Englisch', yue: 'Kantonesisch', ja: 'Japanisch', es: 'Japanisch', fr: 'Japanisch', de: 'Japanisch', ru: 'Japanisch', pt: 'Japanisch', ko: 'Koreanisch', + start: 'Starten Sie die Aufnahme', stop: 'Stoppen Sie und transkribieren Sie', cancel: 'Abbrechen', insert: 'Text einfügen', + loading: 'Erkennungsdienste werden geladen…', requesting: 'Mikrofonzugriff erlauben, um fortzufahren…', recording: 'Aufnahme…', + interrupted: 'Die Aufnahme wurde unterbrochen. Bitte versuchen Sie es erneut.', + local: 'Audio wird auf dem Computer erkannt, auf dem DSH ausgeführt wird. Wenn Modelle heruntergeladen werden müssen, muss dieser Computer in der Lage sein, die ausgewählte Quelle und ihre Dateidienste zu erreichen. Konfigurieren Sie bei Bedarf einen Proxy auf diesem Computer.', + cloud: 'Audio wird an den ausgewählten Cloud-Dienst gesendet.', + empty: 'Keine Sprache erkannt', cancelled: 'Spracheingabe abgebrochen.', + conflict: 'Ihr Entwurf wurde geändert. Das Transkript bleibt erhalten und kann am aktuellen Cursor eingefügt werden.', + failed: 'Spracherkennung fehlgeschlagen: {message}', + unavailable: 'Dieser Browser kann keine Audiodaten aufzeichnen. Verwenden Sie einen Browser mit Mikrofonunterstützung.', + permission: 'Der Mikrofonzugriff ist deaktiviert. Erlauben Sie es in den Browser- und Systemeinstellungen.', + tooLarge: 'Die Aufnahme überschreitet das Dienstlimit. Versuchen Sie es mit einer kürzeren Aufnahme.', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + dictate: 'Диктовать', + 'setupPrompt.title': 'Настройте голосовой ввод перед записью', + 'setupPrompt.body': 'Голосовой ввод включен. Для первого использования требуется загрузка и подготовка моделей локального распознавания. Откройте сведения о плагине, чтобы просмотреть оценки дискового пространства, памяти и времени перед началом установки.', + 'setupPrompt.later': 'Позже', + 'setupPrompt.open': 'Перейти к настройке', + 'setupPrompt.trigger': 'Открыть настройку голосового ввода', + 'setupPrompt.details': 'Открыть настройки голосового плагина', + 'setupPrompt.unavailableTitle': 'Распознавание речи не готово', + 'setupPrompt.unavailableBody': 'Откройте сведения о голосовом плагине, чтобы проверить статус распознавания, ход подготовки или наличие ошибок.', + 'setup.local': 'Локальные модели будут загружены на машину под управлением DSH. Никакой Python или компилятор не требуется.', + 'setup.disk': 'Дисковое пространство', + 'setup.diskValue': 'Разрешить около {gb} ГБ для моделей, среды выполнения и кешей загрузки.', + 'setup.memory': 'Память', + 'setup.memoryValue': 'О {gb} ГБ с загруженной моделью; признание может использовать больше', + 'setup.time': 'Первая настройка', + 'setup.timeValue': 'Разрешите примерно {min}–{max} минут, в зависимости от сети и машины.', + 'setup.estimateNote': 'Это оценки; медленные сети могут занять больше времени. Загрузки используются повторно; Неработающие модели освобождают память по умолчанию.', + 'step.check': 'Проверьте местные ресурсы', + 'step.model': 'Подготовьте модель распознавания', + 'step.vad': 'Подготовьте модель обнаружения голоса', + 'step.verify': 'Проверка файлов модели', + 'step.load': 'Загрузить {name}', + 'stepStatus.pending': 'Не запущено', + 'stepStatus.running': 'В процессе', + 'stepStatus.complete': 'Завершено', + 'stepStatus.failed': 'Не удалось', + 'stepStatus.cancelled': 'Отменено', + 'short.downloading': 'Загрузка', + 'short.failed': 'Установка не удалась', + retryRecording: 'Записать еще раз', + preparationSteps: 'Этапы подготовки', + 'prepare': 'Скачайте и подготовьте', + 'retryPrepare': 'Повторить подготовку', + 'cancelPrepare': 'Отменить подготовку', + 'downloadProgress': 'Прогресс загрузки', + 'downloadBytes': 'Скачать: {completed} / {total} MB, {percent}%', + 'downloadUnknown': 'Скачал {completed} МБ.', + 'elapsed': 'Ожидание {seconds} секунд.', + 'preparationFailed': 'Подготовка не удалась: {message}', + 'download.network': 'Невозможно загрузить {resource}: не удалось подключиться к службе загрузки.', + 'download.dns': 'Невозможно загрузить {resource}: не удалось определить адрес загрузки.', + 'download.timeout': 'Время загрузки {resource} истекло.', + 'download.certificate': 'Невозможно загрузить {resource}: проверка сертификата не удалась.', + 'download.http': 'Невозможно загрузить {resource}: служба загрузки вернула HTTP {status}.', + 'download.integrity': 'Загрузка {resource} является неполной или не прошла проверку.', + 'download.storage': 'Невозможно сохранить {resource}: недостаточно места на диске или разрешения на запись.', + 'download.unknown': 'Не удалось подготовить {resource}.', + 'downloadAdvice.network': 'Убедитесь, что машина, на которой работает DSH, может получить доступ к источнику загрузки и службам загрузки своей модели. При необходимости настройте прокси-сервер на этом компьютере, а затем повторите попытку.', + 'downloadAdvice.dns': 'Проверьте настройки DNS и прокси на машине под управлением DSH. Убедитесь, что он может разрешить домен источника загрузки, затем повторите попытку.', + 'downloadAdvice.timeout': 'Проверьте сетевое или прокси-соединение на компьютере, на котором работает DSH, затем повторите попытку позже. Проверенные загруженные файлы сохраняются.', + 'downloadAdvice.certificate': 'Проверьте системные часы, доверенные сертификаты и настройки прокси-сервера на компьютере, на котором работает DSH, затем повторите попытку.', + 'downloadAdvice.http': 'Убедитесь, что адрес загрузки доступен и прокси-сервер может связаться со службой загрузки, или повторите попытку позже.', + 'downloadAdvice.integrity': 'Повторите загрузку. Остальные заполненные и проверенные файлы сохраняются.', + 'downloadAdvice.storage': 'Проверьте доступное дисковое пространство и разрешение на запись для каталога модели на компьютере, на котором работает DSH, затем повторите попытку.', + 'downloadAdvice.unknown': 'Проверьте сеть, дисковое пространство и права доступа к каталогу модели на компьютере, на котором работает DSH, затем повторите попытку.', + downloadSource: 'Источник загрузки: {source}', + sourceChoice: 'Источник загрузки модели', + sourceAuto: 'Автоматический (рекомендуется)', + sourceHuggingFace: 'Обнимающее лицо', + sourceMirror: 'ВЧ-Зеркало (Китайское зеркало)', + sourceAutoHelp: 'Отдайте предпочтение первому ответившему источнику и попробуйте другой, если загрузка не удалась.', + sourceManualHelp: 'Скачивайте только из выбранного источника. Проверенные загруженные файлы используются повторно.', + downloadCode: 'Код ошибки: {code}', + 'reconnecting': 'Подключение к распознаванию речи…', + 'preparation.unprepared': 'При первом использовании загружаются модели локального распознавания.', + 'preparation.checking': 'Проверка местных ресурсов…', + 'preparation.loading': 'Загрузка {name}…', + 'preparation.waking': 'Пробуждение локального распознавания речи…', + 'preparation.ready': 'Локальное распознавание речи готово.', + 'preparation.standby': 'Подготовлены местные ресурсы. Запись будит распознаватель.', + 'preparation.cancelled': 'Подготовка отменена. Завершенные загрузки сохраняются.', + 'preparation.cancelling': 'Отмена подготовки…', + + cloudReady: 'Облачное распознавание речи готово.', + discard: 'Удалить расшифровку', + transcribingShort: 'Расшифровка…', wakingShort: 'Пробуждение…', + provider: 'Служба распознавания', language: 'Язык распознавания', + inputDevice: 'Устройство ввода', + systemMicrophone: 'Система по умолчанию', + systemMicrophoneNamed: 'Системное значение по умолчанию ({name})', + unnamedSelectedMicrophone: 'Микрофон', + unnamedMicrophone: 'Микрофон {number}', + inputLevel: 'Входной уровень микрофона', + deviceUnavailable: 'Недоступно', + deviceMissing: 'Микрофон недоступен. Выберите другое устройство ввода.', + auto: 'Обнаруживать автоматически', zh: 'китайский', en: 'английский', yue: 'Кантонский диалект', ja: 'японский', es: 'японский', fr: 'японский', de: 'японский', ru: 'японский', pt: 'японский', ko: 'корейский', + start: 'Начать запись', stop: 'Остановись и перепиши', cancel: 'Отмена', insert: 'Вставить текст', + loading: 'Загрузка служб распознавания…', requesting: 'Разрешите доступ к микрофону, чтобы продолжить…', recording: 'Запись…', + interrupted: 'Запись была прервана. Пожалуйста, попробуйте еще раз.', + local: 'Звук распознается на машине под управлением DSH. Если модели необходимо загрузить, этот компьютер должен иметь доступ к выбранному источнику и его файловым службам. При необходимости настройте прокси-сервер на этом компьютере.', + cloud: 'Аудио будет отправлено в выбранный облачный сервис.', + empty: 'Речь не распознается', cancelled: 'Голосовой ввод отменен.', + conflict: 'Ваш черновик изменился. Транскрипт сохраняется и может быть вставлен под текущий курсор.', + failed: 'Не удалось распознать речь: {message}.', + unavailable: 'Этот браузер не может записывать звук. Используйте браузер с поддержкой микрофона.', + permission: 'Доступ к микрофону отключен. Разрешите это в настройках браузера и системы.', + tooLarge: 'Запись превышает лимит обслуживания. Попробуйте более короткую запись.', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + dictate: 'Ditar', + 'setupPrompt.title': 'Configure a entrada de voz antes de gravar', + 'setupPrompt.body': 'A entrada de voz está habilitada. A primeira utilização requer o download e a preparação de modelos de reconhecimento local. Abra os detalhes do plug-in para revisar as estimativas de espaço em disco, memória e tempo antes de iniciar a configuração.', + 'setupPrompt.later': 'Mais tarde', + 'setupPrompt.open': 'Vá para configuração', + 'setupPrompt.trigger': 'Abra a configuração de entrada de voz', + 'setupPrompt.details': 'Abra as configurações do plugin de voz', + 'setupPrompt.unavailableTitle': 'O reconhecimento de fala não está pronto', + 'setupPrompt.unavailableBody': 'Abra os detalhes do plugin de voz para verificar o status do reconhecimento, o progresso da preparação ou erros.', + 'setup.local': 'Os modelos locais serão baixados para a máquina que executa DSH. Nenhum Python ou compilador é necessário.', + 'setup.disk': 'Espaço em disco', + 'setup.diskValue': 'Permitir cerca de {gb} GB para modelos, tempo de execução e caches de download', + 'setup.memory': 'Memória', + 'setup.memoryValue': 'Cerca de {gb} GB com o modelo carregado; o reconhecimento pode usar mais', + 'setup.time': 'Primeira configuração', + 'setup.timeValue': 'Aguarde aproximadamente {min}–{max} minutos, dependendo da rede e da máquina', + 'setup.estimateNote': 'Estas são estimativas; redes lentas podem demorar mais. Os downloads são reutilizados; modelos inativos liberam memória por padrão.', + 'step.check': 'Verifique os recursos locais', + 'step.model': 'Preparar modelo de reconhecimento', + 'step.vad': 'Preparar modelo de detecção de voz', + 'step.verify': 'Verifique os arquivos do modelo', + 'step.load': 'Carregar {name}', + 'stepStatus.pending': 'Não iniciado', + 'stepStatus.running': 'Em andamento', + 'stepStatus.complete': 'Concluído', + 'stepStatus.failed': 'Falha', + 'stepStatus.cancelled': 'Cancelado', + 'short.downloading': 'Baixando', + 'short.failed': 'Falha na configuração', + retryRecording: 'Grave novamente', + preparationSteps: 'Etapas de preparação', + 'prepare': 'Baixe e prepare', + 'retryPrepare': 'Tentar novamente a preparação', + 'cancelPrepare': 'Cancelar preparação', + 'downloadProgress': 'Progresso do download', + 'downloadBytes': 'Baixar: {completed} / {total} MB, {percent}%', + 'downloadUnknown': 'Download de {completed} MB', + 'elapsed': 'Aguardando {seconds} segundos', + 'preparationFailed': 'Falha na preparação: {message}', + 'download.network': 'Não é possível fazer download de {resource}: falha na conexão com o serviço de download.', + 'download.dns': 'Não é possível fazer download de {resource}: o endereço de download não pôde ser resolvido.', + 'download.timeout': 'O download de {resource} expirou.', + 'download.certificate': 'Não é possível fazer download de {resource}: falha na verificação do certificado.', + 'download.http': 'Não é possível fazer download de {resource}: o serviço de download retornou HTTP {status}.', + 'download.integrity': 'O download de {resource} está incompleto ou falhou na verificação.', + 'download.storage': 'Não é possível salvar {resource}: espaço em disco ou permissão de gravação insuficientes.', + 'download.unknown': 'Não foi possível preparar {resource}.', + 'downloadAdvice.network': 'Verifique se a máquina que executa DSH pode acessar a origem de download e seus serviços de download de modelo. Configure um proxy nessa máquina, se necessário, e tente novamente.', + 'downloadAdvice.dns': 'Verifique as configurações de DNS e proxy na máquina que executa DSH. Confirme se ele pode resolver o domínio de origem do download e tente novamente.', + 'downloadAdvice.timeout': 'Verifique a conexão de rede ou proxy na máquina que executa DSH e tente novamente mais tarde. Os arquivos baixados verificados são retidos.', + 'downloadAdvice.certificate': 'Verifique o relógio do sistema, os certificados confiáveis e as configurações de proxy na máquina que executa DSH e tente novamente.', + 'downloadAdvice.http': 'Confirme se o endereço de download está disponível e se o proxy pode acessar o serviço de download ou tente novamente mais tarde.', + 'downloadAdvice.integrity': 'Tente novamente o download. Outros arquivos concluídos e verificados são retidos.', + 'downloadAdvice.storage': 'Verifique o espaço em disco disponível e a permissão de gravação para o diretório de modelo na máquina que executa DSH e tente novamente.', + 'downloadAdvice.unknown': 'Verifique as permissões de rede, espaço em disco e diretório de modelo na máquina que executa DSH e tente novamente.', + downloadSource: 'Fonte de download: {source}', + sourceChoice: 'Fonte de download do modelo', + sourceAuto: 'Automático (recomendado)', + sourceHuggingFace: 'Abraçando o rosto', + sourceMirror: 'Espelho HF (espelho da China)', + sourceAutoHelp: 'Prefira a primeira fonte de resposta e tente outra se o download falhar.', + sourceManualHelp: 'Baixe apenas da fonte selecionada. Os arquivos baixados verificados são reutilizados.', + downloadCode: 'Código de erro: {code}', + 'reconnecting': 'Conectando ao reconhecimento de fala…', + 'preparation.unprepared': 'O primeiro uso baixa os modelos de reconhecimento local.', + 'preparation.checking': 'Verificando recursos locais…', + 'preparation.loading': 'Carregando {name}…', + 'preparation.waking': 'Ativando o reconhecimento de fala local…', + 'preparation.ready': 'O reconhecimento de fala local está pronto.', + 'preparation.standby': 'Os recursos locais estão preparados. A gravação desperta o reconhecedor.', + 'preparation.cancelled': 'Preparação cancelada. Os downloads concluídos são retidos.', + 'preparation.cancelling': 'Cancelando a preparação…', + + cloudReady: 'O reconhecimento de fala na nuvem está pronto.', + discard: 'Descartar transcrição', + transcribingShort: 'Transcrevendo…', wakingShort: 'Acordando…', + provider: 'Serviço de reconhecimento', language: 'Linguagem de reconhecimento', + inputDevice: 'Dispositivo de entrada', + systemMicrophone: 'Padrão do sistema', + systemMicrophoneNamed: 'Padrão do sistema ({name})', + unnamedSelectedMicrophone: 'Microfone', + unnamedMicrophone: 'Microfone {number}', + inputLevel: 'Nível de entrada do microfone', + deviceUnavailable: 'Indisponível', + deviceMissing: 'Microfone indisponível. Escolha outro dispositivo de entrada.', + auto: 'Detectar automaticamente', zh: 'Chinês', en: 'Inglês', yue: 'cantonês', ja: 'Japonês', es: 'Japonês', fr: 'Japonês', de: 'Japonês', ru: 'Japonês', pt: 'Japonês', ko: 'Coreano', + start: 'Comece a gravar', stop: 'Pare e transcreva', cancel: 'Cancelar', insert: 'Inserir texto', + loading: 'Carregando serviços de reconhecimento…', requesting: 'Permitir que o acesso ao microfone continue…', recording: 'Gravando…', + interrupted: 'A gravação foi interrompida. Por favor, tente novamente.', + local: 'O áudio é reconhecido na máquina que executa DSH. Se os modelos precisarem ser baixados, essa máquina deverá ser capaz de acessar a fonte selecionada e seus serviços de arquivo. Configure um proxy nessa máquina, se necessário.', + cloud: 'O áudio será enviado para o serviço de nuvem selecionado.', + empty: 'Nenhuma fala reconhecida', cancelled: 'Entrada de voz cancelada.', + conflict: 'Seu rascunho foi alterado. A transcrição é preservada e pode ser inserida no cursor atual.', + failed: 'Falha no reconhecimento de fala: {message}', + unavailable: 'Este navegador não pode gravar áudio. Use um navegador com suporte para microfone.', + permission: 'O acesso ao microfone está desativado. Permita nas configurações do navegador e do sistema.', + tooLarge: 'A gravação excede o limite de serviço. Experimente uma gravação mais curta.', +} satisfies Record diff --git a/packages/experimental/client-ui-voice-input/src/client/mount.ts b/packages/experimental/client-ui-voice-input/src/client/mount.ts index bfe499f91b..7f43ca9cd1 100644 --- a/packages/experimental/client-ui-voice-input/src/client/mount.ts +++ b/packages/experimental/client-ui-voice-input/src/client/mount.ts @@ -10,7 +10,7 @@ import { createSnapshotStore } from '@deepseek-ai/dsh-client-store' import { VoiceInput, type VoiceInputInjected } from './VoiceInput.tsx' import { Recording } from './audio.ts' import { createMicrophoneDeviceStore } from './microphone-device.ts' -import { en, ja, NS, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, NS, zh } from './locales.ts' import type {} from '@deepseek-ai/dsh-client-ui-plugin-manager/client' import { observeReadiness } from './readiness.ts' import { VoicePreparation } from './PreparationCard.tsx' @@ -19,7 +19,7 @@ import { VoiceSetupPrompt } from './VoiceSetupPrompt.tsx' export const inject = ['remote', 'slots', 'locale'] function registerUi(ctx: Context): void { - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja })) + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt })) const recordings = new Set() const microphone = createMicrophoneDeviceStore() const readiness = observeReadiness(ctx) diff --git a/packages/experimental/computer-use-cua-driver-mcp/locale/de.json b/packages/experimental/computer-use-cua-driver-mcp/locale/de.json new file mode 100644 index 0000000000..45d46d3583 --- /dev/null +++ b/packages/experimental/computer-use-cua-driver-mcp/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Computernutzung (Cua-Treiber MCP)", + "description": "Lassen Sie das Modell den Desktop über eine separat installierte ausführbare Cua-Treiberdatei bedienen." + } +} diff --git a/packages/experimental/computer-use-cua-driver-mcp/locale/es.json b/packages/experimental/computer-use-cua-driver-mcp/locale/es.json new file mode 100644 index 0000000000..73fab70b14 --- /dev/null +++ b/packages/experimental/computer-use-cua-driver-mcp/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Uso de la computadora (Cua Driver MCP)", + "description": "Deje que el modelo opere el escritorio a través de un ejecutable de cua-driver instalado por separado." + } +} diff --git a/packages/experimental/computer-use-cua-driver-mcp/locale/fr.json b/packages/experimental/computer-use-cua-driver-mcp/locale/fr.json new file mode 100644 index 0000000000..57e7939dbb --- /dev/null +++ b/packages/experimental/computer-use-cua-driver-mcp/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Utilisation de l'ordinateur (Cua Driver MCP)", + "description": "Laissez le modèle faire fonctionner le bureau via un exécutable de pilote cua installé séparément." + } +} diff --git a/packages/experimental/computer-use-cua-driver-mcp/locale/pt.json b/packages/experimental/computer-use-cua-driver-mcp/locale/pt.json new file mode 100644 index 0000000000..7f13e08dbe --- /dev/null +++ b/packages/experimental/computer-use-cua-driver-mcp/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Uso do computador (Cua Driver MCP)", + "description": "Deixe o modelo operar a área de trabalho por meio de um executável de driver cua instalado separadamente." + } +} diff --git a/packages/experimental/computer-use-cua-driver-mcp/locale/ru.json b/packages/experimental/computer-use-cua-driver-mcp/locale/ru.json new file mode 100644 index 0000000000..7e54a4f6c0 --- /dev/null +++ b/packages/experimental/computer-use-cua-driver-mcp/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Использование компьютера (драйвер Cua MCP)", + "description": "Позвольте модели управлять рабочим столом через отдельно установленный исполняемый файл cua-драйвера." + } +} diff --git a/packages/experimental/computer-use-cua-driver-native/locale/de.json b/packages/experimental/computer-use-cua-driver-native/locale/de.json new file mode 100644 index 0000000000..b27632b0b2 --- /dev/null +++ b/packages/experimental/computer-use-cua-driver-native/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Computernutzung (Cua-Treiber)", + "description": "Lassen Sie das Modell den Desktop mit der mitgelieferten Cua Driver-Laufzeit bedienen; benötigt Desktop-Berechtigungen für die App, die dsh startet." + } +} diff --git a/packages/experimental/computer-use-cua-driver-native/locale/es.json b/packages/experimental/computer-use-cua-driver-native/locale/es.json new file mode 100644 index 0000000000..0af0972589 --- /dev/null +++ b/packages/experimental/computer-use-cua-driver-native/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Uso de la computadora (Cua Driver)", + "description": "Deje que el modelo opere el escritorio con el tiempo de ejecución del controlador Cua incluido; necesita permisos de escritorio para la aplicación que inicia dsh." + } +} diff --git a/packages/experimental/computer-use-cua-driver-native/locale/fr.json b/packages/experimental/computer-use-cua-driver-native/locale/fr.json new file mode 100644 index 0000000000..d1161ee44e --- /dev/null +++ b/packages/experimental/computer-use-cua-driver-native/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Utilisation de l'ordinateur (Cua Driver)", + "description": "Laissez le modèle faire fonctionner le bureau avec le runtime Cua Driver fourni ; a besoin d'autorisations de bureau pour l'application qui lance dsh." + } +} diff --git a/packages/experimental/computer-use-cua-driver-native/locale/pt.json b/packages/experimental/computer-use-cua-driver-native/locale/pt.json new file mode 100644 index 0000000000..8ed5a16b53 --- /dev/null +++ b/packages/experimental/computer-use-cua-driver-native/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Uso do computador (Driver Cua)", + "description": "Deixe o modelo operar a área de trabalho com o tempo de execução do driver Cua incluído; precisa de permissões de área de trabalho para o aplicativo que inicia dsh." + } +} diff --git a/packages/experimental/computer-use-cua-driver-native/locale/ru.json b/packages/experimental/computer-use-cua-driver-native/locale/ru.json new file mode 100644 index 0000000000..5b67fd6b90 --- /dev/null +++ b/packages/experimental/computer-use-cua-driver-native/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Использование компьютера (драйвер Cua)", + "description": "Позвольте модели управлять рабочим столом с помощью прилагаемой среды выполнения Cua Driver; требуются разрешения на рабочем столе для приложения, которое запускает dsh." + } +} diff --git a/packages/experimental/cot-translation-bundle/locale/de.json b/packages/experimental/cot-translation-bundle/locale/de.json new file mode 100644 index 0000000000..2f39909ea9 --- /dev/null +++ b/packages/experimental/cot-translation-bundle/locale/de.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Maschinelle Übersetzung der Argumentation", + "description": "Maschinelle Übersetzung erweiterter Argumentation; Der Quelltext wird an den ausgewählten Dienst gesendet.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/cot-translation-bundle/locale/es.json b/packages/experimental/cot-translation-bundle/locale/es.json new file mode 100644 index 0000000000..d8fe981f0d --- /dev/null +++ b/packages/experimental/cot-translation-bundle/locale/es.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Traducción automática de razonamiento", + "description": "Traducción automática de razonamiento ampliado; El texto fuente se envía al servicio seleccionado.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/cot-translation-bundle/locale/fr.json b/packages/experimental/cot-translation-bundle/locale/fr.json new file mode 100644 index 0000000000..d8c1a37e2f --- /dev/null +++ b/packages/experimental/cot-translation-bundle/locale/fr.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Traduction automatique du raisonnement", + "description": "Traduction automatique d'un raisonnement élargi ; le texte source est envoyé au service sélectionné.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/cot-translation-bundle/locale/pt.json b/packages/experimental/cot-translation-bundle/locale/pt.json new file mode 100644 index 0000000000..cb58ee0687 --- /dev/null +++ b/packages/experimental/cot-translation-bundle/locale/pt.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Tradução automática de raciocínio", + "description": "Tradução automática de raciocínio expandido; o texto fonte é enviado ao serviço selecionado.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/cot-translation-bundle/locale/ru.json b/packages/experimental/cot-translation-bundle/locale/ru.json new file mode 100644 index 0000000000..61fab30215 --- /dev/null +++ b/packages/experimental/cot-translation-bundle/locale/ru.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Машинный перевод рассуждений", + "description": "Машинный перевод развернутых рассуждений; исходный текст отправляется в выбранный сервис.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/cua-bundle/locale/de.json b/packages/experimental/cua-bundle/locale/de.json new file mode 100644 index 0000000000..8ab0af3e43 --- /dev/null +++ b/packages/experimental/cua-bundle/locale/de.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Computernutzung", + "description": "Unterstützt derzeit macOS; Die Windows-Unterstützung befindet sich in der Entwicklung. Lädt die Computernutzung für bestehende und neue PTC-Sitzungen. Wechseln Sie in den PTC-Modus und erteilen Sie die Berechtigungen für Barrierefreiheit und Bildschirmaufzeichnung, um ihn zu verwenden.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/cua-bundle/locale/es.json b/packages/experimental/cua-bundle/locale/es.json new file mode 100644 index 0000000000..88150f789a --- /dev/null +++ b/packages/experimental/cua-bundle/locale/es.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Uso de la computadora", + "description": "Actualmente es compatible con macOS; El soporte para Windows está en desarrollo. Carga el uso de la computadora para sesiones PTC nuevas y existentes. Cambie al modo PTC y otorgue permisos de Accesibilidad y Grabación de pantalla para usarlo.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/cua-bundle/locale/fr.json b/packages/experimental/cua-bundle/locale/fr.json new file mode 100644 index 0000000000..58f2c84db9 --- /dev/null +++ b/packages/experimental/cua-bundle/locale/fr.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Utilisation de l'ordinateur", + "description": "Prend actuellement en charge macOS ; La prise en charge de Windows est en cours de développement. Charge l'utilisation de l'ordinateur pour les sessions PTC existantes et nouvelles. Passez en mode PTC et accordez les autorisations d’accessibilité et d’enregistrement d’écran pour l’utiliser.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/cua-bundle/locale/pt.json b/packages/experimental/cua-bundle/locale/pt.json new file mode 100644 index 0000000000..4027bebaf8 --- /dev/null +++ b/packages/experimental/cua-bundle/locale/pt.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Uso do computador", + "description": "Atualmente suporta macOS; O suporte Windows está em desenvolvimento. Carrega o uso do computador para sessões PTC novas e existentes. Mude para o modo PTC e conceda permissões de acessibilidade e gravação de tela para usá-lo.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/cua-bundle/locale/ru.json b/packages/experimental/cua-bundle/locale/ru.json new file mode 100644 index 0000000000..2acf8381a1 --- /dev/null +++ b/packages/experimental/cua-bundle/locale/ru.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Использование компьютера", + "description": "В настоящее время поддерживается macOS; Поддержка Windows находится в разработке. Загружает использование компьютера для существующих и новых сеансов PTC. Переключитесь в режим PTC и предоставьте разрешения на доступность и запись экрана для его использования.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/cua-macos/locale/de.json b/packages/experimental/cua-macos/locale/de.json new file mode 100644 index 0000000000..de1dc5f6fb --- /dev/null +++ b/packages/experimental/cua-macos/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "macOS Computer Use Anbieter", + "description": "Stellen Sie native macOS-Anwendungen und -Fenster für den gemeinsam genutzten Computer Use-Dienst bereit." + } +} diff --git a/packages/experimental/cua-macos/locale/es.json b/packages/experimental/cua-macos/locale/es.json new file mode 100644 index 0000000000..061cd8f9d8 --- /dev/null +++ b/packages/experimental/cua-macos/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Proveedor macOS Computer Use", + "description": "Proporcione aplicaciones y ventanas nativas macOS para el servicio compartido Computer Use." + } +} diff --git a/packages/experimental/cua-macos/locale/fr.json b/packages/experimental/cua-macos/locale/fr.json new file mode 100644 index 0000000000..660aa8edd7 --- /dev/null +++ b/packages/experimental/cua-macos/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Fournisseur macOS Computer Use", + "description": "Fournissez des applications et des fenêtres macOS natives pour le service partagé Computer Use." + } +} diff --git a/packages/experimental/cua-macos/locale/pt.json b/packages/experimental/cua-macos/locale/pt.json new file mode 100644 index 0000000000..1f7a27c605 --- /dev/null +++ b/packages/experimental/cua-macos/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "macOS Computer Use provedor", + "description": "Forneça aplicativos e janelas macOS nativos para o serviço Computer Use compartilhado." + } +} diff --git a/packages/experimental/cua-macos/locale/ru.json b/packages/experimental/cua-macos/locale/ru.json new file mode 100644 index 0000000000..cb2a08d63f --- /dev/null +++ b/packages/experimental/cua-macos/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "macOS Computer Use поставщик", + "description": "Предоставьте собственные приложения и окна macOS для общей службы Computer Use." + } +} diff --git a/packages/experimental/cua/locale/de.json b/packages/experimental/cua/locale/de.json new file mode 100644 index 0000000000..1e89cc0e0a --- /dev/null +++ b/packages/experimental/cua/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Computer Use-Dienst", + "description": "Verwalten Sie den Anwendungszugriff, die Berechtigungen und die protokollierte Toolausführung für Computer Use." + } +} diff --git a/packages/experimental/cua/locale/es.json b/packages/experimental/cua/locale/es.json new file mode 100644 index 0000000000..72e5e36d77 --- /dev/null +++ b/packages/experimental/cua/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Servicio Computer Use", + "description": "Administre el acceso a las aplicaciones, los permisos y la ejecución de herramientas registradas para Computer Use." + } +} diff --git a/packages/experimental/cua/locale/fr.json b/packages/experimental/cua/locale/fr.json new file mode 100644 index 0000000000..9604929800 --- /dev/null +++ b/packages/experimental/cua/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Service Computer Use", + "description": "Gérez l'accès aux applications, les autorisations et l'exécution des outils enregistrés pour Computer Use." + } +} diff --git a/packages/experimental/cua/locale/pt.json b/packages/experimental/cua/locale/pt.json new file mode 100644 index 0000000000..979c9fd367 --- /dev/null +++ b/packages/experimental/cua/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Computer Use serviço", + "description": "Gerencie o acesso ao aplicativo, as permissões e a execução registrada da ferramenta para Computer Use." + } +} diff --git a/packages/experimental/cua/locale/ru.json b/packages/experimental/cua/locale/ru.json new file mode 100644 index 0000000000..276ae5b6d4 --- /dev/null +++ b/packages/experimental/cua/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Computer Use сервис", + "description": "Управляйте доступом к приложениям, разрешениями и протоколируемым выполнением инструментов для Computer Use." + } +} diff --git a/packages/experimental/cua/src/client/locales.ts b/packages/experimental/cua/src/client/locales.ts index 7ca793616b..8dae1d7b70 100644 --- a/packages/experimental/cua/src/client/locales.ts +++ b/packages/experimental/cua/src/client/locales.ts @@ -125,3 +125,188 @@ export const ja = { 'failed': '権限を更新できませんでした: {message}', 'queryFailed': '権限を確認できませんでした: {message}', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + title: 'Autorizar el uso de la computadora', + applicationsTitle: 'Administrar aplicaciones a las que puede acceder el uso de la computadora', + setupTitle: 'Configurar el uso de la computadora antes de usarla', + setupBody: 'El uso de la computadora está habilitado. Antes de usarlo, cambie al modo PTC y otorgue permisos de Accesibilidad y Grabación de pantalla. Abra los detalles del complemento para completar la configuración.', + setupQueryFailed: 'El uso de la computadora está habilitado, pero no se pudieron verificar los permisos del sistema. Abra los detalles del complemento para ver el error y vuelva a intentarlo.', + defaultTitle: 'Modo predeterminado para nuevas sesiones', + defaultBody: 'El uso de la computadora está disponible solo en el modo PTC.', + defaultConfirm: 'Establecer en PTC', defaultSet: 'PTC es el valor predeterminado', + defaultUnavailable: 'No se pudo leer el modo predeterminado. Compruébalo en Configuración.', + defaultReadOnly: 'La configuración del modo predeterminado es de sólo lectura.', + defaultNotSaved: 'El modo predeterminado no se guardó. Intentar otra vez.', + defaultFailed: 'No se pudo cambiar el modo predeterminado: {message}', + persistentTitle: 'Modo de ejecución PTC', + persistentBody: 'Mantenga variables y objetos de aplicación en todas las llamadas a herramientas. El cambio reinicia el tiempo de ejecución PTC.', + persistentConfirm: 'Usar modo persistente', persistentSet: 'Modo persistente habilitado', + persistentUnavailable: 'No se pudo leer el modo de ejecución PTC. Compruébalo en Configuración.', + persistentReadOnly: 'La configuración de ejecución de PTC es de solo lectura.', + persistentNotSaved: 'El modo de ejecución PTC no se guardó. Intentar otra vez.', + persistentFailed: 'No se pudo cambiar el modo de ejecución de PTC: {message}', + openSetup: 'Abrir configuración', later: 'Más tarde', close: 'Cerrar', + accessibility: 'Accesibilidad', screenRecording: 'Grabación de pantalla', + accessibilityUse: 'Lea los controles de la interfaz, haga clic y escriba.', screenRecordingUse: 'Capture la ventana de la aplicación seleccionada.', + accessibilityPermission: 'En Configuración del sistema, permita que {application} lea los controles de la interfaz, haga clic y escriba.', + screenRecordingPermission: 'En Configuración del sistema, permita que {application} capture ventanas de aplicaciones.', + permissionHint: 'Administre los permisos en Configuración del sistema para la aplicación nombrada por macOS.', + granted: 'Permitido', unknown: 'Desconocido', request: 'Solicitar permiso', settings: 'Abrir configuración del sistema', retry: 'Reintentar', + allowedApps: 'Aplicaciones siempre permitidas', + blockedApps: 'Aplicaciones no permitidas', retryApproval: 'Permitir preguntar de nuevo', + retryAllowed: 'La siguiente selección de aplicación le preguntará nuevamente; el acceso no ha sido concedido', + noApps: 'No hay aplicaciones siempre permitidas o bloqueadas.', + revoke: 'Revocar', revoked: 'Acceso a la aplicación revocado', requested: 'Revise el mensaje macOS o abra Configuración del sistema si no aparece ningún mensaje', opened: 'Configuración del sistema abierta', + applicationsFailed: 'No se pudo cargar el acceso a la aplicación: {message}', iconsFailed: 'No se pudieron cargar los íconos de la aplicación: {message}', + failed: 'No se pudieron actualizar los permisos: {message}', queryFailed: 'No se pudieron verificar los permisos: {message}', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + title: "Autoriser l'utilisation de l'ordinateur", + applicationsTitle: "Gérer les applications auxquelles l'ordinateur peut accéder", + setupTitle: "Configurer l'utilisation de l'ordinateur avant utilisation", + setupBody: "L'utilisation de l'ordinateur est autorisée. Avant de l'utiliser, passez en mode PTC et accordez les autorisations d'accessibilité et d'enregistrement d'écran. Ouvrez les détails du plugin pour terminer la configuration.", + setupQueryFailed: "L'utilisation de l'ordinateur est activée, mais les autorisations système n'ont pas pu être vérifiées. Ouvrez les détails du plugin pour voir l'erreur et réessayez.", + defaultTitle: 'Mode par défaut pour les nouvelles sessions', + defaultBody: "L'utilisation de l'ordinateur est disponible uniquement en mode PTC.", + defaultConfirm: 'Réglé sur PTC', defaultSet: 'PTC est la valeur par défaut', + defaultUnavailable: 'Impossible de lire le mode par défaut. Vérifiez-le dans Paramètres.', + defaultReadOnly: 'Les paramètres du mode par défaut sont en lecture seule.', + defaultNotSaved: "Le mode par défaut n'a pas été enregistré. Essayer à nouveau.", + defaultFailed: 'Impossible de modifier le mode par défaut : {message}', + persistentTitle: "Mode d'exécution PTC", + persistentBody: 'Conservez les variables et les objets d’application lors des appels d’outils. La commutation redémarre le runtime PTC.', + persistentConfirm: 'Utiliser le mode persistant', persistentSet: 'Mode persistant activé', + persistentUnavailable: "Impossible de lire le mode d'exécution PTC. Vérifiez-le dans Paramètres.", + persistentReadOnly: "Les paramètres d'exécution PTC sont en lecture seule.", + persistentNotSaved: "Le mode d'exécution PTC n'a pas été enregistré. Essayer à nouveau.", + persistentFailed: "Impossible de modifier le mode d'exécution de PTC : {message}", + openSetup: 'Ouvrir les paramètres', later: 'Plus tard', close: 'Fermer', + accessibility: 'Accessibilité', screenRecording: "Enregistrement d'écran", + accessibilityUse: 'Lisez les commandes de l’interface, cliquez et tapez.', screenRecordingUse: "Capturez la fenêtre de l'application sélectionnée.", + accessibilityPermission: "Dans Paramètres système, autorisez {application} à lire les commandes de l'interface, à cliquer et à taper.", + screenRecordingPermission: "Dans Paramètres système, autorisez {application} à capturer les fenêtres d'application.", + permissionHint: "Gérez les autorisations dans les paramètres système pour l'application nommée par macOS.", + granted: 'Autorisé', unknown: 'Inconnu', request: "Demander l'autorisation", settings: 'Ouvrir les paramètres système', retry: 'Réessayer', + allowedApps: 'Applications toujours autorisées', + blockedApps: 'Candidatures non autorisées', retryApproval: 'Autoriser la demande à nouveau', + retryAllowed: "La prochaine sélection de candidatures demandera à nouveau ; l'accès n'a pas été accordé", + noApps: 'Aucune application toujours autorisée ou bloquée.', + revoke: 'Révoquer', revoked: "Accès à l'application révoqué", requested: "Consultez l'invite macOS ou ouvrez les paramètres système si aucune invite n'apparaît.", opened: 'Paramètres système ouverts', + applicationsFailed: "Impossible de charger l'accès à l'application : {message}", iconsFailed: "Impossible de charger les icônes d'application : {message}", + failed: 'Impossible de mettre à jour les autorisations : {message}', queryFailed: 'Impossible de vérifier les autorisations : {message}', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + title: 'Autorisieren Sie die Computernutzung', + applicationsTitle: 'Verwalten Sie Anwendungen, auf die der Computer zugreifen kann', + setupTitle: 'Richten Sie die Computernutzung vor der Nutzung ein', + setupBody: 'Die Computernutzung ist aktiviert. Wechseln Sie vor der Verwendung in den PTC-Modus und erteilen Sie die Berechtigungen für Barrierefreiheit und Bildschirmaufzeichnung. Öffnen Sie die Plugin-Details, um die Einrichtung abzuschließen.', + setupQueryFailed: 'Die Computernutzung ist aktiviert, aber die Systemberechtigungen konnten nicht überprüft werden. Öffnen Sie die Plugin-Details, um den Fehler anzuzeigen, und versuchen Sie es erneut.', + defaultTitle: 'Standardmodus für neue Sitzungen', + defaultBody: 'Die Computernutzung ist nur im PTC-Modus verfügbar.', + defaultConfirm: 'Auf PTC setzen', defaultSet: 'PTC ist die Standardeinstellung', + defaultUnavailable: 'Der Standardmodus konnte nicht gelesen werden. Überprüfen Sie es in den Einstellungen.', + defaultReadOnly: 'Die Standardmoduseinstellungen sind schreibgeschützt.', + defaultNotSaved: 'Der Standardmodus wurde nicht gespeichert. Versuchen Sie es erneut.', + defaultFailed: 'Der Standardmodus konnte nicht geändert werden: {message}', + persistentTitle: 'PTC Ausführungsmodus', + persistentBody: 'Behalten Sie Variablen und Anwendungsobjekte über Werkzeugaufrufe hinweg bei. Durch den Wechsel wird die PTC-Laufzeit neu gestartet.', + persistentConfirm: 'Verwenden Sie den persistenten Modus', persistentSet: 'Persistenter Modus aktiviert', + persistentUnavailable: 'Der PTC-Ausführungsmodus konnte nicht gelesen werden. Überprüfen Sie es in den Einstellungen.', + persistentReadOnly: 'Die Ausführungseinstellungen von PTC sind schreibgeschützt.', + persistentNotSaved: 'Der PTC-Ausführungsmodus wurde nicht gespeichert. Versuchen Sie es erneut.', + persistentFailed: 'Der PTC-Ausführungsmodus konnte nicht geändert werden: {message}', + openSetup: 'Einstellungen öffnen', later: 'Später', close: 'Schließen', + accessibility: 'Barrierefreiheit', screenRecording: 'Bildschirmaufzeichnung', + accessibilityUse: 'Lesen Sie die Steuerelemente der Benutzeroberfläche, klicken Sie und geben Sie ein.', screenRecordingUse: 'Erfassen Sie das ausgewählte Anwendungsfenster.', + accessibilityPermission: 'Erlauben Sie {application} in den Systemeinstellungen, Schnittstellensteuerelemente zu lesen, zu klicken und zu tippen.', + screenRecordingPermission: 'Erlauben Sie {application} in den Systemeinstellungen, Anwendungsfenster zu erfassen.', + permissionHint: 'Verwalten Sie Berechtigungen in den Systemeinstellungen für die Anwendung mit dem Namen macOS.', + granted: 'Erlaubt', unknown: 'Unbekannt', request: 'Bitte um Erlaubnis', settings: 'Öffnen Sie die Systemeinstellungen', retry: 'Erneut versuchen', + allowedApps: 'Immer zulässige Anwendungen', + blockedApps: 'Bewerbungen nicht erlaubt', retryApproval: 'Erlaube noch einmal nachzufragen', + retryAllowed: 'Bei der nächsten Anwendungsauswahl werden Sie erneut gefragt; Der Zugriff wurde nicht gewährt', + noApps: 'Keine immer erlaubten oder blockierten Anwendungen.', + revoke: 'Widerrufen', revoked: 'Anwendungszugriff widerrufen', requested: 'Überprüfen Sie die macOS-Eingabeaufforderung oder öffnen Sie die Systemeinstellungen, wenn keine Eingabeaufforderung angezeigt wird', opened: 'Systemeinstellungen geöffnet', + applicationsFailed: 'Anwendungszugriff konnte nicht geladen werden: {message}', iconsFailed: 'Anwendungssymbole konnten nicht geladen werden: {message}', + failed: 'Berechtigungen konnten nicht aktualisiert werden: {message}', queryFailed: 'Berechtigungen konnten nicht überprüft werden: {message}', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + title: 'Разрешить использование компьютера', + applicationsTitle: 'Управление приложениями, к которым может иметь доступ компьютер', + setupTitle: 'Настройте использование компьютера перед использованием', + setupBody: 'Использование компьютера разрешено. Прежде чем использовать его, переключитесь в режим PTC и предоставьте разрешения на доступность и запись экрана. Откройте сведения о плагине, чтобы завершить настройку.', + setupQueryFailed: 'Использование компьютера разрешено, но системные разрешения проверить не удалось. Откройте сведения о плагине, чтобы увидеть ошибку, и повторите попытку.', + defaultTitle: 'Режим по умолчанию для новых сеансов', + defaultBody: 'Использование компьютера доступно только в режиме PTC.', + defaultConfirm: 'Установить на PTC', defaultSet: 'PTC — значение по умолчанию.', + defaultUnavailable: 'Не удалось прочитать режим по умолчанию. Проверьте это в настройках.', + defaultReadOnly: 'Настройки режима по умолчанию доступны только для чтения.', + defaultNotSaved: 'Режим по умолчанию не сохранился. Попробуйте еще раз.', + defaultFailed: 'Не удалось изменить режим по умолчанию: {message}.', + persistentTitle: 'Режим выполнения PTC', + persistentBody: 'Сохраняйте переменные и объекты приложения при вызовах инструментов. Переключение перезапускает среду выполнения PTC.', + persistentConfirm: 'Использовать постоянный режим', persistentSet: 'Постоянный режим включен', + persistentUnavailable: 'Не удалось прочитать режим выполнения PTC. Проверьте это в настройках.', + persistentReadOnly: 'Настройки выполнения PTC доступны только для чтения.', + persistentNotSaved: 'Режим выполнения PTC не был сохранен. Попробуйте еще раз.', + persistentFailed: 'Не удалось изменить режим выполнения PTC: {message}.', + openSetup: 'Открыть настройки', later: 'Позже', close: 'Закрыть', + accessibility: 'Доступность', screenRecording: 'Запись экрана', + accessibilityUse: 'Прочтите элементы управления интерфейсом, щелкните и введите текст.', screenRecordingUse: 'Захват выбранного окна приложения.', + accessibilityPermission: 'В настройках системы разрешите {application} читать элементы управления интерфейсом, щелкать и печатать.', + screenRecordingPermission: 'В настройках системы разрешите {application} захватывать окна приложений.', + permissionHint: 'Управляйте разрешениями в настройках системы для приложения с именем macOS.', + granted: 'Разрешено', unknown: 'Неизвестно', request: 'Запросить разрешение', settings: 'Открыть настройки системы', retry: 'Повторить', + allowedApps: 'Всегда разрешенные приложения', + blockedApps: 'Приложения не разрешены', retryApproval: 'Разрешить спросить еще раз', + retryAllowed: 'При следующем выборе приложения запрос будет повторен; доступ не предоставлен', + noApps: 'Никаких всегда разрешенных или заблокированных приложений.', + revoke: 'Отозвать', revoked: 'Доступ к приложению отозван', requested: 'Просмотрите подсказку macOS или откройте «Системные настройки», если подсказка не появляется.', opened: 'Системные настройки открыты', + applicationsFailed: 'Не удалось загрузить доступ к приложению: {message}.', iconsFailed: 'Не удалось загрузить значки приложений: {message}.', + failed: 'Не удалось обновить разрешения: {message}.', queryFailed: 'Не удалось проверить разрешения: {message}', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + title: 'Autorizar o uso do computador', + applicationsTitle: 'Gerenciar aplicativos que o computador pode acessar', + setupTitle: 'Configure o uso do computador antes de usar', + setupBody: 'O uso do computador está habilitado. Antes de usá-lo, alterne para o modo PTC e conceda permissões de acessibilidade e gravação de tela. Abra os detalhes do plugin para concluir a configuração.', + setupQueryFailed: 'O uso do computador está ativado, mas não foi possível verificar as permissões do sistema. Abra os detalhes do plugin para ver o erro e tente novamente.', + defaultTitle: 'Modo padrão para novas sessões', + defaultBody: 'O uso do computador está disponível somente no modo PTC.', + defaultConfirm: 'Definir como PTC', defaultSet: 'PTC é o padrão', + defaultUnavailable: 'Não foi possível ler o modo padrão. Verifique em Configurações.', + defaultReadOnly: 'As configurações do modo padrão são somente leitura.', + defaultNotSaved: 'O modo padrão não foi salvo. Tente novamente.', + defaultFailed: 'Não foi possível alterar o modo padrão: {message}', + persistentTitle: 'PTC modo de execução', + persistentBody: 'Mantenha variáveis e objetos de aplicação em todas as chamadas de ferramenta. A alternância reinicia o tempo de execução PTC.', + persistentConfirm: 'Usar modo persistente', persistentSet: 'Modo persistente ativado', + persistentUnavailable: 'Não foi possível ler o modo de execução PTC. Verifique em Configurações.', + persistentReadOnly: 'PTC configurações de execução são somente leitura.', + persistentNotSaved: 'O modo de execução PTC não foi salvo. Tente novamente.', + persistentFailed: 'Não foi possível alterar o modo de execução PTC: {message}', + openSetup: 'Abrir configurações', later: 'Mais tarde', close: 'Fechar', + accessibility: 'Acessibilidade', screenRecording: 'Gravação de tela', + accessibilityUse: 'Leia os controles da interface, clique e digite.', screenRecordingUse: 'Capture a janela do aplicativo selecionado.', + accessibilityPermission: 'Nas configurações do sistema, permita que {application} leia os controles da interface, clique e digite.', + screenRecordingPermission: 'Nas configurações do sistema, permita que {application} capture janelas de aplicativos.', + permissionHint: 'Gerencie as permissões nas Configurações do sistema para o aplicativo nomeado por macOS.', + granted: 'Permitido', unknown: 'Desconhecido', request: 'Solicitar permissão', settings: 'Abra as configurações do sistema', retry: 'Tentar novamente', + allowedApps: 'Aplicativos sempre permitidos', + blockedApps: 'Aplicativos não permitidos', retryApproval: 'Permitir perguntar novamente', + retryAllowed: 'A próxima seleção de aplicativos perguntará novamente; o acesso não foi concedido', + noApps: 'Nenhum aplicativo sempre permitido ou bloqueado.', + revoke: 'Revogar', revoked: 'Acesso ao aplicativo revogado', requested: 'Revise o prompt macOS ou abra as Configurações do sistema se nenhum prompt aparecer', opened: 'Configurações do sistema abertas', + applicationsFailed: 'Não foi possível carregar o acesso ao aplicativo: {message}', iconsFailed: 'Não foi possível carregar os ícones do aplicativo: {message}', + failed: 'Não foi possível atualizar as permissões: {message}', queryFailed: 'Não foi possível verificar as permissões: {message}', +} satisfies Record diff --git a/packages/experimental/cua/src/client/mount.ts b/packages/experimental/cua/src/client/mount.ts index 9548462050..c81d18f25f 100644 --- a/packages/experimental/cua/src/client/mount.ts +++ b/packages/experimental/cua/src/client/mount.ts @@ -12,7 +12,7 @@ import type { ComposerChainProps } from '@deepseek-ai/dsh-client-ui-conversation import { ApplicationApproval, selectApplicationApproval } from './ApplicationApproval.tsx' import { PermissionController } from './controller.ts' import { PermissionPanel, PermissionSetup, PermissionToast } from './PermissionPanel.tsx' -import { en, ja, NS, zh, type CuaPermissionLocaleKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, NS, zh, type CuaPermissionLocaleKey } from './locales.ts' declare module '@deepseek-ai/dsh-client-ui-slots' { interface LocaleNamespaceMap { @@ -33,7 +33,7 @@ export const inject = ['remote', 'slots', 'locale', 'configForms'] export async function mountCuaPermissions(ctx: Context, contribution: TypertRemoteContribution): Promise<() => Promise> { const transport = ctx.plugin(async (owner) => { await owner.remote.$mount(contribution) }) const ui = ctx.inject(['remote.cuaAccess', 'slots', 'locale'], (ctx) => { - ctx.effect(() => ctx.locale.register(NS, { en, zh, ja })) + ctx.effect(() => ctx.locale.register(NS, { en, zh, ja, es, fr, de, ru, pt })) const controller = new PermissionController(ctx.remote.cuaAccess) const face = controller.face() ctx.slots.inject('conversation.composer', () => ctx.slots.register({ diff --git a/packages/experimental/cua/src/locales.ts b/packages/experimental/cua/src/locales.ts index 391f77c445..9cd8b219e1 100644 --- a/packages/experimental/cua/src/locales.ts +++ b/packages/experimental/cua/src/locales.ts @@ -12,7 +12,7 @@ export const zh = { question: '允许 Computer Use 启动、读取、截图和控制此应用吗?', detail: '会话授权在 DSH 重启或关闭 Computer Use 后失效。', approve: '本会话允许', -} satisfies typeof en +} satisfies Record /** Japanese application-access messages. */ export const ja = { @@ -21,9 +21,62 @@ export const ja = { approve: 'このセッションで許可', } satisfies typeof en +/** Spanish dictionary, checked against the English keys. */ +export const es = { + question: '¿Permitir que Computer Use inicie, lea, capture y controle esta aplicación?', + detail: 'El acceso de esta sesión dura hasta que se reinicie DSH o se desactive Computer Use.', + approve: 'Permitir durante esta sesión', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + question: 'Autoriser Computer Use à lancer, lire, capturer et contrôler cette application ?', + detail: 'L’autorisation de cette session reste valable jusqu’au redémarrage de DSH ou à la désactivation de Computer Use.', + approve: 'Autoriser pour cette session', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + question: 'Darf Computer Use diese Anwendung starten, lesen, aufnehmen und steuern?', + detail: 'Der Zugriff für diese Sitzung gilt, bis DSH neu gestartet oder Computer Use deaktiviert wird.', + approve: 'Für diese Sitzung zulassen', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + question: 'Разрешить Computer Use запуск, чтение, захват и управление этим приложением?', + detail: 'Доступ для этого сеанса действует до перезапуска DSH или отключения Computer Use.', + approve: 'Разрешить для этого сеанса', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + question: 'Permitir que o Computer Use inicie, leia, capture e controle este aplicativo?', + detail: 'O acesso desta sessão dura até que o DSH seja reiniciado ou o Computer Use seja desativado.', + approve: 'Permitir nesta sessão', +} satisfies Record + /** Display translations resolved by the Client; wire choices stay unchanged. */ export const applicationAccessDisplay = { - question: { en: en.question, zh: zh.question, ja: ja.question }, - detail: { en: en.detail, zh: zh.detail, ja: ja.detail }, - approve: { en: en.approve, zh: zh.approve, ja: ja.approve }, + question: { + en: en.question, + zh: zh.question, + ja: ja.question, + es: es.question, + fr: fr.question, + de: de.question, + ru: ru.question, + pt: pt.question, + }, + detail: { en: en.detail, zh: zh.detail, ja: ja.detail, es: es.detail, fr: fr.detail, de: de.detail, ru: ru.detail, pt: pt.detail }, + approve: { + en: en.approve, + zh: zh.approve, + ja: ja.approve, + es: es.approve, + fr: fr.approve, + de: de.approve, + ru: ru.approve, + pt: pt.approve, + }, } diff --git a/packages/experimental/cua/tests/application-access.spec.ts b/packages/experimental/cua/tests/application-access.spec.ts index 946ca78f8c..248fe9fb13 100644 --- a/packages/experimental/cua/tests/application-access.spec.ts +++ b/packages/experimental/cua/tests/application-access.spec.ts @@ -85,7 +85,9 @@ it.each([ detail: { en: 'Session access lasts until DSH restarts or computer use is disabled.', zh: '会话授权在 DSH 重启或关闭 Computer Use 后失效。', ja: 'セッションの許可は DSH の再起動または Computer Use の無効化まで有効です。' }, - approve: { en: 'Allow for this session', zh: '本会话允许', ja: 'このセッションで許可' }, + approve: { en: 'Allow for this session', zh: '本会话允许', ja: 'このセッションで許可', + es: 'Permitir durante esta sesión', fr: 'Autoriser pour cette session', de: 'Für diese Sitzung zulassen', + ru: 'Разрешить для этого сеанса', pt: 'Permitir nesta sessão' }, }, }, }) diff --git a/packages/experimental/hooks-claude-code/locale/de.json b/packages/experimental/hooks-claude-code/locale/de.json new file mode 100644 index 0000000000..78196bc894 --- /dev/null +++ b/packages/experimental/hooks-claude-code/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Claude Code Haken", + "description": "Führen Sie Hooks von Claude Code Hooks.json oder Einstellungen an Harness-Abfangpunkten aus." + } +} diff --git a/packages/experimental/hooks-claude-code/locale/es.json b/packages/experimental/hooks-claude-code/locale/es.json new file mode 100644 index 0000000000..639db400bd --- /dev/null +++ b/packages/experimental/hooks-claude-code/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ganchos Claude Code", + "description": "Ejecute ganchos desde Claude Code hooks.json o configuraciones en los puntos de intercepción del arnés." + } +} diff --git a/packages/experimental/hooks-claude-code/locale/fr.json b/packages/experimental/hooks-claude-code/locale/fr.json new file mode 100644 index 0000000000..d63142cdf5 --- /dev/null +++ b/packages/experimental/hooks-claude-code/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Crochets Claude Code", + "description": "Exécutez des hooks à partir de Claude Code hooks.json ou des paramètres aux points d’interception Harness." + } +} diff --git a/packages/experimental/hooks-claude-code/locale/pt.json b/packages/experimental/hooks-claude-code/locale/pt.json new file mode 100644 index 0000000000..7823990e51 --- /dev/null +++ b/packages/experimental/hooks-claude-code/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Claude Code ganchos", + "description": "Execute ganchos de Claude Code hooks.json ou configurações nos pontos de interceptação do Harness." + } +} diff --git a/packages/experimental/hooks-claude-code/locale/ru.json b/packages/experimental/hooks-claude-code/locale/ru.json new file mode 100644 index 0000000000..b41dfa7d94 --- /dev/null +++ b/packages/experimental/hooks-claude-code/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Claude Code крючков", + "description": "Запускайте перехватчики из Claude Codeooks.json или настроек в точках перехвата Harness." + } +} diff --git a/packages/experimental/hooks-codex/locale/de.json b/packages/experimental/hooks-codex/locale/de.json new file mode 100644 index 0000000000..c0039a3c4a --- /dev/null +++ b/packages/experimental/hooks-codex/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Codex Haken", + "description": "Führen Sie Hooks von Codex Hooks.json an den Harness-Abfangpunkten aus." + } +} diff --git a/packages/experimental/hooks-codex/locale/es.json b/packages/experimental/hooks-codex/locale/es.json new file mode 100644 index 0000000000..160967f74d --- /dev/null +++ b/packages/experimental/hooks-codex/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ganchos Codex", + "description": "Ejecute ganchos desde Codex hooks.json en los puntos de intercepción del arnés." + } +} diff --git a/packages/experimental/hooks-codex/locale/fr.json b/packages/experimental/hooks-codex/locale/fr.json new file mode 100644 index 0000000000..1aba9e7910 --- /dev/null +++ b/packages/experimental/hooks-codex/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Crochets Codex", + "description": "Exécutez les hooks à partir de Codex hooks.json aux points d’interception Harness." + } +} diff --git a/packages/experimental/hooks-codex/locale/pt.json b/packages/experimental/hooks-codex/locale/pt.json new file mode 100644 index 0000000000..4f325dc22b --- /dev/null +++ b/packages/experimental/hooks-codex/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Codex ganchos", + "description": "Execute ganchos de Codex hooks.json nos pontos de interceptação do Harness." + } +} diff --git a/packages/experimental/hooks-codex/locale/ru.json b/packages/experimental/hooks-codex/locale/ru.json new file mode 100644 index 0000000000..feacc0df40 --- /dev/null +++ b/packages/experimental/hooks-codex/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Codex крючков", + "description": "Запускайте перехватчики из Codexooks.json в точках перехвата Harness." + } +} diff --git a/packages/experimental/inspector-profile/locale/de.json b/packages/experimental/inspector-profile/locale/de.json new file mode 100644 index 0000000000..78767ff472 --- /dev/null +++ b/packages/experimental/inspector-profile/locale/de.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Entwicklertools", + "description": "Untersuchen und debuggen Sie rohe Sitzungsdaten, gruppierte Chat-Nachrichten und das NodeJS-Backend.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/inspector-profile/locale/es.json b/packages/experimental/inspector-profile/locale/es.json new file mode 100644 index 0000000000..70e7940d9e --- /dev/null +++ b/packages/experimental/inspector-profile/locale/es.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Herramientas de desarrollador", + "description": "Inspeccione y depure datos de sesión sin procesar, mensajes de chat agrupados y el backend NodeJS.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/inspector-profile/locale/fr.json b/packages/experimental/inspector-profile/locale/fr.json new file mode 100644 index 0000000000..b3847d2a9f --- /dev/null +++ b/packages/experimental/inspector-profile/locale/fr.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Outils de développement", + "description": "Inspectez et déboguez les données brutes de session, les messages de discussion groupés et le backend NodeJS.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/inspector-profile/locale/pt.json b/packages/experimental/inspector-profile/locale/pt.json new file mode 100644 index 0000000000..f27d371967 --- /dev/null +++ b/packages/experimental/inspector-profile/locale/pt.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Ferramentas de desenvolvedor", + "description": "Inspecione e depure dados brutos da sessão, mensagens de bate-papo agrupadas e o back-end NodeJS.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/inspector-profile/locale/ru.json b/packages/experimental/inspector-profile/locale/ru.json new file mode 100644 index 0000000000..95f07b61d9 --- /dev/null +++ b/packages/experimental/inspector-profile/locale/ru.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Инструменты разработчика", + "description": "Проверяйте и отлаживайте необработанные данные сеанса, сгруппированные сообщения чата и серверную часть NodeJS.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/inspector/locale/de.json b/packages/experimental/inspector/locale/de.json new file mode 100644 index 0000000000..3acc2c51d5 --- /dev/null +++ b/packages/experimental/inspector/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "NodeJS-Inspektor", + "description": "Drücken Sie Strg/Befehl+Umschalt+. , um Chrome DevTools im unteren Bereich zum Entwickeln und Debuggen zu öffnen." + } +} diff --git a/packages/experimental/inspector/locale/es.json b/packages/experimental/inspector/locale/es.json new file mode 100644 index 0000000000..b747f11dbb --- /dev/null +++ b/packages/experimental/inspector/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Inspector NodeJS", + "description": "Presione Ctrl/Cmd+Mayús+. para abrir Chrome DevTools en el panel inferior para desarrollo y depuración." + } +} diff --git a/packages/experimental/inspector/locale/fr.json b/packages/experimental/inspector/locale/fr.json new file mode 100644 index 0000000000..cf162e4417 --- /dev/null +++ b/packages/experimental/inspector/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Inspecteur NodeJS", + "description": "Appuyez sur Ctrl/Cmd+Maj+. pour ouvrir Chrome DevTools dans le panneau inférieur pour le développement et le débogage." + } +} diff --git a/packages/experimental/inspector/locale/pt.json b/packages/experimental/inspector/locale/pt.json new file mode 100644 index 0000000000..097f36a11f --- /dev/null +++ b/packages/experimental/inspector/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "NodeJS inspetor", + "description": "Pressione Ctrl/Cmd+Shift+. para abrir o Chrome DevTools no painel inferior para desenvolvimento e depuração." + } +} diff --git a/packages/experimental/inspector/locale/ru.json b/packages/experimental/inspector/locale/ru.json new file mode 100644 index 0000000000..e6cf3a7f6f --- /dev/null +++ b/packages/experimental/inspector/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "NodeJS инспектор", + "description": "Нажмите Ctrl/Cmd+Shift+. чтобы открыть Chrome DevTools на нижней панели для разработки и отладки." + } +} diff --git a/packages/experimental/inspector/src/client/bottom/locales.ts b/packages/experimental/inspector/src/client/bottom/locales.ts index 6fd18dcef6..0fc3b22b1e 100644 --- a/packages/experimental/inspector/src/client/bottom/locales.ts +++ b/packages/experimental/inspector/src/client/bottom/locales.ts @@ -31,3 +31,48 @@ export const ja = { 'resize': 'NodeJS インスペクターパネルのサイズ変更', 'frameTitle': 'NodeJS インスペクター', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + title: 'Inspector NodeJS', + toggle: 'Alternar inspector NodeJS', + close: 'Contraer', + resize: 'Cambiar el tamaño del panel inspector NodeJS', + frameTitle: 'Inspector NodeJS', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + title: 'Inspecteur NodeJS', + toggle: "Basculer l'inspecteur NodeJS", + close: 'Réduire', + resize: "Redimensionner le panneau d'inspection NodeJS", + frameTitle: 'Inspecteur NodeJS', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + title: 'NodeJS-Inspektor', + toggle: 'Schalten Sie den NodeJS-Inspektor um', + close: 'Einklappen', + resize: 'Größe des NodeJS-Inspektorfelds ändern', + frameTitle: 'NodeJS-Inspektor', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + title: 'NodeJS инспектор', + toggle: 'Переключить инспектор NodeJS', + close: 'Свернуть', + resize: 'Изменение размера панели инспектора NodeJS', + frameTitle: 'NodeJS инспектор', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + title: 'NodeJS inspetor', + toggle: 'Alternar inspetor NodeJS', + close: 'Recolher', + resize: 'Redimensionar painel do inspetor NodeJS', + frameTitle: 'NodeJS inspetor', +} satisfies Record diff --git a/packages/experimental/inspector/src/client/bottom/page.tsx b/packages/experimental/inspector/src/client/bottom/page.tsx index affe4c00e0..f7aebe64af 100644 --- a/packages/experimental/inspector/src/client/bottom/page.tsx +++ b/packages/experimental/inspector/src/client/bottom/page.tsx @@ -12,7 +12,7 @@ import type {} from '@deepseek-ai/dsh-client-locale/client' import type { InspectorSourceId } from '../../shared/bridge/ids.ts' import { bindInspectorKeyboard } from './keyboard.ts' import { InspectorResizeHandle } from './resize.tsx' -import { zh, en, ja } from './locales.ts' +import { zh, en, ja, es, fr, de, ru, pt } from './locales.ts' import css from './page.module.css' const ID = 'inspector.toggle' as ShortcutCommandId @@ -58,7 +58,7 @@ function InspectorPage({ t, frontendUrl, close, bindFrame, usePanel }: export function registerInspectorPage(ctx: Context, sourceId: InspectorSourceId): void { const query = new URLSearchParams({ disableLocaleInfoBar: 'true', clientSourceId: sourceId }) const frontendUrl = `inspector/devtools/devtools_app.html?${query}` - ctx.effect(() => ctx.locale.register('inspectorPanel', { zh, en, ja })) + ctx.effect(() => ctx.locale.register('inspectorPanel', { zh, en, ja, es, fr, de, ru, pt })) const t = ctx.locale.bind('inspectorPanel') ctx.slots.inject('shell.bottom', function* () { const panel = createSnapshotStore('unopened') diff --git a/packages/experimental/plugin-market-bundle/locale/de.json b/packages/experimental/plugin-market-bundle/locale/de.json new file mode 100644 index 0000000000..84e4d22d05 --- /dev/null +++ b/packages/experimental/plugin-market-bundle/locale/de.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Benutzerdefinierte Plugin-Märkte", + "description": "Fügt Plugins eine Registerkarte „Entdecken“ hinzu, um Bundles aus den von Ihnen hinzugefügten Plugin-Marktindizes zu durchsuchen und zu installieren.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/plugin-market-bundle/locale/es.json b/packages/experimental/plugin-market-bundle/locale/es.json new file mode 100644 index 0000000000..f798e4f937 --- /dev/null +++ b/packages/experimental/plugin-market-bundle/locale/es.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Mercados de complementos personalizados", + "description": "Agrega una pestaña Descubrir a los complementos para explorar e instalar paquetes de los índices del mercado de complementos que agregue.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/plugin-market-bundle/locale/fr.json b/packages/experimental/plugin-market-bundle/locale/fr.json new file mode 100644 index 0000000000..a57f3569c9 --- /dev/null +++ b/packages/experimental/plugin-market-bundle/locale/fr.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Marchés de plugins personnalisés", + "description": "Ajoute un onglet Découvrir aux plugins pour parcourir et installer les bundles à partir des index de marché des plugins que vous ajoutez.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/plugin-market-bundle/locale/pt.json b/packages/experimental/plugin-market-bundle/locale/pt.json new file mode 100644 index 0000000000..ddcf3299d7 --- /dev/null +++ b/packages/experimental/plugin-market-bundle/locale/pt.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Mercados de plugins personalizados", + "description": "Adiciona uma guia Descobrir aos plug-ins para navegar e instalar pacotes de índices de mercado de plug-ins que você adiciona.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/plugin-market-bundle/locale/ru.json b/packages/experimental/plugin-market-bundle/locale/ru.json new file mode 100644 index 0000000000..4bb579886c --- /dev/null +++ b/packages/experimental/plugin-market-bundle/locale/ru.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Рынки пользовательских плагинов", + "description": "Добавляет вкладку «Обнаружение» в «Плагины» для просмотра и установки пакетов из добавленных вами рыночных индексов плагинов.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/ptc-runtime-python/locale/de.json b/packages/experimental/ptc-runtime-python/locale/de.json new file mode 100644 index 0000000000..cad4e9d929 --- /dev/null +++ b/packages/experimental/ptc-runtime-python/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Python PTC-Laufzeit", + "description": "Führen Sie programmgesteuerten Tool-Aufrufcode in CPython-Unterprozessen aus." + } +} diff --git a/packages/experimental/ptc-runtime-python/locale/es.json b/packages/experimental/ptc-runtime-python/locale/es.json new file mode 100644 index 0000000000..fcbfc65967 --- /dev/null +++ b/packages/experimental/ptc-runtime-python/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Tiempo de ejecución de Python PTC", + "description": "Ejecute código de llamada de herramientas programáticas en subprocesos CPython." + } +} diff --git a/packages/experimental/ptc-runtime-python/locale/fr.json b/packages/experimental/ptc-runtime-python/locale/fr.json new file mode 100644 index 0000000000..e731e96919 --- /dev/null +++ b/packages/experimental/ptc-runtime-python/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Exécution Python PTC", + "description": "Exécutez du code d’appel d’outil de programmation dans les sous-processus CPython." + } +} diff --git a/packages/experimental/ptc-runtime-python/locale/pt.json b/packages/experimental/ptc-runtime-python/locale/pt.json new file mode 100644 index 0000000000..25e6521992 --- /dev/null +++ b/packages/experimental/ptc-runtime-python/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Tempo de execução do Python PTC", + "description": "Execute código de chamada de ferramenta programática em subprocessos CPython." + } +} diff --git a/packages/experimental/ptc-runtime-python/locale/ru.json b/packages/experimental/ptc-runtime-python/locale/ru.json new file mode 100644 index 0000000000..49a86c7fbe --- /dev/null +++ b/packages/experimental/ptc-runtime-python/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Среда выполнения Python PTC", + "description": "Запускайте программный код вызова инструментов в подпроцессах CPython." + } +} diff --git a/packages/experimental/ralph-bundle/locale/de.json b/packages/experimental/ralph-bundle/locale/de.json new file mode 100644 index 0000000000..86a12dabcb --- /dev/null +++ b/packages/experimental/ralph-bundle/locale/de.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Ralph-Loops", + "description": "Führen Sie explizit angeforderte wiederholte Arbeiten mit neuen Agenten durch.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/ralph-bundle/locale/es.json b/packages/experimental/ralph-bundle/locale/es.json new file mode 100644 index 0000000000..ac2c44b2a6 --- /dev/null +++ b/packages/experimental/ralph-bundle/locale/es.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Bucles de Ralph", + "description": "Ejecute trabajos repetidos solicitados explícitamente con agentes nuevos.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/ralph-bundle/locale/fr.json b/packages/experimental/ralph-bundle/locale/fr.json new file mode 100644 index 0000000000..9ce92c7c13 --- /dev/null +++ b/packages/experimental/ralph-bundle/locale/fr.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Boucles Ralph", + "description": "Exécutez le travail répété explicitement demandé avec de nouveaux agents.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/ralph-bundle/locale/pt.json b/packages/experimental/ralph-bundle/locale/pt.json new file mode 100644 index 0000000000..a739d28652 --- /dev/null +++ b/packages/experimental/ralph-bundle/locale/pt.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Loops de Ralph", + "description": "Execute trabalhos repetidos solicitados explicitamente com novos agentes.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/ralph-bundle/locale/ru.json b/packages/experimental/ralph-bundle/locale/ru.json new file mode 100644 index 0000000000..02ee30dccf --- /dev/null +++ b/packages/experimental/ralph-bundle/locale/ru.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Ральф петли", + "description": "Запуск явно запрошенной повторной работы со свежими агентами.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/session-inspector/locale/de.json b/packages/experimental/session-inspector/locale/de.json new file mode 100644 index 0000000000..09fbe3ee50 --- /dev/null +++ b/packages/experimental/session-inspector/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sitzungsprotokoll", + "description": "Aktivieren Sie die Analyse der Rohdaten und gruppierten Chat-Nachrichten der aktuellen Sitzung in der Sitzungsseitenleiste." + } +} diff --git a/packages/experimental/session-inspector/locale/es.json b/packages/experimental/session-inspector/locale/es.json new file mode 100644 index 0000000000..f7d98f5f5c --- /dev/null +++ b/packages/experimental/session-inspector/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Registro de sesión", + "description": "Habilite el análisis de los datos sin procesar de la sesión actual y los mensajes de chat agrupados en la barra lateral de la sesión." + } +} diff --git a/packages/experimental/session-inspector/locale/fr.json b/packages/experimental/session-inspector/locale/fr.json new file mode 100644 index 0000000000..13497a11ea --- /dev/null +++ b/packages/experimental/session-inspector/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Journal de session", + "description": "Activez l'analyse des données brutes de la session en cours et des messages de discussion groupés dans la barre latérale de la session." + } +} diff --git a/packages/experimental/session-inspector/locale/pt.json b/packages/experimental/session-inspector/locale/pt.json new file mode 100644 index 0000000000..417b62d336 --- /dev/null +++ b/packages/experimental/session-inspector/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Registro da sessão", + "description": "Ative a análise dos dados brutos da sessão atual e das mensagens de bate-papo agrupadas na barra lateral da sessão." + } +} diff --git a/packages/experimental/session-inspector/locale/ru.json b/packages/experimental/session-inspector/locale/ru.json new file mode 100644 index 0000000000..e58fa609a3 --- /dev/null +++ b/packages/experimental/session-inspector/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Журнал сеанса", + "description": "Включите анализ необработанных данных текущего сеанса и сгруппированных сообщений чата на боковой панели сеанса." + } +} diff --git a/packages/experimental/session-inspector/src/client/index.ts b/packages/experimental/session-inspector/src/client/index.ts index 966f0cafcf..fd36e4b1b8 100644 --- a/packages/experimental/session-inspector/src/client/index.ts +++ b/packages/experimental/session-inspector/src/client/index.ts @@ -3,7 +3,7 @@ import type { Context } from '@deepseek-ai/cordis' import type {} from '@deepseek-ai/dsh-client-locale/client' import type {} from '@deepseek-ai/dsh-client-ui-sidebar-right/client' -import { en, ja, NS, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, NS, zh } from './locales.ts' import { registerInspectorTab } from './views/index.ts' /** Services required to register the localized Session-bound sidebar tab. */ @@ -14,6 +14,6 @@ export const inject = ['slots', 'locale', 'sessions', 'uiSession', 'uiConversati * @param ctx - Client plugin context owning the dictionaries and registrations. */ export function apply(ctx: Context): void { - ctx.effect(() => ctx.locale.register(NS, { en, zh, ja }), 'session-inspector: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { en, zh, ja, es, fr, de, ru, pt }), 'session-inspector: dictionaries') registerInspectorTab(ctx) } diff --git a/packages/experimental/session-inspector/src/client/locales.ts b/packages/experimental/session-inspector/src/client/locales.ts index dab989d4e6..7c5beab615 100644 --- a/packages/experimental/session-inspector/src/client/locales.ts +++ b/packages/experimental/session-inspector/src/client/locales.ts @@ -180,3 +180,283 @@ export const ja = { 'object.more': 'さらに表示', 'object.navigation': '生データのナビゲーション', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'tab.title': 'Registro de sesión', + 'tab.description': 'Analice registros sin procesar y mensajes de chat agrupados para la sesión actual en la barra lateral.', + 'view.presentation': 'Presentación', + 'view.sessionLog': 'Registro crudo', + 'view.chatNode': 'grupo de chat', + 'picker.pick': 'Elige un elemento en la vista de chat', + 'picker.cancel': 'Cancelar selección (Esc)', + 'picker.instructions': 'Pase el cursor sobre el chat principal para obtener una vista previa y luego haga clic para seleccionar. Esc se cancela.', + 'picker.noMatch': 'No hay ningún registro coincidente en esta tabla. Elija otro elemento o presione Esc para cancelar.', + 'picker.noChat': 'Abre esta sesión en el chat principal antes de elegir.', + 'table.id': 'índice', + 'table.type': 'Tipo', + 'filter.title': 'Tipos de filtro', + 'filter.input': 'Escriba palabra clave', + 'filter.placeholder': 'Escriba un fragmento, p. delta', + 'filter.help': 'Contiene coincidencias (*palabra clave*). Enter confirma; Esc se cancela.', + 'filter.candidates': 'Escriba sugerencias', + 'filter.loading': 'Buscando sugerencias...', + 'filter.failed': 'No se pudieron cargar sugerencias de tipo.', + 'filter.noCandidates': 'Sin sugerencias. Aún puedes aplicar esta palabra clave.', + 'filter.clear': 'Borrar', + 'filter.cancel': 'Cancelar', + 'filter.apply': 'Aplicar filtro', + 'filter.context': 'Contexto principal de un registro coincidente', + 'table.location': 'T/S', + 'table.time': 'Hora (UTC)', + 'table.data': 'Datos', + 'table.older': 'Cargar antes', + 'table.loading': 'Cargando…', + 'table.latest': 'Seguir lo último', + 'table.empty': 'Sin registros', + 'table.raw': 'Datos sin procesar', + 'table.rawError': 'Este registro no se pudo serializar. Seleccione otro registro para continuar.', + 'table.resizeDetails': 'Cambiar el tamaño del panel de datos sin procesar', + 'table.close': 'Cerrar', + 'table.expand': 'Ampliar niños', + 'table.collapse': 'Colapso niños', + 'table.removed': 'Este registro fue eliminado o liquidado. Seleccione un registro actual.', + 'object.node': 'Nodo', + 'object.nodeData': 'Datos de nodo', + 'object.group': 'grupo', + 'object.groupData': 'Datos del grupo', + 'object.turn': 'Turno', + 'object.turnData': 'Datos del turno', + 'object.step': 'paso', + 'object.stepData': 'datos de paso', + 'object.accessor': '[Getter/setter, no evaluado]', + 'object.empty': 'vacio', + 'object.absent': '[Ranura vacía]', + 'object.properties': 'Otras propiedades', + 'object.more': 'Mostrar más', + 'object.navigation': 'Navegación de datos sin procesar', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'tab.title': 'Journal de session', + 'tab.description': 'Analysez les journaux bruts et les messages de discussion groupés pour la session en cours dans la barre latérale.', + 'view.presentation': 'Présentation', + 'view.sessionLog': 'Journal brut', + 'view.chatNode': 'Groupe de discussion', + 'picker.pick': 'Choisissez un élément dans la vue de discussion', + 'picker.cancel': 'Annuler le prélèvement (Esc)', + 'picker.instructions': 'Passez la souris dans le chat principal pour prévisualiser, puis cliquez pour sélectionner. Esc annule.', + 'picker.noMatch': 'Aucun enregistrement correspondant dans ce tableau. Choisissez un autre élément ou appuyez sur Echap pour annuler.', + 'picker.noChat': 'Ouvrez cette session dans le chat principal avant de choisir.', + 'table.id': 'Indice', + 'table.type': 'Tapez', + 'filter.title': 'Types de filtres', + 'filter.input': 'Tapez le mot-clé', + 'filter.placeholder': 'Tapez un fragment, par ex. delta', + 'filter.help': 'Contient une correspondance (*mot-clé*). Entrez confirme ; Esc annule.', + 'filter.candidates': 'Tapez des suggestions', + 'filter.loading': 'Trouver des suggestions…', + 'filter.failed': "Les suggestions de types n'ont pas pu être chargées.", + 'filter.noCandidates': 'Aucune suggestion. Vous pouvez toujours appliquer ce mot-clé.', + 'filter.clear': 'Effacer', + 'filter.cancel': 'Annuler', + 'filter.apply': 'Appliquer le filtre', + 'filter.context': "Contexte parent d'un enregistrement correspondant", + 'table.location': 'T/S', + 'table.time': 'Heure (UTC)', + 'table.data': 'Données', + 'table.older': 'Charger plus tôt', + 'table.loading': 'Chargement…', + 'table.latest': 'Suivre les dernières', + 'table.empty': 'Aucun enregistrement', + 'table.raw': 'Données brutes', + 'table.rawError': "Cet enregistrement n'a pas pu être sérialisé. Sélectionnez un autre enregistrement pour continuer.", + 'table.resizeDetails': 'Redimensionner le panneau de données brutes', + 'table.close': 'Fermer', + 'table.expand': 'Développer les enfants', + 'table.collapse': 'Réduire les enfants', + 'table.removed': 'Cet enregistrement a été supprimé ou réglé. Sélectionnez un enregistrement actuel.', + 'object.node': 'Nœud', + 'object.nodeData': 'Données de nœud', + 'object.group': 'Groupe', + 'object.groupData': 'Données de groupe', + 'object.turn': 'Tour', + 'object.turnData': 'Données du tour', + 'object.step': 'Étape', + 'object.stepData': "Données d'étape", + 'object.accessor': '[Getter/setter, non évalué]', + 'object.empty': 'Vide', + 'object.absent': '[Emplacement vide]', + 'object.properties': 'Autres propriétés', + 'object.more': 'Afficher plus', + 'object.navigation': 'Navigation dans les données brutes', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'tab.title': 'Sitzungsprotokoll', + 'tab.description': 'Analysieren Sie Rohprotokolle und gruppierte Chat-Nachrichten für die aktuelle Sitzung in der Seitenleiste.', + 'view.presentation': 'Präsentation', + 'view.sessionLog': 'Rohprotokoll', + 'view.chatNode': 'Chat-Gruppe', + 'picker.pick': 'Wählen Sie ein Element in der Chat-Ansicht aus', + 'picker.cancel': 'Kommissionierung abbrechen (Esc)', + 'picker.instructions': 'Bewegen Sie den Mauszeiger über den Hauptchat, um eine Vorschau anzuzeigen, und klicken Sie dann zum Auswählen. Esc bricht ab.', + 'picker.noMatch': 'Kein passender Datensatz in dieser Tabelle. Wählen Sie ein anderes Element aus oder drücken Sie Esc, um den Vorgang abzubrechen.', + 'picker.noChat': 'Öffnen Sie diese Sitzung im Hauptchat, bevor Sie eine Auswahl treffen.', + 'table.id': 'Index', + 'table.type': 'Typ', + 'filter.title': 'Filtertypen', + 'filter.input': 'Geben Sie das Schlüsselwort ein', + 'filter.placeholder': 'Geben Sie ein Fragment ein, z. B. Delta', + 'filter.help': 'Enthält passendes (*Schlüsselwort*). Enter bestätigt; Esc bricht ab.', + 'filter.candidates': 'Typvorschläge', + 'filter.loading': 'Vorschläge finden…', + 'filter.failed': 'Typvorschläge konnten nicht geladen werden.', + 'filter.noCandidates': 'Keine Vorschläge. Sie können dieses Schlüsselwort weiterhin anwenden.', + 'filter.clear': 'Klar', + 'filter.cancel': 'Abbrechen', + 'filter.apply': 'Filter anwenden', + 'filter.context': 'Übergeordneter Kontext eines übereinstimmenden Datensatzes', + 'table.location': 'T/S', + 'table.time': 'Zeit (UTC)', + 'table.data': 'Daten', + 'table.older': 'Früher laden', + 'table.loading': 'Laden…', + 'table.latest': 'Folgen Sie dem neuesten Stand', + 'table.empty': 'Keine Aufzeichnungen', + 'table.raw': 'Rohdaten', + 'table.rawError': 'Dieser Datensatz konnte nicht serialisiert werden. Wählen Sie einen anderen Datensatz aus, um fortzufahren.', + 'table.resizeDetails': 'Größe des Rohdatenbereichs ändern', + 'table.close': 'Schließen', + 'table.expand': 'Erweitern Sie Kinder', + 'table.collapse': 'Kinder zusammenbrechen lassen', + 'table.removed': 'Dieser Datensatz wurde entfernt oder erledigt. Wählen Sie einen aktuellen Datensatz aus.', + 'object.node': 'Knoten', + 'object.nodeData': 'Knotendaten', + 'object.group': 'Gruppe', + 'object.groupData': 'Gruppendaten', + 'object.turn': 'Runde', + 'object.turnData': 'Rundendaten', + 'object.step': 'Schritt', + 'object.stepData': 'Schrittdaten', + 'object.accessor': '[Getter/Setter, nicht ausgewertet]', + 'object.empty': 'Leer', + 'object.absent': '[Leerer Steckplatz]', + 'object.properties': 'Andere Eigenschaften', + 'object.more': 'Mehr anzeigen', + 'object.navigation': 'Rohdatennavigation', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'tab.title': 'Журнал сеанса', + 'tab.description': 'Анализируйте необработанные журналы и сгруппированные сообщения чата для текущего сеанса на боковой панели.', + 'view.presentation': 'Презентация', + 'view.sessionLog': 'Необработанный журнал', + 'view.chatNode': 'Группа чата', + 'picker.pick': 'Выберите элемент в представлении чата', + 'picker.cancel': 'Отменить выбор (Esc)', + 'picker.instructions': 'Наведите указатель мыши на главный чат, чтобы просмотреть его, затем нажмите, чтобы выбрать. Esc отменяет.', + 'picker.noMatch': 'В этой таблице нет соответствующей записи. Выберите другой элемент или нажмите Esc для отмены.', + 'picker.noChat': 'Прежде чем выбирать, откройте эту сессию в главном чате.', + 'table.id': 'Индекс', + 'table.type': 'Тип', + 'filter.title': 'Типы фильтров', + 'filter.input': 'Введите ключевое слово', + 'filter.placeholder': 'Введите фрагмент, например. дельта', + 'filter.help': 'Содержит совпадение (*ключевое слово*). Enter подтверждает; Esc отменяет.', + 'filter.candidates': 'Введите предложения', + 'filter.loading': 'Поиск предложений…', + 'filter.failed': 'Не удалось загрузить предлагаемые типы.', + 'filter.noCandidates': 'Никаких предложений. Вы все еще можете применить это ключевое слово.', + 'filter.clear': 'Очистить', + 'filter.cancel': 'Отмена', + 'filter.apply': 'Применить фильтр', + 'filter.context': 'Родительский контекст соответствующей записи', + 'table.location': 'T/S', + 'table.time': 'Время (UTC)', + 'table.data': 'Данные', + 'table.older': 'Загрузить раньше', + 'table.loading': 'Загрузка…', + 'table.latest': 'Следите за последними', + 'table.empty': 'Нет записей', + 'table.raw': 'Необработанные данные', + 'table.rawError': 'Эту запись не удалось сериализовать. Выберите другую запись, чтобы продолжить.', + 'table.resizeDetails': 'Изменение размера панели необработанных данных', + 'table.close': 'Закрыть', + 'table.expand': 'Развернуть детей', + 'table.collapse': 'Свернуть детей', + 'table.removed': 'Этот рекорд был удален или погашен. Выберите текущую запись.', + 'object.node': 'Узел', + 'object.nodeData': 'Данные узла', + 'object.group': 'Группа', + 'object.groupData': 'Групповые данные', + 'object.turn': 'Ход', + 'object.turnData': 'Данные хода', + 'object.step': 'Шаг', + 'object.stepData': 'Данные шага', + 'object.accessor': '[Получатель/сеттер, не оценивается]', + 'object.empty': 'Пустой', + 'object.absent': '[Пустой слот]', + 'object.properties': 'Другие объекты недвижимости', + 'object.more': 'Показать больше', + 'object.navigation': 'Навигация по необработанным данным', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'tab.title': 'Registro da sessão', + 'tab.description': 'Analise logs brutos e mensagens de bate-papo agrupadas da sessão atual na barra lateral.', + 'view.presentation': 'Apresentação', + 'view.sessionLog': 'Registro bruto', + 'view.chatNode': 'Grupo de bate-papo', + 'picker.pick': 'Escolha um elemento na visualização do chat', + 'picker.cancel': 'Cancelar seleção (Esc)', + 'picker.instructions': 'Passe o mouse no chat principal para visualizar e clique para selecionar. Esc cancela.', + 'picker.noMatch': 'Nenhum registro correspondente nesta tabela. Escolha outro elemento ou pressione Esc para cancelar.', + 'picker.noChat': 'Abra esta sessão no chat principal antes de escolher.', + 'table.id': 'Índice', + 'table.type': 'Tipo', + 'filter.title': 'Tipos de filtro', + 'filter.input': 'Digite palavra-chave', + 'filter.placeholder': 'Digite um fragmento, por ex. delta', + 'filter.help': 'Contém correspondência (*palavra-chave*). Digite confirma; Esc cancela.', + 'filter.candidates': 'Digite sugestões', + 'filter.loading': 'Encontrando sugestões…', + 'filter.failed': 'Não foi possível carregar as sugestões de tipo.', + 'filter.noCandidates': 'Sem sugestões. Você ainda pode aplicar esta palavra-chave.', + 'filter.clear': 'Limpar', + 'filter.cancel': 'Cancelar', + 'filter.apply': 'Aplicar filtro', + 'filter.context': 'Contexto pai de um registro correspondente', + 'table.location': 'T/S', + 'table.time': 'Hora (UTC)', + 'table.data': 'Dados', + 'table.older': 'Carregar mais cedo', + 'table.loading': 'Carregando…', + 'table.latest': 'Siga as últimas', + 'table.empty': 'Sem registros', + 'table.raw': 'Dados brutos', + 'table.rawError': 'Este registro não pôde ser serializado. Selecione outro registro para continuar.', + 'table.resizeDetails': 'Redimensionar painel de dados brutos', + 'table.close': 'Fechar', + 'table.expand': 'Expandir filhos', + 'table.collapse': 'Recolher filhos', + 'table.removed': 'Este registro foi removido ou resolvido. Selecione um registro atual.', + 'object.node': 'Nó', + 'object.nodeData': 'Dados do nó', + 'object.group': 'Grupo', + 'object.groupData': 'Dados do grupo', + 'object.turn': 'Turno', + 'object.turnData': 'Dados do turno', + 'object.step': 'Passo', + 'object.stepData': 'Dados da etapa', + 'object.accessor': '[Getter/setter, não avaliado]', + 'object.empty': 'Vazio', + 'object.absent': '[Slot vazio]', + 'object.properties': 'Outras propriedades', + 'object.more': 'Mostrar mais', + 'object.navigation': 'Navegação de dados brutos', +} satisfies Record diff --git a/packages/experimental/session-search/locale/de.json b/packages/experimental/session-search/locale/de.json new file mode 100644 index 0000000000..a48d3c0d84 --- /dev/null +++ b/packages/experimental/session-search/locale/de.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Sitzungssuche", + "description": "Geben Sie Agenten Tools an die Hand, mit denen sie frühere Sitzungen im aktuellen Arbeitsbereich durchsuchen und lesen können.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/session-search/locale/es.json b/packages/experimental/session-search/locale/es.json new file mode 100644 index 0000000000..c9806106e6 --- /dev/null +++ b/packages/experimental/session-search/locale/es.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "búsqueda de sesión", + "description": "Ofrezca a los agentes herramientas para buscar y leer sesiones anteriores desde el espacio de trabajo actual.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/session-search/locale/fr.json b/packages/experimental/session-search/locale/fr.json new file mode 100644 index 0000000000..26f19d00b5 --- /dev/null +++ b/packages/experimental/session-search/locale/fr.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Recherche de sessions", + "description": "Donnez aux agents des outils pour rechercher et lire les sessions précédentes à partir de l’espace de travail actuel.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/session-search/locale/pt.json b/packages/experimental/session-search/locale/pt.json new file mode 100644 index 0000000000..bd7295aace --- /dev/null +++ b/packages/experimental/session-search/locale/pt.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Pesquisa de sessão", + "description": "Forneça aos agentes ferramentas para pesquisar e ler sessões anteriores do espaço de trabalho atual.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/session-search/locale/ru.json b/packages/experimental/session-search/locale/ru.json new file mode 100644 index 0000000000..b87aa723f2 --- /dev/null +++ b/packages/experimental/session-search/locale/ru.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Поиск сеанса", + "description": "Предоставьте агентам инструменты для поиска и чтения предыдущих сеансов из текущего рабочего пространства.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/session-title-all-prompts-llm/locale/de.json b/packages/experimental/session-title-all-prompts-llm/locale/de.json new file mode 100644 index 0000000000..d7ce24a565 --- /dev/null +++ b/packages/experimental/session-title-all-prompts-llm/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sitzungstitel für alle Nachrichten", + "description": "Generieren Sie Sitzungstitel aus allen Benutzernachrichten in der Sitzung." + } +} diff --git a/packages/experimental/session-title-all-prompts-llm/locale/es.json b/packages/experimental/session-title-all-prompts-llm/locale/es.json new file mode 100644 index 0000000000..ca9b6cd73c --- /dev/null +++ b/packages/experimental/session-title-all-prompts-llm/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Títulos de sesión de todos los mensajes", + "description": "Genere títulos de sesión a partir de todos los mensajes de usuario en la sesión." + } +} diff --git a/packages/experimental/session-title-all-prompts-llm/locale/fr.json b/packages/experimental/session-title-all-prompts-llm/locale/fr.json new file mode 100644 index 0000000000..a04e9415e8 --- /dev/null +++ b/packages/experimental/session-title-all-prompts-llm/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Titres de session contenant tous les messages", + "description": "Générez des titres de session à partir de tous les messages utilisateur de la session." + } +} diff --git a/packages/experimental/session-title-all-prompts-llm/locale/pt.json b/packages/experimental/session-title-all-prompts-llm/locale/pt.json new file mode 100644 index 0000000000..1ad3ee1541 --- /dev/null +++ b/packages/experimental/session-title-all-prompts-llm/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Títulos de sessões com todas as mensagens", + "description": "Gere títulos de sessão de todas as mensagens do usuário na sessão." + } +} diff --git a/packages/experimental/session-title-all-prompts-llm/locale/ru.json b/packages/experimental/session-title-all-prompts-llm/locale/ru.json new file mode 100644 index 0000000000..0c47b680ed --- /dev/null +++ b/packages/experimental/session-title-all-prompts-llm/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Заголовки всех сеансов сообщений", + "description": "Генерируйте заголовки сеансов из всех сообщений пользователя в сеансе." + } +} diff --git a/packages/experimental/session-titles-bundle/locale/de.json b/packages/experimental/session-titles-bundle/locale/de.json new file mode 100644 index 0000000000..e86eecf12f --- /dev/null +++ b/packages/experimental/session-titles-bundle/locale/de.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Konversationsfolgende Titel", + "description": "Aktualisieren Sie die Sitzungstitel, wenn neue menschliche Eingabeaufforderungen eintreffen.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/session-titles-bundle/locale/es.json b/packages/experimental/session-titles-bundle/locale/es.json new file mode 100644 index 0000000000..c8069b5bb4 --- /dev/null +++ b/packages/experimental/session-titles-bundle/locale/es.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Títulos que siguen la conversación", + "description": "Actualice los títulos de las sesiones a medida que lleguen nuevas indicaciones humanas.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/session-titles-bundle/locale/fr.json b/packages/experimental/session-titles-bundle/locale/fr.json new file mode 100644 index 0000000000..271901332f --- /dev/null +++ b/packages/experimental/session-titles-bundle/locale/fr.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Titres de suivi de conversation", + "description": "Actualisez les titres des sessions à mesure que de nouvelles invites humaines arrivent.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/session-titles-bundle/locale/pt.json b/packages/experimental/session-titles-bundle/locale/pt.json new file mode 100644 index 0000000000..29f75c6955 --- /dev/null +++ b/packages/experimental/session-titles-bundle/locale/pt.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Títulos que acompanham conversas", + "description": "Atualize os títulos das sessões à medida que novos prompts humanos chegam.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/session-titles-bundle/locale/ru.json b/packages/experimental/session-titles-bundle/locale/ru.json new file mode 100644 index 0000000000..a9a376b442 --- /dev/null +++ b/packages/experimental/session-titles-bundle/locale/ru.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Заголовки, следующие за разговором", + "description": "Обновляйте названия сеансов по мере поступления новых запросов от человека.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/skill-badge/locale/de.json b/packages/experimental/skill-badge/locale/de.json new file mode 100644 index 0000000000..d8949c9ba4 --- /dev/null +++ b/packages/experimental/skill-badge/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DSH", + "description": "Stellen Sie die offizielle Abzeichenfähigkeit „powered-by-DSH“ bereit." + } +} diff --git a/packages/experimental/skill-badge/locale/es.json b/packages/experimental/skill-badge/locale/es.json new file mode 100644 index 0000000000..62b0c347c5 --- /dev/null +++ b/packages/experimental/skill-badge/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DSH", + "description": "Proporcione la habilidad de insignia oficial impulsada por DSH." + } +} diff --git a/packages/experimental/skill-badge/locale/fr.json b/packages/experimental/skill-badge/locale/fr.json new file mode 100644 index 0000000000..c4d4eaf03b --- /dev/null +++ b/packages/experimental/skill-badge/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DSH", + "description": "Fournissez la compétence de badge officielle propulsée par DSH." + } +} diff --git a/packages/experimental/skill-badge/locale/pt.json b/packages/experimental/skill-badge/locale/pt.json new file mode 100644 index 0000000000..28b4c08977 --- /dev/null +++ b/packages/experimental/skill-badge/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DSH", + "description": "Forneça a habilidade oficial do selo powered-by-DSH." + } +} diff --git a/packages/experimental/skill-badge/locale/ru.json b/packages/experimental/skill-badge/locale/ru.json new file mode 100644 index 0000000000..7b26ba54ee --- /dev/null +++ b/packages/experimental/skill-badge/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DSH", + "description": "Предоставьте официальный навык значка Powered by DSH." + } +} diff --git a/packages/experimental/speech-to-text-sensevoice/locale/de.json b/packages/experimental/speech-to-text-sensevoice/locale/de.json new file mode 100644 index 0000000000..4771295115 --- /dev/null +++ b/packages/experimental/speech-to-text-sensevoice/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Lokale SenseVoice-Erkennung", + "description": "Transkribieren Sie Aufnahmen lokal mit SenseVoice in Text." + } +} diff --git a/packages/experimental/speech-to-text-sensevoice/locale/es.json b/packages/experimental/speech-to-text-sensevoice/locale/es.json new file mode 100644 index 0000000000..375b4ac0de --- /dev/null +++ b/packages/experimental/speech-to-text-sensevoice/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Local SenseReconocimiento de voz", + "description": "Transcribe grabaciones a texto localmente con SenseVoice." + } +} diff --git a/packages/experimental/speech-to-text-sensevoice/locale/fr.json b/packages/experimental/speech-to-text-sensevoice/locale/fr.json new file mode 100644 index 0000000000..a4413476e4 --- /dev/null +++ b/packages/experimental/speech-to-text-sensevoice/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Reconnaissance locale SenseVoice", + "description": "Transcrivez les enregistrements en texte localement avec SenseVoice." + } +} diff --git a/packages/experimental/speech-to-text-sensevoice/locale/pt.json b/packages/experimental/speech-to-text-sensevoice/locale/pt.json new file mode 100644 index 0000000000..8f4f2233d3 --- /dev/null +++ b/packages/experimental/speech-to-text-sensevoice/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Reconhecimento local SenseVoice", + "description": "Transcreva gravações em texto localmente com SenseVoice." + } +} diff --git a/packages/experimental/speech-to-text-sensevoice/locale/ru.json b/packages/experimental/speech-to-text-sensevoice/locale/ru.json new file mode 100644 index 0000000000..635c563b18 --- /dev/null +++ b/packages/experimental/speech-to-text-sensevoice/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Локальное распознавание SenseVoice", + "description": "Транскрибируйте записи в текст локально с помощью SenseVoice." + } +} diff --git a/packages/experimental/speech-to-text/locale/de.json b/packages/experimental/speech-to-text/locale/de.json new file mode 100644 index 0000000000..55ccfecfed --- /dev/null +++ b/packages/experimental/speech-to-text/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Spracherkennung", + "description": "Verwalten Sie die Sprachtranskription und wählen Sie einen Erkennungsdienst aus." + } +} diff --git a/packages/experimental/speech-to-text/locale/es.json b/packages/experimental/speech-to-text/locale/es.json new file mode 100644 index 0000000000..7065257bd8 --- /dev/null +++ b/packages/experimental/speech-to-text/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "reconocimiento de voz", + "description": "Administre la transcripción de voz y seleccione un servicio de reconocimiento." + } +} diff --git a/packages/experimental/speech-to-text/locale/fr.json b/packages/experimental/speech-to-text/locale/fr.json new file mode 100644 index 0000000000..f0573d0040 --- /dev/null +++ b/packages/experimental/speech-to-text/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Reconnaissance vocale", + "description": "Gérez la transcription vocale et sélectionnez un service de reconnaissance." + } +} diff --git a/packages/experimental/speech-to-text/locale/pt.json b/packages/experimental/speech-to-text/locale/pt.json new file mode 100644 index 0000000000..0bb42d2031 --- /dev/null +++ b/packages/experimental/speech-to-text/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Reconhecimento de fala", + "description": "Gerencie a transcrição de fala e selecione um serviço de reconhecimento." + } +} diff --git a/packages/experimental/speech-to-text/locale/ru.json b/packages/experimental/speech-to-text/locale/ru.json new file mode 100644 index 0000000000..09b6156c98 --- /dev/null +++ b/packages/experimental/speech-to-text/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Распознавание речи", + "description": "Управляйте транскрипцией речи и выбирайте службу распознавания." + } +} diff --git a/packages/experimental/subagent-oar/locale/de.json b/packages/experimental/subagent-oar/locale/de.json new file mode 100644 index 0000000000..f552def8d2 --- /dev/null +++ b/packages/experimental/subagent-oar/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "OAR-Subagenten", + "description": "Delegieren Sie Aufgaben über OAR an installierte Codierungsagenten mit den Konfigurationen Codex und Claude Code." + } +} diff --git a/packages/experimental/subagent-oar/locale/es.json b/packages/experimental/subagent-oar/locale/es.json new file mode 100644 index 0000000000..e409de1c55 --- /dev/null +++ b/packages/experimental/subagent-oar/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Subagentes de OAR", + "description": "Delegue tareas a los agentes de codificación instalados a través de OAR, con configuraciones Codex y Claude Code." + } +} diff --git a/packages/experimental/subagent-oar/locale/fr.json b/packages/experimental/subagent-oar/locale/fr.json new file mode 100644 index 0000000000..5de7d98065 --- /dev/null +++ b/packages/experimental/subagent-oar/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sous-agents OAR", + "description": "Déléguez des tâches aux agents de codage installés via OAR, avec les configurations Codex et Claude Code." + } +} diff --git a/packages/experimental/subagent-oar/locale/pt.json b/packages/experimental/subagent-oar/locale/pt.json new file mode 100644 index 0000000000..e3588abb3d --- /dev/null +++ b/packages/experimental/subagent-oar/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Subagentes OAR", + "description": "Delegue tarefas aos agentes de codificação instalados por meio do OAR, com configurações Codex e Claude Code." + } +} diff --git a/packages/experimental/subagent-oar/locale/ru.json b/packages/experimental/subagent-oar/locale/ru.json new file mode 100644 index 0000000000..cc38b60a19 --- /dev/null +++ b/packages/experimental/subagent-oar/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Субагенты ОАР", + "description": "Делегируйте задачи установленным агентам кодирования через OAR с помощью конфигураций Codex и Claude Code." + } +} diff --git a/packages/experimental/terminal-bundle/locale/de.json b/packages/experimental/terminal-bundle/locale/de.json new file mode 100644 index 0000000000..d74f141381 --- /dev/null +++ b/packages/experimental/terminal-bundle/locale/de.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Persistente Terminals", + "description": "Halten Sie Shell-Prozesse über Tool-Aufrufe hinweg am Leben.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/terminal-bundle/locale/es.json b/packages/experimental/terminal-bundle/locale/es.json new file mode 100644 index 0000000000..b3edaf51a0 --- /dev/null +++ b/packages/experimental/terminal-bundle/locale/es.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Terminales persistentes", + "description": "Mantenga vivos los procesos de shell en todas las llamadas a herramientas.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/terminal-bundle/locale/fr.json b/packages/experimental/terminal-bundle/locale/fr.json new file mode 100644 index 0000000000..fe5ccfe323 --- /dev/null +++ b/packages/experimental/terminal-bundle/locale/fr.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Terminaux persistants", + "description": "Maintenez les processus shell en vie lors des appels d’outils.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/terminal-bundle/locale/pt.json b/packages/experimental/terminal-bundle/locale/pt.json new file mode 100644 index 0000000000..013134143b --- /dev/null +++ b/packages/experimental/terminal-bundle/locale/pt.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Terminais persistentes", + "description": "Mantenha os processos shell ativos durante as chamadas de ferramentas.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/terminal-bundle/locale/ru.json b/packages/experimental/terminal-bundle/locale/ru.json new file mode 100644 index 0000000000..9eb8da010c --- /dev/null +++ b/packages/experimental/terminal-bundle/locale/ru.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Постоянные терминалы", + "description": "Поддерживайте активность процессов оболочки во время вызовов инструментов.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/tool-agent-team/locale/de.json b/packages/experimental/tool-agent-team/locale/de.json new file mode 100644 index 0000000000..0120064160 --- /dev/null +++ b/packages/experimental/tool-agent-team/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Team-Tools", + "description": "Geben Sie Agenten Tools an die Hand, mit denen sie Mitglieder koordinieren, Nachrichten austauschen und gemeinsame Aufgaben verwalten können." + } +} diff --git a/packages/experimental/tool-agent-team/locale/es.json b/packages/experimental/tool-agent-team/locale/es.json new file mode 100644 index 0000000000..58f336e814 --- /dev/null +++ b/packages/experimental/tool-agent-team/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramientas de equipo", + "description": "Ofrezca a los agentes herramientas para coordinar miembros, intercambiar mensajes y gestionar tareas compartidas." + } +} diff --git a/packages/experimental/tool-agent-team/locale/fr.json b/packages/experimental/tool-agent-team/locale/fr.json new file mode 100644 index 0000000000..e60a3f8807 --- /dev/null +++ b/packages/experimental/tool-agent-team/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outils d'équipe", + "description": "Donnez aux agents des outils pour coordonner les membres, échanger des messages et gérer les tâches partagées." + } +} diff --git a/packages/experimental/tool-agent-team/locale/pt.json b/packages/experimental/tool-agent-team/locale/pt.json new file mode 100644 index 0000000000..57dd18c9cd --- /dev/null +++ b/packages/experimental/tool-agent-team/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramentas de equipe", + "description": "Dê aos agentes ferramentas para coordenar membros, trocar mensagens e gerenciar tarefas compartilhadas." + } +} diff --git a/packages/experimental/tool-agent-team/locale/ru.json b/packages/experimental/tool-agent-team/locale/ru.json new file mode 100644 index 0000000000..8d82fb6d38 --- /dev/null +++ b/packages/experimental/tool-agent-team/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Командные инструменты", + "description": "Предоставьте агентам инструменты для координации участников, обмена сообщениями и управления общими задачами." + } +} diff --git a/packages/experimental/tool-ralph/locale/de.json b/packages/experimental/tool-ralph/locale/de.json new file mode 100644 index 0000000000..dd53db0846 --- /dev/null +++ b/packages/experimental/tool-ralph/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ralph Iterationstool", + "description": "Lassen Sie neue Unteragenten Runde für Runde das gleiche Ziel verfolgen und geben Sie dabei einen kurzen Bericht aus der vorherigen Runde weiter." + } +} diff --git a/packages/experimental/tool-ralph/locale/es.json b/packages/experimental/tool-ralph/locale/es.json new file mode 100644 index 0000000000..129fefecff --- /dev/null +++ b/packages/experimental/tool-ralph/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramienta de iteración Ralph", + "description": "Ejecute nuevos subagentes ronda por ronda alrededor del mismo objetivo, transmitiéndoles un breve informe de la ronda anterior." + } +} diff --git a/packages/experimental/tool-ralph/locale/fr.json b/packages/experimental/tool-ralph/locale/fr.json new file mode 100644 index 0000000000..478dd9d4ce --- /dev/null +++ b/packages/experimental/tool-ralph/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outil d'itération Ralph", + "description": "Exécutez de nouveaux sous-agents tour par tour autour du même objectif, en leur transmettant un bref rapport du tour précédent." + } +} diff --git a/packages/experimental/tool-ralph/locale/pt.json b/packages/experimental/tool-ralph/locale/pt.json new file mode 100644 index 0000000000..60ff05ca82 --- /dev/null +++ b/packages/experimental/tool-ralph/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramenta de Iteração Ralph", + "description": "Execute novos subagentes rodada por rodada em torno do mesmo objetivo, transmitindo um breve relatório da rodada anterior." + } +} diff --git a/packages/experimental/tool-ralph/locale/ru.json b/packages/experimental/tool-ralph/locale/ru.json new file mode 100644 index 0000000000..916b972056 --- /dev/null +++ b/packages/experimental/tool-ralph/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Инструмент итерации Ральфа", + "description": "Поочередно запускайте новых субагентов для достижения одной и той же цели, передавая им краткий отчет о предыдущем раунде." + } +} diff --git a/packages/experimental/tool-session-query/locale/de.json b/packages/experimental/tool-session-query/locale/de.json new file mode 100644 index 0000000000..847f66e918 --- /dev/null +++ b/packages/experimental/tool-session-query/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Tools für den Sitzungsverlauf", + "description": "Durchsuchen Sie den Sitzungsverlauf und lesen Sie Verläufe und Ereignisse entsprechend den Berechtigungen des Arbeitsbereichs." + } +} diff --git a/packages/experimental/tool-session-query/locale/es.json b/packages/experimental/tool-session-query/locale/es.json new file mode 100644 index 0000000000..9e95db6ebb --- /dev/null +++ b/packages/experimental/tool-session-query/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramientas de historial de sesiones", + "description": "Busque el historial de sesiones y lea trayectorias y eventos según los permisos del espacio de trabajo." + } +} diff --git a/packages/experimental/tool-session-query/locale/fr.json b/packages/experimental/tool-session-query/locale/fr.json new file mode 100644 index 0000000000..e8208773f1 --- /dev/null +++ b/packages/experimental/tool-session-query/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outils d'historique de session", + "description": "Recherchez l’historique des sessions et lisez les trajectoires et les événements en fonction des autorisations de l’espace de travail." + } +} diff --git a/packages/experimental/tool-session-query/locale/pt.json b/packages/experimental/tool-session-query/locale/pt.json new file mode 100644 index 0000000000..aa72842e5f --- /dev/null +++ b/packages/experimental/tool-session-query/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramentas de histórico de sessão", + "description": "Pesquise o histórico da sessão e leia trajetórias e eventos de acordo com as permissões do espaço de trabalho." + } +} diff --git a/packages/experimental/tool-session-query/locale/ru.json b/packages/experimental/tool-session-query/locale/ru.json new file mode 100644 index 0000000000..53d3650c04 --- /dev/null +++ b/packages/experimental/tool-session-query/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Инструменты истории сеансов", + "description": "Выполняйте поиск в истории сеансов и читайте траектории и события в соответствии с разрешениями рабочей области." + } +} diff --git a/packages/experimental/tool-subagent-oar/locale/de.json b/packages/experimental/tool-subagent-oar/locale/de.json new file mode 100644 index 0000000000..56d0098d05 --- /dev/null +++ b/packages/experimental/tool-subagent-oar/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "OAR-Subagenten-Tool", + "description": "Wählen Sie für jede eigenständige Aufgabe einen konfigurierten externen Agenten aus." + } +} diff --git a/packages/experimental/tool-subagent-oar/locale/es.json b/packages/experimental/tool-subagent-oar/locale/es.json new file mode 100644 index 0000000000..4e0f205de5 --- /dev/null +++ b/packages/experimental/tool-subagent-oar/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramienta subagente OAR", + "description": "Elija un agente externo configurado para cada tarea independiente." + } +} diff --git a/packages/experimental/tool-subagent-oar/locale/fr.json b/packages/experimental/tool-subagent-oar/locale/fr.json new file mode 100644 index 0000000000..46adade87b --- /dev/null +++ b/packages/experimental/tool-subagent-oar/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outil de sous-agent OAR", + "description": "Choisissez un agent externe configuré pour chaque tâche autonome." + } +} diff --git a/packages/experimental/tool-subagent-oar/locale/pt.json b/packages/experimental/tool-subagent-oar/locale/pt.json new file mode 100644 index 0000000000..6ddff34aff --- /dev/null +++ b/packages/experimental/tool-subagent-oar/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramenta de subagente OAR", + "description": "Escolha um agente externo configurado para cada tarefa autônoma." + } +} diff --git a/packages/experimental/tool-subagent-oar/locale/ru.json b/packages/experimental/tool-subagent-oar/locale/ru.json new file mode 100644 index 0000000000..9285b30c27 --- /dev/null +++ b/packages/experimental/tool-subagent-oar/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Инструмент субагента OAR", + "description": "Выберите настроенный внешний агент для каждой отдельной задачи." + } +} diff --git a/packages/experimental/tool-terminal/locale/de.json b/packages/experimental/tool-terminal/locale/de.json new file mode 100644 index 0000000000..8c68d209bc --- /dev/null +++ b/packages/experimental/tool-terminal/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Persistente Terminal-Tools", + "description": "Stellen Sie sechs persistente PTY-Tools mit isoliertem Sitzungsbesitz und Integration von Hintergrundaufgaben bereit." + } +} diff --git a/packages/experimental/tool-terminal/locale/es.json b/packages/experimental/tool-terminal/locale/es.json new file mode 100644 index 0000000000..223f19fdaa --- /dev/null +++ b/packages/experimental/tool-terminal/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramientas de terminal persistente", + "description": "Proporcione seis herramientas PTY persistentes con propiedad de sesión aislada e integración de tareas en segundo plano." + } +} diff --git a/packages/experimental/tool-terminal/locale/fr.json b/packages/experimental/tool-terminal/locale/fr.json new file mode 100644 index 0000000000..0a287f3778 --- /dev/null +++ b/packages/experimental/tool-terminal/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outils de terminal persistants", + "description": "Fournissez six outils PTY persistants avec propriété de session isolée et intégration de tâches en arrière-plan." + } +} diff --git a/packages/experimental/tool-terminal/locale/pt.json b/packages/experimental/tool-terminal/locale/pt.json new file mode 100644 index 0000000000..64ea1683f7 --- /dev/null +++ b/packages/experimental/tool-terminal/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramentas de terminal persistentes", + "description": "Forneça seis ferramentas PTY persistentes com propriedade de sessão isolada e integração de tarefas em segundo plano." + } +} diff --git a/packages/experimental/tool-terminal/locale/ru.json b/packages/experimental/tool-terminal/locale/ru.json new file mode 100644 index 0000000000..38d713c59a --- /dev/null +++ b/packages/experimental/tool-terminal/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Постоянные терминальные инструменты", + "description": "Предоставьте шесть постоянных инструментов PTY с изолированным владением сеансом и интеграцией фоновых задач." + } +} diff --git a/packages/experimental/tool-worktree/locale/de.json b/packages/experimental/tool-worktree/locale/de.json new file mode 100644 index 0000000000..2fdd99f663 --- /dev/null +++ b/packages/experimental/tool-worktree/locale/de.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Git-Arbeitsbäume", + "description": "Lassen Sie den Agenten einen neuen Git-Zweig und Arbeitsbaum erstellen und fahren Sie dann dort fort.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/tool-worktree/locale/es.json b/packages/experimental/tool-worktree/locale/es.json new file mode 100644 index 0000000000..69d239b19b --- /dev/null +++ b/packages/experimental/tool-worktree/locale/es.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "árboles de trabajo de git", + "description": "Deje que el agente cree una nueva rama de Git y un árbol de trabajo y luego continúe allí.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/tool-worktree/locale/fr.json b/packages/experimental/tool-worktree/locale/fr.json new file mode 100644 index 0000000000..073bbb802d --- /dev/null +++ b/packages/experimental/tool-worktree/locale/fr.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Arbres de travail Git", + "description": "Laissez l’agent créer une nouvelle branche et un nouvel arbre de travail Git, puis continuez là.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/tool-worktree/locale/pt.json b/packages/experimental/tool-worktree/locale/pt.json new file mode 100644 index 0000000000..03caa832dd --- /dev/null +++ b/packages/experimental/tool-worktree/locale/pt.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Árvores de trabalho Git", + "description": "Deixe o agente criar uma nova ramificação e árvore de trabalho do Git e continue lá.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/tool-worktree/locale/ru.json b/packages/experimental/tool-worktree/locale/ru.json new file mode 100644 index 0000000000..eb4cf7407a --- /dev/null +++ b/packages/experimental/tool-worktree/locale/ru.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Рабочие деревья Git", + "description": "Позвольте агенту создать новую ветку и рабочее дерево Git, а затем продолжите работу там.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/translator/locale/de.json b/packages/experimental/translator/locale/de.json new file mode 100644 index 0000000000..6858b66b76 --- /dev/null +++ b/packages/experimental/translator/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Übersetzungsdienst", + "description": "Übersetzen Sie Text und verwenden Sie in der Sitzung gespeicherte Übersetzungen wieder." + } +} diff --git a/packages/experimental/translator/locale/es.json b/packages/experimental/translator/locale/es.json new file mode 100644 index 0000000000..828e7b9c78 --- /dev/null +++ b/packages/experimental/translator/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Servicio de traducción", + "description": "Traduce texto y reutiliza las traducciones guardadas en la sesión." + } +} diff --git a/packages/experimental/translator/locale/fr.json b/packages/experimental/translator/locale/fr.json new file mode 100644 index 0000000000..6e132db73e --- /dev/null +++ b/packages/experimental/translator/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Service de traduction", + "description": "Traduisez le texte et réutilisez les traductions enregistrées dans la session." + } +} diff --git a/packages/experimental/translator/locale/pt.json b/packages/experimental/translator/locale/pt.json new file mode 100644 index 0000000000..7c2bd342de --- /dev/null +++ b/packages/experimental/translator/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Serviço de tradução", + "description": "Traduza texto e reutilize traduções salvas na sessão." + } +} diff --git a/packages/experimental/translator/locale/ru.json b/packages/experimental/translator/locale/ru.json new file mode 100644 index 0000000000..886e56f795 --- /dev/null +++ b/packages/experimental/translator/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Услуги перевода", + "description": "Переведите текст и повторно используйте переводы, сохраненные в сеансе." + } +} diff --git a/packages/experimental/voice-input-bundle/locale/de.json b/packages/experimental/voice-input-bundle/locale/de.json new file mode 100644 index 0000000000..ceb1ff524d --- /dev/null +++ b/packages/experimental/voice-input-bundle/locale/de.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Spracheingabe", + "description": "Transkribieren Sie Aufnahmen lokal mit SenseVoice; Für die erste Verwendung müssen Abhängigkeiten installiert werden.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/voice-input-bundle/locale/es.json b/packages/experimental/voice-input-bundle/locale/es.json new file mode 100644 index 0000000000..cf5515a994 --- /dev/null +++ b/packages/experimental/voice-input-bundle/locale/es.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Entrada de voz", + "description": "Transcribe grabaciones localmente con SenseVoice; El primer uso requiere instalar dependencias.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/voice-input-bundle/locale/fr.json b/packages/experimental/voice-input-bundle/locale/fr.json new file mode 100644 index 0000000000..efcb87ff7c --- /dev/null +++ b/packages/experimental/voice-input-bundle/locale/fr.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Saisie vocale", + "description": "Transcrivez les enregistrements localement avec SenseVoice ; la première utilisation nécessite l'installation de dépendances.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/voice-input-bundle/locale/pt.json b/packages/experimental/voice-input-bundle/locale/pt.json new file mode 100644 index 0000000000..a50a67956c --- /dev/null +++ b/packages/experimental/voice-input-bundle/locale/pt.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Entrada de voz", + "description": "Transcreva gravações localmente com SenseVoice; o primeiro uso requer a instalação de dependências.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/voice-input-bundle/locale/ru.json b/packages/experimental/voice-input-bundle/locale/ru.json new file mode 100644 index 0000000000..474fc4c149 --- /dev/null +++ b/packages/experimental/voice-input-bundle/locale/ru.json @@ -0,0 +1,7 @@ +{ + "meta": { + "title": "Голосовой ввод", + "description": "Транскрибируйте записи локально с помощью SenseVoice; при первом использовании требуется установка зависимостей.", + "detail": "docs/DETAIL.md" + } +} diff --git a/packages/experimental/webhook-github/locale/de.json b/packages/experimental/webhook-github/locale/de.json new file mode 100644 index 0000000000..b562af5410 --- /dev/null +++ b/packages/experimental/webhook-github/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "GitHub Webhooks", + "description": "Überprüfen Sie signierte GitHub HTTP-Webhooks und leiten Sie sie an den Webhook-Dienst weiter." + } +} diff --git a/packages/experimental/webhook-github/locale/es.json b/packages/experimental/webhook-github/locale/es.json new file mode 100644 index 0000000000..564c99f383 --- /dev/null +++ b/packages/experimental/webhook-github/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Webhooks GitHub", + "description": "Verifique los webhooks GitHub HTTP firmados y reenvíelos al servicio Webhook." + } +} diff --git a/packages/experimental/webhook-github/locale/fr.json b/packages/experimental/webhook-github/locale/fr.json new file mode 100644 index 0000000000..f8c1102375 --- /dev/null +++ b/packages/experimental/webhook-github/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Webhooks GitHub", + "description": "Vérifiez les webhooks GitHub HTTP signés et transférez-les au service Webhook." + } +} diff --git a/packages/experimental/webhook-github/locale/pt.json b/packages/experimental/webhook-github/locale/pt.json new file mode 100644 index 0000000000..756a19e48a --- /dev/null +++ b/packages/experimental/webhook-github/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "GitHub webhooks", + "description": "Verifique webhooks GitHub HTTP assinados e encaminhe-os para o serviço Webhook." + } +} diff --git a/packages/experimental/webhook-github/locale/ru.json b/packages/experimental/webhook-github/locale/ru.json new file mode 100644 index 0000000000..94edd6e152 --- /dev/null +++ b/packages/experimental/webhook-github/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Вебхуки GitHub", + "description": "Проверьте подписанные веб-перехватчики GitHub HTTP и перенаправьте их в службу Webhook." + } +} diff --git a/packages/experimental/webhook/locale/de.json b/packages/experimental/webhook/locale/de.json new file mode 100644 index 0000000000..4019fc12b7 --- /dev/null +++ b/packages/experimental/webhook/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Webhook-Laufzeit", + "description": "Erstellen Sie Harness-Sitzungen in einem Arbeitsbereich über Webhook-Regeln, ohne auf den Abschluss warten zu müssen." + } +} diff --git a/packages/experimental/webhook/locale/es.json b/packages/experimental/webhook/locale/es.json new file mode 100644 index 0000000000..4f406bd11f --- /dev/null +++ b/packages/experimental/webhook/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Tiempo de ejecución del webhook", + "description": "Cree sesiones de Harness en un espacio de trabajo a través de reglas de Webhook sin esperar a que finalicen." + } +} diff --git a/packages/experimental/webhook/locale/fr.json b/packages/experimental/webhook/locale/fr.json new file mode 100644 index 0000000000..0be212731e --- /dev/null +++ b/packages/experimental/webhook/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Exécution du webhook", + "description": "Créez des sessions Harness dans un espace de travail via des règles Webhook sans attendre la fin." + } +} diff --git a/packages/experimental/webhook/locale/pt.json b/packages/experimental/webhook/locale/pt.json new file mode 100644 index 0000000000..907389729b --- /dev/null +++ b/packages/experimental/webhook/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Tempo de execução do webhook", + "description": "Crie sessões do Harness em um espaço de trabalho por meio de regras de Webhook sem aguardar a conclusão." + } +} diff --git a/packages/experimental/webhook/locale/ru.json b/packages/experimental/webhook/locale/ru.json new file mode 100644 index 0000000000..98ec4c2caf --- /dev/null +++ b/packages/experimental/webhook/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Среда выполнения вебхука", + "description": "Создавайте сеансы Harness в рабочей области с помощью правил Webhook, не дожидаясь завершения." + } +} diff --git a/packages/experimental/worktree/locale/de.json b/packages/experimental/worktree/locale/de.json new file mode 100644 index 0000000000..c729e3fadf --- /dev/null +++ b/packages/experimental/worktree/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Worktree-Dienst", + "description": "Erstellen Sie benannte Git-Arbeitsbäume und ändern Sie das Arbeitsverzeichnis der aktuellen Sitzung." + } +} diff --git a/packages/experimental/worktree/locale/es.json b/packages/experimental/worktree/locale/es.json new file mode 100644 index 0000000000..195f47b93c --- /dev/null +++ b/packages/experimental/worktree/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Servicio de árbol de trabajo", + "description": "Cree árboles de trabajo Git con nombre y cambie el directorio de trabajo de la sesión actual." + } +} diff --git a/packages/experimental/worktree/locale/fr.json b/packages/experimental/worktree/locale/fr.json new file mode 100644 index 0000000000..3c16a0ba9c --- /dev/null +++ b/packages/experimental/worktree/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Service d'arbre de travail", + "description": "Créez des arbres de travail Git nommés et modifiez le répertoire de travail de la session en cours." + } +} diff --git a/packages/experimental/worktree/locale/pt.json b/packages/experimental/worktree/locale/pt.json new file mode 100644 index 0000000000..13afba33bf --- /dev/null +++ b/packages/experimental/worktree/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Serviço de árvore de trabalho", + "description": "Crie árvores de trabalho Git nomeadas e altere o diretório de trabalho da sessão atual." + } +} diff --git a/packages/experimental/worktree/locale/ru.json b/packages/experimental/worktree/locale/ru.json new file mode 100644 index 0000000000..814de08251 --- /dev/null +++ b/packages/experimental/worktree/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Сервис рабочего дерева", + "description": "Создайте именованные рабочие деревья Git и измените рабочий каталог текущего сеанса." + } +} diff --git a/packages/extensions/cordis-client-runner/locale/de.json b/packages/extensions/cordis-client-runner/locale/de.json new file mode 100644 index 0000000000..62cfd9e525 --- /dev/null +++ b/packages/extensions/cordis-client-runner/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Dynamischer Plug-in-Browser-Runner", + "description": "Laden Sie den Browser-Teil des temporären dynamischen Plug-Ins und führen Sie ihn aus." + } +} diff --git a/packages/extensions/cordis-client-runner/locale/es.json b/packages/extensions/cordis-client-runner/locale/es.json new file mode 100644 index 0000000000..263c35569f --- /dev/null +++ b/packages/extensions/cordis-client-runner/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ejecutor de navegador de complemento dinámico", + "description": "Cargue y ejecute la parte del navegador del complemento dinámico temporal." + } +} diff --git a/packages/extensions/cordis-client-runner/locale/fr.json b/packages/extensions/cordis-client-runner/locale/fr.json new file mode 100644 index 0000000000..f5c444889c --- /dev/null +++ b/packages/extensions/cordis-client-runner/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Exécuteur de navigateur de plug-in dynamique", + "description": "Chargez et exécutez la partie navigateur du plug-in dynamique temporaire." + } +} diff --git a/packages/extensions/cordis-client-runner/locale/pt.json b/packages/extensions/cordis-client-runner/locale/pt.json new file mode 100644 index 0000000000..e82cb2bbaa --- /dev/null +++ b/packages/extensions/cordis-client-runner/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Executor de navegador de plug-in dinâmico", + "description": "Carregue e execute a parte do navegador do plug-in dinâmico temporário." + } +} diff --git a/packages/extensions/cordis-client-runner/locale/ru.json b/packages/extensions/cordis-client-runner/locale/ru.json new file mode 100644 index 0000000000..6f51c2142f --- /dev/null +++ b/packages/extensions/cordis-client-runner/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Динамический плагин для запуска браузера", + "description": "Загрузите и запустите браузерную часть временного динамического плагина." + } +} diff --git a/packages/extensions/cordis-host-runner/locale/de.json b/packages/extensions/cordis-host-runner/locale/de.json new file mode 100644 index 0000000000..716776ddee --- /dev/null +++ b/packages/extensions/cordis-host-runner/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Dynamischer Plug-in-Server-Runner", + "description": "Verwalten Sie temporäre dynamische Plug-in-Definitionen und führen Sie deren serverseitige Teile aus." + } +} diff --git a/packages/extensions/cordis-host-runner/locale/es.json b/packages/extensions/cordis-host-runner/locale/es.json new file mode 100644 index 0000000000..42b7cca8cc --- /dev/null +++ b/packages/extensions/cordis-host-runner/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ejecutor de servidor de complemento dinámico", + "description": "Administre definiciones de complementos dinámicos temporales y ejecute sus partes del lado del servidor." + } +} diff --git a/packages/extensions/cordis-host-runner/locale/fr.json b/packages/extensions/cordis-host-runner/locale/fr.json new file mode 100644 index 0000000000..31afe24322 --- /dev/null +++ b/packages/extensions/cordis-host-runner/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Exécuteur de serveur de plug-in dynamique", + "description": "Gérez les définitions de plug-ins dynamiques temporaires et exécutez leurs parties côté serveur." + } +} diff --git a/packages/extensions/cordis-host-runner/locale/pt.json b/packages/extensions/cordis-host-runner/locale/pt.json new file mode 100644 index 0000000000..c99c41f2f1 --- /dev/null +++ b/packages/extensions/cordis-host-runner/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Executor de servidor de plug-in dinâmico", + "description": "Gerencie definições de plug-ins dinâmicos temporários e execute suas partes do lado do servidor." + } +} diff --git a/packages/extensions/cordis-host-runner/locale/ru.json b/packages/extensions/cordis-host-runner/locale/ru.json new file mode 100644 index 0000000000..0f5179cf27 --- /dev/null +++ b/packages/extensions/cordis-host-runner/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Динамический плагин для запуска серверов", + "description": "Управляйте временными динамическими определениями плагинов и запускайте их серверные части." + } +} diff --git a/packages/extensions/tool-cordis/locale/de.json b/packages/extensions/tool-cordis/locale/de.json new file mode 100644 index 0000000000..cf39c9c374 --- /dev/null +++ b/packages/extensions/tool-cordis/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Plugin API-Abfragetool", + "description": "Lassen Sie AI den Server und den Browser nach verfügbaren API abfragen, bevor Sie das Plug-in entwickeln." + } +} diff --git a/packages/extensions/tool-cordis/locale/es.json b/packages/extensions/tool-cordis/locale/es.json new file mode 100644 index 0000000000..07bf1563d9 --- /dev/null +++ b/packages/extensions/tool-cordis/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Complemento API herramienta de consulta", + "description": "Deje que AI consulte el servidor y el navegador para ver si hay API disponible antes de desarrollar el complemento." + } +} diff --git a/packages/extensions/tool-cordis/locale/fr.json b/packages/extensions/tool-cordis/locale/fr.json new file mode 100644 index 0000000000..d3f173ac00 --- /dev/null +++ b/packages/extensions/tool-cordis/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outil de requête du plug-in API", + "description": "Laissez AI interroger le serveur et le navigateur pour connaître les API disponibles avant de développer le plug-in." + } +} diff --git a/packages/extensions/tool-cordis/locale/host/de.json b/packages/extensions/tool-cordis/locale/host/de.json new file mode 100644 index 0000000000..b2efb63be5 --- /dev/null +++ b/packages/extensions/tool-cordis/locale/host/de.json @@ -0,0 +1,5 @@ +{ + "meta": { + "title": "Dienst zur Inspektion der Plugin-API" + } +} diff --git a/packages/extensions/tool-cordis/locale/host/es.json b/packages/extensions/tool-cordis/locale/host/es.json new file mode 100644 index 0000000000..792fba3214 --- /dev/null +++ b/packages/extensions/tool-cordis/locale/host/es.json @@ -0,0 +1,5 @@ +{ + "meta": { + "title": "Servicio de inspección de API de plugins" + } +} diff --git a/packages/extensions/tool-cordis/locale/host/fr.json b/packages/extensions/tool-cordis/locale/host/fr.json new file mode 100644 index 0000000000..b99c316540 --- /dev/null +++ b/packages/extensions/tool-cordis/locale/host/fr.json @@ -0,0 +1,5 @@ +{ + "meta": { + "title": "Service d’inspection des API de plugins" + } +} diff --git a/packages/extensions/tool-cordis/locale/host/pt.json b/packages/extensions/tool-cordis/locale/host/pt.json new file mode 100644 index 0000000000..bf13cdba94 --- /dev/null +++ b/packages/extensions/tool-cordis/locale/host/pt.json @@ -0,0 +1,5 @@ +{ + "meta": { + "title": "Serviço de inspeção de APIs de plug-ins" + } +} diff --git a/packages/extensions/tool-cordis/locale/host/ru.json b/packages/extensions/tool-cordis/locale/host/ru.json new file mode 100644 index 0000000000..5235a26c44 --- /dev/null +++ b/packages/extensions/tool-cordis/locale/host/ru.json @@ -0,0 +1,5 @@ +{ + "meta": { + "title": "Служба инспекции API плагинов" + } +} diff --git a/packages/extensions/tool-cordis/locale/pt.json b/packages/extensions/tool-cordis/locale/pt.json new file mode 100644 index 0000000000..21f7e4721d --- /dev/null +++ b/packages/extensions/tool-cordis/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramenta de consulta do plug-in API", + "description": "Deixe a IA consultar o servidor e o navegador em busca de API disponíveis antes de desenvolver o plug-in." + } +} diff --git a/packages/extensions/tool-cordis/locale/ru.json b/packages/extensions/tool-cordis/locale/ru.json new file mode 100644 index 0000000000..2f969843c8 --- /dev/null +++ b/packages/extensions/tool-cordis/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Плагин API, инструмент запросов", + "description": "Позвольте ИИ запросить у сервера и браузера доступный API, прежде чем разрабатывать плагин." + } +} diff --git a/packages/extensions/ui-cordis/locale/de.json b/packages/extensions/ui-cordis/locale/de.json new file mode 100644 index 0000000000..c0d56ea0d7 --- /dev/null +++ b/packages/extensions/ui-cordis/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Dynamische Plug-in-Laufkarte", + "description": "Zeigt dynamische Plug-In-Definitionen an und bietet Steuerelemente zum Ausführen und Stoppen." + } +} diff --git a/packages/extensions/ui-cordis/locale/es.json b/packages/extensions/ui-cordis/locale/es.json new file mode 100644 index 0000000000..0010e3f46d --- /dev/null +++ b/packages/extensions/ui-cordis/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Tarjeta de ejecución dinámica enchufable", + "description": "Muestra definiciones dinámicas de complementos y proporciona controles de ejecución y parada." + } +} diff --git a/packages/extensions/ui-cordis/locale/fr.json b/packages/extensions/ui-cordis/locale/fr.json new file mode 100644 index 0000000000..23ac47c152 --- /dev/null +++ b/packages/extensions/ui-cordis/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Carte de fonctionnement enfichable dynamique", + "description": "Affiche les définitions de plug-in dynamiques et fournit des contrôles d'exécution et d'arrêt." + } +} diff --git a/packages/extensions/ui-cordis/locale/pt.json b/packages/extensions/ui-cordis/locale/pt.json new file mode 100644 index 0000000000..00ea376abb --- /dev/null +++ b/packages/extensions/ui-cordis/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Placa de corrida plug-in dinâmica", + "description": "Exibe definições dinâmicas de plug-in e fornece controles de execução e parada." + } +} diff --git a/packages/extensions/ui-cordis/locale/ru.json b/packages/extensions/ui-cordis/locale/ru.json new file mode 100644 index 0000000000..977b05a27a --- /dev/null +++ b/packages/extensions/ui-cordis/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Динамическая подключаемая беговая карта", + "description": "Отображает динамические определения плагинов и обеспечивает элементы управления запуском и остановкой." + } +} diff --git a/packages/extensions/ui-cordis/src/client/index.ts b/packages/extensions/ui-cordis/src/client/index.ts index 26eb254437..dae71afa42 100644 --- a/packages/extensions/ui-cordis/src/client/index.ts +++ b/packages/extensions/ui-cordis/src/client/index.ts @@ -17,7 +17,7 @@ import { createCordisInventory } from './inventory.ts' import { CordisRunCardRegistry } from './run-card-index.ts' import type { CordisDynamicPort } from './dynamic-port.ts' import type { CordisCardFace, CordisPanelFace, CordisRunCardFace } from './slots.ts' -import { en, ja, NS, zh } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, NS, zh } from './locales.ts' export type { CordisCardFace, CordisPanelFace, CordisRunCardFace, CordisToolViewOwnerProps } from './slots.ts' export type { CordisActionResult, CordisDynamicPort, CordisInventoryRow } from './dynamic-port.ts' @@ -40,7 +40,7 @@ export const inject = [ /** Mount every Cordis browser surface over the shared Host inventory. */ export function apply(ctx: ClientContext): void { - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'ui-cordis: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'ui-cordis: dictionaries') const port: CordisDynamicPort = { stop: async (sessionId, pluginId) => { diff --git a/packages/extensions/ui-cordis/src/client/locales.ts b/packages/extensions/ui-cordis/src/client/locales.ts index 5483c81a3a..524871507a 100644 --- a/packages/extensions/ui-cordis/src/client/locales.ts +++ b/packages/extensions/ui-cordis/src/client/locales.ts @@ -176,3 +176,278 @@ export const ja = { 'body.copy': 'コピー', 'body.copied': 'コピーしました', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'row.defineTitle': 'Registrar el complemento Cordis', + 'a11y.preparing': 'Preparando una llamada a la herramienta Cordis', + 'row.runTitle': 'Ejecute el complemento Cordis', + 'row.updateTitle': 'Actualizar el complemento Cordis', + 'row.stopTitle': 'Detener el complemento Cordis', + 'row.removeTitle': 'Eliminar el complemento Cordis', + 'purpose.missing': '(sin propósito dado)', + 'status.idle': 'Listo', + 'status.awaitingApproval': 'En espera de aprobación', + 'status.failed': 'La ejecución falló', + 'status.clientPending': 'Cliente listo para activar', + 'status.running': 'corriendo', + 'status.removed': 'Eliminado', + 'status.superseded': 'Ejecución más nueva disponible', + 'run.removed': 'Este paquete ya no existe', + 'run.superseded': 'Una tarjeta de ejecución más nueva está disponible a continuación', + 'panel.hint': 'Ejecute controles en vivo en el panel Cordis arriba de Configuración', + 'panel.plugins.aria': 'Complementos Cordis', + 'panel.approvals.aria': 'Aprobaciones Cordis', + 'panel.trigger': 'Complemento Cordis', + 'panel.runningCount': '{count} corriendo', + 'panel.title': 'Complementos Cordis', + 'panel.empty': 'Aún no se han definido complementos', + 'panel.loading': 'Leyendo…', + 'panel.readFailed': 'Error al leer el inventario de complementos: {message}', + 'panel.group.current': 'Esta sesión', + 'panel.group.others': 'Otras sesiones', + 'panel.version': 'Versión', + 'panel.current': 'Actual: {packageId}', + 'panel.next': 'Siguiente: {packageId}', + 'action.approve': 'Permitir', + 'action.approveOnce': 'Permitir solo esta versión', + 'action.approvePlugin': 'Permitir versiones futuras de este complemento', + 'action.decline': 'Rechazar', + 'action.run': 'correr', + 'action.stop': 'Detener', + 'action.remove': 'Quitar', + 'action.retry': 'Reintentar', + 'action.rollback': 'retroceder', + 'action.inspect': 'inspeccionar', + 'render.failedAbdicated': 'Error de renderizado en {slot}; se restauró la interfaz de usuario predeterminada:', + 'render.failedHeld': 'Error de renderizado en {slot}:', + 'a11y.defining': 'Definiendo el complemento', + 'a11y.failed': 'Definición fallida', + 'a11y.stopped': 'Definición interrumpida', + 'body.source': 'Fuente del complemento', + 'body.hostCode': 'Anfitrión', + 'body.clientCode': 'Cliente', + 'body.output': 'Resultado', + 'body.copy': 'Copiar', + 'body.copied': 'Copiado', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'row.defineTitle': 'Enregistrer le plugin Cordis', + 'a11y.preparing': "Préparation d'un appel d'outil Cordis", + 'row.runTitle': 'Exécuter le plugin Cordis', + 'row.updateTitle': 'Mettre à jour le plug-in Cordis', + 'row.stopTitle': 'Arrêter le plug-in Cordis', + 'row.removeTitle': 'Supprimer le plug-in Cordis', + 'purpose.missing': '(aucun but donné)', + 'status.idle': 'Prêt', + 'status.awaitingApproval': "En attente d'approbation", + 'status.failed': "Échec de l'exécution", + 'status.clientPending': 'Client prêt à activer', + 'status.running': 'Courir', + 'status.removed': 'Supprimé', + 'status.superseded': 'Exécution plus récente disponible', + 'run.removed': "Ce forfait n'existe plus", + 'run.superseded': 'Une carte de course plus récente est disponible ci-dessous', + 'panel.hint': 'Exécutez les contrôles en direct dans le panneau Cordis au-dessus des paramètres', + 'panel.plugins.aria': 'Plugins Cordis', + 'panel.approvals.aria': 'Homologations Cordis', + 'panel.trigger': 'Plugin Cordis', + 'panel.runningCount': "{count} en cours d'exécution", + 'panel.title': 'Plugins Cordis', + 'panel.empty': "Aucun plugin défini pour l'instant", + 'panel.loading': 'Lecture…', + 'panel.readFailed': "Échec de la lecture de l'inventaire du plugin : {message}", + 'panel.group.current': 'Cette séance', + 'panel.group.others': 'Autres séances', + 'panel.version': 'Version', + 'panel.current': 'Actuel : {packageId}', + 'panel.next': 'Suivant : {packageId}', + 'action.approve': 'Autoriser', + 'action.approveOnce': 'Autoriser cette version uniquement', + 'action.approvePlugin': 'Autoriser les futures versions de ce plugin', + 'action.decline': 'Refuser', + 'action.run': 'Courir', + 'action.stop': 'Arrêter', + 'action.remove': 'Supprimer', + 'action.retry': 'Réessayer', + 'action.rollback': 'Revenir en arrière', + 'action.inspect': 'Inspecter', + 'render.failedAbdicated': "Le rendu a échoué dans {slot} ; l'interface utilisateur par défaut a été restaurée :", + 'render.failedHeld': 'Échec du rendu dans {slot} :', + 'a11y.defining': 'Définir le plugin', + 'a11y.failed': 'Échec de la définition', + 'a11y.stopped': 'Définition interrompue', + 'body.source': 'Source du plugin', + 'body.hostCode': 'Hôte', + 'body.clientCode': 'Client', + 'body.output': 'Résultat', + 'body.copy': 'Copier', + 'body.copied': 'Copié', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'row.defineTitle': 'Registrieren Sie das Cordis-Plugin', + 'a11y.preparing': 'Vorbereiten eines Cordis-Toolaufrufs', + 'row.runTitle': 'Führen Sie das Cordis-Plugin aus', + 'row.updateTitle': 'Aktualisieren Sie das Cordis-Plugin', + 'row.stopTitle': 'Stoppen Sie das Cordis-Plugin', + 'row.removeTitle': 'Entfernen Sie das Cordis-Plugin', + 'purpose.missing': '(kein Zweck angegeben)', + 'status.idle': 'Bereit', + 'status.awaitingApproval': 'Warten auf Genehmigung', + 'status.failed': 'Ausführung fehlgeschlagen', + 'status.clientPending': 'Client bereit zur Aktivierung', + 'status.running': 'Laufen', + 'status.removed': 'Entfernt', + 'status.superseded': 'Neuere Ausführung verfügbar', + 'run.removed': 'Dieses Paket existiert nicht mehr', + 'run.superseded': 'Eine neuere Laufkarte ist unten verfügbar', + 'panel.hint': 'Führen Sie die Steuerelemente live im Cordis-Bedienfeld über den Einstellungen aus', + 'panel.plugins.aria': 'Cordis-Plugins', + 'panel.approvals.aria': 'Cordis-Zulassungen', + 'panel.trigger': 'Cordis-Plugin', + 'panel.runningCount': '{count} läuft', + 'panel.title': 'Cordis-Plugins', + 'panel.empty': 'Noch keine Plugins definiert', + 'panel.loading': 'Lesen…', + 'panel.readFailed': 'Das Lesen des Plugin-Inventars ist fehlgeschlagen: {message}', + 'panel.group.current': 'Diese Sitzung', + 'panel.group.others': 'Andere Sitzungen', + 'panel.version': 'Version', + 'panel.current': 'Aktuell: {packageId}', + 'panel.next': 'Weiter: {packageId}', + 'action.approve': 'Erlauben', + 'action.approveOnce': 'Nur diese Version zulassen', + 'action.approvePlugin': 'Zukünftige Versionen dieses Plugins zulassen', + 'action.decline': 'Ablehnen', + 'action.run': 'Lauf', + 'action.stop': 'Stopp', + 'action.remove': 'Entfernen', + 'action.retry': 'Erneut versuchen', + 'action.rollback': 'Zurückrollen', + 'action.inspect': 'Inspizieren', + 'render.failedAbdicated': 'Das Rendern ist in {slot} fehlgeschlagen. Die Standard-Benutzeroberfläche wurde wiederhergestellt:', + 'render.failedHeld': 'Das Rendern ist in {slot} fehlgeschlagen:', + 'a11y.defining': 'Definieren des Plugins', + 'a11y.failed': 'Definition fehlgeschlagen', + 'a11y.stopped': 'Definition unterbrochen', + 'body.source': 'Plugin-Quelle', + 'body.hostCode': 'Gastgeber', + 'body.clientCode': 'Kunde', + 'body.output': 'Ergebnis', + 'body.copy': 'Kopieren', + 'body.copied': 'Kopiert', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'row.defineTitle': 'Зарегистрировать плагин Cordis', + 'a11y.preparing': 'Подготовка вызова инструмента Cordis', + 'row.runTitle': 'Запустите плагин Cordis', + 'row.updateTitle': 'Обновите плагин Cordis', + 'row.stopTitle': 'Остановить плагин Cordis', + 'row.removeTitle': 'Удалить плагин Cordis', + 'purpose.missing': '(цель не указана)', + 'status.idle': 'Готово', + 'status.awaitingApproval': 'Ожидает одобрения', + 'status.failed': 'Запустить не удалось', + 'status.clientPending': 'Клиент готов к активации', + 'status.running': 'Бег', + 'status.removed': 'Удален', + 'status.superseded': 'Доступна новая версия', + 'run.removed': 'Этот пакет больше не существует', + 'run.superseded': 'Более новая карта запуска доступна ниже.', + 'panel.hint': 'Запускайте элементы управления в реальном времени на панели Cordis над настройками.', + 'panel.plugins.aria': 'Плагины Cordis', + 'panel.approvals.aria': 'Допуски Cordis', + 'panel.trigger': 'Плагин Cordis', + 'panel.runningCount': '{count} работает', + 'panel.title': 'Плагины Cordis', + 'panel.empty': 'Плагины еще не определены', + 'panel.loading': 'Чтение…', + 'panel.readFailed': 'Не удалось прочитать список плагинов: {message}.', + 'panel.group.current': 'Эта сессия', + 'panel.group.others': 'Другие сессии', + 'panel.version': 'Версия', + 'panel.current': 'Текущий: {packageId}', + 'panel.next': 'Далее: {packageId}', + 'action.approve': 'Разрешить', + 'action.approveOnce': 'Разрешить только эту версию', + 'action.approvePlugin': 'Разрешить будущие версии этого плагина', + 'action.decline': 'Снижение', + 'action.run': 'Беги', + 'action.stop': 'Стоп', + 'action.remove': 'Удалить', + 'action.retry': 'Повторить', + 'action.rollback': 'Откат назад', + 'action.inspect': 'Осмотреть', + 'render.failedAbdicated': 'Не удалось выполнить рендеринг в {slot}; пользовательский интерфейс по умолчанию был восстановлен:', + 'render.failedHeld': 'Не удалось выполнить рендеринг в {slot}:', + 'a11y.defining': 'Определение плагина', + 'a11y.failed': 'Определение не выполнено', + 'a11y.stopped': 'Определение прервано', + 'body.source': 'Источник плагина', + 'body.hostCode': 'Хост', + 'body.clientCode': 'Клиент', + 'body.output': 'Результат', + 'body.copy': 'Копировать', + 'body.copied': 'Скопировано', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'row.defineTitle': 'Registre o plug-in Cordis', + 'a11y.preparing': 'Preparando uma chamada de ferramenta Cordis', + 'row.runTitle': 'Execute o plug-in Cordis', + 'row.updateTitle': 'Atualizar plug-in Cordis', + 'row.stopTitle': 'Parar o plug-in Cordis', + 'row.removeTitle': 'Remover plug-in Cordis', + 'purpose.missing': '(sem propósito dado)', + 'status.idle': 'Pronto', + 'status.awaitingApproval': 'Aguardando aprovação', + 'status.failed': 'Falha na execução', + 'status.clientPending': 'Cliente pronto para ativar', + 'status.running': 'Correndo', + 'status.removed': 'Removido', + 'status.superseded': 'Execução mais recente disponível', + 'run.removed': 'Este pacote não existe mais', + 'run.superseded': 'Um cartão de corrida mais recente está disponível abaixo', + 'panel.hint': 'Execute os controles ao vivo no painel Cordis acima de Configurações', + 'panel.plugins.aria': 'Cordis plug-ins', + 'panel.approvals.aria': 'Cordis aprovações', + 'panel.trigger': 'Cordis Plug-in', + 'panel.runningCount': '{count} em execução', + 'panel.title': 'Cordis plug-ins', + 'panel.empty': 'Nenhum plug-in definido ainda', + 'panel.loading': 'Lendo…', + 'panel.readFailed': 'Falha na leitura do inventário do plug-in: {message}', + 'panel.group.current': 'Esta sessão', + 'panel.group.others': 'Outras sessões', + 'panel.version': 'Versão', + 'panel.current': 'Atual: {packageId}', + 'panel.next': 'Próximo: {packageId}', + 'action.approve': 'Permitir', + 'action.approveOnce': 'Permitir apenas esta versão', + 'action.approvePlugin': 'Permitir versões futuras deste plugin', + 'action.decline': 'Recusar', + 'action.run': 'Corre', + 'action.stop': 'Pare', + 'action.remove': 'Remover', + 'action.retry': 'Tentar novamente', + 'action.rollback': 'Reverter', + 'action.inspect': 'Inspecionar', + 'render.failedAbdicated': 'A renderização falhou em {slot}; a IU padrão foi restaurada:', + 'render.failedHeld': 'Falha na renderização em {slot}:', + 'a11y.defining': 'Definindo o plug-in', + 'a11y.failed': 'Falha na definição', + 'a11y.stopped': 'Definição interrompida', + 'body.source': 'Fonte do plug-in', + 'body.hostCode': 'Anfitrião', + 'body.clientCode': 'Cliente', + 'body.output': 'Resultado', + 'body.copy': 'Copiar', + 'body.copied': 'Copiado', +} satisfies Record diff --git a/packages/feedback/command-feedback/locale/de.json b/packages/feedback/command-feedback/locale/de.json new file mode 100644 index 0000000000..56e3131347 --- /dev/null +++ b/packages/feedback/command-feedback/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sitzungs-Feedback-Befehl", + "description": "Zeichnen Sie die Bewertung der Sitzung durch den Benutzer über Eingaben wie /feedback auf." + } +} diff --git a/packages/feedback/command-feedback/locale/es.json b/packages/feedback/command-feedback/locale/es.json new file mode 100644 index 0000000000..4f3c0ae32e --- /dev/null +++ b/packages/feedback/command-feedback/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "comando de retroalimentación de sesión", + "description": "Registre la evaluación del usuario de la sesión a través de entradas como /feedback." + } +} diff --git a/packages/feedback/command-feedback/locale/fr.json b/packages/feedback/command-feedback/locale/fr.json new file mode 100644 index 0000000000..c43c76ebab --- /dev/null +++ b/packages/feedback/command-feedback/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "commande de retour de session", + "description": "Enregistrez l'évaluation de la session par l'utilisateur via des entrées telles que /feedback." + } +} diff --git a/packages/feedback/command-feedback/locale/pt.json b/packages/feedback/command-feedback/locale/pt.json new file mode 100644 index 0000000000..3216c7b1be --- /dev/null +++ b/packages/feedback/command-feedback/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "comando de feedback da sessão", + "description": "Registre a avaliação do usuário sobre a sessão por meio de entradas como /feedback." + } +} diff --git a/packages/feedback/command-feedback/locale/ru.json b/packages/feedback/command-feedback/locale/ru.json new file mode 100644 index 0000000000..c8159c20d5 --- /dev/null +++ b/packages/feedback/command-feedback/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "команда обратной связи сеанса", + "description": "Запишите оценку сеанса пользователем с помощью таких входов, как /feedback." + } +} diff --git a/packages/feedback/message-feedback/locale/de.json b/packages/feedback/message-feedback/locale/de.json new file mode 100644 index 0000000000..2e3b04a90c --- /dev/null +++ b/packages/feedback/message-feedback/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Aufzeichnung der Nachrichtenrückmeldung", + "description": "Erfassen Sie die Vorlieben und Abneigungen der Benutzer sowie zusätzliche Kommentare zu den Antworten des Assistenten." + } +} diff --git a/packages/feedback/message-feedback/locale/es.json b/packages/feedback/message-feedback/locale/es.json new file mode 100644 index 0000000000..cd61f04495 --- /dev/null +++ b/packages/feedback/message-feedback/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Registro de comentarios de mensajes", + "description": "Registre los gustos, disgustos y comentarios adicionales de los usuarios sobre las respuestas del asistente." + } +} diff --git a/packages/feedback/message-feedback/locale/fr.json b/packages/feedback/message-feedback/locale/fr.json new file mode 100644 index 0000000000..0ce2ce76dc --- /dev/null +++ b/packages/feedback/message-feedback/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Enregistrement des commentaires sur les messages", + "description": "Enregistrez les goûts, les aversions et les commentaires supplémentaires des utilisateurs sur les réponses de l'assistant." + } +} diff --git a/packages/feedback/message-feedback/locale/pt.json b/packages/feedback/message-feedback/locale/pt.json new file mode 100644 index 0000000000..c3ce39a0cb --- /dev/null +++ b/packages/feedback/message-feedback/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Registro de feedback de mensagem", + "description": "Registre o que os usuários gostam, não gostam e comentários adicionais nas respostas do assistente." + } +} diff --git a/packages/feedback/message-feedback/locale/ru.json b/packages/feedback/message-feedback/locale/ru.json new file mode 100644 index 0000000000..7a97459ff1 --- /dev/null +++ b/packages/feedback/message-feedback/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Запись обратной связи по сообщению", + "description": "Записывайте лайки и антипатии пользователей, а также дополнительные комментарии к ответам помощника." + } +} diff --git a/packages/fs/fs-local/locale/de.json b/packages/fs/fs-local/locale/de.json new file mode 100644 index 0000000000..fb24e42dd7 --- /dev/null +++ b/packages/fs/fs-local/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Lokales Dateisystem", + "description": "Greifen Sie über das lokale Dateisystem auf Dateien zu." + } +} diff --git a/packages/fs/fs-local/locale/es.json b/packages/fs/fs-local/locale/es.json new file mode 100644 index 0000000000..d520fe44ee --- /dev/null +++ b/packages/fs/fs-local/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sistema de archivos local", + "description": "Acceda a archivos a través del sistema de archivos local." + } +} diff --git a/packages/fs/fs-local/locale/fr.json b/packages/fs/fs-local/locale/fr.json new file mode 100644 index 0000000000..fbfdc8916c --- /dev/null +++ b/packages/fs/fs-local/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Système de fichiers local", + "description": "Accédez aux fichiers via le système de fichiers local." + } +} diff --git a/packages/fs/fs-local/locale/pt.json b/packages/fs/fs-local/locale/pt.json new file mode 100644 index 0000000000..882da690e2 --- /dev/null +++ b/packages/fs/fs-local/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sistema de arquivos local", + "description": "Acesse arquivos por meio do sistema de arquivos local." + } +} diff --git a/packages/fs/fs-local/locale/ru.json b/packages/fs/fs-local/locale/ru.json new file mode 100644 index 0000000000..8f68b233df --- /dev/null +++ b/packages/fs/fs-local/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Локальная файловая система", + "description": "Доступ к файлам через локальную файловую систему." + } +} diff --git a/packages/fs/fs-observation-policy/locale/de.json b/packages/fs/fs-observation-policy/locale/de.json new file mode 100644 index 0000000000..a9f325ec6b --- /dev/null +++ b/packages/fs/fs-observation-policy/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Dateibearbeitungsschutz", + "description": "Bitten Sie die KI, die Datei vor der Bearbeitung zu lesen und den Inhalt erneut zu bestätigen, wenn sich die Datei ändert." + } +} diff --git a/packages/fs/fs-observation-policy/locale/es.json b/packages/fs/fs-observation-policy/locale/es.json new file mode 100644 index 0000000000..6c027367e7 --- /dev/null +++ b/packages/fs/fs-observation-policy/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Protección de edición de archivos", + "description": "Pídale a la IA que lea el archivo antes de editarlo y reconfirme el contenido si el archivo cambia." + } +} diff --git a/packages/fs/fs-observation-policy/locale/fr.json b/packages/fs/fs-observation-policy/locale/fr.json new file mode 100644 index 0000000000..38b77212a8 --- /dev/null +++ b/packages/fs/fs-observation-policy/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Protection contre l'édition de fichiers", + "description": "Demandez à l'IA de lire le fichier avant de le modifier et de reconfirmer le contenu si le fichier change." + } +} diff --git a/packages/fs/fs-observation-policy/locale/pt.json b/packages/fs/fs-observation-policy/locale/pt.json new file mode 100644 index 0000000000..4e78d59d9e --- /dev/null +++ b/packages/fs/fs-observation-policy/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Proteção de edição de arquivos", + "description": "Peça à IA para ler o arquivo antes de editá-lo e reconfirme o conteúdo se o arquivo for alterado." + } +} diff --git a/packages/fs/fs-observation-policy/locale/ru.json b/packages/fs/fs-observation-policy/locale/ru.json new file mode 100644 index 0000000000..5045a24b1e --- /dev/null +++ b/packages/fs/fs-observation-policy/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Защита от редактирования файлов", + "description": "Попросите ИИ прочитать файл перед редактированием и повторно подтвердите содержимое, если файл изменится." + } +} diff --git a/packages/fs/fs-sandbox/locale/de.json b/packages/fs/fs-sandbox/locale/de.json new file mode 100644 index 0000000000..5aebfb9f0c --- /dev/null +++ b/packages/fs/fs-sandbox/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Datei-Sandbox-Zugriff", + "description": "Beschränken Sie den Umfang des Schreibens und Bearbeitens von Dateien entsprechend dem aktuellen Berechtigungsmodus." + } +} diff --git a/packages/fs/fs-sandbox/locale/es.json b/packages/fs/fs-sandbox/locale/es.json new file mode 100644 index 0000000000..2e022a9ab2 --- /dev/null +++ b/packages/fs/fs-sandbox/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Acceso a la zona de pruebas de archivos", + "description": "Limite el alcance de escritura y edición de archivos de acuerdo con el modo de permiso actual." + } +} diff --git a/packages/fs/fs-sandbox/locale/fr.json b/packages/fs/fs-sandbox/locale/fr.json new file mode 100644 index 0000000000..9f7db24041 --- /dev/null +++ b/packages/fs/fs-sandbox/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Accès au bac à sable de fichiers", + "description": "Limitez la portée de l’écriture et de la modification des fichiers en fonction du mode d’autorisation actuel." + } +} diff --git a/packages/fs/fs-sandbox/locale/pt.json b/packages/fs/fs-sandbox/locale/pt.json new file mode 100644 index 0000000000..a4db296ced --- /dev/null +++ b/packages/fs/fs-sandbox/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Acesso à sandbox de arquivos", + "description": "Limite o escopo de gravação e edição de arquivos de acordo com o modo de permissão atual." + } +} diff --git a/packages/fs/fs-sandbox/locale/ru.json b/packages/fs/fs-sandbox/locale/ru.json new file mode 100644 index 0000000000..be5a530ea6 --- /dev/null +++ b/packages/fs/fs-sandbox/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Доступ к файловой песочнице", + "description": "Ограничьте область записи и редактирования файлов в соответствии с текущим режимом разрешений." + } +} diff --git a/packages/fs/tool-fs-search/locale/de.json b/packages/fs/tool-fs-search/locale/de.json new file mode 100644 index 0000000000..19944f4f1c --- /dev/null +++ b/packages/fs/tool-fs-search/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Dateisuchtool", + "description": "Lassen Sie die KI lokale Dateien nach Dateinamen oder Textinhalt durchsuchen." + } +} diff --git a/packages/fs/tool-fs-search/locale/es.json b/packages/fs/tool-fs-search/locale/es.json new file mode 100644 index 0000000000..172602e390 --- /dev/null +++ b/packages/fs/tool-fs-search/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "herramienta de búsqueda de archivos", + "description": "Deje que AI busque archivos locales por nombre de archivo o contenido de texto." + } +} diff --git a/packages/fs/tool-fs-search/locale/fr.json b/packages/fs/tool-fs-search/locale/fr.json new file mode 100644 index 0000000000..a58b771e38 --- /dev/null +++ b/packages/fs/tool-fs-search/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outil de recherche de fichiers", + "description": "Laissez l'IA rechercher les fichiers locaux par nom de fichier ou par contenu textuel." + } +} diff --git a/packages/fs/tool-fs-search/locale/pt.json b/packages/fs/tool-fs-search/locale/pt.json new file mode 100644 index 0000000000..168b26c34d --- /dev/null +++ b/packages/fs/tool-fs-search/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramenta de pesquisa de arquivos", + "description": "Deixe a IA pesquisar arquivos locais por nome de arquivo ou conteúdo de texto." + } +} diff --git a/packages/fs/tool-fs-search/locale/ru.json b/packages/fs/tool-fs-search/locale/ru.json new file mode 100644 index 0000000000..d3491b1152 --- /dev/null +++ b/packages/fs/tool-fs-search/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Инструмент поиска файлов", + "description": "Позвольте ИИ искать локальные файлы по имени файла или текстовому содержимому." + } +} diff --git a/packages/fs/tool-fs/locale/de.json b/packages/fs/tool-fs/locale/de.json new file mode 100644 index 0000000000..8f9a48b1c7 --- /dev/null +++ b/packages/fs/tool-fs/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Tools zum Lesen und Schreiben von Dateien", + "description": "Lassen Sie die KI Arbeitsdateien lesen, erstellen und bearbeiten." + } +} diff --git a/packages/fs/tool-fs/locale/es.json b/packages/fs/tool-fs/locale/es.json new file mode 100644 index 0000000000..cf5397d400 --- /dev/null +++ b/packages/fs/tool-fs/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramientas de lectura y escritura de archivos.", + "description": "Deje que AI lea, cree y edite archivos de trabajo." + } +} diff --git a/packages/fs/tool-fs/locale/fr.json b/packages/fs/tool-fs/locale/fr.json new file mode 100644 index 0000000000..f8916300fe --- /dev/null +++ b/packages/fs/tool-fs/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outils de lecture et d'écriture de fichiers", + "description": "Laissez l'IA lire, créer et modifier des fichiers de travail." + } +} diff --git a/packages/fs/tool-fs/locale/pt.json b/packages/fs/tool-fs/locale/pt.json new file mode 100644 index 0000000000..994745ae43 --- /dev/null +++ b/packages/fs/tool-fs/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramentas de leitura e gravação de arquivos", + "description": "Deixe a IA ler, criar e editar arquivos de trabalho." + } +} diff --git a/packages/fs/tool-fs/locale/ru.json b/packages/fs/tool-fs/locale/ru.json new file mode 100644 index 0000000000..374ca3e81b --- /dev/null +++ b/packages/fs/tool-fs/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Инструменты чтения и записи файлов", + "description": "Позвольте ИИ читать, создавать и редактировать рабочие файлы." + } +} diff --git a/packages/fs/tool-str-replace-editor/locale/de.json b/packages/fs/tool-str-replace-editor/locale/de.json new file mode 100644 index 0000000000..b00fcd7870 --- /dev/null +++ b/packages/fs/tool-str-replace-editor/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Texteditor-Tools", + "description": "Anzeigen, Erstellen, Ersetzen und Einfügen von Text über den Dateisystemdienst." + } +} diff --git a/packages/fs/tool-str-replace-editor/locale/es.json b/packages/fs/tool-str-replace-editor/locale/es.json new file mode 100644 index 0000000000..3d33fbe578 --- /dev/null +++ b/packages/fs/tool-str-replace-editor/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramientas de edición de texto", + "description": "Vea, cree, reemplace e inserte texto a través del servicio del sistema de archivos." + } +} diff --git a/packages/fs/tool-str-replace-editor/locale/fr.json b/packages/fs/tool-str-replace-editor/locale/fr.json new file mode 100644 index 0000000000..d460c7ace0 --- /dev/null +++ b/packages/fs/tool-str-replace-editor/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outils d'édition de texte", + "description": "Affichez, créez, remplacez et insérez du texte via le service de système de fichiers." + } +} diff --git a/packages/fs/tool-str-replace-editor/locale/pt.json b/packages/fs/tool-str-replace-editor/locale/pt.json new file mode 100644 index 0000000000..fc7d558f0b --- /dev/null +++ b/packages/fs/tool-str-replace-editor/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramentas de edição de texto", + "description": "Visualize, crie, substitua e insira texto por meio do serviço do sistema de arquivos." + } +} diff --git a/packages/fs/tool-str-replace-editor/locale/ru.json b/packages/fs/tool-str-replace-editor/locale/ru.json new file mode 100644 index 0000000000..fae4e3449c --- /dev/null +++ b/packages/fs/tool-str-replace-editor/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Инструменты текстового редактора", + "description": "Просмотр, создание, замена и вставка текста через службу файловой системы." + } +} diff --git a/packages/goal/command-goal/locale/de.json b/packages/goal/command-goal/locale/de.json new file mode 100644 index 0000000000..9e45931078 --- /dev/null +++ b/packages/goal/command-goal/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Zielverwaltungsbefehl", + "description": "Legen Sie aktuelle Sitzungsziele über Benutzerbefehle fest und verwalten Sie sie." + } +} diff --git a/packages/goal/command-goal/locale/es.json b/packages/goal/command-goal/locale/es.json new file mode 100644 index 0000000000..2a7d673744 --- /dev/null +++ b/packages/goal/command-goal/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "comando de gestión de objetivos", + "description": "Establezca y administre los objetivos de la sesión actual mediante comandos de usuario." + } +} diff --git a/packages/goal/command-goal/locale/fr.json b/packages/goal/command-goal/locale/fr.json new file mode 100644 index 0000000000..4750de6bce --- /dev/null +++ b/packages/goal/command-goal/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "commande de gestion de cible", + "description": "Définissez et gérez les objectifs de la session en cours via les commandes utilisateur." + } +} diff --git a/packages/goal/command-goal/locale/pt.json b/packages/goal/command-goal/locale/pt.json new file mode 100644 index 0000000000..403a46ddd7 --- /dev/null +++ b/packages/goal/command-goal/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "comando de gerenciamento de alvo", + "description": "Defina e gerencie os alvos da sessão atual por meio de comandos do usuário." + } +} diff --git a/packages/goal/command-goal/locale/ru.json b/packages/goal/command-goal/locale/ru.json new file mode 100644 index 0000000000..d439097ae6 --- /dev/null +++ b/packages/goal/command-goal/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "команда управления целью", + "description": "Устанавливайте текущие цели сеанса и управляйте ими с помощью пользовательских команд." + } +} diff --git a/packages/goal/goal-round-driver/locale/de.json b/packages/goal/goal-round-driver/locale/de.json new file mode 100644 index 0000000000..8a61f022c1 --- /dev/null +++ b/packages/goal/goal-round-driver/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Automatische Fortsetzung des Ziels", + "description": "Lassen Sie die KI die Ziele der aktuellen Sitzung weiter vorantreiben, sofern die Bedingungen und Credits dies zulassen." + } +} diff --git a/packages/goal/goal-round-driver/locale/es.json b/packages/goal/goal-round-driver/locale/es.json new file mode 100644 index 0000000000..b5910b1816 --- /dev/null +++ b/packages/goal/goal-round-driver/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Continuación automática del objetivo", + "description": "Deje que la IA continúe avanzando hacia los objetivos de la sesión actual según lo permitan las condiciones y los créditos." + } +} diff --git a/packages/goal/goal-round-driver/locale/fr.json b/packages/goal/goal-round-driver/locale/fr.json new file mode 100644 index 0000000000..110ca10509 --- /dev/null +++ b/packages/goal/goal-round-driver/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Poursuite automatique de la cible", + "description": "Laissez l’IA continuer à faire avancer les objectifs de la session en cours dans la mesure où les conditions et les crédits le permettent." + } +} diff --git a/packages/goal/goal-round-driver/locale/pt.json b/packages/goal/goal-round-driver/locale/pt.json new file mode 100644 index 0000000000..74c5918bff --- /dev/null +++ b/packages/goal/goal-round-driver/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Continuação automática desejada", + "description": "Deixe a IA continuar a avançar nos objetivos da sessão atual conforme as condições e os créditos permitirem." + } +} diff --git a/packages/goal/goal-round-driver/locale/ru.json b/packages/goal/goal-round-driver/locale/ru.json new file mode 100644 index 0000000000..0ced61fc0d --- /dev/null +++ b/packages/goal/goal-round-driver/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Целевое автопродолжение", + "description": "Пусть ИИ продолжит продвигать цели текущей сессии, насколько позволяют условия и кредиты." + } +} diff --git a/packages/goal/goal/locale/de.json b/packages/goal/goal/locale/de.json new file mode 100644 index 0000000000..e9aaef5894 --- /dev/null +++ b/packages/goal/goal/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ziel", + "description": "Erfassen Sie Sitzungsziele und verwalten Sie den Status und Lebenszyklus der Ziele." + } +} diff --git a/packages/goal/goal/locale/es.json b/packages/goal/goal/locale/es.json new file mode 100644 index 0000000000..47f978884c --- /dev/null +++ b/packages/goal/goal/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "objetivo", + "description": "Registre los objetivos de la sesión y administre el estado y el ciclo de vida de los objetivos." + } +} diff --git a/packages/goal/goal/locale/fr.json b/packages/goal/goal/locale/fr.json new file mode 100644 index 0000000000..0ed5e900cc --- /dev/null +++ b/packages/goal/goal/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "objectif", + "description": "Enregistrez les cibles de session et gérez l’état et le cycle de vie des cibles." + } +} diff --git a/packages/goal/goal/locale/pt.json b/packages/goal/goal/locale/pt.json new file mode 100644 index 0000000000..af4f9de7fb --- /dev/null +++ b/packages/goal/goal/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "objetivo", + "description": "Registre os alvos da sessão e gerencie o status e o ciclo de vida dos alvos." + } +} diff --git a/packages/goal/goal/locale/ru.json b/packages/goal/goal/locale/ru.json new file mode 100644 index 0000000000..6163b966d2 --- /dev/null +++ b/packages/goal/goal/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "цель", + "description": "Записывайте цели сеанса и управляйте статусом и жизненным циклом целей." + } +} diff --git a/packages/goal/tool-goal/locale/de.json b/packages/goal/tool-goal/locale/de.json new file mode 100644 index 0000000000..385de824d7 --- /dev/null +++ b/packages/goal/tool-goal/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Zielmanagement-Tool", + "description": "Lassen Sie die KI aktuelle Sitzungsziele festlegen, anzeigen und aktualisieren." + } +} diff --git a/packages/goal/tool-goal/locale/es.json b/packages/goal/tool-goal/locale/es.json new file mode 100644 index 0000000000..7af26917ed --- /dev/null +++ b/packages/goal/tool-goal/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramienta de gestión de objetivos", + "description": "Deje que la IA establezca, vea y actualice los objetivos de la sesión actual." + } +} diff --git a/packages/goal/tool-goal/locale/fr.json b/packages/goal/tool-goal/locale/fr.json new file mode 100644 index 0000000000..39b641d5e1 --- /dev/null +++ b/packages/goal/tool-goal/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outil de gestion des objectifs", + "description": "Laissez l'IA définir, afficher et mettre à jour les objectifs de la session en cours." + } +} diff --git a/packages/goal/tool-goal/locale/pt.json b/packages/goal/tool-goal/locale/pt.json new file mode 100644 index 0000000000..ca7bf68e97 --- /dev/null +++ b/packages/goal/tool-goal/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramenta de gerenciamento de metas", + "description": "Deixe a IA definir, visualizar e atualizar as metas da sessão atual." + } +} diff --git a/packages/goal/tool-goal/locale/ru.json b/packages/goal/tool-goal/locale/ru.json new file mode 100644 index 0000000000..47c3bd043c --- /dev/null +++ b/packages/goal/tool-goal/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Инструмент управления целями", + "description": "Позвольте ИИ устанавливать, просматривать и обновлять текущие цели сеанса." + } +} diff --git a/packages/guard/repeat-tool-reminder/locale/de.json b/packages/guard/repeat-tool-reminder/locale/de.json new file mode 100644 index 0000000000..8af5f5cf78 --- /dev/null +++ b/packages/guard/repeat-tool-reminder/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Erinnerung an Werkzeugaufruf wiederholen", + "description": "Fordern Sie die KI auf, ihren Ansatz anzupassen, wenn sie wiederholt dieselben Toolaufrufe ausführt." + } +} diff --git a/packages/guard/repeat-tool-reminder/locale/es.json b/packages/guard/repeat-tool-reminder/locale/es.json new file mode 100644 index 0000000000..7e70a7adf3 --- /dev/null +++ b/packages/guard/repeat-tool-reminder/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Repetir recordatorio de llamada de herramienta", + "description": "Solicite a la IA que ajuste su enfoque cuando realice repetidamente las mismas llamadas a herramientas." + } +} diff --git a/packages/guard/repeat-tool-reminder/locale/fr.json b/packages/guard/repeat-tool-reminder/locale/fr.json new file mode 100644 index 0000000000..58e740dca3 --- /dev/null +++ b/packages/guard/repeat-tool-reminder/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Répéter le rappel d'appel d'outil", + "description": "Inviter l’IA à ajuster son approche lorsqu’elle exécute à plusieurs reprises les mêmes appels d’outil." + } +} diff --git a/packages/guard/repeat-tool-reminder/locale/pt.json b/packages/guard/repeat-tool-reminder/locale/pt.json new file mode 100644 index 0000000000..ecbb46c841 --- /dev/null +++ b/packages/guard/repeat-tool-reminder/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Repetir lembrete de chamada de ferramenta", + "description": "Solicite à IA que ajuste sua abordagem quando executar repetidamente as mesmas chamadas de ferramenta." + } +} diff --git a/packages/guard/repeat-tool-reminder/locale/ru.json b/packages/guard/repeat-tool-reminder/locale/ru.json new file mode 100644 index 0000000000..0f3044f953 --- /dev/null +++ b/packages/guard/repeat-tool-reminder/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Напоминание о повторном вызове инструмента", + "description": "Попросите ИИ скорректировать свой подход, когда он неоднократно выполняет одни и те же вызовы инструментов." + } +} diff --git a/packages/guard/timeout-policy/locale/de.json b/packages/guard/timeout-policy/locale/de.json new file mode 100644 index 0000000000..a908ff2cdd --- /dev/null +++ b/packages/guard/timeout-policy/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Timeout-Kontrolle für Tool-Aufrufe", + "description": "Senden Sie ein Abbruchsignal entsprechend dem Zeitlimit jedes Tools und geben Sie das Timeout-Ergebnis zurück." + } +} diff --git a/packages/guard/timeout-policy/locale/es.json b/packages/guard/timeout-policy/locale/es.json new file mode 100644 index 0000000000..f298169c16 --- /dev/null +++ b/packages/guard/timeout-policy/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Control de tiempo de espera de llamada de herramienta", + "description": "Envía una señal de cancelación de acuerdo con el límite de tiempo de cada herramienta y devuelve el resultado del tiempo de espera." + } +} diff --git a/packages/guard/timeout-policy/locale/fr.json b/packages/guard/timeout-policy/locale/fr.json new file mode 100644 index 0000000000..969a8e8790 --- /dev/null +++ b/packages/guard/timeout-policy/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Contrôle du délai d'expiration des appels d'outils", + "description": "Envoyez un signal d'annulation en fonction de la limite de temps de chaque outil et renvoyez le résultat du délai d'attente." + } +} diff --git a/packages/guard/timeout-policy/locale/pt.json b/packages/guard/timeout-policy/locale/pt.json new file mode 100644 index 0000000000..317eb8d2db --- /dev/null +++ b/packages/guard/timeout-policy/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Controle de tempo limite de chamada de ferramenta", + "description": "Envia um sinal de cancelamento de acordo com o limite de tempo de cada ferramenta e retorna o resultado do timeout." + } +} diff --git a/packages/guard/timeout-policy/locale/ru.json b/packages/guard/timeout-policy/locale/ru.json new file mode 100644 index 0000000000..e243c14058 --- /dev/null +++ b/packages/guard/timeout-policy/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Управление тайм-аутом вызова инструмента", + "description": "Отправьте сигнал отмены в соответствии с лимитом времени каждого инструмента и верните результат тайм-аута." + } +} diff --git a/packages/host/directory-picker-auto/locale/de.json b/packages/host/directory-picker-auto/locale/de.json new file mode 100644 index 0000000000..ae3dfd19a5 --- /dev/null +++ b/packages/host/directory-picker-auto/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Anpassung der Verzeichnisauswahlmethode", + "description": "Wählen Sie je nach laufender Umgebung das Systemverzeichnis-Dialogfeld oder die In-App-Verzeichnissuche aus." + } +} diff --git a/packages/host/directory-picker-auto/locale/es.json b/packages/host/directory-picker-auto/locale/es.json new file mode 100644 index 0000000000..1f2deafe0b --- /dev/null +++ b/packages/host/directory-picker-auto/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Adaptación del método de selección de directorio.", + "description": "Seleccione el cuadro de diálogo del directorio del sistema o la exploración del directorio en la aplicación según el entorno de ejecución." + } +} diff --git a/packages/host/directory-picker-auto/locale/fr.json b/packages/host/directory-picker-auto/locale/fr.json new file mode 100644 index 0000000000..05831437d0 --- /dev/null +++ b/packages/host/directory-picker-auto/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Adaptation de la méthode de sélection d'annuaire", + "description": "Sélectionnez la boîte de dialogue du répertoire système ou la navigation dans le répertoire dans l'application en fonction de l'environnement d'exécution." + } +} diff --git a/packages/host/directory-picker-auto/locale/pt.json b/packages/host/directory-picker-auto/locale/pt.json new file mode 100644 index 0000000000..f6657cffea --- /dev/null +++ b/packages/host/directory-picker-auto/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Adaptação do método de seleção de diretório", + "description": "Selecione a caixa de diálogo do diretório do sistema ou a navegação no diretório do aplicativo de acordo com o ambiente em execução." + } +} diff --git a/packages/host/directory-picker-auto/locale/ru.json b/packages/host/directory-picker-auto/locale/ru.json new file mode 100644 index 0000000000..c159b4e5fb --- /dev/null +++ b/packages/host/directory-picker-auto/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Адаптация метода выбора каталога", + "description": "Выберите диалоговое окно системного каталога или просмотр каталога в приложении в соответствии с запущенной средой." + } +} diff --git a/packages/host/directory-picker-browse/locale/de.json b/packages/host/directory-picker-browse/locale/de.json new file mode 100644 index 0000000000..2cc8bd3853 --- /dev/null +++ b/packages/host/directory-picker-browse/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "In-App-Verzeichnis-Browsing-Dienst", + "description": "Bietet die Möglichkeit, lokale Verzeichnisse aufzulisten und zu erstellen, um Verzeichnisse innerhalb der Anwendung auszuwählen." + } +} diff --git a/packages/host/directory-picker-browse/locale/es.json b/packages/host/directory-picker-browse/locale/es.json new file mode 100644 index 0000000000..b062f5d7d5 --- /dev/null +++ b/packages/host/directory-picker-browse/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Servicio de exploración de directorios en la aplicación", + "description": "Proporciona la capacidad de enumerar y crear directorios locales para seleccionar directorios dentro de la aplicación." + } +} diff --git a/packages/host/directory-picker-browse/locale/fr.json b/packages/host/directory-picker-browse/locale/fr.json new file mode 100644 index 0000000000..357d96f8bc --- /dev/null +++ b/packages/host/directory-picker-browse/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Service de navigation dans l'annuaire intégré à l'application", + "description": "Offre la possibilité de répertorier et de créer des répertoires locaux pour sélectionner des répertoires dans l'application." + } +} diff --git a/packages/host/directory-picker-browse/locale/pt.json b/packages/host/directory-picker-browse/locale/pt.json new file mode 100644 index 0000000000..aa0b98cdd0 --- /dev/null +++ b/packages/host/directory-picker-browse/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Serviço de navegação de diretório no aplicativo", + "description": "Fornece a capacidade de listar e criar diretórios locais para selecionar diretórios no aplicativo." + } +} diff --git a/packages/host/directory-picker-browse/locale/ru.json b/packages/host/directory-picker-browse/locale/ru.json new file mode 100644 index 0000000000..43425d8b4f --- /dev/null +++ b/packages/host/directory-picker-browse/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Служба просмотра каталогов в приложении", + "description": "Предоставляет возможность составлять список и создавать локальные каталоги для выбора каталогов внутри приложения." + } +} diff --git a/packages/host/directory-picker-native/locale/de.json b/packages/host/directory-picker-native/locale/de.json new file mode 100644 index 0000000000..e02abd49d6 --- /dev/null +++ b/packages/host/directory-picker-native/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Systemverzeichnis-Auswahldienst", + "description": "Ruft den Verzeichnisauswahldialog des Betriebssystems auf." + } +} diff --git a/packages/host/directory-picker-native/locale/es.json b/packages/host/directory-picker-native/locale/es.json new file mode 100644 index 0000000000..cee8ec774e --- /dev/null +++ b/packages/host/directory-picker-native/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Servicio de selección de directorio del sistema.", + "description": "Llama al cuadro de diálogo de selección de directorio del sistema operativo." + } +} diff --git a/packages/host/directory-picker-native/locale/fr.json b/packages/host/directory-picker-native/locale/fr.json new file mode 100644 index 0000000000..b9e3908cb1 --- /dev/null +++ b/packages/host/directory-picker-native/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Service de sélection d'annuaire système", + "description": "Appelle la boîte de dialogue de sélection de répertoire du système d'exploitation." + } +} diff --git a/packages/host/directory-picker-native/locale/pt.json b/packages/host/directory-picker-native/locale/pt.json new file mode 100644 index 0000000000..64ef44e15f --- /dev/null +++ b/packages/host/directory-picker-native/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Serviço de seleção de diretório do sistema", + "description": "Chama a caixa de diálogo de seleção de diretório do sistema operacional." + } +} diff --git a/packages/host/directory-picker-native/locale/ru.json b/packages/host/directory-picker-native/locale/ru.json new file mode 100644 index 0000000000..267c73b0c9 --- /dev/null +++ b/packages/host/directory-picker-native/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Служба выбора системного каталога", + "description": "Вызывает диалог выбора каталога операционной системы." + } +} diff --git a/packages/host/frontend-static/locale/de.json b/packages/host/frontend-static/locale/de.json new file mode 100644 index 0000000000..1dee77b358 --- /dev/null +++ b/packages/host/frontend-static/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Statischer Frontend-Server", + "description": "Stellen Sie die Einstiegsseite und statische Dateien der Webanwendung bereit, lehnen Sie Pfade außerhalb ihres Verzeichnisses ab und geben Sie 404 für fehlende Ressourcen zurück." + } +} diff --git a/packages/host/frontend-static/locale/es.json b/packages/host/frontend-static/locale/es.json new file mode 100644 index 0000000000..fda0cdd479 --- /dev/null +++ b/packages/host/frontend-static/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Servidor front-end estático", + "description": "Sirve la página de entrada de la aplicación web y los archivos estáticos, rechaza las rutas fuera de su directorio y devuelve 404 para los recursos faltantes." + } +} diff --git a/packages/host/frontend-static/locale/fr.json b/packages/host/frontend-static/locale/fr.json new file mode 100644 index 0000000000..c0a262127b --- /dev/null +++ b/packages/host/frontend-static/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Serveur frontal statique", + "description": "Servir la page d'entrée et les fichiers statiques de l'application Web, rejeter les chemins en dehors de leur répertoire et renvoyer 404 pour les ressources manquantes." + } +} diff --git a/packages/host/frontend-static/locale/pt.json b/packages/host/frontend-static/locale/pt.json new file mode 100644 index 0000000000..a8cb44bf2a --- /dev/null +++ b/packages/host/frontend-static/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Servidor front-end estático", + "description": "Sirva a página de entrada e os arquivos estáticos do aplicativo Web, rejeite caminhos fora de seu diretório e retorne 404 para recursos ausentes." + } +} diff --git a/packages/host/frontend-static/locale/ru.json b/packages/host/frontend-static/locale/ru.json new file mode 100644 index 0000000000..99ff3819c3 --- /dev/null +++ b/packages/host/frontend-static/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Статический интерфейсный сервер", + "description": "Обслуживать входную страницу веб-приложения и статические файлы, отклонять пути за пределами их каталога и возвращать 404 для отсутствующих ресурсов." + } +} diff --git a/packages/host/open-in-app/locale/de.json b/packages/host/open-in-app/locale/de.json new file mode 100644 index 0000000000..63505efe52 --- /dev/null +++ b/packages/host/open-in-app/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Externer Bewerbungseröffnungsservice", + "description": "Finden Sie verfügbare lokale Apps und öffnen Sie Dateien oder Arbeitsbereiche mit der ausgewählten App." + } +} diff --git a/packages/host/open-in-app/locale/es.json b/packages/host/open-in-app/locale/es.json new file mode 100644 index 0000000000..b54b610aed --- /dev/null +++ b/packages/host/open-in-app/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Servicio de apertura de aplicaciones externas", + "description": "Encuentre aplicaciones locales disponibles y abra archivos o espacios de trabajo con la aplicación seleccionada." + } +} diff --git a/packages/host/open-in-app/locale/fr.json b/packages/host/open-in-app/locale/fr.json new file mode 100644 index 0000000000..459b691c5a --- /dev/null +++ b/packages/host/open-in-app/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Service d'ouverture de candidature externe", + "description": "Recherchez les applications locales disponibles et ouvrez des fichiers ou des espaces de travail avec l'application sélectionnée." + } +} diff --git a/packages/host/open-in-app/locale/pt.json b/packages/host/open-in-app/locale/pt.json new file mode 100644 index 0000000000..da4cd30b4c --- /dev/null +++ b/packages/host/open-in-app/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Serviço de abertura de aplicativos externos", + "description": "Encontre aplicativos locais disponíveis e abra arquivos ou áreas de trabalho com o aplicativo selecionado." + } +} diff --git a/packages/host/open-in-app/locale/ru.json b/packages/host/open-in-app/locale/ru.json new file mode 100644 index 0000000000..6e8fb616ab --- /dev/null +++ b/packages/host/open-in-app/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Сервис открытия внешних приложений", + "description": "Найдите доступные локальные приложения и откройте файлы или рабочие области с помощью выбранного приложения." + } +} diff --git a/packages/host/plugin-inventory/locale/de.json b/packages/host/plugin-inventory/locale/de.json new file mode 100644 index 0000000000..924121cf97 --- /dev/null +++ b/packages/host/plugin-inventory/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Plugin-Manifestdienst", + "description": "Bietet eine schreibgeschützte Liste der aktuellen Plug-In-Einträge, des Aktivierungsstatus der Konfiguration und des Ausführungsstatus." + } +} diff --git a/packages/host/plugin-inventory/locale/es.json b/packages/host/plugin-inventory/locale/es.json new file mode 100644 index 0000000000..d2e1242d5f --- /dev/null +++ b/packages/host/plugin-inventory/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Servicio de manifiesto de complemento", + "description": "Proporciona una lista de solo lectura de las entradas de complementos actuales, el estado de habilitación de la configuración y el estado de ejecución." + } +} diff --git a/packages/host/plugin-inventory/locale/fr.json b/packages/host/plugin-inventory/locale/fr.json new file mode 100644 index 0000000000..cd465d83ec --- /dev/null +++ b/packages/host/plugin-inventory/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Service de manifeste de plugin", + "description": "Fournit une liste en lecture seule des entrées actuelles du plug-in, de l'état d'activation de la configuration et de l'état d'exécution." + } +} diff --git a/packages/host/plugin-inventory/locale/pt.json b/packages/host/plugin-inventory/locale/pt.json new file mode 100644 index 0000000000..648863e1fb --- /dev/null +++ b/packages/host/plugin-inventory/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Serviço de manifesto de plug-in", + "description": "Fornece uma listagem somente leitura das entradas atuais do plug-in, do status de ativação da configuração e do status de execução." + } +} diff --git a/packages/host/plugin-inventory/locale/ru.json b/packages/host/plugin-inventory/locale/ru.json new file mode 100644 index 0000000000..c95a42e6c7 --- /dev/null +++ b/packages/host/plugin-inventory/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Служба манифеста плагина", + "description": "Предоставляет доступный только для чтения список текущих записей подключаемого модуля, состояние включения конфигурации и состояние работы." + } +} diff --git a/packages/host/product-telemetry-otel/locale/de.json b/packages/host/product-telemetry-otel/locale/de.json new file mode 100644 index 0000000000..13ecfe05e3 --- /dev/null +++ b/packages/host/product-telemetry-otel/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Berichterstattung über Produktnutzungsvorfälle", + "description": "Melden Sie bestimmte Produktnutzungsereignisse über OpenTelemetry an den konfigurierten Dienst." + } +} diff --git a/packages/host/product-telemetry-otel/locale/es.json b/packages/host/product-telemetry-otel/locale/es.json new file mode 100644 index 0000000000..2692c3fd88 --- /dev/null +++ b/packages/host/product-telemetry-otel/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Informe de incidentes de uso del producto", + "description": "Informe eventos de uso de productos específicos al servicio configurado a través de OpenTelemetry." + } +} diff --git a/packages/host/product-telemetry-otel/locale/fr.json b/packages/host/product-telemetry-otel/locale/fr.json new file mode 100644 index 0000000000..a577ca4b03 --- /dev/null +++ b/packages/host/product-telemetry-otel/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Rapport d'incident d'utilisation du produit", + "description": "Signalez les événements d'utilisation du produit spécifiés au service configuré via OpenTelemetry." + } +} diff --git a/packages/host/product-telemetry-otel/locale/pt.json b/packages/host/product-telemetry-otel/locale/pt.json new file mode 100644 index 0000000000..5cc63f18c1 --- /dev/null +++ b/packages/host/product-telemetry-otel/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Relatório de incidentes de uso do produto", + "description": "Relate eventos de uso de produto especificados para o serviço configurado por meio do OpenTelemetry." + } +} diff --git a/packages/host/product-telemetry-otel/locale/ru.json b/packages/host/product-telemetry-otel/locale/ru.json new file mode 100644 index 0000000000..406e69f23b --- /dev/null +++ b/packages/host/product-telemetry-otel/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Отчеты об инцидентах, связанных с использованием продукта", + "description": "Сообщайте об указанных событиях использования продукта в настроенную службу через OpenTelemetry." + } +} diff --git a/packages/host/webserver/locale/de.json b/packages/host/webserver/locale/de.json new file mode 100644 index 0000000000..2c5dbbad37 --- /dev/null +++ b/packages/host/webserver/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Webserver", + "description": "Registrieren Sie das Webseiten- und Schnittstellenrouting, um den HTTP-Dienst bereitzustellen." + } +} diff --git a/packages/host/webserver/locale/es.json b/packages/host/webserver/locale/es.json new file mode 100644 index 0000000000..775571f636 --- /dev/null +++ b/packages/host/webserver/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "servidor web", + "description": "Registre el enrutamiento de la página web y la interfaz para brindar el servicio HTTP." + } +} diff --git a/packages/host/webserver/locale/fr.json b/packages/host/webserver/locale/fr.json new file mode 100644 index 0000000000..0a1b68d227 --- /dev/null +++ b/packages/host/webserver/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "serveur Web", + "description": "Enregistrez le routage de la page Web et de l'interface pour fournir le service HTTP." + } +} diff --git a/packages/host/webserver/locale/pt.json b/packages/host/webserver/locale/pt.json new file mode 100644 index 0000000000..1a2162e91f --- /dev/null +++ b/packages/host/webserver/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "servidor web", + "description": "Registre o roteamento de página da web e interface para fornecer o serviço HTTP." + } +} diff --git a/packages/host/webserver/locale/ru.json b/packages/host/webserver/locale/ru.json new file mode 100644 index 0000000000..572d70ae3a --- /dev/null +++ b/packages/host/webserver/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "веб-сервер", + "description": "Зарегистрируйте веб-страницу и маршрутизацию интерфейса для предоставления услуги HTTP." + } +} diff --git a/packages/interaction/commands/locale/de.json b/packages/interaction/commands/locale/de.json new file mode 100644 index 0000000000..cdafb0a39b --- /dev/null +++ b/packages/interaction/commands/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Befehle", + "description": "Registrieren und verwalten Sie die vom Plugin bereitgestellten Benutzerbefehle." + } +} diff --git a/packages/interaction/commands/locale/es.json b/packages/interaction/commands/locale/es.json new file mode 100644 index 0000000000..d195dd24b2 --- /dev/null +++ b/packages/interaction/commands/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "comandos", + "description": "Registre y administre los comandos de usuario proporcionados por el complemento." + } +} diff --git a/packages/interaction/commands/locale/fr.json b/packages/interaction/commands/locale/fr.json new file mode 100644 index 0000000000..bf0faa2ac5 --- /dev/null +++ b/packages/interaction/commands/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "commandes", + "description": "Enregistrez et gérez les commandes utilisateur fournies par le plugin." + } +} diff --git a/packages/interaction/commands/locale/pt.json b/packages/interaction/commands/locale/pt.json new file mode 100644 index 0000000000..87a7ffa059 --- /dev/null +++ b/packages/interaction/commands/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "comandos", + "description": "Registre e gerencie os comandos do usuário fornecidos pelo plugin." + } +} diff --git a/packages/interaction/commands/locale/ru.json b/packages/interaction/commands/locale/ru.json new file mode 100644 index 0000000000..1f3dc1b24f --- /dev/null +++ b/packages/interaction/commands/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "команды", + "description": "Регистрируйте и управляйте пользовательскими командами, предоставляемыми плагином." + } +} diff --git a/packages/interaction/permission-presets/locale/de.json b/packages/interaction/permission-presets/locale/de.json new file mode 100644 index 0000000000..1b2913d2b2 --- /dev/null +++ b/packages/interaction/permission-presets/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Berechtigungsmodusdienst", + "description": "Verwalten Sie die von Benutzern ausgewählten Berechtigungsmodi und vereinheitlichen Sie die entsprechenden Sandbox- und Genehmigungsstrategien." + } +} diff --git a/packages/interaction/permission-presets/locale/es.json b/packages/interaction/permission-presets/locale/es.json new file mode 100644 index 0000000000..cd0ab6b153 --- /dev/null +++ b/packages/interaction/permission-presets/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Servicio en modo permiso", + "description": "Administre los modos de permiso seleccionados por los usuarios y unifique el sandbox y las estrategias de aprobación correspondientes." + } +} diff --git a/packages/interaction/permission-presets/locale/fr.json b/packages/interaction/permission-presets/locale/fr.json new file mode 100644 index 0000000000..9d15468c49 --- /dev/null +++ b/packages/interaction/permission-presets/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Service en mode autorisation", + "description": "Gérez les modes d'autorisation sélectionnés par les utilisateurs et unifiez les stratégies de bac à sable et d'approbation correspondantes." + } +} diff --git a/packages/interaction/permission-presets/locale/pt.json b/packages/interaction/permission-presets/locale/pt.json new file mode 100644 index 0000000000..c6fbc4b9fd --- /dev/null +++ b/packages/interaction/permission-presets/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Serviço de modo de permissão", + "description": "Gerencie os modos de permissão selecionados pelos usuários e unifique as estratégias de sandbox e aprovação correspondentes." + } +} diff --git a/packages/interaction/permission-presets/locale/ru.json b/packages/interaction/permission-presets/locale/ru.json new file mode 100644 index 0000000000..fbbcfdacda --- /dev/null +++ b/packages/interaction/permission-presets/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Служба режима разрешений", + "description": "Управляйте режимами разрешений, выбранными пользователями, и унифицируйте соответствующие стратегии песочницы и утверждения." + } +} diff --git a/packages/interaction/tool-ask-user/locale/de.json b/packages/interaction/tool-ask-user/locale/de.json new file mode 100644 index 0000000000..7321254240 --- /dev/null +++ b/packages/interaction/tool-ask-user/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Tool zum Stellen von Benutzerfragen", + "description": "Lassen Sie die KI dem Benutzer Fragen stellen, wenn sie zusätzliche Informationen oder Auswahlmöglichkeiten benötigt." + } +} diff --git a/packages/interaction/tool-ask-user/locale/es.json b/packages/interaction/tool-ask-user/locale/es.json new file mode 100644 index 0000000000..352a9b8c5a --- /dev/null +++ b/packages/interaction/tool-ask-user/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramienta para hacer preguntas a los usuarios", + "description": "Deje que la IA haga preguntas al usuario cuando necesite información u opciones adicionales." + } +} diff --git a/packages/interaction/tool-ask-user/locale/fr.json b/packages/interaction/tool-ask-user/locale/fr.json new file mode 100644 index 0000000000..8b669ce1ff --- /dev/null +++ b/packages/interaction/tool-ask-user/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outil Poser des questions aux utilisateurs", + "description": "Laissez l'IA poser des questions à l'utilisateur lorsqu'elle a besoin d'informations ou de choix supplémentaires." + } +} diff --git a/packages/interaction/tool-ask-user/locale/pt.json b/packages/interaction/tool-ask-user/locale/pt.json new file mode 100644 index 0000000000..b7c28170d5 --- /dev/null +++ b/packages/interaction/tool-ask-user/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramenta para fazer perguntas aos usuários", + "description": "Deixe a IA fazer perguntas ao usuário quando precisar de informações ou escolhas adicionais." + } +} diff --git a/packages/interaction/tool-ask-user/locale/ru.json b/packages/interaction/tool-ask-user/locale/ru.json new file mode 100644 index 0000000000..90eabf1880 --- /dev/null +++ b/packages/interaction/tool-ask-user/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Инструмент «Задавать вопросы пользователям»", + "description": "Позвольте ИИ задавать пользователю вопросы, когда ему нужна дополнительная информация или выбор." + } +} diff --git a/packages/interaction/user-approval/locale/de.json b/packages/interaction/user-approval/locale/de.json new file mode 100644 index 0000000000..c5a331432f --- /dev/null +++ b/packages/interaction/user-approval/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Benutzergenehmigungsdienst", + "description": "Fordern Sie vom Benutzer eine Betriebsberechtigung an und geben Sie das Genehmigungsergebnis zurück." + } +} diff --git a/packages/interaction/user-approval/locale/es.json b/packages/interaction/user-approval/locale/es.json new file mode 100644 index 0000000000..0882a1b014 --- /dev/null +++ b/packages/interaction/user-approval/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Servicio de aprobación de usuarios", + "description": "Solicite autorización de operación al usuario y devuelva el resultado de la aprobación." + } +} diff --git a/packages/interaction/user-approval/locale/fr.json b/packages/interaction/user-approval/locale/fr.json new file mode 100644 index 0000000000..869a227c84 --- /dev/null +++ b/packages/interaction/user-approval/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Service d'approbation des utilisateurs", + "description": "Demander l'autorisation d'opération à l'utilisateur et renvoyer le résultat de l'approbation." + } +} diff --git a/packages/interaction/user-approval/locale/pt.json b/packages/interaction/user-approval/locale/pt.json new file mode 100644 index 0000000000..2220083dca --- /dev/null +++ b/packages/interaction/user-approval/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Serviço de aprovação de usuário", + "description": "Solicite autorização de operação ao usuário e retorne o resultado da aprovação." + } +} diff --git a/packages/interaction/user-approval/locale/ru.json b/packages/interaction/user-approval/locale/ru.json new file mode 100644 index 0000000000..68f7d51762 --- /dev/null +++ b/packages/interaction/user-approval/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Служба утверждения пользователей", + "description": "Запросить авторизацию операции у пользователя и вернуть результат утверждения." + } +} diff --git a/packages/interaction/user-questions/locale/de.json b/packages/interaction/user-questions/locale/de.json new file mode 100644 index 0000000000..2fbafa02dd --- /dev/null +++ b/packages/interaction/user-questions/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Benutzerfragendienst", + "description": "Lassen Sie die laufende KI dem Benutzer Fragen stellen und auf Antworten warten." + } +} diff --git a/packages/interaction/user-questions/locale/es.json b/packages/interaction/user-questions/locale/es.json new file mode 100644 index 0000000000..3b1e094a61 --- /dev/null +++ b/packages/interaction/user-questions/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Servicio de preguntas del usuario", + "description": "Deje que la IA en ejecución haga preguntas al usuario y espere respuestas." + } +} diff --git a/packages/interaction/user-questions/locale/fr.json b/packages/interaction/user-questions/locale/fr.json new file mode 100644 index 0000000000..d23764998f --- /dev/null +++ b/packages/interaction/user-questions/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Service de questions des utilisateurs", + "description": "Laissez l'IA en cours d'exécution poser des questions à l'utilisateur et attendre les réponses." + } +} diff --git a/packages/interaction/user-questions/locale/pt.json b/packages/interaction/user-questions/locale/pt.json new file mode 100644 index 0000000000..1158ebf965 --- /dev/null +++ b/packages/interaction/user-questions/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Serviço de perguntas do usuário", + "description": "Deixe a IA em execução fazer perguntas ao usuário e aguardar as respostas." + } +} diff --git a/packages/interaction/user-questions/locale/ru.json b/packages/interaction/user-questions/locale/ru.json new file mode 100644 index 0000000000..9f2c4f2042 --- /dev/null +++ b/packages/interaction/user-questions/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Служба вопросов пользователей", + "description": "Позвольте работающему ИИ задавать пользователю вопросы и ждать ответов." + } +} diff --git a/packages/jobs/jobs-local/locale/de.json b/packages/jobs/jobs-local/locale/de.json new file mode 100644 index 0000000000..cf337e489c --- /dev/null +++ b/packages/jobs/jobs-local/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "lokale Hintergrundaufgabe", + "description": "Verwalten Sie Hintergrundaufgaben im aktuellen Prozess und deren Ausführungsstatus." + } +} diff --git a/packages/jobs/jobs-local/locale/es.json b/packages/jobs/jobs-local/locale/es.json new file mode 100644 index 0000000000..795b70a730 --- /dev/null +++ b/packages/jobs/jobs-local/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "tarea en segundo plano local", + "description": "Administre tareas en segundo plano en el proceso actual y su estado de ejecución." + } +} diff --git a/packages/jobs/jobs-local/locale/fr.json b/packages/jobs/jobs-local/locale/fr.json new file mode 100644 index 0000000000..55e217168d --- /dev/null +++ b/packages/jobs/jobs-local/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "tâche d'arrière-plan locale", + "description": "Gérez les tâches en arrière-plan dans le processus en cours et leur état d'exécution." + } +} diff --git a/packages/jobs/jobs-local/locale/pt.json b/packages/jobs/jobs-local/locale/pt.json new file mode 100644 index 0000000000..4dfc105d55 --- /dev/null +++ b/packages/jobs/jobs-local/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "tarefa em segundo plano local", + "description": "Gerencie tarefas em segundo plano no processo atual e seu status de execução." + } +} diff --git a/packages/jobs/jobs-local/locale/ru.json b/packages/jobs/jobs-local/locale/ru.json new file mode 100644 index 0000000000..e9dafeb31c --- /dev/null +++ b/packages/jobs/jobs-local/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "локальная фоновая задача", + "description": "Управляйте фоновыми задачами в текущем процессе и их статусом выполнения." + } +} diff --git a/packages/jobs/tool-jobs/locale/de.json b/packages/jobs/tool-jobs/locale/de.json new file mode 100644 index 0000000000..5b8fe57a2c --- /dev/null +++ b/packages/jobs/tool-jobs/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Hintergrundaufgabentool", + "description": "Lassen Sie die KI Hintergrundaufgaben anzeigen, Ausgaben lesen oder Aufgaben stoppen." + } +} diff --git a/packages/jobs/tool-jobs/locale/es.json b/packages/jobs/tool-jobs/locale/es.json new file mode 100644 index 0000000000..703ae9bb8a --- /dev/null +++ b/packages/jobs/tool-jobs/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramienta de tarea en segundo plano", + "description": "Haga que la IA vea tareas en segundo plano, lea resultados o detenga tareas." + } +} diff --git a/packages/jobs/tool-jobs/locale/fr.json b/packages/jobs/tool-jobs/locale/fr.json new file mode 100644 index 0000000000..4652566e8b --- /dev/null +++ b/packages/jobs/tool-jobs/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outil de tâche en arrière-plan", + "description": "Demandez à l'IA d'afficher les tâches en arrière-plan, de lire le résultat ou d'arrêter les tâches." + } +} diff --git a/packages/jobs/tool-jobs/locale/pt.json b/packages/jobs/tool-jobs/locale/pt.json new file mode 100644 index 0000000000..d8c599d830 --- /dev/null +++ b/packages/jobs/tool-jobs/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramenta de tarefa em segundo plano", + "description": "Faça com que a IA visualize tarefas em segundo plano, leia a saída ou interrompa tarefas." + } +} diff --git a/packages/jobs/tool-jobs/locale/ru.json b/packages/jobs/tool-jobs/locale/ru.json new file mode 100644 index 0000000000..2844e72f24 --- /dev/null +++ b/packages/jobs/tool-jobs/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Инструмент фоновой задачи", + "description": "Пусть ИИ просматривает фоновые задачи, читает выходные данные или останавливает задачи." + } +} diff --git a/packages/llm/deepseek-llm-api-extensions/locale/de.json b/packages/llm/deepseek-llm-api-extensions/locale/de.json new file mode 100644 index 0000000000..4b7087fdaf --- /dev/null +++ b/packages/llm/deepseek-llm-api-extensions/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek API Erweiterung", + "description": "Erlauben Sie anderen Plugins, Erweiterungsfelder zu DeepSeek Modellanfragen hinzuzufügen." + } +} diff --git a/packages/llm/deepseek-llm-api-extensions/locale/es.json b/packages/llm/deepseek-llm-api-extensions/locale/es.json new file mode 100644 index 0000000000..041055180d --- /dev/null +++ b/packages/llm/deepseek-llm-api-extensions/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek API extensión", + "description": "Permita que otros complementos agreguen campos de extensión a DeepSeek solicitudes de modelo." + } +} diff --git a/packages/llm/deepseek-llm-api-extensions/locale/fr.json b/packages/llm/deepseek-llm-api-extensions/locale/fr.json new file mode 100644 index 0000000000..141f324de0 --- /dev/null +++ b/packages/llm/deepseek-llm-api-extensions/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek API poste", + "description": "Autorisez d'autres plugins à ajouter des champs d'extension à DeepSeek requêtes de modèle." + } +} diff --git a/packages/llm/deepseek-llm-api-extensions/locale/pt.json b/packages/llm/deepseek-llm-api-extensions/locale/pt.json new file mode 100644 index 0000000000..7e4703d650 --- /dev/null +++ b/packages/llm/deepseek-llm-api-extensions/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek API extensão", + "description": "Permitir que outros plug-ins adicionem campos de extensão a DeepSeek solicitações de modelo." + } +} diff --git a/packages/llm/deepseek-llm-api-extensions/locale/ru.json b/packages/llm/deepseek-llm-api-extensions/locale/ru.json new file mode 100644 index 0000000000..ccb2e7ef33 --- /dev/null +++ b/packages/llm/deepseek-llm-api-extensions/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Расширение DeepSeek API", + "description": "Разрешить другим плагинам добавлять поля расширения в запросы модели DeepSeek." + } +} diff --git a/packages/llm/llm-deepseek-account/locale/de.json b/packages/llm/llm-deepseek-account/locale/de.json new file mode 100644 index 0000000000..2dad1fb69f --- /dev/null +++ b/packages/llm/llm-deepseek-account/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeekKontomodellzugriff", + "description": "Verwenden Sie das angemeldete DeepSeek-Konto, um eine Verbindung zum Modelldienst herzustellen." + } +} diff --git a/packages/llm/llm-deepseek-account/locale/es.json b/packages/llm/llm-deepseek-account/locale/es.json new file mode 100644 index 0000000000..481dd993a9 --- /dev/null +++ b/packages/llm/llm-deepseek-account/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeekAcceso al modelo de cuenta", + "description": "Utilice la cuenta DeepSeek que haya iniciado sesión para conectarse al servicio modelo." + } +} diff --git a/packages/llm/llm-deepseek-account/locale/fr.json b/packages/llm/llm-deepseek-account/locale/fr.json new file mode 100644 index 0000000000..6283e87303 --- /dev/null +++ b/packages/llm/llm-deepseek-account/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeekAccès au modèle de compte", + "description": "Utilisez le compte DeepSeek connecté pour vous connecter au service de modèles." + } +} diff --git a/packages/llm/llm-deepseek-account/locale/pt.json b/packages/llm/llm-deepseek-account/locale/pt.json new file mode 100644 index 0000000000..2ce9915b07 --- /dev/null +++ b/packages/llm/llm-deepseek-account/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeekAcesso ao modelo de conta", + "description": "Use a conta DeepSeek conectada para se conectar ao serviço de modelo." + } +} diff --git a/packages/llm/llm-deepseek-account/locale/ru.json b/packages/llm/llm-deepseek-account/locale/ru.json new file mode 100644 index 0000000000..30c50ddf7c --- /dev/null +++ b/packages/llm/llm-deepseek-account/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeekДоступ к модели аккаунта", + "description": "Используйте зарегистрированную учетную запись DeepSeek для подключения к сервису модели." + } +} diff --git a/packages/llm/llm-deepseek-api-key/locale/de.json b/packages/llm/llm-deepseek-api-key/locale/de.json new file mode 100644 index 0000000000..063b638ec2 --- /dev/null +++ b/packages/llm/llm-deepseek-api-key/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek API Schlüsselzugriff", + "description": "Stellen Sie mit der Taste API eine Verbindung zum Modelldienst DeepSeek her." + } +} diff --git a/packages/llm/llm-deepseek-api-key/locale/es.json b/packages/llm/llm-deepseek-api-key/locale/es.json new file mode 100644 index 0000000000..2a77d5649c --- /dev/null +++ b/packages/llm/llm-deepseek-api-key/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek API Acceso clave", + "description": "Conéctese al servicio del modelo DeepSeek usando la clave API." + } +} diff --git a/packages/llm/llm-deepseek-api-key/locale/fr.json b/packages/llm/llm-deepseek-api-key/locale/fr.json new file mode 100644 index 0000000000..57d031a69c --- /dev/null +++ b/packages/llm/llm-deepseek-api-key/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek API Clé d'accès", + "description": "Connectez-vous au service de modèle DeepSeek à l'aide de la clé API." + } +} diff --git a/packages/llm/llm-deepseek-api-key/locale/pt.json b/packages/llm/llm-deepseek-api-key/locale/pt.json new file mode 100644 index 0000000000..82812122d9 --- /dev/null +++ b/packages/llm/llm-deepseek-api-key/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek API Acesso chave", + "description": "Conecte-se ao serviço de modelo DeepSeek usando a chave API." + } +} diff --git a/packages/llm/llm-deepseek-api-key/locale/ru.json b/packages/llm/llm-deepseek-api-key/locale/ru.json new file mode 100644 index 0000000000..b03114f799 --- /dev/null +++ b/packages/llm/llm-deepseek-api-key/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek API Доступ по ключу", + "description": "Подключитесь к сервису модели DeepSeek, используя ключ API." + } +} diff --git a/packages/llm/llm-pi-ai/locale/de.json b/packages/llm/llm-pi-ai/locale/de.json new file mode 100644 index 0000000000..70e0fbdf3a --- /dev/null +++ b/packages/llm/llm-pi-ai/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Anpassung des Pi-AI-Modells", + "description": "Bereitstellung der DeepSeek-Modellanpassung über pi-ai für DeepSeek Harness als designverifizierte Implementierung von dsh-llm-deepseek." + } +} diff --git a/packages/llm/llm-pi-ai/locale/es.json b/packages/llm/llm-pi-ai/locale/es.json new file mode 100644 index 0000000000..7f8e4a5998 --- /dev/null +++ b/packages/llm/llm-pi-ai/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "adaptación del modelo pi-ai", + "description": "Proporcionar DeepSeek adaptación del modelo a través de pi-ai para DeepSeek Harness como una implementación de diseño verificado de dsh-llm-deepseek." + } +} diff --git a/packages/llm/llm-pi-ai/locale/fr.json b/packages/llm/llm-pi-ai/locale/fr.json new file mode 100644 index 0000000000..6dc57de728 --- /dev/null +++ b/packages/llm/llm-pi-ai/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "adaptation du modèle pi-ai", + "description": "Fournir une adaptation de modèle DeepSeek via pi-ai pour DeepSeek Harness en tant qu'implémentation vérifiée par la conception de dsh-llm-deepseek." + } +} diff --git a/packages/llm/llm-pi-ai/locale/pt.json b/packages/llm/llm-pi-ai/locale/pt.json new file mode 100644 index 0000000000..414171b6df --- /dev/null +++ b/packages/llm/llm-pi-ai/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "adaptação do modelo pi-ai", + "description": "Fornecimento de adaptação do modelo DeepSeek via pi-ai para DeepSeek Harness como uma implementação verificada por design de dsh-llm-deepseek." + } +} diff --git a/packages/llm/llm-pi-ai/locale/ru.json b/packages/llm/llm-pi-ai/locale/ru.json new file mode 100644 index 0000000000..6e7efc9dfe --- /dev/null +++ b/packages/llm/llm-pi-ai/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "адаптация модели пи-ай", + "description": "Обеспечение адаптации модели DeepSeek через pi-ai для DeepSeek Harness в качестве проверенной реализации dsh-llm-deepseek." + } +} diff --git a/packages/llm/llm-retry/locale/de.json b/packages/llm/llm-retry/locale/de.json new file mode 100644 index 0000000000..ccd3b1b697 --- /dev/null +++ b/packages/llm/llm-retry/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Wiederholung der Modellanforderung", + "description": "Wiederholen Sie fehlgeschlagene Anforderungen gemäß der Richtlinie des Modellanbieters." + } +} diff --git a/packages/llm/llm-retry/locale/es.json b/packages/llm/llm-retry/locale/es.json new file mode 100644 index 0000000000..a932a1a446 --- /dev/null +++ b/packages/llm/llm-retry/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Reintento de solicitud de modelo", + "description": "Vuelva a intentar las solicitudes fallidas según la política del proveedor del modelo." + } +} diff --git a/packages/llm/llm-retry/locale/fr.json b/packages/llm/llm-retry/locale/fr.json new file mode 100644 index 0000000000..d949ad00d7 --- /dev/null +++ b/packages/llm/llm-retry/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Nouvelle tentative de demande de modèle", + "description": "Réessayez les demandes ayant échoué conformément à la politique du fournisseur de modèles." + } +} diff --git a/packages/llm/llm-retry/locale/pt.json b/packages/llm/llm-retry/locale/pt.json new file mode 100644 index 0000000000..7aba612014 --- /dev/null +++ b/packages/llm/llm-retry/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Nova tentativa de solicitação de modelo", + "description": "Tente novamente as solicitações com falha de acordo com a política do provedor do modelo." + } +} diff --git a/packages/llm/llm-retry/locale/ru.json b/packages/llm/llm-retry/locale/ru.json new file mode 100644 index 0000000000..85c25fa67c --- /dev/null +++ b/packages/llm/llm-retry/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Повтор запроса модели", + "description": "Повторите неудачные запросы в соответствии с политикой поставщика модели." + } +} diff --git a/packages/llm/llm/locale/de.json b/packages/llm/llm/locale/de.json new file mode 100644 index 0000000000..51b3b07417 --- /dev/null +++ b/packages/llm/llm/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "llm", + "description": "Stellen Sie eine einheitliche Aufrufschnittstelle für verschiedene Modelle bereit." + } +} diff --git a/packages/llm/llm/locale/es.json b/packages/llm/llm/locale/es.json new file mode 100644 index 0000000000..283632d4d0 --- /dev/null +++ b/packages/llm/llm/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "llm", + "description": "Proporcione una interfaz de llamadas unificada para diferentes modelos." + } +} diff --git a/packages/llm/llm/locale/fr.json b/packages/llm/llm/locale/fr.json new file mode 100644 index 0000000000..b4c537e9ac --- /dev/null +++ b/packages/llm/llm/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "llm", + "description": "Fournit une interface d'appel unifiée pour différents modèles." + } +} diff --git a/packages/llm/llm/locale/pt.json b/packages/llm/llm/locale/pt.json new file mode 100644 index 0000000000..612c8970dd --- /dev/null +++ b/packages/llm/llm/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "llm", + "description": "Fornece uma interface de chamada unificada para diferentes modelos." + } +} diff --git a/packages/llm/llm/locale/ru.json b/packages/llm/llm/locale/ru.json new file mode 100644 index 0000000000..2195597897 --- /dev/null +++ b/packages/llm/llm/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "лм", + "description": "Обеспечьте единый интерфейс вызова для разных моделей." + } +} diff --git a/packages/llm/plugin-package-inventory-deepseek/locale/de.json b/packages/llm/plugin-package-inventory-deepseek/locale/de.json new file mode 100644 index 0000000000..a17c1fe662 --- /dev/null +++ b/packages/llm/plugin-package-inventory-deepseek/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Plug-in-Listenberichte", + "description": "Mit der offiziellen Modell-API-Anfrage wird eine Liste der derzeit aktiven Plugin-Pakete gesendet." + } +} diff --git a/packages/llm/plugin-package-inventory-deepseek/locale/es.json b/packages/llm/plugin-package-inventory-deepseek/locale/es.json new file mode 100644 index 0000000000..45dba4abed --- /dev/null +++ b/packages/llm/plugin-package-inventory-deepseek/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Informes de lista de complementos", + "description": "Se envía una lista de los paquetes de complementos activos actualmente con la solicitud del modelo oficial API." + } +} diff --git a/packages/llm/plugin-package-inventory-deepseek/locale/fr.json b/packages/llm/plugin-package-inventory-deepseek/locale/fr.json new file mode 100644 index 0000000000..b83c55b214 --- /dev/null +++ b/packages/llm/plugin-package-inventory-deepseek/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Rapports sur la liste des plug-ins", + "description": "Une liste des packages de plugins actuellement actifs est envoyée avec la demande officielle de modèle API." + } +} diff --git a/packages/llm/plugin-package-inventory-deepseek/locale/pt.json b/packages/llm/plugin-package-inventory-deepseek/locale/pt.json new file mode 100644 index 0000000000..bdfbe76c9b --- /dev/null +++ b/packages/llm/plugin-package-inventory-deepseek/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Relatórios de lista de plug-ins", + "description": "Uma lista de pacotes de plug-ins atualmente ativos é enviada com a solicitação do modelo oficial API." + } +} diff --git a/packages/llm/plugin-package-inventory-deepseek/locale/ru.json b/packages/llm/plugin-package-inventory-deepseek/locale/ru.json new file mode 100644 index 0000000000..8a203c7c84 --- /dev/null +++ b/packages/llm/plugin-package-inventory-deepseek/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Отчеты по спискам плагинов", + "description": "Список активных на данный момент пакетов плагинов отправляется с официальным запросом модели API." + } +} diff --git a/packages/llm/token-meter/locale/de.json b/packages/llm/token-meter/locale/de.json new file mode 100644 index 0000000000..f26489b745 --- /dev/null +++ b/packages/llm/token-meter/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Token-Messung", + "description": "Schätzen Sie die Token-Nutzung des Modellkontexts, um das Budget für Funktionen wie Komprimierung zu bestimmen." + } +} diff --git a/packages/llm/token-meter/locale/es.json b/packages/llm/token-meter/locale/es.json new file mode 100644 index 0000000000..56763b8150 --- /dev/null +++ b/packages/llm/token-meter/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Medición de tokens", + "description": "Calcule el uso del token del contexto del modelo para determinar el presupuesto para funciones como la compresión." + } +} diff --git a/packages/llm/token-meter/locale/fr.json b/packages/llm/token-meter/locale/fr.json new file mode 100644 index 0000000000..087edb58d1 --- /dev/null +++ b/packages/llm/token-meter/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Comptage des jetons", + "description": "Estimez l'utilisation du jeton du contexte du modèle pour déterminer le budget pour des fonctions telles que la compression." + } +} diff --git a/packages/llm/token-meter/locale/pt.json b/packages/llm/token-meter/locale/pt.json new file mode 100644 index 0000000000..7b7334f656 --- /dev/null +++ b/packages/llm/token-meter/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Medição de token", + "description": "Estime o uso de token do contexto do modelo para determinar o orçamento para funções como compactação." + } +} diff --git a/packages/llm/token-meter/locale/ru.json b/packages/llm/token-meter/locale/ru.json new file mode 100644 index 0000000000..0cb8909b2c --- /dev/null +++ b/packages/llm/token-meter/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Измерение токенов", + "description": "Оцените использование токена контекста модели, чтобы определить бюджет для таких функций, как сжатие." + } +} diff --git a/packages/lsp/lsp-stdio/locale/de.json b/packages/lsp/lsp-stdio/locale/de.json new file mode 100644 index 0000000000..a6b25d633e --- /dev/null +++ b/packages/lsp/lsp-stdio/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Anbieter von Stdio-Sprachservern", + "description": "Stellen Sie über Unterprozesse und JSON-RPC eine Verbindung zu Sprachservern her, öffnen Sie Dateien nach Bedarf und führen Sie Codeabfragen aus." + } +} diff --git a/packages/lsp/lsp-stdio/locale/es.json b/packages/lsp/lsp-stdio/locale/es.json new file mode 100644 index 0000000000..86d92c6499 --- /dev/null +++ b/packages/lsp/lsp-stdio/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Proveedor de servidor de idioma Stdio", + "description": "Conéctese a servidores de idiomas a través de subprocesos y JSON-RPC, abra archivos según sea necesario y ejecute consultas de código." + } +} diff --git a/packages/lsp/lsp-stdio/locale/fr.json b/packages/lsp/lsp-stdio/locale/fr.json new file mode 100644 index 0000000000..a6f2759518 --- /dev/null +++ b/packages/lsp/lsp-stdio/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Fournisseur de serveur de langue Stdio", + "description": "Connectez-vous aux serveurs de langue via des sous-processus et JSON-RPC, ouvrez les fichiers selon vos besoins et exécutez des requêtes de code." + } +} diff --git a/packages/lsp/lsp-stdio/locale/pt.json b/packages/lsp/lsp-stdio/locale/pt.json new file mode 100644 index 0000000000..51295ff47b --- /dev/null +++ b/packages/lsp/lsp-stdio/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Provedor de servidor de linguagem Stdio", + "description": "Conecte-se a servidores de linguagem por meio de subprocessos e JSON-RPC, abra arquivos conforme necessário e execute consultas de código." + } +} diff --git a/packages/lsp/lsp-stdio/locale/ru.json b/packages/lsp/lsp-stdio/locale/ru.json new file mode 100644 index 0000000000..a656d64a14 --- /dev/null +++ b/packages/lsp/lsp-stdio/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Поставщик языкового сервера Stdio", + "description": "Подключайтесь к языковым серверам через подпроцессы и JSON-RPC, открывайте файлы по мере необходимости и выполняйте запросы кода." + } +} diff --git a/packages/lsp/lsp/locale/de.json b/packages/lsp/lsp/locale/de.json new file mode 100644 index 0000000000..711abedf83 --- /dev/null +++ b/packages/lsp/lsp/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sprachserverdienst", + "description": "Registrieren Sie Sprachserver für Definitions-, Referenz-, Implementierungs- und Hover-Abfragen mit konsistenten Fehlern." + } +} diff --git a/packages/lsp/lsp/locale/es.json b/packages/lsp/lsp/locale/es.json new file mode 100644 index 0000000000..30942c83be --- /dev/null +++ b/packages/lsp/lsp/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Servicio de servidor de idiomas", + "description": "Registre servidores de idiomas para consultas de definición, referencia, implementación y desplazamiento con errores consistentes." + } +} diff --git a/packages/lsp/lsp/locale/fr.json b/packages/lsp/lsp/locale/fr.json new file mode 100644 index 0000000000..04962eb6e7 --- /dev/null +++ b/packages/lsp/lsp/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Service de serveur de langue", + "description": "Enregistrez les serveurs de langage pour les requêtes de définition, de référence, d’implémentation et de survol avec des erreurs cohérentes." + } +} diff --git a/packages/lsp/lsp/locale/pt.json b/packages/lsp/lsp/locale/pt.json new file mode 100644 index 0000000000..6d494dfaef --- /dev/null +++ b/packages/lsp/lsp/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Serviço de servidor de idiomas", + "description": "Registre servidores de linguagem para definição, referência, implementação e consultas instantâneas com erros consistentes." + } +} diff --git a/packages/lsp/lsp/locale/ru.json b/packages/lsp/lsp/locale/ru.json new file mode 100644 index 0000000000..4ab8f15500 --- /dev/null +++ b/packages/lsp/lsp/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Служба языкового сервера", + "description": "Зарегистрируйте языковые серверы для определения, ссылки, реализации и запросов при наведении с постоянными ошибками." + } +} diff --git a/packages/lsp/tool-lsp/locale/de.json b/packages/lsp/tool-lsp/locale/de.json new file mode 100644 index 0000000000..46774010d3 --- /dev/null +++ b/packages/lsp/tool-lsp/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sprachserver-Tools", + "description": "Fragen Sie Definitionen, Referenzen, Implementierungen und Hover-Informationen mit einbasierten UTF-16-Cursorpositionen und begrenzten Ergebnissen ab." + } +} diff --git a/packages/lsp/tool-lsp/locale/es.json b/packages/lsp/tool-lsp/locale/es.json new file mode 100644 index 0000000000..bda7d88c31 --- /dev/null +++ b/packages/lsp/tool-lsp/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramientas del servidor de idiomas", + "description": "Consulte definiciones, referencias, implementaciones e información al pasar el mouse utilizando posiciones de cursor UTF-16 basadas en una y resultados acotados." + } +} diff --git a/packages/lsp/tool-lsp/locale/fr.json b/packages/lsp/tool-lsp/locale/fr.json new file mode 100644 index 0000000000..e2cda4fae7 --- /dev/null +++ b/packages/lsp/tool-lsp/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outils de serveur de langue", + "description": "Interrogez des définitions, des références, des implémentations et des informations de survol à l'aide de positions de curseur UTF-16 à base unique et de résultats limités." + } +} diff --git a/packages/lsp/tool-lsp/locale/pt.json b/packages/lsp/tool-lsp/locale/pt.json new file mode 100644 index 0000000000..bc92ae3912 --- /dev/null +++ b/packages/lsp/tool-lsp/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramentas de servidor de idiomas", + "description": "Consulte definições, referências, implementações e informações instantâneas usando posições de cursor UTF-16 baseadas em um e resultados limitados." + } +} diff --git a/packages/lsp/tool-lsp/locale/ru.json b/packages/lsp/tool-lsp/locale/ru.json new file mode 100644 index 0000000000..6b0b1aaa6c --- /dev/null +++ b/packages/lsp/tool-lsp/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Инструменты языкового сервера", + "description": "Определения запросов, ссылки, реализации и информация при наведении с использованием позиций курсора UTF-16 на основе единицы и ограниченных результатов." + } +} diff --git a/packages/mcp/mcp-client/locale/de.json b/packages/mcp/mcp-client/locale/de.json new file mode 100644 index 0000000000..a9e0aec3b6 --- /dev/null +++ b/packages/mcp/mcp-client/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "MCP-Client", + "description": "Stellen Sie eine Verbindung zu MCP-Servern her und stellen Sie deren Tools in Harness zur Verfügung." + } +} diff --git a/packages/mcp/mcp-client/locale/es.json b/packages/mcp/mcp-client/locale/es.json new file mode 100644 index 0000000000..0347e5b050 --- /dev/null +++ b/packages/mcp/mcp-client/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Cliente MCP", + "description": "Conéctese a los servidores MCP y haga que sus herramientas estén disponibles en Harness." + } +} diff --git a/packages/mcp/mcp-client/locale/fr.json b/packages/mcp/mcp-client/locale/fr.json new file mode 100644 index 0000000000..dcf03801cb --- /dev/null +++ b/packages/mcp/mcp-client/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Client MCP", + "description": "Connectez-vous aux serveurs MCP et rendez leurs outils disponibles dans Harness." + } +} diff --git a/packages/mcp/mcp-client/locale/pt.json b/packages/mcp/mcp-client/locale/pt.json new file mode 100644 index 0000000000..7327559895 --- /dev/null +++ b/packages/mcp/mcp-client/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "MCP cliente", + "description": "Conecte-se a MCP servidores e disponibilize suas ferramentas no Harness." + } +} diff --git a/packages/mcp/mcp-client/locale/ru.json b/packages/mcp/mcp-client/locale/ru.json new file mode 100644 index 0000000000..c618e4168e --- /dev/null +++ b/packages/mcp/mcp-client/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "MCP клиент", + "description": "Подключитесь к серверам MCP и сделайте их инструменты доступными в Harness." + } +} diff --git a/packages/mcp/mcp-resources/locale/de.json b/packages/mcp/mcp-resources/locale/de.json new file mode 100644 index 0000000000..90cc07b4c1 --- /dev/null +++ b/packages/mcp/mcp-resources/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "MCP Ressourcenzugriff", + "description": "Lassen Sie die KI vom MCP-Dienst bereitgestellte Ressourcen entdecken und lesen." + } +} diff --git a/packages/mcp/mcp-resources/locale/es.json b/packages/mcp/mcp-resources/locale/es.json new file mode 100644 index 0000000000..83059c43f8 --- /dev/null +++ b/packages/mcp/mcp-resources/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "MCP acceso a recursos", + "description": "Permita que la IA descubra y lea los recursos proporcionados por el servicio MCP." + } +} diff --git a/packages/mcp/mcp-resources/locale/fr.json b/packages/mcp/mcp-resources/locale/fr.json new file mode 100644 index 0000000000..42bf88095f --- /dev/null +++ b/packages/mcp/mcp-resources/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "MCP accès aux ressources", + "description": "Laissez l'IA découvrir et lire les ressources fournies par le service MCP." + } +} diff --git a/packages/mcp/mcp-resources/locale/pt.json b/packages/mcp/mcp-resources/locale/pt.json new file mode 100644 index 0000000000..d38addcef2 --- /dev/null +++ b/packages/mcp/mcp-resources/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "MCP acesso a recursos", + "description": "Deixe a IA descobrir e ler os recursos fornecidos pelo serviço MCP." + } +} diff --git a/packages/mcp/mcp-resources/locale/ru.json b/packages/mcp/mcp-resources/locale/ru.json new file mode 100644 index 0000000000..6cfc4e0b61 --- /dev/null +++ b/packages/mcp/mcp-resources/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "MCP доступ к ресурсу", + "description": "Позвольте ИИ обнаруживать и читать ресурсы, предоставляемые службой MCP." + } +} diff --git a/packages/plan/plan-mode/locale/de.json b/packages/plan/plan-mode/locale/de.json new file mode 100644 index 0000000000..56de6dd821 --- /dev/null +++ b/packages/plan/plan-mode/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Planungsmodus", + "description": "Lassen Sie die KI zunächst den Plan erstellen und nach Überprüfung durch den Benutzer mit der Ausführung fortfahren." + } +} diff --git a/packages/plan/plan-mode/locale/es.json b/packages/plan/plan-mode/locale/es.json new file mode 100644 index 0000000000..e8912e4e3b --- /dev/null +++ b/packages/plan/plan-mode/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "modo de planificación", + "description": "Deje que AI cree el plan primero y pase a ejecución después de la revisión del usuario." + } +} diff --git a/packages/plan/plan-mode/locale/fr.json b/packages/plan/plan-mode/locale/fr.json new file mode 100644 index 0000000000..c3f6bc326a --- /dev/null +++ b/packages/plan/plan-mode/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "mode de planification", + "description": "Laissez l’IA créer le plan en premier et passez à l’exécution après examen par l’utilisateur." + } +} diff --git a/packages/plan/plan-mode/locale/pt.json b/packages/plan/plan-mode/locale/pt.json new file mode 100644 index 0000000000..3bafb463c6 --- /dev/null +++ b/packages/plan/plan-mode/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "modo de planejamento", + "description": "Deixe a IA criar o plano primeiro e passar para a execução após a revisão do usuário." + } +} diff --git a/packages/plan/plan-mode/locale/ru.json b/packages/plan/plan-mode/locale/ru.json new file mode 100644 index 0000000000..8ec3b06c15 --- /dev/null +++ b/packages/plan/plan-mode/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "режим планирования", + "description": "Пусть ИИ сначала создаст план и перейдет к исполнению после проверки пользователем." + } +} diff --git a/packages/preset/agent-preset-registry/locale/de.json b/packages/preset/agent-preset-registry/locale/de.json new file mode 100644 index 0000000000..7317119818 --- /dev/null +++ b/packages/preset/agent-preset-registry/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Agenten-Standardverwaltung", + "description": "Registrieren Sie Agent-Voreinstellungen und speichern Sie Änderungen an der voreingestellten Zusammensetzung." + } +} diff --git a/packages/preset/agent-preset-registry/locale/es.json b/packages/preset/agent-preset-registry/locale/es.json new file mode 100644 index 0000000000..5833ad7c47 --- /dev/null +++ b/packages/preset/agent-preset-registry/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Gestión predeterminada del agente", + "description": "Registre los ajustes preestablecidos del agente y guarde los cambios en la composición preestablecida." + } +} diff --git a/packages/preset/agent-preset-registry/locale/fr.json b/packages/preset/agent-preset-registry/locale/fr.json new file mode 100644 index 0000000000..29bca2c64b --- /dev/null +++ b/packages/preset/agent-preset-registry/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Gestion des défauts des agents", + "description": "Enregistrez les préréglages d’agent et enregistrez les modifications apportées à la composition prédéfinie." + } +} diff --git a/packages/preset/agent-preset-registry/locale/pt.json b/packages/preset/agent-preset-registry/locale/pt.json new file mode 100644 index 0000000000..4734561e1e --- /dev/null +++ b/packages/preset/agent-preset-registry/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Gerenciamento padrão do agente", + "description": "Registre predefinições de agente e salve as alterações na composição predefinida." + } +} diff --git a/packages/preset/agent-preset-registry/locale/ru.json b/packages/preset/agent-preset-registry/locale/ru.json new file mode 100644 index 0000000000..6d9b5d19e9 --- /dev/null +++ b/packages/preset/agent-preset-registry/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Управление агентом по умолчанию", + "description": "Зарегистрируйте пресеты Агента и сохраните изменения в составе пресетов." + } +} diff --git a/packages/preset/agent-preset/locale/de.json b/packages/preset/agent-preset/locale/de.json new file mode 100644 index 0000000000..3f6fd29409 --- /dev/null +++ b/packages/preset/agent-preset/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Standarddefinition des Agenten", + "description": "Deklarieren Sie eine Agent-Voreinstellung und die Kombination der verwendeten Plugins." + } +} diff --git a/packages/preset/agent-preset/locale/es.json b/packages/preset/agent-preset/locale/es.json new file mode 100644 index 0000000000..f0f9eb3703 --- /dev/null +++ b/packages/preset/agent-preset/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Definición predeterminada del agente", + "description": "Declare un ajuste preestablecido de Agente y la combinación de complementos que utiliza." + } +} diff --git a/packages/preset/agent-preset/locale/fr.json b/packages/preset/agent-preset/locale/fr.json new file mode 100644 index 0000000000..edf503a864 --- /dev/null +++ b/packages/preset/agent-preset/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Définition par défaut de l'agent", + "description": "Déclarez un préréglage d'agent et la combinaison de plugins qu'il utilise." + } +} diff --git a/packages/preset/agent-preset/locale/pt.json b/packages/preset/agent-preset/locale/pt.json new file mode 100644 index 0000000000..58857c7783 --- /dev/null +++ b/packages/preset/agent-preset/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Definição padrão do agente", + "description": "Declare uma predefinição de agente e a combinação de plug-ins que ele usa." + } +} diff --git a/packages/preset/agent-preset/locale/ru.json b/packages/preset/agent-preset/locale/ru.json new file mode 100644 index 0000000000..2b7f109dab --- /dev/null +++ b/packages/preset/agent-preset/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Определение агента по умолчанию", + "description": "Объявите предустановку агента и комбинацию используемых им плагинов." + } +} diff --git a/packages/preset/agent-preset/skills/cordis-plugin-development/SKILL.md b/packages/preset/agent-preset/skills/cordis-plugin-development/SKILL.md index 8a3fd8cf62..ea246d47fa 100644 --- a/packages/preset/agent-preset/skills/cordis-plugin-development/SKILL.md +++ b/packages/preset/agent-preset/skills/cordis-plugin-development/SKILL.md @@ -1,17 +1,17 @@ --- name: cordis-plugin-development -description: Use when designing, reviewing, adding, enabling, disabling, installing, configuring, or debugging a plugin, bundle, feature, page, panel, tool, or MCP connection in the current Harness profile, including a shipped plugin that is disabled by default, and for any visual object, decoration, or widget request that names no other destination, which means an installed UI plugin rendered in the Harness Web UI. +description: Use when creating, reviewing, installing, enabling, disabling, configuring, or debugging Harness plugins, bundles, features, tools, MCP connections, pages, panels, decorations or widgets. Visual requests without another destination mean an installed UI plugin in Harness Web UI. --- # Persistent Harness plugins -For implementation, use ordinary workspace files to author a bundle, then `plugin_manager` with `action: install_bundle` and the absolute package directory as `target` to install it in the current profile. Changes affect every session in that profile and survive restart. Load `editing-cordis-compositions` for agent preset changes. +Author a workspace bundle, then install it in the current profile with `plugin_manager` (`action: install_bundle`, absolute package directory as `target`). It persists across sessions and restarts. Load `editing-cordis-compositions` for agent preset changes. Do not write the profile's `package.json` or `cordis.patch.yml`, create packages under `$DSH_HOME`, or run pnpm in the profile directory: `install_bundle` performs those steps, and each hand-made write outside the workspace needs its own approval. Every `plugin_manager` action, including `list_plugins` and `list_bundles`, also needs approval without Full access, so call it only when its result decides the next step. ## Design or review -Read the applicable references below and inspect the proposed or existing plugin against current APIs. Report design choices or findings instead of following the installation workflow. Do not write files, install bundles, or change profile state unless the user requests implementation. +Inspect the plugin against current APIs using the applicable references below. Report choices or findings; write files, install bundles, or change profile state only when implementation is requested. ## Enable a shipped plugin @@ -35,7 +35,7 @@ A shipped bundle can resolve a plugin row and leave it `disabled`. The row id an ## Read next -The files below live in this skill's base directory, which the `skill` tool reported, and the table is the complete list: do not enumerate that directory. In every deployment, including a source checkout, read these files with the file-read tool, write copies into the workspace with the file-write tool, and verify a copy by reading it back. In Desktop the directory sits inside `app.asar`, which only the Host process's own file reads can open; shell commands (`ls`, `cat`, `cp`, `cmp`), the glob and search tools (they run a native ripgrep process), `node`, and pnpm all fail on it. Never install or syntax-check a template in place; copy its contents into the workspace first. +The table lists every file in the base directory reported by `skill`; do not enumerate it. In every deployment, including source checkouts, use file-read/file-write tools to copy these files into the workspace, then read the copies to verify them. Desktop stores the directory in `app.asar`: only Host file reads work there. Shell commands, native glob/search tools, `node`, and pnpm cannot read it. Never install or syntax-check a template in place; copy its contents into the workspace first. | Task | File | |---|---| @@ -43,8 +43,8 @@ The files below live in this skill's base directory, which the `skill` tool repo | Web UI: Client manifest, module loader, slot registration | `references/ui-plugin.md` | | Connecting an MCP server through a configuration-only bundle | `references/mcp-bundle.md` | | Page/panel design checks and verification without browser control | `references/verification.md` | -| UI plugin template, including display resources | `templates/decoration/package.json`, `templates/decoration/cordis.patch.yml`, `templates/decoration/index.js`, `templates/decoration/client.js`, `templates/decoration/locale/en.json`, `templates/decoration/locale/ja.json`, `templates/decoration/icon.svg` | -| MCP bundle template, including display resources | `templates/mcp/package.json`, `templates/mcp/cordis.patch.yml`, `templates/mcp/locale/en.json`, `templates/mcp/locale/ja.json`, `templates/mcp/icon.svg` | +| UI plugin template and display resources | `templates/decoration/package.json`, `templates/decoration/cordis.patch.yml`, `templates/decoration/index.js`, `templates/decoration/client.js`, `templates/decoration/locale/en.json`, `templates/decoration/locale/ja.json`, `templates/decoration/locale/es.json`, `templates/decoration/locale/fr.json`, `templates/decoration/locale/de.json`, `templates/decoration/locale/ru.json`, `templates/decoration/locale/pt.json`, `templates/decoration/icon.svg` | +| MCP template and display resources | `templates/mcp/package.json`, `templates/mcp/cordis.patch.yml`, `templates/mcp/locale/en.json`, `templates/mcp/locale/ja.json`, `templates/mcp/locale/es.json`, `templates/mcp/locale/fr.json`, `templates/mcp/locale/de.json`, `templates/mcp/locale/ru.json`, `templates/mcp/locale/pt.json`, `templates/mcp/icon.svg` | | Loader patch dialect and the list of installable plugin packages | the `cordis-composition-reference` skill | | Choosing extension points, contexts, and state mechanisms for upgrade stability and performance | `references/practices.md` | | Sharing application operations between UI actions and agent tools | `references/user-actions.md` | diff --git a/packages/preset/agent-preset/skills/cordis-plugin-development/templates/decoration/locale/de.json b/packages/preset/agent-preset/skills/cordis-plugin-development/templates/decoration/locale/de.json new file mode 100644 index 0000000000..28f720e5dc --- /dev/null +++ b/packages/preset/agent-preset/skills/cordis-plugin-development/templates/decoration/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Komponistendekoration", + "description": "Zeigt einen blauen Kreis unter dem Nachrichtenersteller an." + } +} diff --git a/packages/preset/agent-preset/skills/cordis-plugin-development/templates/decoration/locale/es.json b/packages/preset/agent-preset/skills/cordis-plugin-development/templates/decoration/locale/es.json new file mode 100644 index 0000000000..de8c075ed2 --- /dev/null +++ b/packages/preset/agent-preset/skills/cordis-plugin-development/templates/decoration/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Decoración del compositor", + "description": "Muestra un círculo azul debajo del redactor del mensaje." + } +} diff --git a/packages/preset/agent-preset/skills/cordis-plugin-development/templates/decoration/locale/fr.json b/packages/preset/agent-preset/skills/cordis-plugin-development/templates/decoration/locale/fr.json new file mode 100644 index 0000000000..cb96c5563c --- /dev/null +++ b/packages/preset/agent-preset/skills/cordis-plugin-development/templates/decoration/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Décoration du compositeur", + "description": "Affiche un cercle bleu sous le compositeur du message." + } +} diff --git a/packages/preset/agent-preset/skills/cordis-plugin-development/templates/decoration/locale/pt.json b/packages/preset/agent-preset/skills/cordis-plugin-development/templates/decoration/locale/pt.json new file mode 100644 index 0000000000..50a7b87780 --- /dev/null +++ b/packages/preset/agent-preset/skills/cordis-plugin-development/templates/decoration/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Decoração do compositor", + "description": "Exibe um círculo azul abaixo do compositor da mensagem." + } +} diff --git a/packages/preset/agent-preset/skills/cordis-plugin-development/templates/decoration/locale/ru.json b/packages/preset/agent-preset/skills/cordis-plugin-development/templates/decoration/locale/ru.json new file mode 100644 index 0000000000..ef10cc2665 --- /dev/null +++ b/packages/preset/agent-preset/skills/cordis-plugin-development/templates/decoration/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Композиторское украшение", + "description": "Отображает синий кружок под составителем сообщения." + } +} diff --git a/packages/preset/agent-preset/skills/cordis-plugin-development/templates/mcp/locale/de.json b/packages/preset/agent-preset/skills/cordis-plugin-development/templates/mcp/locale/de.json new file mode 100644 index 0000000000..0a875281a6 --- /dev/null +++ b/packages/preset/agent-preset/skills/cordis-plugin-development/templates/mcp/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Demo-MCP-Verbindung", + "description": "Verbindet einen Remote-MCP-Server, um seine Tools dem Agenten zur Verfügung zu stellen." + } +} diff --git a/packages/preset/agent-preset/skills/cordis-plugin-development/templates/mcp/locale/es.json b/packages/preset/agent-preset/skills/cordis-plugin-development/templates/mcp/locale/es.json new file mode 100644 index 0000000000..307f421538 --- /dev/null +++ b/packages/preset/agent-preset/skills/cordis-plugin-development/templates/mcp/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Conexión de demostración MCP", + "description": "Conecta un servidor MCP remoto para que sus herramientas estén disponibles para el agente." + } +} diff --git a/packages/preset/agent-preset/skills/cordis-plugin-development/templates/mcp/locale/fr.json b/packages/preset/agent-preset/skills/cordis-plugin-development/templates/mcp/locale/fr.json new file mode 100644 index 0000000000..ebf0f84f80 --- /dev/null +++ b/packages/preset/agent-preset/skills/cordis-plugin-development/templates/mcp/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Démo connexion MCP", + "description": "Connecte un serveur MCP distant pour mettre ses outils à disposition de l'agent." + } +} diff --git a/packages/preset/agent-preset/skills/cordis-plugin-development/templates/mcp/locale/pt.json b/packages/preset/agent-preset/skills/cordis-plugin-development/templates/mcp/locale/pt.json new file mode 100644 index 0000000000..7a8b4f7c67 --- /dev/null +++ b/packages/preset/agent-preset/skills/cordis-plugin-development/templates/mcp/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Conexão de demonstração MCP", + "description": "Conecta um servidor MCP remoto para disponibilizar suas ferramentas ao agente." + } +} diff --git a/packages/preset/agent-preset/skills/cordis-plugin-development/templates/mcp/locale/ru.json b/packages/preset/agent-preset/skills/cordis-plugin-development/templates/mcp/locale/ru.json new file mode 100644 index 0000000000..1151ec35e2 --- /dev/null +++ b/packages/preset/agent-preset/skills/cordis-plugin-development/templates/mcp/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Демо-соединение MCP", + "description": "Подключает удаленный сервер MCP, чтобы сделать его инструменты доступными для агента." + } +} diff --git a/packages/preset/persona/locale/de.json b/packages/preset/persona/locale/de.json new file mode 100644 index 0000000000..7a54e0f9b5 --- /dev/null +++ b/packages/preset/persona/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Persona", + "description": "Stellt dem aktuellen Agenten Beschreibungen der in der Komposition definierten Rollen und Verhaltensweisen bereit." + } +} diff --git a/packages/preset/persona/locale/es.json b/packages/preset/persona/locale/es.json new file mode 100644 index 0000000000..6ab8e1345a --- /dev/null +++ b/packages/preset/persona/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "persona", + "description": "Proporciona al agente actual descripciones de los roles y comportamientos definidos en la composición." + } +} diff --git a/packages/preset/persona/locale/fr.json b/packages/preset/persona/locale/fr.json new file mode 100644 index 0000000000..5d024eed4b --- /dev/null +++ b/packages/preset/persona/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "personnage", + "description": "Fournit à l’agent actuel des descriptions des rôles et des comportements définis dans la composition." + } +} diff --git a/packages/preset/persona/locale/pt.json b/packages/preset/persona/locale/pt.json new file mode 100644 index 0000000000..d3f9212377 --- /dev/null +++ b/packages/preset/persona/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "pessoa", + "description": "Fornece ao agente atual descrições das funções e comportamentos definidos na composição." + } +} diff --git a/packages/preset/persona/locale/ru.json b/packages/preset/persona/locale/ru.json new file mode 100644 index 0000000000..52658366a6 --- /dev/null +++ b/packages/preset/persona/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "личность", + "description": "Предоставляет текущему агенту описания ролей и поведений, определенных в композиции." + } +} diff --git a/packages/ptc-runtime/ptc-runtime-node/locale/de.json b/packages/ptc-runtime/ptc-runtime-node/locale/de.json new file mode 100644 index 0000000000..c684b3fdb2 --- /dev/null +++ b/packages/ptc-runtime/ptc-runtime-node/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Laufzeit des Knotens PTC", + "description": "Führen Sie den Code aus, der das Tool im Node-Prozess in der Sandbox aufruft." + } +} diff --git a/packages/ptc-runtime/ptc-runtime-node/locale/es.json b/packages/ptc-runtime/ptc-runtime-node/locale/es.json new file mode 100644 index 0000000000..01b646393f --- /dev/null +++ b/packages/ptc-runtime/ptc-runtime-node/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Tiempo de ejecución del nodo PTC", + "description": "Ejecute el código que llama a la herramienta en el proceso Node en el sandbox." + } +} diff --git a/packages/ptc-runtime/ptc-runtime-node/locale/fr.json b/packages/ptc-runtime/ptc-runtime-node/locale/fr.json new file mode 100644 index 0000000000..91a68a8593 --- /dev/null +++ b/packages/ptc-runtime/ptc-runtime-node/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Exécution du nœud PTC", + "description": "Exécutez le code qui appelle l'outil dans le processus Node dans le bac à sable." + } +} diff --git a/packages/ptc-runtime/ptc-runtime-node/locale/pt.json b/packages/ptc-runtime/ptc-runtime-node/locale/pt.json new file mode 100644 index 0000000000..f231a6a4fa --- /dev/null +++ b/packages/ptc-runtime/ptc-runtime-node/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Tempo de execução do nó PTC", + "description": "Execute o código que chama a ferramenta no processo do Node no sandbox." + } +} diff --git a/packages/ptc-runtime/ptc-runtime-node/locale/ru.json b/packages/ptc-runtime/ptc-runtime-node/locale/ru.json new file mode 100644 index 0000000000..89f5e38eda --- /dev/null +++ b/packages/ptc-runtime/ptc-runtime-node/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Время выполнения узла PTC", + "description": "Выполните код, вызывающий инструмент, в процессе Node в песочнице." + } +} diff --git a/packages/sandbox/sandbox-local/locale/de.json b/packages/sandbox/sandbox-local/locale/de.json new file mode 100644 index 0000000000..9d4e9c2aba --- /dev/null +++ b/packages/sandbox/sandbox-local/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "lokale Prozess-Sandbox", + "description": "Sorgen Sie für eine Prozessisolierung nach Betriebssystem und begrenzen Sie den Zugriffsbereich von Befehlen." + } +} diff --git a/packages/sandbox/sandbox-local/locale/es.json b/packages/sandbox/sandbox-local/locale/es.json new file mode 100644 index 0000000000..5d54934be8 --- /dev/null +++ b/packages/sandbox/sandbox-local/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "caja de arena de proceso local", + "description": "Proporciona aislamiento de procesos por sistema operativo y limita el alcance de acceso de los comandos." + } +} diff --git a/packages/sandbox/sandbox-local/locale/fr.json b/packages/sandbox/sandbox-local/locale/fr.json new file mode 100644 index 0000000000..ccf1cc74f1 --- /dev/null +++ b/packages/sandbox/sandbox-local/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "bac à sable de processus local", + "description": "Assurer l'isolation des processus par système d'exploitation et limiter la portée d'accès des commandes." + } +} diff --git a/packages/sandbox/sandbox-local/locale/pt.json b/packages/sandbox/sandbox-local/locale/pt.json new file mode 100644 index 0000000000..a76d753273 --- /dev/null +++ b/packages/sandbox/sandbox-local/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "sandbox de processo local", + "description": "Fornece isolamento de processos por sistema operacional e limita o escopo de acesso dos comandos." + } +} diff --git a/packages/sandbox/sandbox-local/locale/ru.json b/packages/sandbox/sandbox-local/locale/ru.json new file mode 100644 index 0000000000..c8a9558071 --- /dev/null +++ b/packages/sandbox/sandbox-local/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "локальная песочница процесса", + "description": "Обеспечьте изоляцию процессов операционной системой и ограничьте область доступа команд." + } +} diff --git a/packages/sandbox/sandbox-policy/locale/de.json b/packages/sandbox/sandbox-policy/locale/de.json new file mode 100644 index 0000000000..4204f3722c --- /dev/null +++ b/packages/sandbox/sandbox-policy/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sandbox-Berechtigungsrichtlinie", + "description": "Bestimmen Sie die Grenzwerte für jeden Vorgang basierend auf dem Berechtigungsmodus und dem Arbeitsbereich der aktuellen Sitzung." + } +} diff --git a/packages/sandbox/sandbox-policy/locale/es.json b/packages/sandbox/sandbox-policy/locale/es.json new file mode 100644 index 0000000000..216e5a3731 --- /dev/null +++ b/packages/sandbox/sandbox-policy/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Política de permisos de zona de pruebas", + "description": "Determine los límites para cada operación según el modo de permiso y el espacio de trabajo de la sesión actual." + } +} diff --git a/packages/sandbox/sandbox-policy/locale/fr.json b/packages/sandbox/sandbox-policy/locale/fr.json new file mode 100644 index 0000000000..c7e817af90 --- /dev/null +++ b/packages/sandbox/sandbox-policy/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Politique d'autorisation du bac à sable", + "description": "Déterminez les limites de chaque opération en fonction du mode d'autorisation et de l'espace de travail de la session en cours." + } +} diff --git a/packages/sandbox/sandbox-policy/locale/pt.json b/packages/sandbox/sandbox-policy/locale/pt.json new file mode 100644 index 0000000000..c16982e153 --- /dev/null +++ b/packages/sandbox/sandbox-policy/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Política de permissão de sandbox", + "description": "Determine os limites para cada operação com base no modo de permissão e no espaço de trabalho da sessão atual." + } +} diff --git a/packages/sandbox/sandbox-policy/locale/ru.json b/packages/sandbox/sandbox-policy/locale/ru.json new file mode 100644 index 0000000000..3e46e2f73b --- /dev/null +++ b/packages/sandbox/sandbox-policy/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Политика разрешений песочницы", + "description": "Определите ограничения для каждой операции на основе режима разрешений и рабочей области текущего сеанса." + } +} diff --git a/packages/sandbox/sandbox/src/locales.ts b/packages/sandbox/sandbox/src/locales.ts index 30fc56d32d..264f9c2dbf 100644 --- a/packages/sandbox/sandbox/src/locales.ts +++ b/packages/sandbox/sandbox/src/locales.ts @@ -15,12 +15,46 @@ export const ja = { escalation: (mode: string, justification: string): string => `${mode} 権限でこの操作を許可します:${justification}`, } satisfies typeof en +/** Spanish dictionary, checked against the English keys. */ +export const es = { + escalation: (mode: string, justification: string): string => `Permite esta operación con permisos ${mode}: ${justification}`, +} satisfies typeof en + +/** French dictionary, checked against the English keys. */ +export const fr = { + escalation: (mode: string, justification: string): string => `Autoriser cette opération avec les permissions ${mode} : ${justification}`, +} satisfies typeof en + +/** German dictionary, checked against the English keys. */ +export const de = { + escalation: (mode: string, justification: string): string => `Diesen Vorgang mit ${mode}-Berechtigungen zulassen: ${justification}`, +} satisfies typeof en + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + escalation: (mode: string, justification: string): string => `Разрешить эту операцию с правами ${mode}: ${justification}`, +} satisfies typeof en + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + escalation: (mode: string, justification: string): string => `Permitir esta operação com permissões ${mode}: ${justification}`, +} satisfies typeof en + /** * Build translations for the existing Client localized-text resolver. * @param mode - requested sandbox mode. * @param justification - raw model justification, preserved in every translation. * @returns localized approval text. */ -export function escalationDisplayReason(mode: string, justification: string): Record<'en' | 'zh' | 'ja', string> { - return { en: en.escalation(mode, justification), zh: zh.escalation(mode, justification), ja: ja.escalation(mode, justification) } +export function escalationDisplayReason(mode: string, justification: string): Record<'en' | 'zh' | 'ja' | 'es' | 'fr' | 'de' | 'ru' | 'pt', string> { + return { + en: en.escalation(mode, justification), + zh: zh.escalation(mode, justification), + ja: ja.escalation(mode, justification), + es: es.escalation(mode, justification), + fr: fr.escalation(mode, justification), + de: de.escalation(mode, justification), + ru: ru.escalation(mode, justification), + pt: pt.escalation(mode, justification), + } } diff --git a/packages/schedule/schedule/locale/de.json b/packages/schedule/schedule/locale/de.json new file mode 100644 index 0000000000..7372ecb6b8 --- /dev/null +++ b/packages/schedule/schedule/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Aufgabenplanung", + "description": "Speichert Automatisierungsaufgaben, führt jede bei Fälligkeit in ihrer ursprünglichen Sitzung aus und stellt dem Agenten Tools zur Verwaltung bereit." + } +} diff --git a/packages/schedule/schedule/locale/es.json b/packages/schedule/schedule/locale/es.json new file mode 100644 index 0000000000..1a58bc20c4 --- /dev/null +++ b/packages/schedule/schedule/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Programación de tareas", + "description": "Almacena tareas de automatización, ejecuta cada una en su sesión original cuando corresponde y brinda al agente herramientas para administrarlas." + } +} diff --git a/packages/schedule/schedule/locale/fr.json b/packages/schedule/schedule/locale/fr.json new file mode 100644 index 0000000000..8880b37b09 --- /dev/null +++ b/packages/schedule/schedule/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Planification des tâches", + "description": "Stocke les tâches d'automatisation, les exécute chacune dans sa session d'origine lorsqu'elle est due et donne à l'agent les outils pour les gérer." + } +} diff --git a/packages/schedule/schedule/locale/pt.json b/packages/schedule/schedule/locale/pt.json new file mode 100644 index 0000000000..87663d82de --- /dev/null +++ b/packages/schedule/schedule/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Agendamento de tarefas", + "description": "Armazena tarefas de automação, executa cada uma em sua sessão original no momento devido e fornece ao agente ferramentas para gerenciá-las." + } +} diff --git a/packages/schedule/schedule/locale/ru.json b/packages/schedule/schedule/locale/ru.json new file mode 100644 index 0000000000..2564032655 --- /dev/null +++ b/packages/schedule/schedule/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Планирование задач", + "description": "Сохраняет задачи автоматизации, запускает каждую из них в исходном сеансе, когда наступает срок, и предоставляет агенту инструменты для управления ими." + } +} diff --git a/packages/schedule/tool-schedule/locale/de.json b/packages/schedule/tool-schedule/locale/de.json new file mode 100644 index 0000000000..5dbca5d0c9 --- /dev/null +++ b/packages/schedule/tool-schedule/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Planungstools", + "description": "Automatisierte Aufgaben erstellen, anzeigen, aktualisieren und löschen." + } +} diff --git a/packages/schedule/tool-schedule/locale/es.json b/packages/schedule/tool-schedule/locale/es.json new file mode 100644 index 0000000000..e9826486a1 --- /dev/null +++ b/packages/schedule/tool-schedule/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramientas de programación", + "description": "Cree, vea, actualice y elimine tareas automatizadas." + } +} diff --git a/packages/schedule/tool-schedule/locale/fr.json b/packages/schedule/tool-schedule/locale/fr.json new file mode 100644 index 0000000000..50c6542e07 --- /dev/null +++ b/packages/schedule/tool-schedule/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outils de planification", + "description": "Créez, affichez, mettez à jour et supprimez des tâches automatisées." + } +} diff --git a/packages/schedule/tool-schedule/locale/pt.json b/packages/schedule/tool-schedule/locale/pt.json new file mode 100644 index 0000000000..8147294809 --- /dev/null +++ b/packages/schedule/tool-schedule/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramentas de agendamento", + "description": "Crie, visualize, atualize e exclua tarefas automatizadas." + } +} diff --git a/packages/schedule/tool-schedule/locale/ru.json b/packages/schedule/tool-schedule/locale/ru.json new file mode 100644 index 0000000000..1b324fc1ff --- /dev/null +++ b/packages/schedule/tool-schedule/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Инструменты планирования", + "description": "Создавайте, просматривайте, обновляйте и удаляйте автоматизированные задачи." + } +} diff --git a/packages/sdk/server/locale/de.json b/packages/sdk/server/locale/de.json new file mode 100644 index 0000000000..da5759d212 --- /dev/null +++ b/packages/sdk/server/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "SDK-Server", + "description": "Bedienen Sie SDK-Clients in separaten Prozessen über JSON-RPC über Standardeingabe und -ausgabe." + } +} diff --git a/packages/sdk/server/locale/es.json b/packages/sdk/server/locale/es.json new file mode 100644 index 0000000000..ff7083b3ba --- /dev/null +++ b/packages/sdk/server/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "servidor SDK", + "description": "Atienda a los clientes SDK en procesos separados a través de JSON-RPC a través de entrada y salida estándar." + } +} diff --git a/packages/sdk/server/locale/fr.json b/packages/sdk/server/locale/fr.json new file mode 100644 index 0000000000..8b46124826 --- /dev/null +++ b/packages/sdk/server/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Serveur SDK", + "description": "Servez les clients SDK dans des processus distincts via JSON-RPC via une entrée et une sortie standard." + } +} diff --git a/packages/sdk/server/locale/pt.json b/packages/sdk/server/locale/pt.json new file mode 100644 index 0000000000..87f0f91663 --- /dev/null +++ b/packages/sdk/server/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "SDK servidor", + "description": "Atenda SDK clientes em processos separados por meio de JSON-RPC em entrada e saída padrão." + } +} diff --git a/packages/sdk/server/locale/ru.json b/packages/sdk/server/locale/ru.json new file mode 100644 index 0000000000..6dff6a9b74 --- /dev/null +++ b/packages/sdk/server/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "SDK сервер", + "description": "Обслуживайте клиентов SDK в отдельных процессах через JSON-RPC через стандартный ввод и вывод." + } +} diff --git a/packages/session-query/session-log-export/locale/de.json b/packages/session-query/session-log-export/locale/de.json new file mode 100644 index 0000000000..dd6f6875f7 --- /dev/null +++ b/packages/session-query/session-log-export/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Export des Sitzungsprotokolls", + "description": "Bietet Befehle zum Exportieren von Sitzungsprotokollen und Downloadfunktionen." + } +} diff --git a/packages/session-query/session-log-export/locale/es.json b/packages/session-query/session-log-export/locale/es.json new file mode 100644 index 0000000000..43bda6d0c8 --- /dev/null +++ b/packages/session-query/session-log-export/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Exportación del registro de sesión", + "description": "Proporciona comandos de exportación de registros de sesión y funciones de descarga." + } +} diff --git a/packages/session-query/session-log-export/locale/fr.json b/packages/session-query/session-log-export/locale/fr.json new file mode 100644 index 0000000000..778ac4e987 --- /dev/null +++ b/packages/session-query/session-log-export/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Exportation du journal de session", + "description": "Fournit des commandes d’exportation de journaux de session et des fonctions de téléchargement." + } +} diff --git a/packages/session-query/session-log-export/locale/pt.json b/packages/session-query/session-log-export/locale/pt.json new file mode 100644 index 0000000000..915afc0240 --- /dev/null +++ b/packages/session-query/session-log-export/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Exportação de log de sessão", + "description": "Fornece comandos de exportação de log de sessão e funções de download." + } +} diff --git a/packages/session-query/session-log-export/locale/ru.json b/packages/session-query/session-log-export/locale/ru.json new file mode 100644 index 0000000000..b5dc30765a --- /dev/null +++ b/packages/session-query/session-log-export/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Экспорт журнала сеансов", + "description": "Предоставляет команды экспорта журнала сеанса и функции загрузки." + } +} diff --git a/packages/session-query/session-log-export/src/client/index.ts b/packages/session-query/session-log-export/src/client/index.ts index 24a274bc58..74808d1751 100644 --- a/packages/session-query/session-log-export/src/client/index.ts +++ b/packages/session-query/session-log-export/src/client/index.ts @@ -13,7 +13,7 @@ import { SessionLogDownloadController } from './controller.ts' import { SessionMarkdownCopyController } from './copy-controller.ts' import { SessionMarkdownCopyToast, type SessionMarkdownCopyToastInjected } from './CopyToast.tsx' import { SessionLogDownloadHeaderAction, type SessionLogDownloadHeaderInjected } from './HeaderAction.tsx' -import { en, ja, NS, zh, type SessionLogDownloadKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, NS, zh, type SessionLogDownloadKey } from './locales.ts' declare module '@deepseek-ai/cordis' { interface Context { @@ -42,7 +42,7 @@ export function apply(ctx: ClientContext): void { ctx.provide('sessionLogDownload', controller) ctx.effect(() => async () => { await controller.dispose() }, 'session-log-download: browser download lifecycle') ctx.effect(() => async () => { await copyController.dispose() }, 'session-log-download: browser Markdown copy lifecycle') - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'session-log-download: browser dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'session-log-download: browser dictionaries') const feedbackAvailable = createSnapshotStore(false) ctx.inject(['feedbackUi'], (scope: ClientContext) => { scope.effect(() => { diff --git a/packages/session-query/session-log-export/src/client/locales.ts b/packages/session-query/session-log-export/src/client/locales.ts index b3bb8ba6e2..40e3007aa1 100644 --- a/packages/session-query/session-log-export/src/client/locales.ts +++ b/packages/session-query/session-log-export/src/client/locales.ts @@ -57,3 +57,93 @@ export const ja = { 'dialog.close': '閉じる', 'dialog.commandFailed': 'セッションのエクスポートを開始できませんでした。', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'header.more': 'Más acciones', + 'menu.copyMarkdown': 'Copiar sesión como Markdown', + 'menu.download': 'Descargar registro de sesión', + 'menu.feedback': 'Comentarios', + 'toast.copied': 'Sesión copiada como Markdown.', + 'toast.preparationFailed': 'No se pudo leer la sesión para copiarla. Intentar otra vez.', + 'toast.clipboardFailed': 'No se pudo escribir en el portapapeles. Verifique los permisos del portapapeles e inténtelo nuevamente.', + 'dialog.preparingTitle': 'Sesión de exportación', + 'dialog.preparingDescription': 'Preparar un ZIP que contenga esta Sesión, sus subsesiones y archivos adjuntos.', + 'dialog.successTitle': 'Descarga de sesión iniciada', + 'dialog.successDescription': 'El navegador está descargando el ZIP de la sesión.', + 'dialog.errorTitle': 'Error al exportar la sesión', + 'dialog.close': 'Cerrar', + 'dialog.commandFailed': 'No se pudo iniciar la exportación de la sesión.', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'header.more': 'Plus de propositions', + 'menu.copyMarkdown': 'Copier la session sous Markdown', + 'menu.download': 'Télécharger le journal de session', + 'menu.feedback': 'Commentaires', + 'toast.copied': 'Session copiée sous le nom Markdown.', + 'toast.preparationFailed': 'Impossible de lire la session pour la copier. Essayer à nouveau.', + 'toast.clipboardFailed': "Impossible d'écrire dans le presse-papiers. Vérifiez l'autorisation du presse-papiers et réessayez.", + 'dialog.preparingTitle': "Session d'exportation", + 'dialog.preparingDescription': "Préparation d'un ZIP contenant cette session, ses sous-sessions et les pièces jointes.", + 'dialog.successTitle': 'Le téléchargement de la session a commencé', + 'dialog.successDescription': 'Le navigateur télécharge le ZIP de la session.', + 'dialog.errorTitle': "Échec de l'exportation de la session", + 'dialog.close': 'Fermer', + 'dialog.commandFailed': "Impossible de démarrer l'exportation de session.", +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'header.more': 'Weitere Aktionen', + 'menu.copyMarkdown': 'Kopieren Sie die Sitzung als Markdown', + 'menu.download': 'Sitzungsprotokoll herunterladen', + 'menu.feedback': 'Rückmeldung', + 'toast.copied': 'Sitzung als Markdown kopiert.', + 'toast.preparationFailed': 'Die Sitzung zum Kopieren konnte nicht gelesen werden. Versuchen Sie es erneut.', + 'toast.clipboardFailed': 'Es konnte nicht in die Zwischenablage geschrieben werden. Überprüfen Sie die Berechtigung für die Zwischenablage und versuchen Sie es erneut.', + 'dialog.preparingTitle': 'Sitzung exportieren', + 'dialog.preparingDescription': 'Vorbereiten einer ZIP-Datei mit dieser Sitzung, ihren Untersitzungen und Anhängen.', + 'dialog.successTitle': 'Sitzungsdownload gestartet', + 'dialog.successDescription': 'Der Browser lädt die Sitzungs-ZIP herunter.', + 'dialog.errorTitle': 'Der Sitzungsexport ist fehlgeschlagen', + 'dialog.close': 'Schließen', + 'dialog.commandFailed': 'Der Sitzungsexport konnte nicht gestartet werden.', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'header.more': 'Дополнительные действия', + 'menu.copyMarkdown': 'Скопировать сеанс как Markdown', + 'menu.download': 'Скачать журнал сеанса', + 'menu.feedback': 'Обратная связь', + 'toast.copied': 'Сессия скопирована как Markdown.', + 'toast.preparationFailed': 'Не удалось прочитать сеанс для копирования. Попробуйте еще раз.', + 'toast.clipboardFailed': 'Не удалось записать в буфер обмена. Проверьте разрешение буфера обмена и повторите попытку.', + 'dialog.preparingTitle': 'Экспорт сеанса', + 'dialog.preparingDescription': 'Подготовка ZIP-файла, содержащего этот сеанс, его подсеансы и вложения.', + 'dialog.successTitle': 'Загрузка сеанса началась', + 'dialog.successDescription': 'Браузер загружает ZIP-файл сеанса.', + 'dialog.errorTitle': 'Экспорт сеанса не удался', + 'dialog.close': 'Закрыть', + 'dialog.commandFailed': 'Не удалось начать экспорт сеанса.', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'header.more': 'Mais ações', + 'menu.copyMarkdown': 'Copiar sessão como Markdown', + 'menu.download': 'Baixar registro da sessão', + 'menu.feedback': 'Comentários', + 'toast.copied': 'Sessão copiada como Markdown.', + 'toast.preparationFailed': 'Não foi possível ler a sessão para cópia. Tente novamente.', + 'toast.clipboardFailed': 'Não foi possível gravar na área de transferência. Verifique a permissão da área de transferência e tente novamente.', + 'dialog.preparingTitle': 'Exportando Sessão', + 'dialog.preparingDescription': 'Preparando um ZIP contendo esta Sessão, suas subsessões e anexos.', + 'dialog.successTitle': 'Download da sessão iniciado', + 'dialog.successDescription': 'O navegador está baixando o ZIP da sessão.', + 'dialog.errorTitle': 'Falha na exportação da sessão', + 'dialog.close': 'Fechar', + 'dialog.commandFailed': 'Não foi possível iniciar a exportação da sessão.', +} satisfies Record diff --git a/packages/session-query/session-query-sqlite/locale/de.json b/packages/session-query/session-query-sqlite/locale/de.json new file mode 100644 index 0000000000..b8c1f3d54b --- /dev/null +++ b/packages/session-query/session-query-sqlite/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Konversationsabfragen und -suchen", + "description": "Fragen Sie Sitzungsdatensätze ab und stellen Sie eine Volltextsuche für SQLite bereit, wenn diese in der Konfiguration aktiviert ist." + } +} diff --git a/packages/session-query/session-query-sqlite/locale/es.json b/packages/session-query/session-query-sqlite/locale/es.json new file mode 100644 index 0000000000..42dcab6091 --- /dev/null +++ b/packages/session-query/session-query-sqlite/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Consultas y búsquedas conversacionales", + "description": "Consulta registros de sesión y proporciona búsqueda de texto completo para SQLite cuando esté habilitado en la configuración." + } +} diff --git a/packages/session-query/session-query-sqlite/locale/fr.json b/packages/session-query/session-query-sqlite/locale/fr.json new file mode 100644 index 0000000000..06a9eee96d --- /dev/null +++ b/packages/session-query/session-query-sqlite/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Requêtes et recherches conversationnelles", + "description": "Interrogez les enregistrements de session et effectuez une recherche en texte intégral pour SQLite lorsqu'elle est activée dans la configuration." + } +} diff --git a/packages/session-query/session-query-sqlite/locale/pt.json b/packages/session-query/session-query-sqlite/locale/pt.json new file mode 100644 index 0000000000..c2aa6831fd --- /dev/null +++ b/packages/session-query/session-query-sqlite/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Consultas e pesquisas conversacionais", + "description": "Consulte registros de sessão e forneça pesquisa de texto completo para SQLite quando ativado na configuração." + } +} diff --git a/packages/session-query/session-query-sqlite/locale/ru.json b/packages/session-query/session-query-sqlite/locale/ru.json new file mode 100644 index 0000000000..738e088466 --- /dev/null +++ b/packages/session-query/session-query-sqlite/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Разговорные запросы и поиски", + "description": "Запрашивать записи сеансов и обеспечивать полнотекстовый поиск для SQLite, если это разрешено в конфигурации." + } +} diff --git a/packages/session/message-quotes/locale/de.json b/packages/session/message-quotes/locale/de.json new file mode 100644 index 0000000000..48aa810c81 --- /dev/null +++ b/packages/session/message-quotes/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Nachrichtenzitate", + "description": "Ausgewählten Text zitieren und als Markdown-Blockzitat anzeigen." + } +} diff --git a/packages/session/message-quotes/locale/es.json b/packages/session/message-quotes/locale/es.json new file mode 100644 index 0000000000..f0b791f4f2 --- /dev/null +++ b/packages/session/message-quotes/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Citas de mensajes", + "description": "Cita el texto seleccionado y muéstralo como una cita en bloque Markdown." + } +} diff --git a/packages/session/message-quotes/locale/fr.json b/packages/session/message-quotes/locale/fr.json new file mode 100644 index 0000000000..64b38b5a5f --- /dev/null +++ b/packages/session/message-quotes/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Citations de messages", + "description": "Citez le texte sélectionné et affichez-le sous forme de citation en bloc Markdown." + } +} diff --git a/packages/session/message-quotes/locale/pt.json b/packages/session/message-quotes/locale/pt.json new file mode 100644 index 0000000000..dbc3dcb4d4 --- /dev/null +++ b/packages/session/message-quotes/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Citações de mensagens", + "description": "Cite o texto selecionado e exiba-o como uma citação em bloco Markdown." + } +} diff --git a/packages/session/message-quotes/locale/ru.json b/packages/session/message-quotes/locale/ru.json new file mode 100644 index 0000000000..2328853e75 --- /dev/null +++ b/packages/session/message-quotes/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Цитаты сообщений", + "description": "Цитируйте выделенный текст и отображайте его как блочную цитату Markdown." + } +} diff --git a/packages/session/message-quotes/src/client/index.ts b/packages/session/message-quotes/src/client/index.ts index b0748db925..e7a9348052 100644 --- a/packages/session/message-quotes/src/client/index.ts +++ b/packages/session/message-quotes/src/client/index.ts @@ -8,7 +8,7 @@ import type {} from '@deepseek-ai/dsh-client-ui-renderer/client' import { QuoteSelectionAction } from './QuoteSelection.tsx' import { QuotedUserText } from './QuotedUserText.tsx' import { quoteRule } from './quote-rule.ts' -import { en, ja, NS, zh, type MessageQuotesKey } from './locales.ts' +import { en, ja, es, fr, de, ru, pt, NS, zh, type MessageQuotesKey } from './locales.ts' export type {} from './quote-rule.ts' @@ -30,7 +30,7 @@ export const inject = ['slots', 'locale', 'sessions', 'uiConversation'] * @param ctx - Client root context owning every Quote contribution. */ export function apply(ctx: Context): void { - ctx.effect(() => ctx.locale.register(NS, { zh, en, ja }), 'message-quotes: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'message-quotes: dictionaries') ctx.effect(() => ctx.uiConversation.userText.register(quoteRule), 'message-quotes: UserText rule') ctx.effect(() => ctx.uiConversation.interactions.register({ id: 'quote', diff --git a/packages/session/message-quotes/src/client/locales.ts b/packages/session/message-quotes/src/client/locales.ts index fab1fbc782..4d704e803e 100644 --- a/packages/session/message-quotes/src/client/locales.ts +++ b/packages/session/message-quotes/src/client/locales.ts @@ -20,3 +20,28 @@ export const en: Record = { export const ja = { 'quote.add': 'テキストを引用', } satisfies Record + +/** Spanish dictionary, checked against the English keys. */ +export const es = { + 'quote.add': 'Texto de cotización', +} satisfies Record + +/** French dictionary, checked against the English keys. */ +export const fr = { + 'quote.add': 'Texte de citation', +} satisfies Record + +/** German dictionary, checked against the English keys. */ +export const de = { + 'quote.add': 'Zitattext', +} satisfies Record + +/** Russian dictionary, checked against the English keys. */ +export const ru = { + 'quote.add': 'Текст цитаты', +} satisfies Record + +/** Portuguese dictionary, checked against the English keys. */ +export const pt = { + 'quote.add': 'Citação de texto', +} satisfies Record diff --git a/packages/session/session-checkpoint-policy/locale/de.json b/packages/session/session-checkpoint-policy/locale/de.json new file mode 100644 index 0000000000..5b13ebeec2 --- /dev/null +++ b/packages/session/session-checkpoint-policy/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sitzungskontrollpunkt", + "description": "Speichern Sie Sitzungsaufzeichnungen vor Modellanfragen und Werkzeugoperationen, die externe Auswirkungen haben können." + } +} diff --git a/packages/session/session-checkpoint-policy/locale/es.json b/packages/session/session-checkpoint-policy/locale/es.json new file mode 100644 index 0000000000..8b61a9f9ad --- /dev/null +++ b/packages/session/session-checkpoint-policy/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "punto de control de sesión", + "description": "Guarde registros de sesión antes de solicitudes de modelo y operaciones de herramientas que puedan tener efectos externos." + } +} diff --git a/packages/session/session-checkpoint-policy/locale/fr.json b/packages/session/session-checkpoint-policy/locale/fr.json new file mode 100644 index 0000000000..c613619b69 --- /dev/null +++ b/packages/session/session-checkpoint-policy/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "point de contrôle de session", + "description": "Enregistrez les enregistrements de session avant les demandes de modèle et les opérations d'outils pouvant avoir des effets externes." + } +} diff --git a/packages/session/session-checkpoint-policy/locale/pt.json b/packages/session/session-checkpoint-policy/locale/pt.json new file mode 100644 index 0000000000..dba8d19214 --- /dev/null +++ b/packages/session/session-checkpoint-policy/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "ponto de verificação de sessão", + "description": "Salve registros de sessão antes de solicitações de modelo e operações de ferramentas que possam ter efeitos externos." + } +} diff --git a/packages/session/session-checkpoint-policy/locale/ru.json b/packages/session/session-checkpoint-policy/locale/ru.json new file mode 100644 index 0000000000..bcd5e5cbc4 --- /dev/null +++ b/packages/session/session-checkpoint-policy/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "контрольная точка сеанса", + "description": "Сохраняйте записи сеансов перед запросами модели и операциями инструмента, которые могут иметь внешние последствия." + } +} diff --git a/packages/session/session-log-deepseek/locale/de.json b/packages/session/session-log-deepseek/locale/de.json new file mode 100644 index 0000000000..63fc6088ed --- /dev/null +++ b/packages/session/session-log-deepseek/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Hochladen des Sitzungsprotokolls", + "description": "Wenn diese Option aktiviert ist, werden Sitzungsprotokolle mit offiziellen Modell-API-Anfragen auf DeepSeek hochgeladen." + } +} diff --git a/packages/session/session-log-deepseek/locale/es.json b/packages/session/session-log-deepseek/locale/es.json new file mode 100644 index 0000000000..0b2e78a1d0 --- /dev/null +++ b/packages/session/session-log-deepseek/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Carga del registro de sesión", + "description": "Cuando está habilitado, los registros de sesión se cargan en DeepSeek con las solicitudes del modelo oficial API." + } +} diff --git a/packages/session/session-log-deepseek/locale/fr.json b/packages/session/session-log-deepseek/locale/fr.json new file mode 100644 index 0000000000..4fa490600e --- /dev/null +++ b/packages/session/session-log-deepseek/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Importation du journal de session", + "description": "Lorsqu'ils sont activés, les journaux de session sont téléchargés sur DeepSeek avec les requêtes officielles du modèle API." + } +} diff --git a/packages/session/session-log-deepseek/locale/pt.json b/packages/session/session-log-deepseek/locale/pt.json new file mode 100644 index 0000000000..2994499019 --- /dev/null +++ b/packages/session/session-log-deepseek/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Upload do registro da sessão", + "description": "Quando ativado, os logs de sessão são enviados para DeepSeek com solicitações de modelo oficial API." + } +} diff --git a/packages/session/session-log-deepseek/locale/ru.json b/packages/session/session-log-deepseek/locale/ru.json new file mode 100644 index 0000000000..0edc0c68e2 --- /dev/null +++ b/packages/session/session-log-deepseek/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Загрузка журнала сеанса", + "description": "Если этот параметр включен, журналы сеансов загружаются в DeepSeek с официальными запросами модели API." + } +} diff --git a/packages/session/session-persistence-jsonl/locale/de.json b/packages/session/session-persistence-jsonl/locale/de.json new file mode 100644 index 0000000000..e9364fe853 --- /dev/null +++ b/packages/session/session-persistence-jsonl/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Persistenz des Sitzungsprotokolls", + "description": "Speichern Sie das Sitzungsprotokoll als lokale JSONL-Datei zur späteren Wiederherstellung und zum Lesen." + } +} diff --git a/packages/session/session-persistence-jsonl/locale/es.json b/packages/session/session-persistence-jsonl/locale/es.json new file mode 100644 index 0000000000..804584df34 --- /dev/null +++ b/packages/session/session-persistence-jsonl/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Persistencia del registro de sesión", + "description": "Guarde el registro de la sesión como un archivo JSONL local para recuperarlo y leerlo más adelante." + } +} diff --git a/packages/session/session-persistence-jsonl/locale/fr.json b/packages/session/session-persistence-jsonl/locale/fr.json new file mode 100644 index 0000000000..5b0f0469dc --- /dev/null +++ b/packages/session/session-persistence-jsonl/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Persistance du journal de session", + "description": "Enregistrez le journal de session en tant que fichier JSONL local pour une récupération et une lecture ultérieures." + } +} diff --git a/packages/session/session-persistence-jsonl/locale/pt.json b/packages/session/session-persistence-jsonl/locale/pt.json new file mode 100644 index 0000000000..ffd45b219a --- /dev/null +++ b/packages/session/session-persistence-jsonl/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Persistência do log de sessão", + "description": "Salve o log da sessão como um arquivo JSONL local para recuperação e leitura posterior." + } +} diff --git a/packages/session/session-persistence-jsonl/locale/ru.json b/packages/session/session-persistence-jsonl/locale/ru.json new file mode 100644 index 0000000000..78c81474c9 --- /dev/null +++ b/packages/session/session-persistence-jsonl/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Сохранение журнала сеанса", + "description": "Сохраните журнал сеанса как локальный файл JSONL для последующего восстановления и чтения." + } +} diff --git a/packages/session/session-projection-cache/locale/de.json b/packages/session/session-projection-cache/locale/de.json new file mode 100644 index 0000000000..8b02f0352f --- /dev/null +++ b/packages/session/session-projection-cache/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sitzungsstatus-Cache", + "description": "Aus Sitzungsprotokollen generierter Cache-Status zum schnellen Lesen durch Funktionen wie Sitzungslisten." + } +} diff --git a/packages/session/session-projection-cache/locale/es.json b/packages/session/session-projection-cache/locale/es.json new file mode 100644 index 0000000000..cc8243b87d --- /dev/null +++ b/packages/session/session-projection-cache/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "caché de estado de sesión", + "description": "Estado de caché generado a partir de registros de sesión para una lectura rápida mediante funciones como listas de sesiones." + } +} diff --git a/packages/session/session-projection-cache/locale/fr.json b/packages/session/session-projection-cache/locale/fr.json new file mode 100644 index 0000000000..5f4e5f7727 --- /dev/null +++ b/packages/session/session-projection-cache/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "cache d'état de session", + "description": "État du cache généré à partir des journaux de session pour une lecture rapide grâce à des fonctionnalités telles que les listes de sessions." + } +} diff --git a/packages/session/session-projection-cache/locale/pt.json b/packages/session/session-projection-cache/locale/pt.json new file mode 100644 index 0000000000..49023a60c2 --- /dev/null +++ b/packages/session/session-projection-cache/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "cache de estado de sessão", + "description": "Status do cache gerado a partir de logs de sessão para leitura rápida por recursos como listas de sessões." + } +} diff --git a/packages/session/session-projection-cache/locale/ru.json b/packages/session/session-projection-cache/locale/ru.json new file mode 100644 index 0000000000..394d979159 --- /dev/null +++ b/packages/session/session-projection-cache/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "кэш состояния сеанса", + "description": "Статус кэша генерируется из журналов сеансов для быстрого чтения с помощью таких функций, как списки сеансов." + } +} diff --git a/packages/session/session-projection/locale/de.json b/packages/session/session-projection/locale/de.json new file mode 100644 index 0000000000..a22b85d831 --- /dev/null +++ b/packages/session/session-projection/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Zusammenfassung des Sitzungsstatus", + "description": "Generieren Sie Titel, Status und andere Informationen aus dem Sitzungsprotokoll, damit andere Funktionen sie lesen können." + } +} diff --git a/packages/session/session-projection/locale/es.json b/packages/session/session-projection/locale/es.json new file mode 100644 index 0000000000..f07ebe1afb --- /dev/null +++ b/packages/session/session-projection/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Resumen del estado de la sesión", + "description": "Genere título, estado y otra información a partir del registro de sesión para que otras funciones lo lean." + } +} diff --git a/packages/session/session-projection/locale/fr.json b/packages/session/session-projection/locale/fr.json new file mode 100644 index 0000000000..fdbe841c2c --- /dev/null +++ b/packages/session/session-projection/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Résumé de l'état de la session", + "description": "Générez un titre, un statut et d'autres informations à partir du journal de session pour que d'autres fonctions puissent les lire." + } +} diff --git a/packages/session/session-projection/locale/pt.json b/packages/session/session-projection/locale/pt.json new file mode 100644 index 0000000000..58348778d7 --- /dev/null +++ b/packages/session/session-projection/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Resumo do estado da sessão", + "description": "Gere título, status e outras informações do log da sessão para leitura de outras funções." + } +} diff --git a/packages/session/session-projection/locale/ru.json b/packages/session/session-projection/locale/ru.json new file mode 100644 index 0000000000..5ebf25fed0 --- /dev/null +++ b/packages/session/session-projection/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Сводка состояния сеанса", + "description": "Генерируйте заголовок, статус и другую информацию из журнала сеанса для чтения другими функциями." + } +} diff --git a/packages/session/session-stats/locale/de.json b/packages/session/session-stats/locale/de.json new file mode 100644 index 0000000000..46e161509d --- /dev/null +++ b/packages/session/session-stats/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sitzungsstatistiken", + "description": "Fassen Sie statistische Informationen wie die Anzahl der Interaktionen und die für die Sitzung aufgewendete Zeit zusammen." + } +} diff --git a/packages/session/session-stats/locale/es.json b/packages/session/session-stats/locale/es.json new file mode 100644 index 0000000000..c3dc7b9847 --- /dev/null +++ b/packages/session/session-stats/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "estadísticas de sesión", + "description": "Resuma información estadística como el número de interacciones y el tiempo dedicado a la sesión." + } +} diff --git a/packages/session/session-stats/locale/fr.json b/packages/session/session-stats/locale/fr.json new file mode 100644 index 0000000000..98673c0a2c --- /dev/null +++ b/packages/session/session-stats/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "statistiques de session", + "description": "Résumez les informations statistiques telles que le nombre d’interactions et le temps passé sur la session." + } +} diff --git a/packages/session/session-stats/locale/pt.json b/packages/session/session-stats/locale/pt.json new file mode 100644 index 0000000000..6b2662b4a2 --- /dev/null +++ b/packages/session/session-stats/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "estatísticas da sessão", + "description": "Resuma informações estatísticas, como o número de interações e o tempo gasto na sessão." + } +} diff --git a/packages/session/session-stats/locale/ru.json b/packages/session/session-stats/locale/ru.json new file mode 100644 index 0000000000..dc47e10796 --- /dev/null +++ b/packages/session/session-stats/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "статистика сеанса", + "description": "Суммируйте статистическую информацию, такую как количество взаимодействий и время, потраченное на сеанс." + } +} diff --git a/packages/session/session-telemetry-otel/locale/de.json b/packages/session/session-telemetry-otel/locale/de.json new file mode 100644 index 0000000000..9e22befeba --- /dev/null +++ b/packages/session/session-telemetry-otel/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Hochladen des Feedback-Sitzungsprotokolls", + "description": "Gemäß der Feedback-Autorisierungsrichtlinie werden relevante Sitzungsprotokolle über OpenTelemetry hochgeladen." + } +} diff --git a/packages/session/session-telemetry-otel/locale/es.json b/packages/session/session-telemetry-otel/locale/es.json new file mode 100644 index 0000000000..56e8806e85 --- /dev/null +++ b/packages/session/session-telemetry-otel/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Carga del registro de sesión de comentarios", + "description": "De acuerdo con la política de autorización de comentarios, los registros de sesiones relevantes se cargan a través de OpenTelemetry." + } +} diff --git a/packages/session/session-telemetry-otel/locale/fr.json b/packages/session/session-telemetry-otel/locale/fr.json new file mode 100644 index 0000000000..915e4f13f7 --- /dev/null +++ b/packages/session/session-telemetry-otel/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Téléchargement du journal de la session de commentaires", + "description": "Conformément à la politique d'autorisation des commentaires, les journaux de session pertinents sont téléchargés via OpenTelemetry." + } +} diff --git a/packages/session/session-telemetry-otel/locale/pt.json b/packages/session/session-telemetry-otel/locale/pt.json new file mode 100644 index 0000000000..8a686dc3c3 --- /dev/null +++ b/packages/session/session-telemetry-otel/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Upload do log da sessão de feedback", + "description": "De acordo com a política de autorização de feedback, os logs de sessão relevantes são carregados por meio do OpenTelemetry." + } +} diff --git a/packages/session/session-telemetry-otel/locale/ru.json b/packages/session/session-telemetry-otel/locale/ru.json new file mode 100644 index 0000000000..37924923d0 --- /dev/null +++ b/packages/session/session-telemetry-otel/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Загрузка журнала сеанса обратной связи", + "description": "В соответствии с политикой авторизации обратной связи соответствующие журналы сеансов загружаются через OpenTelemetry." + } +} diff --git a/packages/session/session-title-first-prompt-llm/locale/de.json b/packages/session/session-title-first-prompt-llm/locale/de.json new file mode 100644 index 0000000000..3d88a2f920 --- /dev/null +++ b/packages/session/session-title-first-prompt-llm/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Die erste Nachricht generiert einen Titel", + "description": "Verwenden Sie ein Modell, um einen Titel basierend auf der ersten Nachricht in der Konversation zu generieren." + } +} diff --git a/packages/session/session-title-first-prompt-llm/locale/es.json b/packages/session/session-title-first-prompt-llm/locale/es.json new file mode 100644 index 0000000000..0b0fb294b9 --- /dev/null +++ b/packages/session/session-title-first-prompt-llm/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "El primer mensaje genera título.", + "description": "Utilice un modelo para generar un título basado en el primer mensaje de la conversación." + } +} diff --git a/packages/session/session-title-first-prompt-llm/locale/fr.json b/packages/session/session-title-first-prompt-llm/locale/fr.json new file mode 100644 index 0000000000..bc8c6ccc2a --- /dev/null +++ b/packages/session/session-title-first-prompt-llm/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Le premier message génère un titre", + "description": "Utilisez un modèle pour générer un titre basé sur le premier message de la conversation." + } +} diff --git a/packages/session/session-title-first-prompt-llm/locale/pt.json b/packages/session/session-title-first-prompt-llm/locale/pt.json new file mode 100644 index 0000000000..03b4a9ea9d --- /dev/null +++ b/packages/session/session-title-first-prompt-llm/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "A primeira mensagem gera título", + "description": "Use um modelo para gerar um título com base na primeira mensagem da conversa." + } +} diff --git a/packages/session/session-title-first-prompt-llm/locale/ru.json b/packages/session/session-title-first-prompt-llm/locale/ru.json new file mode 100644 index 0000000000..78f8c05444 --- /dev/null +++ b/packages/session/session-title-first-prompt-llm/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Первое сообщение генерирует заголовок", + "description": "Используйте модель для создания заголовка на основе первого сообщения в разговоре." + } +} diff --git a/packages/session/session-title/locale/de.json b/packages/session/session-title/locale/de.json new file mode 100644 index 0000000000..7b191b67e0 --- /dev/null +++ b/packages/session/session-title/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sitzungstitelservice", + "description": "Speichern und lesen Sie Sitzungstitel und verwalten Sie, wie Titel generiert werden." + } +} diff --git a/packages/session/session-title/locale/es.json b/packages/session/session-title/locale/es.json new file mode 100644 index 0000000000..9bc2e18b5a --- /dev/null +++ b/packages/session/session-title/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "servicio de título de sesión", + "description": "Guarde y lea títulos de sesiones y administre cómo se generan los títulos." + } +} diff --git a/packages/session/session-title/locale/fr.json b/packages/session/session-title/locale/fr.json new file mode 100644 index 0000000000..be8310d404 --- /dev/null +++ b/packages/session/session-title/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "service de titre de session", + "description": "Enregistrez et lisez les titres de session et gérez la manière dont les titres sont générés." + } +} diff --git a/packages/session/session-title/locale/pt.json b/packages/session/session-title/locale/pt.json new file mode 100644 index 0000000000..081c55a803 --- /dev/null +++ b/packages/session/session-title/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "serviço de título de sessão", + "description": "Salve e leia os títulos das sessões e gerencie como os títulos são gerados." + } +} diff --git a/packages/session/session-title/locale/ru.json b/packages/session/session-title/locale/ru.json new file mode 100644 index 0000000000..3e7920ce87 --- /dev/null +++ b/packages/session/session-title/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "служба названия сеанса", + "description": "Сохраняйте и читайте заголовки сеансов, а также управляйте созданием заголовков." + } +} diff --git a/packages/session/session-turn-outline/locale/de.json b/packages/session/session-turn-outline/locale/de.json new file mode 100644 index 0000000000..61d5c4e979 --- /dev/null +++ b/packages/session/session-turn-outline/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sitzungsturn-Verzeichnis", + "description": "Erstellen Sie ein Sitzungsturn-Verzeichnis und unterstützen Sie die Positionierung und Interaktion mit dem Sprungverlauf." + } +} diff --git a/packages/session/session-turn-outline/locale/es.json b/packages/session/session-turn-outline/locale/es.json new file mode 100644 index 0000000000..63e3420fd2 --- /dev/null +++ b/packages/session/session-turn-outline/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Lista de turnos de sesión", + "description": "Genere un directorio de turnos de sesión y admita el posicionamiento y la interacción del historial de saltos." + } +} diff --git a/packages/session/session-turn-outline/locale/fr.json b/packages/session/session-turn-outline/locale/fr.json new file mode 100644 index 0000000000..12f6950f83 --- /dev/null +++ b/packages/session/session-turn-outline/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Répertoire de tour de session", + "description": "Générez un répertoire de rotation de session et prenez en charge l'interaction avec le positionnement et l'historique des sauts." + } +} diff --git a/packages/session/session-turn-outline/locale/pt.json b/packages/session/session-turn-outline/locale/pt.json new file mode 100644 index 0000000000..09f4243efc --- /dev/null +++ b/packages/session/session-turn-outline/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Diretório de turno de sessão", + "description": "Gere diretório de giro de sessão e suporte ao posicionamento e interação do histórico de salto." + } +} diff --git a/packages/session/session-turn-outline/locale/ru.json b/packages/session/session-turn-outline/locale/ru.json new file mode 100644 index 0000000000..d0b344bf2f --- /dev/null +++ b/packages/session/session-turn-outline/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Каталог поворота сеанса", + "description": "Создание каталога поворотов сеанса и поддержка позиционирования и взаимодействия с историей переходов." + } +} diff --git a/packages/session/tool-working-directory/locale/de.json b/packages/session/tool-working-directory/locale/de.json new file mode 100644 index 0000000000..e0b0406058 --- /dev/null +++ b/packages/session/tool-working-directory/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Arbeitsverzeichnis-Tools", + "description": "Lesen und ändern Sie das Arbeitsverzeichnis der aktuellen Sitzung." + } +} diff --git a/packages/session/tool-working-directory/locale/es.json b/packages/session/tool-working-directory/locale/es.json new file mode 100644 index 0000000000..9c66b23400 --- /dev/null +++ b/packages/session/tool-working-directory/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramientas del directorio de trabajo", + "description": "Lea y cambie el directorio de trabajo de la sesión actual." + } +} diff --git a/packages/session/tool-working-directory/locale/fr.json b/packages/session/tool-working-directory/locale/fr.json new file mode 100644 index 0000000000..2aea6a9d53 --- /dev/null +++ b/packages/session/tool-working-directory/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outils du répertoire de travail", + "description": "Lire et modifier le répertoire de travail de la session en cours." + } +} diff --git a/packages/session/tool-working-directory/locale/pt.json b/packages/session/tool-working-directory/locale/pt.json new file mode 100644 index 0000000000..d4db416054 --- /dev/null +++ b/packages/session/tool-working-directory/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramentas de diretório de trabalho", + "description": "Leia e altere o diretório de trabalho da sessão atual." + } +} diff --git a/packages/session/tool-working-directory/locale/ru.json b/packages/session/tool-working-directory/locale/ru.json new file mode 100644 index 0000000000..74037c4030 --- /dev/null +++ b/packages/session/tool-working-directory/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Инструменты рабочего каталога", + "description": "Прочитайте и измените рабочий каталог текущего сеанса." + } +} diff --git a/packages/session/working-directory/locale/de.json b/packages/session/working-directory/locale/de.json new file mode 100644 index 0000000000..2f2cad6440 --- /dev/null +++ b/packages/session/working-directory/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sitzungsarbeitsverzeichnisse", + "description": "Verwalten Sie Sitzungsarbeitsverzeichnisse, speichern Sie Verzeichnisänderungen und stellen Sie dem Modell Arbeitsverzeichniskontext zur Verfügung." + } +} diff --git a/packages/session/working-directory/locale/es.json b/packages/session/working-directory/locale/es.json new file mode 100644 index 0000000000..027de149b1 --- /dev/null +++ b/packages/session/working-directory/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Directorios de trabajo de sesiones", + "description": "Administre los directorios de trabajo de las sesiones, guarde los cambios de directorio y proporcione al modelo el contexto del directorio de trabajo." + } +} diff --git a/packages/session/working-directory/locale/fr.json b/packages/session/working-directory/locale/fr.json new file mode 100644 index 0000000000..0f3b40f674 --- /dev/null +++ b/packages/session/working-directory/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Répertoires de travail de session", + "description": "Gérez les répertoires de travail de session, enregistrez les modifications de répertoire et fournissez au modèle le contexte du répertoire de travail." + } +} diff --git a/packages/session/working-directory/locale/pt.json b/packages/session/working-directory/locale/pt.json new file mode 100644 index 0000000000..0a20984dfe --- /dev/null +++ b/packages/session/working-directory/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Diretórios de trabalho da sessão", + "description": "Gerencie diretórios de trabalho da sessão, salve alterações de diretório e forneça ao modelo o contexto do diretório de trabalho." + } +} diff --git a/packages/session/working-directory/locale/ru.json b/packages/session/working-directory/locale/ru.json new file mode 100644 index 0000000000..11d215d199 --- /dev/null +++ b/packages/session/working-directory/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Рабочие каталоги сеанса", + "description": "Управляйте рабочими каталогами сеанса, сохраняйте изменения каталогов и предоставляйте модели контекст рабочего каталога." + } +} diff --git a/packages/settings/settings/locale/de.json b/packages/settings/settings/locale/de.json new file mode 100644 index 0000000000..51b0336229 --- /dev/null +++ b/packages/settings/settings/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Einstellungen", + "description": "Stellen Sie eine einheitliche Benutzeroberfläche für andere Plug-Ins bereit." + } +} diff --git a/packages/settings/settings/locale/es.json b/packages/settings/settings/locale/es.json new file mode 100644 index 0000000000..23c5165ca4 --- /dev/null +++ b/packages/settings/settings/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "ajustes", + "description": "Proporciona una interfaz de configuración de usuario unificada para otros complementos." + } +} diff --git a/packages/settings/settings/locale/fr.json b/packages/settings/settings/locale/fr.json new file mode 100644 index 0000000000..ddf0c022d3 --- /dev/null +++ b/packages/settings/settings/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "paramètres", + "description": "Fournissez une interface de configuration utilisateur unifiée pour les autres plug-ins." + } +} diff --git a/packages/settings/settings/locale/pt.json b/packages/settings/settings/locale/pt.json new file mode 100644 index 0000000000..701f4cc829 --- /dev/null +++ b/packages/settings/settings/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "configurações", + "description": "Fornece uma interface de configuração de usuário unificada para outros plug-ins." + } +} diff --git a/packages/settings/settings/locale/ru.json b/packages/settings/settings/locale/ru.json new file mode 100644 index 0000000000..7c47ed001b --- /dev/null +++ b/packages/settings/settings/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "настройки", + "description": "Предоставьте единый интерфейс пользовательских настроек для других плагинов." + } +} diff --git a/packages/shell/bash-local/locale/de.json b/packages/shell/bash-local/locale/de.json new file mode 100644 index 0000000000..73d788d1dc --- /dev/null +++ b/packages/shell/bash-local/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Lokale Bash-Ausführung", + "description": "Führen Sie Bash-Befehle in lokalen Unterprozessen aus." + } +} diff --git a/packages/shell/bash-local/locale/es.json b/packages/shell/bash-local/locale/es.json new file mode 100644 index 0000000000..b40d1afefc --- /dev/null +++ b/packages/shell/bash-local/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ejecución local de Bash", + "description": "Ejecute comandos Bash en subprocesos locales." + } +} diff --git a/packages/shell/bash-local/locale/fr.json b/packages/shell/bash-local/locale/fr.json new file mode 100644 index 0000000000..8a27bd62b7 --- /dev/null +++ b/packages/shell/bash-local/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Exécution locale de Bash", + "description": "Exécutez les commandes Bash dans les sous-processus locaux." + } +} diff --git a/packages/shell/bash-local/locale/pt.json b/packages/shell/bash-local/locale/pt.json new file mode 100644 index 0000000000..3beed02a1f --- /dev/null +++ b/packages/shell/bash-local/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Execução local do Bash", + "description": "Execute comandos Bash em subprocessos locais." + } +} diff --git a/packages/shell/bash-local/locale/ru.json b/packages/shell/bash-local/locale/ru.json new file mode 100644 index 0000000000..67f1ba8ed0 --- /dev/null +++ b/packages/shell/bash-local/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Локальное выполнение Bash", + "description": "Запускайте команды Bash в локальных подпроцессах." + } +} diff --git a/packages/shell/bash-sandbox/locale/de.json b/packages/shell/bash-sandbox/locale/de.json new file mode 100644 index 0000000000..6e2c378b06 --- /dev/null +++ b/packages/shell/bash-sandbox/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Bash-Sandbox-Ausführung", + "description": "Führen Sie Bash-Befehle innerhalb der aktuellen Sandbox-Berechtigungen aus." + } +} diff --git a/packages/shell/bash-sandbox/locale/es.json b/packages/shell/bash-sandbox/locale/es.json new file mode 100644 index 0000000000..bd34a210a5 --- /dev/null +++ b/packages/shell/bash-sandbox/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ejecución de la zona de pruebas de Bash", + "description": "Ejecute comandos Bash dentro de los permisos actuales de la zona de pruebas." + } +} diff --git a/packages/shell/bash-sandbox/locale/fr.json b/packages/shell/bash-sandbox/locale/fr.json new file mode 100644 index 0000000000..2db759674c --- /dev/null +++ b/packages/shell/bash-sandbox/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Exécution du bac à sable Bash", + "description": "Exécutez les commandes Bash dans les autorisations actuelles du bac à sable." + } +} diff --git a/packages/shell/bash-sandbox/locale/pt.json b/packages/shell/bash-sandbox/locale/pt.json new file mode 100644 index 0000000000..b0be610140 --- /dev/null +++ b/packages/shell/bash-sandbox/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Execução de sandbox Bash", + "description": "Execute comandos Bash dentro das permissões atuais do sandbox." + } +} diff --git a/packages/shell/bash-sandbox/locale/ru.json b/packages/shell/bash-sandbox/locale/ru.json new file mode 100644 index 0000000000..44b5b81dbd --- /dev/null +++ b/packages/shell/bash-sandbox/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Выполнение песочницы Bash", + "description": "Выполняйте команды Bash в пределах текущих разрешений песочницы." + } +} diff --git a/packages/shell/pwsh-local/locale/de.json b/packages/shell/pwsh-local/locale/de.json new file mode 100644 index 0000000000..01bd80cb54 --- /dev/null +++ b/packages/shell/pwsh-local/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Lokale PowerShell-Ausführung", + "description": "Führen Sie Befehle über lokale PowerShell aus." + } +} diff --git a/packages/shell/pwsh-local/locale/es.json b/packages/shell/pwsh-local/locale/es.json new file mode 100644 index 0000000000..18c214861d --- /dev/null +++ b/packages/shell/pwsh-local/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ejecución local de PowerShell", + "description": "Ejecute comandos a través de PowerShell local." + } +} diff --git a/packages/shell/pwsh-local/locale/fr.json b/packages/shell/pwsh-local/locale/fr.json new file mode 100644 index 0000000000..542b6fa868 --- /dev/null +++ b/packages/shell/pwsh-local/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Exécution PowerShell locale", + "description": "Exécutez des commandes via PowerShell local." + } +} diff --git a/packages/shell/pwsh-local/locale/pt.json b/packages/shell/pwsh-local/locale/pt.json new file mode 100644 index 0000000000..d527492f1f --- /dev/null +++ b/packages/shell/pwsh-local/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Execução local do PowerShell", + "description": "Execute comandos por meio do PowerShell local." + } +} diff --git a/packages/shell/pwsh-local/locale/ru.json b/packages/shell/pwsh-local/locale/ru.json new file mode 100644 index 0000000000..0fe019cb42 --- /dev/null +++ b/packages/shell/pwsh-local/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Локальное выполнение PowerShell", + "description": "Запускайте команды через локальный PowerShell." + } +} diff --git a/packages/shell/pwsh-sandbox/locale/de.json b/packages/shell/pwsh-sandbox/locale/de.json new file mode 100644 index 0000000000..8d8f8f9a4a --- /dev/null +++ b/packages/shell/pwsh-sandbox/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "PowerShell-Sandbox-Ausführung", + "description": "Führen Sie PowerShell-Befehle innerhalb der aktuellen Sandbox-Berechtigungen aus." + } +} diff --git a/packages/shell/pwsh-sandbox/locale/es.json b/packages/shell/pwsh-sandbox/locale/es.json new file mode 100644 index 0000000000..6bdb5f483c --- /dev/null +++ b/packages/shell/pwsh-sandbox/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ejecución de zona de pruebas de PowerShell", + "description": "Ejecute comandos de PowerShell dentro de los permisos actuales de la zona de pruebas." + } +} diff --git a/packages/shell/pwsh-sandbox/locale/fr.json b/packages/shell/pwsh-sandbox/locale/fr.json new file mode 100644 index 0000000000..636087226e --- /dev/null +++ b/packages/shell/pwsh-sandbox/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Exécution du bac à sable PowerShell", + "description": "Exécutez les commandes PowerShell dans le cadre des autorisations sandbox actuelles." + } +} diff --git a/packages/shell/pwsh-sandbox/locale/pt.json b/packages/shell/pwsh-sandbox/locale/pt.json new file mode 100644 index 0000000000..6c1486e80f --- /dev/null +++ b/packages/shell/pwsh-sandbox/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Execução de sandbox do PowerShell", + "description": "Execute comandos do PowerShell dentro das permissões atuais do sandbox." + } +} diff --git a/packages/shell/pwsh-sandbox/locale/ru.json b/packages/shell/pwsh-sandbox/locale/ru.json new file mode 100644 index 0000000000..b2101ce1b0 --- /dev/null +++ b/packages/shell/pwsh-sandbox/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Выполнение песочницы PowerShell", + "description": "Выполняйте команды PowerShell в пределах текущих разрешений песочницы." + } +} diff --git a/packages/shell/shell-env/locale/de.json b/packages/shell/shell-env/locale/de.json new file mode 100644 index 0000000000..a6279ce62c --- /dev/null +++ b/packages/shell/shell-env/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Befehlsumgebungsvariablen", + "description": "Stellen Sie DSH Umgebungsvariablen einheitlich für Befehlsausführungstools bereit." + } +} diff --git a/packages/shell/shell-env/locale/es.json b/packages/shell/shell-env/locale/es.json new file mode 100644 index 0000000000..d2c78496d8 --- /dev/null +++ b/packages/shell/shell-env/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "variables de entorno de comando", + "description": "Proporcione DSH variables de entorno de manera uniforme para las herramientas de ejecución de comandos." + } +} diff --git a/packages/shell/shell-env/locale/fr.json b/packages/shell/shell-env/locale/fr.json new file mode 100644 index 0000000000..f25c54b2de --- /dev/null +++ b/packages/shell/shell-env/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "variables d'environnement de commande", + "description": "Fournissez des variables d'environnement DSH de manière uniforme pour les outils d'exécution de commandes." + } +} diff --git a/packages/shell/shell-env/locale/pt.json b/packages/shell/shell-env/locale/pt.json new file mode 100644 index 0000000000..3bcff2b932 --- /dev/null +++ b/packages/shell/shell-env/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "variáveis de ambiente de comando", + "description": "Forneça DSH variáveis de ambiente uniformemente para ferramentas de execução de comandos." + } +} diff --git a/packages/shell/shell-env/locale/ru.json b/packages/shell/shell-env/locale/ru.json new file mode 100644 index 0000000000..87ad3d1289 --- /dev/null +++ b/packages/shell/shell-env/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "переменные среды команды", + "description": "Предоставьте переменные среды DSH единообразно для инструментов выполнения команд." + } +} diff --git a/packages/shell/tool-bash-persistent/locale/de.json b/packages/shell/tool-bash-persistent/locale/de.json new file mode 100644 index 0000000000..127f61db7e --- /dev/null +++ b/packages/shell/tool-bash-persistent/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Persistente Bash-Tools", + "description": "Lassen Sie die KI in einer Bash-Sitzung, die den Status beibehält, kontinuierlich Befehle ausführen." + } +} diff --git a/packages/shell/tool-bash-persistent/locale/es.json b/packages/shell/tool-bash-persistent/locale/es.json new file mode 100644 index 0000000000..7cecba9c51 --- /dev/null +++ b/packages/shell/tool-bash-persistent/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramientas Bash persistentes", + "description": "Haga que la IA ejecute comandos continuamente en una sesión Bash que conserve el estado." + } +} diff --git a/packages/shell/tool-bash-persistent/locale/fr.json b/packages/shell/tool-bash-persistent/locale/fr.json new file mode 100644 index 0000000000..1e7e4abdca --- /dev/null +++ b/packages/shell/tool-bash-persistent/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outils Bash persistants", + "description": "Demandez à l'IA d'exécuter des commandes en continu dans une session Bash qui préserve l'état." + } +} diff --git a/packages/shell/tool-bash-persistent/locale/pt.json b/packages/shell/tool-bash-persistent/locale/pt.json new file mode 100644 index 0000000000..9089420d32 --- /dev/null +++ b/packages/shell/tool-bash-persistent/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramentas Bash persistentes", + "description": "Faça com que a IA execute comandos continuamente em uma sessão Bash que preserve o estado." + } +} diff --git a/packages/shell/tool-bash-persistent/locale/ru.json b/packages/shell/tool-bash-persistent/locale/ru.json new file mode 100644 index 0000000000..12d74d4444 --- /dev/null +++ b/packages/shell/tool-bash-persistent/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Постоянные инструменты Bash", + "description": "Заставьте ИИ непрерывно выполнять команды в сеансе Bash, сохраняющем состояние." + } +} diff --git a/packages/shell/tool-bash/locale/de.json b/packages/shell/tool-bash/locale/de.json new file mode 100644 index 0000000000..f00b158b32 --- /dev/null +++ b/packages/shell/tool-bash/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Bash-Befehlstool", + "description": "Lassen Sie die KI Bash-Befehle ausführen und Hintergrundvorgänge und Berechtigungsanwendungen gemäß der Konfiguration verwalten." + } +} diff --git a/packages/shell/tool-bash/locale/es.json b/packages/shell/tool-bash/locale/es.json new file mode 100644 index 0000000000..3f7c88285f --- /dev/null +++ b/packages/shell/tool-bash/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "herramienta de comando bash", + "description": "Deje que AI ejecute comandos Bash y administre operaciones en segundo plano y aplicaciones de permisos según lo configurado." + } +} diff --git a/packages/shell/tool-bash/locale/fr.json b/packages/shell/tool-bash/locale/fr.json new file mode 100644 index 0000000000..c5bf2dbf20 --- /dev/null +++ b/packages/shell/tool-bash/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outil de commande Bash", + "description": "Laissez l'IA exécuter des commandes Bash et gérer les opérations en arrière-plan et les applications d'autorisation comme configuré." + } +} diff --git a/packages/shell/tool-bash/locale/pt.json b/packages/shell/tool-bash/locale/pt.json new file mode 100644 index 0000000000..7904e2b204 --- /dev/null +++ b/packages/shell/tool-bash/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramenta de comando Bash", + "description": "Deixe a IA executar comandos Bash e gerenciar operações em segundo plano e aplicativos de permissão conforme configurado." + } +} diff --git a/packages/shell/tool-bash/locale/ru.json b/packages/shell/tool-bash/locale/ru.json new file mode 100644 index 0000000000..bcf78d1e53 --- /dev/null +++ b/packages/shell/tool-bash/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Командный инструмент Bash", + "description": "Позвольте ИИ выполнять команды Bash и управлять фоновыми операциями и приложениями разрешений в соответствии с настройками." + } +} diff --git a/packages/shell/tool-pwsh-persistent/locale/de.json b/packages/shell/tool-pwsh-persistent/locale/de.json new file mode 100644 index 0000000000..67e413cd94 --- /dev/null +++ b/packages/shell/tool-pwsh-persistent/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Persistente PowerShell-Tools", + "description": "Lassen Sie die KI Befehle kontinuierlich in einer PowerShell-Sitzung ausführen, die den Status beibehält." + } +} diff --git a/packages/shell/tool-pwsh-persistent/locale/es.json b/packages/shell/tool-pwsh-persistent/locale/es.json new file mode 100644 index 0000000000..b059041542 --- /dev/null +++ b/packages/shell/tool-pwsh-persistent/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramientas persistentes de PowerShell", + "description": "Deje que la IA ejecute comandos continuamente en una sesión de PowerShell que conserve el estado." + } +} diff --git a/packages/shell/tool-pwsh-persistent/locale/fr.json b/packages/shell/tool-pwsh-persistent/locale/fr.json new file mode 100644 index 0000000000..71300f1c9f --- /dev/null +++ b/packages/shell/tool-pwsh-persistent/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outils PowerShell persistants", + "description": "Laissez l'IA exécuter des commandes en continu dans une session PowerShell qui préserve l'état." + } +} diff --git a/packages/shell/tool-pwsh-persistent/locale/pt.json b/packages/shell/tool-pwsh-persistent/locale/pt.json new file mode 100644 index 0000000000..136d1e1d89 --- /dev/null +++ b/packages/shell/tool-pwsh-persistent/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramentas persistentes do PowerShell", + "description": "Deixe a IA executar comandos continuamente em uma sessão do PowerShell que preserva o estado." + } +} diff --git a/packages/shell/tool-pwsh-persistent/locale/ru.json b/packages/shell/tool-pwsh-persistent/locale/ru.json new file mode 100644 index 0000000000..e09591cf95 --- /dev/null +++ b/packages/shell/tool-pwsh-persistent/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Постоянные инструменты PowerShell", + "description": "Позвольте ИИ непрерывно выполнять команды в сеансе PowerShell, сохраняющем состояние." + } +} diff --git a/packages/shell/tool-pwsh/locale/de.json b/packages/shell/tool-pwsh/locale/de.json new file mode 100644 index 0000000000..d6202cdb6f --- /dev/null +++ b/packages/shell/tool-pwsh/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "PowerShell-Befehlstool", + "description": "Lassen Sie die KI PowerShell-Befehle ausführen." + } +} diff --git a/packages/shell/tool-pwsh/locale/es.json b/packages/shell/tool-pwsh/locale/es.json new file mode 100644 index 0000000000..1e9157980f --- /dev/null +++ b/packages/shell/tool-pwsh/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramienta de comando PowerShell", + "description": "Deje que la IA ejecute comandos de PowerShell." + } +} diff --git a/packages/shell/tool-pwsh/locale/fr.json b/packages/shell/tool-pwsh/locale/fr.json new file mode 100644 index 0000000000..0b17ca1b44 --- /dev/null +++ b/packages/shell/tool-pwsh/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outil de commande PowerShell", + "description": "Laissez l'IA exécuter des commandes PowerShell." + } +} diff --git a/packages/shell/tool-pwsh/locale/pt.json b/packages/shell/tool-pwsh/locale/pt.json new file mode 100644 index 0000000000..4fa61e55ba --- /dev/null +++ b/packages/shell/tool-pwsh/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramenta de comando do PowerShell", + "description": "Deixe a IA executar comandos do PowerShell." + } +} diff --git a/packages/shell/tool-pwsh/locale/ru.json b/packages/shell/tool-pwsh/locale/ru.json new file mode 100644 index 0000000000..0100f7ef73 --- /dev/null +++ b/packages/shell/tool-pwsh/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Командный инструмент PowerShell", + "description": "Позвольте ИИ выполнять команды PowerShell." + } +} diff --git a/packages/skill/skill-filesystem/locale/de.json b/packages/skill/skill-filesystem/locale/de.json new file mode 100644 index 0000000000..9c0b304ea4 --- /dev/null +++ b/packages/skill/skill-filesystem/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Laden lokaler Fertigkeiten", + "description": "Entdecken und lesen Sie Fähigkeiten aus lokalen Verzeichnissen." + } +} diff --git a/packages/skill/skill-filesystem/locale/es.json b/packages/skill/skill-filesystem/locale/es.json new file mode 100644 index 0000000000..0425256570 --- /dev/null +++ b/packages/skill/skill-filesystem/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Carga de habilidades locales", + "description": "Descubra y lea habilidades de directorios locales." + } +} diff --git a/packages/skill/skill-filesystem/locale/fr.json b/packages/skill/skill-filesystem/locale/fr.json new file mode 100644 index 0000000000..2645b948ac --- /dev/null +++ b/packages/skill/skill-filesystem/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Chargement de compétences locales", + "description": "Découvrez et lisez les compétences des annuaires locaux." + } +} diff --git a/packages/skill/skill-filesystem/locale/pt.json b/packages/skill/skill-filesystem/locale/pt.json new file mode 100644 index 0000000000..3075c8ed97 --- /dev/null +++ b/packages/skill/skill-filesystem/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Carregamento de habilidade local", + "description": "Descubra e leia habilidades em diretórios locais." + } +} diff --git a/packages/skill/skill-filesystem/locale/ru.json b/packages/skill/skill-filesystem/locale/ru.json new file mode 100644 index 0000000000..9bfff111ad --- /dev/null +++ b/packages/skill/skill-filesystem/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Загрузка местных навыков", + "description": "Находите и читайте навыки в местных каталогах." + } +} diff --git a/packages/skill/skill-office/locale/de.json b/packages/skill/skill-office/locale/de.json new file mode 100644 index 0000000000..472fe8bb82 --- /dev/null +++ b/packages/skill/skill-office/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Bürokenntnisse", + "description": "Stellen Sie integrierte Word-, PowerPoint- und Excel-Workflows sowie LibreOffice Kit-Vorgänge bereit." + } +} diff --git a/packages/skill/skill-office/locale/es.json b/packages/skill/skill-office/locale/es.json new file mode 100644 index 0000000000..d03523c327 --- /dev/null +++ b/packages/skill/skill-office/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "habilidades de oficina", + "description": "Proporcione flujos de trabajo integrados de Word, PowerPoint y Excel y operaciones del kit LibreOffice." + } +} diff --git a/packages/skill/skill-office/locale/fr.json b/packages/skill/skill-office/locale/fr.json new file mode 100644 index 0000000000..968c0edc95 --- /dev/null +++ b/packages/skill/skill-office/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Compétences bureautiques", + "description": "Fournissez des flux de travail Word, PowerPoint et Excel intégrés ainsi que des opérations du kit LibreOffice." + } +} diff --git a/packages/skill/skill-office/locale/pt.json b/packages/skill/skill-office/locale/pt.json new file mode 100644 index 0000000000..2d4bdf6f11 --- /dev/null +++ b/packages/skill/skill-office/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Habilidades de escritório", + "description": "Fornece fluxos de trabalho integrados do Word, PowerPoint e Excel e operações do LibreOffice Kit." + } +} diff --git a/packages/skill/skill-office/locale/ru.json b/packages/skill/skill-office/locale/ru.json new file mode 100644 index 0000000000..f9a694cdb1 --- /dev/null +++ b/packages/skill/skill-office/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Офисные навыки", + "description": "Обеспечьте встроенные рабочие процессы Word, PowerPoint и Excel, а также операции LibreOffice Kit." + } +} diff --git a/packages/skill/skill/locale/de.json b/packages/skill/skill/locale/de.json new file mode 100644 index 0000000000..4586fe5c0f --- /dev/null +++ b/packages/skill/skill/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Geschicklichkeit", + "description": "Fassen Sie Fähigkeiten aus verschiedenen Quellen zusammen, damit die KI sie abfragen und verwenden kann." + } +} diff --git a/packages/skill/skill/locale/es.json b/packages/skill/skill/locale/es.json new file mode 100644 index 0000000000..5b2e607b05 --- /dev/null +++ b/packages/skill/skill/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "habilidad", + "description": "Agregue habilidades de diferentes fuentes para que la IA las consulte y utilice." + } +} diff --git a/packages/skill/skill/locale/fr.json b/packages/skill/skill/locale/fr.json new file mode 100644 index 0000000000..ec6920e9ec --- /dev/null +++ b/packages/skill/skill/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "compétence", + "description": "Regroupez les compétences de différentes sources pour que l’IA puisse les interroger et les utiliser." + } +} diff --git a/packages/skill/skill/locale/pt.json b/packages/skill/skill/locale/pt.json new file mode 100644 index 0000000000..30c9a89fbc --- /dev/null +++ b/packages/skill/skill/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "habilidade", + "description": "Agregue habilidades de diferentes fontes para a IA consultar e usar." + } +} diff --git a/packages/skill/skill/locale/ru.json b/packages/skill/skill/locale/ru.json new file mode 100644 index 0000000000..e18da9a121 --- /dev/null +++ b/packages/skill/skill/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "умение", + "description": "Объединяйте навыки из разных источников, чтобы ИИ мог их запрашивать и использовать." + } +} diff --git a/packages/skill/tool-skill/locale/de.json b/packages/skill/tool-skill/locale/de.json new file mode 100644 index 0000000000..888ed2f5ee --- /dev/null +++ b/packages/skill/tool-skill/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Tool zum Laden von Fertigkeiten", + "description": "Lassen Sie die KI bei Bedarf Fertigkeitsbeschreibungen laden." + } +} diff --git a/packages/skill/tool-skill/locale/es.json b/packages/skill/tool-skill/locale/es.json new file mode 100644 index 0000000000..53dfaab98e --- /dev/null +++ b/packages/skill/tool-skill/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramienta de carga de habilidades", + "description": "Deje que la IA cargue descripciones de habilidades a pedido." + } +} diff --git a/packages/skill/tool-skill/locale/fr.json b/packages/skill/tool-skill/locale/fr.json new file mode 100644 index 0000000000..87d8c17f78 --- /dev/null +++ b/packages/skill/tool-skill/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outil de chargement de compétences", + "description": "Laissez l’IA charger les descriptions de compétences à la demande." + } +} diff --git a/packages/skill/tool-skill/locale/pt.json b/packages/skill/tool-skill/locale/pt.json new file mode 100644 index 0000000000..bb27f67d73 --- /dev/null +++ b/packages/skill/tool-skill/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramenta de carregamento de habilidades", + "description": "Deixe a IA carregar descrições de habilidades sob demanda." + } +} diff --git a/packages/skill/tool-skill/locale/ru.json b/packages/skill/tool-skill/locale/ru.json new file mode 100644 index 0000000000..6e838b9d2e --- /dev/null +++ b/packages/skill/tool-skill/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Инструмент загрузки навыков", + "description": "Позвольте ИИ загружать описания навыков по требованию." + } +} diff --git a/packages/skill/tool-workspace-dependencies/locale/de.json b/packages/skill/tool-workspace-dependencies/locale/de.json new file mode 100644 index 0000000000..2461f02f7b --- /dev/null +++ b/packages/skill/tool-workspace-dependencies/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Arbeitsbereichsabhängigkeiten", + "description": "Geben Sie absolute Pfade zu den gebündelten Python-, Node.js- und pnpm-Laufzeiten an." + } +} diff --git a/packages/skill/tool-workspace-dependencies/locale/es.json b/packages/skill/tool-workspace-dependencies/locale/es.json new file mode 100644 index 0000000000..f1d31fc449 --- /dev/null +++ b/packages/skill/tool-workspace-dependencies/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Dependencias del espacio de trabajo", + "description": "Proporcione rutas absolutas a los tiempos de ejecución de Python, Node.js y pnpm incluidos." + } +} diff --git a/packages/skill/tool-workspace-dependencies/locale/fr.json b/packages/skill/tool-workspace-dependencies/locale/fr.json new file mode 100644 index 0000000000..c4448ac387 --- /dev/null +++ b/packages/skill/tool-workspace-dependencies/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Dépendances de l'espace de travail", + "description": "Fournissez des chemins absolus vers les environnements d'exécution Python, Node.js et pnpm fournis." + } +} diff --git a/packages/skill/tool-workspace-dependencies/locale/pt.json b/packages/skill/tool-workspace-dependencies/locale/pt.json new file mode 100644 index 0000000000..5e4099b361 --- /dev/null +++ b/packages/skill/tool-workspace-dependencies/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Dependências do espaço de trabalho", + "description": "Forneça caminhos absolutos para os tempos de execução Python, Node.js e pnpm incluídos." + } +} diff --git a/packages/skill/tool-workspace-dependencies/locale/ru.json b/packages/skill/tool-workspace-dependencies/locale/ru.json new file mode 100644 index 0000000000..9339bd795b --- /dev/null +++ b/packages/skill/tool-workspace-dependencies/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Зависимости рабочей области", + "description": "Укажите абсолютные пути к связанным средам выполнения Python, Node.js и pnpm." + } +} diff --git a/packages/spill/spill-local/locale/de.json b/packages/spill/spill-local/locale/de.json new file mode 100644 index 0000000000..334146306f --- /dev/null +++ b/packages/spill/spill-local/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Lokale Speicherung langer Ergebnisse", + "description": "Speichern Sie übermäßig lange Tool-Ergebnisse in einer sitzungsspezifischen lokalen Datei." + } +} diff --git a/packages/spill/spill-local/locale/es.json b/packages/spill/spill-local/locale/es.json new file mode 100644 index 0000000000..ea8d48272f --- /dev/null +++ b/packages/spill/spill-local/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Almacenamiento local de resultados largos", + "description": "Guarde los resultados de la herramienta excesivamente largos en un archivo local específico de la sesión." + } +} diff --git a/packages/spill/spill-local/locale/fr.json b/packages/spill/spill-local/locale/fr.json new file mode 100644 index 0000000000..530caeb745 --- /dev/null +++ b/packages/spill/spill-local/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Stockage local des résultats longs", + "description": "Enregistrez les résultats de l'outil trop longs dans un fichier local spécifique à la session." + } +} diff --git a/packages/spill/spill-local/locale/pt.json b/packages/spill/spill-local/locale/pt.json new file mode 100644 index 0000000000..a49385529e --- /dev/null +++ b/packages/spill/spill-local/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Armazenamento local de resultados longos", + "description": "Salve resultados de ferramentas excessivamente longos em um arquivo local específico da sessão." + } +} diff --git a/packages/spill/spill-local/locale/ru.json b/packages/spill/spill-local/locale/ru.json new file mode 100644 index 0000000000..797fd415d5 --- /dev/null +++ b/packages/spill/spill-local/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Локальное хранилище длинных результатов", + "description": "Сохраняйте слишком длинные результаты работы инструмента в локальном файле, специфичном для сеанса." + } +} diff --git a/packages/spill/spill-policy/locale/de.json b/packages/spill/spill-policy/locale/de.json new file mode 100644 index 0000000000..666fa9ab31 --- /dev/null +++ b/packages/spill/spill-policy/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Kontrolle der Werkzeugergebnislänge", + "description": "Begrenzen Sie die Länge der Tool-Ergebnisse, die direkt im Kontext platziert werden, und behalten Sie den Lesepfad für die vollständigen Ergebnisse bei." + } +} diff --git a/packages/spill/spill-policy/locale/es.json b/packages/spill/spill-policy/locale/es.json new file mode 100644 index 0000000000..a9b5776cc5 --- /dev/null +++ b/packages/spill/spill-policy/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Control de longitud del resultado de la herramienta", + "description": "Limite la longitud de los resultados de la herramienta colocados directamente en el contexto y conserve la ruta de lectura para los resultados completos." + } +} diff --git a/packages/spill/spill-policy/locale/fr.json b/packages/spill/spill-policy/locale/fr.json new file mode 100644 index 0000000000..c722da300a --- /dev/null +++ b/packages/spill/spill-policy/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Contrôle de la longueur du résultat de l'outil", + "description": "Limitez la longueur des résultats des outils placés directement dans le contexte et conservez le chemin de lecture pour les résultats complets." + } +} diff --git a/packages/spill/spill-policy/locale/pt.json b/packages/spill/spill-policy/locale/pt.json new file mode 100644 index 0000000000..c06ac70351 --- /dev/null +++ b/packages/spill/spill-policy/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Controle do comprimento do resultado da ferramenta", + "description": "Limite o comprimento dos resultados da ferramenta colocados diretamente no contexto e preserve o caminho de leitura para os resultados completos." + } +} diff --git a/packages/spill/spill-policy/locale/ru.json b/packages/spill/spill-policy/locale/ru.json new file mode 100644 index 0000000000..2187d80f8c --- /dev/null +++ b/packages/spill/spill-policy/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Контроль длины результата инструмента", + "description": "Ограничьте длину результатов инструмента, помещенных непосредственно в контекст, и сохраните путь чтения для полных результатов." + } +} diff --git a/packages/ssh/fs-ssh/locale/de.json b/packages/ssh/fs-ssh/locale/de.json new file mode 100644 index 0000000000..6213c429cb --- /dev/null +++ b/packages/ssh/fs-ssh/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "SSH-Dateisystem", + "description": "Greifen Sie über den gemeinsam genutzten POSIX-SSH-Helfer auf Remote-Dateien zu." + } +} diff --git a/packages/ssh/fs-ssh/locale/es.json b/packages/ssh/fs-ssh/locale/es.json new file mode 100644 index 0000000000..76dff4f25e --- /dev/null +++ b/packages/ssh/fs-ssh/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "sistema de archivos SSH", + "description": "Acceda a archivos remotos a través del asistente POSIX SSH compartido." + } +} diff --git a/packages/ssh/fs-ssh/locale/fr.json b/packages/ssh/fs-ssh/locale/fr.json new file mode 100644 index 0000000000..077bfd9902 --- /dev/null +++ b/packages/ssh/fs-ssh/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Système de fichiers SSH", + "description": "Accédez aux fichiers distants via l'assistant POSIX SSH partagé." + } +} diff --git a/packages/ssh/fs-ssh/locale/pt.json b/packages/ssh/fs-ssh/locale/pt.json new file mode 100644 index 0000000000..51e7f4e35a --- /dev/null +++ b/packages/ssh/fs-ssh/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sistema de arquivos SSH", + "description": "Acesse arquivos remotos por meio do auxiliar SSH POSIX compartilhado." + } +} diff --git a/packages/ssh/fs-ssh/locale/ru.json b/packages/ssh/fs-ssh/locale/ru.json new file mode 100644 index 0000000000..0e4e35bd76 --- /dev/null +++ b/packages/ssh/fs-ssh/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Файловая система SSH", + "description": "Доступ к удаленным файлам через общий помощник POSIX SSH." + } +} diff --git a/packages/ssh/sandbox-ssh/locale/de.json b/packages/ssh/sandbox-ssh/locale/de.json new file mode 100644 index 0000000000..cec06f31f5 --- /dev/null +++ b/packages/ssh/sandbox-ssh/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "SSH-Prozess-Sandbox", + "description": "Erstellen Sie Sandbox-Befehle für Remote-POSIX-Prozesse über den gemeinsam genutzten SSH-Helfer." + } +} diff --git a/packages/ssh/sandbox-ssh/locale/es.json b/packages/ssh/sandbox-ssh/locale/es.json new file mode 100644 index 0000000000..54b45ef51b --- /dev/null +++ b/packages/ssh/sandbox-ssh/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Zona de pruebas de proceso SSH", + "description": "Cree comandos de espacio aislado para procesos POSIX remotos a través del asistente SSH compartido." + } +} diff --git a/packages/ssh/sandbox-ssh/locale/fr.json b/packages/ssh/sandbox-ssh/locale/fr.json new file mode 100644 index 0000000000..64f9245eb2 --- /dev/null +++ b/packages/ssh/sandbox-ssh/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Bac à sable de processus SSH", + "description": "Créez des commandes sandbox pour les processus POSIX distants via l'assistant SSH partagé." + } +} diff --git a/packages/ssh/sandbox-ssh/locale/pt.json b/packages/ssh/sandbox-ssh/locale/pt.json new file mode 100644 index 0000000000..de505bd7ed --- /dev/null +++ b/packages/ssh/sandbox-ssh/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Área restrita do processo SSH", + "description": "Crie comandos sandbox para processos POSIX remotos por meio do auxiliar SSH compartilhado." + } +} diff --git a/packages/ssh/sandbox-ssh/locale/ru.json b/packages/ssh/sandbox-ssh/locale/ru.json new file mode 100644 index 0000000000..dba6000ff2 --- /dev/null +++ b/packages/ssh/sandbox-ssh/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Песочница процесса SSH", + "description": "Создавайте команды песочницы для удаленных процессов POSIX с помощью общего помощника SSH." + } +} diff --git a/packages/ssh/ssh/locale/de.json b/packages/ssh/ssh/locale/de.json new file mode 100644 index 0000000000..433178684c --- /dev/null +++ b/packages/ssh/ssh/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "SSH-Verbindungen", + "description": "Teilen Sie OpenSSH-Verbindungen und versionierte POSIX-Remote-Helfer." + } +} diff --git a/packages/ssh/ssh/locale/es.json b/packages/ssh/ssh/locale/es.json new file mode 100644 index 0000000000..b5a0defa0e --- /dev/null +++ b/packages/ssh/ssh/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Conexiones SSH", + "description": "Comparta conexiones OpenSSH y ayudantes remotos POSIX versionados." + } +} diff --git a/packages/ssh/ssh/locale/fr.json b/packages/ssh/ssh/locale/fr.json new file mode 100644 index 0000000000..56bc262406 --- /dev/null +++ b/packages/ssh/ssh/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Connexions SSH", + "description": "Partagez des connexions OpenSSH et des assistants distants POSIX versionnés." + } +} diff --git a/packages/ssh/ssh/locale/pt.json b/packages/ssh/ssh/locale/pt.json new file mode 100644 index 0000000000..7f9ba3a290 --- /dev/null +++ b/packages/ssh/ssh/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Conexões SSH", + "description": "Compartilhe conexões OpenSSH e ajudantes remotos POSIX versionados." + } +} diff --git a/packages/ssh/ssh/locale/ru.json b/packages/ssh/ssh/locale/ru.json new file mode 100644 index 0000000000..bf482a7b54 --- /dev/null +++ b/packages/ssh/ssh/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "SSH-соединения", + "description": "Делитесь соединениями OpenSSH и удаленными помощниками POSIX с поддержкой версий." + } +} diff --git a/packages/ssh/subprocess-ssh/locale/de.json b/packages/ssh/subprocess-ssh/locale/de.json new file mode 100644 index 0000000000..26c1a7dcb3 --- /dev/null +++ b/packages/ssh/subprocess-ssh/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "SSH-Unterprozesse", + "description": "Stellen Sie Unterprozesse und Terminals über den gemeinsamen POSIX-SSH-Helfer bereit." + } +} diff --git a/packages/ssh/subprocess-ssh/locale/es.json b/packages/ssh/subprocess-ssh/locale/es.json new file mode 100644 index 0000000000..015c777b04 --- /dev/null +++ b/packages/ssh/subprocess-ssh/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Subprocesos SSH", + "description": "Proporcione subprocesos y terminales a través del asistente POSIX SSH compartido." + } +} diff --git a/packages/ssh/subprocess-ssh/locale/fr.json b/packages/ssh/subprocess-ssh/locale/fr.json new file mode 100644 index 0000000000..8589f030fc --- /dev/null +++ b/packages/ssh/subprocess-ssh/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sous-processus SSH", + "description": "Fournissez des sous-processus et des terminaux via l'assistant POSIX SSH partagé." + } +} diff --git a/packages/ssh/subprocess-ssh/locale/pt.json b/packages/ssh/subprocess-ssh/locale/pt.json new file mode 100644 index 0000000000..da5a2f7b20 --- /dev/null +++ b/packages/ssh/subprocess-ssh/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Subprocessos SSH", + "description": "Forneça subprocessos e terminais por meio do auxiliar SSH POSIX compartilhado." + } +} diff --git a/packages/ssh/subprocess-ssh/locale/ru.json b/packages/ssh/subprocess-ssh/locale/ru.json new file mode 100644 index 0000000000..7d0c57d933 --- /dev/null +++ b/packages/ssh/subprocess-ssh/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Подпроцессы SSH", + "description": "Предоставляйте подпроцессы и терминалы через общий помощник POSIX SSH." + } +} diff --git a/packages/storage/storage-domain/locale/de.json b/packages/storage/storage-domain/locale/de.json new file mode 100644 index 0000000000..c8e5921370 --- /dev/null +++ b/packages/storage/storage-domain/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Strukturierte Datenspeicherung", + "description": "Speichern Sie Schlüsselwertdaten anhand der Prüfsumme der Datenstruktur und benachrichtigen Sie andere Plug-Ins über Änderungen." + } +} diff --git a/packages/storage/storage-domain/locale/es.json b/packages/storage/storage-domain/locale/es.json new file mode 100644 index 0000000000..56b64e4c28 --- /dev/null +++ b/packages/storage/storage-domain/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Almacenamiento de datos estructurados", + "description": "Guarde los datos clave-valor mediante suma de verificación de la estructura de datos y notifique a otros complementos sobre los cambios." + } +} diff --git a/packages/storage/storage-domain/locale/fr.json b/packages/storage/storage-domain/locale/fr.json new file mode 100644 index 0000000000..ea25349832 --- /dev/null +++ b/packages/storage/storage-domain/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Stockage de données structuré", + "description": "Enregistrez les données clé-valeur par somme de contrôle de la structure des données et informez les autres plug-ins des modifications." + } +} diff --git a/packages/storage/storage-domain/locale/pt.json b/packages/storage/storage-domain/locale/pt.json new file mode 100644 index 0000000000..fc6a33cccd --- /dev/null +++ b/packages/storage/storage-domain/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Armazenamento de dados estruturados", + "description": "Salve dados de valor-chave por soma de verificação da estrutura de dados e notifique outros plug-ins sobre alterações." + } +} diff --git a/packages/storage/storage-domain/locale/ru.json b/packages/storage/storage-domain/locale/ru.json new file mode 100644 index 0000000000..da0b9f77af --- /dev/null +++ b/packages/storage/storage-domain/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Структурированное хранилище данных", + "description": "Сохраняйте данные «ключ-значение» по контрольной сумме структуры данных и уведомляйте другие плагины об изменениях." + } +} diff --git a/packages/storage/storage-json/locale/de.json b/packages/storage/storage-json/locale/de.json new file mode 100644 index 0000000000..7acd833907 --- /dev/null +++ b/packages/storage/storage-json/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "JSON Dateispeicher", + "description": "Speichern Sie Schlüsselwertdaten in einer lokalen JSON-Datei." + } +} diff --git a/packages/storage/storage-json/locale/es.json b/packages/storage/storage-json/locale/es.json new file mode 100644 index 0000000000..b887fe43d8 --- /dev/null +++ b/packages/storage/storage-json/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "JSON almacenamiento de archivos", + "description": "Guarde los datos clave-valor en un archivo JSON local." + } +} diff --git a/packages/storage/storage-json/locale/fr.json b/packages/storage/storage-json/locale/fr.json new file mode 100644 index 0000000000..624e1fd83f --- /dev/null +++ b/packages/storage/storage-json/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "JSON stockage de fichiers", + "description": "Enregistrez les données clé-valeur dans un fichier JSON local." + } +} diff --git a/packages/storage/storage-json/locale/pt.json b/packages/storage/storage-json/locale/pt.json new file mode 100644 index 0000000000..e35d3b5196 --- /dev/null +++ b/packages/storage/storage-json/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "JSON armazenamento de arquivos", + "description": "Salve dados de valores-chave em um arquivo JSON local." + } +} diff --git a/packages/storage/storage-json/locale/ru.json b/packages/storage/storage-json/locale/ru.json new file mode 100644 index 0000000000..2a12630a06 --- /dev/null +++ b/packages/storage/storage-json/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "JSON файловое хранилище", + "description": "Сохраните данные «ключ-значение» в локальном файле JSON." + } +} diff --git a/packages/storage/storage-sqlite/locale/de.json b/packages/storage/storage-sqlite/locale/de.json new file mode 100644 index 0000000000..e5438eb579 --- /dev/null +++ b/packages/storage/storage-sqlite/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "SQLite-Speicher", + "description": "Speichern Sie Harness-Schlüsselwertdaten in SQLite." + } +} diff --git a/packages/storage/storage-sqlite/locale/es.json b/packages/storage/storage-sqlite/locale/es.json new file mode 100644 index 0000000000..a52893dadf --- /dev/null +++ b/packages/storage/storage-sqlite/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "almacenamiento SQLite", + "description": "Almacene los datos clave-valor de Harness en SQLite." + } +} diff --git a/packages/storage/storage-sqlite/locale/fr.json b/packages/storage/storage-sqlite/locale/fr.json new file mode 100644 index 0000000000..f6f43ed4b7 --- /dev/null +++ b/packages/storage/storage-sqlite/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Stockage SQLite", + "description": "Stockez les données clé-valeur Harness dans SQLite." + } +} diff --git a/packages/storage/storage-sqlite/locale/pt.json b/packages/storage/storage-sqlite/locale/pt.json new file mode 100644 index 0000000000..fcf5e3543c --- /dev/null +++ b/packages/storage/storage-sqlite/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "SQLite armazenamento", + "description": "Armazene dados de valor-chave do Harness em SQLite." + } +} diff --git a/packages/storage/storage-sqlite/locale/ru.json b/packages/storage/storage-sqlite/locale/ru.json new file mode 100644 index 0000000000..d1e03ffe2e --- /dev/null +++ b/packages/storage/storage-sqlite/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "SQLite хранилище", + "description": "Сохраните данные «ключ-значение» Harness в SQLite." + } +} diff --git a/packages/storage/storage/locale/de.json b/packages/storage/storage/locale/de.json new file mode 100644 index 0000000000..16cd40ea91 --- /dev/null +++ b/packages/storage/storage/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Lagerung", + "description": "Einheitliche Verwaltung des Speicher-Backends und der von Plug-Ins verwendeten Datenzugriffsmethoden." + } +} diff --git a/packages/storage/storage/locale/es.json b/packages/storage/storage/locale/es.json new file mode 100644 index 0000000000..f8edd32bca --- /dev/null +++ b/packages/storage/storage/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "almacenamiento", + "description": "Gestión unificada del backend de almacenamiento y los métodos de acceso a datos utilizados por los complementos." + } +} diff --git a/packages/storage/storage/locale/fr.json b/packages/storage/storage/locale/fr.json new file mode 100644 index 0000000000..e701f95a27 --- /dev/null +++ b/packages/storage/storage/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "stockage", + "description": "Gestion unifiée du backend de stockage et des méthodes d'accès aux données utilisées par les plug-ins." + } +} diff --git a/packages/storage/storage/locale/pt.json b/packages/storage/storage/locale/pt.json new file mode 100644 index 0000000000..90cedf8a19 --- /dev/null +++ b/packages/storage/storage/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "armazenamento", + "description": "Gerenciamento unificado do back-end de armazenamento e métodos de acesso a dados usados por plug-ins." + } +} diff --git a/packages/storage/storage/locale/ru.json b/packages/storage/storage/locale/ru.json new file mode 100644 index 0000000000..b28963ef5d --- /dev/null +++ b/packages/storage/storage/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "хранение", + "description": "Унифицированное управление серверной частью хранилища и методами доступа к данным, используемыми плагинами." + } +} diff --git a/packages/subagent/subagent-acp/locale/de.json b/packages/subagent/subagent-acp/locale/de.json new file mode 100644 index 0000000000..867bf1d524 --- /dev/null +++ b/packages/subagent/subagent-acp/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "ACP Subagent-Backend", + "description": "Führen Sie externe Agenten in Unterprozessen über ACP aus." + } +} diff --git a/packages/subagent/subagent-acp/locale/es.json b/packages/subagent/subagent-acp/locale/es.json new file mode 100644 index 0000000000..dff45d0622 --- /dev/null +++ b/packages/subagent/subagent-acp/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "backend del subagente ACP", + "description": "Ejecutar agentes externos en subprocesos a través de ACP." + } +} diff --git a/packages/subagent/subagent-acp/locale/fr.json b/packages/subagent/subagent-acp/locale/fr.json new file mode 100644 index 0000000000..065021d523 --- /dev/null +++ b/packages/subagent/subagent-acp/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Backend du sous-agent ACP", + "description": "Exécutez des agents externes dans des sous-processus via ACP." + } +} diff --git a/packages/subagent/subagent-acp/locale/pt.json b/packages/subagent/subagent-acp/locale/pt.json new file mode 100644 index 0000000000..55f6a72196 --- /dev/null +++ b/packages/subagent/subagent-acp/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "ACP back-end do subagente", + "description": "Execute agentes externos em subprocessos por meio de ACP." + } +} diff --git a/packages/subagent/subagent-acp/locale/ru.json b/packages/subagent/subagent-acp/locale/ru.json new file mode 100644 index 0000000000..8766dc9bc8 --- /dev/null +++ b/packages/subagent/subagent-acp/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Серверная часть субагента ACP", + "description": "Запускайте внешние агенты в подпроцессах через ACP." + } +} diff --git a/packages/subagent/subagent-claude-code/locale/de.json b/packages/subagent/subagent-claude-code/locale/de.json new file mode 100644 index 0000000000..f7848ccec2 --- /dev/null +++ b/packages/subagent/subagent-claude-code/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Claude Code-Subagent", + "description": "Delegieren Sie eine Aufgabe an Claude Code, indem Sie dessen native Authentifizierung und Einstellungen verwenden." + } +} diff --git a/packages/subagent/subagent-claude-code/locale/es.json b/packages/subagent/subagent-claude-code/locale/es.json new file mode 100644 index 0000000000..7e0897c631 --- /dev/null +++ b/packages/subagent/subagent-claude-code/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Subagente Claude Code", + "description": "Delegue una tarea a Claude Code utilizando su autenticación y configuración nativas." + } +} diff --git a/packages/subagent/subagent-claude-code/locale/fr.json b/packages/subagent/subagent-claude-code/locale/fr.json new file mode 100644 index 0000000000..4de0eceff5 --- /dev/null +++ b/packages/subagent/subagent-claude-code/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sous-agent Claude Code", + "description": "Déléguez une tâche à Claude Code à l’aide de son authentification et de ses paramètres natifs." + } +} diff --git a/packages/subagent/subagent-claude-code/locale/pt.json b/packages/subagent/subagent-claude-code/locale/pt.json new file mode 100644 index 0000000000..c83ab3734c --- /dev/null +++ b/packages/subagent/subagent-claude-code/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Claude Code subagente", + "description": "Delegue uma tarefa a Claude Code usando sua autenticação e configurações nativas." + } +} diff --git a/packages/subagent/subagent-claude-code/locale/ru.json b/packages/subagent/subagent-claude-code/locale/ru.json new file mode 100644 index 0000000000..5e18baeabb --- /dev/null +++ b/packages/subagent/subagent-claude-code/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Субагент Claude Code", + "description": "Делегируйте одну задачу Claude Code, используя его встроенную аутентификацию и настройки." + } +} diff --git a/packages/subagent/subagent-codex/locale/de.json b/packages/subagent/subagent-codex/locale/de.json new file mode 100644 index 0000000000..14c448dc25 --- /dev/null +++ b/packages/subagent/subagent-codex/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Codex-Subagent", + "description": "Delegieren Sie eine Aufgabe an Codex, indem Sie dessen native Authentifizierung und Einstellungen verwenden." + } +} diff --git a/packages/subagent/subagent-codex/locale/es.json b/packages/subagent/subagent-codex/locale/es.json new file mode 100644 index 0000000000..475b650734 --- /dev/null +++ b/packages/subagent/subagent-codex/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Subagente Codex", + "description": "Delegue una tarea a Codex utilizando su autenticación y configuración nativas." + } +} diff --git a/packages/subagent/subagent-codex/locale/fr.json b/packages/subagent/subagent-codex/locale/fr.json new file mode 100644 index 0000000000..9f6b954708 --- /dev/null +++ b/packages/subagent/subagent-codex/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Sous-agent Codex", + "description": "Déléguez une tâche à Codex à l’aide de son authentification et de ses paramètres natifs." + } +} diff --git a/packages/subagent/subagent-codex/locale/pt.json b/packages/subagent/subagent-codex/locale/pt.json new file mode 100644 index 0000000000..e2746242b9 --- /dev/null +++ b/packages/subagent/subagent-codex/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Codex subagente", + "description": "Delegue uma tarefa a Codex usando sua autenticação e configurações nativas." + } +} diff --git a/packages/subagent/subagent-codex/locale/ru.json b/packages/subagent/subagent-codex/locale/ru.json new file mode 100644 index 0000000000..b078ef03c5 --- /dev/null +++ b/packages/subagent/subagent-codex/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Субагент Codex", + "description": "Делегируйте одну задачу Codex, используя его встроенную аутентификацию и настройки." + } +} diff --git a/packages/subagent/subagent-dsh-sdk/locale/de.json b/packages/subagent/subagent-dsh-sdk/locale/de.json new file mode 100644 index 0000000000..f44f683c9f --- /dev/null +++ b/packages/subagent/subagent-dsh-sdk/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DSH SDK Subagent-Backend", + "description": "Führen Sie Harness in einem Unterprozess über TypeScript SDK und JSON-RPC über Standardeingabe und -ausgabe aus." + } +} diff --git a/packages/subagent/subagent-dsh-sdk/locale/es.json b/packages/subagent/subagent-dsh-sdk/locale/es.json new file mode 100644 index 0000000000..db11962a8c --- /dev/null +++ b/packages/subagent/subagent-dsh-sdk/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DSH SDK backend del subagente", + "description": "Ejecute Harness en un subproceso a través de TypeScript SDK y JSON-RPC a través de entrada y salida estándar." + } +} diff --git a/packages/subagent/subagent-dsh-sdk/locale/fr.json b/packages/subagent/subagent-dsh-sdk/locale/fr.json new file mode 100644 index 0000000000..858885abc9 --- /dev/null +++ b/packages/subagent/subagent-dsh-sdk/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Backend du sous-agent DSH SDK", + "description": "Exécutez Harness dans un sous-processus via TypeScript SDK et JSON-RPC sur l'entrée et la sortie standard." + } +} diff --git a/packages/subagent/subagent-dsh-sdk/locale/pt.json b/packages/subagent/subagent-dsh-sdk/locale/pt.json new file mode 100644 index 0000000000..64867f9354 --- /dev/null +++ b/packages/subagent/subagent-dsh-sdk/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DSH SDK back-end do subagente", + "description": "Execute o Harness em um subprocesso por meio do TypeScript SDK e JSON-RPC em entrada e saída padrão." + } +} diff --git a/packages/subagent/subagent-dsh-sdk/locale/ru.json b/packages/subagent/subagent-dsh-sdk/locale/ru.json new file mode 100644 index 0000000000..7ba35d22ca --- /dev/null +++ b/packages/subagent/subagent-dsh-sdk/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DSH SDK Серверная часть субагента", + "description": "Запустите Harness в подпроцессе через TypeScript SDK и JSON-RPC через стандартный ввод и вывод." + } +} diff --git a/packages/subagent/subagent-fork-in-process/locale/de.json b/packages/subagent/subagent-fork-in-process/locale/de.json new file mode 100644 index 0000000000..2d2c5e0fb5 --- /dev/null +++ b/packages/subagent/subagent-fork-in-process/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Backend des untergeordneten Agenten des Kontexts erben", + "description": "Erstellen Sie einen untergeordneten Agenten mithilfe eines Teils des Verlaufs der übergeordneten Sitzung." + } +} diff --git a/packages/subagent/subagent-fork-in-process/locale/es.json b/packages/subagent/subagent-fork-in-process/locale/es.json new file mode 100644 index 0000000000..b0142267ab --- /dev/null +++ b/packages/subagent/subagent-fork-in-process/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Heredar el backend del agente secundario de contexto", + "description": "Cree un agente secundario utilizando un fragmento del historial de la sesión principal." + } +} diff --git a/packages/subagent/subagent-fork-in-process/locale/fr.json b/packages/subagent/subagent-fork-in-process/locale/fr.json new file mode 100644 index 0000000000..4abb1c015f --- /dev/null +++ b/packages/subagent/subagent-fork-in-process/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Hériter le backend de l'agent enfant du contexte", + "description": "Créez un agent enfant à l'aide d'un morceau d'historique de la session parent." + } +} diff --git a/packages/subagent/subagent-fork-in-process/locale/pt.json b/packages/subagent/subagent-fork-in-process/locale/pt.json new file mode 100644 index 0000000000..3ca03e5d70 --- /dev/null +++ b/packages/subagent/subagent-fork-in-process/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herdar back-end do agente filho do contexto", + "description": "Crie um agente filho usando um histórico da sessão pai." + } +} diff --git a/packages/subagent/subagent-fork-in-process/locale/ru.json b/packages/subagent/subagent-fork-in-process/locale/ru.json new file mode 100644 index 0000000000..2c01449e4b --- /dev/null +++ b/packages/subagent/subagent-fork-in-process/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Наследовать серверную часть дочернего агента контекста", + "description": "Создайте дочерний агент, используя часть истории родительского сеанса." + } +} diff --git a/packages/subagent/subagent-spawn-in-process/locale/de.json b/packages/subagent/subagent-spawn-in-process/locale/de.json new file mode 100644 index 0000000000..9e918ea37c --- /dev/null +++ b/packages/subagent/subagent-spawn-in-process/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Erstellen Sie ein neues Subagenten-Backend", + "description": "Erstellen Sie im aktuellen Prozess einen neuen Subagenten und führen Sie unabhängige Aufgaben aus." + } +} diff --git a/packages/subagent/subagent-spawn-in-process/locale/es.json b/packages/subagent/subagent-spawn-in-process/locale/es.json new file mode 100644 index 0000000000..be20dd3e6b --- /dev/null +++ b/packages/subagent/subagent-spawn-in-process/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Crear un nuevo backend de subagente", + "description": "Cree un nuevo subagente en el proceso actual y realice tareas independientes." + } +} diff --git a/packages/subagent/subagent-spawn-in-process/locale/fr.json b/packages/subagent/subagent-spawn-in-process/locale/fr.json new file mode 100644 index 0000000000..4101a47051 --- /dev/null +++ b/packages/subagent/subagent-spawn-in-process/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Créer un nouveau backend de sous-agent", + "description": "Créez un nouveau sous-agent dans le processus en cours et effectuez des tâches indépendantes." + } +} diff --git a/packages/subagent/subagent-spawn-in-process/locale/pt.json b/packages/subagent/subagent-spawn-in-process/locale/pt.json new file mode 100644 index 0000000000..f23bce79b7 --- /dev/null +++ b/packages/subagent/subagent-spawn-in-process/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Crie um novo back-end de subagente", + "description": "Crie um novo subagente no processo atual e execute tarefas independentes." + } +} diff --git a/packages/subagent/subagent-spawn-in-process/locale/ru.json b/packages/subagent/subagent-spawn-in-process/locale/ru.json new file mode 100644 index 0000000000..1a58618290 --- /dev/null +++ b/packages/subagent/subagent-spawn-in-process/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Создайте новый сервер субагента", + "description": "Создайте нового субагента в текущем процессе и выполняйте независимые задачи." + } +} diff --git a/packages/subagent/subagent/locale/de.json b/packages/subagent/subagent/locale/de.json new file mode 100644 index 0000000000..0313a1c934 --- /dev/null +++ b/packages/subagent/subagent/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Subagent", + "description": "Verwalten Sie das Subagenten-Backend und stellen Sie eine einheitliche Schnittstelle für die Aufgabendelegierung bereit." + } +} diff --git a/packages/subagent/subagent/locale/es.json b/packages/subagent/subagent/locale/es.json new file mode 100644 index 0000000000..6c8d817199 --- /dev/null +++ b/packages/subagent/subagent/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "subagente", + "description": "Administre el backend del subagente y proporcione una interfaz unificada para la delegación de tareas." + } +} diff --git a/packages/subagent/subagent/locale/fr.json b/packages/subagent/subagent/locale/fr.json new file mode 100644 index 0000000000..42d8ed29e6 --- /dev/null +++ b/packages/subagent/subagent/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "sous-agent", + "description": "Gérez le backend du sous-agent et fournissez une interface unifiée pour la délégation de tâches." + } +} diff --git a/packages/subagent/subagent/locale/pt.json b/packages/subagent/subagent/locale/pt.json new file mode 100644 index 0000000000..497251f0d2 --- /dev/null +++ b/packages/subagent/subagent/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "subagente", + "description": "Gerencie o back-end do subagente e forneça uma interface unificada para delegação de tarefas." + } +} diff --git a/packages/subagent/subagent/locale/ru.json b/packages/subagent/subagent/locale/ru.json new file mode 100644 index 0000000000..f267ed6ed1 --- /dev/null +++ b/packages/subagent/subagent/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "субагент", + "description": "Управляйте серверной частью субагента и предоставляйте единый интерфейс для делегирования задач." + } +} diff --git a/packages/subagent/tool-subagent-control/locale/de.json b/packages/subagent/tool-subagent-control/locale/de.json new file mode 100644 index 0000000000..633accfa15 --- /dev/null +++ b/packages/subagent/tool-subagent-control/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Kontrolltools für Subagenten", + "description": "Lassen Sie die KI Nachrichten an Subagenten senden oder deren Betrieb unterbrechen." + } +} diff --git a/packages/subagent/tool-subagent-control/locale/es.json b/packages/subagent/tool-subagent-control/locale/es.json new file mode 100644 index 0000000000..2e5b7d21ca --- /dev/null +++ b/packages/subagent/tool-subagent-control/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramientas de control de subagentes", + "description": "Deje que la IA envíe mensajes a los subagentes o interrumpa su operación." + } +} diff --git a/packages/subagent/tool-subagent-control/locale/fr.json b/packages/subagent/tool-subagent-control/locale/fr.json new file mode 100644 index 0000000000..0d51d30df8 --- /dev/null +++ b/packages/subagent/tool-subagent-control/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outils de contrôle des sous-agents", + "description": "Laissez l'IA envoyer des messages aux sous-agents ou interrompre leur fonctionnement." + } +} diff --git a/packages/subagent/tool-subagent-control/locale/pt.json b/packages/subagent/tool-subagent-control/locale/pt.json new file mode 100644 index 0000000000..35ef3ca2ac --- /dev/null +++ b/packages/subagent/tool-subagent-control/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramentas de controle de subagentes", + "description": "Deixe a IA enviar mensagens aos subagentes ou interromper sua operação." + } +} diff --git a/packages/subagent/tool-subagent-control/locale/ru.json b/packages/subagent/tool-subagent-control/locale/ru.json new file mode 100644 index 0000000000..46c83a51a7 --- /dev/null +++ b/packages/subagent/tool-subagent-control/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Инструменты управления субагентами", + "description": "Позвольте ИИ отправлять сообщения субагентам или прерывать их работу." + } +} diff --git a/packages/subagent/tool-subagent/locale/de.json b/packages/subagent/tool-subagent/locale/de.json new file mode 100644 index 0000000000..be68005287 --- /dev/null +++ b/packages/subagent/tool-subagent/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Subagenten-Delegierungstool", + "description": "Lassen Sie die KI Unteragenten Aufgaben zuweisen und die laufenden Ergebnisse erhalten." + } +} diff --git a/packages/subagent/tool-subagent/locale/es.json b/packages/subagent/tool-subagent/locale/es.json new file mode 100644 index 0000000000..821a4d5790 --- /dev/null +++ b/packages/subagent/tool-subagent/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramienta de delegación de subagente", + "description": "Deje que la IA asigne tareas a subagentes y obtenga los resultados en ejecución." + } +} diff --git a/packages/subagent/tool-subagent/locale/fr.json b/packages/subagent/tool-subagent/locale/fr.json new file mode 100644 index 0000000000..a3108b713d --- /dev/null +++ b/packages/subagent/tool-subagent/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outil de délégation de sous-agents", + "description": "Laissez l'IA attribuer des tâches aux sous-agents et obtenir les résultats en cours." + } +} diff --git a/packages/subagent/tool-subagent/locale/model-selection-settings/de.json b/packages/subagent/tool-subagent/locale/model-selection-settings/de.json new file mode 100644 index 0000000000..55d0f5d058 --- /dev/null +++ b/packages/subagent/tool-subagent/locale/model-selection-settings/de.json @@ -0,0 +1,5 @@ +{ + "meta": { + "title": "Modellauswahl für Unteragenten" + } +} diff --git a/packages/subagent/tool-subagent/locale/model-selection-settings/es.json b/packages/subagent/tool-subagent/locale/model-selection-settings/es.json new file mode 100644 index 0000000000..5123f22b74 --- /dev/null +++ b/packages/subagent/tool-subagent/locale/model-selection-settings/es.json @@ -0,0 +1,5 @@ +{ + "meta": { + "title": "Configuración de selección de modelos de subagentes" + } +} diff --git a/packages/subagent/tool-subagent/locale/model-selection-settings/fr.json b/packages/subagent/tool-subagent/locale/model-selection-settings/fr.json new file mode 100644 index 0000000000..87d4f57ad4 --- /dev/null +++ b/packages/subagent/tool-subagent/locale/model-selection-settings/fr.json @@ -0,0 +1,5 @@ +{ + "meta": { + "title": "Paramètres de sélection des modèles des sous-agents" + } +} diff --git a/packages/subagent/tool-subagent/locale/model-selection-settings/pt.json b/packages/subagent/tool-subagent/locale/model-selection-settings/pt.json new file mode 100644 index 0000000000..59bcc83656 --- /dev/null +++ b/packages/subagent/tool-subagent/locale/model-selection-settings/pt.json @@ -0,0 +1,5 @@ +{ + "meta": { + "title": "Configurações de seleção de modelos dos subagentes" + } +} diff --git a/packages/subagent/tool-subagent/locale/model-selection-settings/ru.json b/packages/subagent/tool-subagent/locale/model-selection-settings/ru.json new file mode 100644 index 0000000000..015c8a8885 --- /dev/null +++ b/packages/subagent/tool-subagent/locale/model-selection-settings/ru.json @@ -0,0 +1,5 @@ +{ + "meta": { + "title": "Настройки выбора модели для субагентов" + } +} diff --git a/packages/subagent/tool-subagent/locale/pt.json b/packages/subagent/tool-subagent/locale/pt.json new file mode 100644 index 0000000000..be0acc4513 --- /dev/null +++ b/packages/subagent/tool-subagent/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramenta de delegação de subagentes", + "description": "Deixe a IA atribuir tarefas aos subagentes e obter os resultados da execução." + } +} diff --git a/packages/subagent/tool-subagent/locale/ru.json b/packages/subagent/tool-subagent/locale/ru.json new file mode 100644 index 0000000000..0e207abd42 --- /dev/null +++ b/packages/subagent/tool-subagent/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Инструмент делегирования субагента", + "description": "Позвольте ИИ назначать задачи субагентам и получать текущие результаты." + } +} diff --git a/packages/subprocess/subprocess-local/locale/de.json b/packages/subprocess/subprocess-local/locale/de.json new file mode 100644 index 0000000000..a9527c9794 --- /dev/null +++ b/packages/subprocess/subprocess-local/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "lokaler untergeordneter Prozess", + "description": "Bietet lokale Prozessstart- und Verwaltungsfunktionen für andere Plug-Ins." + } +} diff --git a/packages/subprocess/subprocess-local/locale/es.json b/packages/subprocess/subprocess-local/locale/es.json new file mode 100644 index 0000000000..24d4f34acb --- /dev/null +++ b/packages/subprocess/subprocess-local/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "proceso secundario local", + "description": "Proporciona capacidades de gestión e inicio de procesos locales para otros complementos." + } +} diff --git a/packages/subprocess/subprocess-local/locale/fr.json b/packages/subprocess/subprocess-local/locale/fr.json new file mode 100644 index 0000000000..48e83442a2 --- /dev/null +++ b/packages/subprocess/subprocess-local/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "processus enfant local", + "description": "Fournit des fonctionnalités de démarrage et de gestion de processus locaux pour d’autres plug-ins." + } +} diff --git a/packages/subprocess/subprocess-local/locale/pt.json b/packages/subprocess/subprocess-local/locale/pt.json new file mode 100644 index 0000000000..5b7ea24676 --- /dev/null +++ b/packages/subprocess/subprocess-local/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "processo filho local", + "description": "Fornece recursos de inicialização e gerenciamento de processos locais para outros plug-ins." + } +} diff --git a/packages/subprocess/subprocess-local/locale/ru.json b/packages/subprocess/subprocess-local/locale/ru.json new file mode 100644 index 0000000000..5a1d107814 --- /dev/null +++ b/packages/subprocess/subprocess-local/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "локальный дочерний процесс", + "description": "Предоставляет возможности локального запуска процессов и управления для других подключаемых модулей." + } +} diff --git a/packages/telemetry/otel/locale/de.json b/packages/telemetry/otel/locale/de.json new file mode 100644 index 0000000000..0617227978 --- /dev/null +++ b/packages/telemetry/otel/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Hotel", + "description": "Stellen Sie unabhängige Datenberichtskanäle für Produktereignisse und Sitzungsprotokolle bereit." + } +} diff --git a/packages/telemetry/otel/locale/es.json b/packages/telemetry/otel/locale/es.json new file mode 100644 index 0000000000..d7b40160cb --- /dev/null +++ b/packages/telemetry/otel/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "hotel", + "description": "Proporcione canales de informes de datos independientes para eventos de productos y registros de sesiones." + } +} diff --git a/packages/telemetry/otel/locale/fr.json b/packages/telemetry/otel/locale/fr.json new file mode 100644 index 0000000000..98a7284060 --- /dev/null +++ b/packages/telemetry/otel/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "hôtel", + "description": "Fournissez des canaux de reporting de données indépendants pour les événements de produits et les journaux de session." + } +} diff --git a/packages/telemetry/otel/locale/pt.json b/packages/telemetry/otel/locale/pt.json new file mode 100644 index 0000000000..eee3a1938e --- /dev/null +++ b/packages/telemetry/otel/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "hotel", + "description": "Forneça canais independentes de relatórios de dados para eventos de produtos e logs de sessões." + } +} diff --git a/packages/telemetry/otel/locale/ru.json b/packages/telemetry/otel/locale/ru.json new file mode 100644 index 0000000000..6a29c4f388 --- /dev/null +++ b/packages/telemetry/otel/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "отель", + "description": "Обеспечьте независимые каналы передачи данных для событий продукта и журналов сеансов." + } +} diff --git a/packages/terminal/terminal-bash/locale/de.json b/packages/terminal/terminal-bash/locale/de.json new file mode 100644 index 0000000000..4ce1479d79 --- /dev/null +++ b/packages/terminal/terminal-bash/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Persistentes Shell-Backend", + "description": "Stellt ein Shell-Terminal bereit, das den Status über mehrere Aufrufe hinweg beibehält." + } +} diff --git a/packages/terminal/terminal-bash/locale/es.json b/packages/terminal/terminal-bash/locale/es.json new file mode 100644 index 0000000000..1f22763ea6 --- /dev/null +++ b/packages/terminal/terminal-bash/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Backend de Shell persistente", + "description": "Proporciona una terminal de shell que conserva el estado en múltiples invocaciones." + } +} diff --git a/packages/terminal/terminal-bash/locale/fr.json b/packages/terminal/terminal-bash/locale/fr.json new file mode 100644 index 0000000000..1fd07f813a --- /dev/null +++ b/packages/terminal/terminal-bash/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Backend Shell persistant", + "description": "Fournit un terminal shell qui préserve l’état lors de plusieurs appels." + } +} diff --git a/packages/terminal/terminal-bash/locale/pt.json b/packages/terminal/terminal-bash/locale/pt.json new file mode 100644 index 0000000000..06507f1222 --- /dev/null +++ b/packages/terminal/terminal-bash/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Back-end de Shell persistente", + "description": "Fornece um terminal shell que preserva o estado em várias invocações." + } +} diff --git a/packages/terminal/terminal-bash/locale/ru.json b/packages/terminal/terminal-bash/locale/ru.json new file mode 100644 index 0000000000..0cb2faed11 --- /dev/null +++ b/packages/terminal/terminal-bash/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Серверная часть Persistent Shell", + "description": "Предоставляет терминал оболочки, который сохраняет состояние при нескольких вызовах." + } +} diff --git a/packages/terminal/terminal/locale/de.json b/packages/terminal/terminal/locale/de.json new file mode 100644 index 0000000000..ee73e72526 --- /dev/null +++ b/packages/terminal/terminal/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Terminal", + "description": "Verwalten Sie persistente interaktive Terminalsitzungen sowie deren Eingabe, Ausgabe und Bereinigung." + } +} diff --git a/packages/terminal/terminal/locale/es.json b/packages/terminal/terminal/locale/es.json new file mode 100644 index 0000000000..54801edb87 --- /dev/null +++ b/packages/terminal/terminal/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "terminales", + "description": "Administre sesiones de terminal interactivas persistentes y su entrada, salida y limpieza." + } +} diff --git a/packages/terminal/terminal/locale/fr.json b/packages/terminal/terminal/locale/fr.json new file mode 100644 index 0000000000..f3b23d6365 --- /dev/null +++ b/packages/terminal/terminal/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "borne", + "description": "Gérez les sessions de terminal interactif persistant ainsi que leurs entrées, sorties et nettoyage." + } +} diff --git a/packages/terminal/terminal/locale/pt.json b/packages/terminal/terminal/locale/pt.json new file mode 100644 index 0000000000..3696ad7e55 --- /dev/null +++ b/packages/terminal/terminal/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "terminal", + "description": "Gerencie sessões de terminal interativo persistentes e sua entrada, saída e limpeza." + } +} diff --git a/packages/terminal/terminal/locale/ru.json b/packages/terminal/terminal/locale/ru.json new file mode 100644 index 0000000000..9e6d6bb686 --- /dev/null +++ b/packages/terminal/terminal/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "терминал", + "description": "Управляйте постоянными интерактивными сеансами терминала, а также их вводом, выводом и очисткой." + } +} diff --git a/packages/todo/tool-todo/locale/de.json b/packages/todo/tool-todo/locale/de.json new file mode 100644 index 0000000000..5f058e5860 --- /dev/null +++ b/packages/todo/tool-todo/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "To-Do-Listen-Tool", + "description": "Lassen Sie die KI Aufgaben-To-Do-Listen erstellen und aktualisieren." + } +} diff --git a/packages/todo/tool-todo/locale/es.json b/packages/todo/tool-todo/locale/es.json new file mode 100644 index 0000000000..0ba998d5d3 --- /dev/null +++ b/packages/todo/tool-todo/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramienta de lista de tareas pendientes", + "description": "Deje que AI cree y actualice listas de tareas pendientes." + } +} diff --git a/packages/todo/tool-todo/locale/fr.json b/packages/todo/tool-todo/locale/fr.json new file mode 100644 index 0000000000..2016c3377c --- /dev/null +++ b/packages/todo/tool-todo/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outil de liste de tâches", + "description": "Laissez l'IA créer et mettre à jour des listes de tâches à effectuer." + } +} diff --git a/packages/todo/tool-todo/locale/pt.json b/packages/todo/tool-todo/locale/pt.json new file mode 100644 index 0000000000..50b6e41221 --- /dev/null +++ b/packages/todo/tool-todo/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramenta de lista de tarefas", + "description": "Deixe a IA criar e atualizar listas de tarefas pendentes." + } +} diff --git a/packages/todo/tool-todo/locale/ru.json b/packages/todo/tool-todo/locale/ru.json new file mode 100644 index 0000000000..1ae139e117 --- /dev/null +++ b/packages/todo/tool-todo/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Инструмент списка дел", + "description": "Позвольте ИИ создавать и обновлять списки дел." + } +} diff --git a/packages/typert/loader/locale/de.json b/packages/typert/loader/locale/de.json new file mode 100644 index 0000000000..6b31833d3d --- /dev/null +++ b/packages/typert/loader/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Laden des Typert-Typs", + "description": "Laden Sie die vom Plug-in generierten Typinformationen zur Abfrage und zum Aufruf zur Laufzeit." + } +} diff --git a/packages/typert/loader/locale/es.json b/packages/typert/loader/locale/es.json new file mode 100644 index 0000000000..75d0f730f7 --- /dev/null +++ b/packages/typert/loader/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Carga tipo Typert", + "description": "Cargue la información de tipo generada por el complemento para consultarla y llamarla en tiempo de ejecución." + } +} diff --git a/packages/typert/loader/locale/fr.json b/packages/typert/loader/locale/fr.json new file mode 100644 index 0000000000..db75da99ef --- /dev/null +++ b/packages/typert/loader/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Chargement de type Typert", + "description": "Chargez les informations de type générées par le plug-in pour la requête et l'appel au moment de l'exécution." + } +} diff --git a/packages/typert/loader/locale/pt.json b/packages/typert/loader/locale/pt.json new file mode 100644 index 0000000000..e6dd020267 --- /dev/null +++ b/packages/typert/loader/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Carregamento do tipo Typert", + "description": "Carregue as informações de tipo geradas pelo plug-in para consulta e chamada em tempo de execução." + } +} diff --git a/packages/typert/loader/locale/ru.json b/packages/typert/loader/locale/ru.json new file mode 100644 index 0000000000..a80e24ce51 --- /dev/null +++ b/packages/typert/loader/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Тип загрузки типа", + "description": "Загрузите информацию о типе, сгенерированную подключаемым модулем, для запроса и вызова во время выполнения." + } +} diff --git a/packages/typert/registry/locale/de.json b/packages/typert/registry/locale/de.json new file mode 100644 index 0000000000..0783a102b5 --- /dev/null +++ b/packages/typert/registry/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Typert-Typregistrierung", + "description": "Stellt Laufzeittypinformationen und Remote-Aufrufdefinitionen für Plug-Ins bereit." + } +} diff --git a/packages/typert/registry/locale/es.json b/packages/typert/registry/locale/es.json new file mode 100644 index 0000000000..ec708bcfae --- /dev/null +++ b/packages/typert/registry/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "registro tipo typert", + "description": "Proporciona información sobre el tipo de tiempo de ejecución y definiciones de llamadas remotas a los complementos." + } +} diff --git a/packages/typert/registry/locale/fr.json b/packages/typert/registry/locale/fr.json new file mode 100644 index 0000000000..08443c7b29 --- /dev/null +++ b/packages/typert/registry/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Registre de types Typert", + "description": "Fournit des informations sur le type d’exécution et des définitions d’appels distants aux plug-ins." + } +} diff --git a/packages/typert/registry/locale/pt.json b/packages/typert/registry/locale/pt.json new file mode 100644 index 0000000000..a1ccb6eacd --- /dev/null +++ b/packages/typert/registry/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Registro do tipo Typert", + "description": "Fornece informações de tipo de tempo de execução e definições de chamadas remotas para plug-ins." + } +} diff --git a/packages/typert/registry/locale/ru.json b/packages/typert/registry/locale/ru.json new file mode 100644 index 0000000000..07ef72f9d1 --- /dev/null +++ b/packages/typert/registry/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Тип реестра типов", + "description": "Предоставляет информацию о типах среды выполнения и определения удаленных вызовов для подключаемых модулей." + } +} diff --git a/packages/web/tool-web/locale/de.json b/packages/web/tool-web/locale/de.json new file mode 100644 index 0000000000..13479d9915 --- /dev/null +++ b/packages/web/tool-web/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Websuch- und Lesetools", + "description": "Lassen Sie die KI das Web durchsuchen und den Seiteninhalt lesen." + } +} diff --git a/packages/web/tool-web/locale/es.json b/packages/web/tool-web/locale/es.json new file mode 100644 index 0000000000..23d0b51c71 --- /dev/null +++ b/packages/web/tool-web/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramientas de búsqueda y lectura web.", + "description": "Deje que AI busque en la web y lea el contenido de la página." + } +} diff --git a/packages/web/tool-web/locale/fr.json b/packages/web/tool-web/locale/fr.json new file mode 100644 index 0000000000..fe0b0d5dfe --- /dev/null +++ b/packages/web/tool-web/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outils de recherche et de lecture sur le Web", + "description": "Laissez l'IA rechercher sur le Web et lire le contenu de la page." + } +} diff --git a/packages/web/tool-web/locale/pt.json b/packages/web/tool-web/locale/pt.json new file mode 100644 index 0000000000..9d19ee2979 --- /dev/null +++ b/packages/web/tool-web/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramentas de pesquisa e leitura na web", + "description": "Deixe a IA pesquisar na web e ler o conteúdo da página." + } +} diff --git a/packages/web/tool-web/locale/ru.json b/packages/web/tool-web/locale/ru.json new file mode 100644 index 0000000000..2b487b8bf9 --- /dev/null +++ b/packages/web/tool-web/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Инструменты веб-поиска и чтения", + "description": "Позвольте ИИ искать в Интернете и читать содержимое страниц." + } +} diff --git a/packages/web/web-deepseek-api/locale/de.json b/packages/web/web-deepseek-api/locale/de.json new file mode 100644 index 0000000000..ed74fa65aa --- /dev/null +++ b/packages/web/web-deepseek-api/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Websuche und Crawling API", + "description": "Verwenden Sie DeepSeekSuchenAPI, um die Webseite zu durchsuchen, und Abrufen API, um den Webseitentext zu crawlen." + } +} diff --git a/packages/web/web-deepseek-api/locale/es.json b/packages/web/web-deepseek-api/locale/es.json new file mode 100644 index 0000000000..dc442c6219 --- /dev/null +++ b/packages/web/web-deepseek-api/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Búsqueda y rastreo web API", + "description": "Utilice DeepSeekBuscar API para buscar en la página web y Buscar API para rastrear el texto de la página web." + } +} diff --git a/packages/web/web-deepseek-api/locale/fr.json b/packages/web/web-deepseek-api/locale/fr.json new file mode 100644 index 0000000000..ee128f3d8b --- /dev/null +++ b/packages/web/web-deepseek-api/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Recherche et exploration sur le Web API", + "description": "Utilisez DeepSeekRechercherAPI pour rechercher la page Web et RécupérerAPI pour explorer le texte de la page Web." + } +} diff --git a/packages/web/web-deepseek-api/locale/pt.json b/packages/web/web-deepseek-api/locale/pt.json new file mode 100644 index 0000000000..4dbd09b87a --- /dev/null +++ b/packages/web/web-deepseek-api/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Pesquisa e rastreamento na Web API", + "description": "Use DeepSeekPesquisarAPI para pesquisar a página da web e Buscar API para rastrear o texto da página da web." + } +} diff --git a/packages/web/web-deepseek-api/locale/ru.json b/packages/web/web-deepseek-api/locale/ru.json new file mode 100644 index 0000000000..0609788669 --- /dev/null +++ b/packages/web/web-deepseek-api/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Поиск и сканирование в Интернете API", + "description": "Используйте DeepSeekПоиск API для поиска на веб-странице и функцию \"Поиск\" API для сканирования текста веб-страницы." + } +} diff --git a/packages/web/web-fetch-http/locale/de.json b/packages/web/web-fetch-http/locale/de.json new file mode 100644 index 0000000000..ba13c69285 --- /dev/null +++ b/packages/web/web-fetch-http/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Von öffentlichen Webseiten beziehen", + "description": "Lesen Sie den Inhalt der Webseite HTTP oder HTTPS, ohne dass eine Anmeldung erforderlich ist." + } +} diff --git a/packages/web/web-fetch-http/locale/es.json b/packages/web/web-fetch-http/locale/es.json new file mode 100644 index 0000000000..97bb75f9fa --- /dev/null +++ b/packages/web/web-fetch-http/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Obtener de páginas web públicas", + "description": "Lea el contenido de la página web HTTP o HTTPS sin necesidad de iniciar sesión." + } +} diff --git a/packages/web/web-fetch-http/locale/fr.json b/packages/web/web-fetch-http/locale/fr.json new file mode 100644 index 0000000000..c4717a1d24 --- /dev/null +++ b/packages/web/web-fetch-http/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Obtenir à partir de pages Web publiques", + "description": "Lisez le contenu de la page Web HTTP ou HTTPS sans nécessiter de connexion." + } +} diff --git a/packages/web/web-fetch-http/locale/pt.json b/packages/web/web-fetch-http/locale/pt.json new file mode 100644 index 0000000000..48cc7d1cfb --- /dev/null +++ b/packages/web/web-fetch-http/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Obter de páginas da web públicas", + "description": "Leia o conteúdo da página da web HTTP ou HTTPS sem precisar fazer login." + } +} diff --git a/packages/web/web-fetch-http/locale/ru.json b/packages/web/web-fetch-http/locale/ru.json new file mode 100644 index 0000000000..642148b75c --- /dev/null +++ b/packages/web/web-fetch-http/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Получить с общедоступных веб-страниц", + "description": "Прочтите содержимое веб-страницы HTTP или HTTPS без необходимости входа в систему." + } +} diff --git a/packages/web/web-search-deepseek/locale/de.json b/packages/web/web-search-deepseek/locale/de.json new file mode 100644 index 0000000000..7ac9d5c096 --- /dev/null +++ b/packages/web/web-search-deepseek/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek Websuche", + "description": "Stellen Sie Websuchergebnisse über DeepSeek bereit." + } +} diff --git a/packages/web/web-search-deepseek/locale/es.json b/packages/web/web-search-deepseek/locale/es.json new file mode 100644 index 0000000000..8a5ed6f6a8 --- /dev/null +++ b/packages/web/web-search-deepseek/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek búsqueda web", + "description": "Ofrecer resultados de búsqueda web a través de DeepSeek." + } +} diff --git a/packages/web/web-search-deepseek/locale/fr.json b/packages/web/web-search-deepseek/locale/fr.json new file mode 100644 index 0000000000..84d00356aa --- /dev/null +++ b/packages/web/web-search-deepseek/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek recherche sur le Web", + "description": "Présentez les résultats de recherche sur le Web via DeepSeek." + } +} diff --git a/packages/web/web-search-deepseek/locale/pt.json b/packages/web/web-search-deepseek/locale/pt.json new file mode 100644 index 0000000000..ab385434a1 --- /dev/null +++ b/packages/web/web-search-deepseek/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek pesquisa na web", + "description": "Veicule resultados de pesquisa na Web por meio de DeepSeek." + } +} diff --git a/packages/web/web-search-deepseek/locale/ru.json b/packages/web/web-search-deepseek/locale/ru.json new file mode 100644 index 0000000000..cea72492ab --- /dev/null +++ b/packages/web/web-search-deepseek/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "DeepSeek веб-поиск", + "description": "Предоставляйте результаты веб-поиска через DeepSeek." + } +} diff --git a/packages/web/web-search-exa/locale/de.json b/packages/web/web-search-exa/locale/de.json new file mode 100644 index 0000000000..b34a2ecd25 --- /dev/null +++ b/packages/web/web-search-exa/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Exa-Websuche", + "description": "Durchsuchen Sie das Web mit Exa." + } +} diff --git a/packages/web/web-search-exa/locale/es.json b/packages/web/web-search-exa/locale/es.json new file mode 100644 index 0000000000..fcc3ee4c7c --- /dev/null +++ b/packages/web/web-search-exa/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Exa búsqueda web", + "description": "Busque en la Web a través de Exa." + } +} diff --git a/packages/web/web-search-exa/locale/fr.json b/packages/web/web-search-exa/locale/fr.json new file mode 100644 index 0000000000..8ee6236f6b --- /dev/null +++ b/packages/web/web-search-exa/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Recherche sur le Web Exa", + "description": "Recherchez sur le Web via Exa." + } +} diff --git a/packages/web/web-search-exa/locale/pt.json b/packages/web/web-search-exa/locale/pt.json new file mode 100644 index 0000000000..eb2081f00d --- /dev/null +++ b/packages/web/web-search-exa/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Exa pesquisa na web", + "description": "Pesquise na Web através do Exa." + } +} diff --git a/packages/web/web-search-exa/locale/ru.json b/packages/web/web-search-exa/locale/ru.json new file mode 100644 index 0000000000..8240ca4a31 --- /dev/null +++ b/packages/web/web-search-exa/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Веб-поиск Exa", + "description": "Поиск в Интернете через Exa." + } +} diff --git a/packages/web/web-search-perplexity/locale/de.json b/packages/web/web-search-perplexity/locale/de.json new file mode 100644 index 0000000000..b689965afe --- /dev/null +++ b/packages/web/web-search-perplexity/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Verwirrung bei der Websuche", + "description": "Durchsuchen Sie das Web mithilfe von Perplexity." + } +} diff --git a/packages/web/web-search-perplexity/locale/es.json b/packages/web/web-search-perplexity/locale/es.json new file mode 100644 index 0000000000..fd9386d848 --- /dev/null +++ b/packages/web/web-search-perplexity/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Búsqueda web de perplejidad", + "description": "Busque en la Web a través de la perplejidad." + } +} diff --git a/packages/web/web-search-perplexity/locale/fr.json b/packages/web/web-search-perplexity/locale/fr.json new file mode 100644 index 0000000000..7753f0205b --- /dev/null +++ b/packages/web/web-search-perplexity/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Recherche sur le Web Perplexité", + "description": "Recherchez sur le Web grâce à Perplexity." + } +} diff --git a/packages/web/web-search-perplexity/locale/pt.json b/packages/web/web-search-perplexity/locale/pt.json new file mode 100644 index 0000000000..474178de63 --- /dev/null +++ b/packages/web/web-search-perplexity/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Pesquisa na web de perplexidade", + "description": "Pesquise na Web através da perplexidade." + } +} diff --git a/packages/web/web-search-perplexity/locale/ru.json b/packages/web/web-search-perplexity/locale/ru.json new file mode 100644 index 0000000000..bec57bdb8f --- /dev/null +++ b/packages/web/web-search-perplexity/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Недоумение в веб-поиске", + "description": "Поиск в Интернете через недоумение." + } +} diff --git a/packages/web/web/locale/de.json b/packages/web/web/locale/de.json new file mode 100644 index 0000000000..1b48304e4d --- /dev/null +++ b/packages/web/web/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Web", + "description": "Ein Dienstanbieter, der Websuche und Inhaltserfassung vereint." + } +} diff --git a/packages/web/web/locale/es.json b/packages/web/web/locale/es.json new file mode 100644 index 0000000000..d71b783ded --- /dev/null +++ b/packages/web/web/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "web", + "description": "Un proveedor de servicios que unifica la búsqueda web y la adquisición de contenidos." + } +} diff --git a/packages/web/web/locale/fr.json b/packages/web/web/locale/fr.json new file mode 100644 index 0000000000..adc2ca8ef7 --- /dev/null +++ b/packages/web/web/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "la toile", + "description": "Un fournisseur de services qui unifie la recherche sur le Web et l'acquisition de contenu." + } +} diff --git a/packages/web/web/locale/pt.json b/packages/web/web/locale/pt.json new file mode 100644 index 0000000000..df48f575dc --- /dev/null +++ b/packages/web/web/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "rede", + "description": "Um provedor de serviços que unifica a pesquisa na web e a aquisição de conteúdo." + } +} diff --git a/packages/web/web/locale/ru.json b/packages/web/web/locale/ru.json new file mode 100644 index 0000000000..195b9bcde6 --- /dev/null +++ b/packages/web/web/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "сеть", + "description": "Поставщик услуг, который объединяет веб-поиск и получение контента." + } +} diff --git a/packages/workflow/tool-workflow/locale/de.json b/packages/workflow/tool-workflow/locale/de.json new file mode 100644 index 0000000000..c801eb7d71 --- /dev/null +++ b/packages/workflow/tool-workflow/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Workflow-Tools", + "description": "Lassen Sie die KI JavaScript-Skripte schreiben und ausführen, um mehrere Werkzeugvorgänge zu orchestrieren." + } +} diff --git a/packages/workflow/tool-workflow/locale/es.json b/packages/workflow/tool-workflow/locale/es.json new file mode 100644 index 0000000000..342b704900 --- /dev/null +++ b/packages/workflow/tool-workflow/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Herramientas de flujo de trabajo", + "description": "Deje que la IA escriba y ejecute scripts JavaScript para organizar múltiples operaciones de herramientas." + } +} diff --git a/packages/workflow/tool-workflow/locale/fr.json b/packages/workflow/tool-workflow/locale/fr.json new file mode 100644 index 0000000000..4559206d9c --- /dev/null +++ b/packages/workflow/tool-workflow/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Outils de flux de travail", + "description": "Laissez l'IA écrire et exécuter des scripts JavaScript pour orchestrer plusieurs opérations d'outils." + } +} diff --git a/packages/workflow/tool-workflow/locale/pt.json b/packages/workflow/tool-workflow/locale/pt.json new file mode 100644 index 0000000000..6b2a0d027c --- /dev/null +++ b/packages/workflow/tool-workflow/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Ferramentas de fluxo de trabalho", + "description": "Deixe a IA escrever e executar scripts JavaScript para orquestrar várias operações de ferramentas." + } +} diff --git a/packages/workflow/tool-workflow/locale/ru.json b/packages/workflow/tool-workflow/locale/ru.json new file mode 100644 index 0000000000..49a8f98054 --- /dev/null +++ b/packages/workflow/tool-workflow/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Инструменты рабочего процесса", + "description": "Позвольте ИИ писать и запускать сценарии JavaScript для управления несколькими операциями инструментов." + } +} diff --git a/packages/workflow/workflow-ptc/locale/de.json b/packages/workflow/workflow-ptc/locale/de.json new file mode 100644 index 0000000000..21c3bf81fc --- /dev/null +++ b/packages/workflow/workflow-ptc/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Workflow-Ausführungs-Engine", + "description": "Führen Sie Workflow-Orchestrierungscode mit der gemeinsam genutzten PTC-Laufzeit aus." + } +} diff --git a/packages/workflow/workflow-ptc/locale/es.json b/packages/workflow/workflow-ptc/locale/es.json new file mode 100644 index 0000000000..22a11daac1 --- /dev/null +++ b/packages/workflow/workflow-ptc/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Motor de ejecución de flujo de trabajo", + "description": "Ejecute el código de orquestación del flujo de trabajo utilizando el tiempo de ejecución compartido PTC." + } +} diff --git a/packages/workflow/workflow-ptc/locale/fr.json b/packages/workflow/workflow-ptc/locale/fr.json new file mode 100644 index 0000000000..d592c7f611 --- /dev/null +++ b/packages/workflow/workflow-ptc/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Moteur d'exécution de workflow", + "description": "Exécutez le code d'orchestration de workflow à l'aide du runtime PTC partagé." + } +} diff --git a/packages/workflow/workflow-ptc/locale/pt.json b/packages/workflow/workflow-ptc/locale/pt.json new file mode 100644 index 0000000000..b180466f0b --- /dev/null +++ b/packages/workflow/workflow-ptc/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Mecanismo de execução de fluxo de trabalho", + "description": "Execute o código de orquestração de fluxo de trabalho usando o tempo de execução PTC compartilhado." + } +} diff --git a/packages/workflow/workflow-ptc/locale/ru.json b/packages/workflow/workflow-ptc/locale/ru.json new file mode 100644 index 0000000000..b0027a6b16 --- /dev/null +++ b/packages/workflow/workflow-ptc/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Механизм выполнения рабочего процесса", + "description": "Выполните код оркестрации рабочего процесса, используя общую среду выполнения PTC." + } +} diff --git a/packages/workspace/workspace/locale/de.json b/packages/workspace/workspace/locale/de.json new file mode 100644 index 0000000000..b79a4e1eec --- /dev/null +++ b/packages/workspace/workspace/locale/de.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Arbeitsbereich", + "description": "Speichern Sie Arbeitsbereichsinformationen und verwalten Sie Arbeitsbereichs-Sitzungszuordnungen." + } +} diff --git a/packages/workspace/workspace/locale/es.json b/packages/workspace/workspace/locale/es.json new file mode 100644 index 0000000000..01effd793a --- /dev/null +++ b/packages/workspace/workspace/locale/es.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "espacio de trabajo", + "description": "Guarde información del espacio de trabajo y administre asociaciones de sesión de espacio de trabajo." + } +} diff --git a/packages/workspace/workspace/locale/fr.json b/packages/workspace/workspace/locale/fr.json new file mode 100644 index 0000000000..5698f7a4f6 --- /dev/null +++ b/packages/workspace/workspace/locale/fr.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "espace de travail", + "description": "Enregistrez les informations de l’espace de travail et gérez les associations espace de travail-session." + } +} diff --git a/packages/workspace/workspace/locale/pt.json b/packages/workspace/workspace/locale/pt.json new file mode 100644 index 0000000000..8b72a847e1 --- /dev/null +++ b/packages/workspace/workspace/locale/pt.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "área de trabalho", + "description": "Salve informações do espaço de trabalho e gerencie associações de sessões de espaço de trabalho." + } +} diff --git a/packages/workspace/workspace/locale/ru.json b/packages/workspace/workspace/locale/ru.json new file mode 100644 index 0000000000..89dc8341bd --- /dev/null +++ b/packages/workspace/workspace/locale/ru.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "рабочее пространство", + "description": "Сохраняйте информацию о рабочей области и управляйте ассоциациями рабочей области и сеанса." + } +} diff --git a/scripts/gen-official-bundle-catalog.spec.ts b/scripts/gen-official-bundle-catalog.spec.ts index ca722daeb9..a6d243d373 100644 --- a/scripts/gen-official-bundle-catalog.spec.ts +++ b/scripts/gen-official-bundle-catalog.spec.ts @@ -7,6 +7,8 @@ import { afterEach, describe, expect, it } from 'vitest' import { ON_DEMAND_BUNDLES } from '../packages/boot/official-bundles/src/index.ts' import { generateOfficialBundleCatalog, renderOfficialBundleCatalog, syncOfficialBundleCatalog } from './gen-official-bundle-catalog.ts' +import { SHIPPED_LOCALE_IDS } from './shipped-locales.ts' + const roots: string[] = [] const output = 'packages/boot/official-bundles/src/catalog.generated.ts' @@ -32,6 +34,7 @@ function fixture(): string { write(root, `${dir}/locale/en.json`, { meta: { title: 'Native agent', description: 'Delegate a task.' } }) write(root, `${dir}/locale/zh.json`, { meta: { title: '原生智能体', description: '委派任务。' } }) write(root, `${dir}/locale/ja.json`, { meta: { title: 'ネイティブエージェント', description: 'タスクを委派します。' } }) + for (const language of ['es', 'fr', 'de', 'ru', 'pt']) write(root, `${dir}/locale/${language}.json`, { meta: { title: 'Native agent', description: 'Delegate a task.' } }) } write(root, output, '') return root @@ -50,8 +53,8 @@ describe('Official bundle catalog generation', () => { const entries = generateOfficialBundleCatalog(fixture()) expect(entries.map(entry => entry.packageName)).toEqual(ON_DEMAND_BUNDLES) expect(entries[0]?.meta).toEqual({ - title: { en: 'Native agent', zh: '原生智能体', ja: 'ネイティブエージェント' }, - description: { en: 'Delegate a task.', zh: '委派任务。', ja: 'タスクを委派します。' }, + title: { en: 'Native agent', zh: '原生智能体', ja: 'ネイティブエージェント', ...Object.fromEntries(['es', 'fr', 'de', 'ru', 'pt'].map(id => [id, 'Native agent'])) }, + description: { en: 'Delegate a task.', zh: '委派任务。', ja: 'タスクを委派します。', ...Object.fromEntries(['es', 'fr', 'de', 'ru', 'pt'].map(id => [id, 'Delegate a task.'])) }, icon: `data:image/svg+xml;base64,${Buffer.from('').toString('base64')}`, }) expect(renderOfficialBundleCatalog(entries)).not.toContain('1.2.3') @@ -81,14 +84,14 @@ describe('Official bundle catalog generation', () => { expect(() => generateOfficialBundleCatalog(root, [ON_DEMAND_BUNDLES[0]!, ON_DEMAND_BUNDLES[0]!])).toThrow('distinct package names') }) - it.each(['icon', 'en', 'zh', 'ja'])('rejects missing %s metadata', (resource) => { + it.each(['icon', ...SHIPPED_LOCALE_IDS])('rejects missing %s metadata', (resource) => { const root = fixture() const dir = directory(ON_DEMAND_BUNDLES[0]!) rmSync(join(root, dir, resource === 'icon' ? 'icon.svg' : `locale/${resource}.json`)) expect(() => generateOfficialBundleCatalog(root)).toThrow() }) - it.each(['en', 'zh', 'ja'])('requires explicit %s fields instead of metadata fallback text', (language) => { + it.each(SHIPPED_LOCALE_IDS)('requires explicit %s fields instead of metadata fallback text', (language) => { const root = fixture() write(root, `${directory(ON_DEMAND_BUNDLES[0]!)}/locale/${language}.json`, { meta: { description: 'Only a description.' } }) expect(() => generateOfficialBundleCatalog(root)).toThrow(`explicit ${language} title and description`) diff --git a/scripts/gen-official-bundle-catalog.ts b/scripts/gen-official-bundle-catalog.ts index 96e0ed741a..0bc5b7aaf6 100644 --- a/scripts/gen-official-bundle-catalog.ts +++ b/scripts/gen-official-bundle-catalog.ts @@ -9,6 +9,8 @@ import { ON_DEMAND_BUNDLES } from '../packages/boot/official-bundles/src/bundles import type { OfficialBundleCatalogEntry } from '../packages/boot/official-bundles/src/index.ts' import { readPluginMeta, resolvePluginResource } from '../packages/boot/app-boot/src/package-meta.ts' +import { SHIPPED_LOCALE_IDS } from './shipped-locales.ts' + const OUTPUT = 'packages/boot/official-bundles/src/catalog.generated.ts' /** @@ -49,7 +51,7 @@ export function generateOfficialBundleCatalog(root: string, names: readonly stri throw new Error(`${packageName}: Official catalog entries must be public DSH bundle packages`) } const parentURL = pathToFileURL(resolve(root, entry.path)).href - for (const language of ['en', 'zh', 'ja']) { + for (const language of SHIPPED_LOCALE_IDS) { const file = resolvePluginResource(`${packageName}/locale/${language}.json`, parentURL) const dictionary = JSON.parse(readFileSync(file, 'utf8')) as { meta?: { title?: unknown; description?: unknown } } if (typeof dictionary.meta?.title !== 'string' || dictionary.meta.title.trim() === '' @@ -63,7 +65,7 @@ export function generateOfficialBundleCatalog(root: string, names: readonly stri throw new Error(`${packageName}: Official catalog entries require an icon and localized title and description`) } for (const value of [meta.title, meta.description]) { - for (const language of ['en', 'zh', 'ja']) { + for (const language of SHIPPED_LOCALE_IDS) { if (typeof value[language] !== 'string' || value[language].trim() === '') { throw new Error(`${packageName}: Official metadata requires ${language} text`) } diff --git a/scripts/locale-dictionary-parity.spec.ts b/scripts/locale-dictionary-parity.spec.ts index e777cb5101..2488ed22e1 100644 --- a/scripts/locale-dictionary-parity.spec.ts +++ b/scripts/locale-dictionary-parity.spec.ts @@ -1,7 +1,7 @@ /** * Gate for the invariant `FALLBACK_LOCALE` rests on: every shipped dictionary - * declares the same keys in `zh`, `en`, and `ja`; Japanese dictionaries also - * preserve the English literal-template placeholders. + * declares the same keys in every shipped language; translations also + * preserve the English placeholders, command examples, and API field names. * * The locale runtime resolves a key through the active locale, then through * the single fallback locale (`en`), then surfaces the key itself. With @@ -27,6 +27,8 @@ import { fileURLToPath } from 'node:url' import ts from 'typescript' import { describe, expect, it } from 'vitest' +import { SHIPPED_LOCALE_IDS, localeTokens, type ShippedLocaleId } from './shipped-locales.ts' + const root = fileURLToPath(new URL('..', import.meta.url)) /** Repo-relative path with `/` separators, so messages and suffix tests match on every OS. */ @@ -101,7 +103,7 @@ function dictionariesIn(file: string): Dictionary[] { // before parsing — the silent narrowing this gate exists to prevent. A bare // `\b(zh|en)\b` misses `zhSettings`/`accessZh`, because `\b` does not hold // between `h` and an uppercase letter. - if (!/\b(zh|en|ja)\b|\b(zh|en|ja)[A-Z]|(Zh|En|Ja)\b/.test(text)) return [] + if (!/\b(zh|en|ja|es|fr|de|ru|pt)\b|\b(zh|en|ja|es|fr|de|ru|pt)[A-Z]|(Zh|En|Ja|Es|Fr|De|Ru|Pt)\b/.test(text)) return [] const source = ts.createSourceFile(file, text, ts.ScriptTarget.ESNext, true) const found: Dictionary[] = [] const rel = relative(file) @@ -153,7 +155,7 @@ function dictionariesIn(file: string): Dictionary[] { if (name === 'register' && node.arguments.length >= 3) { const [ns, tag, dict] = node.arguments if (ns === undefined || tag === undefined || !ts.isStringLiteral(tag)) return - if (tag.text !== 'zh' && tag.text !== 'en' && tag.text !== 'ja') return + if (!SHIPPED_LOCALE_IDS.some(id => id === tag.text)) return const raw = unwrap(dict) const literal = raw !== undefined && ts.isIdentifier(raw) ? (() => { @@ -185,7 +187,7 @@ function dictionariesIn(file: string): Dictionary[] { const literal = unwrap(dict) if (tag === undefined || !ts.isStringLiteral(tag)) continue if (literal === undefined || !ts.isObjectLiteralExpression(literal)) continue - if (tag.text !== 'zh' && tag.text !== 'en' && tag.text !== 'ja') continue + if (!SHIPPED_LOCALE_IDS.some(id => id === tag.text)) continue found.push({ file: rel, name: `${tag.text}@inline:${site}`, keys: keysOf(literal), templates: templatesOf(literal) }) } } @@ -239,8 +241,8 @@ function unwrap(node: ts.Expression | undefined): ts.Expression | undefined { * @param name - export name or synthetic inline name. * @returns locale plus pair key, or undefined when the name names no locale. */ -function localeOf(name: string): { locale: 'zh' | 'en' | 'ja'; pair: string } | undefined { - for (const locale of ['zh', 'en', 'ja'] as const) { +function localeOf(name: string): { locale: ShippedLocaleId; pair: string } | undefined { + for (const locale of SHIPPED_LOCALE_IDS) { const other = locale[0]!.toUpperCase() + locale.slice(1) if (name === locale) return { locale, pair: '' } // Synthetic names for inline shapes carry their own pair key after the @@ -255,9 +257,9 @@ function localeOf(name: string): { locale: 'zh' | 'en' | 'ja'; pair: string } | } /** - * Check that each object-form registration supplies its Japanese dictionary. + * Check that each object-form registration supplies every shipped-language dictionary. * @param file - absolute source path. - * @returns registration sites missing Japanese, or using an unresolved local identifier. + * @returns registration sites missing a shipped language, or using an unresolved local identifier. */ function registrationProblems(file: string): string[] { const text = readFileSync(file, 'utf8') @@ -289,11 +291,13 @@ function registrationProblems(file: string): string[] { } } if (entries.has('zh') && entries.has('en')) { - const ja = entries.get('ja') const site = `${relative(file)}:${source.getLineAndCharacterOfPosition(node.getStart(source)).line + 1}` - if (ja === undefined) problems.push(`${site}: registration has no Japanese dictionary`) - else if (ts.isIdentifier(ja) && !imported.has(ja.text) && !locals.has(ja.text)) { - problems.push(`${site}: Japanese dictionary ${ja.text} is not imported or declared`) + for (const language of SHIPPED_LOCALE_IDS) { + const dictionary = entries.get(language) + if (dictionary === undefined) problems.push(`${site}: registration has no ${language} dictionary`) + else if (ts.isIdentifier(dictionary) && !imported.has(dictionary.text) && !locals.has(dictionary.text)) { + problems.push(`${site}: ${language} dictionary ${dictionary.text} is not imported or declared`) + } } } } @@ -305,11 +309,11 @@ function registrationProblems(file: string): string[] { } describe('shipped locale dictionaries', () => { - it('registers Japanese alongside every object-form bilingual dictionary', () => { + it('registers every shipped language alongside every object-form bilingual dictionary', () => { expect(sourceFiles().flatMap(registrationProblems)).toEqual([]) }) - it('keeps bilingual keys aligned and Japanese keys and placeholders complete', () => { + it('keeps bilingual keys aligned and shipped-language keys and placeholders complete', () => { const files = sourceFiles() // Guard the discovery itself: an empty or narrowed sweep would pass every // assertion below while checking nothing. @@ -325,9 +329,9 @@ describe('shipped locale dictionaries', () => { if (dicts.length > 0) perFile.set(relative(file), dicts) } - const groups = new Map>() - const place = (key: string, locale: 'zh' | 'en' | 'ja', dict: Dictionary): void => { - const slot = groups.get(key) ?? new Map<'zh' | 'en' | 'ja', Dictionary>() + const groups = new Map>() + const place = (key: string, locale: ShippedLocaleId, dict: Dictionary): void => { + const slot = groups.get(key) ?? new Map() if (slot.has(locale)) { throw new Error(`two ${locale} dictionaries claim pair ${key}: ${slot.get(locale)?.file} and ${dict.file}`) } @@ -367,24 +371,27 @@ describe('shipped locale dictionaries', () => { const enOnly = en.keys.filter(k => !zh.keys.includes(k)) if (zhOnly.length > 0) problems.push(`${zh.file} ${zh.name} has keys absent from ${en.name}: ${zhOnly.join(', ')}`) if (enOnly.length > 0) problems.push(`${en.file} ${en.name} has keys absent from ${zh.name}: ${enOnly.join(', ')}`) - const ja = slot.get('ja') - if (ja === undefined) { - problems.push(`${key} has no Japanese dictionary`) - } else { - const missing = en.keys.filter(k => !ja.keys.includes(k)) - const extra = ja.keys.filter(k => !en.keys.includes(k)) - if (missing.length > 0 || extra.length > 0) { - problems.push(`${ja.file} ${ja.name}: missing [${missing.join(', ')}], extra [${extra.join(', ')}]`) - } - for (const [name, text] of Object.entries(en.templates)) { - const translated = ja.templates[name] - if (translated === undefined) continue - const placeholders = (value: string): string => (value.match(/\{\w+\}/gu) ?? []).sort().join(', ') - if (placeholders(text) !== placeholders(translated)) { - problems.push(`${ja.file} ${ja.name}.${name} changes placeholders from ${en.name}`) + for (const language of SHIPPED_LOCALE_IDS.filter(id => id !== 'en' && id !== 'zh')) { + const ja = slot.get(language) + if (ja === undefined) { + problems.push(`${key} has no ${language} dictionary`) + } else { + const missing = en.keys.filter(k => !ja.keys.includes(k)) + const extra = ja.keys.filter(k => !en.keys.includes(k)) + if (missing.length > 0 || extra.length > 0) { + problems.push(`${ja.file} ${ja.name}: missing [${missing.join(', ')}], extra [${extra.join(', ')}]`) + } + for (const [name, text] of Object.entries(en.templates)) { + const translated = ja.templates[name] + if (translated === undefined) continue + const placeholders = (value: string): string => localeTokens(value).join(', ') + if (placeholders(text) !== placeholders(translated)) { + problems.push(`${ja.file} ${ja.name}.${name} changes placeholders or literal tokens from ${en.name}`) + } } } } + } // The shipped dictionary count only grows; a collapse means discovery or diff --git a/scripts/run-gates.ts b/scripts/run-gates.ts index 5392190939..5735eddf96 100644 --- a/scripts/run-gates.ts +++ b/scripts/run-gates.ts @@ -392,7 +392,7 @@ function ciSharedStaticGates(): Gate[] { function i18nGates(includeDictionaries: boolean): Gate[] { return [ pnpmScript('installer-locales', 'verify-installer-locales', { label: 'Windows installer locales' }), - pnpmScript('locale-metadata', 'verify-locale-metadata', { label: 'Japanese plugin metadata' }), + pnpmScript('locale-metadata', 'verify-locale-metadata', { label: 'plugin locale metadata' }), ...includeDictionaries ? [pnpmExec('locale-dictionaries', ['vitest', 'run', 'scripts/locale-dictionary-parity.spec.ts'], { label: 'locale dictionaries' })] : [], ] } diff --git a/scripts/shipped-locales.spec.ts b/scripts/shipped-locales.spec.ts new file mode 100644 index 0000000000..be318f117e --- /dev/null +++ b/scripts/shipped-locales.spec.ts @@ -0,0 +1,22 @@ +/** Translations preserve executable command examples and named interpolation fields. */ +import { expect, it } from 'vitest' +import { localeTokens } from './shipped-locales.ts' + +it('retains repeated placeholders, commands, and API identifiers', () => { + expect(localeTokens('Use /plan off, /compact and /THEME=dark with {count}, {count} and reasoning_effort.')) + .toEqual(['/THEME=dark', '/compact', '/plan off', 'reasoning_effort', '{count}', '{count}']) +}) + +it('ignores translated prose and non-command slashes', () => { + expect(localeTokens('Cmd/Ctrl+Enter · tok/s · https://example.test/v1')).toEqual([]) + expect(localeTokens('Используйте /plan off и {count}')) + .toEqual(localeTokens('Use /plan off and {count}')) +}) + +it.each([['/plan off', '/plan désactivé'], ['/THEME=light', '/THEME=claro'], ['reasoning_effort', 'Reasoning_effort'], ['{count}', '{other}']])('detects a change from %s to %s', (source, translated) => { + expect(localeTokens(translated)).not.toEqual(localeTokens(source)) +}) + +it('recognizes commands at the start of copy or after CJK punctuation', () => { + expect(localeTokens('/THEME=auto、/THEME=light')).toEqual(['/THEME=auto', '/THEME=light']) +}) diff --git a/scripts/shipped-locales.ts b/scripts/shipped-locales.ts new file mode 100644 index 0000000000..62c9debada --- /dev/null +++ b/scripts/shipped-locales.ts @@ -0,0 +1,14 @@ +/** Languages whose UI dictionaries and package metadata ship with Harness. */ +export const SHIPPED_LOCALE_IDS = ['en', 'zh', 'ja', 'es', 'fr', 'de', 'ru', 'pt'] as const + +/** Locale id required by repository translation checks. */ +export type ShippedLocaleId = typeof SHIPPED_LOCALE_IDS[number] + +/** + * Extract copy tokens that translations must preserve verbatim. + * @param text - Dictionary text containing placeholders, slash commands or API field names. + * @returns Sorted tokens, retaining repeated occurrences. + */ +export function localeTokens(text: string): string[] { + return (text.match(/\{\w+\}|(? { for (const root of roots.splice(0)) rmSync(root, { recursive: true, force: true }) }) @@ -16,6 +18,9 @@ function fixture(ja: unknown = { meta: { title: '名前 {name}', description: ' writeFileSync(join(directory, 'en.json'), JSON.stringify({ meta: { title: 'Name {name}' } })) writeFileSync(join(directory, 'zh.json'), JSON.stringify({ meta: { title: '名称 {name}', description: '描述' } })) writeFileSync(join(directory, 'ja.json'), JSON.stringify(ja)) + for (const language of ['es', 'fr', 'de', 'ru', 'pt']) { + writeFileSync(join(directory, `${language}.json`), JSON.stringify({ meta: { title: 'Name {name}', description: 'Description.' } })) + } return root } @@ -42,7 +47,7 @@ it('checks referenced detail documents', () => { const root = fixture() const directory = join(root, 'packages/demo/plugin/locale') const meta = { title: 'Name {name}', description: 'Description.', detail: 'docs/DETAIL.md' } - for (const language of ['en', 'zh', 'ja']) writeFileSync(join(directory, `${language}.json`), JSON.stringify({ meta })) + for (const language of SHIPPED_LOCALE_IDS) writeFileSync(join(directory, `${language}.json`), JSON.stringify({ meta })) expect(localeMetadataProblems(root).join('\n')).toContain('missing detail resource') mkdirSync(join(directory, '../docs')) writeFileSync(join(directory, '../docs/DETAIL.md'), '# Detail\n') @@ -84,6 +89,7 @@ it('checks nested subpath locale resources and package-relative detail files', ( expect(localeMetadataProblems(root).join('\n')).toContain('locale/tools') expect(localeMetadataProblems(root).join('\n')).toContain('ja.json') writeFileSync(join(directory, 'ja.json'), JSON.stringify({ meta: { title: 'ツール', detail: 'docs/TOOLS.md' } })) + for (const language of ['es', 'fr', 'de', 'ru', 'pt']) writeFileSync(join(directory, `${language}.json`), JSON.stringify({ meta: { title: 'Tools', detail: 'docs/TOOLS.md' } })) expect(localeMetadataProblems(root)).toEqual([]) }) @@ -108,6 +114,7 @@ it('permits missing Chinese resources for loadable plugins', () => { writeFileSync(join(directory, 'src/index.ts'), 'export function apply() {}') writeFileSync(join(directory, 'package.json'), JSON.stringify({ name: '@deepseek-ai/dsh-demo' })) rmSync(join(directory, 'locale/zh.json')) + for (const language of ['es', 'fr', 'de', 'ru', 'pt']) writeFileSync(join(directory, `locale/${language}.json`), JSON.stringify({ meta: { title: 'Name {name}' } })) expect(localeMetadataProblems(root)).toEqual([]) }) @@ -119,3 +126,15 @@ it('excludes packages formally classified as test helpers', () => { writeFileSync(join(directory, 'package.json'), JSON.stringify({ name: '@deepseek-ai/dsh-llm-replay' })) expect(localeMetadataProblems(root)).toEqual([]) }) + +it.each(['es', 'fr', 'de', 'ru', 'pt'])('rejects missing %s metadata', (language) => { + const root = fixture() + rmSync(join(root, `packages/demo/plugin/locale/${language}.json`)) + expect(localeMetadataProblems(root).join('\n')).toContain(`${language}.json`) +}) + +it.each(['es', 'fr', 'de', 'ru', 'pt'])('rejects untranslated Chinese descriptions in %s metadata', (language) => { + const root = fixture() + writeFileSync(join(root, `packages/demo/plugin/locale/${language}.json`), JSON.stringify({ meta: { title: 'Name {name}', description: '描述' } })) + expect(localeMetadataProblems(root).join('\n')).toContain(`${language}.json: meta.description contains untranslated source text`) +}) diff --git a/scripts/verify-locale-metadata.ts b/scripts/verify-locale-metadata.ts index 027cb31fb4..8bada0cb47 100644 --- a/scripts/verify-locale-metadata.ts +++ b/scripts/verify-locale-metadata.ts @@ -1,8 +1,9 @@ -/** Check Japanese coverage of package metadata and plugin templates without loading plugins. */ +/** Check shipped-language coverage of package metadata and plugin templates without loading plugins. */ import { existsSync, globSync, readFileSync } from 'node:fs' import { basename, posix, join, resolve } from 'node:path' import { detailPath } from '../packages/util/plugin-detail/src/document.ts' import { PRODUCT_PACKAGE_POLICY } from './product-package-policy.ts' +import { SHIPPED_LOCALE_IDS, localeTokens } from './shipped-locales.ts' import { collectConfigCatalog } from './gen-config-catalog.ts' /** Flatten metadata strings and reject values that cannot be translated. */ @@ -13,14 +14,14 @@ function strings(value: unknown, key = ''): Record { } /** - * Compare Japanese metadata with every field supplied by English or Chinese. + * Compare shipped-language metadata with every field supplied by English or Chinese. * @param root - repository or fixture root. * @returns actionable missing-file, field, placeholder and resource diagnostics. */ export function localeMetadataProblems(root: string): string[] { const directories = new Set(globSync('packages/**/locale/**/*.json', { cwd: root, exclude: ['packages/**/node_modules/**', 'packages/**/lib/**', 'packages/**/tests/**'], - }).map(file => file.replaceAll('\\', '/')).filter(file => ['en.json', 'zh.json', 'ja.json'].includes(basename(file))).map(file => posix.dirname(file))) + }).map(file => file.replaceAll('\\', '/')).filter(file => SHIPPED_LOCALE_IDS.some(language => basename(file) === `${language}.json`)).map(file => posix.dirname(file))) for (const entry of collectConfigCatalog(root)) { const dir = entry.dir.replaceAll('\\', '/') if (PRODUCT_PACKAGE_POLICY[dir]?.category === 'test') continue @@ -47,14 +48,19 @@ export function localeMetadataProblems(root: string): string[] { const zh = existsSync(join(root, directory, 'zh.json')) ? read('zh') : {} const description = en['meta.description'] if (description !== undefined && !/[.!?]$/u.test(description)) problems.push(`${directory}/en.json: meta.description must end with sentence punctuation`) - const ja = read('ja') const expected = { ...zh, ...en } - for (const key of new Set([...Object.keys(expected), ...Object.keys(ja)])) { - if (ja[key] === undefined) problems.push(`${directory}/ja.json: missing ${key}`) - else if (expected[key] === undefined) problems.push(`${directory}/ja.json: unexpected ${key}`) - else { - const placeholders = (text: string): string => (text.match(/\{\w+\}/gu) ?? []).sort().join(',') - if (placeholders(ja[key]) !== placeholders(expected[key])) problems.push(`${directory}/ja.json: ${key} changes placeholders`) + for (const language of SHIPPED_LOCALE_IDS.filter(id => id !== 'en' && id !== 'zh')) { + const translated = read(language) + for (const key of new Set([...Object.keys(expected), ...Object.keys(translated)])) { + if (translated[key] === undefined) problems.push(`${directory}/${language}.json: missing ${key}`) + else if (expected[key] === undefined) problems.push(`${directory}/${language}.json: unexpected ${key}`) + else { + if (language !== 'ja' && key === 'meta.description' && /\p{Script=Han}/u.test(expected[key]) && translated[key] === expected[key]) { + problems.push(`${directory}/${language}.json: ${key} contains untranslated source text`) + } + const placeholders = (text: string): string => localeTokens(text).join(',') + if (placeholders(translated[key]) !== placeholders(expected[key])) problems.push(`${directory}/${language}.json: ${key} changes placeholders or literal tokens`) + } } } } catch (error) { @@ -68,5 +74,5 @@ if (import.meta.filename === resolve(process.argv[1] ?? '')) { const problems = localeMetadataProblems(resolve(import.meta.dirname, '..')) for (const problem of problems) console.error(problem) if (problems.length > 0) process.exitCode = 1 - else console.log('verify-locale-metadata: all package and template metadata has complete Japanese translations.') + else console.log('verify-locale-metadata: all package and template metadata has complete shipped-language translations.') } diff --git a/tsconfig.host.json b/tsconfig.host.json index 89da2748d3..81a3067ad0 100644 --- a/tsconfig.host.json +++ b/tsconfig.host.json @@ -9,6 +9,7 @@ }, "include": [ "apps/web/tests/japanese-plugin-metadata.e2e.ts", + "apps/web/tests/additional-locales.e2e.ts", "apps/web/tests/rich-text-quotes.e2e.ts", "apps/web/tests/hover-input.e2e.ts", "apps/web/tests/collapse-timing.e2e.ts",