dsh-composer-plus 1.11.2 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.es.md CHANGED
@@ -14,7 +14,7 @@ Mejoras de comodidad al estilo de Codex para la interfaz de escritorio y web de
14
14
 
15
15
  <p align="center"><img src="docs/images/hero.webp" width="820" alt="DeepSeek Harness con Composer Plus: el proyecto en ejecución muestra un indicador de carga en la barra lateral y el panel de cambios muestra un diff de git"></p>
16
16
 
17
- Plugin comunitario no oficial. Las únicas llamadas de red son las de la comprobación de actualizaciones (las versiones publicadas en GitHub y el registro de npm). Desactiva **Actualizaciones automáticas** para que no se hagan al iniciar. **Ideas de funciones** llama al modelo de tu propio chat solo cuando haces clic en **Sugerir funciones**. **Predicción del siguiente mensaje** (activada de forma predeterminada) llama al modelo elegido en Configuración (el predeterminado de dsh, salvo que elijas otro) una vez después de cada turno terminado, sin ningún clic. Desactívala en **Configuración → Composer Plus** para detener estas llamadas. **Completar al escribir** (desactivado de forma predeterminada) llama al modelo elegido para esta función (de forma predeterminada, el de la predicción) en cada pausa mientras escribes, después de que lo actives. **Conexión móvil** (desactivada de forma predeterminada) acepta conexiones del iPhone desde tu red local o tu tailnet solo después de que la actives.
17
+ Plugin comunitario no oficial. Las únicas llamadas de red son las de la comprobación de actualizaciones (las versiones publicadas en GitHub y el registro de npm). Desactiva **Actualizaciones automáticas** para que no se hagan al iniciar. **Ideas de funciones** llama al modelo de tu propio chat solo cuando haces clic en **Sugerir funciones**. **Predicción del siguiente mensaje** (activada de forma predeterminada) llama al modelo elegido en Configuración (el predeterminado de dsh, salvo que elijas otro) una vez después de cada turno terminado, sin ningún clic. Desactívala en **Configuración → Composer Plus** para detener estas llamadas. **Completar al escribir** (desactivado de forma predeterminada) llama al modelo elegido para esta función (de forma predeterminada, el de la predicción) en cada pausa mientras escribes, después de que lo actives. **Mejorar prompt** solo llama a un modelo cuando haces clic en su varita mágica. **Conexión móvil** (desactivada de forma predeterminada) acepta conexiones del iPhone desde tu red local o tu tailnet solo después de que la actives.
18
18
 
19
19
  ## Instalación
20
20
 
@@ -29,46 +29,51 @@ dsh plugin --profile web add dsh-composer-plus
29
29
 
30
30
  Después, reinicia dsh. (La CLI no puede instalar en el perfil de escritorio: de eso se encarga la app).
31
31
 
32
- > El pnpm de dsh omite las versiones publicadas hace menos de 24 horas. Justo después de una versión nueva, añade la versión: `dsh-composer-plus@1.11.2`.
32
+ > El pnpm de dsh omite las versiones publicadas hace menos de 24 horas. Justo después de una versión nueva, añade la versión: `dsh-composer-plus@1.12.0`.
33
33
 
34
34
  ## Funciones
35
35
 
36
+ <!-- BEGIN GENERATED FEATURES: edit docs/features.json, then run npm run build:readme -->
37
+
36
38
  | Función | Cómo usarla | Captura |
37
39
  |---|---|---|
