← Back to home@pilahito

dsh-locale-es

Paquete de idioma español para la GUI web de DeepSeek Harness (DSH): 42 namespaces y 1257 cadenas traducidas

Stars
0
Language
JavaScript
Created
Sep 13, 2026
Updated
Sep 13, 2026

Introduction

dsh-locale-es — interfaz de DeepSeek Harness en español

Paquete de idioma español para la GUI web de DSH (http://127.0.0.1:3080). La interfaz solo traía inglés (en) y chino (zh); este paquete añade es sin tocar ni un fichero de DSH: se instala como plugin de cliente en tu perfil web.

Estado: instalado y activo. 42 namespaces · 1257 cadenas traducidas.

📣 Anuncio: Discussions #1 — Paquete de idioma español para la GUI web

La GUI de DSH en español


Cómo funciona

DSH trae un servicio de localización (@deepseek-ai/dsh-client-locale) con:

  • un catálogo de idiomas ampliable (ctx.locale.addLanguage({ id, label, fallback })), y
  • diccionarios por namespace (ctx.locale.register(ns, locale, dict)), con cadena de respaldo: primero es, y lo que falte cae a en.

Los plugins de cliente se cargan como módulos de navegador servidos por el host en /plugins. Por eso el paquete solo necesita:

pack/dsh-locale-es/
├── package.json      # declara dsh.client { platform: web, inject: [locale] }
└── lib/
    ├── index.js      # mitad host: no hace nada (apply vacío)
    └── client.js     # bundle del navegador: idioma + diccionarios

lib/client.js se registra con el cargador de DSH (window.__ModuleLoader__.load({ id, factory })) y en apply(ctx) hace:

ctx.effect(() => ctx.locale.addLanguage({ id: "es", label: "Español", fallback: "en" }), "…")
ctx.effect(() => ctx.locale.register(ns, "es", dict), "…")   // uno por namespace

La preferencia se guarda en $DSH_HOME/settings.yaml (locale.preference: es).

Instalación

./instalar.sh          # copia el paquete al perfil y añade la entrada al parche
./instalar.sh --quitar # lo desinstala y revierte el parche

El instalador solo escribe en $DSH_HOME/profiles/web:

QuéDónde
El paquetenode_modules/dsh-locale-es/
La activacióncordis.patch.yml → - insert: [{ id: locale-es, name: 'dsh-locale-es' }]

Es idempotente y hace copia .bak del parche antes de tocarlo. Después, recarga la página con Ctrl+Shift+R (los plugins de cliente se cargan al arrancar la página). Si no aparece en español: Ajustes → General → Idioma → Español.

Estructura del proyecto

dsh-es/
├── instalar.sh                  # instalación/desinstalación en el perfil web
├── data/
│   ├── dictionaries.json        # extraído ejecutando los bundles (en + zh)
│   ├── dictionaries-static.json # extraído por análisis estático (rellena huecos)
│   ├── chunks/                  # lotes de traducción (entrada)
│   ├── parts/                   # lotes traducidos (salida por lote)
│   └── translations.es.json     # ⭐ las 1257 traducciones (editable a mano)
├── pack/dsh-locale-es/          # paquete listo para instalar (generado)
└── tools/
    ├── extract-dicts.mjs        # ejecuta cada bundle cliente y captura sus diccionarios
    ├── static-dicts.mjs         # extractor estático + verificación cruzada
    ├── make-chunks.mjs          # reparte las cadenas en lotes equilibrados
    ├── merge-parts.mjs          # fusiona los lotes en translations.es.json
    ├── build-pack.mjs           # genera pack/ (valida cobertura y marcadores)
    ├── test-pack.mjs            # autotest del paquete generado
    └── gui-fetch.mjs            # cliente HTTP local de la GUI (para verificar)

Reconstruir / actualizar tras una versión nueva de DSH

node tools/extract-dicts.mjs     # re-extrae los diccionarios en inglés
node tools/static-dicts.mjs      # (opcional) rellena huecos y verifica
node tools/make-chunks.mjs 6     # nuevos lotes con las cadenas nuevas
#   → traducir data/chunks/*.json a data/parts/*.json
node tools/merge-parts.mjs
node tools/build-pack.mjs        # avisa de claves sin traducir o mal formadas
node tools/test-pack.mjs
./instalar.sh

build-pack.mjs falla en silencio útil: informa de claves sin traducir, namespaces desconocidos y marcadores de posición ({count}, {name}…) que no coincidan con el original, y no incluye en el paquete ninguna cadena sospechosa (esas siguen saliendo en inglés por el respaldo).

Añadir otro idioma

Duplica el flujo cambiando es por el código correspondiente en data/translations.<id>.json y en tools/build-pack.mjs (LANGUAGE). El fallback debe ser en.

Verificación hecha

  • Grafo de arranque: GET / del host ya incluye {"id":"dsh-locale-es", …, "inject":["@deepseek-ai/dsh-client-locale"]} — el patchReload: live del perfil lo cargó sin reiniciar DSH.
  • Bundle servido: /plugins/??dsh-locale-es/client.js es idéntico byte a byte al generado (el host solo añade el trailer del source map).
  • Autotest: node tools/test-pack.mjs → 42 namespaces, 1257 claves, idioma es con respaldo en, sin claves huérfanas ni marcadores alterados.
  • Runtime real de DSH (node tools/test-real-runtime.mjs): carga el LocaleRuntime auténtico que se sirve al navegador, le registra los diccionarios en/zh reales de los 42 namespaces y aplica el paquete es. Comprueba con código de producción que:
    • el catálogo pasa a zh, en, es con la etiqueta «Español»,
    • la preferencia guardada (locale.preference: es) se adopta → activo es,
    • sidebar.session.new → «Nueva sesión», common.cancel → «Cancelar»,
    • los marcadores se sustituyen: … truncado en 120 caracteres,
    • lo no traducido cae al inglés y una clave desconocida se muestra tal cual,
    • setLocale('en') y setLocale('es') conmutan correctamente,
    • cobertura 1257/1257 claves resueltas (0 sin traducir).
  • Preferencia: ~/.dsh/settings.yaml guarda locale.preference: es (fichero vigilado con chokidar, así que se aplica en caliente).
  • Navegador real (node tools/verify-firefox.mjs → captura-gui-es.png): Firefox headless con la cookie de sesión firmada abre la GUI y la captura. La interfaz sale en español: «Ajustes», «Elegir espacio de trabajo», «Elige un espacio de trabajo para empezar», «Vista previa», «Hacia lo desconocido». La captura es reproducible (mismo SHA-256 en ejecuciones distintas), así que sirve como prueba de regresión tras cada cambio.

Autenticación de la verificación

El host protege la GUI: el token de la URL que imprime dsh web es efímero (aleatorio por proceso y solo en memoria), pero la cookie de sesión se firma con el secreto durable de ~/.dsh/.credentials.yaml. tools/cookie.mjs reproduce ese algoritmo (dsh-auth-<sha256(authority)> + HMAC-SHA256 del payload), así que se puede verificar la GUI sin navegador del usuario.

Para Firefox, tools/verify-firefox.mjs siembra la cookie en el cookies.sqlite del perfil headless. Dos detalles que cuestan un rato descubrir, anotados aquí:

  • expiry va en milisegundos en las versiones recientes (una fecha en segundos se interpreta como 1970 → cookie caducada → nunca se envía).
  • sameSite usa los valores de nsICookie, no 0/1/2: None = 0, Lax = 256, Strict = 512.
  • cookies.sqlite funciona en modo WAL: para comprobar si Firefox lo usa, mira también cookies.sqlite-wal, no solo la mtime del fichero principal.

Relación con el proyecto oficial

DSH (deepseek-ai/deepseek-harness) solo distribuye inglés (en) y chino (zh): en packages/client/locale/src/locales/ únicamente hay en.ts y zh.ts. Este repositorio añade el español como plugin de cliente, sin modificar ni un fichero del proyecto oficial.

El CONTRIBUTING.md oficial no acepta pull requests externos y pide dos cosas a quien publica un plugin; este repositorio cumple las dos:

  • topic dsh-plugin — es el mecanismo oficial de descubrimiento del ecosistema de plugins.
  • no depender del árbol oficial en tiempo de ejecución — el paquete consume solo la API pública del servicio locale (addLanguage + register), que es la vía que el propio DSH documenta para paquetes de idioma externos.

Para seguir el proyecto oficial sin mezclar historiales hay un remoto upstream:

git remote -v          # origin = este repo · upstream = deepseek-harness
git fetch upstream     # solo si quieres consultar el árbol oficial (repo grande)

La extracción de cadenas no lee el repositorio oficial, sino el DSH instalado (/usr/lib/node_modules/@deepseek-ai/dsh), así que para actualizar tras una versión nueva basta con:

node tools/extract-dicts.mjs && node tools/static-dicts.mjs
node tools/make-chunks.mjs 6   # traducir lo nuevo → data/parts/
node tools/merge-parts.mjs && node tools/build-pack.mjs && node tools/test-pack.mjs
./instalar.sh

Si algún día el español se integra en el proyecto oficial, este paquete puede retirarse sin más: solo añade un idioma al catálogo, con respaldo en inglés.

Limitaciones

  • Una cadena que DSH añada en una versión futura saldrá en inglés hasta que se traduzca (comportamiento del respaldo, no un fallo).
  • Si reinstalas dependencias del perfil (dsh plugin --profile web add …, pnpm install), el directorio node_modules/dsh-locale-es puede desaparecer: vuelve a ejecutar ./instalar.sh.
  • Los textos que DSH captura al registrar un comando (no los pinta por slots) pueden quedarse en el idioma del arranque hasta reiniciar DSH; es una limitación documentada del propio servicio de idiomas de DSH.