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

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: primeroes, y lo que falte cae aen.
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 paquete | node_modules/dsh-locale-es/ |
| La activación | cordis.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"]}— elpatchReload: livedel perfil lo cargó sin reiniciar DSH. - Bundle servido:
/plugins/??dsh-locale-es/client.jses 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, idiomaescon respaldoen, sin claves huérfanas ni marcadores alterados. - Runtime real de DSH (
node tools/test-real-runtime.mjs): carga elLocaleRuntimeauténtico que se sirve al navegador, le registra los diccionariosen/zhreales de los 42 namespaces y aplica el paquetees. Comprueba con código de producción que:- el catálogo pasa a
zh, en, escon la etiqueta «Español», - la preferencia guardada (
locale.preference: es) se adopta → activoes, 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')ysetLocale('es')conmutan correctamente,- cobertura 1257/1257 claves resueltas (0 sin traducir).
- el catálogo pasa a
- Preferencia:
~/.dsh/settings.yamlguardalocale.preference: es(fichero vigilado conchokidar, 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í:
expiryva en milisegundos en las versiones recientes (una fecha en segundos se interpreta como 1970 → cookie caducada → nunca se envía).sameSiteusa los valores densICookie, no 0/1/2:None = 0,Lax = 256,Strict = 512.cookies.sqlitefunciona en modo WAL: para comprobar si Firefox lo usa, mira tambiéncookies.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 directorionode_modules/dsh-locale-espuede 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.