38
- | **Panel de cambios** | Barra lateral derecha → `+` → **Cambios**. Elige **Sin confirmar**, **Sin preparar**, **Preparados** o **Rama** para ver los archivos cambiados con sus contadores `+/-`; haz clic en un archivo para ver su diff. **Último turno** abre la revisión propia de dsh del último turno. | <a href="assets/features/changesPanel.webp"><img src="assets/features/changesPanel.webp" width="160" alt="Captura del Panel de cambios"></a> |
39
- | **Ideas de funciones** | Barra lateral derecha → `+` → **Ideas de funciones** → **Sugerir funciones**. El modelo del propio chat lee un breve resumen del proyecto del chat (los archivos del nivel superior, el principio del README y del manifiesto, los últimos 15 commits) y sugiere hasta 8 funciones. Las muestra como un montón de tarjetas en el idioma de la interfaz de dsh. Desliza una tarjeta hacia la derecha (o haz clic en **✓**, o pulsa `→`; en todos los casos la tarjeta sale volando hacia su lado) para iniciar un nuevo chat en el mismo proyecto: empieza en modo plan con la idea como petición, así que nada cambia antes de que apruebes el plan. Para saltarte el plan, haz clic en **▶ Crear ahora** (o pulsa `↑`; la tarjeta sale volando hacia arriba): el nuevo chat empieza enseguida con la idea como una petición normal, y el modelo hace el cambio y ejecuta sus comprobaciones (las aprobaciones se aplican como siempre). Desliza hacia la izquierda (o **✕**, o `←`) para omitirla; **Deshacer** (o `Z`) recupera una tarjeta omitida. Haz clic en **↓** (o pulsa `↓`) para guardar una buena idea para más tarde: va a la lista **Después** del proyecto, que aparece en todos los chats de la misma carpeta de proyecto (también tras un reinicio). **Después (N)** abre la lista; **Planificar** inicia el mismo chat en modo plan para la idea y **Crear ahora**, el chat sin plan; los dos la quitan de la lista. **Planificar todo (N)** inicia un solo chat en modo plan para todas las ideas de la lista, así que las partes comunes se planifican una sola vez. **Quitar de la lista** la elimina. **Copiar como lista de tareas** copia toda la lista al portapapeles como una lista de tareas de Markdown (`- [ ] Title — Summary`, una línea por idea) para un gestor de incidencias o un archivo TODO; no hace ninguna llamada de red. **Más ideas** añade tarjetas. Para recibir ideas sobre un solo tema, escribe un **Tema de enfoque** corto en el campo junto a **Sugerir funciones** (como máximo 80 caracteres; `Enter` también pide sugerencias), o haz clic en uno de los temas fijos que hay debajo: **Rendimiento**, **Accesibilidad**, **Pruebas**, **Seguridad**, **Usabilidad** o **Documentación** (haz clic otra vez para quitarlo). Entonces el modelo solo sugiere funciones sobre ese tema; un campo vacío significa cualquier función. Las ideas no se sugieren dos veces en un proyecto: cada idea sugerida (omitida, guardada o iniciada) va al **Historial** del proyecto, se le indica al modelo que no vuelva a sugerirlas y se descarta un título repetido. **Historial** las muestra como **Iniciada** o **Sugerida**; **Olvidar** (u **Olvidar todo**) deja que una vuelva a aparecer; una idea que sigue en la lista **Después** queda fuera de las sugerencias hasta que la quitas de allí. El modelo solo se ejecuta cuando haces clic. | <a href="assets/features/featureIdeas.webp"><img src="assets/features/featureIdeas.webp" width="160" alt="Captura de Ideas de funciones"></a> |
40
- | **Búsqueda en el contenido** | La búsqueda propia de la barra lateral de dsh (la lupa junto a **Espacios de trabajo**; `Cmd+K` en la app de escritorio, `Cmd+Alt+K` en un navegador) también encuentra chats por las palabras de tus mensajes y de las respuestas, no solo por el título, y muestra el texto que coincide debajo del chat. dsh ya incluye esta búsqueda, pero viene desactivada; esta función la activa con un archivo de índice de búsqueda en tu equipo. El índice se crea en la primera búsqueda después de iniciar dsh (unos 15 s para 250 chats, consulta Límites) y se conserva para los siguientes inicios. Activada de forma predeterminada; un cambio se aplica después de reiniciar dsh. | <a href="assets/features/contentSearch.webp"><img src="assets/features/contentSearch.webp" width="160" alt="Captura de Búsqueda en el contenido"></a> |
41
- | **Revertir turno** | Pasa el puntero por encima de uno de tus mensajes y haz clic en **↶** (junto a Copiar). **Solo el chat** quita ese mensaje y todo lo que viene después (respuestas, llamadas a herramientas) del chat y del contexto del modelo, y vuelve a poner el mensaje en el editor: cámbialo y envíalo de nuevo. **Chat y archivos** primero muestra los archivos del proyecto que cambiaron desde ese mensaje y después también los devuelve a su estado anterior, incluidos los cambios hechos por comandos (`bash`), no solo por las herramientas de edición de dsh. Si hay un turno en ejecución, primero se detiene. El registro del chat nunca se reescribe: un marcador oculto esconde la parte retirada, igual que el propio `/compact` de dsh esconde los mensajes antiguos. Si [dsh-rewind-plugin](https://www.npmjs.com/package/dsh-rewind-plugin) está instalado, ese plugin hace este trabajo y Composer Plus no muestra un segundo botón. | <a href="assets/features/turnRollback.webp"><img src="assets/features/turnRollback.webp" width="160" alt="Captura de Revertir turno"></a> |
42
- | **Eliminar chat** | Barra lateral → menú **…** de un chat (o clic derecho) → **Eliminar…** → **Eliminar**. dsh por sí solo solo puede archivar. El chat se detiene (su turno, sus trabajos en segundo plano, sus subagentes y sus recordatorios, igual que con el archivado propio de dsh) y su historial guardado, con los chats de sus subagentes, se mueve a la Papelera de macOS (en otros sistemas: `$DSH_HOME/trash`). Para recuperarlo, devuelve la carpeta a su sitio y reinicia dsh: aparece en la vista **Solo archivadas** de la barra lateral. | <a href="assets/features/deleteChat.webp"><img src="assets/features/deleteChat.webp" width="160" alt="Captura de Eliminar chat"></a> |
43
- | **Nombre del proyecto en el compositor** | La fila que hay debajo del editor (turnos, tokens, aciertos de caché, contexto) empieza con el nombre del proyecto del chat, así que siempre ves en qué proyecto trabaja un chat. Es el título del proyecto en dsh, o el nombre de la carpeta si el proyecto no tiene título. Pasa el puntero por encima para ver la ruta completa de la carpeta. Haz clic en él para encontrar el chat en la barra lateral, en la vista de lista o de proyectos: la barra lateral y el proyecto se abren (también un proyecto contraído y su **Mostrar más**), la lista se desplaza hasta el chat y el chat parpadea durante 5 segundos. | <a href="assets/features/projectName.webp"><img src="assets/features/projectName.webp" width="160" alt="Captura de Nombre del proyecto en el compositor"></a> |
44
- | **Historial de entrada** | Con el editor vacío, pulsa `↑` / `↓` para recorrer los mensajes que enviaste, como en una terminal. | <a href="assets/features/inputHistory.webp"><img src="assets/features/inputHistory.webp" width="160" alt="Captura de Historial de entrada"></a> |
45
- | **Modo plan con Shift+Tab** | `Shift+Tab` añade `/plan ` al principio del borrador (púlsalo otra vez para quitarlo). Si el chat ya está en modo plan, `Shift+Tab` sale de él. | <a href="assets/features/planToggle.webp"><img src="assets/features/planToggle.webp" width="160" alt="Captura de Modo plan con Shift+Tab"></a> |
46
- | **Mantener el foco en el editor** | Después de enviar un comando `/` o una skill, el cursor se queda en el editor y puedes volver a escribir enseguida. También funciona con macros de teclado que escriben un comando y pulsan `Enter`. dsh pone el editor en solo lectura mientras resuelve el comando, y entonces el navegador le quita el foco. Esta función le devuelve el foco, salvo que lo tenga un menú, un diálogo u otro campo. | <a href="assets/features/keepFocus.webp"><img src="assets/features/keepFocus.webp" width="160" alt="Captura de Mantener el foco en el editor"></a> |
47
- | **Continuar con un clic** | Después de un turno detenido, fallido o cortado, el editor vacío muestra **▶**. Un clic reanuda la conversación existente sin escribir en el campo de entrada ni añadir un mensaje visible al chat (el modelo recibe una breve nota oculta de “continúa desde donde te detuviste”, porque algunos proveedores, como Claude, rechazan una petición que termina con una respuesta del asistente). Los mensajes de la cola se quedan en ella: ▶ continúa solo la tarea detenida y después se ejecuta la cola. Un turno completado mantiene el botón normal de enviar. | <a href="assets/features/continueButton.webp"><img src="assets/features/continueButton.webp" width="160" alt="Captura de Continuar con un clic"></a> |
48
- | **Reanudar tras reiniciar** | Desactivada de forma predeterminada: actívala en **Configuración → Composer Plus**. Si sales de dsh (o se cierra) mientras un chat está trabajando, ese chat continúa solo cuando vuelves a abrir dsh, con la misma nota oculta que Continuar con un clic. Si había una ronda de un objetivo (`/goal`) en ejecución, el objetivo sigue con su siguiente ronda (dsh pausa los objetivos en cada inicio hasta que los reanudas). Los chats que detuviste, que terminaron o que fallaron no continúan. dsh no tiene ningún ajuste para esto: solo marca ese turno como interrumpido. | <a href="assets/features/resumeAfterRestart.webp"><img src="assets/features/resumeAfterRestart.webp" width="160" alt="Captura de Reanudar tras reiniciar"></a> |
49
- | **Arrastrar y soltar en la cola** | Los mensajes en cola tienen un asa (⠿). Arrástrala para reordenar, o pon el foco en el asa y pulsa `↑` / `↓`. `Esc` cancela. | <a href="assets/features/queueReorder.webp"><img src="assets/features/queueReorder.webp" width="160" alt="Captura de Arrastrar y soltar en la cola"></a> |
50
- | **Copiar enlace de sesión** | Haz clic derecho en un chat de la barra lateral → **Copiar enlace de sesión**. Pega el enlace `dsh-session:…` en otro chat para adjuntar ese chat como contexto de solo lectura. dsh 0.2.1 tiene su propia opción **Copiar ID de sesión**, que copia solo el id; esta opción aparece justo después. | <a href="assets/features/copyDeeplink.webp"><img src="assets/features/copyDeeplink.webp" width="160" alt="Captura de Copiar enlace de sesión"></a> |
51
- | **Exportar chat como Markdown** | Haz clic derecho en un chat de la barra lateral (o abre su menú **…**) → **Exportar como Markdown…**. Un diálogo muestra cuántos mensajes tiene el chat. **Copiar al portapapeles** copia el chat como Markdown y **Guardar archivo .md** lo guarda como `<chat title>.md` mediante la descarga del navegador (en la app de escritorio de dsh: en tu carpeta Descargas o con un diálogo para guardar, según la configuración de tu sistema). El archivo tiene el título del chat, el nombre del proyecto y la fecha, y después una sección `## Tú` o `## Asistente` por cada mensaje. Los bloques de código quedan como están; un bloque de código que un mensaje deja abierto se cierra. | <a href="assets/features/exportMarkdown.webp"><img src="assets/features/exportMarkdown.webp" width="160" alt="Captura de Exportar chat como Markdown"></a> |
52
- | **Copiar ruta del proyecto** | Haz clic derecho en un proyecto de la barra lateral → **Copiar ruta** copia la ruta completa de su carpeta. | <a href="assets/features/copyProjectPath.webp"><img src="assets/features/copyProjectPath.webp" width="160" alt="Captura de Copiar ruta del proyecto"></a> |
53
- | **Búsqueda de proyectos en un chat nuevo** | Chat nuevo → el botón de proyecto encima del editor. Los proyectos aparecen en orden A–Z, con un cuadro **Buscar proyectos** arriba. Escribe parte de un nombre (sin distinguir mayúsculas ni acentos) y pulsa `Enter` para elegir la primera coincidencia. Si nada coincide, aparece **Ningún proyecto coincide**. El orden de proyectos guardado de dsh en la barra lateral no cambia. | <a href="assets/features/projectPicker.webp"><img src="assets/features/projectPicker.webp" width="160" alt="Captura de Búsqueda de proyectos en un chat nuevo"></a> |
54
- | **Predicción del siguiente mensaje** | Activada de forma predeterminada; puedes desactivarla en **Configuración → Composer Plus**. Cuando el agente termina un turno (no uno detenido o fallido), el editor vacío muestra en gris una predicción de tu siguiente mensaje, con la indicación **Tab para aceptar**. `Tab` pone el texto en el editor, pero no lo envía. `Esc` la oculta durante ese turno. Si empiezas a escribir, también se oculta, y un turno nuevo la sustituye. El menú **Modelo** bajo el interruptor muestra los modelos propios de dsh (la misma lista que el menú de modelos de dsh). **Predeterminado de dsh** está seleccionado de forma predeterminada y sigue el modelo predeterminado de dsh. Cada turno terminado cuesta una llamada breve al modelo. En Tether, la predicción aparece encima del editor vacío: tócala para ponerla en el campo. | <a href="assets/features/nextPrediction.webp"><img src="assets/features/nextPrediction.webp" width="160" alt="Captura de Predicción del siguiente mensaje"></a> |
55
- | **Completar al escribir** | Desactivado de forma predeterminada; puedes activarlo en **Configuración → Composer Plus**. Mientras escribes, un texto gris justo después del cursor muestra cómo puede seguir tu mensaje. `Tab` lo añade al mensaje, pero no lo envía. `Esc` lo oculta. Solo sugiere tus propias palabras siguientes: nunca una respuesta para ti, ni textos de error o nombres inventados. Si el mensaje parece completo o el modelo no está seguro, no aparece nada. Si escribes las letras siguientes del texto gris, este se mantiene, sin una nueva llamada al modelo. Tiene su propio menú **Modelo** bajo su interruptor. Su primera opción, **Igual que la predicción del siguiente mensaje**, usa el modelo de **Predicción del siguiente mensaje** (es la opción predeterminada); elige otro modelo para usar uno distinto en cada función, por ejemplo un modelo más rápido para las compleciones. Hace una llamada al modelo en cada pausa mientras escribes, así que gasta muchos más tokens que la predicción: elige un modelo rápido y de bajo coste. No se ejecuta con un comando de barra, con un mensaje que tenga un chip de archivo ni cuando el cursor no está al final. En Tether, el resto aparece encima del campo mientras escribes: tócalo para añadirlo. | <a href="assets/features/typingCompletion.webp"><img src="assets/features/typingCompletion.webp" width="160" alt="Captura de Completar al escribir"></a> |
56
- | **Permitir en este chat** | Cuando la revisión automática te pregunta, la tarjeta de aprobación muestra **Permitir en este chat**: a partir de entonces, la misma herramienta en el mismo chat queda permitida, con cualquier argumento. Un chip en la cabecera muestra los permisos concedidos y permite revocarlos. Los permisos se mantienen tras un reinicio. | <a href="assets/features/allowForChat.webp"><img src="assets/features/allowForChat.webp" width="160" alt="Captura de Permitir en este chat"></a> |
57
- | **Estado del proyecto** | La fila de un proyecto en la barra lateral muestra el mismo indicador de en ejecución / en espera / terminado que sus chats, así que un proyecto contraído también te dice que un chat de dentro está trabajando o te necesita. Primero se muestra un chat que te espera, luego un chat terminado que aún no has abierto (el punto verde, también mientras otro chat sigue en ejecución) y luego el indicador de en ejecución. Pasa el puntero por encima para ver los detalles. | <a href="assets/features/projectStatus.webp"><img src="assets/features/projectStatus.webp" width="160" alt="Captura de Estado del proyecto"></a> |
58
- | **Proyectos activos primero** | Cuando un chat empieza a ejecutarse o te necesita, su proyecto sube al principio de la barra lateral con la animación de filas propia de dsh (el mismo movimiento que al arrastrarlo allí). Los proyectos terminados se quedan donde están; arrástralos a donde quieras, como siempre. Los movimientos se guardan en el orden de proyectos de dsh, así que al desactivar esta función se mantiene el orden actual. | <a href="assets/features/projectStatus.webp"><img src="assets/features/projectStatus.webp" width="160" alt="Captura de Proyectos activos primero"></a> |
59
- | **Filtro de proyectos recientes** | Barra lateral → opciones de vista (icono de controles deslizantes) → **Activos en las últimas 2 horas**. Mientras está seleccionado, la barra lateral solo muestra los proyectos con un chat activo en las últimas 2 horas: un chat actualizado en ese tiempo, un chat en ejecución o en espera, el chat abierto o un chat terminado que aún no has abierto (el punto verde de “terminado” de dsh), también después de las 2 horas. Los proyectos sin un chat así se ocultan, también los nuevos y vacíos. Selecciónalo otra vez para mostrar todos los proyectos. La elección se guarda en este dispositivo. | <a href="assets/features/recentProjects.webp"><img src="assets/features/recentProjects.webp" width="160" alt="Captura de Filtro de proyectos recientes"></a> |
60
- | **Contraer todos los proyectos** | Mientras hay un proyecto abierto en la barra lateral, aparece un botón junto a las opciones de vista (icono de controles deslizantes). Haz clic en él para cerrar a la vez todos los proyectos abiertos, por ejemplo 3 proyectos abiertos de 5. El botón se oculta de nuevo cuando no hay ningún proyecto abierto. | <a href="assets/features/collapseProjects.webp"><img src="assets/features/collapseProjects.webp" width="160" alt="Captura de Contraer todos los proyectos"></a> |
61
- | **Ordenar por estado** | Barra lateral → opciones de vista → **Ordenar por** → **Por estado** (con **En una sola lista**). Primero aparecen los chats terminados (el punto de “terminado” de dsh, que también recibe un turno que acabó con un error), luego los chats en ejecución o en espera, luego los chats con una automatización activa (Tareas automatizadas) y, por último, el resto en el orden de dsh. Al abrir un chat terminado, este baja. Solo cambia la vista: selecciona **Manual** o **Última actualización** para volver. | <a href="assets/features/statusOrder.webp"><img src="assets/features/statusOrder.webp" width="160" alt="Captura de Ordenar por estado"></a> |
62
- | **Notificaciones en segundo plano** | Mientras dsh está en segundo plano, recibes una notificación cuando un turno termina (la primera línea de la respuesta) o cuando un chat de verdad te espera: una aprobación (el nombre de la herramienta), una respuesta (la pregunta) o la revisión de un plan. Una solicitud tiene que seguir abierta 1,5 s después, así que las aprobaciones que se responden automáticamente (permisos de la revisión automática, otros plugins) no generan ningún aviso, y una notificación se retira en cuanto se responde su solicitud. La insignia del Dock o de la barra de tareas cuenta los chats en espera. Al hacer clic se abre ese chat. | <a href="assets/features/notifications.webp"><img src="assets/features/notifications.webp" width="160" alt="Captura de Notificaciones en segundo plano"></a> |
63
- | **11 idiomas adicionales para la interfaz** | Configuración → Composer Plus → **Idioma de la aplicación** cambia toda la interfaz de dsh a Türkçe, Español, Português (Brasil), Français, Deutsch, Русский, 日本語, 한국어, Bahasa Indonesia, Tiếng Việt o हिन्दी (consulta más abajo). | <a href="assets/features/language.webp"><img src="assets/features/language.webp" width="160" alt="Captura de los 11 idiomas adicionales para la interfaz"></a> |
64
- | **Conexión móvil (iPhone)** | Usa dsh desde tu iPhone con la app [Tether](tether/), en la misma red Wi-Fi o a través de [Tailscale](https://tailscale.com). Actívala en **Configuración → Composer Plus** (está desactivada de forma predeterminada, porque abre un puerto de red en este Mac). Después haz clic en **Conexión móvil**, abajo a la izquierda de la barra lateral: escanea el código QR con la Cámara del iPhone (toca **Open in Tether**) o con **Scan code** en Tether, toca **Connect** y haz clic en **Approve**. Primero instala Tether: sin la app, la Cámara no puede abrir el código. El teléfono muestra tus chats, envía mensajes, responde aprobaciones y preguntas, y cambia de modelo y de agente. Empareja todos los Mac que quieras: el nombre del Mac, arriba a la izquierda en la app, te permite cambiar entre ellos. | <a href="assets/features/mobileConnect.webp"><img src="assets/features/mobileConnect.webp" width="160" alt="Captura de Conexión móvil"></a> |
65
- | **Actualizaciones automáticas** | Al iniciar dsh, el plugin consulta la [última versión publicada en GitHub](https://github.com/furkancak1r/dsh-composer-plus/releases/latest). Si es más reciente y ya está en npm, instala esa versión exacta con el gestor de plugins propio de dsh (el mismo camino que Configuración → Plugins) y te avisa. **Reinicia dsh** para cargarla. **Configuración → Composer Plus → Actualizaciones de Composer Plus** muestra la versión y tiene los botones **Buscar actualizaciones** / **Actualizar ahora**. | <a href="assets/features/autoUpdate.webp"><img src="assets/features/autoUpdate.webp" width="160" alt="Captura de Actualizaciones automáticas"></a> |
40
+ | **Panel de cambios** | <a id="feature-changespanel"></a>Barra lateral derecha → `+` → **Cambios**. Elige **Sin confirmar**, **Sin preparar**, **Preparados** o **Rama** para ver los archivos cambiados con sus contadores `+/-`; haz clic en un archivo para ver su diff. **Último turno** abre la revisión propia de dsh del último turno. | <a href="assets/features/changesPanel.webp"><img src="assets/features/changesPanel.webp" width="160" alt="Captura: Panel de cambios"></a> |
41
+ | **Ideas de funciones** | <a id="feature-featureideas"></a>Barra lateral derecha → `+` → **Ideas de funciones** → **Sugerir funciones**. El modelo del propio chat lee un breve resumen del proyecto del chat (los archivos del nivel superior, el principio del README y del manifiesto, los últimos 15 commits) y sugiere hasta 8 funciones. Las muestra como un montón de tarjetas en el idioma de la interfaz de dsh. Desliza una tarjeta hacia la derecha (o haz clic en **✓**, o pulsa `→`; en todos los casos la tarjeta sale volando hacia su lado) para iniciar un nuevo chat en el mismo proyecto: empieza en modo plan con la idea como petición, así que nada cambia antes de que apruebes el plan. Para saltarte el plan, haz clic en **▶ Crear ahora** (o pulsa `↑`; la tarjeta sale volando hacia arriba): el nuevo chat empieza enseguida con la idea como una petición normal, y el modelo hace el cambio y ejecuta sus comprobaciones (las aprobaciones se aplican como siempre). Desliza hacia la izquierda (o **✕**, o `←`) para omitirla; **Deshacer** (o `Z`) recupera una tarjeta omitida. Haz clic en **↓** (o pulsa `↓`) para guardar una buena idea para más tarde: va a la lista **Después** del proyecto, que aparece en todos los chats de la misma carpeta de proyecto (también tras un reinicio). **Después (N)** abre la lista; **Planificar** inicia el mismo chat en modo plan para la idea y **Crear ahora**, el chat sin plan; los dos la quitan de la lista. **Planificar todo (N)** inicia un solo chat en modo plan para todas las ideas de la lista, así que las partes comunes se planifican una sola vez. **Quitar de la lista** la elimina. **Copiar como lista de tareas** copia toda la lista al portapapeles como una lista de tareas de Markdown (`- [ ] Title — Summary`, una línea por idea) para un gestor de incidencias o un archivo TODO; no hace ninguna llamada de red. **Más ideas** añade tarjetas. Para recibir ideas sobre un solo tema, escribe un **Tema de enfoque** corto en el campo junto a **Sugerir funciones** (como máximo 80 caracteres; `Enter` también pide sugerencias), o haz clic en uno de los temas fijos que hay debajo: **Rendimiento**, **Accesibilidad**, **Pruebas**, **Seguridad**, **Usabilidad** o **Documentación** (haz clic otra vez para quitarlo). Entonces el modelo solo sugiere funciones sobre ese tema; un campo vacío significa cualquier función. Las ideas no se sugieren dos veces en un proyecto: cada idea sugerida (omitida, guardada o iniciada) va al **Historial** del proyecto, se le indica al modelo que no vuelva a sugerirlas y se descarta un título repetido. **Historial** las muestra como **Iniciada** o **Sugerida**; **Olvidar** (u **Olvidar todo**) deja que una vuelva a aparecer; una idea que sigue en la lista **Después** queda fuera de las sugerencias hasta que la quitas de allí. El modelo solo se ejecuta cuando haces clic. | <a href="assets/features/featureIdeas.webp"><img src="assets/features/featureIdeas.webp" width="160" alt="Captura: Ideas de funciones"></a> |
42
+ | **Búsqueda en el contenido** | <a id="feature-contentsearch"></a>La búsqueda propia de la barra lateral de dsh (la lupa junto a **Espacios de trabajo**; `Cmd+K` en la app de escritorio, `Cmd+Alt+K` en un navegador) también encuentra chats por las palabras de tus mensajes y de las respuestas, no solo por el título, y muestra el texto que coincide debajo del chat. dsh ya incluye esta búsqueda, pero viene desactivada; esta función la activa con un archivo de índice de búsqueda en tu equipo. El índice se crea en la primera búsqueda después de iniciar dsh (unos 15 s para 250 chats, consulta Límites) y se conserva para los siguientes inicios. Activada de forma predeterminada; un cambio se aplica después de reiniciar dsh. | <a href="assets/features/contentSearch.webp"><img src="assets/features/contentSearch.webp" width="160" alt="Captura: Búsqueda en el contenido"></a> |
43
+ | **Revertir turno** | <a id="feature-turnrollback"></a>Pasa el puntero por encima de uno de tus mensajes y haz clic en **↶** (junto a Copiar). **Solo el chat** quita ese mensaje y todo lo que viene después (respuestas, llamadas a herramientas) del chat y del contexto del modelo, y vuelve a poner el mensaje en el editor: cámbialo y envíalo de nuevo. **Chat y archivos** primero muestra los archivos del proyecto que cambiaron desde ese mensaje y después también los devuelve a su estado anterior, incluidos los cambios hechos por comandos (`bash`), no solo por las herramientas de edición de dsh. Si hay un turno en ejecución, primero se detiene. El registro del chat nunca se reescribe: un marcador oculto esconde la parte retirada, igual que el propio `/compact` de dsh esconde los mensajes antiguos. Si [dsh-rewind-plugin](https://www.npmjs.com/package/dsh-rewind-plugin) está instalado, ese plugin hace este trabajo y Composer Plus no muestra un segundo botón. | <a href="assets/features/turnRollback.webp"><img src="assets/features/turnRollback.webp" width="160" alt="Captura: Revertir turno"></a> |
44
+ | **Eliminar chat** | <a id="feature-deletechat"></a>Barra lateral → menú **…** de un chat (o clic derecho) → **Eliminar…** → **Eliminar**. dsh por sí solo solo puede archivar. El chat se detiene (su turno, sus trabajos en segundo plano, sus subagentes y sus recordatorios, igual que con el archivado propio de dsh) y su historial guardado, con los chats de sus subagentes, se mueve a la Papelera de macOS (en otros sistemas: `$DSH_HOME/trash`). Para recuperarlo, devuelve la carpeta a su sitio y reinicia dsh: aparece en la vista **Solo archivadas** de la barra lateral. | <a href="assets/features/deleteChat.webp"><img src="assets/features/deleteChat.webp" width="160" alt="Captura: Eliminar chat"></a> |
45
+ | **Nombre del proyecto en el compositor** | <a id="feature-projectname"></a>La fila que hay debajo del editor (turnos, tokens, aciertos de caché, contexto) empieza con el nombre del proyecto del chat, así que siempre ves en qué proyecto trabaja un chat. Es el título del proyecto en dsh, o el nombre de la carpeta si el proyecto no tiene título. Pasa el puntero por encima para ver la ruta completa de la carpeta. Haz clic en él para encontrar el chat en la barra lateral, en la vista de lista o de proyectos: la barra lateral y el proyecto se abren (también un proyecto contraído y su **Mostrar N sesiones más**), la lista se desplaza hasta el chat y el chat parpadea durante 5 segundos. | <a href="assets/features/projectName.webp"><img src="assets/features/projectName.webp" width="160" alt="Captura: Nombre del proyecto en el compositor"></a> |
46
+ | **Historial de entrada** | <a id="feature-inputhistory"></a>Con el editor vacío, pulsa `↑` / `↓` para recorrer los mensajes que enviaste, como en una terminal. | <a href="assets/features/inputHistory.webp"><img src="assets/features/inputHistory.webp" width="160" alt="Captura: Historial de entrada"></a> |
47
+ | **Modo plan con Shift+Tab** | <a id="feature-plantoggle"></a>`Shift+Tab` añade `/plan ` al principio del borrador (púlsalo otra vez para quitarlo). Si el chat ya está en modo plan, `Shift+Tab` sale de él. | <a href="assets/features/planToggle.webp"><img src="assets/features/planToggle.webp" width="160" alt="Captura: Modo plan con Shift+Tab"></a> |
48
+ | **Mantener el foco en el editor** | <a id="feature-keepfocus"></a>Después de enviar un comando `/` o una skill, el cursor se queda en el editor y puedes volver a escribir enseguida. También funciona con macros de teclado que escriben un comando y pulsan `Enter`. dsh pone el editor en solo lectura mientras resuelve el comando, y entonces el navegador le quita el foco. Esta función le devuelve el foco, salvo que lo tenga un menú, un diálogo u otro campo. | <a href="assets/features/keepFocus.webp"><img src="assets/features/keepFocus.webp" width="160" alt="Captura: Mantener el foco en el editor"></a> |
49
+ | **Continuar con un clic** | <a id="feature-continuebutton"></a>Después de un turno detenido, fallido o cortado, el editor vacío muestra **▶**. Un clic reanuda la conversación existente sin escribir en el campo de entrada ni añadir un mensaje visible al chat (el modelo recibe una breve nota oculta de “continúa desde donde te detuviste”, porque algunos proveedores, como Claude, rechazan una petición que termina con una respuesta del asistente). Los mensajes de la cola se quedan en ella: ▶ continúa solo la tarea detenida y después se ejecuta la cola. Un turno completado mantiene el botón normal de enviar. | <a href="assets/features/continueButton.webp"><img src="assets/features/continueButton.webp" width="160" alt="Captura: Continuar con un clic"></a> |
50
+ | **Reanudar tras reiniciar** | <a id="feature-resumeafterrestart"></a>Desactivada de forma predeterminada: actívala en **Configuración → Composer Plus**. Si sales de dsh (o se cierra) mientras un chat está trabajando, ese chat continúa solo cuando vuelves a abrir dsh, con la misma nota oculta que Continuar con un clic. Si había una ronda de un objetivo (`/goal`) en ejecución, el objetivo sigue con su siguiente ronda (dsh pausa los objetivos en cada inicio hasta que los reanudas). Los chats que detuviste, que terminaron o que fallaron no continúan. dsh no tiene ningún ajuste para esto: solo marca ese turno como interrumpido. | <a href="assets/features/resumeAfterRestart.webp"><img src="assets/features/resumeAfterRestart.webp" width="160" alt="Captura: Reanudar tras reiniciar"></a> |
51
+ | **Arrastrar y soltar en la cola** | <a id="feature-queuereorder"></a>Los mensajes en cola tienen un asa (⠿). Arrástrala para reordenar, o pon el foco en el asa y pulsa `↑` / `↓`. `Esc` cancela. | <a href="assets/features/queueReorder.webp"><img src="assets/features/queueReorder.webp" width="160" alt="Captura: Arrastrar y soltar en la cola"></a> |
52
+ | **Copiar enlace de sesión** | <a id="feature-copydeeplink"></a>Haz clic derecho en un chat de la barra lateral → **Copiar enlace de sesión**. Pega el enlace `dsh-session:…` en otro chat para adjuntar ese chat como contexto de solo lectura. dsh 0.2.1 tiene su propia opción **Copiar ID de sesión**, que copia solo el id; esta opción aparece justo después. | <a href="assets/features/copyDeeplink.webp"><img src="assets/features/copyDeeplink.webp" width="160" alt="Captura: Copiar enlace de sesión"></a> |
53
+ | **Exportar chat como Markdown** | <a id="feature-exportmarkdown"></a>Haz clic derecho en un chat de la barra lateral (o abre su menú **…**) → **Exportar como Markdown…**. Un diálogo muestra cuántos mensajes tiene el chat. **Copiar al portapapeles** copia el chat como Markdown y **Guardar archivo .md** lo guarda como `<chat title>.md` mediante la descarga del navegador (en la app de escritorio de dsh: en tu carpeta Descargas o con un diálogo para guardar, según la configuración de tu sistema). El archivo tiene el título del chat, el nombre del proyecto y la fecha, y después una sección `## Tú` o `## Asistente` por cada mensaje. Los bloques de código quedan como están; un bloque de código que un mensaje deja abierto se cierra. | <a href="assets/features/exportMarkdown.webp"><img src="assets/features/exportMarkdown.webp" width="160" alt="Captura: Exportar chat como Markdown"></a> |
54
+ | **Copiar ruta del proyecto** | <a id="feature-copyprojectpath"></a>Haz clic derecho en un proyecto de la barra lateral → **Copiar ruta** copia la ruta completa de su carpeta. | <a href="assets/features/copyProjectPath.webp"><img src="assets/features/copyProjectPath.webp" width="160" alt="Captura: Copiar ruta del proyecto"></a> |
55
+ | **Búsqueda de proyectos en un chat nuevo** | <a id="feature-projectpicker"></a>Chat nuevo → el botón de proyecto encima del editor. Los proyectos aparecen en orden A–Z, con un cuadro **Buscar proyectos** arriba. Escribe parte de un nombre (sin distinguir mayúsculas ni acentos) y pulsa `Enter` para elegir la primera coincidencia. Si nada coincide, aparece **Ningún proyecto coincide**. El orden de proyectos guardado de dsh en la barra lateral no cambia. | <a href="assets/features/projectPicker.webp"><img src="assets/features/projectPicker.webp" width="160" alt="Captura: Búsqueda de proyectos en un chat nuevo"></a> |
56
+ | **Predicción del siguiente mensaje** | <a id="feature-nextprediction"></a>Activada de forma predeterminada; puedes desactivarla en **Configuración → Composer Plus**. Cuando el agente termina un turno (no uno detenido o fallido), el editor vacío muestra en gris una predicción de tu siguiente mensaje, con la indicación **Tab para aceptar**. `Tab` pone el texto en el editor, pero no lo envía. `Esc` la oculta durante ese turno. Si empiezas a escribir, también se oculta, y un turno nuevo la sustituye. El menú **Modelo** bajo el interruptor muestra los modelos propios de dsh (la misma lista que el menú de modelos de dsh). **Predeterminado de dsh** está seleccionado de forma predeterminada y sigue el modelo predeterminado de dsh. Cada turno terminado cuesta una llamada breve al modelo. En Tether, la predicción aparece encima del editor vacío: tócala para ponerla en el campo. | <a href="assets/features/nextPrediction.webp"><img src="assets/features/nextPrediction.webp" width="160" alt="Captura: Predicción del siguiente mensaje"></a> |
57
+ | **Completar al escribir** | <a id="feature-typingcompletion"></a>Desactivado de forma predeterminada; puedes activarlo en **Configuración → Composer Plus**. Mientras escribes, un texto gris justo después del cursor muestra cómo puede seguir tu mensaje. `Tab` lo añade al mensaje, pero no lo envía. `Esc` lo oculta. Solo sugiere tus propias palabras siguientes: nunca una respuesta para ti, ni textos de error o nombres inventados. Si el mensaje parece completo o el modelo no está seguro, no aparece nada. Si escribes las letras siguientes del texto gris, este se mantiene, sin una nueva llamada al modelo. Tiene su propio menú **Modelo** bajo su interruptor. Su primera opción, **Igual que la predicción del siguiente mensaje**, usa el modelo de **Predicción del siguiente mensaje** (es la opción predeterminada); elige otro modelo para usar uno distinto en cada función, por ejemplo un modelo más rápido para las compleciones. Hace una llamada al modelo en cada pausa mientras escribes, así que gasta muchos más tokens que la predicción: elige un modelo rápido y de bajo coste. No se ejecuta con un comando de barra, con un mensaje que tenga un chip de archivo ni cuando el cursor no está al final. En Tether, el resto aparece encima del campo mientras escribes: tócalo para añadirlo. | <a href="assets/features/typingCompletion.webp"><img src="assets/features/typingCompletion.webp" width="160" alt="Captura: Completar al escribir"></a> |
58
+ | **Mejorar prompt** | <a id="feature-promptimprove"></a>Escribe una petición aproximada y luego haz clic en la varita mágica (**Mejorar prompt**) junto al menú de modelos. Una llamada al modelo la reescribe como un prompt más claro: primero el objetivo, pasos numerados cortos cuando hay varias partes y la comprobación que hay que ejecutar. Lee este chat (sin los mensajes revertidos), el README, AGENTS.md y el manifiesto del proyecto, los archivos modificados y los archivos cuyo nombre coincide con tus palabras, y mantiene tu idioma. Nunca inventa nombres de archivo. El texto nuevo sustituye tu borrador, pero no se envía: léelo, edítalo y luego pulsa `Enter`. `Cmd/Ctrl+Z` recupera tu texto en un solo paso, y el botón (**Deshacer mejora**) también. Si escribes mientras trabaja, tu texto nuevo se mantiene. `Esc` o un segundo clic lo cancela. Tiene su propio menú **Modelo** en Configuración (predeterminado: **Igual que el modelo del chat**). No funciona con comandos de barra ni con un mensaje que tenga un chip de archivo. En Tether, la varita está junto al campo. | <a href="assets/features/promptImprove.webp"><img src="assets/features/promptImprove.webp" width="160" alt="Captura: Mejorar prompt"></a> |
59
+ | **Permitir en este chat** | <a id="feature-allowforchat"></a>Cuando la revisión automática te pregunta, la tarjeta de aprobación muestra **Permitir en este chat**: a partir de entonces, la misma herramienta en el mismo chat queda permitida, con cualquier argumento. Un chip en la cabecera muestra los permisos concedidos y permite revocarlos. Los permisos se mantienen tras un reinicio. | <a href="assets/features/allowForChat.webp"><img src="assets/features/allowForChat.webp" width="160" alt="Captura: Permitir en este chat"></a> |
60
+ | **Estado del proyecto** | <a id="feature-projectstatus"></a>La fila de un proyecto en la barra lateral muestra el mismo indicador de en ejecución / en espera / terminado que sus chats, así que un proyecto contraído también te dice que un chat de dentro está trabajando o te necesita. Primero se muestra un chat que te espera, luego un chat terminado que aún no has abierto (el punto verde, también mientras otro chat sigue en ejecución) y luego el indicador de en ejecución. Pasa el puntero por encima para ver los detalles. | <a href="assets/features/projectStatus.webp"><img src="assets/features/projectStatus.webp" width="160" alt="Captura: Estado del proyecto"></a> |
61
+ | **Proyectos activos primero** | <a id="feature-activeprojectsfirst"></a>Cuando un chat empieza a ejecutarse o te necesita, su proyecto sube al principio de la barra lateral con la animación de filas propia de dsh (el mismo movimiento que al arrastrarlo allí). Los proyectos terminados se quedan donde están; arrástralos a donde quieras, como siempre. Los movimientos se guardan en el orden de proyectos de dsh, así que al desactivar esta función se mantiene el orden actual. | <a href="assets/features/projectStatus.webp"><img src="assets/features/projectStatus.webp" width="160" alt="Captura: Proyectos activos primero"></a> |
62
+ | **Filtro de proyectos recientes** | <a id="feature-recentprojects"></a>Barra lateral → opciones de vista (icono de controles deslizantes) → **Activos en las últimas 2 horas**. Mientras está seleccionado, la barra lateral solo muestra los proyectos con un chat activo en las últimas 2 horas: un chat actualizado en ese tiempo, un chat en ejecución o en espera, el chat abierto o un chat terminado que aún no has abierto (el punto verde de “terminado” de dsh), también después de las 2 horas. Los proyectos sin un chat así se ocultan, también los nuevos y vacíos. Selecciónalo otra vez para mostrar todos los proyectos. La elección se guarda en este dispositivo. | <a href="assets/features/recentProjects.webp"><img src="assets/features/recentProjects.webp" width="160" alt="Captura: Filtro de proyectos recientes"></a> |
63
+ | **Contraer todos los proyectos** | <a id="feature-collapseprojects"></a>Mientras hay un proyecto abierto en la barra lateral, aparece un botón junto a las opciones de vista (icono de controles deslizantes). Haz clic en él para cerrar a la vez todos los proyectos abiertos, por ejemplo 3 proyectos abiertos de 5. El botón se oculta de nuevo cuando no hay ningún proyecto abierto. | <a href="assets/features/collapseProjects.webp"><img src="assets/features/collapseProjects.webp" width="160" alt="Captura: Contraer todos los proyectos"></a> |
64
+ | **Ordenar por estado** | <a id="feature-statusorder"></a>Barra lateral → opciones de vista → **Ordenar por** → **Por estado** (con **En una sola lista**). Primero aparecen los chats terminados (el punto de “terminado” de dsh, que también recibe un turno que acabó con un error), luego los chats en ejecución o en espera, luego los chats con una automatización activa (Tareas automatizadas) y, por último, el resto en el orden de dsh. Al abrir un chat terminado, este baja. Solo cambia la vista: selecciona **Manual** o **Última actualización** para volver. | <a href="assets/features/statusOrder.webp"><img src="assets/features/statusOrder.webp" width="160" alt="Captura: Ordenar por estado"></a> |
65
+ | **Notificaciones en segundo plano** | <a id="feature-notifications"></a>Mientras dsh está en segundo plano, recibes una notificación cuando un turno termina (la primera línea de la respuesta) o cuando un chat de verdad te espera: una aprobación (el nombre de la herramienta), una respuesta (la pregunta) o la revisión de un plan. Una solicitud tiene que seguir abierta 1,5 s después, así que las aprobaciones que se responden automáticamente (permisos de la revisión automática, otros plugins) no generan ningún aviso, y una notificación se retira en cuanto se responde su solicitud. La insignia del Dock o de la barra de tareas cuenta los chats en espera. Al hacer clic se abre ese chat. | <a href="assets/features/notifications.webp"><img src="assets/features/notifications.webp" width="160" alt="Captura: Notificaciones en segundo plano"></a> |
66
+ | **Idioma de la aplicación** | <a id="feature-language"></a>Configuración → Composer Plus → **Idioma de la aplicación** cambia toda la interfaz de dsh a Türkçe, Español, Português (Brasil), Français, Deutsch, Русский, 日本語, 한국어, Bahasa Indonesia, Tiếng Việt o हिन्दी (consulta más abajo). | <a href="assets/features/language.webp"><img src="assets/features/language.webp" width="160" alt="Captura: Idioma de la aplicación"></a> |
67
+ | **Conexión móvil (iPhone)** | <a id="feature-mobileconnect"></a>Usa dsh desde tu iPhone con la app [Tether](tether/), en la misma red Wi-Fi o a través de [Tailscale](https://tailscale.com). Actívala en **Configuración → Composer Plus** (está desactivada de forma predeterminada, porque abre un puerto de red en este Mac). Después haz clic en **Conexión móvil**, abajo a la izquierda de la barra lateral: escanea el código QR con la Cámara del iPhone (toca **Open in Tether**) o con **Scan code** en Tether, toca **Connect** y haz clic en **Approve**. Primero instala Tether: sin la app, la Cámara no puede abrir el código. El teléfono muestra tus chats, envía mensajes, responde aprobaciones y preguntas, y cambia de modelo y de agente. Empareja todos los Mac que quieras: el nombre del Mac, arriba a la izquierda en la app, te permite cambiar entre ellos. | <a href="assets/features/mobileConnect.webp"><img src="assets/features/mobileConnect.webp" width="160" alt="Captura: Conexión móvil (iPhone)"></a> |
68
+ | **Actualizaciones automáticas** | <a id="feature-autoupdate"></a>Al iniciar dsh, el plugin consulta la [última versión publicada en GitHub](https://github.com/furkancak1r/dsh-composer-plus/releases/latest). Si es más reciente y ya está en npm, instala esa versión exacta con el gestor de plugins propio de dsh (el mismo camino que Configuración → Plugins) y te avisa. Reinicia dsh para cargarla. **Configuración → Composer Plus → Actualizaciones de Composer Plus** muestra la versión y tiene los botones **Buscar actualizaciones** / **Actualizar ahora**. La primera vez que dsh se inicia con la nueva versión, una ventana **Novedades de Composer Plus N** muestra una vez las notas de esa versión (de la misma comprobación de actualizaciones, sin otra llamada de red); **Cerrar** o `Esc` la cierra. | <a href="assets/features/autoUpdate.webp"><img src="assets/features/autoUpdate.webp" width="160" alt="Captura: Actualizaciones automáticas"></a> |
69
+
70
+ <!-- END GENERATED FEATURES -->
66
71
 
67
72
  Los botones, la información emergente, los avisos y las notificaciones siguen el idioma elegido en dsh (consulta Idioma de la aplicación más abajo).
68
73
 
69
74
  ## Configuración
70
75
 
71
- Cada función se puede activar o desactivar por separado en **Configuración → Composer Plus** de dsh. Cada fila tiene una captura pequeña: pasa el puntero por encima para ver una vista previa más grande, o haz clic para abrirla a tamaño completo (`Esc` la cierra). El cuadro **Buscar funciones** de la parte superior filtra la página por nombre o descripción (en cualquier idioma, sin distinguir mayúsculas ni acentos); `Esc` lo vacía. Cada fila tiene un interruptor y una breve descripción. Los cambios se aplican de inmediato, sin reiniciar, y se recuerdan en ese dispositivo. Todo está activado de forma predeterminada, salvo **Conexión móvil**, **Reanudar tras reiniciar** y **Completar al escribir**. El Host de dsh guarda los interruptores de estas tres funciones y los de **Búsqueda en el contenido**, **Revertir turno** y **Predicción del siguiente mensaje**, así que se aplican a todas las ventanas y se mantienen tras un reinicio. El Host también guarda el **Modelo** elegido para **Predicción del siguiente mensaje** y el de **Completar al escribir** (por defecto **Igual que la predicción del siguiente mensaje**). **Búsqueda en el contenido** solo cambia después de reiniciar dsh (dsh la lee al iniciar); hasta entonces, su fila dice **Reinicia dsh para aplicar este cambio.**
76
+ Cada función se puede activar o desactivar por separado en **Configuración → Composer Plus** de dsh. Cada fila tiene una captura pequeña: pasa el puntero por encima para ver una vista previa más grande, o haz clic para abrirla a tamaño completo (`Esc` la cierra). El cuadro **Buscar funciones** de la parte superior filtra la página por nombre o descripción (en cualquier idioma, sin distinguir mayúsculas ni acentos); `Esc` lo vacía. Cada fila tiene un interruptor y una breve descripción. El pequeño **?** junto al nombre de una fila abre la parte de este README que describe esa función, en el README del idioma de la interfaz de dsh. Los cambios se aplican de inmediato, sin reiniciar, y se recuerdan en ese dispositivo. Todo está activado de forma predeterminada, salvo **Conexión móvil**, **Reanudar tras reiniciar** y **Completar al escribir**. El Host de dsh guarda los interruptores de estas tres funciones y los de **Búsqueda en el contenido**, **Revertir turno** y **Predicción del siguiente mensaje**, así que se aplican a todas las ventanas y se mantienen tras un reinicio. El Host también guarda el **Modelo** elegido para **Predicción del siguiente mensaje**, el de **Completar al escribir** (por defecto **Igual que la predicción del siguiente mensaje**) y el de **Mejorar prompt** (por defecto **Igual que el modelo del chat**). **Búsqueda en el contenido** solo cambia después de reiniciar dsh (dsh la lee al iniciar); hasta entonces, su fila dice **Reinicia dsh para aplicar este cambio.**
72
77
 
73
78
  <p align="center"><img src="docs/images/settings.webp" width="720" alt="Configuración → Composer Plus: búsqueda de funciones, selector de idioma, fila de actualizaciones y un interruptor por función, con una vista previa de la captura al pasar el puntero"></p>
74
79
 
@@ -120,16 +125,17 @@ Probado en dsh `0.2.0-rc.2` (escritorio y web) y `0.2.1-rc.2` (web). La CI ejecu
120
125
  - **Revertir turno:** antes de cada uno de tus mensajes, el Host toma una instantánea git de la carpeta del chat en su propio almacén, `$DSH_HOME/cache/composer-plus/rollback/<chat>.git` (carpeta solo para el propietario). Contiene copias de los archivos de esa carpeta que git ve (no de los archivos ignorados), así que es tan privado como el proyecto. Lee los objetos de tu repositorio (no copia lo que git ya tiene) y nunca escribe en el índice, el `HEAD`, las ramas, las etiquetas, el stash ni la configuración de tu repositorio; el único cambio que git hace allí es una marca de tiempo más reciente en los archivos de objetos que reutiliza (esto retrasa su limpieza con `git gc`). Una reversión con archivos solo escribe archivos normales dentro de la carpeta del chat; omite los enlaces simbólicos, las tuberías y todo lo que esté fuera de la carpeta. Nada sale de tu equipo. Puedes eliminar el almacén mientras dsh está cerrado (entonces la reversión solo funciona para el chat, hasta que haya mensajes nuevos). **Eliminar chat** también elimina el almacén de ese chat. El interruptor está en `$DSH_HOME/storages/dsh-composer-plus/rollback.json`.
121
126
  - **Exportar chat como Markdown:** la parte Host lee solo el registro propio del chat (los mismos mensajes que muestra dsh) y se los pasa a la página; no lee ningún archivo del proyecto y no envía nada por la red. El Markdown va solo a tu portapapeles o al archivo que guardas.
122
127
  - **Eliminar chat:** mueve a la Papelera las carpetas de registro propias del chat (`$DSH_HOME/sessions/<project>/<chat>`). No toca la carpeta del proyecto.
123
- - **Permitir en este chat:** los permisos concedidos se guardan en `$DSH_HOME/storages/dsh-composer-plus/grants.json` (archivo con permisos solo para el propietario). Un permiso cubre **una herramienta exacta en un chat**. Si esa herramienta puede escribir, el permiso también cubre cualquier escritura. Revócalo desde el chip de la cabecera.
128
+ - **Permitir en este chat:** los permisos concedidos se guardan en `$DSH_HOME/storages/dsh-composer-plus/grants.json` (archivo con permisos solo para el propietario). Un permiso cubre una herramienta exacta en un chat. Si esa herramienta puede escribir, el permiso también cubre cualquier escritura. Revócalo desde el chip de la cabecera.
124
129
  - La revisión automática sigue ejecutándose en cada llamada; los fallos de la revisión nunca se permiten automáticamente.
125
- - **Conexión móvil:** desactivada hasta que la actives. Mientras está activada, la parte Host ejecuta la pasarela de Tether: HTTPS en el puerto 19390, que solo acepta tu subred Wi-Fi y tu tailnet (100.64.0.0/10), y una página de emparejamiento en `127.0.0.1:19391` (solo este Mac). Un teléfono necesita un código de un solo uso del código QR (válido 5 minutos) y que hagas clic en **Approve** en el Mac. El teléfono fija el certificado de la pasarela. El Mac solo guarda un hash del token de cada teléfono (30 días, se renueva mientras se usa); **Revoke** cierra de inmediato las conexiones de ese teléfono. Los teléfonos solo pueden llamar a una lista permitida de métodos de dsh (chats, prompts, adjuntos, comandos de barra, aprobaciones, preguntas, modelos, agentes, objetivos), no a la configuración, las credenciales, el explorador de archivos ni la terminal. Datos: `$DSH_HOME/storages/dsh-composer-plus/mobile/`. Detalles: [tether/README.md](tether/README.md).
130
+ - **Conexión móvil:** desactivada hasta que la actives. Mientras está activada, la parte Host ejecuta la pasarela de Tether: HTTPS en el puerto 19390, que solo acepta tu subred Wi-Fi y tu tailnet (100.64.0.0/10), y una página de emparejamiento en `127.0.0.1:19391` (solo este Mac). Un teléfono necesita un código de un solo uso del código QR (válido 5 minutos) y que hagas clic en **Approve** en el Mac. El teléfono fija el certificado de la pasarela. El Mac solo guarda un hash del token de cada teléfono (30 días, se renueva mientras se usa); **Remove** cierra de inmediato las conexiones de ese teléfono. Los teléfonos solo pueden llamar a una lista permitida de métodos de dsh (chats, prompts, adjuntos, comandos de barra, aprobaciones, preguntas, modelos, agentes, objetivos), no a la configuración, las credenciales, el explorador de archivos ni la terminal. Datos: `$DSH_HOME/storages/dsh-composer-plus/mobile/`. Detalles: [tether/README.md](tether/README.md).
126
131
  - **Actualizaciones:** la parte Host pide a `api.github.com` la última versión publicada y a `registry.npmjs.org` esa versión exacta; no se envía nada sobre ti ni sobre tus chats. La instalación usa el gestor de plugins de dsh (`pnpm add dsh-composer-plus@<version>`; cuando dsh 0.2.1 lo rechaza para un plugin ya instalado, `pnpm add https://registry.npmjs.org/dsh-composer-plus/-/dsh-composer-plus-<version>.tgz`, y después el perfil indica esa URL como origen del plugin), así que se aplican las comprobaciones propias de dsh del registro, de los scripts y de la compatibilidad de versiones. Nunca se instalan etiquetas de prerelease ni versiones anteriores.
127
132
  - **Predicción del siguiente mensaje:** activada de forma predeterminada; desactívala en **Configuración → Composer Plus** para detener estas llamadas al modelo. Después de cada turno terminado, la parte Host envía tus propios mensajes del chat y las respuestas de texto del agente (sin salida de herramientas, sin contexto oculto ni razonamiento), como máximo unos 6.000 caracteres (la parte más reciente), al modelo elegido (el predeterminado de dsh, salvo que elijas otro). Va con los ajustes de proveedor propios de dsh, en una sola petición. No se guarda nada en el chat: la predicción no se añade al historial del chat. El interruptor y el modelo elegido están en `$DSH_HOME/storages/dsh-composer-plus/predict.json` (archivo solo para el propietario).
128
133
  - **Completar al escribir:** desactivado hasta que lo actives. Mientras está activado, en cada pausa mientras escribes, la parte Host envía el texto que llevas escrito y tus propios mensajes del chat y las respuestas de texto del agente (sin salida de herramientas, sin contexto oculto ni razonamiento), como máximo unos 3.000 caracteres del chat, al modelo elegido en **Completar al escribir** (de forma predeterminada, el modelo de **Predicción del siguiente mensaje**). Una pausa más reciente detiene la petición anterior. No se guarda nada en el chat. El interruptor está en `$DSH_HOME/storages/dsh-composer-plus/complete.json` (archivo solo para el propietario).
134
+ - **Mejorar prompt:** no se ejecuta nada hasta que haces clic en la varita mágica. Entonces la parte Host envía tu borrador, tus propios mensajes del chat y las respuestas de texto del agente (sin salida de herramientas, sin contexto oculto, sin razonamiento ni mensajes revertidos; como máximo unos 6.000 caracteres, la parte más reciente), el mismo resumen del proyecto que **Ideas de funciones** (con las mismas reglas de archivos: sin `.env*` ni archivos de claves, sin enlaces simbólicos que salgan de la carpeta, sin FIFO), las rutas que `git status` muestra como modificadas y hasta 30 rutas con seguimiento o sin seguimiento (no ignoradas) cuyos nombres comparten palabras con tu borrador, al modelo elegido en **Mejorar prompt** (de forma predeterminada, el modelo del propio chat), en una sola petición. No se envía el contenido de ningún archivo aparte de ese resumen. No se escribe nada en el chat ni en el proyecto: la respuesta solo sustituye tu borrador en el editor, y tú decides si lo envías. El modelo elegido está en `$DSH_HOME/storages/dsh-composer-plus/improve.json` (archivo solo para el propietario).
129
135
 
130
136
  ## Solución de problemas
131
137
 
132
- - **No hay notificaciones en macOS:** Ajustes del Sistema → Notificaciones → DeepSeek Harness → permitir. Elige **Alertas** para que se queden en pantalla.
138
+ - **No hay notificaciones en macOS:** Ajustes del Sistema → Notificaciones → DeepSeek Harness → permitir. Elige Alertas para que se queden en pantalla.
133
139
  - **Faltan ▶, las asas de la cola, el estado del proyecto, la opción de proyectos recientes, Contraer todos los proyectos, Copiar ruta, el cuadro de búsqueda de proyectos, la predicción del siguiente mensaje, la compleción al escribir, Permitir en este chat o el clic derecho después de actualizar dsh:** estos elementos se enganchan al HTML actual de dsh, porque dsh aún no tiene un espacio para ellos. Si dsh cambia ese marcado, se ocultan solos; nada más se rompe. Por favor, abre una [incidencia](https://github.com/furkancak1r/dsh-composer-plus/issues).
134
140
  - **«Error al actualizar» o «no se instaló desde npm»:** una copia enlazada desde una carpeta local o renombrada no puede actualizarse sola; reinstala `dsh-composer-plus` desde Configuración → Plugins. En los demás casos, el mensaje muestra la primera línea del error de pnpm; **Buscar actualizaciones** lo vuelve a intentar.
135
141
  - **Conexión móvil dice que la pasarela no está en ejecución:** "no IPv4 address on en0" significa que este Mac no tiene dirección Wi-Fi ni Ethernet; "EADDRINUSE" significa que otro dsh (u otra app) usa el puerto 19390 o 19391. Solo un dsh a la vez puede ejecutar Conexión móvil.
@@ -139,7 +145,7 @@ Probado en dsh `0.2.0-rc.2` (escritorio y web) y `0.2.1-rc.2` (web). La CI ejecu
139
145
  - **Chat y archivos aparece en gris:** el proyecto no es un repositorio git, no hay ninguna instantánea de antes de ese mensaje (el mensaje es anterior al plugin, o una de las 50 instantáneas más recientes la sustituyó), o no cambió ningún archivo.
140
146
  - **Eliminar dice que otro dsh tiene abierto este chat:** un segundo dsh que usa el mismo directorio home de dsh tiene el bloqueo del chat. Cierra esa ventana o ese dsh y vuelve a eliminarlo. Mientras tanto, el chat sigue archivado.
141
147
  - **Un chat no continuó tras un reinicio:** Reanudar tras reiniciar estaba desactivado cuando dsh se cerró, detuviste tú mismo ese turno, el turno ya había terminado (completado o fallido), el chat estaba archivado, o había más de 20 chats en ejecución (continúan los 20 más recientes).
142
- - **La instalación falla justo después de una versión nueva:** añade la versión (`dsh-composer-plus@1.11.2`); consulta la nota de instalación de más arriba.
148
+ - **La instalación falla justo después de una versión nueva:** añade la versión (`dsh-composer-plus@1.12.0`); consulta la nota de instalación de más arriba.
143
149
 
144
150
  ## Límites
145
151
 
@@ -156,7 +162,7 @@ Probado en dsh `0.2.0-rc.2` (escritorio y web) y `0.2.1-rc.2` (web). La CI ejecu
156
162
  - La cola de dsh no tiene una acción `move`, así que la parte Host del plugin mueve el propio mensaje dentro de la cola de dsh (un solo cambio, el mismo mensaje). Los mensajes con imágenes o archivos también se mueven. Solo se mueven tus propios mensajes: una ronda de un objetivo o una respuesta a una pregunta en la cola se queda donde está. Si un mensaje empieza a enviarse mientras arrastras, no se mueve nada y un aviso lo indica.
157
163
  - dsh 0.2.1 carga una actualización de inmediato cuando la nueva versión no cambia ningún ajuste de dsh; en caso contrario, y en dsh 0.2.0, reinicia dsh para cargarla. El plugin nunca reinicia dsh por ti. Los perfiles web/CLI sin el gestor de plugins de dsh solo avisan de que hay una versión nueva.
158
164
  - **Mantener el foco en el editor** solo devuelve el foco después de un comando `/` o una skill. Mientras dsh resuelve el comando, el editor queda en solo lectura unos milisegundos, así que las teclas que pulses en ese tiempo se pierden. Si el menú `/` de dsh sigue abierto, `Enter` elige la fila resaltada y no envía.
159
- - **Conexión móvil** solo funciona en macOS (usa `en0`, `openssl`, `swift` y `dns-sd`). Usa los puertos fijos 19390 y 19391, así que solo un dsh por Mac puede ejecutarla a la vez (cada Mac es una entrada en la lista de Mac del teléfono). El teléfono solo recibe notificaciones mientras Tether está abierta o acaba de pasar a segundo plano (no hay servicio push). La app de iOS aún no está en la App Store: compílala desde `tether/ios` con Xcode.
165
+ - **Conexión móvil** solo funciona en macOS (usa `en0`, `openssl`, `swift` y `dns-sd`). Usa los puertos fijos 19390 y 19391, así que solo un dsh por Mac puede ejecutarla a la vez (cada Mac es una entrada en la lista de Mac del teléfono). El teléfono solo recibe notificaciones mientras Tether está abierta o acaba de pasar a segundo plano (no hay servicio push). La app de iOS aún no está en la App Store: compílala desde `tether/ios` con Xcode. Los puntos verdes de Tether siguen al Mac: un chat que abres en dsh también pierde su punto en el teléfono. Un chat que abres en Tether pierde su punto solo en los teléfonos. El punto propio de dsh en el Mac se queda hasta que abres el chat allí.
160
166
  - Un enlace de sesión funciona dentro de los chats; hacer clic en él no abre el chat.
161
167
  - Al hacer clic en una notificación enviada antes de un reinicio, solo se trae dsh al frente.
162
168
  - Los proyectos activos se mueven con el orden de proyectos guardado de dsh, así que el nuevo orden se mantiene tras un reinicio. Los chats que no pertenecen a ningún proyecto («Sin agrupar») no se pueden mover; dsh siempre los muestra al final.
@@ -165,6 +171,7 @@ Probado en dsh `0.2.0-rc.2` (escritorio y web) y `0.2.1-rc.2` (web). La CI ejecu
165
171
  - dsh tampoco tiene un punto de extensión en el menú de proyectos de un chat nuevo, así que el cuadro **Buscar proyectos** y el orden A–Z se enganchan al marcado del menú de dsh. Si una actualización de dsh cambia ese marcado, el menú aparece tal como lo dibuja dsh: en el orden guardado y sin el cuadro. El orden A–Z es solo una vista: no cambia el orden de proyectos guardado de dsh.
166
172
  - dsh tampoco tiene un punto de extensión para una indicación en el editor, así que el texto de **Predicción del siguiente mensaje** se coloca sobre el texto de ejemplo propio de dsh (`[data-composer-placeholder]`). Si una actualización de dsh cambia ese marcado, no aparece ninguna predicción. Mientras está activada, cada turno terminado cuesta una llamada breve al modelo.
167
173
  - **Completar al escribir** muestra su texto mediante la indicación propia del editor de dsh (el estilo `--dsh-composer-hint` que dsh usa para la indicación del argumento de un comando de barra). No se ejecuta con un comando de barra, con un mensaje que tenga un chip de archivo o de símbolo ni cuando el cursor no está al final del mensaje. Si una actualización de dsh cambia ese estilo, no aparece ninguna compleción. Cada pausa mientras escribes cuesta una llamada al modelo.
174
+ - **Mejorar prompt** solo ve un breve resumen del proyecto, las rutas modificadas y las rutas cuyos nombres coinciden con tus palabras: no el código en sí. Por eso puede pasar por alto el archivo correcto, y solo nombra rutas que recibió. Lee el texto nuevo antes de enviarlo. No se ejecuta con un comando de barra ni con un mensaje que tenga un chip de archivo o de símbolo (el texto nuevo es texto plano, así que perdería el chip), y un mensaje puede tener como máximo 8.000 caracteres. Las imágenes siguen adjuntas: solo cambia el texto. Cada clic cuesta una llamada al modelo; un modelo potente puede tardar un minuto (`Esc` lo cancela).
168
175
  - Se ha pedido soporte integrado en el proyecto original: `move` para la cola en [#773](https://github.com/deepseek-ai/deepseek-harness/discussions/773) y un estado de Continuar en [#9269](https://github.com/deepseek-ai/deepseek-harness/discussions/9269).
169
176
 
170
177
  ## Preguntas frecuentes
@@ -189,6 +196,8 @@ Probado en dsh `0.2.0-rc.2` (escritorio y web) y `0.2.1-rc.2` (web). La CI ejecu
189
196
 
190
197
  **¿Qué modelo escribe la predicción?** El modelo que eliges en **Configuración → Composer Plus → Predicción del siguiente mensaje → Modelo**. La lista es la propia lista de modelos de dsh. **Predeterminado de dsh** sigue el modelo predeterminado de dsh. Si dsh ya no muestra el modelo elegido, la predicción usa el predeterminado. **Completar al escribir** tiene su propio menú **Modelo**: **Igual que la predicción del siguiente mensaje** (la opción predeterminada) sigue el modelo de la predicción; otra opción se usa solo para las compleciones. Si dsh ya no muestra ese modelo, las compleciones usan el modelo de la predicción.
191
198
 
199
+ **¿Puede dsh mejorar mi prompt antes de enviarlo, como el botón Enhance prompt de Roo Code o Augment?** Sí, con **Mejorar prompt** (activado de forma predeterminada): escribe una petición aproximada y haz clic en la varita mágica junto al menú de modelos. Reescribe el texto con este chat y el proyecto como contexto, en tu idioma, y no lo envía. `Cmd/Ctrl+Z` o **Deshacer mejora** recuperan tu texto. Elige su modelo en **Configuración → Composer Plus → Mejorar prompt → Modelo**.
200
+
192
201
  **¿Cómo reordeno los mensajes en cola en dsh?** Arrastra el asa ⠿ de un mensaje en cola, o pon el foco en ella y pulsa `↑` / `↓`.
193
202
 
194
203
  **¿Cómo evito que la revisión automática pregunte por la misma herramienta en un chat?** Haz clic en **Permitir en este chat** en la tarjeta de aprobación. Solo cubre esa herramienta exacta en ese chat; revoca el permiso desde el chip de la cabecera.
@@ -219,8 +228,12 @@ SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-sidebar-projects.mjs /pa
219
228
  PLAYWRIGHT=/path/to/playwright node test/browser-recent-finished.mjs /path/to/dsh/lib/bin.js
220
229
  # Order by status (fake model + Schedule): real-app test + its thumbnail
221
230
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-status-order.mjs /path/to/dsh/lib/bin.js
222
- # every Settings feature row shows a loading screenshot
231
+ # every Settings feature row shows a loading screenshot and a ? link to its README row
223
232
  PLAYWRIGHT=/path/to/playwright node test/browser-settings-shots.mjs /path/to/dsh/lib/bin.js
233
+ # What's new after an update: the release notes show once, Esc and Close close them
234
+ PLAYWRIGHT=/path/to/playwright node test/browser-whats-new.mjs /path/to/dsh/lib/bin.js
235
+ # README feature anchors (the ? links) on github.com, headless: each #feature-… shows the start of its row
236
+ PLAYWRIGHT=/path/to/playwright node test/browser-readme-anchors.mjs
224
237
  # Keep composer focus (fake model + demo skill): typing goes on after a / command + its thumbnail
225
238
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-keep-focus.mjs /path/to/dsh/lib/bin.js
226
239
  # Mobile connect: switch on, QR popover, a fake iPhone pairs and calls dsh through the gateway, switch off + its thumbnail
@@ -235,14 +248,17 @@ SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-export-markdown.mjs /pat
235
248
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-content-search.mjs /path/to/dsh/lib/bin.js
236
249
  # Turn rollback + Delete chat (fake model, made-up git project): bash edit → ↶ Chat and files → files back, .git unchanged; Delete… → Trash + its thumbnails
237
250
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-turn-rollback.mjs /path/to/dsh/lib/bin.js
251
+ # Improve prompt (fake model, made-up git project): the wand sends the draft with the chat and the project, the answer replaces the draft, Cmd+Z and Undo bring it back + its thumbnail
252
+ SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-prompt-improve.mjs /path/to/dsh/lib/bin.js
238
253
  ```
239
254
 
240
255
  ```sh
241
256
  npm run build:locales # after editing locales/<id>.json
257
+ npm run build:readme # after editing docs/features.json
242
258
  npm test
243
259
  ```
244
260
 
245
- **Regla para las funciones nuevas:** cada fila de función en Configuración → Composer Plus muestra una captura. Añade el id de la función a `SHOT_OF` en `client.js` y a `SHOTS` en `index.js`, e incluye `assets/features/<id>.webp` (tomada del dsh de demostración desechable, con la interfaz en inglés, de unos 60 kB o menos). Añade la función a la tabla del README con la misma imagen, en `README.md` y en cada `README.<id>.md` traducido. `test/shots.test.mjs` falla cuando una función no tiene captura, y `test/browser-settings-shots.mjs` comprueba la página de Configuración real. La lista completa de comprobaciones para cada cambio está en [AGENTS.md](AGENTS.md).
261
+ **Regla para las funciones nuevas:** cada fila de función en Configuración → Composer Plus muestra una captura. Añade el id de la función a `SHOT_OF` en `client.js` y a `SHOTS` en `index.js`, e incluye `assets/features/<id>.webp` (tomada del dsh de demostración desechable, con la interfaz en inglés, de unos 60 kB o menos). Añade la función, con la misma imagen, a `docs/features.json` y ejecuta `npm run build:readme`: escribe la tabla de funciones de `README.md` y de cada `README.<id>.md` traducido, y la lista de `llms.txt`. `test/shots.test.mjs` falla cuando una función no tiene captura, y `test/browser-settings-shots.mjs` comprueba la página de Configuración real. La lista completa de comprobaciones para cada cambio está en [AGENTS.md](AGENTS.md).
246
262
 
247
263
  Las pruebas ejecutan el `client.js` real contra un React/DOM falso, y el `index.js` real (la parte Host) contra un repositorio git temporal. Las pruebas de la pasarela de Tether (`test/tether-gateway.test.mjs`) usan un host de dsh simulado y una pasarela TLS real. La app de iPhone está en `tether/ios` (consulta [tether/README.md](tether/README.md) y [tether/AGENTS.md](tether/AGENTS.md)). `node test/browser-history.mjs '<dsh web URL with ?token=…>'` comprueba el historial de entrada en un navegador real contra un `dsh web` desechable con su propio `DSH_HOME`.
248
264