diff --git a/packages/ui/src/lib/i18n/index.tsx b/packages/ui/src/lib/i18n/index.tsx index 2855d109..a63e53f1 100644 --- a/packages/ui/src/lib/i18n/index.tsx +++ b/packages/ui/src/lib/i18n/index.tsx @@ -1,18 +1,28 @@ import { createContext, createEffect, createMemo, createSignal, onCleanup, onMount, useContext } from "solid-js" import type { ParentComponent } from "solid-js" import { useConfig } from "../../stores/preferences" -import { enMessages } from "./messages/en/index" +import { enMessages } from "./messages/en" +import { esMessages } from "./messages/es" +import { frMessages } from "./messages/fr" +import { ruMessages } from "./messages/ru" +import { jaMessages } from "./messages/ja" +import { zhHansMessages } from "./messages/zh-Hans" type Messages = Record export type TranslateParams = Record -export type Locale = "en" +export type Locale = "en" | "es" | "fr" | "ru" | "ja" | "zh-Hans" -const SUPPORTED_LOCALES: readonly Locale[] = ["en"] as const +const SUPPORTED_LOCALES: readonly Locale[] = ["en", "es", "fr", "ru", "ja", "zh-Hans"] as const const messagesByLocale: Record = { en: enMessages, + es: esMessages, + fr: frMessages, + ru: ruMessages, + ja: jaMessages, + "zh-Hans": zhHansMessages, } function normalizeLocaleTag(value: string): string { @@ -28,8 +38,15 @@ function matchSupportedLocale(value: string | undefined): Locale | null { const exact = supportedLower.get(lower) if (exact) return exact - const base = lower.split("-")[0] + const parts = lower.split("-") + const base = parts[0] if (!base) return null + + if (base === "zh") { + const zhHans = supportedLower.get("zh-hans") + return zhHans ?? null + } + const baseMatch = supportedLower.get(base) return baseMatch ?? null } diff --git a/packages/ui/src/lib/i18n/messages/en/index.ts b/packages/ui/src/lib/i18n/messages/en/index.ts index 19722524..a7b1ef6a 100644 --- a/packages/ui/src/lib/i18n/messages/en/index.ts +++ b/packages/ui/src/lib/i18n/messages/en/index.ts @@ -14,7 +14,7 @@ import { sessionMessages } from "./session" import { settingsMessages } from "./settings" import { timeMessages } from "./time" import { toolCallMessages } from "./toolCall" -import { mergeMessageParts } from "./merge" +import { mergeMessageParts } from "../merge" export const enMessages = mergeMessageParts( folderSelectionMessages, diff --git a/packages/ui/src/lib/i18n/messages/en/merge.ts b/packages/ui/src/lib/i18n/messages/en/merge.ts deleted file mode 100644 index 814bb321..00000000 --- a/packages/ui/src/lib/i18n/messages/en/merge.ts +++ /dev/null @@ -1,25 +0,0 @@ -export type MessageCatalog = Record - -type MergeParts = Parts extends readonly [ - infer Head extends MessageCatalog, - ...infer Tail extends MessageCatalog[], -] - ? Head & MergeParts - : {} - -export function mergeMessageParts( - ...parts: Parts -): MergeParts { - const result: Record = Object.create(null) - - for (const part of parts) { - for (const [key, value] of Object.entries(part)) { - if (key in result) { - throw new Error(`Duplicate i18n message key: ${key}`) - } - result[key] = value - } - } - - return result as MergeParts -} diff --git a/packages/ui/src/lib/i18n/messages/es/advancedSettings.ts b/packages/ui/src/lib/i18n/messages/es/advancedSettings.ts new file mode 100644 index 00000000..08a61edd --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/es/advancedSettings.ts @@ -0,0 +1,6 @@ +export const advancedSettingsMessages = { + "advancedSettings.title": "Configuración avanzada", + "advancedSettings.environmentVariables.title": "Variables de entorno", + "advancedSettings.environmentVariables.subtitle": "Se aplican cada vez que inicia una nueva instancia de OpenCode", + "advancedSettings.actions.close": "Cerrar", +} as const diff --git a/packages/ui/src/lib/i18n/messages/es/app.ts b/packages/ui/src/lib/i18n/messages/es/app.ts new file mode 100644 index 00000000..9d5ac8ce --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/es/app.ts @@ -0,0 +1,29 @@ +export const appMessages = { + "app.launchError.title": "No se pudo iniciar OpenCode", + "app.launchError.description": "No pudimos iniciar el binario de OpenCode seleccionado. Revisa la salida de error abajo o elige un binario distinto en Configuración avanzada.", + "app.launchError.binaryPathLabel": "Ruta del binario", + "app.launchError.errorOutputLabel": "Salida de error", + "app.launchError.openAdvancedSettings": "Abrir Configuración avanzada", + "app.launchError.close": "Cerrar", + "app.launchError.closeTitle": "Cerrar (Esc)", + "app.launchError.fallbackMessage": "No se pudo iniciar el workspace", + + "app.stopInstance.confirmMessage": "¿Detener la instancia de OpenCode? Esto detendrá el servidor.", + "app.stopInstance.title": "Detener instancia", + "app.stopInstance.confirmLabel": "Detener", + "app.stopInstance.cancelLabel": "Seguir ejecutándose", + + "emptyState.logoAlt": "Logo de CodeNomad", + "emptyState.brandTitle": "CodeNomad", + "emptyState.tagline": "Selecciona una carpeta para empezar a programar con IA", + "emptyState.actions.selectFolder": "Seleccionar carpeta", + "emptyState.actions.selecting": "Seleccionando...", + "emptyState.keyboardShortcut": "Atajo de teclado: {shortcut}", + "emptyState.examples": "Ejemplos: {example}", + "emptyState.multipleInstances": "Puedes tener varias instancias de la misma carpeta", + + "releases.upgradeRequired.title": "Actualización requerida", + "releases.upgradeRequired.message.withVersion": "Actualiza a CodeNomad {version} para usar la UI más reciente.", + "releases.upgradeRequired.message.noVersion": "Actualiza CodeNomad para usar la UI más reciente.", + "releases.upgradeRequired.action.getUpdate": "Obtener actualización", +} as const diff --git a/packages/ui/src/lib/i18n/messages/es/commands.ts b/packages/ui/src/lib/i18n/messages/es/commands.ts new file mode 100644 index 00000000..150db676 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/es/commands.ts @@ -0,0 +1,160 @@ +export const commandMessages = { + "commandPalette.title": "Paleta de comandos", + "commandPalette.description": "Busca y ejecuta comandos", + "commandPalette.searchPlaceholder": "Escribe un comando o busca...", + "commandPalette.empty": "No se encontraron comandos para \"{query}\"", + "commandPalette.category.customCommands": "Comandos personalizados", + "commandPalette.category.instance": "Instancia", + "commandPalette.category.session": "Sesión", + "commandPalette.category.agentModel": "Agente y modelo", + "commandPalette.category.inputFocus": "Entrada y foco", + "commandPalette.category.system": "Sistema", + "commandPalette.category.other": "Otro", + + "commands.newInstance.label": "Nueva instancia", + "commands.newInstance.description": "Abrir el selector de carpetas para crear una nueva instancia", + "commands.newInstance.keywords": "carpeta, proyecto, workspace", + + "commands.closeInstance.label": "Cerrar instancia", + "commands.closeInstance.description": "Detener el servidor de la instancia actual", + "commands.closeInstance.keywords": "detener, salir, cerrar", + + "commands.nextInstance.label": "Siguiente instancia", + "commands.nextInstance.description": "Cambiar a la siguiente pestaña de instancia", + "commands.nextInstance.keywords": "cambiar, navegar", + + "commands.previousInstance.label": "Instancia anterior", + "commands.previousInstance.description": "Cambiar a la pestaña de instancia anterior", + "commands.previousInstance.keywords": "cambiar, navegar", + + "commands.newSession.label": "Nueva sesión", + "commands.newSession.description": "Crear una nueva sesión principal", + "commands.newSession.keywords": "crear, iniciar", + + "commands.closeSession.label": "Cerrar sesión", + "commands.closeSession.description": "Cerrar la sesión principal actual", + "commands.closeSession.keywords": "cerrar, detener", + + "commands.scrubSessions.label": "Depurar sesiones", + "commands.scrubSessions.description": "Eliminar sesiones vacías, sesiones de subagente que ya completaron su tarea principal y sesiones bifurcadas innecesarias.", + "commands.scrubSessions.keywords": "limpieza, blanco, vacías, sesiones, quitar, eliminar, depurar", + + "commands.instanceInfo.label": "Info de la instancia", + "commands.instanceInfo.description": "Abrir el resumen de la instancia para ver logs y estado", + "commands.instanceInfo.keywords": "info, logs, consola, salida", + + "commands.nextSession.label": "Siguiente sesión", + "commands.nextSession.description": "Cambiar a la siguiente pestaña de sesión", + "commands.nextSession.keywords": "cambiar, navegar", + + "commands.previousSession.label": "Sesión anterior", + "commands.previousSession.description": "Cambiar a la pestaña de sesión anterior", + "commands.previousSession.keywords": "cambiar, navegar", + + "commands.compactSession.label": "Compactar sesión", + "commands.compactSession.description": "Resumir y compactar la sesión actual", + "commands.compactSession.keywords": "resumir, comprimir", + "commands.compactSession.errorFallback": "No se pudo compactar la sesión", + "commands.compactSession.alert.title": "La compactación falló", + "commands.compactSession.alert.message": "La compactación falló: {message}", + + "commands.undoLastMessage.label": "Deshacer último mensaje", + "commands.undoLastMessage.description": "Revertir el último mensaje", + "commands.undoLastMessage.keywords": "revertir, deshacer", + "commands.undoLastMessage.none.title": "No hay acciones para deshacer", + "commands.undoLastMessage.none.message": "Nada que deshacer", + "commands.undoLastMessage.failed.title": "No se pudo deshacer", + "commands.undoLastMessage.failed.message": "No se pudo revertir el mensaje", + + "commands.openModelSelector.label": "Abrir selector de modelo", + "commands.openModelSelector.description": "Elegir un modelo diferente", + "commands.openModelSelector.keywords": "modelo, llm, IA", + + "commands.selectModelVariant.label": "Seleccionar variante del modelo", + "commands.selectModelVariant.description": "Elegir un nivel de esfuerzo de pensamiento para el modelo actual", + "commands.selectModelVariant.keywords": "variante, pensamiento, razonamiento, esfuerzo", + + "commands.openAgentSelector.label": "Abrir selector de agente", + "commands.openAgentSelector.description": "Elegir un agente diferente", + "commands.openAgentSelector.keywords": "agente, modo", + + "commands.clearInput.label": "Limpiar entrada", + "commands.clearInput.description": "Borrar el área de texto del prompt", + "commands.clearInput.keywords": "limpiar, reiniciar", + + "commands.thinkingBlocks.label.show": "Mostrar bloques de pensamiento", + "commands.thinkingBlocks.label.hide": "Ocultar bloques de pensamiento", + "commands.thinkingBlocks.description": "Mostrar/ocultar el proceso de pensamiento de la IA", + "commands.thinkingBlocks.keywords": "pensamiento, razonamiento, alternar, mostrar, ocultar", + + "commands.timelineToolCalls.label.show": "Mostrar llamadas de herramienta en la línea de tiempo", + "commands.timelineToolCalls.label.hide": "Ocultar llamadas de herramienta en la línea de tiempo", + "commands.timelineToolCalls.description": "Alternar entradas de llamadas de herramienta en la línea de tiempo de mensajes", + "commands.timelineToolCalls.keywords": "línea de tiempo, herramienta, alternar", + + "commands.common.expanded": "Expandido", + "commands.common.collapsed": "Colapsado", + "commands.common.visible": "Visible", + "commands.common.hidden": "Oculto", + "commands.common.enabled": "Activado", + "commands.common.disabled": "Desactivado", + + "commands.thinkingBlocksDefault.label": "Bloques de pensamiento por defecto · {state}", + "commands.thinkingBlocksDefault.description": "Alternar si los bloques de pensamiento empiezan expandidos", + "commands.thinkingBlocksDefault.keywords": "pensamiento, razonamiento, expandir, colapsar, por defecto", + + "commands.diffViewSplit.label": "Usar vista de diff dividida", + "commands.diffViewSplit.description": "Mostrar diffs de llamadas de herramienta lado a lado", + "commands.diffViewSplit.keywords": "diff, dividir, vista", + + "commands.diffViewUnified.label": "Usar vista de diff unificada", + "commands.diffViewUnified.description": "Mostrar diffs de llamadas de herramienta en línea", + "commands.diffViewUnified.keywords": "diff, unificada, vista", + + "commands.toolOutputsDefault.label": "Salidas de herramientas por defecto · {state}", + "commands.toolOutputsDefault.description": "Alternar la expansión por defecto de las salidas de herramientas", + "commands.toolOutputsDefault.keywords": "herramienta, salida, expandir, colapsar", + + "commands.diagnosticsDefault.label": "Diagnósticos por defecto · {state}", + "commands.diagnosticsDefault.description": "Alternar la expansión por defecto de la salida de diagnósticos", + "commands.diagnosticsDefault.keywords": "diagnósticos, expandir, colapsar", + + "commands.tokenUsageDisplay.label": "Mostrar uso de tokens · {state}", + "commands.tokenUsageDisplay.description": "Mostrar u ocultar estadísticas de tokens y costo en los mensajes del asistente", + "commands.tokenUsageDisplay.keywords": "token, uso, costo, estadísticas", + + "commands.autoCleanupBlankSessions.label": "Auto-limpieza de sesiones vacías · {state}", + "commands.autoCleanupBlankSessions.description": "Limpiar automáticamente las sesiones vacías al crear nuevas", + "commands.autoCleanupBlankSessions.keywords": "auto, limpieza, vacías, sesiones, alternar", + + "commands.showHelp.label": "Mostrar ayuda", + "commands.showHelp.description": "Mostrar atajos de teclado y ayuda", + "commands.showHelp.keywords": "atajos, ayuda", + + "commands.custom.argumentsPrompt.message": "Argumentos para /{name}", + "commands.custom.argumentsPrompt.title": "Comando personalizado", + "commands.custom.argumentsPrompt.inputLabel": "Argumentos", + "commands.custom.argumentsPrompt.inputPlaceholder": "p. ej. foo bar", + "commands.custom.argumentsPrompt.confirmLabel": "Ejecutar", + "commands.custom.argumentsPrompt.cancelLabel": "Cancelar", + "commands.custom.argumentsPrompt.openFailed.message": "No se pudo abrir el diálogo de argumentos.", + "commands.custom.argumentsPrompt.openFailed.title": "Argumentos del comando", + "commands.custom.entries.descriptionFallback": "Comando personalizado", + "commands.custom.sessionRequired.message": "Selecciona una sesión antes de ejecutar un comando personalizado.", + "commands.custom.sessionRequired.title": "Se requiere sesión", + "commands.custom.runFailed.message": "No se pudo ejecutar el comando personalizado. Revisa la consola para más detalles.", + "commands.custom.runFailed.title": "El comando falló", + + "unifiedPicker.loading.searching": "Buscando...", + "unifiedPicker.loading.loadingWorkspace": "Cargando workspace...", + "unifiedPicker.title.command": "Seleccionar comando", + "unifiedPicker.title.mention": "Seleccionar agente o archivo", + "unifiedPicker.empty": "No se encontraron resultados", + "unifiedPicker.sections.commands": "COMANDOS", + "unifiedPicker.sections.agents": "AGENTES", + "unifiedPicker.sections.files": "ARCHIVOS", + "unifiedPicker.badge.subagent": "subagente", + "unifiedPicker.footer.navigate": "navegar", + "unifiedPicker.footer.select": "seleccionar", + "unifiedPicker.footer.close": "cerrar", +} as const diff --git a/packages/ui/src/lib/i18n/messages/es/dialogs.ts b/packages/ui/src/lib/i18n/messages/es/dialogs.ts new file mode 100644 index 00000000..07d89db3 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/es/dialogs.ts @@ -0,0 +1,16 @@ +export const dialogMessages = { + "alertDialog.fallbackTitle.info": "Aviso", + "alertDialog.fallbackTitle.warning": "Por favor revisa", + "alertDialog.fallbackTitle.error": "Algo salió mal", + "alertDialog.actions.confirm": "Confirmar", + "alertDialog.actions.run": "Ejecutar", + "alertDialog.actions.ok": "OK", + "alertDialog.actions.cancel": "Cancelar", + "alertDialog.prompt.inputLabel": "Entrada", + + "backgroundProcessOutputDialog.title": "Salida en segundo plano", + "backgroundProcessOutputDialog.actions.close": "Cerrar", + "backgroundProcessOutputDialog.loading": "Cargando salida...", + "backgroundProcessOutputDialog.truncatedNotice": "Salida truncada para mostrar.", + "backgroundProcessOutputDialog.loadErrorFallback": "No se pudo cargar la salida.", +} as const diff --git a/packages/ui/src/lib/i18n/messages/es/filesystem.ts b/packages/ui/src/lib/i18n/messages/es/filesystem.ts new file mode 100644 index 00000000..5a57d177 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/es/filesystem.ts @@ -0,0 +1,43 @@ +export const filesystemMessages = { + "directoryBrowser.defaultDescription": "Explora carpetas bajo la raíz del workspace configurado.", + "directoryBrowser.close": "Cerrar", + "directoryBrowser.currentFolder": "Carpeta actual", + "directoryBrowser.selectCurrent": "Seleccionar actual", + "directoryBrowser.newFolder": "Nueva carpeta", + "directoryBrowser.creating": "Creando…", + "directoryBrowser.loadingFolders": "Cargando carpetas…", + "directoryBrowser.noFolders": "No hay carpetas disponibles.", + "directoryBrowser.upOneLevel": "Subir un nivel", + "directoryBrowser.select": "Seleccionar", + "directoryBrowser.load.errorFallback": "No se pudo cargar el sistema de archivos", + "directoryBrowser.createFolder.promptMessage": "Crea una nueva carpeta en el directorio actual.", + "directoryBrowser.createFolder.title": "Nueva carpeta", + "directoryBrowser.createFolder.inputLabel": "Nombre de la carpeta", + "directoryBrowser.createFolder.inputPlaceholder": "p. ej. mi-nuevo-proyecto", + "directoryBrowser.createFolder.confirmLabel": "Crear", + "directoryBrowser.createFolder.cancelLabel": "Cancelar", + "directoryBrowser.createFolder.invalidNameMessage": "Introduce un único nombre de carpeta.", + "directoryBrowser.createFolder.invalidNameDetail": "Los nombres de carpeta no pueden incluir barras, '..' ni '~'.", + "directoryBrowser.createFolder.errorFallback": "No se pudo crear la carpeta", + + "filesystemBrowser.descriptionFallback": "Busca una ruta bajo la raíz del workspace configurado.", + "filesystemBrowser.rootLabel": "Raíz: {root}", + "filesystemBrowser.actions.close": "Cerrar", + "filesystemBrowser.actions.retry": "Reintentar", + "filesystemBrowser.actions.select": "Seleccionar", + "filesystemBrowser.filterLabel": "Filtro", + "filesystemBrowser.search.placeholder.directories": "Buscar carpetas", + "filesystemBrowser.search.placeholder.files": "Buscar archivos", + "filesystemBrowser.currentFolder.label": "Carpeta actual", + "filesystemBrowser.currentFolder.selectCurrent": "Seleccionar actual", + "filesystemBrowser.loading.filesystem": "sistema de archivos", + "filesystemBrowser.loading.workspaceRoot": "raíz del workspace", + "filesystemBrowser.loading.loadingWithPath": "Cargando {path}…", + "filesystemBrowser.empty.noEntries": "No se encontraron elementos.", + "filesystemBrowser.navigation.upOneLevel": "Subir un nivel", + "filesystemBrowser.hints.navigate": "Navegar", + "filesystemBrowser.hints.select": "Seleccionar", + "filesystemBrowser.hints.close": "Cerrar", + "filesystemBrowser.errors.loadFilesystemFallback": "No se pudo cargar el sistema de archivos", + "filesystemBrowser.errors.openDirectoryFallback": "No se pudo abrir el directorio", +} as const diff --git a/packages/ui/src/lib/i18n/messages/es/folderSelection.ts b/packages/ui/src/lib/i18n/messages/es/folderSelection.ts new file mode 100644 index 00000000..813db2ea --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/es/folderSelection.ts @@ -0,0 +1,34 @@ +export const folderSelectionMessages = { + "folderSelection.logoAlt": "Logo de CodeNomad", + "folderSelection.tagline": "Selecciona una carpeta para empezar a programar con IA", + + "folderSelection.links.github": "GitHub de CodeNomad", + "folderSelection.links.githubStars": "Estrellas de CodeNomad en GitHub", + "folderSelection.links.discord": "Discord de CodeNomad", + + "folderSelection.empty.title": "No hay carpetas recientes", + "folderSelection.empty.description": "Explora una carpeta para comenzar", + + "folderSelection.recent.title": "Carpetas recientes", + "folderSelection.recent.subtitle.one": "{count} carpeta disponible", + "folderSelection.recent.subtitle.other": "{count} carpetas disponibles", + "folderSelection.recent.remove": "Quitar de recientes", + + "folderSelection.browse.title": "Explorar carpetas", + "folderSelection.browse.subtitle": "Selecciona cualquier carpeta en tu ordenador", + "folderSelection.browse.button": "Explorar carpetas", + "folderSelection.browse.buttonOpening": "Abriendo...", + + "folderSelection.advancedSettings": "Configuración avanzada", + + "folderSelection.hints.navigate": "Navegar", + "folderSelection.hints.select": "Seleccionar", + "folderSelection.hints.remove": "Quitar", + "folderSelection.hints.browse": "Explorar", + + "folderSelection.loading.title": "Iniciando instancia...", + "folderSelection.loading.subtitle": "Espera un momento mientras preparamos tu workspace.", + + "folderSelection.dialog.title": "Seleccionar workspace", + "folderSelection.dialog.description": "Selecciona un workspace para empezar a programar.", +} as const diff --git a/packages/ui/src/lib/i18n/messages/es/index.ts b/packages/ui/src/lib/i18n/messages/es/index.ts new file mode 100644 index 00000000..9bf3d8c1 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/es/index.ts @@ -0,0 +1,36 @@ +import { advancedSettingsMessages } from "./advancedSettings" +import { appMessages } from "./app" +import { commandMessages } from "./commands" +import { dialogMessages } from "./dialogs" +import { filesystemMessages } from "./filesystem" +import { folderSelectionMessages } from "./folderSelection" +import { instanceMessages } from "./instance" +import { loadingScreenMessages } from "./loadingScreen" +import { logMessages } from "./logs" +import { markdownMessages } from "./markdown" +import { messagingMessages } from "./messaging" +import { remoteAccessMessages } from "./remoteAccess" +import { sessionMessages } from "./session" +import { settingsMessages } from "./settings" +import { timeMessages } from "./time" +import { toolCallMessages } from "./toolCall" +import { mergeMessageParts } from "../merge" + +export const esMessages = mergeMessageParts( + folderSelectionMessages, + advancedSettingsMessages, + loadingScreenMessages, + timeMessages, + appMessages, + dialogMessages, + filesystemMessages, + instanceMessages, + logMessages, + sessionMessages, + messagingMessages, + toolCallMessages, + markdownMessages, + settingsMessages, + remoteAccessMessages, + commandMessages, +) diff --git a/packages/ui/src/lib/i18n/messages/es/instance.ts b/packages/ui/src/lib/i18n/messages/es/instance.ts new file mode 100644 index 00000000..a2252e6b --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/es/instance.ts @@ -0,0 +1,125 @@ +export const instanceMessages = { + "instanceTabs.new.title": "Nueva instancia (Cmd/Ctrl+N)", + "instanceTabs.new.ariaLabel": "Nueva instancia", + "instanceTabs.remote.title": "Conexión remota", + "instanceTabs.remote.ariaLabel": "Conexión remota", + + "instanceInfo.title": "Información de la instancia", + "instanceInfo.labels.folder": "Carpeta", + "instanceInfo.labels.project": "Proyecto", + "instanceInfo.labels.versionControl": "Control de versiones", + "instanceInfo.labels.opencodeVersion": "Versión de OpenCode", + "instanceInfo.labels.binaryPath": "Ruta del binario", + "instanceInfo.labels.environmentVariables": "Variables de entorno ({count})", + "instanceInfo.loading": "Cargando...", + "instanceInfo.server.title": "Servidor", + "instanceInfo.server.port": "Puerto:", + "instanceInfo.server.pid": "PID:", + "instanceInfo.server.status": "Estado:", + + "instanceTab.status.permission": "Esperando permiso", + "instanceTab.status.compacting": "Compactando", + "instanceTab.status.working": "Trabajando", + "instanceTab.status.idle": "Inactiva", + "instanceTab.status.ariaLabel": "Estado de la instancia: {status}", + "instanceTab.actions.close.ariaLabel": "Cerrar instancia", + + "instanceShell.leftPanel.sessionsTitle": "Sesiones", + "instanceShell.leftPanel.instanceInfo": "Info de la instancia", + + "instanceShell.leftDrawer.pin": "Fijar panel izquierdo", + "instanceShell.leftDrawer.unpin": "Desfijar panel izquierdo", + "instanceShell.leftDrawer.toggle.pinned": "Panel izquierdo fijado", + "instanceShell.leftDrawer.toggle.open": "Abrir panel izquierdo", + "instanceShell.leftDrawer.toggle.close": "Cerrar panel izquierdo", + + "instanceShell.rightDrawer.pin": "Fijar panel derecho", + "instanceShell.rightDrawer.unpin": "Desfijar panel derecho", + "instanceShell.rightDrawer.toggle.pinned": "Panel derecho fijado", + "instanceShell.rightDrawer.toggle.open": "Abrir panel derecho", + "instanceShell.rightDrawer.toggle.close": "Cerrar panel derecho", + + "instanceShell.metrics.usedLabel": "Usado", + "instanceShell.metrics.availableLabel": "Disp.", + + "instanceShell.commandPalette.openAriaLabel": "Abrir paleta de comandos", + "instanceShell.commandPalette.button": "Paleta de comandos", + + "instanceShell.connection.ariaLabel": "Connection {status}", + "instanceShell.connection.connected": "Conectada", + "instanceShell.connection.connecting": "Conectando...", + "instanceShell.connection.disconnected": "Desconectada", + "instanceShell.connection.unknown": "Desconocida", + + "instanceWelcome.shortcuts.newSession": "Nueva sesión", + "instanceWelcome.empty.title": "No hay sesiones anteriores", + "instanceWelcome.empty.description": "Crea una nueva sesión abajo para comenzar", + "instanceWelcome.loading.title": "Cargando sesiones", + "instanceWelcome.loading.description": "Obteniendo tus sesiones anteriores...", + "instanceWelcome.resume.title": "Reanudar sesión", + "instanceWelcome.resume.subtitle.one": "{count} sesión disponible", + "instanceWelcome.resume.subtitle.other": "{count} sesiones disponibles", + "instanceWelcome.session.untitled": "Sesión sin título", + "instanceWelcome.new.title": "Iniciar nueva sesión", + "instanceWelcome.new.subtitle": "Reutilizaremos tu último agente/modelo automáticamente", + "instanceWelcome.new.createButton": "Crear sesión", + "instanceWelcome.overlay.close": "Cerrar", + "instanceWelcome.actions.viewInstanceInfo": "Ver info de la instancia", + "instanceWelcome.actions.renameTitle": "Renombrar sesión", + "instanceWelcome.actions.deleteTitle": "Eliminar sesión", + "instanceWelcome.hints.navigate": "Navegar", + "instanceWelcome.hints.jump": "Saltar", + "instanceWelcome.hints.firstLast": "Primero/Último", + "instanceWelcome.hints.resume": "Reanudar", + "instanceWelcome.hints.delete": "Eliminar", + "instanceWelcome.toasts.renameError": "No se pudo renombrar la sesión", + + "instanceDisconnected.title": "Instancia desconectada", + "instanceDisconnected.folderFallback": "este workspace", + "instanceDisconnected.reasonFallback": "El servidor dejó de responder", + "instanceDisconnected.description": "{folder} ya no se puede alcanzar. Cierra la pestaña para seguir trabajando.", + "instanceDisconnected.details.title": "Detalles", + "instanceDisconnected.details.folderLabel": "Carpeta:", + "instanceDisconnected.actions.closeInstance": "Cerrar instancia", + + "instanceShell.empty.title": "No hay sesión seleccionada", + "instanceShell.empty.description": "Selecciona una sesión para ver mensajes", + + "instanceShell.rightPanel.title": "Panel de estado", + "instanceShell.rightPanel.sections.plan": "Plan", + "instanceShell.rightPanel.sections.backgroundProcesses": "Shells en segundo plano", + "instanceShell.rightPanel.sections.mcp": "Servidores MCP", + "instanceShell.rightPanel.sections.lsp": "Servidores LSP", + "instanceShell.rightPanel.sections.plugins": "Plugins", + + "instanceShell.plan.noSessionSelected": "Selecciona una sesión para ver el plan.", + "instanceShell.plan.empty": "Aún no hay nada planificado.", + + "instanceShell.backgroundProcesses.empty": "No hay procesos en segundo plano.", + "instanceShell.backgroundProcesses.status": "Estado: {status}", + "instanceShell.backgroundProcesses.output": "Salida: {sizeKb} KB", + "instanceShell.backgroundProcesses.actions.output": "Salida", + "instanceShell.backgroundProcesses.actions.stop": "Detener", + "instanceShell.backgroundProcesses.actions.terminate": "Terminar", + + "versionPill.appWithVersion": "App {version}", + "versionPill.ui": "UI", + "versionPill.uiWithVersion": "UI {version}", + "versionPill.source": " ({source})", + + "opencodeBinarySelector.title": "Binario de OpenCode", + "opencodeBinarySelector.subtitle": "Elige qué ejecutable de OpenCode debe ejecutarse", + "opencodeBinarySelector.customPath.placeholder": "Introduce la ruta al binario de opencode…", + "opencodeBinarySelector.actions.add": "Agregar", + "opencodeBinarySelector.actions.browse": "Explorar binario…", + "opencodeBinarySelector.actions.removeTitle": "Quitar binario", + "opencodeBinarySelector.badge.systemPath": "Usar binario del PATH del sistema", + "opencodeBinarySelector.status.checkingVersions": "Comprobando versiones…", + "opencodeBinarySelector.status.checking": "Comprobando…", + "opencodeBinarySelector.dialog.title": "Seleccionar binario de OpenCode", + "opencodeBinarySelector.dialog.description": "Explora los archivos expuestos por el servidor del CLI.", + "opencodeBinarySelector.validation.invalidBinary": "Binario de OpenCode no válido", + "opencodeBinarySelector.validation.alreadyValidating": "Ya se está validando", + "opencodeBinarySelector.display.systemPath": "{name} (PATH del sistema)", + "opencodeBinarySelector.versionLabel": "v{version}", +} as const diff --git a/packages/ui/src/lib/i18n/messages/es/loadingScreen.ts b/packages/ui/src/lib/i18n/messages/es/loadingScreen.ts new file mode 100644 index 00000000..9e107879 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/es/loadingScreen.ts @@ -0,0 +1,17 @@ +export const loadingScreenMessages = { + "loadingScreen.logoAlt": "Logo de CodeNomad", + "loadingScreen.status.issue": "Se produjo un problema", + "loadingScreen.actions.showAnother": "Mostrar otra", + "loadingScreen.errors.missingRoot": "No se encontró el elemento raíz de carga", + + "loadingScreen.phrases.neurons": "Calentando las neuronas de la IA…", + "loadingScreen.phrases.daydreaming": "Convenciendo a la IA de dejar de soñar despierta…", + "loadingScreen.phrases.goggles": "Puliendo las gafas de código de la IA…", + "loadingScreen.phrases.reorganizingFiles": "Pidiéndole a la IA que deje de reorganizar tus archivos…", + "loadingScreen.phrases.coffee": "Dándole más café a la IA…", + "loadingScreen.phrases.nodeModules": "Enseñándole a la IA a no borrar node_modules (otra vez)…", + "loadingScreen.phrases.actNatural": "Diciéndole a la IA que actúe natural antes de que llegues…", + "loadingScreen.phrases.rewritingHistory": "Pidiéndole a la IA que deje de reescribir la historia…", + "loadingScreen.phrases.stretch": "Dejando que la IA se estire antes de su sprint de código…", + "loadingScreen.phrases.keyboardControl": "Convenciendo a la IA de devolverte el control del teclado…", +} as const diff --git a/packages/ui/src/lib/i18n/messages/es/logs.ts b/packages/ui/src/lib/i18n/messages/es/logs.ts new file mode 100644 index 00000000..ab1cdc68 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/es/logs.ts @@ -0,0 +1,18 @@ +export const logMessages = { + "logsView.title": "Registros del servidor", + "logsView.actions.show": "Mostrar registros del servidor", + "logsView.actions.hide": "Ocultar registros del servidor", + "logsView.envVars.title": "Variables de entorno ({count})", + "logsView.paused.title": "Los registros del servidor están en pausa", + "logsView.paused.description": "Activa el streaming para ver la actividad de tu servidor de OpenCode.", + "logsView.empty.waiting": "Esperando la salida del servidor...", + "logsView.scrollToBottom": "Desplazarse al final", + + "infoView.logs.title": "Registros del servidor", + "infoView.logs.actions.show": "Mostrar registros del servidor", + "infoView.logs.actions.hide": "Ocultar registros del servidor", + "infoView.logs.paused.title": "Los registros del servidor están en pausa", + "infoView.logs.paused.description": "Activa el streaming para ver la actividad de tu servidor de OpenCode.", + "infoView.logs.empty.waiting": "Esperando la salida del servidor...", + "infoView.logs.scrollToBottom": "Desplazarse al final", +} as const diff --git a/packages/ui/src/lib/i18n/messages/es/markdown.ts b/packages/ui/src/lib/i18n/messages/es/markdown.ts new file mode 100644 index 00000000..f92d46b9 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/es/markdown.ts @@ -0,0 +1,7 @@ +export const markdownMessages = { + "markdown.codeBlock.copy.label": "Copiar", + "markdown.codeBlock.copy.copied": "¡Copiado!", + "markdown.codeBlock.copy.failed": "Error", + + "markdown.copy": "Copiar", +} as const diff --git a/packages/ui/src/lib/i18n/messages/es/messaging.ts b/packages/ui/src/lib/i18n/messages/es/messaging.ts new file mode 100644 index 00000000..5cca187a --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/es/messaging.ts @@ -0,0 +1,109 @@ +export const messagingMessages = { + "messageListHeader.sidebar.openSessionListAriaLabel": "Abrir lista de sesiones", + "messageListHeader.metrics.usedLabel": "Usado", + "messageListHeader.metrics.availableLabel": "Disp.", + "messageListHeader.commandPalette.ariaLabel": "Abrir paleta de comandos", + "messageListHeader.commandPalette.button": "Paleta de comandos", + "messageListHeader.connection.connected": "Conectado", + "messageListHeader.connection.connecting": "Conectando...", + "messageListHeader.connection.disconnected": "Desconectado", + + "messageSection.empty.logoAlt": "Logo de CodeNomad", + "messageSection.empty.brandTitle": "CodeNomad", + "messageSection.empty.title": "Inicia una conversación", + "messageSection.empty.description": "Escribe un mensaje abajo o abre la Paleta de comandos:", + "messageSection.empty.tips.commandPalette": "Paleta de comandos", + "messageSection.empty.tips.askAboutCodebase": "Pregunta sobre tu codebase", + "messageSection.empty.tips.attachFilesPrefix": "Adjunta archivos con", + "messageSection.loading.messages": "Cargando mensajes...", + "messageSection.scroll.toFirstAriaLabel": "Desplazarse al primer mensaje", + "messageSection.scroll.toLatestAriaLabel": "Desplazarse al último mensaje", + "messageSection.quote.addAsQuote": "Añadir como cita", + "messageSection.quote.addAsCode": "Añadir como código", + + "messageTimeline.ariaLabel": "Línea de tiempo de mensajes", + "messageTimeline.segment.user.label": "Tú", + "messageTimeline.segment.assistant.label": "Asist.", + "messageTimeline.segment.compaction.label": "Compactación", + "messageTimeline.tool.fallbackLabel": "Llamada de herramienta", + "messageTimeline.tooltip.userFallback": "Mensaje del usuario", + "messageTimeline.tooltip.assistantFallback": "Respuesta del asistente", + "messageTimeline.tooltip.compaction.auto": "Compactación automática", + "messageTimeline.tooltip.compaction.manual": "Compactación manual", + "messageTimeline.text.filePrefix": "[Archivo] {filename}", + "messageTimeline.text.attachment": "Adjunto", + + "messageBlock.tool.header": "Llamada de herramienta", + "messageBlock.tool.unknown": "desconocido", + "messageBlock.tool.goToSession.label": "Ir a sesión", + "messageBlock.tool.goToSession.title": "Ir a la sesión", + "messageBlock.tool.goToSession.unavailableTitle": "La sesión aún no está disponible", + + "messageBlock.compaction.ariaLabel": "Compactación de sesión", + "messageBlock.compaction.autoLabel": "Sesión compactada automáticamente", + "messageBlock.compaction.manualLabel": "Sesión compactada por ti", + "messageBlock.usage.input": "Entrada", + "messageBlock.usage.output": "Salida", + "messageBlock.usage.reasoning": "Razonamiento", + "messageBlock.usage.cacheRead": "Lectura de cache", + "messageBlock.usage.cacheWrite": "Escritura de cache", + "messageBlock.usage.cost": "Costo", + "messageBlock.step.agentLabel": "Agente: {agent}", + "messageBlock.step.modelLabel": "Modelo: {model}", + "messageBlock.reasoning.thinkingLabel": "Pensamiento", + "messageBlock.reasoning.expandAriaLabel": "Expandir pensamiento", + "messageBlock.reasoning.collapseAriaLabel": "Colapsar pensamiento", + "messageBlock.reasoning.indicator.hide": "Ocultar", + "messageBlock.reasoning.indicator.view": "Ver", + "messageBlock.reasoning.detailsAriaLabel": "Detalles del razonamiento", + + "codeBlockInline.actions.copy": "Copiar", + "codeBlockInline.actions.copied": "¡Copiado!", + + "messageItem.speaker.you": "Tú", + "messageItem.speaker.assistant": "Asistente", + "messageItem.actions.revert": "Revertir", + "messageItem.actions.revertTitle": "Revertir a este mensaje", + "messageItem.actions.fork": "Fork", + "messageItem.actions.forkTitle": "Fork desde este mensaje", + "messageItem.actions.copy": "Copiar", + "messageItem.actions.copyTitle": "Copiar mensaje", + "messageItem.actions.copied": "¡Copiado!", + "messageItem.status.queued": "EN COLA", + "messageItem.status.generating": "Generando...", + "messageItem.status.sending": "Enviando...", + "messageItem.status.failedToSend": "No se pudo enviar el mensaje", + "messageItem.attachment.defaultName": "adjunto", + "messageItem.attachment.downloadAriaLabel": "Descargar {name}", + "messageItem.agentMeta.agentLabel": "Agente: {agent}", + "messageItem.agentMeta.modelLabel": "Modelo: {model}", + "messageItem.errors.authenticationFallback": "Error de autenticación", + "messageItem.errors.outputLengthExceeded": "Se excedió la longitud de salida del mensaje", + "messageItem.errors.requestAborted": "La solicitud fue abortada", + "messageItem.errors.unknownFallback": "Se produjo un error desconocido", + + "attachmentChip.removeAriaLabel": "Quitar adjunto", + + "expandButton.toggleAriaLabel": "Alternar altura de entrada del chat", + + "promptInput.placeholder.shell": "Ejecuta un comando de shell (Esc para salir)...", + "promptInput.placeholder.default": "Escribe tu mensaje, @file, @agent, o pega imágenes y texto...", + "promptInput.hints.shell.exit": "para salir del modo shell", + "promptInput.hints.shell.enable": "Modo shell", + "promptInput.hints.commands": "Comandos", + "promptInput.history.previousAriaLabel": "Prompt anterior", + "promptInput.history.nextAriaLabel": "Siguiente prompt", + "promptInput.overlay.newLine": "Nueva línea", + "promptInput.overlay.send": "Enviar", + "promptInput.overlay.filesAgents": "Archivos/agentes", + "promptInput.overlay.history": "Historial", + "promptInput.overlay.attachments": "• {count} archivo(s) adjunto(s)", + "promptInput.overlay.shellModeActive": "Modo shell activo", + "promptInput.overlay.press": "Pulsa", + "promptInput.overlay.againToAbort": "otra vez para abortar la sesión", + "promptInput.stopSession.ariaLabel": "Detener sesión", + "promptInput.stopSession.title": "Detener sesión", + "promptInput.send.ariaLabel": "Enviar mensaje", + "promptInput.send.errorFallback": "No se pudo enviar el mensaje", + "promptInput.send.errorTitle": "Error al enviar", +} as const diff --git a/packages/ui/src/lib/i18n/messages/es/remoteAccess.ts b/packages/ui/src/lib/i18n/messages/es/remoteAccess.ts new file mode 100644 index 00000000..3539c8f4 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/es/remoteAccess.ts @@ -0,0 +1,51 @@ +export const remoteAccessMessages = { + "remoteAccess.eyebrow": "Transferencia remota", + "remoteAccess.title": "Conectar a CodeNomad de forma remota", + "remoteAccess.subtitle": "Usa las direcciones de abajo para abrir CodeNomad desde otro dispositivo.", + "remoteAccess.close": "Cerrar acceso remoto", + "remoteAccess.refresh": "Actualizar", + + "remoteAccess.sections.listeningMode.label": "Modo de escucha", + "remoteAccess.sections.listeningMode.help": "Permite o limita las transferencias remotas vinculando a todas las interfaces o solo a localhost.", + "remoteAccess.toggle.on": "Activado", + "remoteAccess.toggle.off": "Desactivado", + "remoteAccess.toggle.title": "Permitir conexiones desde otras IP", + "remoteAccess.toggle.caption.all": "Vinculado a 0.0.0.0", + "remoteAccess.toggle.caption.local": "Vinculado a 127.0.0.1", + "remoteAccess.toggle.note": "Cambiar esto requiere reiniciar y detiene temporalmente todas las instancias activas. Comparte las direcciones de abajo una vez que el servidor se reinicie.", + "remoteAccess.listeningMode.restartConfirm.message": "¿Reiniciar para aplicar el modo de escucha? Esto detendrá todas las instancias en ejecución.", + "remoteAccess.listeningMode.restartConfirm.title.all": "Abrir a otros dispositivos", + "remoteAccess.listeningMode.restartConfirm.title.local": "Limitar a este dispositivo", + "remoteAccess.listeningMode.restartConfirm.confirmLabel": "Reiniciar ahora", + "remoteAccess.listeningMode.restartConfirm.cancelLabel": "Cancelar", + "remoteAccess.restart.errorManual": "No se pudo reiniciar automáticamente. Reinicia la app para aplicar el cambio.", + + "remoteAccess.sections.serverPassword.label": "Contraseña del servidor", + "remoteAccess.sections.serverPassword.help": "Las transferencias remotas requieren una contraseña. Define una fácil de recordar para habilitar inicios de sesión desde otros dispositivos.", + "remoteAccess.authStatus.unavailable": "Estado de autenticación no disponible.", + "remoteAccess.username": "Usuario: {username}", + "remoteAccess.password.status.set": "Hay una contraseña configurada para el acceso remoto.", + "remoteAccess.password.status.unset": "Aún no hay una contraseña fácil de recordar. Configura una para permitir inicios de sesión por transferencia remota.", + "remoteAccess.password.actions.cancel": "Cancelar", + "remoteAccess.password.actions.change": "Cambiar contraseña", + "remoteAccess.password.actions.set": "Configurar contraseña", + "remoteAccess.password.form.newPassword": "Nueva contraseña", + "remoteAccess.password.form.confirmPassword": "Confirmar contraseña", + "remoteAccess.password.form.placeholder": "Al menos 8 caracteres", + "remoteAccess.password.error.tooShort": "La contraseña debe tener al menos 8 caracteres.", + "remoteAccess.password.error.mismatch": "Las contraseñas no coinciden.", + "remoteAccess.password.save.saving": "Guardando…", + "remoteAccess.password.save.label": "Guardar contraseña", + + "remoteAccess.sections.addresses.label": "Direcciones accesibles", + "remoteAccess.sections.addresses.help": "Abre o escanea desde otra máquina para transferir el control.", + "remoteAccess.addresses.loading": "Cargando direcciones…", + "remoteAccess.addresses.none": "Aún no hay direcciones disponibles.", + "remoteAccess.address.scope.network": "Red", + "remoteAccess.address.scope.loopback": "Loopback", + "remoteAccess.address.scope.internal": "Interna", + "remoteAccess.address.open": "Abrir", + "remoteAccess.address.showQr": "Mostrar QR", + "remoteAccess.address.hideQr": "Ocultar QR", + "remoteAccess.address.qrAlt": "QR para {url}", +} as const diff --git a/packages/ui/src/lib/i18n/messages/es/session.ts b/packages/ui/src/lib/i18n/messages/es/session.ts new file mode 100644 index 00000000..f4ab8ff7 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/es/session.ts @@ -0,0 +1,67 @@ +export const sessionMessages = { + "sessionPicker.title": "OpenCode • {folder}", + "sessionPicker.empty.noPrevious": "No hay sesiones anteriores", + "sessionPicker.resume.title": "Reanudar una sesión ({count}):", + "sessionPicker.session.untitled": "Sin título", + "sessionPicker.divider.or": "o", + "sessionPicker.new.title": "Iniciar nueva sesión:", + "sessionPicker.agents.loading": "Cargando agentes...", + "sessionPicker.actions.creating": "Creando...", + "sessionPicker.actions.createSession": "Crear sesión", + "sessionPicker.actions.cancel": "Cancelar", + + "sessionList.header.title": "Sesiones", + "sessionList.session.untitled": "Sin título", + "sessionList.status.working": "Trabajando", + "sessionList.status.compacting": "Compactando", + "sessionList.status.idle": "Inactiva", + "sessionList.status.needsPermission": "Requiere permiso", + "sessionList.status.needsInput": "Requiere entrada", + "sessionList.expand.collapseAriaLabel": "Colapsar sesión", + "sessionList.expand.expandAriaLabel": "Expandir sesión", + "sessionList.expand.collapseTitle": "Colapsar", + "sessionList.expand.expandTitle": "Expandir", + "sessionList.actions.copyId.ariaLabel": "Copiar ID de sesión", + "sessionList.actions.copyId.title": "Copiar ID de sesión", + "sessionList.actions.rename.ariaLabel": "Renombrar sesión", + "sessionList.actions.rename.title": "Renombrar sesión", + "sessionList.actions.delete.ariaLabel": "Eliminar sesión", + "sessionList.actions.delete.title": "Eliminar sesión", + "sessionList.copyId.success": "ID de sesión copiado", + "sessionList.copyId.error": "No se pudo copiar el ID de sesión", + "sessionList.delete.error": "No se pudo eliminar la sesión", + "sessionList.rename.error": "No se pudo renombrar la sesión", + + "sessionRenameDialog.title": "Renombrar sesión", + "sessionRenameDialog.description.withLabel": "Actualiza el título de \"{label}\".", + "sessionRenameDialog.description.default": "Establece un nuevo título para esta sesión.", + "sessionRenameDialog.input.label": "Nombre de la sesión", + "sessionRenameDialog.input.placeholder": "Introduce un nombre de sesión", + "sessionRenameDialog.actions.cancel": "Cancelar", + "sessionRenameDialog.actions.rename": "Renombrar", + "sessionRenameDialog.actions.renaming": "Renombrando…", + + "sessionView.fallback.sessionNotFound": "No se encontró la sesión", + "sessionView.alerts.abortFailed.message": "No se pudo detener la sesión", + "sessionView.alerts.abortFailed.title": "No se pudo detener", + "sessionView.alerts.revertFailed.message": "No se pudo revertir al mensaje", + "sessionView.alerts.revertFailed.title": "No se pudo revertir", + "sessionView.alerts.forkFailed.message": "No se pudo hacer fork de la sesión", + "sessionView.alerts.forkFailed.title": "No se pudo hacer fork", + "sessionView.attachments.expandPastedTextAriaLabel": "Expandir texto pegado", + "sessionView.attachments.insertPastedTextTitle": "Insertar texto pegado", + "sessionView.attachments.removeAriaLabel": "Quitar adjunto", + + "sessionEvents.sessionCompactedToast": "La sesión {label} fue compactada", + "sessionEvents.sessionError.unknown": "Error desconocido", + "sessionEvents.sessionError.title": "Error de sesión", + "sessionEvents.sessionError.message": "Error: {message}", + + "sessionState.cleanup.deepConfirm.message": "Esta limpieza puede ser lenta y puede eliminar sesiones que no pretendías eliminar. ¿Estás seguro?", + "sessionState.cleanup.deepConfirm.title": "Limpieza profunda de sesiones", + "sessionState.cleanup.deepConfirm.detail": "La limpieza profunda de sesiones eliminará todas las sesiones sin mensajes, quitará cualquier sesión de subagente finalizada y limpiará cualquier fork no usado de una sesión.", + "sessionState.cleanup.deepConfirm.confirmLabel": "Continuar", + "sessionState.cleanup.deepConfirm.cancelLabel": "Cancelar", + "sessionState.cleanup.toast.one": "Se limpió {count} sesión vacía", + "sessionState.cleanup.toast.other": "Se limpiaron {count} sesiones vacías", +} as const diff --git a/packages/ui/src/lib/i18n/messages/es/settings.ts b/packages/ui/src/lib/i18n/messages/es/settings.ts new file mode 100644 index 00000000..ca0a14f2 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/es/settings.ts @@ -0,0 +1,54 @@ +export const settingsMessages = { + "instanceServiceStatus.sections.lsp": "Servidores LSP", + "instanceServiceStatus.sections.mcp": "Servidores MCP", + "instanceServiceStatus.sections.plugins": "Plugins", + "instanceServiceStatus.lsp.loading": "Cargando servidores LSP...", + "instanceServiceStatus.lsp.empty": "No se detectaron servidores LSP.", + "instanceServiceStatus.lsp.status.connected": "Conectado", + "instanceServiceStatus.lsp.status.error": "Error", + "instanceServiceStatus.mcp.loading": "Cargando servidores MCP...", + "instanceServiceStatus.mcp.empty": "No se detectaron servidores MCP.", + "instanceServiceStatus.mcp.toggleAriaLabel": "Alternar servidor MCP {name}", + "instanceServiceStatus.plugins.loading": "Cargando plugins...", + "instanceServiceStatus.plugins.empty": "No hay plugins configurados.", + + "permissionBanner.pendingRequests.one": "{count} solicitud pendiente", + "permissionBanner.pendingRequests.other": "{count} solicitudes pendientes", + "permissionBanner.detail.permission.one": "{count} permiso", + "permissionBanner.detail.permission.other": "{count} permisos", + "permissionBanner.detail.question.one": "{count} pregunta", + "permissionBanner.detail.question.other": "{count} preguntas", + "permissionBanner.detail.wrapper": " ({detail})", + + "agentSelector.placeholder": "Seleccionar agente...", + "agentSelector.badge.subagent": "subagente", + "agentSelector.none": "Ninguno", + "agentSelector.trigger.primary": "Agente: {agent}", + + "modelSelector.placeholder.search": "Buscar modelos...", + "modelSelector.none": "Ninguno", + "modelSelector.trigger.primary": "Modelo: {model}", + + "thinkingSelector.variant.default": "Por defecto", + "thinkingSelector.label": "Pensamiento: {variant}", + + "envEditor.title": "Variables de entorno", + "envEditor.count.one": "({count} variable)", + "envEditor.count.other": "({count} variables)", + "envEditor.fields.name.placeholder": "Nombre de la variable", + "envEditor.fields.name.readOnlyTitle": "Nombre de la variable (solo lectura)", + "envEditor.fields.value.placeholder": "Valor de la variable", + "envEditor.actions.remove.title": "Quitar variable", + "envEditor.actions.add.title": "Agregar variable", + "envEditor.empty": "No hay variables de entorno configuradas. Agrega variables arriba para personalizar el entorno de OpenCode.", + "envEditor.help": "Estas variables estarán disponibles en el entorno de OpenCode al iniciar instancias.", + + "contextUsagePanel.headings.tokens": "Tokens", + "contextUsagePanel.headings.context": "Contexto", + "contextUsagePanel.labels.input": "Entrada", + "contextUsagePanel.labels.output": "Salida", + "contextUsagePanel.labels.cost": "Costo", + "contextUsagePanel.labels.used": "Usado", + "contextUsagePanel.labels.available": "Disp.", + "contextUsagePanel.unavailable": "--", +} as const diff --git a/packages/ui/src/lib/i18n/messages/es/time.ts b/packages/ui/src/lib/i18n/messages/es/time.ts new file mode 100644 index 00000000..3dfbeadd --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/es/time.ts @@ -0,0 +1,6 @@ +export const timeMessages = { + "time.relative.justNow": "justo ahora", + "time.relative.daysAgoShort": "hace {count} d", + "time.relative.hoursAgoShort": "hace {count} h", + "time.relative.minutesAgoShort": "hace {count} m", +} as const diff --git a/packages/ui/src/lib/i18n/messages/es/toolCall.ts b/packages/ui/src/lib/i18n/messages/es/toolCall.ts new file mode 100644 index 00000000..e42c6ea0 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/es/toolCall.ts @@ -0,0 +1,121 @@ +export const toolCallMessages = { + "toolCall.pending.waitingToRun": "Esperando para ejecutar...", + "toolCall.error.label": "Error:", + + "toolCall.diff.label": "Diff", + "toolCall.diff.label.withPath": "Diff · {path}", + "toolCall.diff.viewMode.ariaLabel": "Modo de vista de diff", + "toolCall.diff.viewMode.split": "Dividida", + "toolCall.diff.viewMode.unified": "Unificada", + + "toolCall.diagnostics.title": "Diagnósticos", + "toolCall.diagnostics.ariaLabel": "Diagnósticos", + "toolCall.diagnostics.ariaLabel.withLabel": "Diagnósticos {label}", + "toolCall.diagnostics.severity.error.short": "ERR", + "toolCall.diagnostics.severity.warning.short": "WARN", + "toolCall.diagnostics.severity.info.short": "INFO", + + "toolCall.renderer.toolName.shell": "Shell", + "toolCall.renderer.toolName.fetch": "Fetch", + "toolCall.renderer.toolName.invalid": "Inválido", + "toolCall.renderer.toolName.plan": "Plan", + "toolCall.renderer.toolName.applyPatch": "Aplicar patch", + + "toolCall.renderer.action.working": "Trabajando...", + "toolCall.renderer.action.writingCommand": "Escribiendo comando...", + "toolCall.renderer.action.preparingEdit": "Preparando edición...", + "toolCall.renderer.action.readingFile": "Leyendo archivo...", + "toolCall.renderer.action.preparingWrite": "Preparando escritura...", + "toolCall.renderer.action.preparingPatch": "Preparando patch...", + "toolCall.renderer.action.planning": "Planificando...", + "toolCall.renderer.action.fetchingFromWeb": "Obteniendo desde la web...", + "toolCall.renderer.action.findingFiles": "Buscando archivos...", + "toolCall.renderer.action.searchingContent": "Buscando contenido...", + "toolCall.renderer.action.listingDirectory": "Listando directorio...", + + "toolCall.renderer.bash.title.timeout": "Tiempo de espera: {timeout}", + "toolCall.renderer.read.detail.offset": "Desplazamiento: {offset}", + "toolCall.renderer.read.detail.limit": "Límite: {limit}", + + "toolCall.renderer.todo.empty": "Aún no hay elementos del plan.", + "toolCall.renderer.todo.status.pending": "Pendiente", + "toolCall.renderer.todo.status.inProgress": "En progreso", + "toolCall.renderer.todo.status.completed": "Completado", + "toolCall.renderer.todo.status.cancelled": "Cancelado", + "toolCall.renderer.todo.title.plan": "Plan", + "toolCall.renderer.todo.title.creating": "Creando plan", + "toolCall.renderer.todo.title.completing": "Completando plan", + "toolCall.renderer.todo.title.updating": "Actualizando plan", + + "toolCall.permission.status.required": "Permiso requerido", + "toolCall.permission.status.queued": "Permiso en cola", + "toolCall.permission.requestedDiff.label": "Diff solicitado", + "toolCall.permission.requestedDiff.withPath": "Diff solicitado · {path}", + "toolCall.permission.queuedText": "Esperando respuestas de permisos anteriores.", + "toolCall.permission.actions.allowOnce": "Permitir una vez", + "toolCall.permission.actions.alwaysAllow": "Permitir siempre", + "toolCall.permission.actions.deny": "Denegar", + "toolCall.permission.shortcuts.allowOnce": "Permitir una vez", + "toolCall.permission.shortcuts.alwaysAllow": "Permitir siempre", + "toolCall.permission.shortcuts.deny": "Denegar", + "toolCall.permission.errors.unableToUpdate": "No se pudo actualizar el permiso", + + "permissionApproval.title": "Solicitudes", + "permissionApproval.empty": "No hay solicitudes pendientes.", + "permissionApproval.kind.permission": "Permiso", + "permissionApproval.kind.question": "Pregunta", + "permissionApproval.questionCount.one": "{count} pregunta", + "permissionApproval.questionCount.other": "{count} preguntas", + "permissionApproval.status.active": "Activa", + "permissionApproval.actions.closeAriaLabel": "Cerrar", + "permissionApproval.actions.goToSession": "Ir a sesión", + "permissionApproval.actions.loadingSession": "Cargando…", + "permissionApproval.actions.loadSession": "Cargar sesión", + "permissionApproval.actions.allowOnce": "Permitir una vez", + "permissionApproval.actions.alwaysAllow": "Permitir siempre", + "permissionApproval.actions.deny": "Denegar", + "permissionApproval.fallbackHint": "Carga la sesión para más información.", + "permissionApproval.errors.unableToUpdatePermission": "No se pudo actualizar el permiso", + + "toolCall.question.status.required": "Pregunta requerida", + "toolCall.question.status.queued": "Pregunta en cola", + "toolCall.question.status.questions": "Preguntas", + "toolCall.question.action.awaitingAnswers": "Esperando respuestas...", + "toolCall.question.title.questions": "Preguntas", + "toolCall.question.title.askingQuestions": "Haciendo preguntas", + "toolCall.question.type.one": "Pregunta", + "toolCall.question.type.other": "Preguntas", + "toolCall.question.number": "P{number}:", + "toolCall.question.multiple": "Múltiple", + "toolCall.question.custom.title": "Escribe una respuesta personalizada", + "toolCall.question.custom.label": "Respuesta personalizada", + "toolCall.question.custom.placeholder": "Escribe tu propia respuesta", + "toolCall.question.actions.submit": "Enviar", + "toolCall.question.actions.dismiss": "Descartar", + "toolCall.question.shortcuts.submit": "Enviar", + "toolCall.question.shortcuts.dismiss": "Descartar", + "toolCall.question.queuedText": "Esperando respuestas anteriores.", + "toolCall.question.validation.answerAll": "Responde todas las preguntas antes de enviar.", + "toolCall.question.errors.unableToReply": "No se pudo responder", + "toolCall.question.errors.unableToDismiss": "No se pudo descartar", + + "toolCall.task.action.delegating": "Delegando...", + "toolCall.task.sections.prompt": "Prompt", + "toolCall.task.sections.steps": "Pasos", + "toolCall.task.sections.output": "Salida", + "toolCall.task.steps.count": "{count} pasos", + "toolCall.task.meta.agentModel": "Agente: {agent} • Modelo: {model}", + "toolCall.task.meta.agent": "Agente: {agent}", + "toolCall.task.meta.model": "Modelo: {model}", + + "toolCall.status.pending": "Pendiente", + "toolCall.status.running": "En ejecución", + "toolCall.status.completed": "Completado", + "toolCall.status.error": "Error", + "toolCall.status.unknown": "Desconocido", + + "toolCall.applyPatch.action.preparing": "Preparando apply_patch...", + "toolCall.applyPatch.title.withFileCount.one": "{tool} ({count} archivo)", + "toolCall.applyPatch.title.withFileCount.other": "{tool} ({count} archivos)", + "toolCall.applyPatch.fileFallback": "Archivo {number}", +} as const diff --git a/packages/ui/src/lib/i18n/messages/fr/advancedSettings.ts b/packages/ui/src/lib/i18n/messages/fr/advancedSettings.ts new file mode 100644 index 00000000..ecd9c5e7 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/fr/advancedSettings.ts @@ -0,0 +1,6 @@ +export const advancedSettingsMessages = { + "advancedSettings.title": "Paramètres avancés", + "advancedSettings.environmentVariables.title": "Variables d'environnement", + "advancedSettings.environmentVariables.subtitle": "Appliquées à chaque démarrage d'une nouvelle instance OpenCode", + "advancedSettings.actions.close": "Fermer", +} as const diff --git a/packages/ui/src/lib/i18n/messages/fr/app.ts b/packages/ui/src/lib/i18n/messages/fr/app.ts new file mode 100644 index 00000000..b014c89a --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/fr/app.ts @@ -0,0 +1,29 @@ +export const appMessages = { + "app.launchError.title": "Impossible de lancer OpenCode", + "app.launchError.description": "Nous n'avons pas pu démarrer le binaire OpenCode sélectionné. Consultez la sortie d'erreur ci-dessous ou choisissez un autre binaire dans les Paramètres avancés.", + "app.launchError.binaryPathLabel": "Chemin du binaire", + "app.launchError.errorOutputLabel": "Sortie d'erreur", + "app.launchError.openAdvancedSettings": "Ouvrir les paramètres avancés", + "app.launchError.close": "Fermer", + "app.launchError.closeTitle": "Fermer (Esc)", + "app.launchError.fallbackMessage": "Échec du lancement de l'espace de travail", + + "app.stopInstance.confirmMessage": "Arrêter l'instance OpenCode ? Cela arrêtera le serveur.", + "app.stopInstance.title": "Arrêter l'instance", + "app.stopInstance.confirmLabel": "Arrêter", + "app.stopInstance.cancelLabel": "Laisser tourner", + + "emptyState.logoAlt": "Logo CodeNomad", + "emptyState.brandTitle": "CodeNomad", + "emptyState.tagline": "Sélectionnez un dossier pour commencer à coder avec l'IA", + "emptyState.actions.selectFolder": "Sélectionner un dossier", + "emptyState.actions.selecting": "Sélection...", + "emptyState.keyboardShortcut": "Raccourci clavier : {shortcut}", + "emptyState.examples": "Exemples : {example}", + "emptyState.multipleInstances": "Vous pouvez avoir plusieurs instances du même dossier", + + "releases.upgradeRequired.title": "Mise à jour requise", + "releases.upgradeRequired.message.withVersion": "Mettez à jour vers CodeNomad {version} pour utiliser la dernière UI.", + "releases.upgradeRequired.message.noVersion": "Mettez à jour CodeNomad pour utiliser la dernière UI.", + "releases.upgradeRequired.action.getUpdate": "Obtenir la mise à jour", +} as const diff --git a/packages/ui/src/lib/i18n/messages/fr/commands.ts b/packages/ui/src/lib/i18n/messages/fr/commands.ts new file mode 100644 index 00000000..b19499e6 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/fr/commands.ts @@ -0,0 +1,160 @@ +export const commandMessages = { + "commandPalette.title": "Palette de commandes", + "commandPalette.description": "Rechercher et exécuter des commandes", + "commandPalette.searchPlaceholder": "Tapez une commande ou recherchez...", + "commandPalette.empty": "Aucune commande trouvée pour \"{query}\"", + "commandPalette.category.customCommands": "Commandes personnalisées", + "commandPalette.category.instance": "Instance", + "commandPalette.category.session": "Session", + "commandPalette.category.agentModel": "Agent et modèle", + "commandPalette.category.inputFocus": "Saisie et focus", + "commandPalette.category.system": "Système", + "commandPalette.category.other": "Autre", + + "commands.newInstance.label": "Nouvelle instance", + "commands.newInstance.description": "Ouvrir le sélecteur de dossiers pour créer une nouvelle instance", + "commands.newInstance.keywords": "dossier, projet, espace de travail", + + "commands.closeInstance.label": "Fermer l'instance", + "commands.closeInstance.description": "Arrêter le serveur de l'instance actuelle", + "commands.closeInstance.keywords": "arrêter, quitter, fermer", + + "commands.nextInstance.label": "Instance suivante", + "commands.nextInstance.description": "Passer à l'onglet d'instance suivant", + "commands.nextInstance.keywords": "changer, naviguer, suivant", + + "commands.previousInstance.label": "Instance précédente", + "commands.previousInstance.description": "Passer à l'onglet d'instance précédent", + "commands.previousInstance.keywords": "changer, naviguer, précédent", + + "commands.newSession.label": "Nouvelle session", + "commands.newSession.description": "Créer une nouvelle session parente", + "commands.newSession.keywords": "créer, démarrer", + + "commands.closeSession.label": "Fermer la session", + "commands.closeSession.description": "Fermer la session parente actuelle", + "commands.closeSession.keywords": "fermer, arrêter", + + "commands.scrubSessions.label": "Nettoyer les sessions", + "commands.scrubSessions.description": "Supprimer les sessions vides, les sessions de sous-agent ayant terminé leur tâche principale, ainsi que les sessions forkées inutiles.", + "commands.scrubSessions.keywords": "nettoyage, vide, sessions, supprimer, effacer", + + "commands.instanceInfo.label": "Infos de l'instance", + "commands.instanceInfo.description": "Ouvrir la vue d'ensemble de l'instance pour les journaux et le statut", + "commands.instanceInfo.keywords": "infos, journaux, console, sortie, logs", + + "commands.nextSession.label": "Session suivante", + "commands.nextSession.description": "Passer à l'onglet de session suivant", + "commands.nextSession.keywords": "changer, naviguer, suivant", + + "commands.previousSession.label": "Session précédente", + "commands.previousSession.description": "Passer à l'onglet de session précédent", + "commands.previousSession.keywords": "changer, naviguer, précédent", + + "commands.compactSession.label": "Compacter la session", + "commands.compactSession.description": "Résumer et compacter la session actuelle", + "commands.compactSession.keywords": "résumer, compresser, compact", + "commands.compactSession.errorFallback": "Impossible de compacter la session", + "commands.compactSession.alert.title": "Échec du compactage", + "commands.compactSession.alert.message": "Échec du compactage : {message}", + + "commands.undoLastMessage.label": "Annuler le dernier message", + "commands.undoLastMessage.description": "Revenir sur le dernier message", + "commands.undoLastMessage.keywords": "revenir, annuler", + "commands.undoLastMessage.none.title": "Aucune action à annuler", + "commands.undoLastMessage.none.message": "Rien à annuler", + "commands.undoLastMessage.failed.title": "Échec de l'annulation", + "commands.undoLastMessage.failed.message": "Impossible de revenir au message", + + "commands.openModelSelector.label": "Ouvrir le sélecteur de modèle", + "commands.openModelSelector.description": "Choisir un autre modèle", + "commands.openModelSelector.keywords": "modèle, llm, ia, ai", + + "commands.selectModelVariant.label": "Sélectionner la variante du modèle", + "commands.selectModelVariant.description": "Choisir un effort de réflexion pour le modèle actuel", + "commands.selectModelVariant.keywords": "variante, réflexion, raisonnement, effort", + + "commands.openAgentSelector.label": "Ouvrir le sélecteur d'agent", + "commands.openAgentSelector.description": "Choisir un autre agent", + "commands.openAgentSelector.keywords": "agent, mode", + + "commands.clearInput.label": "Effacer la saisie", + "commands.clearInput.description": "Effacer la zone de texte du prompt", + "commands.clearInput.keywords": "effacer, réinitialiser, prompt", + + "commands.thinkingBlocks.label.show": "Afficher les blocs de réflexion", + "commands.thinkingBlocks.label.hide": "Masquer les blocs de réflexion", + "commands.thinkingBlocks.description": "Afficher/masquer le processus de réflexion de l'IA", + "commands.thinkingBlocks.keywords": "réflexion, raisonnement, basculer, afficher, masquer", + + "commands.timelineToolCalls.label.show": "Afficher les appels d'outil dans la timeline", + "commands.timelineToolCalls.label.hide": "Masquer les appels d'outil dans la timeline", + "commands.timelineToolCalls.description": "Afficher/masquer les entrées d'appel d'outil dans la timeline des messages", + "commands.timelineToolCalls.keywords": "timeline, outil, basculer", + + "commands.common.expanded": "Développé", + "commands.common.collapsed": "Réduit", + "commands.common.visible": "Visible", + "commands.common.hidden": "Masqué", + "commands.common.enabled": "Activé", + "commands.common.disabled": "Désactivé", + + "commands.thinkingBlocksDefault.label": "Blocs de réflexion par défaut · {state}", + "commands.thinkingBlocksDefault.description": "Choisir si les blocs de réflexion démarrent développés", + "commands.thinkingBlocksDefault.keywords": "réflexion, raisonnement, développer, réduire, défaut", + + "commands.diffViewSplit.label": "Utiliser la vue diff côte à côte", + "commands.diffViewSplit.description": "Afficher les diffs d'appels d'outil côte à côte", + "commands.diffViewSplit.keywords": "diff, côte à côte, vue", + + "commands.diffViewUnified.label": "Utiliser la vue diff unifiée", + "commands.diffViewUnified.description": "Afficher les diffs d'appels d'outil en ligne", + "commands.diffViewUnified.keywords": "diff, unifiée, vue", + + "commands.toolOutputsDefault.label": "Sorties d'outil par défaut · {state}", + "commands.toolOutputsDefault.description": "Choisir l'ouverture par défaut des sorties d'outil", + "commands.toolOutputsDefault.keywords": "outil, sortie, développer, réduire", + + "commands.diagnosticsDefault.label": "Diagnostics par défaut · {state}", + "commands.diagnosticsDefault.description": "Choisir l'ouverture par défaut de la sortie des diagnostics", + "commands.diagnosticsDefault.keywords": "diagnostics, développer, réduire", + + "commands.tokenUsageDisplay.label": "Affichage de l'usage des tokens · {state}", + "commands.tokenUsageDisplay.description": "Afficher ou masquer les stats de tokens et de coût pour les messages de l'assistant", + "commands.tokenUsageDisplay.keywords": "token, usage, coût, stats", + + "commands.autoCleanupBlankSessions.label": "Nettoyage auto des sessions vides · {state}", + "commands.autoCleanupBlankSessions.description": "Nettoyer automatiquement les sessions vides lors de la création de nouvelles", + "commands.autoCleanupBlankSessions.keywords": "auto, nettoyage, vide, sessions, basculer", + + "commands.showHelp.label": "Afficher l'aide", + "commands.showHelp.description": "Afficher les raccourcis clavier et l'aide", + "commands.showHelp.keywords": "raccourcis, aide", + + "commands.custom.argumentsPrompt.message": "Arguments pour /{name}", + "commands.custom.argumentsPrompt.title": "Commande personnalisée", + "commands.custom.argumentsPrompt.inputLabel": "Arguments", + "commands.custom.argumentsPrompt.inputPlaceholder": "ex. foo bar", + "commands.custom.argumentsPrompt.confirmLabel": "Exécuter", + "commands.custom.argumentsPrompt.cancelLabel": "Annuler", + "commands.custom.argumentsPrompt.openFailed.message": "Impossible d'ouvrir l'invite d'arguments.", + "commands.custom.argumentsPrompt.openFailed.title": "Arguments de commande", + "commands.custom.entries.descriptionFallback": "Commande personnalisée", + "commands.custom.sessionRequired.message": "Sélectionnez une session avant d'exécuter une commande personnalisée.", + "commands.custom.sessionRequired.title": "Session requise", + "commands.custom.runFailed.message": "Impossible d'exécuter la commande personnalisée. Consultez la console pour les détails.", + "commands.custom.runFailed.title": "Échec de la commande", + + "unifiedPicker.loading.searching": "Recherche...", + "unifiedPicker.loading.loadingWorkspace": "Chargement de l'espace de travail...", + "unifiedPicker.title.command": "Sélectionner une commande", + "unifiedPicker.title.mention": "Sélectionner un agent ou un fichier", + "unifiedPicker.empty": "Aucun résultat", + "unifiedPicker.sections.commands": "COMMANDES", + "unifiedPicker.sections.agents": "AGENTS", + "unifiedPicker.sections.files": "FICHIERS", + "unifiedPicker.badge.subagent": "sous-agent", + "unifiedPicker.footer.navigate": "naviguer", + "unifiedPicker.footer.select": "sélectionner", + "unifiedPicker.footer.close": "fermer", +} as const diff --git a/packages/ui/src/lib/i18n/messages/fr/dialogs.ts b/packages/ui/src/lib/i18n/messages/fr/dialogs.ts new file mode 100644 index 00000000..a9789362 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/fr/dialogs.ts @@ -0,0 +1,16 @@ +export const dialogMessages = { + "alertDialog.fallbackTitle.info": "Attention", + "alertDialog.fallbackTitle.warning": "Veuillez vérifier", + "alertDialog.fallbackTitle.error": "Un problème est survenu", + "alertDialog.actions.confirm": "Confirmer", + "alertDialog.actions.run": "Exécuter", + "alertDialog.actions.ok": "OK", + "alertDialog.actions.cancel": "Annuler", + "alertDialog.prompt.inputLabel": "Saisie", + + "backgroundProcessOutputDialog.title": "Sortie en arrière-plan", + "backgroundProcessOutputDialog.actions.close": "Fermer", + "backgroundProcessOutputDialog.loading": "Chargement de la sortie...", + "backgroundProcessOutputDialog.truncatedNotice": "Sortie tronquée pour l'affichage.", + "backgroundProcessOutputDialog.loadErrorFallback": "Impossible de charger la sortie.", +} as const diff --git a/packages/ui/src/lib/i18n/messages/fr/filesystem.ts b/packages/ui/src/lib/i18n/messages/fr/filesystem.ts new file mode 100644 index 00000000..b9c4dce8 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/fr/filesystem.ts @@ -0,0 +1,43 @@ +export const filesystemMessages = { + "directoryBrowser.defaultDescription": "Parcourez les dossiers sous la racine d'espace de travail configurée.", + "directoryBrowser.close": "Fermer", + "directoryBrowser.currentFolder": "Dossier actuel", + "directoryBrowser.selectCurrent": "Sélectionner le dossier actuel", + "directoryBrowser.newFolder": "Nouveau dossier", + "directoryBrowser.creating": "Création…", + "directoryBrowser.loadingFolders": "Chargement des dossiers…", + "directoryBrowser.noFolders": "Aucun dossier disponible.", + "directoryBrowser.upOneLevel": "Remonter d'un niveau", + "directoryBrowser.select": "Sélectionner", + "directoryBrowser.load.errorFallback": "Impossible de charger le système de fichiers", + "directoryBrowser.createFolder.promptMessage": "Créer un nouveau dossier dans le répertoire courant.", + "directoryBrowser.createFolder.title": "Nouveau dossier", + "directoryBrowser.createFolder.inputLabel": "Nom du dossier", + "directoryBrowser.createFolder.inputPlaceholder": "ex. mon-nouveau-projet", + "directoryBrowser.createFolder.confirmLabel": "Créer", + "directoryBrowser.createFolder.cancelLabel": "Annuler", + "directoryBrowser.createFolder.invalidNameMessage": "Veuillez saisir un seul nom de dossier.", + "directoryBrowser.createFolder.invalidNameDetail": "Les noms de dossier ne peuvent pas contenir de barres obliques, '..' ou '~'.", + "directoryBrowser.createFolder.errorFallback": "Impossible de créer le dossier", + + "filesystemBrowser.descriptionFallback": "Recherchez un chemin sous la racine d'espace de travail configurée.", + "filesystemBrowser.rootLabel": "Racine : {root}", + "filesystemBrowser.actions.close": "Fermer", + "filesystemBrowser.actions.retry": "Réessayer", + "filesystemBrowser.actions.select": "Sélectionner", + "filesystemBrowser.filterLabel": "Filtrer", + "filesystemBrowser.search.placeholder.directories": "Rechercher des dossiers", + "filesystemBrowser.search.placeholder.files": "Rechercher des fichiers", + "filesystemBrowser.currentFolder.label": "Dossier actuel", + "filesystemBrowser.currentFolder.selectCurrent": "Sélectionner le dossier actuel", + "filesystemBrowser.loading.filesystem": "système de fichiers", + "filesystemBrowser.loading.workspaceRoot": "racine de l'espace de travail", + "filesystemBrowser.loading.loadingWithPath": "Chargement de {path}…", + "filesystemBrowser.empty.noEntries": "Aucune entrée trouvée.", + "filesystemBrowser.navigation.upOneLevel": "Remonter d'un niveau", + "filesystemBrowser.hints.navigate": "Naviguer", + "filesystemBrowser.hints.select": "Sélectionner", + "filesystemBrowser.hints.close": "Fermer", + "filesystemBrowser.errors.loadFilesystemFallback": "Impossible de charger le système de fichiers", + "filesystemBrowser.errors.openDirectoryFallback": "Impossible d'ouvrir le répertoire", +} as const diff --git a/packages/ui/src/lib/i18n/messages/fr/folderSelection.ts b/packages/ui/src/lib/i18n/messages/fr/folderSelection.ts new file mode 100644 index 00000000..c64816da --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/fr/folderSelection.ts @@ -0,0 +1,34 @@ +export const folderSelectionMessages = { + "folderSelection.logoAlt": "Logo CodeNomad", + "folderSelection.tagline": "Sélectionnez un dossier pour commencer à coder avec l'IA", + + "folderSelection.links.github": "GitHub de CodeNomad", + "folderSelection.links.githubStars": "Stars GitHub de CodeNomad", + "folderSelection.links.discord": "Discord de CodeNomad", + + "folderSelection.empty.title": "Aucun dossier récent", + "folderSelection.empty.description": "Parcourez un dossier pour commencer", + + "folderSelection.recent.title": "Dossiers récents", + "folderSelection.recent.subtitle.one": "{count} dossier disponible", + "folderSelection.recent.subtitle.other": "{count} dossiers disponibles", + "folderSelection.recent.remove": "Retirer des récents", + + "folderSelection.browse.title": "Parcourir les dossiers", + "folderSelection.browse.subtitle": "Sélectionnez n'importe quel dossier sur votre ordinateur", + "folderSelection.browse.button": "Parcourir les dossiers", + "folderSelection.browse.buttonOpening": "Ouverture...", + + "folderSelection.advancedSettings": "Paramètres avancés", + + "folderSelection.hints.navigate": "Naviguer", + "folderSelection.hints.select": "Sélectionner", + "folderSelection.hints.remove": "Retirer", + "folderSelection.hints.browse": "Parcourir", + + "folderSelection.loading.title": "Démarrage de l'instance...", + "folderSelection.loading.subtitle": "Patientez pendant que nous préparons votre espace de travail.", + + "folderSelection.dialog.title": "Sélectionner l'espace de travail", + "folderSelection.dialog.description": "Sélectionnez un espace de travail pour commencer à coder.", +} as const diff --git a/packages/ui/src/lib/i18n/messages/fr/index.ts b/packages/ui/src/lib/i18n/messages/fr/index.ts new file mode 100644 index 00000000..ac9d1c6e --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/fr/index.ts @@ -0,0 +1,36 @@ +import { advancedSettingsMessages } from "./advancedSettings" +import { appMessages } from "./app" +import { commandMessages } from "./commands" +import { dialogMessages } from "./dialogs" +import { filesystemMessages } from "./filesystem" +import { folderSelectionMessages } from "./folderSelection" +import { instanceMessages } from "./instance" +import { loadingScreenMessages } from "./loadingScreen" +import { logMessages } from "./logs" +import { markdownMessages } from "./markdown" +import { messagingMessages } from "./messaging" +import { remoteAccessMessages } from "./remoteAccess" +import { sessionMessages } from "./session" +import { settingsMessages } from "./settings" +import { timeMessages } from "./time" +import { toolCallMessages } from "./toolCall" +import { mergeMessageParts } from "../merge" + +export const frMessages = mergeMessageParts( + folderSelectionMessages, + advancedSettingsMessages, + loadingScreenMessages, + timeMessages, + appMessages, + dialogMessages, + filesystemMessages, + instanceMessages, + logMessages, + sessionMessages, + messagingMessages, + toolCallMessages, + markdownMessages, + settingsMessages, + remoteAccessMessages, + commandMessages, +) diff --git a/packages/ui/src/lib/i18n/messages/fr/instance.ts b/packages/ui/src/lib/i18n/messages/fr/instance.ts new file mode 100644 index 00000000..562f50ef --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/fr/instance.ts @@ -0,0 +1,125 @@ +export const instanceMessages = { + "instanceTabs.new.title": "Nouvelle instance (Cmd/Ctrl+N)", + "instanceTabs.new.ariaLabel": "Nouvelle instance", + "instanceTabs.remote.title": "Connexion à distance", + "instanceTabs.remote.ariaLabel": "Connexion à distance", + + "instanceInfo.title": "Informations de l'instance", + "instanceInfo.labels.folder": "Dossier", + "instanceInfo.labels.project": "Projet", + "instanceInfo.labels.versionControl": "Contrôle de version", + "instanceInfo.labels.opencodeVersion": "Version d'OpenCode", + "instanceInfo.labels.binaryPath": "Chemin du binaire", + "instanceInfo.labels.environmentVariables": "Variables d'environnement ({count})", + "instanceInfo.loading": "Chargement...", + "instanceInfo.server.title": "Serveur", + "instanceInfo.server.port": "Port :", + "instanceInfo.server.pid": "PID :", + "instanceInfo.server.status": "Statut :", + + "instanceTab.status.permission": "En attente d'autorisation", + "instanceTab.status.compacting": "Compactage", + "instanceTab.status.working": "En cours", + "instanceTab.status.idle": "Inactif", + "instanceTab.status.ariaLabel": "Statut de l'instance : {status}", + "instanceTab.actions.close.ariaLabel": "Fermer l'instance", + + "instanceShell.leftPanel.sessionsTitle": "Sessions", + "instanceShell.leftPanel.instanceInfo": "Infos de l'instance", + + "instanceShell.leftDrawer.pin": "Épingler le tiroir gauche", + "instanceShell.leftDrawer.unpin": "Désépingler le tiroir gauche", + "instanceShell.leftDrawer.toggle.pinned": "Tiroir gauche épinglé", + "instanceShell.leftDrawer.toggle.open": "Ouvrir le tiroir gauche", + "instanceShell.leftDrawer.toggle.close": "Fermer le tiroir gauche", + + "instanceShell.rightDrawer.pin": "Épingler le tiroir droit", + "instanceShell.rightDrawer.unpin": "Désépingler le tiroir droit", + "instanceShell.rightDrawer.toggle.pinned": "Tiroir droit épinglé", + "instanceShell.rightDrawer.toggle.open": "Ouvrir le tiroir droit", + "instanceShell.rightDrawer.toggle.close": "Fermer le tiroir droit", + + "instanceShell.metrics.usedLabel": "Utilisé", + "instanceShell.metrics.availableLabel": "Dispo", + + "instanceShell.commandPalette.openAriaLabel": "Ouvrir la palette de commandes", + "instanceShell.commandPalette.button": "Palette de commandes", + + "instanceShell.connection.ariaLabel": "Connexion {status}", + "instanceShell.connection.connected": "Connecté", + "instanceShell.connection.connecting": "Connexion...", + "instanceShell.connection.disconnected": "Déconnecté", + "instanceShell.connection.unknown": "Inconnu", + + "instanceWelcome.shortcuts.newSession": "Nouvelle session", + "instanceWelcome.empty.title": "Aucune session précédente", + "instanceWelcome.empty.description": "Créez une nouvelle session ci-dessous pour commencer", + "instanceWelcome.loading.title": "Chargement des sessions", + "instanceWelcome.loading.description": "Récupération de vos sessions précédentes...", + "instanceWelcome.resume.title": "Reprendre une session", + "instanceWelcome.resume.subtitle.one": "{count} session disponible", + "instanceWelcome.resume.subtitle.other": "{count} sessions disponibles", + "instanceWelcome.session.untitled": "Session sans titre", + "instanceWelcome.new.title": "Démarrer une nouvelle session", + "instanceWelcome.new.subtitle": "Nous réutiliserons automatiquement votre dernier agent/modèle", + "instanceWelcome.new.createButton": "Créer la session", + "instanceWelcome.overlay.close": "Fermer", + "instanceWelcome.actions.viewInstanceInfo": "Voir les infos de l'instance", + "instanceWelcome.actions.renameTitle": "Renommer la session", + "instanceWelcome.actions.deleteTitle": "Supprimer la session", + "instanceWelcome.hints.navigate": "Naviguer", + "instanceWelcome.hints.jump": "Sauter", + "instanceWelcome.hints.firstLast": "Prem./Dern.", + "instanceWelcome.hints.resume": "Reprendre", + "instanceWelcome.hints.delete": "Supprimer", + "instanceWelcome.toasts.renameError": "Impossible de renommer la session", + + "instanceDisconnected.title": "Instance déconnectée", + "instanceDisconnected.folderFallback": "cet espace de travail", + "instanceDisconnected.reasonFallback": "Le serveur ne répond plus", + "instanceDisconnected.description": "{folder} n'est plus accessible. Fermez l'onglet pour continuer à travailler.", + "instanceDisconnected.details.title": "Détails", + "instanceDisconnected.details.folderLabel": "Dossier :", + "instanceDisconnected.actions.closeInstance": "Fermer l'instance", + + "instanceShell.empty.title": "Aucune session sélectionnée", + "instanceShell.empty.description": "Sélectionnez une session pour voir les messages", + + "instanceShell.rightPanel.title": "Panneau d'état", + "instanceShell.rightPanel.sections.plan": "Plan", + "instanceShell.rightPanel.sections.backgroundProcesses": "Shells en arrière-plan", + "instanceShell.rightPanel.sections.mcp": "Serveurs MCP", + "instanceShell.rightPanel.sections.lsp": "Serveurs LSP", + "instanceShell.rightPanel.sections.plugins": "Plugins", + + "instanceShell.plan.noSessionSelected": "Sélectionnez une session pour voir le plan.", + "instanceShell.plan.empty": "Aucun plan pour l'instant.", + + "instanceShell.backgroundProcesses.empty": "Aucun processus en arrière-plan.", + "instanceShell.backgroundProcesses.status": "Statut : {status}", + "instanceShell.backgroundProcesses.output": "Sortie : {sizeKb}KB", + "instanceShell.backgroundProcesses.actions.output": "Sortie", + "instanceShell.backgroundProcesses.actions.stop": "Arrêter", + "instanceShell.backgroundProcesses.actions.terminate": "Terminer", + + "versionPill.appWithVersion": "Appli {version}", + "versionPill.ui": "UI", + "versionPill.uiWithVersion": "UI {version}", + "versionPill.source": " ({source})", + + "opencodeBinarySelector.title": "Binaire OpenCode", + "opencodeBinarySelector.subtitle": "Choisissez quel exécutable OpenCode doit lancer", + "opencodeBinarySelector.customPath.placeholder": "Saisissez le chemin vers le binaire opencode…", + "opencodeBinarySelector.actions.add": "Ajouter", + "opencodeBinarySelector.actions.browse": "Parcourir le binaire…", + "opencodeBinarySelector.actions.removeTitle": "Supprimer le binaire", + "opencodeBinarySelector.badge.systemPath": "Utiliser le binaire depuis le PATH système", + "opencodeBinarySelector.status.checkingVersions": "Vérification des versions…", + "opencodeBinarySelector.status.checking": "Vérification…", + "opencodeBinarySelector.dialog.title": "Sélectionner le binaire OpenCode", + "opencodeBinarySelector.dialog.description": "Parcourez les fichiers exposés par le serveur CLI.", + "opencodeBinarySelector.validation.invalidBinary": "Binaire OpenCode invalide", + "opencodeBinarySelector.validation.alreadyValidating": "Validation déjà en cours", + "opencodeBinarySelector.display.systemPath": "{name} (PATH système)", + "opencodeBinarySelector.versionLabel": "v{version}", +} as const diff --git a/packages/ui/src/lib/i18n/messages/fr/loadingScreen.ts b/packages/ui/src/lib/i18n/messages/fr/loadingScreen.ts new file mode 100644 index 00000000..48c0d68c --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/fr/loadingScreen.ts @@ -0,0 +1,17 @@ +export const loadingScreenMessages = { + "loadingScreen.logoAlt": "Logo CodeNomad", + "loadingScreen.status.issue": "Un problème est survenu", + "loadingScreen.actions.showAnother": "En afficher un autre", + "loadingScreen.errors.missingRoot": "Élément racine de chargement introuvable", + + "loadingScreen.phrases.neurons": "Réchauffage des neurones de l'IA…", + "loadingScreen.phrases.daydreaming": "On convainc l'IA d'arrêter de rêvasser…", + "loadingScreen.phrases.goggles": "Polissage des lunettes de code de l'IA…", + "loadingScreen.phrases.reorganizingFiles": "On demande à l'IA d'arrêter de réorganiser vos fichiers…", + "loadingScreen.phrases.coffee": "On donne un café supplémentaire à l'IA…", + "loadingScreen.phrases.nodeModules": "On apprend à l'IA à ne pas supprimer node_modules (encore)…", + "loadingScreen.phrases.actNatural": "On dit à l'IA d'avoir l'air naturel avant votre arrivée…", + "loadingScreen.phrases.rewritingHistory": "On demande à l'IA d'arrêter de réécrire l'histoire…", + "loadingScreen.phrases.stretch": "On laisse l'IA s'étirer avant son sprint de code…", + "loadingScreen.phrases.keyboardControl": "On persuade l'IA de vous rendre le contrôle du clavier…", +} as const diff --git a/packages/ui/src/lib/i18n/messages/fr/logs.ts b/packages/ui/src/lib/i18n/messages/fr/logs.ts new file mode 100644 index 00000000..eda164fa --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/fr/logs.ts @@ -0,0 +1,18 @@ +export const logMessages = { + "logsView.title": "Journaux du serveur", + "logsView.actions.show": "Afficher les journaux du serveur", + "logsView.actions.hide": "Masquer les journaux du serveur", + "logsView.envVars.title": "Variables d'environnement ({count})", + "logsView.paused.title": "Les journaux du serveur sont en pause", + "logsView.paused.description": "Activez le streaming pour suivre l'activité de votre serveur OpenCode.", + "logsView.empty.waiting": "En attente de la sortie du serveur...", + "logsView.scrollToBottom": "Aller en bas", + + "infoView.logs.title": "Journaux du serveur", + "infoView.logs.actions.show": "Afficher les journaux du serveur", + "infoView.logs.actions.hide": "Masquer les journaux du serveur", + "infoView.logs.paused.title": "Les journaux du serveur sont en pause", + "infoView.logs.paused.description": "Activez le streaming pour suivre l'activité de votre serveur OpenCode.", + "infoView.logs.empty.waiting": "En attente de la sortie du serveur...", + "infoView.logs.scrollToBottom": "Aller en bas", +} as const diff --git a/packages/ui/src/lib/i18n/messages/fr/markdown.ts b/packages/ui/src/lib/i18n/messages/fr/markdown.ts new file mode 100644 index 00000000..42a6915a --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/fr/markdown.ts @@ -0,0 +1,7 @@ +export const markdownMessages = { + "markdown.codeBlock.copy.label": "Copier", + "markdown.codeBlock.copy.copied": "Copié !", + "markdown.codeBlock.copy.failed": "Échec", + + "markdown.copy": "Copier", +} as const diff --git a/packages/ui/src/lib/i18n/messages/fr/messaging.ts b/packages/ui/src/lib/i18n/messages/fr/messaging.ts new file mode 100644 index 00000000..0e786925 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/fr/messaging.ts @@ -0,0 +1,109 @@ +export const messagingMessages = { + "messageListHeader.sidebar.openSessionListAriaLabel": "Ouvrir la liste des sessions", + "messageListHeader.metrics.usedLabel": "Utilisé", + "messageListHeader.metrics.availableLabel": "Dispo", + "messageListHeader.commandPalette.ariaLabel": "Ouvrir la palette de commandes", + "messageListHeader.commandPalette.button": "Palette de commandes", + "messageListHeader.connection.connected": "Connecté", + "messageListHeader.connection.connecting": "Connexion...", + "messageListHeader.connection.disconnected": "Déconnecté", + + "messageSection.empty.logoAlt": "Logo CodeNomad", + "messageSection.empty.brandTitle": "CodeNomad", + "messageSection.empty.title": "Démarrer une conversation", + "messageSection.empty.description": "Saisissez un message ci-dessous ou ouvrez la palette de commandes :", + "messageSection.empty.tips.commandPalette": "Palette de commandes", + "messageSection.empty.tips.askAboutCodebase": "Parler de votre codebase", + "messageSection.empty.tips.attachFilesPrefix": "Joindre des fichiers avec", + "messageSection.loading.messages": "Chargement des messages...", + "messageSection.scroll.toFirstAriaLabel": "Aller au premier message", + "messageSection.scroll.toLatestAriaLabel": "Aller au dernier message", + "messageSection.quote.addAsQuote": "Ajouter en citation", + "messageSection.quote.addAsCode": "Ajouter en code", + + "messageTimeline.ariaLabel": "Chronologie des messages", + "messageTimeline.segment.user.label": "Vous", + "messageTimeline.segment.assistant.label": "Asst", + "messageTimeline.segment.compaction.label": "Compaction", + "messageTimeline.tool.fallbackLabel": "Appel d'outil", + "messageTimeline.tooltip.userFallback": "Message utilisateur", + "messageTimeline.tooltip.assistantFallback": "Réponse de l'assistant", + "messageTimeline.tooltip.compaction.auto": "Compaction auto", + "messageTimeline.tooltip.compaction.manual": "Compaction utilisateur", + "messageTimeline.text.filePrefix": "[Fichier] {filename}", + "messageTimeline.text.attachment": "Pièce jointe", + + "messageBlock.tool.header": "Appel d'outil", + "messageBlock.tool.unknown": "inconnu", + "messageBlock.tool.goToSession.label": "Aller à la session", + "messageBlock.tool.goToSession.title": "Aller à la session", + "messageBlock.tool.goToSession.unavailableTitle": "Session pas encore disponible", + + "messageBlock.compaction.ariaLabel": "Compaction de la session", + "messageBlock.compaction.autoLabel": "Session compactée automatiquement", + "messageBlock.compaction.manualLabel": "Session compactée par vous", + "messageBlock.usage.input": "Entrée", + "messageBlock.usage.output": "Sortie", + "messageBlock.usage.reasoning": "Raisonnement", + "messageBlock.usage.cacheRead": "Lecture du cache", + "messageBlock.usage.cacheWrite": "Écriture du cache", + "messageBlock.usage.cost": "Coût", + "messageBlock.step.agentLabel": "Agent : {agent}", + "messageBlock.step.modelLabel": "Modèle : {model}", + "messageBlock.reasoning.thinkingLabel": "Réflexion", + "messageBlock.reasoning.expandAriaLabel": "Développer la réflexion", + "messageBlock.reasoning.collapseAriaLabel": "Réduire la réflexion", + "messageBlock.reasoning.indicator.hide": "Masquer", + "messageBlock.reasoning.indicator.view": "Voir", + "messageBlock.reasoning.detailsAriaLabel": "Détails du raisonnement", + + "codeBlockInline.actions.copy": "Copier", + "codeBlockInline.actions.copied": "Copié !", + + "messageItem.speaker.you": "Vous", + "messageItem.speaker.assistant": "Assistant", + "messageItem.actions.revert": "Revenir", + "messageItem.actions.revertTitle": "Revenir à ce message", + "messageItem.actions.fork": "Fork", + "messageItem.actions.forkTitle": "Fork depuis ce message", + "messageItem.actions.copy": "Copier", + "messageItem.actions.copyTitle": "Copier le message", + "messageItem.actions.copied": "Copié !", + "messageItem.status.queued": "EN FILE", + "messageItem.status.generating": "Génération...", + "messageItem.status.sending": "Envoi...", + "messageItem.status.failedToSend": "Échec de l'envoi du message", + "messageItem.attachment.defaultName": "piece-jointe", + "messageItem.attachment.downloadAriaLabel": "Télécharger {name}", + "messageItem.agentMeta.agentLabel": "Agent : {agent}", + "messageItem.agentMeta.modelLabel": "Modèle : {model}", + "messageItem.errors.authenticationFallback": "Erreur d'authentification", + "messageItem.errors.outputLengthExceeded": "Longueur de sortie du message dépassée", + "messageItem.errors.requestAborted": "La requête a été annulée", + "messageItem.errors.unknownFallback": "Une erreur inconnue est survenue", + + "attachmentChip.removeAriaLabel": "Retirer la pièce jointe", + + "expandButton.toggleAriaLabel": "Basculer la hauteur de la zone de saisie", + + "promptInput.placeholder.shell": "Exécuter une commande shell (Esc pour quitter)...", + "promptInput.placeholder.default": "Tapez votre message, @fichier, @agent, ou collez des images et du texte...", + "promptInput.hints.shell.exit": "pour quitter le mode shell", + "promptInput.hints.shell.enable": "Mode shell", + "promptInput.hints.commands": "Commandes", + "promptInput.history.previousAriaLabel": "Prompt précédent", + "promptInput.history.nextAriaLabel": "Prompt suivant", + "promptInput.overlay.newLine": "Nouvelle ligne", + "promptInput.overlay.send": "Envoyer", + "promptInput.overlay.filesAgents": "Fichiers/agents", + "promptInput.overlay.history": "Historique", + "promptInput.overlay.attachments": "• {count} fichier(s) joint(s)", + "promptInput.overlay.shellModeActive": "Mode shell actif", + "promptInput.overlay.press": "Appuyez sur", + "promptInput.overlay.againToAbort": "à nouveau pour interrompre la session", + "promptInput.stopSession.ariaLabel": "Arrêter la session", + "promptInput.stopSession.title": "Arrêter la session", + "promptInput.send.ariaLabel": "Envoyer le message", + "promptInput.send.errorFallback": "Impossible d'envoyer le message", + "promptInput.send.errorTitle": "Échec de l'envoi", +} as const diff --git a/packages/ui/src/lib/i18n/messages/fr/remoteAccess.ts b/packages/ui/src/lib/i18n/messages/fr/remoteAccess.ts new file mode 100644 index 00000000..8049b1c2 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/fr/remoteAccess.ts @@ -0,0 +1,51 @@ +export const remoteAccessMessages = { + "remoteAccess.eyebrow": "Passation à distance", + "remoteAccess.title": "Se connecter à CodeNomad à distance", + "remoteAccess.subtitle": "Utilisez les adresses ci-dessous pour ouvrir CodeNomad depuis un autre appareil.", + "remoteAccess.close": "Fermer l'accès à distance", + "remoteAccess.refresh": "Rafraîchir", + + "remoteAccess.sections.listeningMode.label": "Mode d'écoute", + "remoteAccess.sections.listeningMode.help": "Autorisez ou limitez les passations à distance en écoutant sur toutes les interfaces ou uniquement sur localhost.", + "remoteAccess.toggle.on": "Activé", + "remoteAccess.toggle.off": "Désactivé", + "remoteAccess.toggle.title": "Autoriser les connexions depuis d'autres IP", + "remoteAccess.toggle.caption.all": "Écoute sur 0.0.0.0", + "remoteAccess.toggle.caption.local": "Écoute sur 127.0.0.1", + "remoteAccess.toggle.note": "Modifier ceci nécessite un redémarrage et stoppe temporairement toutes les instances actives. Partagez les adresses ci-dessous une fois le serveur redémarré.", + "remoteAccess.listeningMode.restartConfirm.message": "Redémarrer pour appliquer le mode d'écoute ? Cela arrêtera toutes les instances en cours.", + "remoteAccess.listeningMode.restartConfirm.title.all": "Ouvrir aux autres appareils", + "remoteAccess.listeningMode.restartConfirm.title.local": "Limiter à cet appareil", + "remoteAccess.listeningMode.restartConfirm.confirmLabel": "Redémarrer maintenant", + "remoteAccess.listeningMode.restartConfirm.cancelLabel": "Annuler", + "remoteAccess.restart.errorManual": "Impossible de redémarrer automatiquement. Veuillez redémarrer l'application pour appliquer le changement.", + + "remoteAccess.sections.serverPassword.label": "Mot de passe du serveur", + "remoteAccess.sections.serverPassword.help": "Les passations à distance nécessitent un mot de passe. Définissez-en un facile à retenir pour autoriser la connexion depuis d'autres appareils.", + "remoteAccess.authStatus.unavailable": "Statut d'authentification indisponible.", + "remoteAccess.username": "Nom d'utilisateur : {username}", + "remoteAccess.password.status.set": "Un mot de passe est défini pour l'accès à distance.", + "remoteAccess.password.status.unset": "Aucun mot de passe mémorable n'est encore défini. Définissez-en un pour autoriser les connexions à distance.", + "remoteAccess.password.actions.cancel": "Annuler", + "remoteAccess.password.actions.change": "Changer le mot de passe", + "remoteAccess.password.actions.set": "Définir le mot de passe", + "remoteAccess.password.form.newPassword": "Nouveau mot de passe", + "remoteAccess.password.form.confirmPassword": "Confirmer le mot de passe", + "remoteAccess.password.form.placeholder": "Au moins 8 caractères", + "remoteAccess.password.error.tooShort": "Le mot de passe doit contenir au moins 8 caractères.", + "remoteAccess.password.error.mismatch": "Les mots de passe ne correspondent pas.", + "remoteAccess.password.save.saving": "Enregistrement…", + "remoteAccess.password.save.label": "Enregistrer le mot de passe", + + "remoteAccess.sections.addresses.label": "Adresses accessibles", + "remoteAccess.sections.addresses.help": "Lancez ou scannez depuis une autre machine pour passer le contrôle.", + "remoteAccess.addresses.loading": "Chargement des adresses…", + "remoteAccess.addresses.none": "Aucune adresse disponible pour le moment.", + "remoteAccess.address.scope.network": "Réseau", + "remoteAccess.address.scope.loopback": "Boucle locale", + "remoteAccess.address.scope.internal": "Interne", + "remoteAccess.address.open": "Ouvrir", + "remoteAccess.address.showQr": "Afficher le QR", + "remoteAccess.address.hideQr": "Masquer le QR", + "remoteAccess.address.qrAlt": "QR pour {url}", +} as const diff --git a/packages/ui/src/lib/i18n/messages/fr/session.ts b/packages/ui/src/lib/i18n/messages/fr/session.ts new file mode 100644 index 00000000..79b34762 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/fr/session.ts @@ -0,0 +1,67 @@ +export const sessionMessages = { + "sessionPicker.title": "OpenCode • {folder}", + "sessionPicker.empty.noPrevious": "Aucune session précédente", + "sessionPicker.resume.title": "Reprendre une session ({count}) :", + "sessionPicker.session.untitled": "Sans titre", + "sessionPicker.divider.or": "ou", + "sessionPicker.new.title": "Démarrer une nouvelle session :", + "sessionPicker.agents.loading": "Chargement des agents...", + "sessionPicker.actions.creating": "Création...", + "sessionPicker.actions.createSession": "Créer une session", + "sessionPicker.actions.cancel": "Annuler", + + "sessionList.header.title": "Sessions", + "sessionList.session.untitled": "Sans titre", + "sessionList.status.working": "En cours", + "sessionList.status.compacting": "Compactage", + "sessionList.status.idle": "Inactif", + "sessionList.status.needsPermission": "Autorisation requise", + "sessionList.status.needsInput": "Entrée requise", + "sessionList.expand.collapseAriaLabel": "Réduire la session", + "sessionList.expand.expandAriaLabel": "Développer la session", + "sessionList.expand.collapseTitle": "Réduire", + "sessionList.expand.expandTitle": "Développer", + "sessionList.actions.copyId.ariaLabel": "Copier l'ID de session", + "sessionList.actions.copyId.title": "Copier l'ID de session", + "sessionList.actions.rename.ariaLabel": "Renommer la session", + "sessionList.actions.rename.title": "Renommer la session", + "sessionList.actions.delete.ariaLabel": "Supprimer la session", + "sessionList.actions.delete.title": "Supprimer la session", + "sessionList.copyId.success": "ID de session copié", + "sessionList.copyId.error": "Impossible de copier l'ID de session", + "sessionList.delete.error": "Impossible de supprimer la session", + "sessionList.rename.error": "Impossible de renommer la session", + + "sessionRenameDialog.title": "Renommer la session", + "sessionRenameDialog.description.withLabel": "Mettre à jour le titre de \"{label}\".", + "sessionRenameDialog.description.default": "Définir un nouveau titre pour cette session.", + "sessionRenameDialog.input.label": "Nom de la session", + "sessionRenameDialog.input.placeholder": "Saisissez un nom de session", + "sessionRenameDialog.actions.cancel": "Annuler", + "sessionRenameDialog.actions.rename": "Renommer", + "sessionRenameDialog.actions.renaming": "Renommage…", + + "sessionView.fallback.sessionNotFound": "Session introuvable", + "sessionView.alerts.abortFailed.message": "Impossible d'arrêter la session", + "sessionView.alerts.abortFailed.title": "Échec de l'arrêt", + "sessionView.alerts.revertFailed.message": "Impossible de revenir au message", + "sessionView.alerts.revertFailed.title": "Échec du retour", + "sessionView.alerts.forkFailed.message": "Impossible de forker la session", + "sessionView.alerts.forkFailed.title": "Échec du fork", + "sessionView.attachments.expandPastedTextAriaLabel": "Développer le texte collé", + "sessionView.attachments.insertPastedTextTitle": "Insérer le texte collé", + "sessionView.attachments.removeAriaLabel": "Retirer la pièce jointe", + + "sessionEvents.sessionCompactedToast": "La session {label} a été compactée", + "sessionEvents.sessionError.unknown": "Erreur inconnue", + "sessionEvents.sessionError.title": "Erreur de session", + "sessionEvents.sessionError.message": "Erreur : {message}", + + "sessionState.cleanup.deepConfirm.message": "Ce nettoyage peut être lent et peut supprimer des sessions que vous ne vouliez pas supprimer. Confirmez-vous ?", + "sessionState.cleanup.deepConfirm.title": "Nettoyage approfondi des sessions", + "sessionState.cleanup.deepConfirm.detail": "Le nettoyage approfondi des sessions supprime toutes les sessions sans messages, retire les sessions de sous-agent terminées et efface les forks inutilisés d'une session.", + "sessionState.cleanup.deepConfirm.confirmLabel": "Continuer", + "sessionState.cleanup.deepConfirm.cancelLabel": "Annuler", + "sessionState.cleanup.toast.one": "Nettoyage de {count} session vide", + "sessionState.cleanup.toast.other": "Nettoyage de {count} sessions vides", +} as const diff --git a/packages/ui/src/lib/i18n/messages/fr/settings.ts b/packages/ui/src/lib/i18n/messages/fr/settings.ts new file mode 100644 index 00000000..4c4badf8 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/fr/settings.ts @@ -0,0 +1,54 @@ +export const settingsMessages = { + "instanceServiceStatus.sections.lsp": "Serveurs LSP", + "instanceServiceStatus.sections.mcp": "Serveurs MCP", + "instanceServiceStatus.sections.plugins": "Plugins", + "instanceServiceStatus.lsp.loading": "Chargement des serveurs LSP...", + "instanceServiceStatus.lsp.empty": "Aucun serveur LSP détecté.", + "instanceServiceStatus.lsp.status.connected": "Connecté", + "instanceServiceStatus.lsp.status.error": "Erreur", + "instanceServiceStatus.mcp.loading": "Chargement des serveurs MCP...", + "instanceServiceStatus.mcp.empty": "Aucun serveur MCP détecté.", + "instanceServiceStatus.mcp.toggleAriaLabel": "Basculer le serveur MCP {name}", + "instanceServiceStatus.plugins.loading": "Chargement des plugins...", + "instanceServiceStatus.plugins.empty": "Aucun plugin configuré.", + + "permissionBanner.pendingRequests.one": "{count} demande en attente", + "permissionBanner.pendingRequests.other": "{count} demandes en attente", + "permissionBanner.detail.permission.one": "{count} autorisation", + "permissionBanner.detail.permission.other": "{count} autorisations", + "permissionBanner.detail.question.one": "{count} question", + "permissionBanner.detail.question.other": "{count} questions", + "permissionBanner.detail.wrapper": " ({detail})", + + "agentSelector.placeholder": "Sélectionner un agent...", + "agentSelector.badge.subagent": "sous-agent", + "agentSelector.none": "Aucun", + "agentSelector.trigger.primary": "Agent : {agent}", + + "modelSelector.placeholder.search": "Rechercher des modèles...", + "modelSelector.none": "Aucun", + "modelSelector.trigger.primary": "Modèle : {model}", + + "thinkingSelector.variant.default": "Par défaut", + "thinkingSelector.label": "Réflexion : {variant}", + + "envEditor.title": "Variables d'environnement", + "envEditor.count.one": "({count} variable)", + "envEditor.count.other": "({count} variables)", + "envEditor.fields.name.placeholder": "Nom de la variable", + "envEditor.fields.name.readOnlyTitle": "Nom de la variable (lecture seule)", + "envEditor.fields.value.placeholder": "Valeur de la variable", + "envEditor.actions.remove.title": "Supprimer la variable", + "envEditor.actions.add.title": "Ajouter une variable", + "envEditor.empty": "Aucune variable d'environnement configurée. Ajoutez des variables ci-dessus pour personnaliser l'environnement OpenCode.", + "envEditor.help": "Ces variables seront disponibles dans l'environnement OpenCode lors du démarrage des instances.", + + "contextUsagePanel.headings.tokens": "Tokens", + "contextUsagePanel.headings.context": "Contexte", + "contextUsagePanel.labels.input": "Entrée", + "contextUsagePanel.labels.output": "Sortie", + "contextUsagePanel.labels.cost": "Coût", + "contextUsagePanel.labels.used": "Utilisé", + "contextUsagePanel.labels.available": "Dispo", + "contextUsagePanel.unavailable": "--", +} as const diff --git a/packages/ui/src/lib/i18n/messages/fr/time.ts b/packages/ui/src/lib/i18n/messages/fr/time.ts new file mode 100644 index 00000000..e36e0a24 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/fr/time.ts @@ -0,0 +1,6 @@ +export const timeMessages = { + "time.relative.justNow": "à l'instant", + "time.relative.daysAgoShort": "il y a {count} j", + "time.relative.hoursAgoShort": "il y a {count} h", + "time.relative.minutesAgoShort": "il y a {count} min", +} as const diff --git a/packages/ui/src/lib/i18n/messages/fr/toolCall.ts b/packages/ui/src/lib/i18n/messages/fr/toolCall.ts new file mode 100644 index 00000000..8de4c8e2 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/fr/toolCall.ts @@ -0,0 +1,121 @@ +export const toolCallMessages = { + "toolCall.pending.waitingToRun": "En attente d'exécution...", + "toolCall.error.label": "Erreur :", + + "toolCall.diff.label": "Diff", + "toolCall.diff.label.withPath": "Diff · {path}", + "toolCall.diff.viewMode.ariaLabel": "Mode d'affichage du diff", + "toolCall.diff.viewMode.split": "Côte à côte", + "toolCall.diff.viewMode.unified": "Unifié", + + "toolCall.diagnostics.title": "Diagnostics", + "toolCall.diagnostics.ariaLabel": "Diagnostics", + "toolCall.diagnostics.ariaLabel.withLabel": "Diagnostics {label}", + "toolCall.diagnostics.severity.error.short": "ERR", + "toolCall.diagnostics.severity.warning.short": "WARN", + "toolCall.diagnostics.severity.info.short": "INFO", + + "toolCall.renderer.toolName.shell": "Shell", + "toolCall.renderer.toolName.fetch": "Fetch", + "toolCall.renderer.toolName.invalid": "Invalide", + "toolCall.renderer.toolName.plan": "Plan", + "toolCall.renderer.toolName.applyPatch": "Appliquer le patch", + + "toolCall.renderer.action.working": "En cours...", + "toolCall.renderer.action.writingCommand": "Rédaction de la commande...", + "toolCall.renderer.action.preparingEdit": "Préparation de la modification...", + "toolCall.renderer.action.readingFile": "Lecture du fichier...", + "toolCall.renderer.action.preparingWrite": "Préparation de l'écriture...", + "toolCall.renderer.action.preparingPatch": "Préparation du patch...", + "toolCall.renderer.action.planning": "Planification...", + "toolCall.renderer.action.fetchingFromWeb": "Récupération sur le Web...", + "toolCall.renderer.action.findingFiles": "Recherche de fichiers...", + "toolCall.renderer.action.searchingContent": "Recherche dans le contenu...", + "toolCall.renderer.action.listingDirectory": "Liste du répertoire...", + + "toolCall.renderer.bash.title.timeout": "Délai : {timeout}", + "toolCall.renderer.read.detail.offset": "Décalage : {offset}", + "toolCall.renderer.read.detail.limit": "Limite : {limit}", + + "toolCall.renderer.todo.empty": "Aucun élément de plan pour l'instant.", + "toolCall.renderer.todo.status.pending": "En attente", + "toolCall.renderer.todo.status.inProgress": "En cours", + "toolCall.renderer.todo.status.completed": "Terminé", + "toolCall.renderer.todo.status.cancelled": "Annulé", + "toolCall.renderer.todo.title.plan": "Plan", + "toolCall.renderer.todo.title.creating": "Création du plan", + "toolCall.renderer.todo.title.completing": "Finalisation du plan", + "toolCall.renderer.todo.title.updating": "Mise à jour du plan", + + "toolCall.permission.status.required": "Autorisation requise", + "toolCall.permission.status.queued": "Autorisation en file d'attente", + "toolCall.permission.requestedDiff.label": "Diff demandé", + "toolCall.permission.requestedDiff.withPath": "Diff demandé · {path}", + "toolCall.permission.queuedText": "En attente des réponses d'autorisations précédentes.", + "toolCall.permission.actions.allowOnce": "Autoriser une fois", + "toolCall.permission.actions.alwaysAllow": "Toujours autoriser", + "toolCall.permission.actions.deny": "Refuser", + "toolCall.permission.shortcuts.allowOnce": "Autoriser une fois", + "toolCall.permission.shortcuts.alwaysAllow": "Toujours autoriser", + "toolCall.permission.shortcuts.deny": "Refuser", + "toolCall.permission.errors.unableToUpdate": "Impossible de mettre à jour l'autorisation", + + "permissionApproval.title": "Demandes", + "permissionApproval.empty": "Aucune demande en attente.", + "permissionApproval.kind.permission": "Autorisation", + "permissionApproval.kind.question": "Question", + "permissionApproval.questionCount.one": "{count} question", + "permissionApproval.questionCount.other": "{count} questions", + "permissionApproval.status.active": "Active", + "permissionApproval.actions.closeAriaLabel": "Fermer", + "permissionApproval.actions.goToSession": "Aller à la session", + "permissionApproval.actions.loadingSession": "Chargement…", + "permissionApproval.actions.loadSession": "Charger la session", + "permissionApproval.actions.allowOnce": "Autoriser une fois", + "permissionApproval.actions.alwaysAllow": "Toujours autoriser", + "permissionApproval.actions.deny": "Refuser", + "permissionApproval.fallbackHint": "Chargez la session pour plus d'informations.", + "permissionApproval.errors.unableToUpdatePermission": "Impossible de mettre à jour l'autorisation", + + "toolCall.question.status.required": "Question requise", + "toolCall.question.status.queued": "Question en file d'attente", + "toolCall.question.status.questions": "Questions", + "toolCall.question.action.awaitingAnswers": "En attente des réponses...", + "toolCall.question.title.questions": "Questions", + "toolCall.question.title.askingQuestions": "Questions en cours", + "toolCall.question.type.one": "Question", + "toolCall.question.type.other": "Questions", + "toolCall.question.number": "Q{number}:", + "toolCall.question.multiple": "Multiple", + "toolCall.question.custom.title": "Saisir une réponse personnalisée", + "toolCall.question.custom.label": "Réponse personnalisée", + "toolCall.question.custom.placeholder": "Saisissez votre propre réponse", + "toolCall.question.actions.submit": "Envoyer", + "toolCall.question.actions.dismiss": "Ignorer", + "toolCall.question.shortcuts.submit": "Envoyer", + "toolCall.question.shortcuts.dismiss": "Ignorer", + "toolCall.question.queuedText": "En attente des réponses précédentes.", + "toolCall.question.validation.answerAll": "Veuillez répondre à toutes les questions avant d'envoyer.", + "toolCall.question.errors.unableToReply": "Impossible de répondre", + "toolCall.question.errors.unableToDismiss": "Impossible d'ignorer", + + "toolCall.task.action.delegating": "Délégation...", + "toolCall.task.sections.prompt": "Prompt", + "toolCall.task.sections.steps": "Étapes", + "toolCall.task.sections.output": "Sortie", + "toolCall.task.steps.count": "{count} étapes", + "toolCall.task.meta.agentModel": "Agent : {agent} • Modèle : {model}", + "toolCall.task.meta.agent": "Agent : {agent}", + "toolCall.task.meta.model": "Modèle : {model}", + + "toolCall.status.pending": "En attente", + "toolCall.status.running": "En cours", + "toolCall.status.completed": "Terminé", + "toolCall.status.error": "Erreur", + "toolCall.status.unknown": "Inconnu", + + "toolCall.applyPatch.action.preparing": "Préparation de apply_patch...", + "toolCall.applyPatch.title.withFileCount.one": "{tool} ({count} fichier)", + "toolCall.applyPatch.title.withFileCount.other": "{tool} ({count} fichiers)", + "toolCall.applyPatch.fileFallback": "Fichier {number}", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ja/advancedSettings.ts b/packages/ui/src/lib/i18n/messages/ja/advancedSettings.ts new file mode 100644 index 00000000..7796a303 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ja/advancedSettings.ts @@ -0,0 +1,6 @@ +export const advancedSettingsMessages = { + "advancedSettings.title": "詳細設定", + "advancedSettings.environmentVariables.title": "環境変数", + "advancedSettings.environmentVariables.subtitle": "新しい OpenCode インスタンス起動時に適用", + "advancedSettings.actions.close": "閉じる", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ja/app.ts b/packages/ui/src/lib/i18n/messages/ja/app.ts new file mode 100644 index 00000000..b592cc59 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ja/app.ts @@ -0,0 +1,29 @@ +export const appMessages = { + "app.launchError.title": "OpenCode を起動できません", + "app.launchError.description": "選択された OpenCode バイナリを起動できませんでした。下のエラー出力を確認するか、詳細設定から別のバイナリを選択してください。", + "app.launchError.binaryPathLabel": "バイナリのパス", + "app.launchError.errorOutputLabel": "エラー出力", + "app.launchError.openAdvancedSettings": "詳細設定を開く", + "app.launchError.close": "閉じる", + "app.launchError.closeTitle": "閉じる (Esc)", + "app.launchError.fallbackMessage": "ワークスペースの起動に失敗しました", + + "app.stopInstance.confirmMessage": "OpenCode インスタンスを停止しますか?サーバーが停止します。", + "app.stopInstance.title": "インスタンスを停止", + "app.stopInstance.confirmLabel": "停止", + "app.stopInstance.cancelLabel": "実行を続ける", + + "emptyState.logoAlt": "CodeNomad ロゴ", + "emptyState.brandTitle": "CodeNomad", + "emptyState.tagline": "フォルダを選択して AI でコーディングを開始", + "emptyState.actions.selectFolder": "フォルダを選択", + "emptyState.actions.selecting": "選択中...", + "emptyState.keyboardShortcut": "キーボードショートカット: {shortcut}", + "emptyState.examples": "例: {example}", + "emptyState.multipleInstances": "同じフォルダのインスタンスを複数作成できます", + + "releases.upgradeRequired.title": "アップグレードが必要です", + "releases.upgradeRequired.message.withVersion": "最新の UI を使うには CodeNomad {version} に更新してください。", + "releases.upgradeRequired.message.noVersion": "最新の UI を使うには CodeNomad を更新してください。", + "releases.upgradeRequired.action.getUpdate": "更新を取得", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ja/commands.ts b/packages/ui/src/lib/i18n/messages/ja/commands.ts new file mode 100644 index 00000000..d22d2a2f --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ja/commands.ts @@ -0,0 +1,160 @@ +export const commandMessages = { + "commandPalette.title": "コマンドパレット", + "commandPalette.description": "コマンドを検索して実行", + "commandPalette.searchPlaceholder": "コマンドを入力するか検索...", + "commandPalette.empty": "「{query}」に一致するコマンドが見つかりません", + "commandPalette.category.customCommands": "カスタムコマンド", + "commandPalette.category.instance": "インスタンス", + "commandPalette.category.session": "セッション", + "commandPalette.category.agentModel": "エージェントとモデル", + "commandPalette.category.inputFocus": "入力とフォーカス", + "commandPalette.category.system": "システム", + "commandPalette.category.other": "その他", + + "commands.newInstance.label": "新しいインスタンス", + "commands.newInstance.description": "フォルダ選択を開いて新しいインスタンスを作成", + "commands.newInstance.keywords": "フォルダ, プロジェクト, ワークスペース, folder, project, workspace", + + "commands.closeInstance.label": "インスタンスを閉じる", + "commands.closeInstance.description": "現在のインスタンスのサーバーを停止", + "commands.closeInstance.keywords": "停止, 終了, 閉じる, stop, quit, close", + + "commands.nextInstance.label": "次のインスタンス", + "commands.nextInstance.description": "次のインスタンスタブへ切り替え", + "commands.nextInstance.keywords": "切り替え, 移動, switch, navigate", + + "commands.previousInstance.label": "前のインスタンス", + "commands.previousInstance.description": "前のインスタンスタブへ切り替え", + "commands.previousInstance.keywords": "切り替え, 移動, switch, navigate", + + "commands.newSession.label": "新しいセッション", + "commands.newSession.description": "新しい親セッションを作成", + "commands.newSession.keywords": "作成, 開始, create, start", + + "commands.closeSession.label": "セッションを閉じる", + "commands.closeSession.description": "現在の親セッションを閉じる", + "commands.closeSession.keywords": "閉じる, 停止, close, stop", + + "commands.scrubSessions.label": "セッションを整理", + "commands.scrubSessions.description": "空のセッション、主要タスクを完了したサブエージェントのセッション、不要なフォークされたセッションを削除します。", + "commands.scrubSessions.keywords": "整理, クリーンアップ, 空, セッション, 削除, cleanup, blank, empty, sessions, remove, delete, scrub", + + "commands.instanceInfo.label": "インスタンス情報", + "commands.instanceInfo.description": "ログと状態のインスタンス概要を開く", + "commands.instanceInfo.keywords": "情報, ログ, コンソール, 出力, info, logs, console, output", + + "commands.nextSession.label": "次のセッション", + "commands.nextSession.description": "次のセッションタブへ切り替え", + "commands.nextSession.keywords": "切り替え, 移動, switch, navigate", + + "commands.previousSession.label": "前のセッション", + "commands.previousSession.description": "前のセッションタブへ切り替え", + "commands.previousSession.keywords": "切り替え, 移動, switch, navigate", + + "commands.compactSession.label": "セッションをコンパクト化", + "commands.compactSession.description": "現在のセッションを要約して圧縮", + "commands.compactSession.keywords": "要約, 圧縮, summarize, compress", + "commands.compactSession.errorFallback": "セッションのコンパクト化に失敗しました", + "commands.compactSession.alert.title": "コンパクト化に失敗", + "commands.compactSession.alert.message": "コンパクト化に失敗しました: {message}", + + "commands.undoLastMessage.label": "直前のメッセージを取り消す", + "commands.undoLastMessage.description": "直前のメッセージへ戻す", + "commands.undoLastMessage.keywords": "取り消し, 戻す, revert, undo", + "commands.undoLastMessage.none.title": "取り消せる操作がありません", + "commands.undoLastMessage.none.message": "取り消すものがありません", + "commands.undoLastMessage.failed.title": "取り消しに失敗", + "commands.undoLastMessage.failed.message": "メッセージを戻せませんでした", + + "commands.openModelSelector.label": "モデルセレクターを開く", + "commands.openModelSelector.description": "別のモデルを選択", + "commands.openModelSelector.keywords": "モデル, LLM, AI, model, llm, ai", + + "commands.selectModelVariant.label": "モデルバリアントを選択", + "commands.selectModelVariant.description": "現在のモデルの思考量を選択", + "commands.selectModelVariant.keywords": "バリアント, 思考, 推論, 努力, variant, thinking, reasoning, effort", + + "commands.openAgentSelector.label": "エージェントセレクターを開く", + "commands.openAgentSelector.description": "別のエージェントを選択", + "commands.openAgentSelector.keywords": "エージェント, モード, agent, mode", + + "commands.clearInput.label": "入力をクリア", + "commands.clearInput.description": "プロンプト入力欄をクリア", + "commands.clearInput.keywords": "クリア, リセット, clear, reset", + + "commands.thinkingBlocks.label.show": "思考ブロックを表示", + "commands.thinkingBlocks.label.hide": "思考ブロックを非表示", + "commands.thinkingBlocks.description": "AI の思考過程を表示/非表示", + "commands.thinkingBlocks.keywords": "思考, 推論, 切り替え, 表示, 非表示, thinking, reasoning, toggle, show, hide", + + "commands.timelineToolCalls.label.show": "タイムラインのツールコールを表示", + "commands.timelineToolCalls.label.hide": "タイムラインのツールコールを非表示", + "commands.timelineToolCalls.description": "メッセージタイムラインのツールコール表示を切り替え", + "commands.timelineToolCalls.keywords": "タイムライン, ツール, 切り替え, timeline, tool, toggle", + + "commands.common.expanded": "展開", + "commands.common.collapsed": "折りたたみ", + "commands.common.visible": "表示", + "commands.common.hidden": "非表示", + "commands.common.enabled": "有効", + "commands.common.disabled": "無効", + + "commands.thinkingBlocksDefault.label": "思考ブロックの既定 · {state}", + "commands.thinkingBlocksDefault.description": "思考ブロックを既定で展開するか切り替え", + "commands.thinkingBlocksDefault.keywords": "思考, 推論, 展開, 折りたたみ, 既定, thinking, reasoning, expand, collapse, default", + + "commands.diffViewSplit.label": "分割 diff 表示を使用", + "commands.diffViewSplit.description": "ツールコールの diff を左右に並べて表示", + "commands.diffViewSplit.keywords": "diff, 分割, 表示, split, view", + + "commands.diffViewUnified.label": "ユニファイド diff 表示を使用", + "commands.diffViewUnified.description": "ツールコールの diff をインラインで表示", + "commands.diffViewUnified.keywords": "diff, ユニファイド, 表示, unified, view", + + "commands.toolOutputsDefault.label": "ツール出力の既定 · {state}", + "commands.toolOutputsDefault.description": "ツール出力を既定で展開するか切り替え", + "commands.toolOutputsDefault.keywords": "ツール, 出力, 展開, 折りたたみ, tool, output, expand, collapse", + + "commands.diagnosticsDefault.label": "診断の既定 · {state}", + "commands.diagnosticsDefault.description": "診断出力を既定で展開するか切り替え", + "commands.diagnosticsDefault.keywords": "診断, 展開, 折りたたみ, diagnostics, expand, collapse", + + "commands.tokenUsageDisplay.label": "トークン使用量表示 · {state}", + "commands.tokenUsageDisplay.description": "アシスタントメッセージのトークン/コスト統計を表示/非表示", + "commands.tokenUsageDisplay.keywords": "トークン, 使用量, コスト, 統計, token, usage, cost, stats", + + "commands.autoCleanupBlankSessions.label": "空セッションの自動クリーンアップ · {state}", + "commands.autoCleanupBlankSessions.description": "新しいセッション作成時に空のセッションを自動的に整理", + "commands.autoCleanupBlankSessions.keywords": "自動, クリーンアップ, 空, セッション, 切り替え, auto, cleanup, blank, sessions, toggle", + + "commands.showHelp.label": "ヘルプを表示", + "commands.showHelp.description": "キーボードショートカットとヘルプを表示", + "commands.showHelp.keywords": "ショートカット, ヘルプ, shortcuts, help", + + "commands.custom.argumentsPrompt.message": "/{name} の引数", + "commands.custom.argumentsPrompt.title": "カスタムコマンド", + "commands.custom.argumentsPrompt.inputLabel": "引数", + "commands.custom.argumentsPrompt.inputPlaceholder": "例: foo bar", + "commands.custom.argumentsPrompt.confirmLabel": "実行", + "commands.custom.argumentsPrompt.cancelLabel": "キャンセル", + "commands.custom.argumentsPrompt.openFailed.message": "引数入力を開けませんでした。", + "commands.custom.argumentsPrompt.openFailed.title": "コマンド引数", + "commands.custom.entries.descriptionFallback": "カスタムコマンド", + "commands.custom.sessionRequired.message": "カスタムコマンドを実行する前にセッションを選択してください。", + "commands.custom.sessionRequired.title": "セッションが必要です", + "commands.custom.runFailed.message": "カスタムコマンドの実行に失敗しました。詳細はコンソールを確認してください。", + "commands.custom.runFailed.title": "コマンドの実行に失敗", + + "unifiedPicker.loading.searching": "検索中...", + "unifiedPicker.loading.loadingWorkspace": "ワークスペースを読み込み中...", + "unifiedPicker.title.command": "コマンドを選択", + "unifiedPicker.title.mention": "エージェントまたはファイルを選択", + "unifiedPicker.empty": "結果が見つかりません", + "unifiedPicker.sections.commands": "コマンド", + "unifiedPicker.sections.agents": "エージェント", + "unifiedPicker.sections.files": "ファイル", + "unifiedPicker.badge.subagent": "サブエージェント", + "unifiedPicker.footer.navigate": "移動", + "unifiedPicker.footer.select": "選択", + "unifiedPicker.footer.close": "閉じる", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ja/dialogs.ts b/packages/ui/src/lib/i18n/messages/ja/dialogs.ts new file mode 100644 index 00000000..c060ba89 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ja/dialogs.ts @@ -0,0 +1,16 @@ +export const dialogMessages = { + "alertDialog.fallbackTitle.info": "お知らせ", + "alertDialog.fallbackTitle.warning": "ご確認ください", + "alertDialog.fallbackTitle.error": "問題が発生しました", + "alertDialog.actions.confirm": "確認", + "alertDialog.actions.run": "実行", + "alertDialog.actions.ok": "OK", + "alertDialog.actions.cancel": "キャンセル", + "alertDialog.prompt.inputLabel": "入力", + + "backgroundProcessOutputDialog.title": "バックグラウンド出力", + "backgroundProcessOutputDialog.actions.close": "閉じる", + "backgroundProcessOutputDialog.loading": "出力を読み込み中...", + "backgroundProcessOutputDialog.truncatedNotice": "表示のため出力を省略しました。", + "backgroundProcessOutputDialog.loadErrorFallback": "出力の読み込みに失敗しました。", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ja/filesystem.ts b/packages/ui/src/lib/i18n/messages/ja/filesystem.ts new file mode 100644 index 00000000..a17934c2 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ja/filesystem.ts @@ -0,0 +1,43 @@ +export const filesystemMessages = { + "directoryBrowser.defaultDescription": "設定された workspace ルート配下のフォルダを参照します。", + "directoryBrowser.close": "閉じる", + "directoryBrowser.currentFolder": "現在のフォルダ", + "directoryBrowser.selectCurrent": "現在のフォルダを選択", + "directoryBrowser.newFolder": "新しいフォルダ", + "directoryBrowser.creating": "作成中…", + "directoryBrowser.loadingFolders": "フォルダを読み込み中…", + "directoryBrowser.noFolders": "利用可能なフォルダがありません。", + "directoryBrowser.upOneLevel": "1 つ上へ", + "directoryBrowser.select": "選択", + "directoryBrowser.load.errorFallback": "ファイルシステムを読み込めません", + "directoryBrowser.createFolder.promptMessage": "現在のディレクトリに新しいフォルダを作成します。", + "directoryBrowser.createFolder.title": "新しいフォルダ", + "directoryBrowser.createFolder.inputLabel": "フォルダ名", + "directoryBrowser.createFolder.inputPlaceholder": "例: my-new-project", + "directoryBrowser.createFolder.confirmLabel": "作成", + "directoryBrowser.createFolder.cancelLabel": "キャンセル", + "directoryBrowser.createFolder.invalidNameMessage": "フォルダ名を 1 つだけ入力してください。", + "directoryBrowser.createFolder.invalidNameDetail": "フォルダ名にスラッシュ、'..'、'~' を含めることはできません。", + "directoryBrowser.createFolder.errorFallback": "フォルダを作成できません", + + "filesystemBrowser.descriptionFallback": "設定された workspace ルート配下のパスを検索します。", + "filesystemBrowser.rootLabel": "ルート: {root}", + "filesystemBrowser.actions.close": "閉じる", + "filesystemBrowser.actions.retry": "再試行", + "filesystemBrowser.actions.select": "選択", + "filesystemBrowser.filterLabel": "フィルター", + "filesystemBrowser.search.placeholder.directories": "フォルダを検索", + "filesystemBrowser.search.placeholder.files": "ファイルを検索", + "filesystemBrowser.currentFolder.label": "現在のフォルダ", + "filesystemBrowser.currentFolder.selectCurrent": "現在のフォルダを選択", + "filesystemBrowser.loading.filesystem": "ファイルシステム", + "filesystemBrowser.loading.workspaceRoot": "workspace ルート", + "filesystemBrowser.loading.loadingWithPath": "{path} を読み込み中…", + "filesystemBrowser.empty.noEntries": "項目が見つかりません。", + "filesystemBrowser.navigation.upOneLevel": "1 つ上へ", + "filesystemBrowser.hints.navigate": "移動", + "filesystemBrowser.hints.select": "選択", + "filesystemBrowser.hints.close": "閉じる", + "filesystemBrowser.errors.loadFilesystemFallback": "ファイルシステムを読み込めません", + "filesystemBrowser.errors.openDirectoryFallback": "ディレクトリを開けません", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ja/folderSelection.ts b/packages/ui/src/lib/i18n/messages/ja/folderSelection.ts new file mode 100644 index 00000000..78433133 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ja/folderSelection.ts @@ -0,0 +1,34 @@ +export const folderSelectionMessages = { + "folderSelection.logoAlt": "CodeNomad ロゴ", + "folderSelection.tagline": "フォルダを選択して AI でコーディングを開始", + + "folderSelection.links.github": "CodeNomad の GitHub", + "folderSelection.links.githubStars": "CodeNomad の GitHub スター", + "folderSelection.links.discord": "CodeNomad の Discord", + + "folderSelection.empty.title": "最近使ったフォルダはありません", + "folderSelection.empty.description": "フォルダを選択して開始", + + "folderSelection.recent.title": "最近使ったフォルダ", + "folderSelection.recent.subtitle.one": "{count} 件のフォルダ", + "folderSelection.recent.subtitle.other": "{count} 件のフォルダ", + "folderSelection.recent.remove": "履歴から削除", + + "folderSelection.browse.title": "フォルダを参照", + "folderSelection.browse.subtitle": "コンピュータ上の任意のフォルダを選択", + "folderSelection.browse.button": "フォルダを参照", + "folderSelection.browse.buttonOpening": "開いています...", + + "folderSelection.advancedSettings": "詳細設定", + + "folderSelection.hints.navigate": "移動", + "folderSelection.hints.select": "選択", + "folderSelection.hints.remove": "削除", + "folderSelection.hints.browse": "参照", + + "folderSelection.loading.title": "インスタンスを起動中...", + "folderSelection.loading.subtitle": "ワークスペースを準備しています。しばらくお待ちください。", + + "folderSelection.dialog.title": "ワークスペースを選択", + "folderSelection.dialog.description": "コーディングを開始するワークスペースを選択してください。", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ja/index.ts b/packages/ui/src/lib/i18n/messages/ja/index.ts new file mode 100644 index 00000000..407f0697 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ja/index.ts @@ -0,0 +1,36 @@ +import { advancedSettingsMessages } from "./advancedSettings" +import { appMessages } from "./app" +import { commandMessages } from "./commands" +import { dialogMessages } from "./dialogs" +import { filesystemMessages } from "./filesystem" +import { folderSelectionMessages } from "./folderSelection" +import { instanceMessages } from "./instance" +import { loadingScreenMessages } from "./loadingScreen" +import { logMessages } from "./logs" +import { markdownMessages } from "./markdown" +import { messagingMessages } from "./messaging" +import { remoteAccessMessages } from "./remoteAccess" +import { sessionMessages } from "./session" +import { settingsMessages } from "./settings" +import { timeMessages } from "./time" +import { toolCallMessages } from "./toolCall" +import { mergeMessageParts } from "../merge" + +export const jaMessages = mergeMessageParts( + folderSelectionMessages, + advancedSettingsMessages, + loadingScreenMessages, + timeMessages, + appMessages, + dialogMessages, + filesystemMessages, + instanceMessages, + logMessages, + sessionMessages, + messagingMessages, + toolCallMessages, + markdownMessages, + settingsMessages, + remoteAccessMessages, + commandMessages, +) diff --git a/packages/ui/src/lib/i18n/messages/ja/instance.ts b/packages/ui/src/lib/i18n/messages/ja/instance.ts new file mode 100644 index 00000000..aca0ec86 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ja/instance.ts @@ -0,0 +1,125 @@ +export const instanceMessages = { + "instanceTabs.new.title": "新しいインスタンス (Cmd/Ctrl+N)", + "instanceTabs.new.ariaLabel": "新しいインスタンス", + "instanceTabs.remote.title": "リモート接続", + "instanceTabs.remote.ariaLabel": "リモート接続", + + "instanceInfo.title": "インスタンス情報", + "instanceInfo.labels.folder": "フォルダ", + "instanceInfo.labels.project": "プロジェクト", + "instanceInfo.labels.versionControl": "バージョン管理", + "instanceInfo.labels.opencodeVersion": "OpenCode バージョン", + "instanceInfo.labels.binaryPath": "バイナリのパス", + "instanceInfo.labels.environmentVariables": "環境変数 ({count})", + "instanceInfo.loading": "読み込み中...", + "instanceInfo.server.title": "サーバー", + "instanceInfo.server.port": "ポート:", + "instanceInfo.server.pid": "PID:", + "instanceInfo.server.status": "状態:", + + "instanceTab.status.permission": "許可待ち", + "instanceTab.status.compacting": "圧縮中", + "instanceTab.status.working": "作業中", + "instanceTab.status.idle": "待機中", + "instanceTab.status.ariaLabel": "インスタンス状態: {status}", + "instanceTab.actions.close.ariaLabel": "インスタンスを閉じる", + + "instanceShell.leftPanel.sessionsTitle": "セッション", + "instanceShell.leftPanel.instanceInfo": "インスタンス情報", + + "instanceShell.leftDrawer.pin": "左ドロワーを固定", + "instanceShell.leftDrawer.unpin": "左ドロワーの固定を解除", + "instanceShell.leftDrawer.toggle.pinned": "左ドロワーを固定しました", + "instanceShell.leftDrawer.toggle.open": "左ドロワーを開く", + "instanceShell.leftDrawer.toggle.close": "左ドロワーを閉じる", + + "instanceShell.rightDrawer.pin": "右ドロワーを固定", + "instanceShell.rightDrawer.unpin": "右ドロワーの固定を解除", + "instanceShell.rightDrawer.toggle.pinned": "右ドロワーを固定しました", + "instanceShell.rightDrawer.toggle.open": "右ドロワーを開く", + "instanceShell.rightDrawer.toggle.close": "右ドロワーを閉じる", + + "instanceShell.metrics.usedLabel": "使用", + "instanceShell.metrics.availableLabel": "残り", + + "instanceShell.commandPalette.openAriaLabel": "コマンドパレットを開く", + "instanceShell.commandPalette.button": "コマンドパレット", + + "instanceShell.connection.ariaLabel": "接続 {status}", + "instanceShell.connection.connected": "接続済み", + "instanceShell.connection.connecting": "接続中...", + "instanceShell.connection.disconnected": "切断", + "instanceShell.connection.unknown": "不明", + + "instanceWelcome.shortcuts.newSession": "新しいセッション", + "instanceWelcome.empty.title": "以前のセッションはありません", + "instanceWelcome.empty.description": "下で新しいセッションを作成して開始", + "instanceWelcome.loading.title": "セッションを読み込み中", + "instanceWelcome.loading.description": "以前のセッションを取得中...", + "instanceWelcome.resume.title": "セッションを再開", + "instanceWelcome.resume.subtitle.one": "{count} 件のセッション", + "instanceWelcome.resume.subtitle.other": "{count} 件のセッション", + "instanceWelcome.session.untitled": "無題のセッション", + "instanceWelcome.new.title": "新しいセッションを開始", + "instanceWelcome.new.subtitle": "前回のエージェント/モデルを自動で再利用します", + "instanceWelcome.new.createButton": "セッションを作成", + "instanceWelcome.overlay.close": "閉じる", + "instanceWelcome.actions.viewInstanceInfo": "インスタンス情報を表示", + "instanceWelcome.actions.renameTitle": "セッション名を変更", + "instanceWelcome.actions.deleteTitle": "セッションを削除", + "instanceWelcome.hints.navigate": "移動", + "instanceWelcome.hints.jump": "ジャンプ", + "instanceWelcome.hints.firstLast": "先頭/末尾", + "instanceWelcome.hints.resume": "再開", + "instanceWelcome.hints.delete": "削除", + "instanceWelcome.toasts.renameError": "セッション名を変更できません", + + "instanceDisconnected.title": "インスタンスが切断されました", + "instanceDisconnected.folderFallback": "このワークスペース", + "instanceDisconnected.reasonFallback": "サーバーが応答しなくなりました", + "instanceDisconnected.description": "{folder} に接続できません。作業を続けるにはタブを閉じてください。", + "instanceDisconnected.details.title": "詳細", + "instanceDisconnected.details.folderLabel": "フォルダ:", + "instanceDisconnected.actions.closeInstance": "インスタンスを閉じる", + + "instanceShell.empty.title": "セッションが選択されていません", + "instanceShell.empty.description": "メッセージを表示するにはセッションを選択してください", + + "instanceShell.rightPanel.title": "ステータスパネル", + "instanceShell.rightPanel.sections.plan": "計画", + "instanceShell.rightPanel.sections.backgroundProcesses": "バックグラウンドシェル", + "instanceShell.rightPanel.sections.mcp": "MCP サーバー", + "instanceShell.rightPanel.sections.lsp": "LSP サーバー", + "instanceShell.rightPanel.sections.plugins": "プラグイン", + + "instanceShell.plan.noSessionSelected": "計画を表示するにはセッションを選択してください。", + "instanceShell.plan.empty": "まだ計画はありません。", + + "instanceShell.backgroundProcesses.empty": "バックグラウンドプロセスはありません。", + "instanceShell.backgroundProcesses.status": "状態: {status}", + "instanceShell.backgroundProcesses.output": "出力: {sizeKb}KB", + "instanceShell.backgroundProcesses.actions.output": "出力", + "instanceShell.backgroundProcesses.actions.stop": "停止", + "instanceShell.backgroundProcesses.actions.terminate": "終了", + + "versionPill.appWithVersion": "アプリ {version}", + "versionPill.ui": "UI", + "versionPill.uiWithVersion": "UI {version}", + "versionPill.source": " ({source})", + + "opencodeBinarySelector.title": "OpenCode バイナリ", + "opencodeBinarySelector.subtitle": "OpenCode を実行する実行ファイルを選択", + "opencodeBinarySelector.customPath.placeholder": "opencode バイナリのパスを入力…", + "opencodeBinarySelector.actions.add": "追加", + "opencodeBinarySelector.actions.browse": "バイナリを参照…", + "opencodeBinarySelector.actions.removeTitle": "バイナリを削除", + "opencodeBinarySelector.badge.systemPath": "system PATH のバイナリを使用", + "opencodeBinarySelector.status.checkingVersions": "バージョンを確認中…", + "opencodeBinarySelector.status.checking": "確認中…", + "opencodeBinarySelector.dialog.title": "OpenCode バイナリを選択", + "opencodeBinarySelector.dialog.description": "CLI サーバーから公開されているファイルを参照します。", + "opencodeBinarySelector.validation.invalidBinary": "OpenCode バイナリが無効です", + "opencodeBinarySelector.validation.alreadyValidating": "すでに検証中です", + "opencodeBinarySelector.display.systemPath": "{name} (system PATH)", + "opencodeBinarySelector.versionLabel": "v{version}", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ja/loadingScreen.ts b/packages/ui/src/lib/i18n/messages/ja/loadingScreen.ts new file mode 100644 index 00000000..a03058c1 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ja/loadingScreen.ts @@ -0,0 +1,17 @@ +export const loadingScreenMessages = { + "loadingScreen.logoAlt": "CodeNomad ロゴ", + "loadingScreen.status.issue": "問題が発生しました", + "loadingScreen.actions.showAnother": "別のメッセージを表示", + "loadingScreen.errors.missingRoot": "読み込み用のルート要素が見つかりません", + + "loadingScreen.phrases.neurons": "AI のニューロンをウォームアップ中…", + "loadingScreen.phrases.daydreaming": "AI に空想をやめるよう説得中…", + "loadingScreen.phrases.goggles": "AI のコード用ゴーグルを磨き中…", + "loadingScreen.phrases.reorganizingFiles": "AI にファイル整理をやめるようお願い中…", + "loadingScreen.phrases.coffee": "AI に追いコーヒーを投入中…", + "loadingScreen.phrases.nodeModules": "AI に node_modules を(また)消さないよう教え中…", + "loadingScreen.phrases.actNatural": "到着前に自然に振る舞うよう AI に指示中…", + "loadingScreen.phrases.rewritingHistory": "履歴を書き換えないよう AI にお願い中…", + "loadingScreen.phrases.stretch": "コーディングスプリント前に AI をストレッチさせています…", + "loadingScreen.phrases.keyboardControl": "AI にキーボードの主導権を渡すよう説得中…", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ja/logs.ts b/packages/ui/src/lib/i18n/messages/ja/logs.ts new file mode 100644 index 00000000..4498f06f --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ja/logs.ts @@ -0,0 +1,18 @@ +export const logMessages = { + "logsView.title": "サーバーログ", + "logsView.actions.show": "サーバーログを表示", + "logsView.actions.hide": "サーバーログを非表示", + "logsView.envVars.title": "環境変数 ({count})", + "logsView.paused.title": "サーバーログは一時停止中です", + "logsView.paused.description": "ストリーミングを有効にして OpenCode サーバーの動作を監視します。", + "logsView.empty.waiting": "サーバー出力を待機中...", + "logsView.scrollToBottom": "最下部へスクロール", + + "infoView.logs.title": "サーバーログ", + "infoView.logs.actions.show": "サーバーログを表示", + "infoView.logs.actions.hide": "サーバーログを非表示", + "infoView.logs.paused.title": "サーバーログは一時停止中です", + "infoView.logs.paused.description": "ストリーミングを有効にして OpenCode サーバーの動作を監視します。", + "infoView.logs.empty.waiting": "サーバー出力を待機中...", + "infoView.logs.scrollToBottom": "最下部へスクロール", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ja/markdown.ts b/packages/ui/src/lib/i18n/messages/ja/markdown.ts new file mode 100644 index 00000000..786f471c --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ja/markdown.ts @@ -0,0 +1,7 @@ +export const markdownMessages = { + "markdown.codeBlock.copy.label": "コピー", + "markdown.codeBlock.copy.copied": "コピーしました!", + "markdown.codeBlock.copy.failed": "失敗", + + "markdown.copy": "コピー", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ja/messaging.ts b/packages/ui/src/lib/i18n/messages/ja/messaging.ts new file mode 100644 index 00000000..f9aa26ed --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ja/messaging.ts @@ -0,0 +1,109 @@ +export const messagingMessages = { + "messageListHeader.sidebar.openSessionListAriaLabel": "セッション一覧を開く", + "messageListHeader.metrics.usedLabel": "使用", + "messageListHeader.metrics.availableLabel": "残り", + "messageListHeader.commandPalette.ariaLabel": "コマンドパレットを開く", + "messageListHeader.commandPalette.button": "コマンドパレット", + "messageListHeader.connection.connected": "接続済み", + "messageListHeader.connection.connecting": "接続中...", + "messageListHeader.connection.disconnected": "切断", + + "messageSection.empty.logoAlt": "CodeNomad ロゴ", + "messageSection.empty.brandTitle": "CodeNomad", + "messageSection.empty.title": "会話を始める", + "messageSection.empty.description": "下にメッセージを入力するか、コマンドパレットを開いてください:", + "messageSection.empty.tips.commandPalette": "コマンドパレット", + "messageSection.empty.tips.askAboutCodebase": "コードベースについて質問", + "messageSection.empty.tips.attachFilesPrefix": "次でファイルを添付:", + "messageSection.loading.messages": "メッセージを読み込み中...", + "messageSection.scroll.toFirstAriaLabel": "最初のメッセージへスクロール", + "messageSection.scroll.toLatestAriaLabel": "最新のメッセージへスクロール", + "messageSection.quote.addAsQuote": "引用として追加", + "messageSection.quote.addAsCode": "コードとして追加", + + "messageTimeline.ariaLabel": "メッセージタイムライン", + "messageTimeline.segment.user.label": "あなた", + "messageTimeline.segment.assistant.label": "AI", + "messageTimeline.segment.compaction.label": "圧縮", + "messageTimeline.tool.fallbackLabel": "ツールコール", + "messageTimeline.tooltip.userFallback": "ユーザーのメッセージ", + "messageTimeline.tooltip.assistantFallback": "アシスタントの応答", + "messageTimeline.tooltip.compaction.auto": "自動コンパクト化", + "messageTimeline.tooltip.compaction.manual": "手動コンパクト化", + "messageTimeline.text.filePrefix": "[ファイル] {filename}", + "messageTimeline.text.attachment": "添付", + + "messageBlock.tool.header": "ツールコール", + "messageBlock.tool.unknown": "不明", + "messageBlock.tool.goToSession.label": "セッションへ移動", + "messageBlock.tool.goToSession.title": "セッションへ移動", + "messageBlock.tool.goToSession.unavailableTitle": "セッションはまだ利用できません", + + "messageBlock.compaction.ariaLabel": "セッションのコンパクト化", + "messageBlock.compaction.autoLabel": "セッションを自動でコンパクト化しました", + "messageBlock.compaction.manualLabel": "セッションをあなたがコンパクト化しました", + "messageBlock.usage.input": "入力", + "messageBlock.usage.output": "出力", + "messageBlock.usage.reasoning": "推論", + "messageBlock.usage.cacheRead": "キャッシュ読み込み", + "messageBlock.usage.cacheWrite": "キャッシュ書き込み", + "messageBlock.usage.cost": "コスト", + "messageBlock.step.agentLabel": "エージェント: {agent}", + "messageBlock.step.modelLabel": "モデル: {model}", + "messageBlock.reasoning.thinkingLabel": "思考", + "messageBlock.reasoning.expandAriaLabel": "思考を展開", + "messageBlock.reasoning.collapseAriaLabel": "思考を折りたたむ", + "messageBlock.reasoning.indicator.hide": "非表示", + "messageBlock.reasoning.indicator.view": "表示", + "messageBlock.reasoning.detailsAriaLabel": "推論の詳細", + + "codeBlockInline.actions.copy": "コピー", + "codeBlockInline.actions.copied": "コピーしました!", + + "messageItem.speaker.you": "あなた", + "messageItem.speaker.assistant": "アシスタント", + "messageItem.actions.revert": "戻す", + "messageItem.actions.revertTitle": "このメッセージまで戻す", + "messageItem.actions.fork": "フォーク", + "messageItem.actions.forkTitle": "このメッセージからフォーク", + "messageItem.actions.copy": "コピー", + "messageItem.actions.copyTitle": "メッセージをコピー", + "messageItem.actions.copied": "コピーしました!", + "messageItem.status.queued": "待機中", + "messageItem.status.generating": "生成中...", + "messageItem.status.sending": "送信中...", + "messageItem.status.failedToSend": "メッセージの送信に失敗しました", + "messageItem.attachment.defaultName": "添付ファイル", + "messageItem.attachment.downloadAriaLabel": "{name} をダウンロード", + "messageItem.agentMeta.agentLabel": "エージェント: {agent}", + "messageItem.agentMeta.modelLabel": "モデル: {model}", + "messageItem.errors.authenticationFallback": "認証エラー", + "messageItem.errors.outputLengthExceeded": "メッセージ出力が長すぎます", + "messageItem.errors.requestAborted": "リクエストが中断されました", + "messageItem.errors.unknownFallback": "不明なエラーが発生しました", + + "attachmentChip.removeAriaLabel": "添付を削除", + + "expandButton.toggleAriaLabel": "チャット入力欄の高さを切り替え", + + "promptInput.placeholder.shell": "シェルコマンドを実行 (Esc で終了)...", + "promptInput.placeholder.default": "メッセージ、@file、@agent を入力、または画像/テキストを貼り付け...", + "promptInput.hints.shell.exit": "でシェルモードを終了", + "promptInput.hints.shell.enable": "シェルモード", + "promptInput.hints.commands": "コマンド", + "promptInput.history.previousAriaLabel": "前のプロンプト", + "promptInput.history.nextAriaLabel": "次のプロンプト", + "promptInput.overlay.newLine": "改行", + "promptInput.overlay.send": "送信", + "promptInput.overlay.filesAgents": "ファイル/エージェント", + "promptInput.overlay.history": "履歴", + "promptInput.overlay.attachments": "• {count} 件のファイルを添付", + "promptInput.overlay.shellModeActive": "シェルモードが有効", + "promptInput.overlay.press": "押す", + "promptInput.overlay.againToAbort": "もう一度押すとセッションを中断", + "promptInput.stopSession.ariaLabel": "セッションを停止", + "promptInput.stopSession.title": "セッションを停止", + "promptInput.send.ariaLabel": "メッセージを送信", + "promptInput.send.errorFallback": "メッセージの送信に失敗しました", + "promptInput.send.errorTitle": "送信に失敗", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ja/remoteAccess.ts b/packages/ui/src/lib/i18n/messages/ja/remoteAccess.ts new file mode 100644 index 00000000..dbc9e221 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ja/remoteAccess.ts @@ -0,0 +1,51 @@ +export const remoteAccessMessages = { + "remoteAccess.eyebrow": "リモート引き継ぎ", + "remoteAccess.title": "CodeNomad にリモート接続", + "remoteAccess.subtitle": "別のデバイスから CodeNomad を開くには、以下のアドレスを使用してください。", + "remoteAccess.close": "リモートアクセスを閉じる", + "remoteAccess.refresh": "更新", + + "remoteAccess.sections.listeningMode.label": "リッスンモード", + "remoteAccess.sections.listeningMode.help": "全インターフェースにバインドするか localhost のみにするかで、リモート引き継ぎを許可/制限します。", + "remoteAccess.toggle.on": "オン", + "remoteAccess.toggle.off": "オフ", + "remoteAccess.toggle.title": "他の IP からの接続を許可", + "remoteAccess.toggle.caption.all": "0.0.0.0 にバインド", + "remoteAccess.toggle.caption.local": "127.0.0.1 にバインド", + "remoteAccess.toggle.note": "変更には再起動が必要で、すべての稼働中インスタンスが一時的に停止します。サーバー再起動後に以下のアドレスを共有してください。", + "remoteAccess.listeningMode.restartConfirm.message": "リッスンモードを適用するため再起動しますか?実行中のインスタンスはすべて停止します。", + "remoteAccess.listeningMode.restartConfirm.title.all": "他のデバイスに公開", + "remoteAccess.listeningMode.restartConfirm.title.local": "このデバイスに限定", + "remoteAccess.listeningMode.restartConfirm.confirmLabel": "今すぐ再起動", + "remoteAccess.listeningMode.restartConfirm.cancelLabel": "キャンセル", + "remoteAccess.restart.errorManual": "自動で再起動できませんでした。変更を適用するにはアプリを再起動してください。", + + "remoteAccess.sections.serverPassword.label": "サーバーパスワード", + "remoteAccess.sections.serverPassword.help": "リモート引き継ぎにはパスワードが必要です。覚えやすいものを設定して他のデバイスからのログインを有効にします。", + "remoteAccess.authStatus.unavailable": "認証状態を取得できません。", + "remoteAccess.username": "ユーザー名: {username}", + "remoteAccess.password.status.set": "リモートアクセス用のパスワードが設定されています。", + "remoteAccess.password.status.unset": "まだ覚えやすいパスワードが設定されていません。設定してリモート引き継ぎログインを有効にしてください。", + "remoteAccess.password.actions.cancel": "キャンセル", + "remoteAccess.password.actions.change": "パスワードを変更", + "remoteAccess.password.actions.set": "パスワードを設定", + "remoteAccess.password.form.newPassword": "新しいパスワード", + "remoteAccess.password.form.confirmPassword": "パスワードの確認", + "remoteAccess.password.form.placeholder": "8 文字以上", + "remoteAccess.password.error.tooShort": "パスワードは 8 文字以上である必要があります。", + "remoteAccess.password.error.mismatch": "パスワードが一致しません。", + "remoteAccess.password.save.saving": "保存中…", + "remoteAccess.password.save.label": "パスワードを保存", + + "remoteAccess.sections.addresses.label": "到達可能なアドレス", + "remoteAccess.sections.addresses.help": "別の端末から起動またはスキャンして操作を引き継ぎます。", + "remoteAccess.addresses.loading": "アドレスを読み込み中…", + "remoteAccess.addresses.none": "まだ利用可能なアドレスがありません。", + "remoteAccess.address.scope.network": "ネットワーク", + "remoteAccess.address.scope.loopback": "ループバック", + "remoteAccess.address.scope.internal": "内部", + "remoteAccess.address.open": "開く", + "remoteAccess.address.showQr": "QR を表示", + "remoteAccess.address.hideQr": "QR を非表示", + "remoteAccess.address.qrAlt": "{url} の QR", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ja/session.ts b/packages/ui/src/lib/i18n/messages/ja/session.ts new file mode 100644 index 00000000..20342942 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ja/session.ts @@ -0,0 +1,67 @@ +export const sessionMessages = { + "sessionPicker.title": "OpenCode • {folder}", + "sessionPicker.empty.noPrevious": "以前のセッションはありません", + "sessionPicker.resume.title": "セッションを再開 ({count}):", + "sessionPicker.session.untitled": "無題", + "sessionPicker.divider.or": "または", + "sessionPicker.new.title": "新しいセッションを開始:", + "sessionPicker.agents.loading": "エージェントを読み込み中...", + "sessionPicker.actions.creating": "作成中...", + "sessionPicker.actions.createSession": "セッションを作成", + "sessionPicker.actions.cancel": "キャンセル", + + "sessionList.header.title": "セッション", + "sessionList.session.untitled": "無題", + "sessionList.status.working": "作業中", + "sessionList.status.compacting": "圧縮中", + "sessionList.status.idle": "待機中", + "sessionList.status.needsPermission": "許可待ち", + "sessionList.status.needsInput": "入力待ち", + "sessionList.expand.collapseAriaLabel": "セッションを折りたたむ", + "sessionList.expand.expandAriaLabel": "セッションを展開", + "sessionList.expand.collapseTitle": "折りたたむ", + "sessionList.expand.expandTitle": "展開", + "sessionList.actions.copyId.ariaLabel": "セッション ID をコピー", + "sessionList.actions.copyId.title": "セッション ID をコピー", + "sessionList.actions.rename.ariaLabel": "セッション名を変更", + "sessionList.actions.rename.title": "セッション名を変更", + "sessionList.actions.delete.ariaLabel": "セッションを削除", + "sessionList.actions.delete.title": "セッションを削除", + "sessionList.copyId.success": "セッション ID をコピーしました", + "sessionList.copyId.error": "セッション ID をコピーできません", + "sessionList.delete.error": "セッションを削除できません", + "sessionList.rename.error": "セッション名を変更できません", + + "sessionRenameDialog.title": "セッション名を変更", + "sessionRenameDialog.description.withLabel": "\"{label}\" のタイトルを更新します。", + "sessionRenameDialog.description.default": "このセッションの新しいタイトルを設定します。", + "sessionRenameDialog.input.label": "セッション名", + "sessionRenameDialog.input.placeholder": "セッション名を入力", + "sessionRenameDialog.actions.cancel": "キャンセル", + "sessionRenameDialog.actions.rename": "変更", + "sessionRenameDialog.actions.renaming": "変更中…", + + "sessionView.fallback.sessionNotFound": "セッションが見つかりません", + "sessionView.alerts.abortFailed.message": "セッションを停止できませんでした", + "sessionView.alerts.abortFailed.title": "停止に失敗", + "sessionView.alerts.revertFailed.message": "メッセージへ戻せませんでした", + "sessionView.alerts.revertFailed.title": "復元に失敗", + "sessionView.alerts.forkFailed.message": "セッションのフォークに失敗しました", + "sessionView.alerts.forkFailed.title": "フォークに失敗", + "sessionView.attachments.expandPastedTextAriaLabel": "貼り付けたテキストを展開", + "sessionView.attachments.insertPastedTextTitle": "貼り付けたテキストを挿入", + "sessionView.attachments.removeAriaLabel": "添付を削除", + + "sessionEvents.sessionCompactedToast": "セッション {label} をコンパクト化しました", + "sessionEvents.sessionError.unknown": "不明なエラー", + "sessionEvents.sessionError.title": "セッションエラー", + "sessionEvents.sessionError.message": "エラー: {message}", + + "sessionState.cleanup.deepConfirm.message": "このクリーンアップは時間がかかる場合があり、意図しないセッションを削除する可能性があります。続行しますか?", + "sessionState.cleanup.deepConfirm.title": "セッションを徹底クリーン", + "sessionState.cleanup.deepConfirm.detail": "徹底クリーンは、メッセージがないセッションをすべて削除し、完了したサブエージェントのセッションを取り除き、未使用のセッションフォークを整理します。", + "sessionState.cleanup.deepConfirm.confirmLabel": "続行", + "sessionState.cleanup.deepConfirm.cancelLabel": "キャンセル", + "sessionState.cleanup.toast.one": "{count} 件の空セッションを整理しました", + "sessionState.cleanup.toast.other": "{count} 件の空セッションを整理しました", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ja/settings.ts b/packages/ui/src/lib/i18n/messages/ja/settings.ts new file mode 100644 index 00000000..7f649992 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ja/settings.ts @@ -0,0 +1,54 @@ +export const settingsMessages = { + "instanceServiceStatus.sections.lsp": "LSP サーバー", + "instanceServiceStatus.sections.mcp": "MCP サーバー", + "instanceServiceStatus.sections.plugins": "プラグイン", + "instanceServiceStatus.lsp.loading": "LSP サーバーを読み込み中...", + "instanceServiceStatus.lsp.empty": "LSP サーバーが検出されませんでした。", + "instanceServiceStatus.lsp.status.connected": "接続済み", + "instanceServiceStatus.lsp.status.error": "エラー", + "instanceServiceStatus.mcp.loading": "MCP サーバーを読み込み中...", + "instanceServiceStatus.mcp.empty": "MCP サーバーが検出されませんでした。", + "instanceServiceStatus.mcp.toggleAriaLabel": "{name} MCP サーバーを切り替え", + "instanceServiceStatus.plugins.loading": "プラグインを読み込み中...", + "instanceServiceStatus.plugins.empty": "プラグインが設定されていません。", + + "permissionBanner.pendingRequests.one": "{count} 件の保留中リクエスト", + "permissionBanner.pendingRequests.other": "{count} 件の保留中リクエスト", + "permissionBanner.detail.permission.one": "{count} 件の許可", + "permissionBanner.detail.permission.other": "{count} 件の許可", + "permissionBanner.detail.question.one": "{count} 件の質問", + "permissionBanner.detail.question.other": "{count} 件の質問", + "permissionBanner.detail.wrapper": " ({detail})", + + "agentSelector.placeholder": "エージェントを選択...", + "agentSelector.badge.subagent": "サブエージェント", + "agentSelector.none": "なし", + "agentSelector.trigger.primary": "エージェント: {agent}", + + "modelSelector.placeholder.search": "モデルを検索...", + "modelSelector.none": "なし", + "modelSelector.trigger.primary": "モデル: {model}", + + "thinkingSelector.variant.default": "デフォルト", + "thinkingSelector.label": "思考: {variant}", + + "envEditor.title": "環境変数", + "envEditor.count.one": "({count} 個)", + "envEditor.count.other": "({count} 個)", + "envEditor.fields.name.placeholder": "変数名", + "envEditor.fields.name.readOnlyTitle": "変数名 (読み取り専用)", + "envEditor.fields.value.placeholder": "変数値", + "envEditor.actions.remove.title": "変数を削除", + "envEditor.actions.add.title": "変数を追加", + "envEditor.empty": "環境変数が設定されていません。上で変数を追加して OpenCode 環境をカスタマイズしてください。", + "envEditor.help": "これらの変数はインスタンス起動時に OpenCode 環境で利用できます。", + + "contextUsagePanel.headings.tokens": "トークン", + "contextUsagePanel.headings.context": "コンテキスト", + "contextUsagePanel.labels.input": "入力", + "contextUsagePanel.labels.output": "出力", + "contextUsagePanel.labels.cost": "コスト", + "contextUsagePanel.labels.used": "使用", + "contextUsagePanel.labels.available": "残り", + "contextUsagePanel.unavailable": "--", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ja/time.ts b/packages/ui/src/lib/i18n/messages/ja/time.ts new file mode 100644 index 00000000..d7948e54 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ja/time.ts @@ -0,0 +1,6 @@ +export const timeMessages = { + "time.relative.justNow": "たった今", + "time.relative.daysAgoShort": "{count} 日前", + "time.relative.hoursAgoShort": "{count} 時間前", + "time.relative.minutesAgoShort": "{count} 分前", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ja/toolCall.ts b/packages/ui/src/lib/i18n/messages/ja/toolCall.ts new file mode 100644 index 00000000..68c1b71f --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ja/toolCall.ts @@ -0,0 +1,121 @@ +export const toolCallMessages = { + "toolCall.pending.waitingToRun": "実行待ち...", + "toolCall.error.label": "エラー:", + + "toolCall.diff.label": "Diff", + "toolCall.diff.label.withPath": "Diff · {path}", + "toolCall.diff.viewMode.ariaLabel": "diff 表示モード", + "toolCall.diff.viewMode.split": "分割", + "toolCall.diff.viewMode.unified": "ユニファイド", + + "toolCall.diagnostics.title": "診断", + "toolCall.diagnostics.ariaLabel": "診断", + "toolCall.diagnostics.ariaLabel.withLabel": "診断 {label}", + "toolCall.diagnostics.severity.error.short": "エラー", + "toolCall.diagnostics.severity.warning.short": "警告", + "toolCall.diagnostics.severity.info.short": "情報", + + "toolCall.renderer.toolName.shell": "シェル", + "toolCall.renderer.toolName.fetch": "フェッチ", + "toolCall.renderer.toolName.invalid": "無効", + "toolCall.renderer.toolName.plan": "計画", + "toolCall.renderer.toolName.applyPatch": "パッチを適用", + + "toolCall.renderer.action.working": "処理中...", + "toolCall.renderer.action.writingCommand": "コマンド作成中...", + "toolCall.renderer.action.preparingEdit": "編集を準備中...", + "toolCall.renderer.action.readingFile": "ファイルを読み込み中...", + "toolCall.renderer.action.preparingWrite": "書き込みを準備中...", + "toolCall.renderer.action.preparingPatch": "パッチを準備中...", + "toolCall.renderer.action.planning": "計画中...", + "toolCall.renderer.action.fetchingFromWeb": "Web から取得中...", + "toolCall.renderer.action.findingFiles": "ファイルを検索中...", + "toolCall.renderer.action.searchingContent": "内容を検索中...", + "toolCall.renderer.action.listingDirectory": "ディレクトリ一覧を取得中...", + + "toolCall.renderer.bash.title.timeout": "タイムアウト: {timeout}", + "toolCall.renderer.read.detail.offset": "オフセット: {offset}", + "toolCall.renderer.read.detail.limit": "上限: {limit}", + + "toolCall.renderer.todo.empty": "まだ項目がありません。", + "toolCall.renderer.todo.status.pending": "保留", + "toolCall.renderer.todo.status.inProgress": "進行中", + "toolCall.renderer.todo.status.completed": "完了", + "toolCall.renderer.todo.status.cancelled": "キャンセル", + "toolCall.renderer.todo.title.plan": "計画", + "toolCall.renderer.todo.title.creating": "計画を作成中", + "toolCall.renderer.todo.title.completing": "計画を完了中", + "toolCall.renderer.todo.title.updating": "計画を更新中", + + "toolCall.permission.status.required": "許可が必要です", + "toolCall.permission.status.queued": "許可待ち", + "toolCall.permission.requestedDiff.label": "要求された diff", + "toolCall.permission.requestedDiff.withPath": "要求された diff · {path}", + "toolCall.permission.queuedText": "先行する許可への回答を待機中です。", + "toolCall.permission.actions.allowOnce": "一度だけ許可", + "toolCall.permission.actions.alwaysAllow": "常に許可", + "toolCall.permission.actions.deny": "拒否", + "toolCall.permission.shortcuts.allowOnce": "一度だけ許可", + "toolCall.permission.shortcuts.alwaysAllow": "常に許可", + "toolCall.permission.shortcuts.deny": "拒否", + "toolCall.permission.errors.unableToUpdate": "許可を更新できません", + + "permissionApproval.title": "リクエスト", + "permissionApproval.empty": "保留中のリクエストはありません。", + "permissionApproval.kind.permission": "許可", + "permissionApproval.kind.question": "質問", + "permissionApproval.questionCount.one": "{count} 件の質問", + "permissionApproval.questionCount.other": "{count} 件の質問", + "permissionApproval.status.active": "有効", + "permissionApproval.actions.closeAriaLabel": "閉じる", + "permissionApproval.actions.goToSession": "セッションへ移動", + "permissionApproval.actions.loadingSession": "読み込み中…", + "permissionApproval.actions.loadSession": "セッションを読み込む", + "permissionApproval.actions.allowOnce": "一度だけ許可", + "permissionApproval.actions.alwaysAllow": "常に許可", + "permissionApproval.actions.deny": "拒否", + "permissionApproval.fallbackHint": "詳しい情報を見るにはセッションを読み込んでください。", + "permissionApproval.errors.unableToUpdatePermission": "許可を更新できません", + + "toolCall.question.status.required": "質問が必要です", + "toolCall.question.status.queued": "質問待ち", + "toolCall.question.status.questions": "質問", + "toolCall.question.action.awaitingAnswers": "回答待ち...", + "toolCall.question.title.questions": "質問", + "toolCall.question.title.askingQuestions": "質問中", + "toolCall.question.type.one": "質問", + "toolCall.question.type.other": "質問", + "toolCall.question.number": "Q{number}:", + "toolCall.question.multiple": "複数", + "toolCall.question.custom.title": "カスタム回答を入力", + "toolCall.question.custom.label": "カスタム回答", + "toolCall.question.custom.placeholder": "回答を入力", + "toolCall.question.actions.submit": "送信", + "toolCall.question.actions.dismiss": "閉じる", + "toolCall.question.shortcuts.submit": "送信", + "toolCall.question.shortcuts.dismiss": "閉じる", + "toolCall.question.queuedText": "先行する回答を待機中です。", + "toolCall.question.validation.answerAll": "送信する前にすべての質問に回答してください。", + "toolCall.question.errors.unableToReply": "回答できません", + "toolCall.question.errors.unableToDismiss": "閉じられません", + + "toolCall.task.action.delegating": "委任中...", + "toolCall.task.sections.prompt": "プロンプト", + "toolCall.task.sections.steps": "手順", + "toolCall.task.sections.output": "出力", + "toolCall.task.steps.count": "{count} 手順", + "toolCall.task.meta.agentModel": "エージェント: {agent} • モデル: {model}", + "toolCall.task.meta.agent": "エージェント: {agent}", + "toolCall.task.meta.model": "モデル: {model}", + + "toolCall.status.pending": "保留", + "toolCall.status.running": "実行中", + "toolCall.status.completed": "完了", + "toolCall.status.error": "エラー", + "toolCall.status.unknown": "不明", + + "toolCall.applyPatch.action.preparing": "apply_patch を準備中...", + "toolCall.applyPatch.title.withFileCount.one": "{tool} ({count} 件のファイル)", + "toolCall.applyPatch.title.withFileCount.other": "{tool} ({count} 件のファイル)", + "toolCall.applyPatch.fileFallback": "ファイル {number}", +} as const diff --git a/packages/ui/src/lib/i18n/messages/merge.ts b/packages/ui/src/lib/i18n/messages/merge.ts new file mode 100644 index 00000000..4350210b --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/merge.ts @@ -0,0 +1,14 @@ +export function mergeMessageParts(...parts: Array>) { + const result: Record = {} + + for (const part of parts) { + for (const [key, value] of Object.entries(part)) { + if (key in result) { + throw new Error(`Duplicate i18n message key: ${key}`) + } + result[key] = value + } + } + + return result +} diff --git a/packages/ui/src/lib/i18n/messages/ru/advancedSettings.ts b/packages/ui/src/lib/i18n/messages/ru/advancedSettings.ts new file mode 100644 index 00000000..fbaab1a7 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ru/advancedSettings.ts @@ -0,0 +1,6 @@ +export const advancedSettingsMessages = { + "advancedSettings.title": "Расширенные настройки", + "advancedSettings.environmentVariables.title": "Переменные окружения", + "advancedSettings.environmentVariables.subtitle": "Применяются при запуске нового экземпляра OpenCode", + "advancedSettings.actions.close": "Закрыть", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ru/app.ts b/packages/ui/src/lib/i18n/messages/ru/app.ts new file mode 100644 index 00000000..410318bd --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ru/app.ts @@ -0,0 +1,29 @@ +export const appMessages = { + "app.launchError.title": "Не удалось запустить OpenCode", + "app.launchError.description": "Не удалось запустить выбранный бинарник OpenCode. Просмотрите вывод ошибки ниже или выберите другой бинарник в расширенных настройках.", + "app.launchError.binaryPathLabel": "Путь к бинарнику", + "app.launchError.errorOutputLabel": "Вывод ошибки", + "app.launchError.openAdvancedSettings": "Открыть расширенные настройки", + "app.launchError.close": "Закрыть", + "app.launchError.closeTitle": "Закрыть (Esc)", + "app.launchError.fallbackMessage": "Не удалось запустить рабочее пространство", + + "app.stopInstance.confirmMessage": "Остановить экземпляр OpenCode? Это остановит сервер.", + "app.stopInstance.title": "Остановить экземпляр", + "app.stopInstance.confirmLabel": "Остановить", + "app.stopInstance.cancelLabel": "Оставить запущенным", + + "emptyState.logoAlt": "Логотип CodeNomad", + "emptyState.brandTitle": "CodeNomad", + "emptyState.tagline": "Выберите папку, чтобы начать писать код с AI", + "emptyState.actions.selectFolder": "Выбрать папку", + "emptyState.actions.selecting": "Выбор…", + "emptyState.keyboardShortcut": "Горячая клавиша: {shortcut}", + "emptyState.examples": "Примеры: {example}", + "emptyState.multipleInstances": "Можно иметь несколько экземпляров одной и той же папки", + + "releases.upgradeRequired.title": "Требуется обновление", + "releases.upgradeRequired.message.withVersion": "Обновите CodeNomad до версии {version}, чтобы использовать последний UI.", + "releases.upgradeRequired.message.noVersion": "Обновите CodeNomad, чтобы использовать последний UI.", + "releases.upgradeRequired.action.getUpdate": "Получить обновление", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ru/commands.ts b/packages/ui/src/lib/i18n/messages/ru/commands.ts new file mode 100644 index 00000000..ded3ac35 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ru/commands.ts @@ -0,0 +1,160 @@ +export const commandMessages = { + "commandPalette.title": "Палитра команд", + "commandPalette.description": "Поиск и запуск команд", + "commandPalette.searchPlaceholder": "Введите команду или начните поиск…", + "commandPalette.empty": "Команды по запросу \"{query}\" не найдены", + "commandPalette.category.customCommands": "Пользовательские команды", + "commandPalette.category.instance": "Экземпляр", + "commandPalette.category.session": "Сессия", + "commandPalette.category.agentModel": "Агент и модель", + "commandPalette.category.inputFocus": "Ввод и фокус", + "commandPalette.category.system": "Система", + "commandPalette.category.other": "Другое", + + "commands.newInstance.label": "Новый экземпляр", + "commands.newInstance.description": "Открыть выбор папки для создания нового экземпляра", + "commands.newInstance.keywords": "папка, проект, рабочее пространство", + + "commands.closeInstance.label": "Закрыть экземпляр", + "commands.closeInstance.description": "Остановить сервер текущего экземпляра", + "commands.closeInstance.keywords": "остановить, выйти, закрыть", + + "commands.nextInstance.label": "Следующий экземпляр", + "commands.nextInstance.description": "Переключиться на следующую вкладку экземпляра", + "commands.nextInstance.keywords": "переключить, навигация", + + "commands.previousInstance.label": "Предыдущий экземпляр", + "commands.previousInstance.description": "Переключиться на предыдущую вкладку экземпляра", + "commands.previousInstance.keywords": "переключить, навигация", + + "commands.newSession.label": "Новая сессия", + "commands.newSession.description": "Создать новую родительскую сессию", + "commands.newSession.keywords": "создать, начать", + + "commands.closeSession.label": "Закрыть сессию", + "commands.closeSession.description": "Закрыть текущую родительскую сессию", + "commands.closeSession.keywords": "закрыть, остановить", + + "commands.scrubSessions.label": "Очистить сессии", + "commands.scrubSessions.description": "Удалить пустые сессии, завершенные сессии субагентов и лишние форкнутые сессии.", + "commands.scrubSessions.keywords": "очистка, пустые, сессии, удалить, убрать", + + "commands.instanceInfo.label": "Информация об экземпляре", + "commands.instanceInfo.description": "Открыть обзор экземпляра с логами и статусом", + "commands.instanceInfo.keywords": "информация, логи, консоль, вывод", + + "commands.nextSession.label": "Следующая сессия", + "commands.nextSession.description": "Переключиться на следующую вкладку сессии", + "commands.nextSession.keywords": "переключить, навигация", + + "commands.previousSession.label": "Предыдущая сессия", + "commands.previousSession.description": "Переключиться на предыдущую вкладку сессии", + "commands.previousSession.keywords": "переключить, навигация", + + "commands.compactSession.label": "Компактировать сессию", + "commands.compactSession.description": "Суммировать и компактировать текущую сессию", + "commands.compactSession.keywords": "суммировать, сжать", + "commands.compactSession.errorFallback": "Не удалось компактировать сессию", + "commands.compactSession.alert.title": "Компактация не удалась", + "commands.compactSession.alert.message": "Компактация не удалась: {message}", + + "commands.undoLastMessage.label": "Отменить последнее сообщение", + "commands.undoLastMessage.description": "Откатить последнее сообщение", + "commands.undoLastMessage.keywords": "откат, отмена", + "commands.undoLastMessage.none.title": "Нечего отменять", + "commands.undoLastMessage.none.message": "Нечего отменять", + "commands.undoLastMessage.failed.title": "Не удалось отменить", + "commands.undoLastMessage.failed.message": "Не удалось откатить сообщение", + + "commands.openModelSelector.label": "Открыть выбор модели", + "commands.openModelSelector.description": "Выбрать другую модель", + "commands.openModelSelector.keywords": "модель, llm, ai", + + "commands.selectModelVariant.label": "Выбрать вариант модели", + "commands.selectModelVariant.description": "Выбрать интенсивность размышлений для текущей модели", + "commands.selectModelVariant.keywords": "вариант, thinking, reasoning, интенсивность", + + "commands.openAgentSelector.label": "Открыть выбор агента", + "commands.openAgentSelector.description": "Выбрать другого агента", + "commands.openAgentSelector.keywords": "агент, режим", + + "commands.clearInput.label": "Очистить ввод", + "commands.clearInput.description": "Очистить поле prompt", + "commands.clearInput.keywords": "очистить, сброс", + + "commands.thinkingBlocks.label.show": "Показать блоки размышлений", + "commands.thinkingBlocks.label.hide": "Скрыть блоки размышлений", + "commands.thinkingBlocks.description": "Показать/скрыть процесс рассуждений AI", + "commands.thinkingBlocks.keywords": "thinking, reasoning, переключить, показать, скрыть", + + "commands.timelineToolCalls.label.show": "Показать Tool Calls в таймлайне", + "commands.timelineToolCalls.label.hide": "Скрыть Tool Calls в таймлайне", + "commands.timelineToolCalls.description": "Переключить отображение вызовов инструментов в таймлайне сообщений", + "commands.timelineToolCalls.keywords": "таймлайн, tool, переключить", + + "commands.common.expanded": "Развернуто", + "commands.common.collapsed": "Свернуто", + "commands.common.visible": "Видимо", + "commands.common.hidden": "Скрыто", + "commands.common.enabled": "Включено", + "commands.common.disabled": "Выключено", + + "commands.thinkingBlocksDefault.label": "Блоки размышлений по умолчанию · {state}", + "commands.thinkingBlocksDefault.description": "Переключить, разворачивать ли блоки размышлений по умолчанию", + "commands.thinkingBlocksDefault.keywords": "thinking, reasoning, развернуть, свернуть, по умолчанию", + + "commands.diffViewSplit.label": "Раздельный просмотр diff", + "commands.diffViewSplit.description": "Показывать diff вызовов инструментов рядом", + "commands.diffViewSplit.keywords": "diff, split, просмотр", + + "commands.diffViewUnified.label": "Единый просмотр diff", + "commands.diffViewUnified.description": "Показывать diff вызовов инструментов в одну колонку", + "commands.diffViewUnified.keywords": "diff, unified, просмотр", + + "commands.toolOutputsDefault.label": "Выводы инструментов по умолчанию · {state}", + "commands.toolOutputsDefault.description": "Переключить, разворачивать ли выводы инструментов по умолчанию", + "commands.toolOutputsDefault.keywords": "tool, output, развернуть, свернуть", + + "commands.diagnosticsDefault.label": "Диагностика по умолчанию · {state}", + "commands.diagnosticsDefault.description": "Переключить, разворачивать ли вывод диагностики по умолчанию", + "commands.diagnosticsDefault.keywords": "diagnostics, развернуть, свернуть", + + "commands.tokenUsageDisplay.label": "Отображение token-статистики · {state}", + "commands.tokenUsageDisplay.description": "Показать или скрыть статистику token и стоимости для сообщений ассистента", + "commands.tokenUsageDisplay.keywords": "token, usage, cost, статистика", + + "commands.autoCleanupBlankSessions.label": "Авто-очистка пустых сессий · {state}", + "commands.autoCleanupBlankSessions.description": "Автоматически очищать пустые сессии при создании новых", + "commands.autoCleanupBlankSessions.keywords": "auto, cleanup, пустые, сессии, переключить", + + "commands.showHelp.label": "Показать справку", + "commands.showHelp.description": "Показать горячие клавиши и справку", + "commands.showHelp.keywords": "горячие клавиши, справка", + + "commands.custom.argumentsPrompt.message": "Аргументы для /{name}", + "commands.custom.argumentsPrompt.title": "Пользовательская команда", + "commands.custom.argumentsPrompt.inputLabel": "Аргументы", + "commands.custom.argumentsPrompt.inputPlaceholder": "например: foo bar", + "commands.custom.argumentsPrompt.confirmLabel": "Запустить", + "commands.custom.argumentsPrompt.cancelLabel": "Отмена", + "commands.custom.argumentsPrompt.openFailed.message": "Не удалось открыть prompt аргументов.", + "commands.custom.argumentsPrompt.openFailed.title": "Аргументы команды", + "commands.custom.entries.descriptionFallback": "Пользовательская команда", + "commands.custom.sessionRequired.message": "Выберите сессию перед запуском пользовательской команды.", + "commands.custom.sessionRequired.title": "Требуется сессия", + "commands.custom.runFailed.message": "Не удалось запустить пользовательскую команду. Проверьте консоль для подробностей.", + "commands.custom.runFailed.title": "Команда не выполнена", + + "unifiedPicker.loading.searching": "Поиск…", + "unifiedPicker.loading.loadingWorkspace": "Загрузка рабочего пространства…", + "unifiedPicker.title.command": "Выберите команду", + "unifiedPicker.title.mention": "Выберите агента или файл", + "unifiedPicker.empty": "Ничего не найдено", + "unifiedPicker.sections.commands": "КОМАНДЫ", + "unifiedPicker.sections.agents": "АГЕНТЫ", + "unifiedPicker.sections.files": "ФАЙЛЫ", + "unifiedPicker.badge.subagent": "субагент", + "unifiedPicker.footer.navigate": "навигация", + "unifiedPicker.footer.select": "выбрать", + "unifiedPicker.footer.close": "закрыть", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ru/dialogs.ts b/packages/ui/src/lib/i18n/messages/ru/dialogs.ts new file mode 100644 index 00000000..017d6b59 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ru/dialogs.ts @@ -0,0 +1,16 @@ +export const dialogMessages = { + "alertDialog.fallbackTitle.info": "Внимание", + "alertDialog.fallbackTitle.warning": "Пожалуйста, проверьте", + "alertDialog.fallbackTitle.error": "Что-то пошло не так", + "alertDialog.actions.confirm": "Подтвердить", + "alertDialog.actions.run": "Запустить", + "alertDialog.actions.ok": "ОК", + "alertDialog.actions.cancel": "Отмена", + "alertDialog.prompt.inputLabel": "Ввод", + + "backgroundProcessOutputDialog.title": "Фоновый вывод", + "backgroundProcessOutputDialog.actions.close": "Закрыть", + "backgroundProcessOutputDialog.loading": "Загрузка вывода…", + "backgroundProcessOutputDialog.truncatedNotice": "Вывод обрезан для отображения.", + "backgroundProcessOutputDialog.loadErrorFallback": "Не удалось загрузить вывод.", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ru/filesystem.ts b/packages/ui/src/lib/i18n/messages/ru/filesystem.ts new file mode 100644 index 00000000..d81816c3 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ru/filesystem.ts @@ -0,0 +1,43 @@ +export const filesystemMessages = { + "directoryBrowser.defaultDescription": "Просматривайте папки в пределах настроенного корня рабочего пространства.", + "directoryBrowser.close": "Закрыть", + "directoryBrowser.currentFolder": "Текущая папка", + "directoryBrowser.selectCurrent": "Выбрать текущую", + "directoryBrowser.newFolder": "Новая папка", + "directoryBrowser.creating": "Создание…", + "directoryBrowser.loadingFolders": "Загрузка папок…", + "directoryBrowser.noFolders": "Папки недоступны.", + "directoryBrowser.upOneLevel": "На уровень выше", + "directoryBrowser.select": "Выбрать", + "directoryBrowser.load.errorFallback": "Не удалось загрузить файловую систему", + "directoryBrowser.createFolder.promptMessage": "Создайте новую папку в текущем каталоге.", + "directoryBrowser.createFolder.title": "Новая папка", + "directoryBrowser.createFolder.inputLabel": "Имя папки", + "directoryBrowser.createFolder.inputPlaceholder": "например my-new-project", + "directoryBrowser.createFolder.confirmLabel": "Создать", + "directoryBrowser.createFolder.cancelLabel": "Отмена", + "directoryBrowser.createFolder.invalidNameMessage": "Введите одно имя папки.", + "directoryBrowser.createFolder.invalidNameDetail": "Имя папки не может содержать слэши, '..' или '~'.", + "directoryBrowser.createFolder.errorFallback": "Не удалось создать папку", + + "filesystemBrowser.descriptionFallback": "Найдите путь в пределах настроенного корня рабочего пространства.", + "filesystemBrowser.rootLabel": "Корень: {root}", + "filesystemBrowser.actions.close": "Закрыть", + "filesystemBrowser.actions.retry": "Повторить", + "filesystemBrowser.actions.select": "Выбрать", + "filesystemBrowser.filterLabel": "Фильтр", + "filesystemBrowser.search.placeholder.directories": "Поиск папок", + "filesystemBrowser.search.placeholder.files": "Поиск файлов", + "filesystemBrowser.currentFolder.label": "Текущая папка", + "filesystemBrowser.currentFolder.selectCurrent": "Выбрать текущую", + "filesystemBrowser.loading.filesystem": "файловую систему", + "filesystemBrowser.loading.workspaceRoot": "корень рабочего пространства", + "filesystemBrowser.loading.loadingWithPath": "Загрузка {path}…", + "filesystemBrowser.empty.noEntries": "Ничего не найдено.", + "filesystemBrowser.navigation.upOneLevel": "На уровень выше", + "filesystemBrowser.hints.navigate": "Навигация", + "filesystemBrowser.hints.select": "Выбрать", + "filesystemBrowser.hints.close": "Закрыть", + "filesystemBrowser.errors.loadFilesystemFallback": "Не удалось загрузить файловую систему", + "filesystemBrowser.errors.openDirectoryFallback": "Не удалось открыть каталог", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ru/folderSelection.ts b/packages/ui/src/lib/i18n/messages/ru/folderSelection.ts new file mode 100644 index 00000000..daeea3f2 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ru/folderSelection.ts @@ -0,0 +1,34 @@ +export const folderSelectionMessages = { + "folderSelection.logoAlt": "Логотип CodeNomad", + "folderSelection.tagline": "Выберите папку, чтобы начать писать код с AI", + + "folderSelection.links.github": "GitHub CodeNomad", + "folderSelection.links.githubStars": "Звезды GitHub CodeNomad", + "folderSelection.links.discord": "Discord CodeNomad", + + "folderSelection.empty.title": "Нет недавних папок", + "folderSelection.empty.description": "Выберите папку, чтобы начать", + + "folderSelection.recent.title": "Недавние папки", + "folderSelection.recent.subtitle.one": "Доступна {count} папка", + "folderSelection.recent.subtitle.other": "Доступно {count} папок", + "folderSelection.recent.remove": "Убрать из недавних", + + "folderSelection.browse.title": "Выбрать папку", + "folderSelection.browse.subtitle": "Выберите любую папку на компьютере", + "folderSelection.browse.button": "Обзор папок", + "folderSelection.browse.buttonOpening": "Открытие…", + + "folderSelection.advancedSettings": "Расширенные настройки", + + "folderSelection.hints.navigate": "Навигация", + "folderSelection.hints.select": "Выбрать", + "folderSelection.hints.remove": "Убрать", + "folderSelection.hints.browse": "Обзор", + + "folderSelection.loading.title": "Запуск экземпляра…", + "folderSelection.loading.subtitle": "Подождите, пока мы подготовим рабочее пространство.", + + "folderSelection.dialog.title": "Выберите рабочее пространство", + "folderSelection.dialog.description": "Выберите рабочее пространство, чтобы начать писать код.", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ru/index.ts b/packages/ui/src/lib/i18n/messages/ru/index.ts new file mode 100644 index 00000000..4188ca55 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ru/index.ts @@ -0,0 +1,36 @@ +import { advancedSettingsMessages } from "./advancedSettings" +import { appMessages } from "./app" +import { commandMessages } from "./commands" +import { dialogMessages } from "./dialogs" +import { filesystemMessages } from "./filesystem" +import { folderSelectionMessages } from "./folderSelection" +import { instanceMessages } from "./instance" +import { loadingScreenMessages } from "./loadingScreen" +import { logMessages } from "./logs" +import { markdownMessages } from "./markdown" +import { messagingMessages } from "./messaging" +import { remoteAccessMessages } from "./remoteAccess" +import { sessionMessages } from "./session" +import { settingsMessages } from "./settings" +import { timeMessages } from "./time" +import { toolCallMessages } from "./toolCall" +import { mergeMessageParts } from "../merge" + +export const ruMessages = mergeMessageParts( + folderSelectionMessages, + advancedSettingsMessages, + loadingScreenMessages, + timeMessages, + appMessages, + dialogMessages, + filesystemMessages, + instanceMessages, + logMessages, + sessionMessages, + messagingMessages, + toolCallMessages, + markdownMessages, + settingsMessages, + remoteAccessMessages, + commandMessages, +) diff --git a/packages/ui/src/lib/i18n/messages/ru/instance.ts b/packages/ui/src/lib/i18n/messages/ru/instance.ts new file mode 100644 index 00000000..b6d536b0 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ru/instance.ts @@ -0,0 +1,125 @@ +export const instanceMessages = { + "instanceTabs.new.title": "Новый экземпляр (Cmd/Ctrl+N)", + "instanceTabs.new.ariaLabel": "Новый экземпляр", + "instanceTabs.remote.title": "Удаленное подключение", + "instanceTabs.remote.ariaLabel": "Удаленное подключение", + + "instanceInfo.title": "Информация об экземпляре", + "instanceInfo.labels.folder": "Папка", + "instanceInfo.labels.project": "Проект", + "instanceInfo.labels.versionControl": "Система контроля версий", + "instanceInfo.labels.opencodeVersion": "Версия OpenCode", + "instanceInfo.labels.binaryPath": "Путь к бинарнику", + "instanceInfo.labels.environmentVariables": "Переменные окружения ({count})", + "instanceInfo.loading": "Загрузка…", + "instanceInfo.server.title": "Сервер", + "instanceInfo.server.port": "Порт:", + "instanceInfo.server.pid": "PID:", + "instanceInfo.server.status": "Статус:", + + "instanceTab.status.permission": "Ожидание разрешения", + "instanceTab.status.compacting": "Компактация", + "instanceTab.status.working": "Работает", + "instanceTab.status.idle": "Простой", + "instanceTab.status.ariaLabel": "Статус экземпляра: {status}", + "instanceTab.actions.close.ariaLabel": "Закрыть экземпляр", + + "instanceShell.leftPanel.sessionsTitle": "Сессии", + "instanceShell.leftPanel.instanceInfo": "Информация об экземпляре", + + "instanceShell.leftDrawer.pin": "Закрепить левую панель", + "instanceShell.leftDrawer.unpin": "Открепить левую панель", + "instanceShell.leftDrawer.toggle.pinned": "Левая панель закреплена", + "instanceShell.leftDrawer.toggle.open": "Открыть левую панель", + "instanceShell.leftDrawer.toggle.close": "Закрыть левую панель", + + "instanceShell.rightDrawer.pin": "Закрепить правую панель", + "instanceShell.rightDrawer.unpin": "Открепить правую панель", + "instanceShell.rightDrawer.toggle.pinned": "Правая панель закреплена", + "instanceShell.rightDrawer.toggle.open": "Открыть правую панель", + "instanceShell.rightDrawer.toggle.close": "Закрыть правую панель", + + "instanceShell.metrics.usedLabel": "Использовано", + "instanceShell.metrics.availableLabel": "Доступно", + + "instanceShell.commandPalette.openAriaLabel": "Открыть палитру команд", + "instanceShell.commandPalette.button": "Палитра команд", + + "instanceShell.connection.ariaLabel": "Соединение {status}", + "instanceShell.connection.connected": "Подключено", + "instanceShell.connection.connecting": "Подключение…", + "instanceShell.connection.disconnected": "Отключено", + "instanceShell.connection.unknown": "Неизвестно", + + "instanceWelcome.shortcuts.newSession": "Новая сессия", + "instanceWelcome.empty.title": "Нет предыдущих сессий", + "instanceWelcome.empty.description": "Создайте новую сессию ниже, чтобы начать", + "instanceWelcome.loading.title": "Загрузка сессий", + "instanceWelcome.loading.description": "Получаем ваши предыдущие сессии…", + "instanceWelcome.resume.title": "Продолжить сессию", + "instanceWelcome.resume.subtitle.one": "{count} сессия доступна", + "instanceWelcome.resume.subtitle.other": "{count} сессий доступно", + "instanceWelcome.session.untitled": "Сессия без названия", + "instanceWelcome.new.title": "Начать новую сессию", + "instanceWelcome.new.subtitle": "Мы автоматически используем последнего агента/модель", + "instanceWelcome.new.createButton": "Создать сессию", + "instanceWelcome.overlay.close": "Закрыть", + "instanceWelcome.actions.viewInstanceInfo": "Показать информацию об экземпляре", + "instanceWelcome.actions.renameTitle": "Переименовать сессию", + "instanceWelcome.actions.deleteTitle": "Удалить сессию", + "instanceWelcome.hints.navigate": "Навигация", + "instanceWelcome.hints.jump": "Перейти", + "instanceWelcome.hints.firstLast": "Первый/последний", + "instanceWelcome.hints.resume": "Продолжить", + "instanceWelcome.hints.delete": "Удалить", + "instanceWelcome.toasts.renameError": "Не удалось переименовать сессию", + + "instanceDisconnected.title": "Экземпляр отключен", + "instanceDisconnected.folderFallback": "это рабочее пространство", + "instanceDisconnected.reasonFallback": "Сервер перестал отвечать", + "instanceDisconnected.description": "{folder} больше недоступно. Закройте вкладку, чтобы продолжить работу.", + "instanceDisconnected.details.title": "Подробности", + "instanceDisconnected.details.folderLabel": "Папка:", + "instanceDisconnected.actions.closeInstance": "Закрыть экземпляр", + + "instanceShell.empty.title": "Сессия не выбрана", + "instanceShell.empty.description": "Выберите сессию, чтобы просмотреть сообщения", + + "instanceShell.rightPanel.title": "Панель состояния", + "instanceShell.rightPanel.sections.plan": "План", + "instanceShell.rightPanel.sections.backgroundProcesses": "Фоновые Shell", + "instanceShell.rightPanel.sections.mcp": "MCP-серверы", + "instanceShell.rightPanel.sections.lsp": "LSP-серверы", + "instanceShell.rightPanel.sections.plugins": "Плагины", + + "instanceShell.plan.noSessionSelected": "Выберите сессию, чтобы просмотреть план.", + "instanceShell.plan.empty": "Пока ничего не запланировано.", + + "instanceShell.backgroundProcesses.empty": "Нет фоновых процессов.", + "instanceShell.backgroundProcesses.status": "Статус: {status}", + "instanceShell.backgroundProcesses.output": "Вывод: {sizeKb}KB", + "instanceShell.backgroundProcesses.actions.output": "Вывод", + "instanceShell.backgroundProcesses.actions.stop": "Остановить", + "instanceShell.backgroundProcesses.actions.terminate": "Завершить", + + "versionPill.appWithVersion": "Приложение {version}", + "versionPill.ui": "UI", + "versionPill.uiWithVersion": "UI {version}", + "versionPill.source": " ({source})", + + "opencodeBinarySelector.title": "OpenCode Binary", + "opencodeBinarySelector.subtitle": "Выберите, какой исполняемый файл OpenCode запускать", + "opencodeBinarySelector.customPath.placeholder": "Введите путь к бинарнику opencode…", + "opencodeBinarySelector.actions.add": "Добавить", + "opencodeBinarySelector.actions.browse": "Выбрать бинарник…", + "opencodeBinarySelector.actions.removeTitle": "Удалить бинарник", + "opencodeBinarySelector.badge.systemPath": "Использовать бинарник из системного PATH", + "opencodeBinarySelector.status.checkingVersions": "Проверка версий…", + "opencodeBinarySelector.status.checking": "Проверка…", + "opencodeBinarySelector.dialog.title": "Выберите бинарник OpenCode", + "opencodeBinarySelector.dialog.description": "Просматривайте файлы, доступные через CLI-сервер.", + "opencodeBinarySelector.validation.invalidBinary": "Неверный бинарник OpenCode", + "opencodeBinarySelector.validation.alreadyValidating": "Проверка уже выполняется", + "opencodeBinarySelector.display.systemPath": "{name} (system PATH)", + "opencodeBinarySelector.versionLabel": "v{version}", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ru/loadingScreen.ts b/packages/ui/src/lib/i18n/messages/ru/loadingScreen.ts new file mode 100644 index 00000000..780906bd --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ru/loadingScreen.ts @@ -0,0 +1,17 @@ +export const loadingScreenMessages = { + "loadingScreen.logoAlt": "Логотип CodeNomad", + "loadingScreen.status.issue": "Возникла проблема", + "loadingScreen.actions.showAnother": "Показать другое", + "loadingScreen.errors.missingRoot": "Корневой элемент загрузки не найден", + + "loadingScreen.phrases.neurons": "Разогреваем нейроны AI…", + "loadingScreen.phrases.daydreaming": "Убеждаем AI перестать мечтать…", + "loadingScreen.phrases.goggles": "Полируем кодовые очки AI…", + "loadingScreen.phrases.reorganizingFiles": "Просим AI перестать реорганизовывать ваши файлы…", + "loadingScreen.phrases.coffee": "Подкармливаем AI дополнительным кофе…", + "loadingScreen.phrases.nodeModules": "Учимся не удалять node_modules (снова)…", + "loadingScreen.phrases.actNatural": "Просим AI вести себя естественно до вашего прихода…", + "loadingScreen.phrases.rewritingHistory": "Просим AI перестать переписывать историю…", + "loadingScreen.phrases.stretch": "Даем AI размяться перед кодинг-спринтом…", + "loadingScreen.phrases.keyboardControl": "Убеждаем AI вернуть вам управление клавиатурой…", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ru/logs.ts b/packages/ui/src/lib/i18n/messages/ru/logs.ts new file mode 100644 index 00000000..e9a364b8 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ru/logs.ts @@ -0,0 +1,18 @@ +export const logMessages = { + "logsView.title": "Логи сервера", + "logsView.actions.show": "Показать логи сервера", + "logsView.actions.hide": "Скрыть логи сервера", + "logsView.envVars.title": "Переменные окружения ({count})", + "logsView.paused.title": "Логи сервера приостановлены", + "logsView.paused.description": "Включите стриминг, чтобы наблюдать за активностью сервера OpenCode.", + "logsView.empty.waiting": "Ожидание вывода сервера…", + "logsView.scrollToBottom": "Прокрутить вниз", + + "infoView.logs.title": "Логи сервера", + "infoView.logs.actions.show": "Показать логи сервера", + "infoView.logs.actions.hide": "Скрыть логи сервера", + "infoView.logs.paused.title": "Логи сервера приостановлены", + "infoView.logs.paused.description": "Включите стриминг, чтобы наблюдать за активностью сервера OpenCode.", + "infoView.logs.empty.waiting": "Ожидание вывода сервера…", + "infoView.logs.scrollToBottom": "Прокрутить вниз", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ru/markdown.ts b/packages/ui/src/lib/i18n/messages/ru/markdown.ts new file mode 100644 index 00000000..1c405038 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ru/markdown.ts @@ -0,0 +1,7 @@ +export const markdownMessages = { + "markdown.codeBlock.copy.label": "Копировать", + "markdown.codeBlock.copy.copied": "Скопировано!", + "markdown.codeBlock.copy.failed": "Не удалось", + + "markdown.copy": "Копировать", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ru/messaging.ts b/packages/ui/src/lib/i18n/messages/ru/messaging.ts new file mode 100644 index 00000000..eeabe2f9 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ru/messaging.ts @@ -0,0 +1,109 @@ +export const messagingMessages = { + "messageListHeader.sidebar.openSessionListAriaLabel": "Открыть список сессий", + "messageListHeader.metrics.usedLabel": "Использовано", + "messageListHeader.metrics.availableLabel": "Доступно", + "messageListHeader.commandPalette.ariaLabel": "Открыть палитру команд", + "messageListHeader.commandPalette.button": "Палитра команд", + "messageListHeader.connection.connected": "Подключено", + "messageListHeader.connection.connecting": "Подключение…", + "messageListHeader.connection.disconnected": "Отключено", + + "messageSection.empty.logoAlt": "Логотип CodeNomad", + "messageSection.empty.brandTitle": "CodeNomad", + "messageSection.empty.title": "Начните разговор", + "messageSection.empty.description": "Введите сообщение ниже или откройте палитру команд:", + "messageSection.empty.tips.commandPalette": "Палитра команд", + "messageSection.empty.tips.askAboutCodebase": "Спросите о своей кодовой базе", + "messageSection.empty.tips.attachFilesPrefix": "Прикрепляйте файлы через", + "messageSection.loading.messages": "Загрузка сообщений…", + "messageSection.scroll.toFirstAriaLabel": "Прокрутить к первому сообщению", + "messageSection.scroll.toLatestAriaLabel": "Прокрутить к последнему сообщению", + "messageSection.quote.addAsQuote": "Добавить как цитату", + "messageSection.quote.addAsCode": "Добавить как код", + + "messageTimeline.ariaLabel": "Таймлайн сообщений", + "messageTimeline.segment.user.label": "Вы", + "messageTimeline.segment.assistant.label": "Асс.", + "messageTimeline.segment.compaction.label": "Компактация", + "messageTimeline.tool.fallbackLabel": "Вызов инструмента", + "messageTimeline.tooltip.userFallback": "Сообщение пользователя", + "messageTimeline.tooltip.assistantFallback": "Ответ ассистента", + "messageTimeline.tooltip.compaction.auto": "Автокомпактация", + "messageTimeline.tooltip.compaction.manual": "Компактация пользователем", + "messageTimeline.text.filePrefix": "[Файл] {filename}", + "messageTimeline.text.attachment": "Вложение", + + "messageBlock.tool.header": "Вызов инструмента", + "messageBlock.tool.unknown": "неизвестно", + "messageBlock.tool.goToSession.label": "Перейти к сессии", + "messageBlock.tool.goToSession.title": "Перейти к сессии", + "messageBlock.tool.goToSession.unavailableTitle": "Сессия пока недоступна", + + "messageBlock.compaction.ariaLabel": "Компактация сессии", + "messageBlock.compaction.autoLabel": "Сессия автоматически компактирована", + "messageBlock.compaction.manualLabel": "Сессия компактирована вами", + "messageBlock.usage.input": "Ввод", + "messageBlock.usage.output": "Вывод", + "messageBlock.usage.reasoning": "Рассуждения", + "messageBlock.usage.cacheRead": "Чтение кэша", + "messageBlock.usage.cacheWrite": "Запись кэша", + "messageBlock.usage.cost": "Стоимость", + "messageBlock.step.agentLabel": "Агент: {agent}", + "messageBlock.step.modelLabel": "Модель: {model}", + "messageBlock.reasoning.thinkingLabel": "Размышления", + "messageBlock.reasoning.expandAriaLabel": "Развернуть размышления", + "messageBlock.reasoning.collapseAriaLabel": "Свернуть размышления", + "messageBlock.reasoning.indicator.hide": "Скрыть", + "messageBlock.reasoning.indicator.view": "Показать", + "messageBlock.reasoning.detailsAriaLabel": "Детали рассуждений", + + "codeBlockInline.actions.copy": "Копировать", + "codeBlockInline.actions.copied": "Скопировано!", + + "messageItem.speaker.you": "Вы", + "messageItem.speaker.assistant": "Ассистент", + "messageItem.actions.revert": "Откатить", + "messageItem.actions.revertTitle": "Откатиться к этому сообщению", + "messageItem.actions.fork": "Форк", + "messageItem.actions.forkTitle": "Форкнуть от этого сообщения", + "messageItem.actions.copy": "Копировать", + "messageItem.actions.copyTitle": "Копировать сообщение", + "messageItem.actions.copied": "Скопировано!", + "messageItem.status.queued": "В ОЧЕРЕДИ", + "messageItem.status.generating": "Генерация…", + "messageItem.status.sending": "Отправка…", + "messageItem.status.failedToSend": "Не удалось отправить сообщение", + "messageItem.attachment.defaultName": "вложение", + "messageItem.attachment.downloadAriaLabel": "Скачать {name}", + "messageItem.agentMeta.agentLabel": "Агент: {agent}", + "messageItem.agentMeta.modelLabel": "Модель: {model}", + "messageItem.errors.authenticationFallback": "Ошибка аутентификации", + "messageItem.errors.outputLengthExceeded": "Превышена длина вывода сообщения", + "messageItem.errors.requestAborted": "Запрос был прерван", + "messageItem.errors.unknownFallback": "Произошла неизвестная ошибка", + + "attachmentChip.removeAriaLabel": "Удалить вложение", + + "expandButton.toggleAriaLabel": "Переключить высоту поля ввода", + + "promptInput.placeholder.shell": "Выполнить команду shell (Esc для выхода)…", + "promptInput.placeholder.default": "Введите сообщение, @file, @agent или вставьте изображения и текст…", + "promptInput.hints.shell.exit": "чтобы выйти из режима shell", + "promptInput.hints.shell.enable": "Режим shell", + "promptInput.hints.commands": "Команды", + "promptInput.history.previousAriaLabel": "Предыдущий prompt", + "promptInput.history.nextAriaLabel": "Следующий prompt", + "promptInput.overlay.newLine": "Новая строка", + "promptInput.overlay.send": "Отправить", + "promptInput.overlay.filesAgents": "Файлы/агенты", + "promptInput.overlay.history": "История", + "promptInput.overlay.attachments": "• прикреплено файлов: {count}", + "promptInput.overlay.shellModeActive": "Режим shell активен", + "promptInput.overlay.press": "Нажмите", + "promptInput.overlay.againToAbort": "еще раз, чтобы прервать сессию", + "promptInput.stopSession.ariaLabel": "Остановить сессию", + "promptInput.stopSession.title": "Остановить сессию", + "promptInput.send.ariaLabel": "Отправить сообщение", + "promptInput.send.errorFallback": "Не удалось отправить сообщение", + "promptInput.send.errorTitle": "Не удалось отправить", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ru/remoteAccess.ts b/packages/ui/src/lib/i18n/messages/ru/remoteAccess.ts new file mode 100644 index 00000000..df90ce3d --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ru/remoteAccess.ts @@ -0,0 +1,51 @@ +export const remoteAccessMessages = { + "remoteAccess.eyebrow": "Удаленная передача управления", + "remoteAccess.title": "Подключитесь к CodeNomad удаленно", + "remoteAccess.subtitle": "Используйте адреса ниже, чтобы открыть CodeNomad с другого устройства.", + "remoteAccess.close": "Закрыть удаленный доступ", + "remoteAccess.refresh": "Обновить", + + "remoteAccess.sections.listeningMode.label": "Режим прослушивания", + "remoteAccess.sections.listeningMode.help": "Разрешайте или ограничивайте удаленную передачу управления, привязываясь ко всем интерфейсам или только к localhost.", + "remoteAccess.toggle.on": "Вкл", + "remoteAccess.toggle.off": "Выкл", + "remoteAccess.toggle.title": "Разрешить подключения с других IP", + "remoteAccess.toggle.caption.all": "Привязка к 0.0.0.0", + "remoteAccess.toggle.caption.local": "Привязка к 127.0.0.1", + "remoteAccess.toggle.note": "Изменение требует перезапуска и временно остановит все активные экземпляры. Поделитесь адресами ниже после перезапуска сервера.", + "remoteAccess.listeningMode.restartConfirm.message": "Перезапустить, чтобы применить режим прослушивания? Это остановит все запущенные экземпляры.", + "remoteAccess.listeningMode.restartConfirm.title.all": "Открыть для других устройств", + "remoteAccess.listeningMode.restartConfirm.title.local": "Ограничить этим устройством", + "remoteAccess.listeningMode.restartConfirm.confirmLabel": "Перезапустить сейчас", + "remoteAccess.listeningMode.restartConfirm.cancelLabel": "Отмена", + "remoteAccess.restart.errorManual": "Не удалось перезапустить автоматически. Перезапустите приложение, чтобы применить изменение.", + + "remoteAccess.sections.serverPassword.label": "Пароль сервера", + "remoteAccess.sections.serverPassword.help": "Для удаленной передачи управления требуется пароль. Установите запоминающийся пароль, чтобы разрешить вход с других устройств.", + "remoteAccess.authStatus.unavailable": "Статус аутентификации недоступен.", + "remoteAccess.username": "Имя пользователя: {username}", + "remoteAccess.password.status.set": "Для удаленного доступа установлен пароль.", + "remoteAccess.password.status.unset": "Пока не установлен запоминающийся пароль. Установите его, чтобы разрешить вход при удаленной передаче управления.", + "remoteAccess.password.actions.cancel": "Отмена", + "remoteAccess.password.actions.change": "Изменить пароль", + "remoteAccess.password.actions.set": "Установить пароль", + "remoteAccess.password.form.newPassword": "Новый пароль", + "remoteAccess.password.form.confirmPassword": "Подтвердите пароль", + "remoteAccess.password.form.placeholder": "Не менее 8 символов", + "remoteAccess.password.error.tooShort": "Пароль должен быть не короче 8 символов.", + "remoteAccess.password.error.mismatch": "Пароли не совпадают.", + "remoteAccess.password.save.saving": "Сохранение…", + "remoteAccess.password.save.label": "Сохранить пароль", + + "remoteAccess.sections.addresses.label": "Доступные адреса", + "remoteAccess.sections.addresses.help": "Откройте или отсканируйте с другой машины, чтобы передать управление.", + "remoteAccess.addresses.loading": "Загрузка адресов…", + "remoteAccess.addresses.none": "Пока нет доступных адресов.", + "remoteAccess.address.scope.network": "Сеть", + "remoteAccess.address.scope.loopback": "Loopback", + "remoteAccess.address.scope.internal": "Внутренний", + "remoteAccess.address.open": "Открыть", + "remoteAccess.address.showQr": "Показать QR", + "remoteAccess.address.hideQr": "Скрыть QR", + "remoteAccess.address.qrAlt": "QR для {url}", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ru/session.ts b/packages/ui/src/lib/i18n/messages/ru/session.ts new file mode 100644 index 00000000..eddb136c --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ru/session.ts @@ -0,0 +1,67 @@ +export const sessionMessages = { + "sessionPicker.title": "OpenCode • {folder}", + "sessionPicker.empty.noPrevious": "Нет предыдущих сессий", + "sessionPicker.resume.title": "Продолжить сессию ({count}):", + "sessionPicker.session.untitled": "Без названия", + "sessionPicker.divider.or": "или", + "sessionPicker.new.title": "Начать новую сессию:", + "sessionPicker.agents.loading": "Загрузка агентов…", + "sessionPicker.actions.creating": "Создание…", + "sessionPicker.actions.createSession": "Создать сессию", + "sessionPicker.actions.cancel": "Отмена", + + "sessionList.header.title": "Сессии", + "sessionList.session.untitled": "Без названия", + "sessionList.status.working": "Работает", + "sessionList.status.compacting": "Компактация", + "sessionList.status.idle": "Простой", + "sessionList.status.needsPermission": "Требуется разрешение", + "sessionList.status.needsInput": "Требуется ввод", + "sessionList.expand.collapseAriaLabel": "Свернуть сессию", + "sessionList.expand.expandAriaLabel": "Развернуть сессию", + "sessionList.expand.collapseTitle": "Свернуть", + "sessionList.expand.expandTitle": "Развернуть", + "sessionList.actions.copyId.ariaLabel": "Скопировать ID сессии", + "sessionList.actions.copyId.title": "Скопировать ID сессии", + "sessionList.actions.rename.ariaLabel": "Переименовать сессию", + "sessionList.actions.rename.title": "Переименовать сессию", + "sessionList.actions.delete.ariaLabel": "Удалить сессию", + "sessionList.actions.delete.title": "Удалить сессию", + "sessionList.copyId.success": "ID сессии скопирован", + "sessionList.copyId.error": "Не удалось скопировать ID сессии", + "sessionList.delete.error": "Не удалось удалить сессию", + "sessionList.rename.error": "Не удалось переименовать сессию", + + "sessionRenameDialog.title": "Переименовать сессию", + "sessionRenameDialog.description.withLabel": "Обновите название для \"{label}\".", + "sessionRenameDialog.description.default": "Установите новое название для этой сессии.", + "sessionRenameDialog.input.label": "Название сессии", + "sessionRenameDialog.input.placeholder": "Введите название сессии", + "sessionRenameDialog.actions.cancel": "Отмена", + "sessionRenameDialog.actions.rename": "Переименовать", + "sessionRenameDialog.actions.renaming": "Переименование…", + + "sessionView.fallback.sessionNotFound": "Сессия не найдена", + "sessionView.alerts.abortFailed.message": "Не удалось остановить сессию", + "sessionView.alerts.abortFailed.title": "Не удалось остановить", + "sessionView.alerts.revertFailed.message": "Не удалось откатиться к сообщению", + "sessionView.alerts.revertFailed.title": "Не удалось откатиться", + "sessionView.alerts.forkFailed.message": "Не удалось форкнуть сессию", + "sessionView.alerts.forkFailed.title": "Не удалось форкнуть", + "sessionView.attachments.expandPastedTextAriaLabel": "Развернуть вставленный текст", + "sessionView.attachments.insertPastedTextTitle": "Вставить вставленный текст", + "sessionView.attachments.removeAriaLabel": "Удалить вложение", + + "sessionEvents.sessionCompactedToast": "Сессия {label} была компактирована", + "sessionEvents.sessionError.unknown": "Неизвестная ошибка", + "sessionEvents.sessionError.title": "Ошибка сессии", + "sessionEvents.sessionError.message": "Ошибка: {message}", + + "sessionState.cleanup.deepConfirm.message": "Эта очистка может быть медленной и может удалить сессии, которые вы не хотели удалять. Вы уверены?", + "sessionState.cleanup.deepConfirm.title": "Глубокая очистка сессий", + "sessionState.cleanup.deepConfirm.detail": "Глубокая очистка сессий удалит все сессии без сообщений, уберет завершенные сессии субагентов и очистит неиспользуемые форки сессий.", + "sessionState.cleanup.deepConfirm.confirmLabel": "Продолжить", + "sessionState.cleanup.deepConfirm.cancelLabel": "Отмена", + "sessionState.cleanup.toast.one": "Удалена {count} пустая сессия", + "sessionState.cleanup.toast.other": "Удалено {count} пустых сессий", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ru/settings.ts b/packages/ui/src/lib/i18n/messages/ru/settings.ts new file mode 100644 index 00000000..6f9c88a8 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ru/settings.ts @@ -0,0 +1,54 @@ +export const settingsMessages = { + "instanceServiceStatus.sections.lsp": "LSP-серверы", + "instanceServiceStatus.sections.mcp": "MCP-серверы", + "instanceServiceStatus.sections.plugins": "Плагины", + "instanceServiceStatus.lsp.loading": "Загрузка LSP-серверов…", + "instanceServiceStatus.lsp.empty": "LSP-серверы не обнаружены.", + "instanceServiceStatus.lsp.status.connected": "Подключено", + "instanceServiceStatus.lsp.status.error": "Ошибка", + "instanceServiceStatus.mcp.loading": "Загрузка MCP-серверов…", + "instanceServiceStatus.mcp.empty": "MCP-серверы не обнаружены.", + "instanceServiceStatus.mcp.toggleAriaLabel": "Переключить MCP-сервер {name}", + "instanceServiceStatus.plugins.loading": "Загрузка плагинов…", + "instanceServiceStatus.plugins.empty": "Плагины не настроены.", + + "permissionBanner.pendingRequests.one": "{count} ожидающий запрос", + "permissionBanner.pendingRequests.other": "{count} ожидающих запросов", + "permissionBanner.detail.permission.one": "{count} разрешение", + "permissionBanner.detail.permission.other": "{count} разрешений", + "permissionBanner.detail.question.one": "{count} вопрос", + "permissionBanner.detail.question.other": "{count} вопросов", + "permissionBanner.detail.wrapper": " ({detail})", + + "agentSelector.placeholder": "Выберите агента…", + "agentSelector.badge.subagent": "субагент", + "agentSelector.none": "Нет", + "agentSelector.trigger.primary": "Агент: {agent}", + + "modelSelector.placeholder.search": "Поиск моделей…", + "modelSelector.none": "Нет", + "modelSelector.trigger.primary": "Модель: {model}", + + "thinkingSelector.variant.default": "По умолчанию", + "thinkingSelector.label": "Размышления: {variant}", + + "envEditor.title": "Переменные окружения", + "envEditor.count.one": "({count} переменная)", + "envEditor.count.other": "({count} переменных)", + "envEditor.fields.name.placeholder": "Имя переменной", + "envEditor.fields.name.readOnlyTitle": "Имя переменной (только чтение)", + "envEditor.fields.value.placeholder": "Значение переменной", + "envEditor.actions.remove.title": "Удалить переменную", + "envEditor.actions.add.title": "Добавить переменную", + "envEditor.empty": "Переменные окружения не настроены. Добавьте переменные выше, чтобы настроить окружение OpenCode.", + "envEditor.help": "Эти переменные будут доступны в окружении OpenCode при запуске экземпляров.", + + "contextUsagePanel.headings.tokens": "Tokens", + "contextUsagePanel.headings.context": "Контекст", + "contextUsagePanel.labels.input": "Ввод", + "contextUsagePanel.labels.output": "Вывод", + "contextUsagePanel.labels.cost": "Стоимость", + "contextUsagePanel.labels.used": "Использовано", + "contextUsagePanel.labels.available": "Доступно", + "contextUsagePanel.unavailable": "--", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ru/time.ts b/packages/ui/src/lib/i18n/messages/ru/time.ts new file mode 100644 index 00000000..a5574a7c --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ru/time.ts @@ -0,0 +1,6 @@ +export const timeMessages = { + "time.relative.justNow": "только что", + "time.relative.daysAgoShort": "{count}д назад", + "time.relative.hoursAgoShort": "{count}ч назад", + "time.relative.minutesAgoShort": "{count}м назад", +} as const diff --git a/packages/ui/src/lib/i18n/messages/ru/toolCall.ts b/packages/ui/src/lib/i18n/messages/ru/toolCall.ts new file mode 100644 index 00000000..daa2ae82 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/ru/toolCall.ts @@ -0,0 +1,121 @@ +export const toolCallMessages = { + "toolCall.pending.waitingToRun": "Ожидание запуска…", + "toolCall.error.label": "Ошибка:", + + "toolCall.diff.label": "Diff", + "toolCall.diff.label.withPath": "Diff · {path}", + "toolCall.diff.viewMode.ariaLabel": "Режим просмотра diff", + "toolCall.diff.viewMode.split": "Раздельный", + "toolCall.diff.viewMode.unified": "Единый", + + "toolCall.diagnostics.title": "Диагностика", + "toolCall.diagnostics.ariaLabel": "Диагностика", + "toolCall.diagnostics.ariaLabel.withLabel": "Диагностика {label}", + "toolCall.diagnostics.severity.error.short": "ERR", + "toolCall.diagnostics.severity.warning.short": "WARN", + "toolCall.diagnostics.severity.info.short": "INFO", + + "toolCall.renderer.toolName.shell": "Shell", + "toolCall.renderer.toolName.fetch": "Fetch", + "toolCall.renderer.toolName.invalid": "Неверный", + "toolCall.renderer.toolName.plan": "План", + "toolCall.renderer.toolName.applyPatch": "Применить патч", + + "toolCall.renderer.action.working": "Выполняется…", + "toolCall.renderer.action.writingCommand": "Запись команды…", + "toolCall.renderer.action.preparingEdit": "Подготовка правки…", + "toolCall.renderer.action.readingFile": "Чтение файла…", + "toolCall.renderer.action.preparingWrite": "Подготовка записи…", + "toolCall.renderer.action.preparingPatch": "Подготовка патча…", + "toolCall.renderer.action.planning": "Планирование…", + "toolCall.renderer.action.fetchingFromWeb": "Получение из интернета…", + "toolCall.renderer.action.findingFiles": "Поиск файлов…", + "toolCall.renderer.action.searchingContent": "Поиск по содержимому…", + "toolCall.renderer.action.listingDirectory": "Просмотр каталога…", + + "toolCall.renderer.bash.title.timeout": "Таймаут: {timeout}", + "toolCall.renderer.read.detail.offset": "Смещение: {offset}", + "toolCall.renderer.read.detail.limit": "Лимит: {limit}", + + "toolCall.renderer.todo.empty": "Пока нет пунктов плана.", + "toolCall.renderer.todo.status.pending": "Ожидает", + "toolCall.renderer.todo.status.inProgress": "В процессе", + "toolCall.renderer.todo.status.completed": "Завершено", + "toolCall.renderer.todo.status.cancelled": "Отменено", + "toolCall.renderer.todo.title.plan": "План", + "toolCall.renderer.todo.title.creating": "Создание плана", + "toolCall.renderer.todo.title.completing": "Завершение плана", + "toolCall.renderer.todo.title.updating": "Обновление плана", + + "toolCall.permission.status.required": "Требуется разрешение", + "toolCall.permission.status.queued": "Разрешение в очереди", + "toolCall.permission.requestedDiff.label": "Запрошенный diff", + "toolCall.permission.requestedDiff.withPath": "Запрошенный diff · {path}", + "toolCall.permission.queuedText": "Ожидание предыдущих ответов по разрешениям.", + "toolCall.permission.actions.allowOnce": "Разрешить один раз", + "toolCall.permission.actions.alwaysAllow": "Всегда разрешать", + "toolCall.permission.actions.deny": "Запретить", + "toolCall.permission.shortcuts.allowOnce": "Разрешить один раз", + "toolCall.permission.shortcuts.alwaysAllow": "Всегда разрешать", + "toolCall.permission.shortcuts.deny": "Запретить", + "toolCall.permission.errors.unableToUpdate": "Не удалось обновить разрешение", + + "permissionApproval.title": "Запросы", + "permissionApproval.empty": "Нет ожидающих запросов.", + "permissionApproval.kind.permission": "Разрешение", + "permissionApproval.kind.question": "Вопрос", + "permissionApproval.questionCount.one": "{count} вопрос", + "permissionApproval.questionCount.other": "{count} вопросов", + "permissionApproval.status.active": "Активно", + "permissionApproval.actions.closeAriaLabel": "Закрыть", + "permissionApproval.actions.goToSession": "Перейти к сессии", + "permissionApproval.actions.loadingSession": "Загрузка…", + "permissionApproval.actions.loadSession": "Загрузить сессию", + "permissionApproval.actions.allowOnce": "Разрешить один раз", + "permissionApproval.actions.alwaysAllow": "Всегда разрешать", + "permissionApproval.actions.deny": "Запретить", + "permissionApproval.fallbackHint": "Загрузите сессию для получения подробностей.", + "permissionApproval.errors.unableToUpdatePermission": "Не удалось обновить разрешение", + + "toolCall.question.status.required": "Требуется ответ", + "toolCall.question.status.queued": "Вопрос в очереди", + "toolCall.question.status.questions": "Вопросы", + "toolCall.question.action.awaitingAnswers": "Ожидание ответов…", + "toolCall.question.title.questions": "Вопросы", + "toolCall.question.title.askingQuestions": "Задаем вопросы", + "toolCall.question.type.one": "Вопрос", + "toolCall.question.type.other": "Вопросы", + "toolCall.question.number": "В{number}:", + "toolCall.question.multiple": "Несколько", + "toolCall.question.custom.title": "Введите свой ответ", + "toolCall.question.custom.label": "Свой ответ", + "toolCall.question.custom.placeholder": "Введите свой ответ", + "toolCall.question.actions.submit": "Отправить", + "toolCall.question.actions.dismiss": "Скрыть", + "toolCall.question.shortcuts.submit": "Отправить", + "toolCall.question.shortcuts.dismiss": "Скрыть", + "toolCall.question.queuedText": "Ожидание предыдущих ответов.", + "toolCall.question.validation.answerAll": "Ответьте на все вопросы перед отправкой.", + "toolCall.question.errors.unableToReply": "Не удалось ответить", + "toolCall.question.errors.unableToDismiss": "Не удалось скрыть", + + "toolCall.task.action.delegating": "Делегирование…", + "toolCall.task.sections.prompt": "Prompt", + "toolCall.task.sections.steps": "Шаги", + "toolCall.task.sections.output": "Вывод", + "toolCall.task.steps.count": "{count} шагов", + "toolCall.task.meta.agentModel": "Агент: {agent} • Модель: {model}", + "toolCall.task.meta.agent": "Агент: {agent}", + "toolCall.task.meta.model": "Модель: {model}", + + "toolCall.status.pending": "В ожидании", + "toolCall.status.running": "Выполняется", + "toolCall.status.completed": "Завершено", + "toolCall.status.error": "Ошибка", + "toolCall.status.unknown": "Неизвестно", + + "toolCall.applyPatch.action.preparing": "Подготовка apply_patch…", + "toolCall.applyPatch.title.withFileCount.one": "{tool} ({count} файл)", + "toolCall.applyPatch.title.withFileCount.other": "{tool} ({count} файлов)", + "toolCall.applyPatch.fileFallback": "Файл {number}", +} as const diff --git a/packages/ui/src/lib/i18n/messages/zh-Hans/advancedSettings.ts b/packages/ui/src/lib/i18n/messages/zh-Hans/advancedSettings.ts new file mode 100644 index 00000000..dd41c187 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/zh-Hans/advancedSettings.ts @@ -0,0 +1,6 @@ +export const advancedSettingsMessages = { + "advancedSettings.title": "高级设置", + "advancedSettings.environmentVariables.title": "环境变量", + "advancedSettings.environmentVariables.subtitle": "每当启动新的 OpenCode 实例时应用", + "advancedSettings.actions.close": "关闭", +} as const diff --git a/packages/ui/src/lib/i18n/messages/zh-Hans/app.ts b/packages/ui/src/lib/i18n/messages/zh-Hans/app.ts new file mode 100644 index 00000000..f3dcbc5a --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/zh-Hans/app.ts @@ -0,0 +1,29 @@ +export const appMessages = { + "app.launchError.title": "无法启动 OpenCode", + "app.launchError.description": "我们无法启动所选的 OpenCode 可执行文件。请查看下面的错误输出,或在“高级设置”中选择其他可执行文件。", + "app.launchError.binaryPathLabel": "可执行文件路径", + "app.launchError.errorOutputLabel": "错误输出", + "app.launchError.openAdvancedSettings": "打开高级设置", + "app.launchError.close": "关闭", + "app.launchError.closeTitle": "关闭 (Esc)", + "app.launchError.fallbackMessage": "启动工作区失败", + + "app.stopInstance.confirmMessage": "停止 OpenCode 实例?这将停止服务器。", + "app.stopInstance.title": "停止实例", + "app.stopInstance.confirmLabel": "停止", + "app.stopInstance.cancelLabel": "继续运行", + + "emptyState.logoAlt": "CodeNomad 徽标", + "emptyState.brandTitle": "CodeNomad", + "emptyState.tagline": "选择文件夹,开始与 AI 一起编码", + "emptyState.actions.selectFolder": "选择文件夹", + "emptyState.actions.selecting": "正在选择...", + "emptyState.keyboardShortcut": "键盘快捷键:{shortcut}", + "emptyState.examples": "示例:{example}", + "emptyState.multipleInstances": "同一个文件夹可以同时打开多个实例", + + "releases.upgradeRequired.title": "需要升级", + "releases.upgradeRequired.message.withVersion": "更新到 CodeNomad {version} 以使用最新的 UI。", + "releases.upgradeRequired.message.noVersion": "更新 CodeNomad 以使用最新的 UI。", + "releases.upgradeRequired.action.getUpdate": "获取更新", +} as const diff --git a/packages/ui/src/lib/i18n/messages/zh-Hans/commands.ts b/packages/ui/src/lib/i18n/messages/zh-Hans/commands.ts new file mode 100644 index 00000000..20a25633 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/zh-Hans/commands.ts @@ -0,0 +1,160 @@ +export const commandMessages = { + "commandPalette.title": "命令面板", + "commandPalette.description": "搜索并执行命令", + "commandPalette.searchPlaceholder": "输入命令或搜索...", + "commandPalette.empty": "未找到与 \"{query}\" 匹配的命令", + "commandPalette.category.customCommands": "自定义命令", + "commandPalette.category.instance": "实例", + "commandPalette.category.session": "会话", + "commandPalette.category.agentModel": "智能体与模型", + "commandPalette.category.inputFocus": "输入与焦点", + "commandPalette.category.system": "系统", + "commandPalette.category.other": "其他", + + "commands.newInstance.label": "新建实例", + "commands.newInstance.description": "打开文件夹选择器以创建新实例", + "commands.newInstance.keywords": "folder, project, workspace, 文件夹, 项目, 工作区", + + "commands.closeInstance.label": "关闭实例", + "commands.closeInstance.description": "停止当前实例的服务器", + "commands.closeInstance.keywords": "stop, quit, close, 停止, 退出, 关闭", + + "commands.nextInstance.label": "下一个实例", + "commands.nextInstance.description": "切换到下一个实例标签页", + "commands.nextInstance.keywords": "switch, navigate, 切换, 导航", + + "commands.previousInstance.label": "上一个实例", + "commands.previousInstance.description": "切换到上一个实例标签页", + "commands.previousInstance.keywords": "switch, navigate, 切换, 导航", + + "commands.newSession.label": "新建会话", + "commands.newSession.description": "创建新的父会话", + "commands.newSession.keywords": "create, start, 创建, 开始", + + "commands.closeSession.label": "关闭会话", + "commands.closeSession.description": "关闭当前父会话", + "commands.closeSession.keywords": "close, stop, 关闭, 停止", + + "commands.scrubSessions.label": "清理会话", + "commands.scrubSessions.description": "移除空会话、已完成主任务的子智能体会话,以及多余的分叉会话。", + "commands.scrubSessions.keywords": "cleanup, blank, empty, sessions, remove, delete, scrub, 清理, 空白, 会话, 删除, 整理", + + "commands.instanceInfo.label": "实例信息", + "commands.instanceInfo.description": "打开实例概览以查看日志和状态", + "commands.instanceInfo.keywords": "info, logs, console, output, 信息, 日志, 控制台, 输出", + + "commands.nextSession.label": "下一个会话", + "commands.nextSession.description": "切换到下一个会话标签页", + "commands.nextSession.keywords": "switch, navigate, 切换, 导航", + + "commands.previousSession.label": "上一个会话", + "commands.previousSession.description": "切换到上一个会话标签页", + "commands.previousSession.keywords": "switch, navigate, 切换, 导航", + + "commands.compactSession.label": "压缩会话", + "commands.compactSession.description": "总结并压缩当前会话", + "commands.compactSession.keywords": "summarize, compress, 总结, 压缩", + "commands.compactSession.errorFallback": "压缩会话失败", + "commands.compactSession.alert.title": "压缩失败", + "commands.compactSession.alert.message": "压缩失败:{message}", + + "commands.undoLastMessage.label": "撤销上一条消息", + "commands.undoLastMessage.description": "回退上一条消息", + "commands.undoLastMessage.keywords": "revert, undo, 回退, 撤销", + "commands.undoLastMessage.none.title": "没有可撤销的操作", + "commands.undoLastMessage.none.message": "没有可撤销的内容", + "commands.undoLastMessage.failed.title": "撤销失败", + "commands.undoLastMessage.failed.message": "回退消息失败", + + "commands.openModelSelector.label": "打开模型选择器", + "commands.openModelSelector.description": "选择其他模型", + "commands.openModelSelector.keywords": "model, llm, ai, 模型", + + "commands.selectModelVariant.label": "选择模型变体", + "commands.selectModelVariant.description": "为当前模型选择思考强度", + "commands.selectModelVariant.keywords": "variant, thinking, reasoning, effort, 变体, 思考, 推理, 强度", + + "commands.openAgentSelector.label": "打开智能体选择器", + "commands.openAgentSelector.description": "选择其他智能体", + "commands.openAgentSelector.keywords": "agent, mode, 智能体, 模式", + + "commands.clearInput.label": "清空输入", + "commands.clearInput.description": "清空 prompt 输入框", + "commands.clearInput.keywords": "clear, reset, 清空, 重置", + + "commands.thinkingBlocks.label.show": "显示思考块", + "commands.thinkingBlocks.label.hide": "隐藏思考块", + "commands.thinkingBlocks.description": "显示/隐藏 AI 思考过程", + "commands.thinkingBlocks.keywords": "thinking, reasoning, toggle, show, hide, 思考, 推理, 切换, 显示, 隐藏", + + "commands.timelineToolCalls.label.show": "显示时间轴工具调用", + "commands.timelineToolCalls.label.hide": "隐藏时间轴工具调用", + "commands.timelineToolCalls.description": "切换消息时间轴中的工具调用条目", + "commands.timelineToolCalls.keywords": "timeline, tool, toggle, 时间轴, 工具, 切换", + + "commands.common.expanded": "展开", + "commands.common.collapsed": "折叠", + "commands.common.visible": "可见", + "commands.common.hidden": "隐藏", + "commands.common.enabled": "启用", + "commands.common.disabled": "禁用", + + "commands.thinkingBlocksDefault.label": "思考块默认 · {state}", + "commands.thinkingBlocksDefault.description": "切换思考块是否默认展开", + "commands.thinkingBlocksDefault.keywords": "thinking, reasoning, expand, collapse, default, 思考, 推理, 展开, 折叠, 默认", + + "commands.diffViewSplit.label": "使用分栏 Diff 视图", + "commands.diffViewSplit.description": "并排显示工具调用的 diff", + "commands.diffViewSplit.keywords": "diff, split, view, 差异, 分栏, 视图", + + "commands.diffViewUnified.label": "使用统一 Diff 视图", + "commands.diffViewUnified.description": "以内联方式显示工具调用的 diff", + "commands.diffViewUnified.keywords": "diff, unified, view, 差异, 统一, 视图", + + "commands.toolOutputsDefault.label": "工具输出默认 · {state}", + "commands.toolOutputsDefault.description": "切换工具输出是否默认展开", + "commands.toolOutputsDefault.keywords": "tool, output, expand, collapse, 工具, 输出, 展开, 折叠", + + "commands.diagnosticsDefault.label": "诊断默认 · {state}", + "commands.diagnosticsDefault.description": "切换诊断输出是否默认展开", + "commands.diagnosticsDefault.keywords": "diagnostics, expand, collapse, 诊断, 展开, 折叠", + + "commands.tokenUsageDisplay.label": "Token 使用显示 · {state}", + "commands.tokenUsageDisplay.description": "显示或隐藏助手消息的 token 和费用统计", + "commands.tokenUsageDisplay.keywords": "token, usage, cost, stats, 令牌, 用量, 费用, 统计", + + "commands.autoCleanupBlankSessions.label": "自动清理空白会话 · {state}", + "commands.autoCleanupBlankSessions.description": "在创建新会话时自动清理空白会话", + "commands.autoCleanupBlankSessions.keywords": "auto, cleanup, blank, sessions, toggle, 自动, 清理, 空白, 会话, 切换", + + "commands.showHelp.label": "显示帮助", + "commands.showHelp.description": "显示键盘快捷键与帮助", + "commands.showHelp.keywords": "shortcuts, help, 快捷键, 帮助", + + "commands.custom.argumentsPrompt.message": "/{name} 的参数", + "commands.custom.argumentsPrompt.title": "自定义命令", + "commands.custom.argumentsPrompt.inputLabel": "参数", + "commands.custom.argumentsPrompt.inputPlaceholder": "例如 foo bar", + "commands.custom.argumentsPrompt.confirmLabel": "运行", + "commands.custom.argumentsPrompt.cancelLabel": "取消", + "commands.custom.argumentsPrompt.openFailed.message": "无法打开参数输入框。", + "commands.custom.argumentsPrompt.openFailed.title": "命令参数", + "commands.custom.entries.descriptionFallback": "自定义命令", + "commands.custom.sessionRequired.message": "运行自定义命令前请先选择一个会话。", + "commands.custom.sessionRequired.title": "需要会话", + "commands.custom.runFailed.message": "运行自定义命令失败。请查看控制台了解详情。", + "commands.custom.runFailed.title": "命令失败", + + "unifiedPicker.loading.searching": "正在搜索...", + "unifiedPicker.loading.loadingWorkspace": "正在加载工作区...", + "unifiedPicker.title.command": "选择命令", + "unifiedPicker.title.mention": "选择智能体或文件", + "unifiedPicker.empty": "未找到结果", + "unifiedPicker.sections.commands": "命令", + "unifiedPicker.sections.agents": "智能体", + "unifiedPicker.sections.files": "文件", + "unifiedPicker.badge.subagent": "子智能体", + "unifiedPicker.footer.navigate": "导航", + "unifiedPicker.footer.select": "选择", + "unifiedPicker.footer.close": "关闭", +} as const diff --git a/packages/ui/src/lib/i18n/messages/zh-Hans/dialogs.ts b/packages/ui/src/lib/i18n/messages/zh-Hans/dialogs.ts new file mode 100644 index 00000000..ed088b84 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/zh-Hans/dialogs.ts @@ -0,0 +1,16 @@ +export const dialogMessages = { + "alertDialog.fallbackTitle.info": "提示", + "alertDialog.fallbackTitle.warning": "请确认", + "alertDialog.fallbackTitle.error": "出错了", + "alertDialog.actions.confirm": "确认", + "alertDialog.actions.run": "运行", + "alertDialog.actions.ok": "确定", + "alertDialog.actions.cancel": "取消", + "alertDialog.prompt.inputLabel": "输入", + + "backgroundProcessOutputDialog.title": "后台输出", + "backgroundProcessOutputDialog.actions.close": "关闭", + "backgroundProcessOutputDialog.loading": "正在加载输出...", + "backgroundProcessOutputDialog.truncatedNotice": "为便于显示,输出已截断。", + "backgroundProcessOutputDialog.loadErrorFallback": "加载输出失败。", +} as const diff --git a/packages/ui/src/lib/i18n/messages/zh-Hans/filesystem.ts b/packages/ui/src/lib/i18n/messages/zh-Hans/filesystem.ts new file mode 100644 index 00000000..baeaf9af --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/zh-Hans/filesystem.ts @@ -0,0 +1,43 @@ +export const filesystemMessages = { + "directoryBrowser.defaultDescription": "浏览已配置的工作区根目录下的文件夹。", + "directoryBrowser.close": "关闭", + "directoryBrowser.currentFolder": "当前文件夹", + "directoryBrowser.selectCurrent": "选择当前", + "directoryBrowser.newFolder": "新建文件夹", + "directoryBrowser.creating": "正在创建…", + "directoryBrowser.loadingFolders": "正在加载文件夹…", + "directoryBrowser.noFolders": "没有可用的文件夹。", + "directoryBrowser.upOneLevel": "上一级", + "directoryBrowser.select": "选择", + "directoryBrowser.load.errorFallback": "无法加载文件系统", + "directoryBrowser.createFolder.promptMessage": "在当前目录中新建文件夹。", + "directoryBrowser.createFolder.title": "新建文件夹", + "directoryBrowser.createFolder.inputLabel": "文件夹名称", + "directoryBrowser.createFolder.inputPlaceholder": "例如 my-new-project", + "directoryBrowser.createFolder.confirmLabel": "创建", + "directoryBrowser.createFolder.cancelLabel": "取消", + "directoryBrowser.createFolder.invalidNameMessage": "请输入单个文件夹名称。", + "directoryBrowser.createFolder.invalidNameDetail": "文件夹名称不能包含斜杠、\"..\" 或 \"~\"。", + "directoryBrowser.createFolder.errorFallback": "无法创建文件夹", + + "filesystemBrowser.descriptionFallback": "在已配置的工作区根目录下搜索路径。", + "filesystemBrowser.rootLabel": "根目录:{root}", + "filesystemBrowser.actions.close": "关闭", + "filesystemBrowser.actions.retry": "重试", + "filesystemBrowser.actions.select": "选择", + "filesystemBrowser.filterLabel": "筛选", + "filesystemBrowser.search.placeholder.directories": "搜索文件夹", + "filesystemBrowser.search.placeholder.files": "搜索文件", + "filesystemBrowser.currentFolder.label": "当前文件夹", + "filesystemBrowser.currentFolder.selectCurrent": "选择当前", + "filesystemBrowser.loading.filesystem": "文件系统", + "filesystemBrowser.loading.workspaceRoot": "工作区根目录", + "filesystemBrowser.loading.loadingWithPath": "正在加载 {path}…", + "filesystemBrowser.empty.noEntries": "未找到任何条目。", + "filesystemBrowser.navigation.upOneLevel": "上一级", + "filesystemBrowser.hints.navigate": "导航", + "filesystemBrowser.hints.select": "选择", + "filesystemBrowser.hints.close": "关闭", + "filesystemBrowser.errors.loadFilesystemFallback": "无法加载文件系统", + "filesystemBrowser.errors.openDirectoryFallback": "无法打开目录", +} as const diff --git a/packages/ui/src/lib/i18n/messages/zh-Hans/folderSelection.ts b/packages/ui/src/lib/i18n/messages/zh-Hans/folderSelection.ts new file mode 100644 index 00000000..9e87f7b4 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/zh-Hans/folderSelection.ts @@ -0,0 +1,34 @@ +export const folderSelectionMessages = { + "folderSelection.logoAlt": "CodeNomad 徽标", + "folderSelection.tagline": "选择文件夹,开始与 AI 一起编码", + + "folderSelection.links.github": "CodeNomad 的 GitHub", + "folderSelection.links.githubStars": "CodeNomad GitHub Star 数", + "folderSelection.links.discord": "CodeNomad 的 Discord", + + "folderSelection.empty.title": "没有最近的文件夹", + "folderSelection.empty.description": "浏览并选择文件夹以开始使用", + + "folderSelection.recent.title": "最近的文件夹", + "folderSelection.recent.subtitle.one": "{count} 个文件夹可用", + "folderSelection.recent.subtitle.other": "{count} 个文件夹可用", + "folderSelection.recent.remove": "从最近列表移除", + + "folderSelection.browse.title": "浏览文件夹", + "folderSelection.browse.subtitle": "选择你电脑上的任意文件夹", + "folderSelection.browse.button": "浏览文件夹", + "folderSelection.browse.buttonOpening": "正在打开...", + + "folderSelection.advancedSettings": "高级设置", + + "folderSelection.hints.navigate": "导航", + "folderSelection.hints.select": "选择", + "folderSelection.hints.remove": "移除", + "folderSelection.hints.browse": "浏览", + + "folderSelection.loading.title": "正在启动实例...", + "folderSelection.loading.subtitle": "正在准备你的工作区,请稍候。", + + "folderSelection.dialog.title": "选择工作区", + "folderSelection.dialog.description": "选择工作区以开始编码。", +} as const diff --git a/packages/ui/src/lib/i18n/messages/zh-Hans/index.ts b/packages/ui/src/lib/i18n/messages/zh-Hans/index.ts new file mode 100644 index 00000000..5da404da --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/zh-Hans/index.ts @@ -0,0 +1,36 @@ +import { advancedSettingsMessages } from "./advancedSettings" +import { appMessages } from "./app" +import { commandMessages } from "./commands" +import { dialogMessages } from "./dialogs" +import { filesystemMessages } from "./filesystem" +import { folderSelectionMessages } from "./folderSelection" +import { instanceMessages } from "./instance" +import { loadingScreenMessages } from "./loadingScreen" +import { logMessages } from "./logs" +import { markdownMessages } from "./markdown" +import { messagingMessages } from "./messaging" +import { remoteAccessMessages } from "./remoteAccess" +import { sessionMessages } from "./session" +import { settingsMessages } from "./settings" +import { timeMessages } from "./time" +import { toolCallMessages } from "./toolCall" +import { mergeMessageParts } from "../merge" + +export const zhHansMessages = mergeMessageParts( + folderSelectionMessages, + advancedSettingsMessages, + loadingScreenMessages, + timeMessages, + appMessages, + dialogMessages, + filesystemMessages, + instanceMessages, + logMessages, + sessionMessages, + messagingMessages, + toolCallMessages, + markdownMessages, + settingsMessages, + remoteAccessMessages, + commandMessages, +) diff --git a/packages/ui/src/lib/i18n/messages/zh-Hans/instance.ts b/packages/ui/src/lib/i18n/messages/zh-Hans/instance.ts new file mode 100644 index 00000000..247b474b --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/zh-Hans/instance.ts @@ -0,0 +1,125 @@ +export const instanceMessages = { + "instanceTabs.new.title": "新建实例 (Cmd/Ctrl+N)", + "instanceTabs.new.ariaLabel": "新建实例", + "instanceTabs.remote.title": "远程连接", + "instanceTabs.remote.ariaLabel": "远程连接", + + "instanceInfo.title": "实例信息", + "instanceInfo.labels.folder": "文件夹", + "instanceInfo.labels.project": "项目", + "instanceInfo.labels.versionControl": "版本控制", + "instanceInfo.labels.opencodeVersion": "OpenCode 版本", + "instanceInfo.labels.binaryPath": "可执行文件路径", + "instanceInfo.labels.environmentVariables": "环境变量({count})", + "instanceInfo.loading": "正在加载...", + "instanceInfo.server.title": "服务器", + "instanceInfo.server.port": "端口:", + "instanceInfo.server.pid": "PID:", + "instanceInfo.server.status": "状态:", + + "instanceTab.status.permission": "等待权限", + "instanceTab.status.compacting": "压缩中", + "instanceTab.status.working": "工作中", + "instanceTab.status.idle": "空闲", + "instanceTab.status.ariaLabel": "实例状态:{status}", + "instanceTab.actions.close.ariaLabel": "关闭实例", + + "instanceShell.leftPanel.sessionsTitle": "会话", + "instanceShell.leftPanel.instanceInfo": "实例信息", + + "instanceShell.leftDrawer.pin": "固定左侧抽屉", + "instanceShell.leftDrawer.unpin": "取消固定左侧抽屉", + "instanceShell.leftDrawer.toggle.pinned": "左侧抽屉已固定", + "instanceShell.leftDrawer.toggle.open": "打开左侧抽屉", + "instanceShell.leftDrawer.toggle.close": "关闭左侧抽屉", + + "instanceShell.rightDrawer.pin": "固定右侧抽屉", + "instanceShell.rightDrawer.unpin": "取消固定右侧抽屉", + "instanceShell.rightDrawer.toggle.pinned": "右侧抽屉已固定", + "instanceShell.rightDrawer.toggle.open": "打开右侧抽屉", + "instanceShell.rightDrawer.toggle.close": "关闭右侧抽屉", + + "instanceShell.metrics.usedLabel": "已用", + "instanceShell.metrics.availableLabel": "可用", + + "instanceShell.commandPalette.openAriaLabel": "打开命令面板", + "instanceShell.commandPalette.button": "命令面板", + + "instanceShell.connection.ariaLabel": "连接 {status}", + "instanceShell.connection.connected": "已连接", + "instanceShell.connection.connecting": "连接中...", + "instanceShell.connection.disconnected": "已断开", + "instanceShell.connection.unknown": "未知", + + "instanceWelcome.shortcuts.newSession": "新建会话", + "instanceWelcome.empty.title": "没有历史会话", + "instanceWelcome.empty.description": "在下方创建新会话以开始使用", + "instanceWelcome.loading.title": "正在加载会话", + "instanceWelcome.loading.description": "正在获取你的历史会话...", + "instanceWelcome.resume.title": "继续会话", + "instanceWelcome.resume.subtitle.one": "{count} 个会话可用", + "instanceWelcome.resume.subtitle.other": "{count} 个会话可用", + "instanceWelcome.session.untitled": "未命名会话", + "instanceWelcome.new.title": "开始新会话", + "instanceWelcome.new.subtitle": "将自动沿用上一次的智能体/模型", + "instanceWelcome.new.createButton": "创建会话", + "instanceWelcome.overlay.close": "关闭", + "instanceWelcome.actions.viewInstanceInfo": "查看实例信息", + "instanceWelcome.actions.renameTitle": "重命名会话", + "instanceWelcome.actions.deleteTitle": "删除会话", + "instanceWelcome.hints.navigate": "导航", + "instanceWelcome.hints.jump": "跳转", + "instanceWelcome.hints.firstLast": "首/末", + "instanceWelcome.hints.resume": "继续", + "instanceWelcome.hints.delete": "删除", + "instanceWelcome.toasts.renameError": "无法重命名会话", + + "instanceDisconnected.title": "实例已断开连接", + "instanceDisconnected.folderFallback": "此工作区", + "instanceDisconnected.reasonFallback": "服务器停止响应", + "instanceDisconnected.description": "{folder} 已无法访问。关闭此标签页以继续工作。", + "instanceDisconnected.details.title": "详情", + "instanceDisconnected.details.folderLabel": "文件夹:", + "instanceDisconnected.actions.closeInstance": "关闭实例", + + "instanceShell.empty.title": "未选择会话", + "instanceShell.empty.description": "选择会话以查看消息", + + "instanceShell.rightPanel.title": "状态面板", + "instanceShell.rightPanel.sections.plan": "计划", + "instanceShell.rightPanel.sections.backgroundProcesses": "后台 Shell", + "instanceShell.rightPanel.sections.mcp": "MCP 服务器", + "instanceShell.rightPanel.sections.lsp": "LSP 服务器", + "instanceShell.rightPanel.sections.plugins": "插件", + + "instanceShell.plan.noSessionSelected": "选择会话以查看计划。", + "instanceShell.plan.empty": "暂无计划。", + + "instanceShell.backgroundProcesses.empty": "没有后台进程。", + "instanceShell.backgroundProcesses.status": "状态:{status}", + "instanceShell.backgroundProcesses.output": "输出:{sizeKb}KB", + "instanceShell.backgroundProcesses.actions.output": "输出", + "instanceShell.backgroundProcesses.actions.stop": "停止", + "instanceShell.backgroundProcesses.actions.terminate": "终止", + + "versionPill.appWithVersion": "应用 {version}", + "versionPill.ui": "UI", + "versionPill.uiWithVersion": "UI {version}", + "versionPill.source": " ({source})", + + "opencodeBinarySelector.title": "OpenCode 可执行文件", + "opencodeBinarySelector.subtitle": "选择 OpenCode 要运行的可执行文件", + "opencodeBinarySelector.customPath.placeholder": "输入 opencode 可执行文件路径…", + "opencodeBinarySelector.actions.add": "添加", + "opencodeBinarySelector.actions.browse": "浏览可执行文件…", + "opencodeBinarySelector.actions.removeTitle": "移除可执行文件", + "opencodeBinarySelector.badge.systemPath": "使用系统 PATH 中的可执行文件", + "opencodeBinarySelector.status.checkingVersions": "正在检查版本…", + "opencodeBinarySelector.status.checking": "正在检查…", + "opencodeBinarySelector.dialog.title": "选择 OpenCode 可执行文件", + "opencodeBinarySelector.dialog.description": "浏览 CLI 服务器暴露的文件。", + "opencodeBinarySelector.validation.invalidBinary": "无效的 OpenCode 可执行文件", + "opencodeBinarySelector.validation.alreadyValidating": "正在验证中", + "opencodeBinarySelector.display.systemPath": "{name}(系统 PATH)", + "opencodeBinarySelector.versionLabel": "v{version}", +} as const diff --git a/packages/ui/src/lib/i18n/messages/zh-Hans/loadingScreen.ts b/packages/ui/src/lib/i18n/messages/zh-Hans/loadingScreen.ts new file mode 100644 index 00000000..7de05883 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/zh-Hans/loadingScreen.ts @@ -0,0 +1,17 @@ +export const loadingScreenMessages = { + "loadingScreen.logoAlt": "CodeNomad 徽标", + "loadingScreen.status.issue": "遇到问题", + "loadingScreen.actions.showAnother": "换一句", + "loadingScreen.errors.missingRoot": "未找到加载根元素", + + "loadingScreen.phrases.neurons": "正在热身 AI 神经元…", + "loadingScreen.phrases.daydreaming": "正在劝 AI 别再走神…", + "loadingScreen.phrases.goggles": "正在擦亮 AI 的代码护目镜…", + "loadingScreen.phrases.reorganizingFiles": "正在请求 AI 别再帮你重排文件…", + "loadingScreen.phrases.coffee": "正在给 AI 加杯咖啡…", + "loadingScreen.phrases.nodeModules": "正在教 AI 别再删除 node_modules(又一次)…", + "loadingScreen.phrases.actNatural": "正在提醒 AI 在你到来前表现自然点…", + "loadingScreen.phrases.rewritingHistory": "正在请 AI 别再重写历史…", + "loadingScreen.phrases.stretch": "正在让 AI 在编码冲刺前伸个懒腰…", + "loadingScreen.phrases.keyboardControl": "正在说服 AI 把键盘控制权交给你…", +} as const diff --git a/packages/ui/src/lib/i18n/messages/zh-Hans/logs.ts b/packages/ui/src/lib/i18n/messages/zh-Hans/logs.ts new file mode 100644 index 00000000..d0b4e9b8 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/zh-Hans/logs.ts @@ -0,0 +1,18 @@ +export const logMessages = { + "logsView.title": "服务器日志", + "logsView.actions.show": "显示服务器日志", + "logsView.actions.hide": "隐藏服务器日志", + "logsView.envVars.title": "环境变量({count})", + "logsView.paused.title": "服务器日志已暂停", + "logsView.paused.description": "启用流式输出以查看 OpenCode 服务器活动。", + "logsView.empty.waiting": "正在等待服务器输出...", + "logsView.scrollToBottom": "滚动到底部", + + "infoView.logs.title": "服务器日志", + "infoView.logs.actions.show": "显示服务器日志", + "infoView.logs.actions.hide": "隐藏服务器日志", + "infoView.logs.paused.title": "服务器日志已暂停", + "infoView.logs.paused.description": "启用流式输出以查看 OpenCode 服务器活动。", + "infoView.logs.empty.waiting": "正在等待服务器输出...", + "infoView.logs.scrollToBottom": "滚动到底部", +} as const diff --git a/packages/ui/src/lib/i18n/messages/zh-Hans/markdown.ts b/packages/ui/src/lib/i18n/messages/zh-Hans/markdown.ts new file mode 100644 index 00000000..0bae2824 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/zh-Hans/markdown.ts @@ -0,0 +1,7 @@ +export const markdownMessages = { + "markdown.codeBlock.copy.label": "复制", + "markdown.codeBlock.copy.copied": "已复制!", + "markdown.codeBlock.copy.failed": "失败", + + "markdown.copy": "复制", +} as const diff --git a/packages/ui/src/lib/i18n/messages/zh-Hans/messaging.ts b/packages/ui/src/lib/i18n/messages/zh-Hans/messaging.ts new file mode 100644 index 00000000..1946d076 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/zh-Hans/messaging.ts @@ -0,0 +1,109 @@ +export const messagingMessages = { + "messageListHeader.sidebar.openSessionListAriaLabel": "打开会话列表", + "messageListHeader.metrics.usedLabel": "已用", + "messageListHeader.metrics.availableLabel": "可用", + "messageListHeader.commandPalette.ariaLabel": "打开命令面板", + "messageListHeader.commandPalette.button": "命令面板", + "messageListHeader.connection.connected": "已连接", + "messageListHeader.connection.connecting": "连接中...", + "messageListHeader.connection.disconnected": "已断开", + + "messageSection.empty.logoAlt": "CodeNomad 徽标", + "messageSection.empty.brandTitle": "CodeNomad", + "messageSection.empty.title": "开始对话", + "messageSection.empty.description": "在下方输入消息,或打开命令面板:", + "messageSection.empty.tips.commandPalette": "命令面板", + "messageSection.empty.tips.askAboutCodebase": "询问你的代码库", + "messageSection.empty.tips.attachFilesPrefix": "通过以下方式附加文件", + "messageSection.loading.messages": "正在加载消息...", + "messageSection.scroll.toFirstAriaLabel": "滚动到第一条消息", + "messageSection.scroll.toLatestAriaLabel": "滚动到最新消息", + "messageSection.quote.addAsQuote": "作为引用添加", + "messageSection.quote.addAsCode": "作为代码添加", + + "messageTimeline.ariaLabel": "消息时间线", + "messageTimeline.segment.user.label": "你", + "messageTimeline.segment.assistant.label": "助手", + "messageTimeline.segment.compaction.label": "压缩", + "messageTimeline.tool.fallbackLabel": "工具调用", + "messageTimeline.tooltip.userFallback": "用户消息", + "messageTimeline.tooltip.assistantFallback": "助手回复", + "messageTimeline.tooltip.compaction.auto": "自动压缩", + "messageTimeline.tooltip.compaction.manual": "手动压缩", + "messageTimeline.text.filePrefix": "[文件] {filename}", + "messageTimeline.text.attachment": "附件", + + "messageBlock.tool.header": "工具调用", + "messageBlock.tool.unknown": "未知", + "messageBlock.tool.goToSession.label": "前往会话", + "messageBlock.tool.goToSession.title": "前往会话", + "messageBlock.tool.goToSession.unavailableTitle": "会话尚不可用", + + "messageBlock.compaction.ariaLabel": "会话压缩", + "messageBlock.compaction.autoLabel": "会话已自动压缩", + "messageBlock.compaction.manualLabel": "会话已由你压缩", + "messageBlock.usage.input": "输入", + "messageBlock.usage.output": "输出", + "messageBlock.usage.reasoning": "推理", + "messageBlock.usage.cacheRead": "缓存读取", + "messageBlock.usage.cacheWrite": "缓存写入", + "messageBlock.usage.cost": "费用", + "messageBlock.step.agentLabel": "智能体:{agent}", + "messageBlock.step.modelLabel": "模型:{model}", + "messageBlock.reasoning.thinkingLabel": "思考", + "messageBlock.reasoning.expandAriaLabel": "展开思考", + "messageBlock.reasoning.collapseAriaLabel": "折叠思考", + "messageBlock.reasoning.indicator.hide": "隐藏", + "messageBlock.reasoning.indicator.view": "查看", + "messageBlock.reasoning.detailsAriaLabel": "推理详情", + + "codeBlockInline.actions.copy": "复制", + "codeBlockInline.actions.copied": "已复制!", + + "messageItem.speaker.you": "你", + "messageItem.speaker.assistant": "助手", + "messageItem.actions.revert": "回退", + "messageItem.actions.revertTitle": "回退到这条消息", + "messageItem.actions.fork": "分叉", + "messageItem.actions.forkTitle": "从这条消息分叉", + "messageItem.actions.copy": "复制", + "messageItem.actions.copyTitle": "复制消息", + "messageItem.actions.copied": "已复制!", + "messageItem.status.queued": "排队中", + "messageItem.status.generating": "正在生成...", + "messageItem.status.sending": "正在发送...", + "messageItem.status.failedToSend": "消息发送失败", + "messageItem.attachment.defaultName": "附件", + "messageItem.attachment.downloadAriaLabel": "下载 {name}", + "messageItem.agentMeta.agentLabel": "智能体:{agent}", + "messageItem.agentMeta.modelLabel": "模型:{model}", + "messageItem.errors.authenticationFallback": "认证错误", + "messageItem.errors.outputLengthExceeded": "消息输出长度超限", + "messageItem.errors.requestAborted": "请求已中止", + "messageItem.errors.unknownFallback": "发生未知错误", + + "attachmentChip.removeAriaLabel": "移除附件", + + "expandButton.toggleAriaLabel": "切换聊天输入框高度", + + "promptInput.placeholder.shell": "运行 shell 命令(Esc 退出)...", + "promptInput.placeholder.default": "输入消息、@file、@agent,或粘贴图片与文本...", + "promptInput.hints.shell.exit": "退出 shell 模式", + "promptInput.hints.shell.enable": "Shell 模式", + "promptInput.hints.commands": "命令", + "promptInput.history.previousAriaLabel": "上一条 prompt", + "promptInput.history.nextAriaLabel": "下一条 prompt", + "promptInput.overlay.newLine": "换行", + "promptInput.overlay.send": "发送", + "promptInput.overlay.filesAgents": "文件/智能体", + "promptInput.overlay.history": "历史", + "promptInput.overlay.attachments": "• 已附加 {count} 个文件", + "promptInput.overlay.shellModeActive": "Shell 模式已启用", + "promptInput.overlay.press": "按下", + "promptInput.overlay.againToAbort": "再次按下以中止会话", + "promptInput.stopSession.ariaLabel": "停止会话", + "promptInput.stopSession.title": "停止会话", + "promptInput.send.ariaLabel": "发送消息", + "promptInput.send.errorFallback": "发送消息失败", + "promptInput.send.errorTitle": "发送失败", +} as const diff --git a/packages/ui/src/lib/i18n/messages/zh-Hans/remoteAccess.ts b/packages/ui/src/lib/i18n/messages/zh-Hans/remoteAccess.ts new file mode 100644 index 00000000..265e65c4 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/zh-Hans/remoteAccess.ts @@ -0,0 +1,51 @@ +export const remoteAccessMessages = { + "remoteAccess.eyebrow": "远程接管", + "remoteAccess.title": "远程连接到 CodeNomad", + "remoteAccess.subtitle": "使用下面的地址从其他设备打开 CodeNomad。", + "remoteAccess.close": "关闭远程访问", + "remoteAccess.refresh": "刷新", + + "remoteAccess.sections.listeningMode.label": "监听模式", + "remoteAccess.sections.listeningMode.help": "通过绑定到所有接口或仅 localhost 来允许或限制远程接管。", + "remoteAccess.toggle.on": "开", + "remoteAccess.toggle.off": "关", + "remoteAccess.toggle.title": "允许其他 IP 连接", + "remoteAccess.toggle.caption.all": "绑定到 0.0.0.0", + "remoteAccess.toggle.caption.local": "绑定到 127.0.0.1", + "remoteAccess.toggle.note": "更改此项需要重启,并会暂时停止所有活动实例。服务器重启后再分享下方地址。", + "remoteAccess.listeningMode.restartConfirm.message": "重启以应用监听模式?这将停止所有正在运行的实例。", + "remoteAccess.listeningMode.restartConfirm.title.all": "对其他设备开放", + "remoteAccess.listeningMode.restartConfirm.title.local": "仅限此设备", + "remoteAccess.listeningMode.restartConfirm.confirmLabel": "立即重启", + "remoteAccess.listeningMode.restartConfirm.cancelLabel": "取消", + "remoteAccess.restart.errorManual": "无法自动重启。请手动重启应用以应用更改。", + + "remoteAccess.sections.serverPassword.label": "服务器密码", + "remoteAccess.sections.serverPassword.help": "远程接管需要密码。设置一个易记的密码,以允许其他设备登录。", + "remoteAccess.authStatus.unavailable": "无法获取认证状态。", + "remoteAccess.username": "用户名:{username}", + "remoteAccess.password.status.set": "已为远程访问设置密码。", + "remoteAccess.password.status.unset": "尚未设置易记密码。设置后可允许远程接管登录。", + "remoteAccess.password.actions.cancel": "取消", + "remoteAccess.password.actions.change": "修改密码", + "remoteAccess.password.actions.set": "设置密码", + "remoteAccess.password.form.newPassword": "新密码", + "remoteAccess.password.form.confirmPassword": "确认密码", + "remoteAccess.password.form.placeholder": "至少 8 个字符", + "remoteAccess.password.error.tooShort": "密码至少需要 8 个字符。", + "remoteAccess.password.error.mismatch": "两次输入的密码不一致。", + "remoteAccess.password.save.saving": "正在保存…", + "remoteAccess.password.save.label": "保存密码", + + "remoteAccess.sections.addresses.label": "可访问地址", + "remoteAccess.sections.addresses.help": "从另一台设备打开或扫描,以接管控制权。", + "remoteAccess.addresses.loading": "正在加载地址…", + "remoteAccess.addresses.none": "暂时没有可用地址。", + "remoteAccess.address.scope.network": "网络", + "remoteAccess.address.scope.loopback": "回环", + "remoteAccess.address.scope.internal": "内部", + "remoteAccess.address.open": "打开", + "remoteAccess.address.showQr": "显示二维码", + "remoteAccess.address.hideQr": "隐藏二维码", + "remoteAccess.address.qrAlt": "{url} 的二维码", +} as const diff --git a/packages/ui/src/lib/i18n/messages/zh-Hans/session.ts b/packages/ui/src/lib/i18n/messages/zh-Hans/session.ts new file mode 100644 index 00000000..effac4f2 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/zh-Hans/session.ts @@ -0,0 +1,67 @@ +export const sessionMessages = { + "sessionPicker.title": "OpenCode • {folder}", + "sessionPicker.empty.noPrevious": "没有历史会话", + "sessionPicker.resume.title": "继续会话({count}):", + "sessionPicker.session.untitled": "未命名", + "sessionPicker.divider.or": "或", + "sessionPicker.new.title": "开始新会话:", + "sessionPicker.agents.loading": "正在加载智能体...", + "sessionPicker.actions.creating": "正在创建...", + "sessionPicker.actions.createSession": "创建会话", + "sessionPicker.actions.cancel": "取消", + + "sessionList.header.title": "会话", + "sessionList.session.untitled": "未命名", + "sessionList.status.working": "工作中", + "sessionList.status.compacting": "压缩中", + "sessionList.status.idle": "空闲", + "sessionList.status.needsPermission": "需要权限", + "sessionList.status.needsInput": "需要输入", + "sessionList.expand.collapseAriaLabel": "折叠会话", + "sessionList.expand.expandAriaLabel": "展开会话", + "sessionList.expand.collapseTitle": "折叠", + "sessionList.expand.expandTitle": "展开", + "sessionList.actions.copyId.ariaLabel": "复制会话 ID", + "sessionList.actions.copyId.title": "复制会话 ID", + "sessionList.actions.rename.ariaLabel": "重命名会话", + "sessionList.actions.rename.title": "重命名会话", + "sessionList.actions.delete.ariaLabel": "删除会话", + "sessionList.actions.delete.title": "删除会话", + "sessionList.copyId.success": "已复制会话 ID", + "sessionList.copyId.error": "无法复制会话 ID", + "sessionList.delete.error": "无法删除会话", + "sessionList.rename.error": "无法重命名会话", + + "sessionRenameDialog.title": "重命名会话", + "sessionRenameDialog.description.withLabel": "更新“{label}”的标题。", + "sessionRenameDialog.description.default": "为此会话设置新标题。", + "sessionRenameDialog.input.label": "会话名称", + "sessionRenameDialog.input.placeholder": "输入会话名称", + "sessionRenameDialog.actions.cancel": "取消", + "sessionRenameDialog.actions.rename": "重命名", + "sessionRenameDialog.actions.renaming": "正在重命名…", + + "sessionView.fallback.sessionNotFound": "未找到会话", + "sessionView.alerts.abortFailed.message": "停止会话失败", + "sessionView.alerts.abortFailed.title": "停止失败", + "sessionView.alerts.revertFailed.message": "回退到消息失败", + "sessionView.alerts.revertFailed.title": "回退失败", + "sessionView.alerts.forkFailed.message": "分叉会话失败", + "sessionView.alerts.forkFailed.title": "分叉失败", + "sessionView.attachments.expandPastedTextAriaLabel": "展开粘贴的文本", + "sessionView.attachments.insertPastedTextTitle": "插入粘贴的文本", + "sessionView.attachments.removeAriaLabel": "移除附件", + + "sessionEvents.sessionCompactedToast": "会话 {label} 已被压缩", + "sessionEvents.sessionError.unknown": "未知错误", + "sessionEvents.sessionError.title": "会话错误", + "sessionEvents.sessionError.message": "错误:{message}", + + "sessionState.cleanup.deepConfirm.message": "此清理可能较慢,并且可能删除你并不想删除的会话。确定要继续吗?", + "sessionState.cleanup.deepConfirm.title": "深度清理会话", + "sessionState.cleanup.deepConfirm.detail": "深度清理会话将删除所有没有消息的会话、移除已完成的子智能体会话,并清除会话中未使用的分叉。", + "sessionState.cleanup.deepConfirm.confirmLabel": "继续", + "sessionState.cleanup.deepConfirm.cancelLabel": "取消", + "sessionState.cleanup.toast.one": "已清理 {count} 个空白会话", + "sessionState.cleanup.toast.other": "已清理 {count} 个空白会话", +} as const diff --git a/packages/ui/src/lib/i18n/messages/zh-Hans/settings.ts b/packages/ui/src/lib/i18n/messages/zh-Hans/settings.ts new file mode 100644 index 00000000..179c10ed --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/zh-Hans/settings.ts @@ -0,0 +1,54 @@ +export const settingsMessages = { + "instanceServiceStatus.sections.lsp": "LSP 服务器", + "instanceServiceStatus.sections.mcp": "MCP 服务器", + "instanceServiceStatus.sections.plugins": "插件", + "instanceServiceStatus.lsp.loading": "正在加载 LSP 服务器...", + "instanceServiceStatus.lsp.empty": "未检测到 LSP 服务器。", + "instanceServiceStatus.lsp.status.connected": "已连接", + "instanceServiceStatus.lsp.status.error": "错误", + "instanceServiceStatus.mcp.loading": "正在加载 MCP 服务器...", + "instanceServiceStatus.mcp.empty": "未检测到 MCP 服务器。", + "instanceServiceStatus.mcp.toggleAriaLabel": "切换 {name} MCP 服务器", + "instanceServiceStatus.plugins.loading": "正在加载插件...", + "instanceServiceStatus.plugins.empty": "未配置插件。", + + "permissionBanner.pendingRequests.one": "{count} 个待处理请求", + "permissionBanner.pendingRequests.other": "{count} 个待处理请求", + "permissionBanner.detail.permission.one": "{count} 项权限", + "permissionBanner.detail.permission.other": "{count} 项权限", + "permissionBanner.detail.question.one": "{count} 个问题", + "permissionBanner.detail.question.other": "{count} 个问题", + "permissionBanner.detail.wrapper": " ({detail})", + + "agentSelector.placeholder": "选择智能体...", + "agentSelector.badge.subagent": "子智能体", + "agentSelector.none": "无", + "agentSelector.trigger.primary": "智能体:{agent}", + + "modelSelector.placeholder.search": "搜索模型...", + "modelSelector.none": "无", + "modelSelector.trigger.primary": "模型:{model}", + + "thinkingSelector.variant.default": "默认", + "thinkingSelector.label": "思考:{variant}", + + "envEditor.title": "环境变量", + "envEditor.count.one": "({count} 个变量)", + "envEditor.count.other": "({count} 个变量)", + "envEditor.fields.name.placeholder": "变量名", + "envEditor.fields.name.readOnlyTitle": "变量名(只读)", + "envEditor.fields.value.placeholder": "变量值", + "envEditor.actions.remove.title": "移除变量", + "envEditor.actions.add.title": "添加变量", + "envEditor.empty": "未配置环境变量。在上方添加变量以自定义 OpenCode 环境。", + "envEditor.help": "启动实例时,这些变量将在 OpenCode 环境中可用。", + + "contextUsagePanel.headings.tokens": "Tokens", + "contextUsagePanel.headings.context": "上下文", + "contextUsagePanel.labels.input": "输入", + "contextUsagePanel.labels.output": "输出", + "contextUsagePanel.labels.cost": "费用", + "contextUsagePanel.labels.used": "已用", + "contextUsagePanel.labels.available": "可用", + "contextUsagePanel.unavailable": "--", +} as const diff --git a/packages/ui/src/lib/i18n/messages/zh-Hans/time.ts b/packages/ui/src/lib/i18n/messages/zh-Hans/time.ts new file mode 100644 index 00000000..7ef87a16 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/zh-Hans/time.ts @@ -0,0 +1,6 @@ +export const timeMessages = { + "time.relative.justNow": "刚刚", + "time.relative.daysAgoShort": "{count} 天前", + "time.relative.hoursAgoShort": "{count} 小时前", + "time.relative.minutesAgoShort": "{count} 分钟前", +} as const diff --git a/packages/ui/src/lib/i18n/messages/zh-Hans/toolCall.ts b/packages/ui/src/lib/i18n/messages/zh-Hans/toolCall.ts new file mode 100644 index 00000000..7a53ea33 --- /dev/null +++ b/packages/ui/src/lib/i18n/messages/zh-Hans/toolCall.ts @@ -0,0 +1,121 @@ +export const toolCallMessages = { + "toolCall.pending.waitingToRun": "等待运行...", + "toolCall.error.label": "错误:", + + "toolCall.diff.label": "Diff", + "toolCall.diff.label.withPath": "Diff · {path}", + "toolCall.diff.viewMode.ariaLabel": "Diff 视图模式", + "toolCall.diff.viewMode.split": "分栏", + "toolCall.diff.viewMode.unified": "统一", + + "toolCall.diagnostics.title": "诊断", + "toolCall.diagnostics.ariaLabel": "诊断", + "toolCall.diagnostics.ariaLabel.withLabel": "诊断 {label}", + "toolCall.diagnostics.severity.error.short": "ERR", + "toolCall.diagnostics.severity.warning.short": "WARN", + "toolCall.diagnostics.severity.info.short": "INFO", + + "toolCall.renderer.toolName.shell": "Shell", + "toolCall.renderer.toolName.fetch": "Fetch", + "toolCall.renderer.toolName.invalid": "无效", + "toolCall.renderer.toolName.plan": "计划", + "toolCall.renderer.toolName.applyPatch": "应用补丁", + + "toolCall.renderer.action.working": "处理中...", + "toolCall.renderer.action.writingCommand": "正在编写命令...", + "toolCall.renderer.action.preparingEdit": "正在准备编辑...", + "toolCall.renderer.action.readingFile": "正在读取文件...", + "toolCall.renderer.action.preparingWrite": "正在准备写入...", + "toolCall.renderer.action.preparingPatch": "正在准备补丁...", + "toolCall.renderer.action.planning": "正在规划...", + "toolCall.renderer.action.fetchingFromWeb": "正在从网络获取...", + "toolCall.renderer.action.findingFiles": "正在查找文件...", + "toolCall.renderer.action.searchingContent": "正在搜索内容...", + "toolCall.renderer.action.listingDirectory": "正在列出目录...", + + "toolCall.renderer.bash.title.timeout": "超时:{timeout}", + "toolCall.renderer.read.detail.offset": "偏移:{offset}", + "toolCall.renderer.read.detail.limit": "限制:{limit}", + + "toolCall.renderer.todo.empty": "暂无计划项。", + "toolCall.renderer.todo.status.pending": "待处理", + "toolCall.renderer.todo.status.inProgress": "进行中", + "toolCall.renderer.todo.status.completed": "已完成", + "toolCall.renderer.todo.status.cancelled": "已取消", + "toolCall.renderer.todo.title.plan": "计划", + "toolCall.renderer.todo.title.creating": "正在创建计划", + "toolCall.renderer.todo.title.completing": "正在完成计划", + "toolCall.renderer.todo.title.updating": "正在更新计划", + + "toolCall.permission.status.required": "需要权限", + "toolCall.permission.status.queued": "权限已排队", + "toolCall.permission.requestedDiff.label": "请求的 Diff", + "toolCall.permission.requestedDiff.withPath": "请求的 Diff · {path}", + "toolCall.permission.queuedText": "正在等待更早的权限响应。", + "toolCall.permission.actions.allowOnce": "仅允许一次", + "toolCall.permission.actions.alwaysAllow": "始终允许", + "toolCall.permission.actions.deny": "拒绝", + "toolCall.permission.shortcuts.allowOnce": "仅允许一次", + "toolCall.permission.shortcuts.alwaysAllow": "始终允许", + "toolCall.permission.shortcuts.deny": "拒绝", + "toolCall.permission.errors.unableToUpdate": "无法更新权限", + + "permissionApproval.title": "请求", + "permissionApproval.empty": "暂无待处理请求。", + "permissionApproval.kind.permission": "权限", + "permissionApproval.kind.question": "问题", + "permissionApproval.questionCount.one": "{count} 个问题", + "permissionApproval.questionCount.other": "{count} 个问题", + "permissionApproval.status.active": "活动", + "permissionApproval.actions.closeAriaLabel": "关闭", + "permissionApproval.actions.goToSession": "前往会话", + "permissionApproval.actions.loadingSession": "正在加载…", + "permissionApproval.actions.loadSession": "加载会话", + "permissionApproval.actions.allowOnce": "仅允许一次", + "permissionApproval.actions.alwaysAllow": "始终允许", + "permissionApproval.actions.deny": "拒绝", + "permissionApproval.fallbackHint": "加载会话以查看更多信息。", + "permissionApproval.errors.unableToUpdatePermission": "无法更新权限", + + "toolCall.question.status.required": "需要回答问题", + "toolCall.question.status.queued": "问题已排队", + "toolCall.question.status.questions": "问题", + "toolCall.question.action.awaitingAnswers": "等待回答...", + "toolCall.question.title.questions": "问题", + "toolCall.question.title.askingQuestions": "正在提问", + "toolCall.question.type.one": "问题", + "toolCall.question.type.other": "问题", + "toolCall.question.number": "Q{number}:", + "toolCall.question.multiple": "多个", + "toolCall.question.custom.title": "输入自定义答案", + "toolCall.question.custom.label": "自定义答案", + "toolCall.question.custom.placeholder": "输入你的答案", + "toolCall.question.actions.submit": "提交", + "toolCall.question.actions.dismiss": "忽略", + "toolCall.question.shortcuts.submit": "提交", + "toolCall.question.shortcuts.dismiss": "忽略", + "toolCall.question.queuedText": "正在等待更早的响应。", + "toolCall.question.validation.answerAll": "请先回答所有问题再提交。", + "toolCall.question.errors.unableToReply": "无法回复", + "toolCall.question.errors.unableToDismiss": "无法忽略", + + "toolCall.task.action.delegating": "正在委派...", + "toolCall.task.sections.prompt": "Prompt", + "toolCall.task.sections.steps": "步骤", + "toolCall.task.sections.output": "输出", + "toolCall.task.steps.count": "{count} 个步骤", + "toolCall.task.meta.agentModel": "智能体:{agent} • 模型:{model}", + "toolCall.task.meta.agent": "智能体:{agent}", + "toolCall.task.meta.model": "模型:{model}", + + "toolCall.status.pending": "待处理", + "toolCall.status.running": "运行中", + "toolCall.status.completed": "已完成", + "toolCall.status.error": "错误", + "toolCall.status.unknown": "未知", + + "toolCall.applyPatch.action.preparing": "正在准备 apply_patch...", + "toolCall.applyPatch.title.withFileCount.one": "{tool}({count} 个文件)", + "toolCall.applyPatch.title.withFileCount.other": "{tool}({count} 个文件)", + "toolCall.applyPatch.fileFallback": "文件 {number}", +} as const