openpencil/src/i18n/locales/es.ts
Kayshen Xu ca1b5370ae
V0.3.0 (#24)
* feat(boolean-operations): implement boolean operations in the editor

- Added a new BooleanToolbar component for union, subtract, and intersect operations.
- Integrated boolean operations into the layer context menu and keyboard shortcuts.
- Enhanced the editor layout to include the boolean toolbar for improved user interaction.
- Updated internationalization support with new translation keys for boolean operations.
- Bumped version to 0.3.0 to reflect the addition of these features.

* refactor(editor): update editor layout and panels for improved functionality

- Replaced the PropertyPanel with a new RightPanel that includes both Property and Code panels.
- Removed the CodePanel from the main editor layout and integrated it into the RightPanel.
- Updated keyboard shortcuts to switch the right panel to the code tab.
- Enhanced the LayerPanel with a resizable width feature for better user experience.
- Added internationalization support for new right panel labels and code panel features.
- Introduced new code generation capabilities for various frameworks in the CodePanel.
- Improved overall layout structure for better responsiveness and usability.

* feat(electron): implement .op file association and enhance file handling

- Added support for .op file association in electron-builder, allowing OpenPencil documents to be opened directly from the file system.
- Implemented IPC handlers for opening and reading .op files, ensuring proper loading of document content.
- Enhanced the main process to handle file opening events on macOS and single-instance locking on Windows/Linux.
- Updated the renderer to listen for file open events and load documents accordingly.
- Improved README to reflect new file association feature.

* fix(canvas): improve layout accuracy for AI-generated designs

- Unify lineHeight default via canonical defaultLineHeight() function
- Unify text measurement by removing duplicate estimators in generation-utils
- Fix optical centering formula to scale proportionally with fontSize
- Round layout positions to whole pixels to prevent sub-pixel artifacts
- Recursively sanitize nested x/y in streaming layout containers
- Fix input trailing icon alignment using fill_container instead of space_between

* feat(canvas): right-align agent badge and add breathing glow border

- Agent badge now right-aligned to frame's right edge instead of after label
- Added breathing glow border around agent-owned frames during generation
- Glow border uses same color and lifecycle as the agent badge
- Removed unused BADGE_GAP constant and useDocumentStore import

* feat(code-panel): enhance tab scrolling functionality and add scrollbar utility

- Introduced left and right scroll buttons for tab navigation in the CodePanel, improving user experience for navigating long tab lists.
- Added a custom utility to hide scrollbars for a cleaner interface.
- Updated styles for better responsiveness and usability in the CodePanel layout.

* fix(docs): update Discord invite links in multiple README files

- Replaced outdated Discord invite links with the new link across all language-specific README files.
- Ensured consistency in the documentation for community engagement.

* feat(code-panel): enhance system prompt for responsive design

- Updated the ENHANCE_SYSTEM_PROMPT to emphasize the importance of responsive design in code rewriting.
- Added detailed guidelines for converting fixed pixel widths to relative units and using responsive Tailwind breakpoints.
- Ensured that the output remains visually faithful on desktop while adapting gracefully across screen sizes.

* feat(docs): add WeChat group information to README.zh.md and include group image

- Introduced a new section in the Chinese README to provide details about the WeChat group for community engagement.
- Added an image representing the WeChat group for better visibility and user interaction.

* feat(electron): enhance theme management and title bar overlay for Windows/Linux

- Updated the `setTheme` method in the Electron API to accept custom colors for the title bar overlay, improving theme synchronization across platforms.
- Adjusted title bar overlay colors for Windows and Linux to ensure proper visibility and aesthetics.
- Enhanced the top bar component to read computed CSS colors and apply them dynamically, ensuring a consistent user interface.
- Improved handling of theme changes in the application to support background and foreground color customization.

* fix(screenshot): update screenshot image for improved clarity and quality

* fix(docs): update WeChat group image path in README.zh.md for consistency

* fix(ai): fix post-generation validation pipeline and text centering

- Fix Agent SDK validation: save temp screenshots inside project dir
  (.openpencil-tmp/) so Claude Code plan mode can read them, instead
  of /tmp/ which is outside the project sandbox
- Enrich validation tree dump with fill colors, stroke, fontSize,
  fontWeight, textAlign, cornerRadius, opacity for comprehensive
  visual analysis
- Add multi-round validation with quality scoring (threshold 8/10),
  500ms stabilization delay between rounds
- Add detailed debug logging to applyValidationFixes showing which
  nodes were found/skipped and property changes
- Fix canvas sync needsTextbox check to also account for textAlign
  (matching isFixedWidthText in factory), preventing IText↔Textbox
  thrashing on every sync tick
- Auto-center text in vertical+center layouts by expanding to full
  container width and injecting textAlign:'center'
- Force Textbox for non-left-aligned text so textAlign is respected
  (IText ignores width and computes its own)

* fix(canvas): use precise text width estimation for fit-content layout

Remove the 14% safety factor from text width estimation when computing
fit-content/natural-width text dimensions. IText auto-computes its own
width and ignores our setting, so the safety margin only inflated the
layout allocation, making text appear left-shifted within its container.

* fix(canvas): center fit-content text in horizontal layouts

For text nodes with fit-content width in horizontal layouts, set
textAlign:'center' to compensate for width estimation inaccuracy.
The estimated box is typically wider than the actual rendered text,
causing left-aligned text to appear visually shifted. Centering
distributes the estimation error evenly on both sides.

* feat(ai): show validation details in checklist panel

- Accumulate validation log (screenshot, analysis, fixes) instead of
  overwriting status messages, so the full process is visible
- Preserve step thinking content in buildFinalStepTags (was discarded)
- Add details field to pipeline items and render in checklist UI
- Each validation step now shows: screenshot captured, issues found,
  quality score, fixes applied

* feat(ai): add visual reference pipeline types and integration hooks

- Add DesignSystem and VisualReference types to ai-types
- Add 'visual-ref' mode to AIDesignRequest and SubTask.htmlReference
- Detect visual-ref candidates in chat handlers (landing pages, websites)
- Wire visual-ref mode in design-generator and orchestrator
- Inject HTML reference snippets into sub-agent prompts

* feat(ai): add modular design principles for sub-agent context

- Add design-principles module with topic files: color, typography,
  spacing, composition, components
- Selectively load relevant principles based on prompt content
- Inject design principles into sub-agent system prompts

* feat(ai): implement visual reference pipeline

- Add design-system-generator: generates color/typography/spacing tokens
- Add design-code-generator: generates HTML/CSS from design system
- Add html-renderer: renders HTML to screenshot via html2canvas
- Add visual-ref-orchestrator: coordinates the full pipeline
  (design system → HTML code → screenshot → enrich subtasks)
- Add html2canvas dependency for client-side HTML rendering

* feat(mcp): default filePath to live canvas and fix cross-platform issues

- Default all MCP tool filePath to live://canvas when omitted, so tools
  operate on the real-time canvas instead of stale files
- Remove filePath from required params in all tool schemas (21 interfaces)
- Fix mcp-server-manager.ts using process.cwd() which fails in Electron
  production on Linux — now checks ELECTRON_RESOURCES_PATH first
- Fix stopMcpHttpServer using SIGTERM on Windows — use taskkill instead
- Force new children reference in applyExternalDocument to ensure canvas
  sync subscriber always detects MCP-pushed document updates

* feat(mcp): enhance design prompt with semantic roles, CJK typography, and layout rules

Add comprehensive design knowledge to MCP design prompt for better
AI-generated designs: design type detection (mobile vs desktop), full
semantic role reference with context-aware defaults, CJK typography
rules, expanded text/layout/form guidelines, and detailed post-processing
documentation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(ai): implement intent classification for chat handlers

- Replace hardcoded keyword matching with a lightweight LLM call to classify user intent in chat messages.
- Introduce a new function `classifyIntent` to determine if the request is for design generation or conversation.
- Update design request handling in `useChatHandlers` to utilize the new classification method.
- Enhance design prompt documentation to reflect changes in design type detection based on intent rather than keywords.

* fix(ai): handle string qualityScore in validation response parsing

The LLM sometimes returns qualityScore as a string (e.g. "8" instead of 8),
causing it to fall through to 0. Also hide misleading "quality: 0/10" display
when the score couldn't be determined, and log raw response for debugging.

* fix(ai): increase validation timeout to 90s and fix quality score parsing

Agent SDK validation requires spawning a process, reading the image, and
analyzing it — 30s was consistently timing out. Also handle string
qualityScore values from LLM responses and hide misleading 0/10 display.

* fix(ai): fix validation timeout and response parsing

- Increase validation timeout from 30s to 180s (Agent SDK needs time
  for subprocess spawn + OAuth auth + multi-turn image reading)
- Strip <tool_use> XML blocks from Agent SDK response before extracting
  JSON — the tool call XML was confusing the regex, causing qualityScore
  to parse as 0 despite valid JSON being present
- Handle string qualityScore values and hide misleading "quality: 0/10"
- Revert unnecessary direct API key approach for validation

* fix(ai): prevent node ID collisions between generations

When generating new content on a canvas with existing nodes, AI-generated
IDs (e.g. brand-spacer) would collide with previous generations. Now
captures pre-existing node IDs at generation start and checks against
them during upsert sanitization. Remapped IDs are tracked in
generationRemappedIds so progressive streaming updates can still find
their nodes.

* fix(ai): require styleGuide in orchestrator plan and fix validation detail icons

- Add fallback default styleGuide when orchestrator LLM omits it
- Strengthen prompt to mark styleGuide as REQUIRED
- Replace emoji icons in validation details with [done]/[pending]/[error]
  markers for consistent styling with the checklist design system

* feat(server): add port file plugin for server instance discovery

- Introduce a new Nitro plugin that writes a port file on server startup to allow the MCP server to discover the running instance, whether it's a development server or Electron.
- Implement error handling in the Electron main process for writing the port file, logging any failures.
- Update Vite configuration to include additional external dependencies in the rollup configuration.

* feat(electron): implement IPC for retrieving pending file paths

- Added a new IPC handler `file:getPending` to retrieve and clear the pending file path when the React app mounts.
- Updated the Electron API to include `getPendingFile` for renderer access.
- Enhanced the `useElectronMenu` hook to load any pending file on application startup.
- Updated UI components to reflect changes in file handling and improved user experience.

* fix(panels): replace emoji icons with styled icons in validation checklist

- Parse [done]/[pending]/[error] prefixes in detail lines and render as
  styled circle icons matching the parent checklist design system
- Replace remaining emoji markers in design-validation.ts with text prefixes
- Fix isApplied detection to recognize new [done] Applied marker

* refactor(electron): update settings path to use platform-standard app data directory

- Changed the settings file path to utilize Electron's user data directory for better cross-platform compatibility.
- Updated the settings writing function to ensure the user data directory is created if it doesn't exist.
- Added comments to clarify the storage location for different operating systems.
- Implemented a fixed partition for localStorage/cookies to maintain data across server port changes.

* feat(ai): enhance validation with pre-checks, structural fixes, and border detection

- Add design-pre-validation.ts: pure code checks before LLM validation
  - Invisible container detection (same fill as parent → auto-add border)
  - Sibling consistency (majority-rule for height/cornerRadius)
- Add structural fixes to validation: addChild/removeNode operations
  - Icon injection via lookupIconByName with server fallback
  - autoFixParentLayout with child count guard to prevent layout breakage
- Add strokeColor/strokeWidth to safe fix properties for border fixes
- Simplify intent classification: all design requests use visual-ref pipeline
- Fix checklist: "Found N issues" now shows [done] instead of [pending]
- Fix qualityScore: only update when > 0 to preserve valid round scores

* fix(ai): cherry-pick safe validation improvements, drop aggressive pre-checks

Keep: stroke tree dump bug fix (object not array), qualityScore=0 false
positive detection, fit_content→fixed safety guard, empty path removal,
type-specific sibling consistency, repeated fix filtering, screenshot
extraction to design-screenshot.ts.

Drop: detectForcedFixedHeight (destroyed input/button heights),
MAX_VALIDATION_ROUNDS 5 (too many rounds), removal of quality threshold
early stop, section regeneration phase.

---------

Co-authored-by: Fini <fini.yang@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:55:35 +08:00

403 lines
16 KiB
TypeScript

import type { TranslationKeys } from './en'
const es: TranslationKeys = {
// ── Common ──
'common.rename': 'Renombrar',
'common.duplicate': 'Duplicar',
'common.delete': 'Eliminar',
'common.cancel': 'Cancelar',
'common.save': 'Guardar',
'common.close': 'Cerrar',
'common.connect': 'Conectar',
'common.disconnect': 'Desconectar',
'common.import': 'Importar',
'common.export': 'Exportar',
'common.name': 'Nombre',
'common.untitled': 'Sin título',
'common.best': 'Recomendado',
'common.selected': '{{count}} seleccionado(s)',
// ── Toolbar ──
'toolbar.select': 'Selección',
'toolbar.text': 'Texto',
'toolbar.frame': 'Marco',
'toolbar.hand': 'Mano',
'toolbar.undo': 'Deshacer',
'toolbar.redo': 'Rehacer',
'toolbar.variables': 'Variables',
'toolbar.uikitBrowser': 'Explorador UIKit',
// ── Shapes ──
'shapes.rectangle': 'Rectángulo',
'shapes.ellipse': 'Elipse',
'shapes.line': 'Línea',
'shapes.icon': 'Icono',
'shapes.importImageSvg': 'Importar imagen o SVG\u2026',
'shapes.pen': 'Pluma',
'shapes.shapeTools': 'Herramientas de forma',
'shapes.moreShapeTools': 'Más herramientas de forma',
// ── Top Bar ──
'topbar.hideLayers': 'Ocultar capas',
'topbar.showLayers': 'Mostrar capas',
'topbar.new': 'Nuevo',
'topbar.open': 'Abrir',
'topbar.save': 'Guardar',
'topbar.importFigma': 'Importar Figma',
'topbar.codePanel': 'Código',
'topbar.lightMode': 'Modo claro',
'topbar.darkMode': 'Modo oscuro',
'topbar.fullscreen': 'Pantalla completa',
'topbar.exitFullscreen': 'Salir de pantalla completa',
'topbar.edited': '— Editado',
'topbar.agentsAndMcp': 'Agentes y MCP',
'topbar.setupAgentsMcp': 'Configurar Agentes y MCP',
'topbar.connected': 'conectado',
'topbar.agentStatus': '{{agents}} agente{{agentSuffix}} · {{mcp}} MCP',
// ── Right Panel ──
'rightPanel.design': 'Diseño',
'rightPanel.code': 'Código',
'rightPanel.noSelection': 'Selecciona un elemento',
// ── Pages ──
'pages.title': 'Páginas',
'pages.addPage': 'Agregar página',
'pages.moveUp': 'Mover arriba',
'pages.moveDown': 'Mover abajo',
// ── Status Bar ──
'statusbar.zoomOut': 'Alejar',
'statusbar.zoomIn': 'Acercar',
'statusbar.resetZoom': 'Restablecer zoom',
// ── Updater ──
'updater.softwareUpdate': 'Actualización de software',
'updater.dismiss': 'Descartar',
'updater.current': 'Actual',
'updater.latest': 'Última',
'updater.unknown': 'Desconocida',
'updater.checking': 'Comprobando...',
'updater.downloadProgress': 'Progreso de descarga',
'updater.checkAgain': 'Comprobar de nuevo',
'updater.restartInstall': 'Reiniciar e instalar',
'updater.installing': 'Instalando...',
'updater.releaseDate': 'Fecha de publicación: {{date}}',
'updater.restartHint':
'Reinicie para aplicar la actualización. El reinicio suele tardar entre 10 y 15 segundos.',
'updater.unknownError': 'Error de actualización desconocido.',
'updater.title.checking': 'Buscando actualizaciones',
'updater.title.available': 'Actualización encontrada',
'updater.title.downloading': 'Descargando actualización',
'updater.title.downloaded': 'Listo para instalar',
'updater.title.error': 'Error de actualización',
'updater.subtitle.checking': 'Buscando la última versión...',
'updater.subtitle.available': 'La versión {{version}} está disponible.',
'updater.subtitle.availableGeneric': 'Hay una nueva versión disponible.',
'updater.subtitle.downloading':
'La versión {{version}} se está descargando en segundo plano.',
'updater.subtitle.downloadingGeneric':
'Descargando el paquete de actualización en segundo plano.',
'updater.subtitle.downloaded': 'La versión {{version}} se ha descargado.',
'updater.subtitle.downloadedGeneric': 'La actualización se ha descargado.',
'updater.subtitle.error':
'No se pudo comprobar o descargar la actualización.',
// ── Layers ──
'layers.title': 'Capas',
'layers.empty':
'Aún no hay capas. Use la barra de herramientas para dibujar formas.',
// ── Layer Context Menu ──
'layerMenu.groupSelection': 'Agrupar selección',
'layerMenu.createComponent': 'Crear componente',
'layerMenu.detachComponent': 'Separar componente',
'layerMenu.detachInstance': 'Separar instancia',
'layerMenu.booleanUnion': 'Unión',
'layerMenu.booleanSubtract': 'Restar',
'layerMenu.booleanIntersect': 'Intersección',
'layerMenu.toggleLock': 'Alternar bloqueo',
'layerMenu.toggleVisibility': 'Alternar visibilidad',
// ── Property Panel ──
'property.createComponent': 'Crear componente',
'property.detachComponent': 'Separar componente',
'property.goToComponent': 'Ir al componente',
'property.detachInstance': 'Separar instancia',
// ── Fill ──
'fill.title': 'Relleno',
'fill.solid': 'Sólido',
'fill.linear': 'Lineal',
'fill.radial': 'Radial',
'fill.stops': 'Paradas',
'fill.angle': 'Ángulo',
// ── Stroke ──
'stroke.title': 'Trazo',
// ── Appearance ──
'appearance.layer': 'Capa',
'appearance.opacity': 'Opacidad',
// ── Layout ──
'layout.flexLayout': 'Diseño Flex',
'layout.freedom': 'Libre (sin diseño)',
'layout.vertical': 'Diseño vertical',
'layout.horizontal': 'Diseño horizontal',
'layout.alignment': 'Alineación',
'layout.gap': 'Espacio',
'layout.spaceBetween': 'Espacio entre',
'layout.spaceAround': 'Espacio alrededor',
'layout.dimensions': 'Dimensiones',
'layout.fillWidth': 'Rellenar ancho',
'layout.fillHeight': 'Rellenar alto',
'layout.hugWidth': 'Ajustar ancho',
'layout.hugHeight': 'Ajustar alto',
'layout.clipContent': 'Recortar contenido',
// ── Padding ──
'padding.title': 'Relleno interior',
'padding.paddingMode': 'Modo de relleno interior',
'padding.paddingValues': 'Valores de relleno interior',
'padding.oneValue': 'Un valor para todos los lados',
'padding.horizontalVertical': 'Horizontal/Vertical',
'padding.topRightBottomLeft': 'Arriba/Derecha/Abajo/Izquierda',
// ── Typography ──
'text.typography': 'Tipografía',
'text.lineHeight': 'Interlineado',
'text.letterSpacing': 'Espaciado entre letras',
'text.horizontal': 'Horizontal',
'text.vertical': 'Vertical',
'text.alignLeft': 'Alinear a la izquierda',
'text.alignCenter': 'Centrar',
'text.alignRight': 'Alinear a la derecha',
'text.justify': 'Justificar',
'text.top': 'Arriba',
'text.middle': 'Medio',
'text.bottom': 'Abajo',
'text.weight.thin': 'Thin',
'text.weight.light': 'Light',
'text.weight.regular': 'Regular',
'text.weight.medium': 'Medium',
'text.weight.semibold': 'Semibold',
'text.weight.bold': 'Bold',
'text.weight.black': 'Black',
// ── Text Layout ──
'textLayout.title': 'Diseño',
'textLayout.dimensions': 'Dimensiones',
'textLayout.resizing': 'Redimensionamiento',
'textLayout.autoWidth': 'Auto W',
'textLayout.autoWidthDesc':
'Ancho automático — el texto se expande horizontalmente',
'textLayout.autoHeight': 'Auto H',
'textLayout.autoHeightDesc':
'Alto automático — ancho fijo, alto autoajustable',
'textLayout.fixed': 'Fijo',
'textLayout.fixedDesc':
'Tamaño fijo — tanto el ancho como el alto son fijos',
'textLayout.fillWidth': 'Rellenar ancho',
'textLayout.fillHeight': 'Rellenar alto',
// ── Effects ──
'effects.title': 'Efectos',
'effects.dropShadow': 'Sombra',
'effects.blur': 'Desenfoque',
'effects.spread': 'Extensión',
'effects.color': 'Color',
// ── Export ──
'export.title': 'Exportar',
'export.format': 'Formato',
'export.scale': 'Escala',
'export.selectedOnly': 'Exportar solo la selección',
'export.exportFormat': 'Exportar {{format}}',
'export.exportLayer': 'Exportar capa',
// ── Corner Radius ──
'cornerRadius.title': 'Radio de esquina',
// ── Size / Position ──
'size.position': 'Posición',
// ── Icon ──
'icon.title': 'Icono',
'icon.searchIcons': 'Buscar iconos...',
'icon.noIconsFound': 'No se encontraron iconos',
'icon.typeToSearch': 'Escriba para buscar iconos de Iconify',
'icon.iconsCount': '{{count}} iconos',
// ── Variables Panel ──
'variables.addTheme': 'Agregar tema',
'variables.addVariant': 'Agregar variante',
'variables.addVariable': 'Agregar variable',
'variables.searchVariables': 'Buscar variables...',
'variables.noMatch': 'Ninguna variable coincide con su búsqueda',
'variables.noDefined': 'No hay variables definidas',
'variables.closeShortcut': 'Cerrar (⌘⇧V)',
'variables.presets': 'Preajustes',
'variables.savePreset': 'Guardar actual como preajuste…',
'variables.loadPreset': 'Cargar preajuste',
'variables.importPreset': 'Importar desde archivo…',
'variables.exportPreset': 'Exportar a archivo…',
'variables.presetName': 'Nombre del preajuste',
'variables.noPresets': 'No hay preajustes guardados',
// ── AI Chat ──
'ai.newChat': 'Nueva conversación',
'ai.collapse': 'Contraer',
'ai.tryExample': 'Pruebe un ejemplo para diseñar...',
'ai.tipSelectElements':
'Consejo: seleccione elementos en el lienzo antes de chatear para dar contexto.',
'ai.generating': 'Generando...',
'ai.designWithAgent': 'Diseñar con agente...',
'ai.attachImage': 'Adjuntar imagen',
'ai.stopGenerating': 'Detener generación',
'ai.sendMessage': 'Enviar mensaje',
'ai.loadingModels': 'Cargando modelos...',
'ai.noModelsConnected': 'Sin modelos conectados',
'ai.quickAction.loginScreen':
'Diseñar una pantalla de inicio de sesión móvil',
'ai.quickAction.loginScreenPrompt':
'Diseña una pantalla de inicio de sesión móvil moderna con campo de correo electrónico, campo de contraseña, botón de inicio de sesión y opciones de inicio de sesión social',
'ai.quickAction.productCard': 'Crear un componente de tarjeta de producto',
'ai.quickAction.productCardPrompt':
'Crea una tarjeta de producto con un marcador de imagen, título, precio y botón de compra',
'ai.quickAction.bottomNav':
'Diseñar una barra de navegación inferior',
'ai.quickAction.bottomNavPrompt':
'Diseña una barra de navegación inferior para aplicación móvil con 5 pestañas: Inicio, Buscar, Agregar, Mensajes, Perfil',
'ai.quickAction.colorPalette':
'Sugerir una paleta de colores para mi aplicación',
'ai.quickAction.colorPalettePrompt':
'Sugiere una paleta de colores moderna para una aplicación de cuidado de mascotas',
// ── Code Panel ──
'code.reactTailwind': 'React + Tailwind',
'code.htmlCss': 'HTML + CSS',
'code.cssVariables': 'CSS Variables',
'code.copyClipboard': 'Copiar al portapapeles',
'code.copied': '¡Copiado!',
'code.download': 'Descargar archivo de código',
'code.closeCodePanel': 'Cerrar panel de código',
'code.genCssVars':
'Generando variables CSS para todo el documento',
'code.genSelected':
'Generando código para {{count}} elemento(s) seleccionado(s)',
'code.genDocument': 'Generando código para todo el documento',
'code.aiEnhance': 'Mejorar con IA',
'code.cancelEnhance': 'Cancelar mejora',
'code.resetEnhance': 'Restablecer original',
'code.enhancing': 'La IA está mejorando el código...',
'code.enhanced': 'Mejorado por IA',
// ── Save Dialog ──
'save.saveAs': 'Guardar como',
'save.fileName': 'Nombre del archivo',
// ── Agent Settings ──
'agents.title': 'Configurar Agentes y MCP',
'agents.agentsOnCanvas': 'Agentes en el lienzo',
'agents.mcpIntegrations': 'Integraciones MCP en terminal',
'agents.transport': 'Transporte',
'agents.port': 'Puerto',
'agents.mcpRestart':
'Las integraciones MCP se aplicarán tras reiniciar la terminal.',
'agents.modelCount': '{{count}} modelo(s)',
'agents.connectionFailed': 'Error de conexión',
'agents.serverError': 'Error del servidor {{status}}',
'agents.failedTo': 'Error al {{action}}',
'agents.failedToMcp': 'Error al {{action}} del servidor MCP',
'agents.failedTransport': 'Error al actualizar el transporte',
'agents.failedMcpTransport': 'Error al actualizar el transporte MCP',
'agents.claudeCode': 'Claude Code',
'agents.claudeModels': 'Modelos Claude',
'agents.codexCli': 'Codex CLI',
'agents.openaiModels': 'Modelos OpenAI',
'agents.opencode': 'OpenCode',
'agents.opencodeDesc': '75+ proveedores LLM',
'agents.copilot': 'GitHub Copilot',
'agents.copilotDesc': 'Modelos GitHub Copilot',
'agents.mcpServer': 'Servidor MCP',
'agents.mcpServerStart': 'Iniciar',
'agents.mcpServerStop': 'Detener',
'agents.mcpServerRunning': 'En ejecución',
'agents.mcpServerStopped': 'Detenido',
'agents.mcpLanAccess': 'Acceso LAN',
'agents.mcpClientConfig': 'Config. del cliente',
'agents.stdio': 'stdio',
'agents.http': 'http',
'agents.stdioHttp': 'stdio + http',
'agents.autoUpdate': 'Buscar actualizaciones automáticamente',
'agents.notInstalled': 'No instalado',
'agents.install': 'Instalar',
'agents.installing': 'Instalando...',
'agents.installFailed': 'Instalación fallida',
'agents.viewDocs': 'Docs',
// ── Figma Import ──
'figma.title': 'Importar desde Figma',
'figma.dropFile': 'Suelte un archivo .fig aquí',
'figma.orBrowse': 'o haga clic para explorar',
'figma.exportTip':
'Exportar desde Figma: Archivo \u2192 Guardar copia local (.fig)',
'figma.selectFigFile': 'Seleccione un archivo .fig',
'figma.noPages': 'No se encontraron páginas en el archivo .fig',
'figma.parseFailed': 'Error al analizar el archivo .fig',
'figma.convertFailed': 'Error al convertir el archivo de Figma',
'figma.parsing': 'Analizando archivo .fig...',
'figma.converting': 'Convirtiendo nodos...',
'figma.selectPage':
'Este archivo tiene {{count}} páginas. Seleccione cuáles importar:',
'figma.layers': '{{count}} capas',
'figma.importAll': 'Importar todas las páginas',
'figma.importComplete': '¡Importación completa!',
'figma.moreWarnings': '...y {{count}} advertencias más',
'figma.tryAgain': 'Intentar de nuevo',
'figma.layoutMode': 'Modo de diseño:',
'figma.preserveLayout': 'Conservar diseño de Figma',
'figma.autoLayout': 'Diseño automático OpenPencil',
'figma.comingSoon': 'Próximamente',
// ── Landing Page ──
'landing.open': 'Open',
'landing.pencil': 'Pencil',
'landing.tagline':
'Herramienta de diseño vectorial de código abierto. Design as Code.',
'landing.newDesign': 'Nuevo diseño',
'landing.shortcutHint':
'Presione {{key1}} + {{key2}} para crear un nuevo diseño',
// ── 404 ──
'notFound.message': 'Página no encontrada',
// ── Component Browser ──
'componentBrowser.title': 'Explorador UIKit',
'componentBrowser.exportKit': 'Exportar kit',
'componentBrowser.importKit': 'Importar kit',
'componentBrowser.kit': 'Kit:',
'componentBrowser.all': 'Todos',
'componentBrowser.imported': '(importado)',
'componentBrowser.components': 'componentes',
'componentBrowser.searchComponents': 'Buscar componentes...',
'componentBrowser.deleteKit': 'Eliminar {{name}}',
'componentBrowser.category.all': 'Todos',
'componentBrowser.category.buttons': 'Botones',
'componentBrowser.category.inputs': 'Entradas',
'componentBrowser.category.cards': 'Tarjetas',
'componentBrowser.category.nav': 'Navegación',
'componentBrowser.category.layout': 'Diseño',
'componentBrowser.category.data': 'Datos',
'componentBrowser.category.feedback': 'Retroalimentación',
'componentBrowser.category.other': 'Otro',
// ── Variable Picker ──
'variablePicker.boundTo': 'Vinculado a --{{name}}',
'variablePicker.bindToVariable': 'Vincular a variable',
'variablePicker.unbind': 'Desvincular variable',
'variablePicker.noVariables': 'No hay variables {{type}} definidas',
} as const
export default es