dsh-composer-plus 1.16.1 → 1.18.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
@@ -29,7 +29,7 @@ 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.16.1`.
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.18.0`.
33
33
 
34
34
  ## Funciones
35
35
 
@@ -47,6 +47,7 @@ Después, reinicia dsh. (La CLI no puede instalar en el perfil de escritorio: de
47
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
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
49
  | **Ajustar la tarjeta de pregunta a la ventana** | <a id="feature-questionfit"></a>Cuando el agente te hace una pregunta, la pregunta y sus respuestas se desplazan juntas en la tarjeta, y **Omitir** y **Enviar** siguen a la vista abajo. La tarjeta usa la altura de la ventana (menos 200 px para la cabecera del chat y una franja del chat), así que crece y se reduce con la ventana. Sin esta función, dsh limita la tarjeta al 60 % de la ventana (520 px como máximo) y solo se desplazan las respuestas: una pregunta larga puede dejar fuera de la tarjeta su propio final, las respuestas y los botones. | <a href="assets/features/questionFit.webp"><img src="assets/features/questionFit.webp" width="160" alt="Captura: Ajustar la tarjeta de pregunta a la ventana"></a> |
50
+ | **Ajustar la cabecera del chat a la ventana** | <a id="feature-headerfit"></a>En una ventana estrecha, los botones de la cabecera del chat de dsh (el modo, los subagentes, los trabajos en segundo plano, Abrir en, la etiqueta de rama y la etiqueta de permisos) ya no se tapan entre sí. El título del chat conserva al menos 120 px; los botones que no caben pasan a una segunda línea a la derecha, y todos se pueden pulsar. Cuando todo cabe en una línea (una ventana ancha), la cabecera es exactamente la de dsh. Sin esta función, dsh solo encoge el título: con un subagente y trabajos en segundo plano, sus botones se superponen en una columna de chat estrecha. La etiqueta de rama (**Una rama por chat**) y la de permisos (**Permitir en este chat**) también se ajustan a la cabecera con este interruptor apagado. | <a href="assets/features/headerFit.webp"><img src="assets/features/headerFit.webp" width="160" alt="Captura: Ajustar la cabecera del chat a la ventana"></a> |
50
51
  | **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> |
51
52
  | **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> |
52
53
  | **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> |
@@ -63,19 +64,25 @@ Después, reinicia dsh. (La CLI no puede instalar en el perfil de escritorio: de
63
64
  | **Ramas en el árbol de espacios de trabajo** | <a id="feature-branchtree"></a>Configuración → Composer Plus → **Ramas en el árbol de espacios de trabajo** (desactivado por defecto). Cada rama que tiene una carpeta de worktree en `<project>/.worktrees/` aparece entonces como un proyecto dentro de su proyecto; elige **Opciones de vista** → **Árbol de espacios de trabajo** de dsh para verla anidada. Una rama cuya carpeta se borra sale de la lista, y dsh muestra sus chats en **Sin agrupar**. Cuando el agente de un chat en la carpeta del proyecto crea una rama y cambia a ella (`git switch -c`, `git checkout -b`) sin cambios sin confirmar en la carpeta, la carpeta del proyecto vuelve a su rama anterior, la rama recibe su propia carpeta y el chat se mueve allí: una copia se abre en el proyecto de la rama y sigue con la tarea, y el chat anterior se archiva. La lista se revisa al iniciar, cada 30 segundos, después de cada turno y cuando vuelves a la ventana. | <a href="assets/features/branchTree.webp"><img src="assets/features/branchTree.webp" width="160" alt="Captura: Ramas en el árbol de espacios de trabajo"></a> |
64
65
  | **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> |
65
66
  | **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> |
66
- | **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> |
67
- | **Comprobación del objetivo** | <a id="feature-goalcheck"></a>Empieza un objetivo con `/goal`. Cuando el agente marca el objetivo como completado en una ronda automática, el objetivo solo se cierra tras dos comprobaciones. Primero, el comando de prueba del proyecto se ejecuta en la carpeta del chat, con el modo sandbox del chat. El comando es el tuyo o el que se encuentra en `package.json`, `Makefile`, `Cargo.toml`, `go.mod` o pytest. Si el paso más reciente del propio agente fue una ejecución correcta de esa prueba, no se vuelve a ejecutar. Después, una llamada independiente al modelo, sin herramientas, lee el objetivo, este chat, `git status` y el resultado de la prueba. Si una comprobación falla, el objetivo sigue activo y el agente lee el motivo; luego continúa la ronda siguiente. Una fila bajo la barra del objetivo (**Comprobación del objetivo**) muestra la prueba y el último resultado. **Editar** define tu propio comando de prueba y un límite de tiempo o de tokens; al superar el límite, el objetivo queda bloqueado. **Ejecutar ahora** ejecuta la comprobación sin cerrar el objetivo. Tiene su propio menú **Modelo** en Configuración (predeterminado: **Igual que el modelo del chat**). Cuando completas el objetivo tú mismo, no se comprueba nada. | <a href="assets/features/goalCheck.webp"><img src="assets/features/goalCheck.webp" width="160" alt="Captura: Comprobación del objetivo"></a> |
68
- | **Memoria del proyecto** | <a id="feature-projectmemory"></a>Desactivada de forma predeterminada: actívala en **Configuración → Composer Plus**. Cada carpeta de proyecto tiene su propia memoria, que los chats posteriores de ese proyecto leen, como DS Bot guarda una por Bot. Después de cada turno terminado, una llamada al modelo del chat lee los mensajes nuevos (no los revertidos), guarda tus preferencias, decisiones y datos duraderos como notas breves, y cambia o elimina las antiguas. El agente también puede guardar, eliminar y buscar notas por sí mismo (`memory_remember`, `memory_forget`, `memory_recall`). Una nota también puede ser global: todos los proyectos la leen. Un chat nuevo recibe las notas en su prompt de sistema; una nota guardada después aparece desde el chat siguiente. Los archivos son Markdown en la carpeta de inicio de dsh (`storages/dsh-composer-plus/memory/`), nunca en la carpeta del proyecto. | <a href="assets/features/projectMemory.webp"><img src="assets/features/projectMemory.webp" width="160" alt="Captura: Memoria del proyecto"></a> |
67
+ | **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**). En un mensaje `/goal <objective>` solo reescribe el objetivo, como una condición de finalización que **Comprobación del objetivo** puede verificar: los resultados, las comprobaciones que deben pasar, la evidencia que hay que mostrar en el chat, una parte que no se puede hacer marcada como sin resolver y una parada cuando el mismo bloqueo persiste. El comando `/goal` se mantiene. No funciona con otros comandos de barra, con una palabra de control de `/goal` (`clear`, `pause`, `resume`) 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> |
68
+ | **Comprobación del objetivo** | <a id="feature-goalcheck"></a>Empieza un objetivo con `/goal`. Cuando el agente marca el objetivo como completado en una ronda automática, el objetivo solo se cierra tras dos comprobaciones. Primero, el comando de prueba del proyecto se ejecuta en la carpeta del chat, con el modo sandbox del chat. El comando es el tuyo o el que se encuentra en `package.json`, `Makefile`, `Cargo.toml`, `go.mod` o pytest. Si el paso más reciente del propio agente fue una ejecución correcta de esa prueba, no se vuelve a ejecutar. Después, una llamada independiente al modelo, sin herramientas, lee el objetivo, este chat, `git status` y el resultado de la prueba. El modelo responde con una tabla de evidencias: cada parte del objetivo queda verificada, incorrecta o sin resolver, con la evidencia y la corrección; el objetivo solo se cierra cuando todas las partes están verificadas. Si una comprobación falla, el objetivo sigue activo y el agente lee cada parte abierta con su evidencia y su corrección; luego continúa la ronda siguiente. Una fila bajo la barra del objetivo (**Comprobación del objetivo**) muestra la prueba, el último resultado y cuántas partes se verificaron (pasa el puntero por encima para ver la tabla). **Editar** define tu propio comando de prueba y un límite de tiempo o de tokens; al superar el límite, el objetivo queda bloqueado. El límite de tokens también cuenta los subagentes del chat. **Ejecutar ahora** ejecuta la comprobación sin cerrar el objetivo. Tiene su propio menú **Modelo** en Configuración (predeterminado: **Igual que el modelo del chat**). Cuando completas el objetivo tú mismo, no se comprueba nada. | <a href="assets/features/goalCheck.webp"><img src="assets/features/goalCheck.webp" width="160" alt="Captura: Comprobación del objetivo"></a> |
69
+ | **Continuar en un chat nuevo** | <a id="feature-handoffchat"></a>Haz clic derecho en un chat de la barra lateral (o abre su menú **…**) → **Continuar en un chat nuevo…**. Una llamada al propio modelo del chat escribe una nota de traspaso con lo que muestra el chat: Tarea, Resultados, Completado, Decisiones, Problemas abiertos y Siguiente acción (las llamadas a herramientas y sus resultados son la evidencia; los pasos que revertiste se omiten). La nota se abre en un diálogo: léela y edítala. **Volver a escribir** escribe una nota nueva. **Iniciar chat nuevo** (o `Cmd/Ctrl+Enter`) abre un chat nuevo en el mismo proyecto con la nota y un enlace al chat anterior como primer mensaje; el chat anterior queda como está. Úsalo cuando un chat largo esté lleno o lento, o para continuar mañana. No se escribe nada en el proyecto. | <a href="assets/features/handoffChat.webp"><img src="assets/features/handoffChat.webp" width="160" alt="Captura: Continuar en un chat nuevo"></a> |
70
+ | **Desglose del contexto** | <a id="feature-contextbreakdown"></a>Barra lateral derecha → `+` → **Contexto**. La página muestra qué llena ahora el contexto del modelo del chat abierto y cuánto de la ventana de contexto usa: el prompt del sistema, las instrucciones del proyecto (AGENTS.md), las skills, tus mensajes, las respuestas del agente y las llamadas a herramientas, los resultados de herramientas (por herramienta), los resultados de MCP (por servidor), las definiciones de herramientas, el resumen de compactación y otras notas de contexto, cada uno con sus tokens y su parte. Haz clic en una parte para ver sus herramientas o servidores. Solo lee el registro del chat, después de `/compact` y de las reversiones, y no llama a ningún modelo; vuelve a leerlo después de cada turno y con **Actualizar**. Úsalo para ver por qué un chat está lento o lleno, por ejemplo por un resultado grande de una herramienta MCP o por muchas definiciones de herramientas. | <a href="assets/features/contextBreakdown.webp"><img src="assets/features/contextBreakdown.webp" width="160" alt="Captura: Desglose del contexto"></a> |
71
+ | **Pasos planificados** | <a id="feature-plannedsteps"></a>Desactivada de forma predeterminada: actívala en **Configuración → Composer Plus**. El agente recibe la herramienta `plan_next_steps`: en el mismo mensaje que un comando, puede planificar los siguientes comandos con sus argumentos exactos y una condición, por ejemplo «ejecuta `npm test` cuando la compilación pase». Cuando el resultado cumple la condición, Composer Plus ejecuta el siguiente paso por sí mismo, sin una nueva llamada al modelo, así un chat largo usa menos tokens. El paso aparece en el chat como una línea corta, «Composer Plus · Planned steps: ran `test` … without a model call», seguida de su llamada a la herramienta y su resultado. Solo pasos de `bash`, `read`, `grep` y `glob`; las aprobaciones, el sandbox y Archivos protegidos se aplican a cada paso como siempre. El modelo vuelve a responder cuando una condición falla, cuando dos pasos están listos a la vez, después del último paso y cuando envías un mensaje. La idea viene de HarnessMM (arXiv 2610.32813). | <a href="assets/features/plannedSteps.webp"><img src="assets/features/plannedSteps.webp" width="160" alt="Captura: Pasos planificados"></a> |
72
+ | **Archivos protegidos** | <a id="feature-protectedfiles"></a>Activado de forma predeterminada. Las herramientas de archivos propias del agente no pueden leer ni cambiar los archivos que coinciden con tus patrones: `read`, `read_image` y `grep` sobre un archivo se rechazan con los patrones de **lectura y escritura**, y `write`, `edit` y `str_replace_editor` con los dos tipos. El agente lee el motivo y se le indica que te pregunte. Los patrones predeterminados son `.env*`, `*.pem` y `*.key`. Configuración → Composer Plus → **Archivos protegidos**: añade un patrón (por ejemplo `published/**` o `config/*.yml`), haz clic en su tipo para cambiar entre **lectura y escritura** y **solo escritura**, quítalo con ✕ o haz clic en **Usar los valores predeterminados**. Un patrón sin `/` coincide con un nombre de archivo en cualquier carpeta. Es una barrera de protección, no un sandbox: un comando de shell (`cat .env`), un script o una herramienta MCP aún pueden llegar al archivo (consulta Límites). | <a href="assets/features/protectedFiles.webp"><img src="assets/features/protectedFiles.webp" width="160" alt="Captura: Archivos protegidos"></a> |
73
+ | **Comandos bloqueados** | <a id="feature-blockedcommands"></a>Activado de forma predeterminada, con una lista vacía. Los comandos de shell del agente (`bash`, `pwsh`) no pueden ejecutar un comando que coincida con tus reglas: una regla **bloquear** rechaza la llamada (el agente lee el motivo y se le indica que te pregunte), una regla **preguntar antes** muestra la tarjeta de aprobación de dsh, y el comando solo se ejecuta cuando tú lo permites. Configuración → Composer Plus → **Comandos bloqueados**: escribe una regla (por ejemplo `npm publish`, `git push --force` o `ssh *192.168.2.19`), haz clic en el tipo para cambiar entre **bloquear** y **preguntar antes** y luego haz clic en **Añadir**; haz clic en el tipo de una regla para cambiarlo y quítala con ✕. Una regla es un nombre de comando y palabras que deben venir después de él en este orden; `*` coincide con cualquier texto. La comprobación también encuentra el comando después de `&&`, `;`, `\|`, dentro de `$(…)`, `bash -c "…"` o `eval`, y después de `sudo` o `env`. Es una barrera de protección, no un sandbox: una variable (`$CMD`), un archivo de script u otro programa aún pueden ejecutar el comando (consulta Límites). | <a href="assets/features/blockedCommands.webp"><img src="assets/features/blockedCommands.webp" width="160" alt="Captura: Comandos bloqueados"></a> |
74
+ | **Tablero de tareas** | <a id="feature-taskboard"></a>Barra lateral izquierda → **Tablero de tareas**. Un tablero kanban de tus proyectos de dsh, para ti y para los agentes: **Por hacer**, **En curso**, **En revisión** y **Hecho** (y **En espera**, ver abajo). Elige un proyecto o **Todos los proyectos** a la izquierda. **Nueva tarea** (o `n`) abre una tarjeta nueva: escribe su título y pulsa `Enter`. Arrastra una tarjeta a otra columna o entre dos tarjetas. Haz clic en una tarjeta para ver y cambiar su **Estado**, sus **Etiquetas**, **Manual** (los agentes la omiten), la descripción (Markdown) y los comentarios. `/` busca en todos los proyectos, `h` muestra solo las tareas manuales y el botón de exportar guarda el tablero como Markdown o JSON. Los agentes reciben herramientas del tablero: pide a un chat que "tome la siguiente tarea del tablero" y moverá la primera tarjeta de **Por hacer** a **En curso**, comentará lo que hizo y la moverá a **En revisión**; tú la mueves a **Hecho**. En un proyecto con tareas abiertas, cada chat recibe esta regla por sí solo. Configuración → Composer Plus → **Tablero de tareas** tiene el interruptor de la columna **En espera**: los agentes te dejan sus tarjetas a ti. | <a href="assets/features/taskBoard.webp"><img src="assets/features/taskBoard.webp" width="160" alt="Captura: Tablero de tareas"></a> |
75
+ | **Memoria del proyecto** | <a id="feature-projectmemory"></a>Desactivada de forma predeterminada: actívala en **Configuración → Composer Plus**. Cada carpeta de proyecto tiene su propia memoria, que los chats posteriores de ese proyecto leen, como DS Bot guarda una por Bot. Después de cada turno terminado, una llamada al modelo del chat lee los mensajes nuevos (no los revertidos), guarda tus preferencias, decisiones y datos duraderos como notas breves, y cambia o elimina las antiguas. El agente también puede guardar, eliminar y buscar notas por sí mismo (`memory_remember`, `memory_forget`, `memory_recall`). Una nota también puede ser global: todos los proyectos la leen. Un chat nuevo recibe las notas en su prompt de sistema; una nota guardada después aparece desde el chat siguiente. Los archivos son Markdown en la carpeta de inicio de dsh (`storages/dsh-composer-plus/memory/`), nunca en la carpeta del proyecto. **Abrir memoria**, en la misma fila, muestra todas las notas guardadas agrupadas por proyecto (y la memoria global), con un filtro. Escribe con tus palabras qué cambiar (por ejemplo "cambié yarn por pnpm") y pulsa **Vista previa de los cambios**: el modelo predeterminado de dsh propone los cambios y solo **Aplicar** los guarda. En Tether: menú del título del chat → Project memory. | <a href="assets/features/projectMemory.webp"><img src="assets/features/projectMemory.webp" width="160" alt="Captura: Memoria del proyecto"></a> |
69
76
  | **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, hasta que termina el límite de tiempo (1 hora por defecto; elígelo en **Configuración → Composer Plus → Permitir en este chat**). Después, el agente vuelve a preguntar. Un chip en la cabecera muestra los permisos concedidos con su hora de fin 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> |
70
77
  | **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. En **Árbol de espacios de trabajo**, la fila de una carpeta superior también muestra los chats de cada proyecto que contiene (por ejemplo, cada carpeta de rama en `.worktrees/`), también cuando está contraída. | <a href="assets/features/projectStatus.webp"><img src="assets/features/projectStatus.webp" width="160" alt="Captura: Estado del proyecto"></a> |
71
- | **Rama de Git en las filas de chat** | <a id="feature-sessionbranch"></a>Cada fila de chat de la barra lateral muestra una pequeña etiqueta gris con la rama de git en la que estaba la carpeta del proyecto del chat en su último turno (por ejemplo `main` o `feature/login`; un HEAD separado muestra su id de commit corto entre paréntesis). Dos chats de un mismo proyecto en ramas distintas ya no se ven iguales, y ves enseguida cuándo vas a continuar un chat en la rama equivocada. Pasa el puntero por la etiqueta para ver el nombre completo. La parte Host lee la rama (`git branch --show-current`, solo lectura) cuando un turno empieza y cuando termina; un chat sin turnos desde que instalaste esto, o una carpeta que no es un repositorio git, no muestra etiqueta. Si la fila de proyecto sobre el chat tiene el mismo nombre que la rama (por ejemplo, una carpeta de «Una rama por chat»), la fila del chat no muestra la etiqueta, pero «En una sola lista» sí la muestra. | <a href="assets/features/sessionBranch.webp"><img src="assets/features/sessionBranch.webp" width="160" alt="Captura: Rama de Git en las filas de chat"></a> |
78
+ | **Rama de Git en las filas de chat** | <a id="feature-sessionbranch"></a>Cada fila de chat de la barra lateral muestra una pequeña etiqueta gris con la rama de git en la que estaba la carpeta del proyecto del chat en su último turno (por ejemplo `main` o `feature/login`; un HEAD separado no tiene rama y no muestra etiqueta). Dos chats de un mismo proyecto en ramas distintas ya no se ven iguales, y ves enseguida cuándo vas a continuar un chat en la rama equivocada. Pasa el puntero por la etiqueta para ver el nombre completo. La parte Host lee la rama (`git branch --show-current`, solo lectura) cuando un turno empieza y cuando termina; un chat sin turnos desde que instalaste esto, o una carpeta que no es un repositorio git, no muestra etiqueta. Si la fila de proyecto sobre el chat tiene el mismo nombre que la rama (por ejemplo, una carpeta de «Una rama por chat»), la fila del chat no muestra la etiqueta, pero «En una sola lista» sí la muestra. | <a href="assets/features/sessionBranch.webp"><img src="assets/features/sessionBranch.webp" width="160" alt="Captura: Rama de Git en las filas de chat"></a> |
72
79
  | **Marcar todo como leído** | <a id="feature-markprojectread"></a>En la barra lateral, haz clic en el botón **…** de un proyecto → **Marcar todo como leído**. Todos los chats de ese proyecto pierden su punto verde de no leído a la vez; los demás proyectos conservan los suyos. La opción aparece en gris (**No hay chats sin leer**) cuando el proyecto no tiene ninguno. | <a href="assets/features/markProjectRead.webp"><img src="assets/features/markProjectRead.webp" width="160" alt="Captura: Marcar todo como leído"></a> |
73
80
  | **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> |
74
81
  | **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. En **Árbol de espacios de trabajo**, una carpeta superior sigue visible mientras un proyecto dentro de ella está activo, y los chats que no estuvieron activos en las últimas 2 horas también se ocultan, así que solo se muestran los chats recientes. 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> |
75
82
  | **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> |
76
83
  | **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> |
77
84
  | **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> |
78
- | **Abrir el chat en espera si estás inactivo** | <a id="feature-idleswitch"></a>Cuando un chat hace una pregunta o espera una aprobación o una revisión del plan (el punto naranja) y no usas dsh durante 30 segundos, dsh abre ese chat. Si esperan varios chats, primero se abre el que lleva más tiempo esperando; el siguiente se abre tras otros 30 segundos sin uso. Una tecla, un clic, un movimiento del ratón, la rueda de desplazamiento o un toque reinician los 30 segundos. Texto en el campo con el foco, texto seleccionado o un menú o diálogo abierto también detienen el cambio. Mientras un chat en espera está en pantalla, nada cambia. Si sales de un chat en espera sin responder, puede volver a abrirse tras los siguientes 30 segundos sin uso. También funciona con dsh en segundo plano, pero dsh no pasa al frente. | <a href="assets/features/idleSwitch.webp"><img src="assets/features/idleSwitch.webp" width="160" alt="Captura: Abrir el chat en espera si estás inactivo"></a> |
85
+ | **Abrir el chat en espera si estás inactivo** | <a id="feature-idleswitch"></a>Cuando un chat hace una pregunta, espera una aprobación o una revisión del plan (el punto naranja) o termina un turno que aún no has leído (el punto verde), y no usas dsh durante 30 segundos, dsh abre ese chat. Los chats naranjas se abren antes que los verdes. En cada grupo, primero se abre el que lleva más tiempo esperando; el siguiente se abre tras otros 30 segundos sin uso. Una tecla, un clic, un movimiento del ratón, la rueda de desplazamiento o un toque reinician los 30 segundos. Texto en el campo con el foco, texto seleccionado o un menú o diálogo abierto también detienen el cambio. Mientras un chat en espera está en pantalla, nada cambia. Si sales de un chat en espera sin responder, puede volver a abrirse tras los siguientes 30 segundos sin uso. Cuando se abre un chat verde, su punto desaparece; el siguiente chat verde solo se abre después de que vuelvas a usar dsh y luego pases 30 segundos sin usarlo. También funciona con dsh en segundo plano, pero dsh no pasa al frente. | <a href="assets/features/idleSwitch.webp"><img src="assets/features/idleSwitch.webp" width="160" alt="Captura: Abrir el chat en espera si estás inactivo"></a> |
79
86
  | **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> |
80
87
  | **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 (con fotos: el **+** del editor → Camera, Photos o Paste image), 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. El panel **Conexión móvil** muestra los iPhone emparejados con su última conexión: **Remove** desconecta uno al instante. “Tailscale only” rechaza la red local (para una red Wi-Fi compartida), y el registro de accesos muestra quién intentó conectarse. En Tether, “Settings → Privacy” bloquea la app con Face ID. | <a href="assets/features/mobileConnect.webp"><img src="assets/features/mobileConnect.webp" width="160" alt="Captura: Conexión móvil (iPhone)"></a> |
81
88
  | **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> |
@@ -160,7 +167,12 @@ Probado en dsh `0.2.0-rc.2` (escritorio y web) y `0.2.1-rc.2` (web). La CI ejecu
160
167
  - **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).
161
168
  - **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).
162
169
  - **Comprobación del objetivo:** solo se ejecuta cuando el agente marca un `/goal` como completado en una ronda automática (o cuando haces clic en **Ejecutar ahora**). La parte Host ejecuta el comando de prueba en la carpeta del chat con el modo sandbox del chat (como la propia herramienta `bash` de dsh: la misma política de acceso a archivos; si ese sandbox no puede iniciarse, la prueba no se ejecuta y la comprobación falla). Para encontrar el comando solo lee `package.json`, `Makefile`, `Cargo.toml`, `go.mod`, `pyproject.toml` y `pytest.ini`, como archivos normales dentro de la carpeta (sin enlaces simbólicos que salgan de ella, sin FIFO). Después envía el objetivo, el chat desde que empezó el objetivo (tus mensajes, las respuestas del agente, las llamadas a herramientas recortadas a 1.000 caracteres y los últimos 2.000 caracteres de cada resultado de herramienta; sin razonamiento ni pasos revertidos; como máximo unos 60.000 caracteres, la parte más reciente), `git status --short` y el final de la salida de la prueba al modelo elegido en **Comprobación del objetivo** (de forma predeterminada, el modelo del propio chat), en una sola petición sin herramientas. La salida de las herramientas puede contener lo que leyó el agente, así que esta petición puede incluir partes de tus archivos, igual que el propio chat. No se escribe nada en el chat ni en el proyecto. Tu comando de prueba, los límites, el último resultado (con el final de su salida) y el modelo elegido están en `$DSH_HOME/storages/dsh-composer-plus/goal-check.json` (archivo solo para el propietario, los 500 chats más recientes).
163
- - **Memoria del proyecto:** desactivada hasta que la actives. Mientras está activada, después de cada turno terminado de un chat de nivel superior, la parte Host envía los mensajes nuevos del propio chat desde la última revisión (tus mensajes y las respuestas de texto del agente; sin salida de herramientas, sin razonamiento, sin contexto oculto, sin mensajes revertidos; la copia del chat padre en un chat bifurcado queda fuera; como máximo unos 16.000 caracteres) y las notas guardadas al modelo del propio chat, como una sola petición sin herramientas. Las notas son archivos Markdown en `$DSH_HOME/storages/dsh-composer-plus/memory/` (archivos solo para el propietario): `projects/<id>/` para cada carpeta de proyecto (`<id>` es un hash de la ruta real de la carpeta; `project.json` nombra la carpeta), `global/`, `journal.jsonl` (cada cambio con la línea anterior y la posterior) y `reviewed.json` (hasta dónde se leyó cada chat). No se escribe nada en la carpeta del proyecto. Se rechazan las notas que parecen una clave, un token, una contraseña o un número de identificación. Las notas de un proyecto entran en el prompt de sistema de cada chat nuevo en esa carpeta, así que llegan al modelo con cada petición de ese chat. El interruptor está en `memory.json`, en la misma carpeta.
170
+ - **Continuar en un chat nuevo:** no se ejecuta nada hasta que haces clic. Entonces la parte Host envía el chat (tal como lo lee la Comprobación del objetivo: sin razonamiento ni pasos revertidos) al modelo del propio chat y muestra la nota de traspaso; solo **Iniciar chat nuevo** crea un chat nuevo. No se escribe nada en el proyecto.
171
+ - **Desglose del contexto:** la parte Host solo lee el registro del chat; ninguna llamada al modelo, ningún archivo del proyecto.
172
+ - **Tablero de tareas:** el tablero (títulos, descripciones, etiquetas y comentarios de tus tareas, las rutas de las carpetas de los proyectos y sus id cortos) está en `$DSH_HOME/storages/dsh-composer-plus/board.json` (archivo solo para el propietario); el interruptor está en `board-switch.json`, junto a él. Nada sale de tu equipo y no se escribe nada en ninguna carpeta de proyecto. Las herramientas del tablero dan a los agentes lo que escribiste en el tablero, así que el texto de una tarea llega al modelo del chat cuando un agente la lee. Un archivo del tablero dañado se guarda como `board.json.broken-<time>` y el tablero empieza vacío.
173
+ - **Archivos protegidos:** la lista y el interruptor están en `$DSH_HOME/storages/dsh-composer-plus/protected-files.json` (archivo solo para el propietario). La comprobación solo lee la ruta de cada llamada a una herramienta de archivos (y su ruta real), nunca el archivo.
174
+ - **Comandos bloqueados:** las reglas y el interruptor están en `$DSH_HOME/storages/dsh-composer-plus/blocked-commands.json` (archivo solo para el propietario). La comprobación solo lee el texto del comando de cada llamada a `bash` y `pwsh`; no ejecuta nada y no envía nada.
175
+ - **Memoria del proyecto:** desactivada hasta que la actives. Mientras está activada, después de cada turno terminado de un chat de nivel superior, la parte Host envía los mensajes nuevos del propio chat desde la última revisión (tus mensajes y las respuestas de texto del agente; sin salida de herramientas, sin razonamiento, sin contexto oculto, sin mensajes revertidos; la copia del chat padre en un chat bifurcado queda fuera; como máximo unos 16.000 caracteres) y las notas guardadas al modelo del propio chat, como una sola petición sin herramientas. Las notas son archivos Markdown en `$DSH_HOME/storages/dsh-composer-plus/memory/` (archivos solo para el propietario): `projects/<id>/` para cada carpeta de proyecto (`<id>` es un hash de la ruta real de la carpeta; `project.json` nombra la carpeta), `global/`, `journal.jsonl` (cada cambio con la línea anterior y la posterior) y `reviewed.json` (hasta dónde se leyó cada chat). No se escribe nada en la carpeta del proyecto. Se rechazan las notas que parecen una clave, un token, una contraseña o un número de identificación. Las notas de un proyecto entran en el prompt de sistema de cada chat nuevo en esa carpeta, así que llegan al modelo con cada petición de ese chat. El interruptor está en `memory.json`, en la misma carpeta. **Abrir memoria** no envía nada hasta que pulsas **Vista previa de los cambios**; entonces envía las notas que muestra y tu texto al modelo predeterminado de dsh, en una sola petición sin herramientas. Sus cambios se escriben solo con **Aplicar**, con `editor` en el registro. Tether lee y cambia las notas por la misma ruta.
164
176
  - **Copia de seguridad:** nada sale de tu equipo. Los archivos comprimidos van a `~/Desktop/dsh-backups` (archivos solo para el propietario). Los secretos no están en un archivo comprimido: los archivos de credenciales (`.credentials.yaml`, `.env`), los archivos de claves (`.pem`, `.key`, `.p12`, `.pfx`) y los valores de los ajustes token, secret, password y API key de los archivos yml se ocultan; sus copias reales se quedan en `composer-plus-vault/<archive>/`, en la misma carpeta (solo para el propietario), solo en este equipo. **Para otro equipo** no copia ningún vault: vuelve a introducir esos secretos allí. Tus registros de chat, tus ajustes y el resto del directorio home de dsh están tal cual en el archivo comprimido: mantén la carpeta privada, igual que el propio `$DSH_HOME`. La copia de seguridad lee los archivos con `O_NOFOLLOW | O_NONBLOCK`; un enlace simbólico se guarda como enlace (nunca se sigue) y un FIFO o un dispositivo se omite. El interruptor y los ajustes de la copia de seguridad automática están en `$DSH_HOME/storages/dsh-composer-plus/auto-backup.json`, el interruptor de la consola de rescate en `rescue-console.json` y, mientras dsh se ejecuta, `running/host-<pid>.json` nombra cada proceso de dsh (la consola de rescate los lee para rechazar una restauración).
165
177
  - **Consola de rescate:** un menú de terminal; no abre ningún puerto de red. Una restauración solo escribe en una carpeta nueva junto al directorio home de dsh (archivos con `O_EXCL | O_NOFOLLOW`, enlaces simbólicos al final y nunca seguidos) y rechaza un archivo comprimido con un nombre inseguro (`..`, una ruta absoluta), un dispositivo o FIFO, más de una carpeta superior o una entrada bajo un enlace.
166
178
 
@@ -182,7 +194,7 @@ Probado en dsh `0.2.0-rc.2` (escritorio y web) y `0.2.1-rc.2` (web). La CI ejecu
182
194
  - **No hay etiqueta de rama en una fila de chat:** el chat no tuvo ningún turno desde que instalaste esta versión, su carpeta no es un repositorio git o **Rama de Git en las filas de chat** está desactivada. Después de una actualización, reinicia dsh (la parte Host registra la rama).
183
195
  - **Comprobación del objetivo dice que la prueba terminó con el código 127 o «not found»:** dsh iniciado desde el Finder o el Dock puede tener un PATH más corto que tu terminal, así que no encuentra `npm`, `pnpm` ni `cargo`. Inicia dsh desde una terminal, o define tu propio comando de prueba con la ruta completa en **Comprobación del objetivo** → **Editar**. **Ejecutar ahora** muestra el resultado al momento.
184
196
  - **El objetivo no se cierra y el agente sigue trabajando:** **Comprobación del objetivo** encontró una prueba fallida o trabajo pendiente; la fila bajo el objetivo muestra el motivo (pasa el puntero por el resultado para ver los detalles). Corrige la causa o el comando de prueba, o completa el objetivo tú mismo con `/goal` o con la barra del objetivo (eso no se comprueba).
185
- - **La instalación falla justo después de una versión nueva:** añade la versión (`dsh-composer-plus@1.16.1`); consulta la nota de instalación de más arriba.
197
+ - **La instalación falla justo después de una versión nueva:** añade la versión (`dsh-composer-plus@1.18.0`); consulta la nota de instalación de más arriba.
186
198
  - **Hacer copia ahora dice «Ya hay otra acción de copia de seguridad en curso»:** hay una acción en marcha en otra ventana de dsh o en la consola de rescate (comparten un archivo de bloqueo, `.composer-plus.lock`, en la carpeta de copias de seguridad). Espera a que termine. Si no hay ninguna acción en marcha, el siguiente clic toma el bloqueo de un proceso cerrado.
187
199
  - **La consola de rescate dice «dsh is running»:** primero sal de dsh. Si dsh está realmente cerrado, el archivo que nombra el mensaje quedó de un cierre inesperado: elimínalo y vuelve a intentarlo.
188
200
  - **Después de una restauración, dsh no se inicia o falta un plugin:** hay que volver a instalar los paquetes de plugins de un perfil. La consola de rescate lo ofrece después de una restauración; o ejecuta `pnpm install` en cada carpeta de `$DSH_HOME/profiles/` que indique. Los secretos que no estaban en el vault (otro equipo) hay que introducirlos de nuevo: la consola los enumera.
@@ -205,6 +217,7 @@ Probado en dsh `0.2.0-rc.2` (escritorio y web) y `0.2.1-rc.2` (web). La CI ejecu
205
217
  - **Permitir en este chat** cuenta el límite de tiempo desde el momento en que se concede el permiso. Un nuevo límite de tiempo se aplica al instante a los permisos vigentes, así que uno más corto puede terminarlos al instante. Los permisos de la versión 1.12 y anteriores no tienen hora: después de la actualización, el agente vuelve a preguntar una vez por esas herramientas.
206
218
  - **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.
207
219
  - **Ajustar la tarjeta de pregunta a la ventana** cambia solo la tarjeta de pregunta de dsh, no la tarjeta de revisión del plan. Encuentra la tarjeta por el marcado de dsh (`data-question-key`, `data-question-scroll`); si una actualización de dsh cambia ese marcado, la tarjeta se ve como la dibuja dsh. La altura de la tarjeta sigue a la ventana, no al chat: en un chat dentro de un panel lateral estrecho, una tarjeta alta puede sobresalir por encima del chat.
220
+ - **Ajustar la cabecera del chat a la ventana** encuentra la cabecera del chat de dsh por sus nombres de clase generados (`_titleRow`, `_titleCluster`, `_crumbs`, `_headerActions`, `_headerUtilities`), porque dsh no ofrece un punto de enganche para su diseño. Si una actualización de dsh los cambia, la cabecera se muestra como la dibuja dsh. En una columna de chat muy estrecha la cabecera puede ocupar dos o tres líneas, así que queda menos espacio sobre los mensajes.
208
221
  - **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). Tether solo las envía después de que actives «Settings → Notifications → Send notifications» en Tether. Esta opción está desactivada de forma predeterminada, e iOS pide el permiso cuando la activas. La app de iOS aún no está en la App Store: compílala desde `tether/ios` con Xcode. «Tailscale only» sigue necesitando una dirección Wi-Fi o Ethernet en el Mac (la pasarela solo se inicia con una). El registro de accesos es propio de cada Mac y solo guarda los 200 intentos más recientes; un intento repetido en menos de un minuto suma uno a la misma fila. El bloqueo de la app Tether no oculta las vistas previas de las notificaciones en la pantalla bloqueada del iPhone: desactívalas en Ajustes de iOS. 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í.
209
222
  - Un enlace de sesión funciona dentro de los chats; hacer clic en él no abre el chat. Un enlace creado con **Copiar enlace del mensaje** abre su mensaje solo en dsh 0.2.1 y posteriores, y solo desde un mensaje de un chat (dsh 0.2.0 no tiene reglas de texto de usuario, así que allí el enlace se copia, pero se muestra como texto normal). Un mensaje que una reversión quitó, o que la compactación eliminó del historial que carga dsh, no se puede mostrar: el enlace lo indica. Los botones 🔗 se enganchan a las filas de mensajes de dsh; si una actualización de dsh cambia ese marcado, no aparecen.
210
223
  - **Marcar todo como leído** cambia los puntos de no leído propios de dsh mediante una parte de dsh que no es una API pública (la lista `completionUnread` del estado de sesión de dsh). Si una actualización de dsh le cambia el nombre, el elemento no aparece. El elemento va en el menú «…» del proyecto de dsh, que no tiene un espacio para plugins; si dsh cambia ese menú, el elemento tampoco aparece.
@@ -219,7 +232,7 @@ Probado en dsh `0.2.0-rc.2` (escritorio y web) y `0.2.1-rc.2` (web). La CI ejecu
219
232
  - **Una rama por chat**: cuando se elimina la carpeta de la rama de un chat (`<project>/.worktrees/<name>`), por ejemplo cuando el propio agente del chat quita el worktree y elimina la rama, el siguiente paso del chat lo saca de esa carpeta. El proyecto de la carpeta de la rama desaparece de la barra lateral, y el chat aparece en Sin agrupar y sigue abierto. En dsh 0.2.1 y posteriores, el chat continúa en la carpeta principal del proyecto, y el modelo recibe una nota sobre la nueva carpeta. En dsh 0.2.0, el chat conserva la carpeta eliminada: un comando allí falla hasta que empieces un chat nuevo. El proyecto de una rama eliminada que ningún chat usa también desaparece de la barra lateral: Composer Plus revisa las carpetas de ramas al iniciar y cada 30 segundos, también sin ningún filtro de la barra lateral. Mientras un chat se mueve, **Nueva rama** en el mismo repositorio responde «inténtalo de nuevo». Con el interruptor apagado, vuelve a aparecer el error propio de dsh («working-directory: directory does not exist»).
220
233
  - **Ramas en el árbol de espacios de trabajo** escribe en git sin un clic: cuando mueve un chat, devuelve la carpeta del proyecto a su rama anterior (`git switch`) y añade un worktree (`git worktree add`). Nunca borra una rama, un worktree ni un archivo. dsh no puede cambiar la carpeta de un chat, así que un chat movido es una copia (la bifurcación propia de dsh, con un id nuevo) y el chat anterior se archiva. La copia sigue con la tarea detenida; una llamada a herramienta que se ejecutaba cuando apareció la rama termina con un rechazo, y el agente la vuelve a ejecutar en la carpeta nueva. Un objetivo del chat anterior no se mueve con él. Solo se mueve un chat cuya carpeta es la carpeta principal del repositorio, y solo por una rama que creó y a la que cambió en ese turno (`git switch -c`, `git checkout -b`): una rama hecha solo con `git branch`, una carpeta con cambios sin confirmar, un worktree vinculado o una subcarpeta no mueven nada. En el árbol solo aparecen los worktrees que están directamente en `<project>/.worktrees/` y tienen una rama; un worktree separado (detached) o uno en otro lugar no aparece. La copia se abre sola solo cuando su chat era el abierto (el plugin lo lee de la fila de la barra lateral de dsh); si no, está en el proyecto de la rama.
221
234
  - **Buscar en el chat** solo busca en lo que muestra la página: los mensajes y respuestas cargados (desplázate hacia arriba o haz clic en **Cargar anteriores** para ver los más antiguos), no en los pasos de herramientas cerrados ni en el texto plegado dentro de la salida de una herramienta. Cuenta como máximo 2.000 coincidencias (después, «2000+»). Usa la API de resaltado del navegador (Chromium 105 y posteriores; la app de escritorio la tiene): en un navegador más antiguo, el recuento y los saltos funcionan sin el color. `Cmd+F` en un Mac (`Ctrl+F` en Windows y Linux) solo lo abre mientras hay un chat en pantalla; en otros lugares, la búsqueda propia del navegador funciona como antes. En un Mac, `Ctrl+F` mantiene su uso de macOS en los campos de texto (el cursor avanza un carácter).
222
- - **Abrir el chat en espera si estás inactivo** solo conoce lo que ve la ventana de dsh: el trabajo en otra app no cuenta, así que con dsh en segundo plano puede abrir un chat en espera a los 30 segundos. No trae dsh al frente. Leer sin pulsar una tecla, hacer clic ni mover el ratón cuenta como inactividad. Solo mira los chats con el punto naranja de dsh (una pregunta, una aprobación o una revisión del plan); la solicitud de un subagente se muestra en su chat principal. Mientras un chat en espera está en pantalla, no se abre otro; un chat que dejaste sin responder puede volver a abrirse tras los siguientes 30 segundos sin uso. Los 30 segundos no se pueden cambiar.
235
+ - **Abrir el chat en espera si estás inactivo** solo conoce lo que ve la ventana de dsh: el trabajo en otra app no cuenta, así que con dsh en segundo plano puede abrir un chat en espera a los 30 segundos. No trae dsh al frente. Leer sin pulsar una tecla, hacer clic ni mover el ratón cuenta como inactividad. Solo mira los chats con el punto naranja de dsh (una pregunta, una aprobación o una revisión del plan) o con su punto verde (un turno terminado que aún no has abierto); la solicitud de un subagente se muestra en su chat principal. Los chats naranjas se abren primero. Abrir un chat verde quita su punto, así que los 30 segundos del siguiente chat verde solo empiezan tras tu siguiente tecla, clic, movimiento del ratón, rueda de desplazamiento o toque: cuando vuelves, los demás puntos verdes siguen ahí. Mientras un chat en espera está en pantalla, no se abre otro; un chat que dejaste sin responder puede volver a abrirse tras los siguientes 30 segundos sin uso. Los 30 segundos no se pueden cambiar.
223
236
  - Al hacer clic en una notificación enviada antes de un reinicio, solo se trae dsh al frente.
224
237
  - 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.
225
238
  - dsh no tiene un punto de extensión en el menú de opciones de vista de la barra lateral, así que la opción de proyectos recientes se añade al menú propio de dsh. Si una actualización de dsh cambia ese menú, la opción no aparece y todos los proyectos siguen visibles. El filtro funciona sobre las filas de proyecto, así que **En una sola lista** no se filtra. En **Árbol de espacios de trabajo**, una carpeta padre sigue visible mientras un proyecto que contiene está activo, y también se ocultan las filas de chat que no estuvieron activas en las últimas 2 horas; en **Espacio de trabajo** solo se filtran las filas de proyecto. El filtro lee qué vista muestra dsh desde el ajuste de vista que dsh guarda (no es una API pública); si una actualización de dsh le cambia el nombre, **Árbol de espacios de trabajo** se filtra como **Espacio de trabajo**. La función Estado del proyecto lee el mismo ajuste: en **Árbol de espacios de trabajo**, la fila de una carpeta padre también cuenta los chats de los proyectos que contiene; si dsh cambia el nombre del ajuste, cada fila muestra solo sus propios chats. **Por estado** tiene el mismo tipo de límite: dsh no tiene un espacio para el orden, así que la opción y el orden de las filas se enganchan al marcado del menú y de la lista de dsh.
@@ -228,10 +241,16 @@ Probado en dsh `0.2.0-rc.2` (escritorio y web) y `0.2.1-rc.2` (web). La CI ejecu
228
241
  - dsh tampoco tiene un punto de extensión que elija dónde se abre **Nueva sesión**. **Espacio de trabajo predeterminado para Nueva sesión** envuelve un método de dsh que no es una API pública (`startSession` del servicio de espacios de trabajo de dsh). Si una actualización de dsh le cambia el nombre, **Nueva sesión** se abre donde elija dsh (el proyecto abierto o el más reciente). Toda llamada que no indica un proyecto usa el predeterminado: el botón de la barra lateral, su atajo, el logotipo y también **Nueva** en la página **Tareas automatizadas**. dsh sigue abriendo el último chat al iniciar. La carpeta general se crea y se añade a tus proyectos en el primer uso; en Windows o Linux con la carpeta Documents movida puede ser otra carpeta distinta de la de dsh.
229
242
  - 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.
230
243
  - **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.
231
- - **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).
232
- - **Comprobación del objetivo** solo comprueba una finalización que el agente hace en una ronda automática del objetivo: una finalización que pides en el chat, `/goal` y la barra del objetivo no se comprueban. El agente puede cambiar las pruebas o los archivos del comando de prueba por sí mismo; el verificador lee el chat y puede verlo, pero puede equivocarse en ambos sentidos (un «no terminado» erróneo cuesta una ronda más; un «terminado» erróneo cierra el objetivo). El verificador ve el chat y `git status`, no el código en sí. Una ejecución de prueba solo se reutiliza cuando el paso más reciente del agente que puede cambiar archivos fue su propia ejecución correcta de `bash` con exactamente el mismo comando en la misma carpeta; un comando con una tubería (`| tail`) o `&&` no se reutiliza. El presupuesto se mide cuando termina un turno, así que un turno puede superarlo. Solo cuentan las llamadas al modelo del propio chat (no las de sus subagentes). `update_goal` espera mientras se ejecuta la comprobación (la prueba como máximo 15 minutos, el verificador como máximo 3 minutos). Una bifurcación recibe un nuevo id de chat, así que empieza sin el comando de prueba ni los límites propios del chat original. Cada finalización que llega al verificador cuesta una llamada al modelo.
244
+ - **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 que no sea `/goal <objetivo>`, con una palabra de control de `/goal` (`clear`, `pause`, `resume`) 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. Para un objetivo de `/goal`, solo escribe condiciones a partir del borrador y del contexto; una condición demasiado estricta puede costar rondas del objetivo, así que léela antes de enviarla. 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).
245
+ - **Comprobación del objetivo** solo comprueba una finalización que el agente hace en una ronda automática del objetivo: una finalización que pides en el chat, `/goal` y la barra del objetivo no se comprueban. El agente puede cambiar las pruebas o los archivos del comando de prueba por sí mismo; el verificador lee el chat y puede verlo, pero puede equivocarse en ambos sentidos (un «no terminado» erróneo cuesta una ronda más; un «terminado» erróneo cierra el objetivo). El verificador ve el chat y `git status`, no el código en sí. Una ejecución de prueba solo se reutiliza cuando el paso más reciente del agente que puede cambiar archivos fue su propia ejecución correcta de `bash` con exactamente el mismo comando en la misma carpeta; un comando con una tubería (`| tail`) o `&&` no se reutiliza. El presupuesto se mide cuando termina un turno, así que un turno puede superarlo. El presupuesto de tokens también cuenta las llamadas de los chats de subagentes del chat (se leen de sus registros guardados al final de cada turno, así que un chat con muchos subagentes tarda un poco más en comprobarse). La tabla de evidencias viene de la propia lectura del chat que hace el verificador: una parte que marca como verificada aún necesita que la revises tú cuando importa. `update_goal` espera mientras se ejecuta la comprobación (la prueba como máximo 15 minutos, el verificador como máximo 3 minutos). Una bifurcación recibe un nuevo id de chat, así que empieza sin el comando de prueba ni los límites propios del chat original. Cada finalización que llega al verificador cuesta una llamada al modelo.
246
+ - **Archivos protegidos** es una barrera de protección, no un sandbox. Cubre las herramientas de archivos propias de dsh (`read`, `read_image`, `grep` en un archivo, `write`, `edit`, `str_replace_editor`). Un comando de shell (`cat .env`), un script que escribe el agente, el shell de un subagente, una herramienta MCP, un listado de `glob` y un `grep` sobre una carpeta entera aún pueden llegar a un archivo protegido. Para un límite real, usa los modos sandbox de dsh o deja los secretos fuera de la carpeta del proyecto. Los patrones conocen `*`, `**` y `?`, no `{a,b}` ni `[ab]`, y no distinguen mayúsculas de minúsculas.
247
+ - **Comandos bloqueados** es una barrera de protección, no un sandbox. Solo lee el texto del comando de las herramientas `bash` y `pwsh` de dsh. Una variable o un alias que nombra el comando (`CMD=npm; $CMD publish`), una función de shell, un archivo de script que escribe el agente, otro programa (`python -c`, `node -e`, `make`), una herramienta MCP y tu propia terminal aún pueden ejecutarlo. Una regla puede coincidir con más de lo que quieres: cualquier palabra de un comando puede ser el nombre del comando (`echo npm publish` coincide con `npm publish`), y puede haber otras palabras entre las palabras de la regla (`git push --force` también coincide con `git push origin main --force`). Alarga una regla cuando coincida con demasiado. **preguntar antes** necesita un chat que pueda preguntar: en un chat cuya política de aprobación es never (por ejemplo, un subagente delegado), dsh no puede mostrar la tarjeta, así que la llamada se rechaza con el motivo. La tarjeta de aprobación muestra el motivo en inglés. **Permitir en este chat** no responde a una tarjeta de **preguntar antes**.
248
+ - **Continuar en un chat nuevo** envía el chat (mensajes, llamadas a herramientas y el final de cada resultado de herramienta, como máximo unos 60.000 caracteres, la parte más reciente) al modelo del propio chat. La nota de traspaso puede omitir una decisión o un archivo: léela antes de empezar. El chat nuevo solo conoce la nota y el chat enlazado (dsh adjunta el chat anterior como contexto de solo lectura); su contexto del modelo empieza pequeño y el chat anterior se queda como está. Solo una nota o un inicio por chat a la vez.
249
+ - **Desglose del contexto** muestra estimaciones con la regla propia de dsh (unos 4 caracteres por token), la misma regla que usa el anillo de contexto de dsh; el recuento propio del modelo puede ser distinto. Las definiciones de herramientas son las de la petición más reciente. Muestra el contexto tal como lo tiene el registro del chat; un turno que se está ejecutando aparece después de su siguiente paso.
250
+ - **Pasos planificados** ahorra tokens solo cuando el modelo planifica: mientras está activada, cada solicitud lleva la herramienta `plan_next_steps` y una instrucción breve (unos 500 tokens), también en los chats donde el modelo nunca planifica. Una condición prueba solo lo que dice (por ejemplo: el código de salida de la compilación fue 0), no que el trabajo sea correcto. `ok` lee las marcas de resultado propias de dsh (`[exit code: N]`, tiempos de espera, rechazos del sandbox); un comando que falla sin un código de salida distinto de cero pasa. Los pasos se ejecutan de uno en uno; dos pasos listos a la vez vuelven al modelo. El mensaje del paso se guarda como un mensaje del asistente del modelo del chat (dsh no tiene una marca para un mensaje escrito por un plugin), por eso su texto dice que Composer Plus lo ejecutó. No está en Tether.
251
+ - **Tablero de tareas** solo conoce los proyectos de dsh: un chat fuera de un proyecto muestra **Todos los proyectos**, y la carpeta de una rama por chat (`<project>/.worktrees/<name>`) cuenta como su proyecto. Los id de proyecto (`acme#12`) vienen del nombre de la carpeta y no cambian cuando cambias el nombre del proyecto en dsh. La regla "mantén el tablero al día" entra en un chat solo cuando su proyecto tiene tareas abiertas; un chat que ya la recibió la conserva. Se indica a los agentes que te dejen **Hecho**, **En espera** y las tareas manuales, pero las herramientas no lo rechazan: un agente aún puede mover una de esas tarjetas. Las herramientas del tablero están en la lista de herramientas de cada chat mientras la función está activada (unos 1.000 tokens por petición); desactívala si no usas el tablero. La página lee el tablero cada 2 segundos mientras se muestra; un cambio de un agente aparece en ese tiempo. Un texto que editas mientras un agente cambia el mismo campo no se guarda: el panel muestra el texto nuevo y el motivo. No hay imágenes, ni sincronización con git entre equipos, ni uso compartido por la red (Kanzo sí los tiene). La idea y el aspecto vienen de [Kanzo](https://github.com/emanuele-em/kanzo), de emanuele-em (AGPL-3.0); Composer Plus no usa su código.
233
252
  - **Prioridad al mensaje enviado tras Detener** solo actúa después de que detienes el chat (o tras un turno que falló, o al abrir un chat que aún tiene cola): un mensaje que envías mientras un turno se ejecuta sigue esperando al final de la cola. Solo pasa por delante de tus propios mensajes en cola: si en la cola espera una ronda de un objetivo o una respuesta a una pregunta, se mantiene el orden de dsh. Lee una parte de dsh que no es una API pública (si el turno detenido aún está terminando); si una actualización de dsh le cambia el nombre, el mensaje pasa delante solo cuando ese turno ha terminado. Los chats de subagentes mantienen el orden de dsh.
234
- - **Memoria del proyecto** pertenece a la primera carpeta del chat (la carpeta de proyecto de dsh): un chat que cambia de carpeta con `cd` conserva la memoria de su primer proyecto, y la misma carpeta abierta por otra ruta a los mismos archivos la comparte. Un chat congela su sección de memoria al empezar, así que una nota guardada después aparece desde el chat siguiente (`memory_recall` la encuentra al momento). La revisión solo guarda lo que el modelo decide guardar: puede pasar por alto un dato o guardar uno erróneo; abre los archivos para comprobarlos y edítalos o bórralos a mano con dsh cerrado. Cada turno terminado con un mensaje tuyo cuesta una llamada al modelo; una llamada fallida vuelve a leer los mismos mensajes después del turno siguiente. Los chats de subagentes no se revisan. La idea y el formato de archivo vienen de [DS Bot](https://github.com/Fei2411/DS-Bot) (Apache-2.0); Composer Plus no usa su código y nunca lee ni escribe la memoria propia de DS Bot.
253
+ - **Memoria del proyecto** pertenece a la primera carpeta del chat (la carpeta de proyecto de dsh): un chat que cambia de carpeta con `cd` conserva la memoria de su primer proyecto, y la misma carpeta abierta por otra ruta a los mismos archivos la comparte. Un chat congela su sección de memoria al empezar, así que una nota guardada después aparece desde el chat siguiente (`memory_recall` la encuentra al momento). La revisión solo guarda lo que el modelo decide guardar: puede pasar por alto un dato o guardar uno erróneo; revísalas en **Abrir memoria** y cámbialas allí, o edita los archivos a mano con dsh cerrado. **Abrir memoria** envía las notas del proyecto seleccionado y las notas globales (todos los proyectos si seleccionas Todas las notas; como mucho unos 60.000 caracteres, el resto solo se cuenta y no puede cambiar en esa solicitud) y tu texto al modelo predeterminado de dsh, no al modelo del chat. Una vista previa se guarda en el Mac 30 minutos y hasta que dsh se reinicia; si una revisión o el agente cambian las notas mientras tanto, **Aplicar** se niega y vuelves a pedir la vista previa. **Aplicar** guarda todos los cambios de una vista previa o ninguno: si un cambio no se puede guardar (por ejemplo, MEMORY.md está lleno), las notas quedan como estaban y se muestra el motivo. Cada turno terminado con un mensaje tuyo cuesta una llamada al modelo; una llamada fallida vuelve a leer los mismos mensajes después del turno siguiente. Los chats de subagentes no se revisan. La idea y el formato de archivo vienen de [DS Bot](https://github.com/Fei2411/DS-Bot) (Apache-2.0); Composer Plus no usa su código y nunca lee ni escribe la memoria propia de DS Bot.
235
254
  - **Copia de seguridad** usa una sola carpeta fija, `~/Desktop/dsh-backups` (la predeterminada de dsh-backup, para que sus archivos comprimidos sigan sirviendo); no hay ningún ajuste para otra carpeta. Un archivo comprimido ocupa más o menos lo mismo que el directorio home de dsh sin `cache/` ni `dsh-runtimes/` (medido: 1,6 GB de archivos dieron un archivo comprimido de 830 MB en unos 30 s en Apple Silicon; dsh siguió respondiendo). Un archivo que cambia mientras se lee se guarda tal como estaba cuando la copia de seguridad lo abrió, así que el registro de un chat abierto puede terminar en una entrada cortada, que dsh repara en su siguiente escritura. El ocultamiento encuentra un secreto en un archivo yml por el nombre de su clave en una línea (`token:`, `apiKey:`, …); un secreto en un mapa de flujo (`{token: x}`), en una lista bajo una de esas claves, en un archivo JSON (por ejemplo, la `apiKey` de un servidor MCP en un archivo `.json`) o con otro nombre se queda en el archivo comprimido. Los archivos comprimidos por tipo de dsh-backup (`dsh-t-…`) no aparecen en la lista. **Para otro equipo** copia el archivo comprimido (un clon en APFS: sin espacio adicional); el vault no va con él. **Hacer copia ahora** no elimina ninguna copia de seguridad. Una copia de seguridad automática conserva las copias más recientes que hizo Composer Plus (el ajuste **Conservar** de **Copia de seguridad automática**) y elimina sus copias más antiguas; las instantáneas anteriores a una actualización se cuentan aparte (se quedan las 2 más recientes). Los archivos comprimidos de dsh-backup nunca se eliminan: quítalos con **Eliminar**. Mientras dsh-backup siga instalado, cuenta los archivos comprimidos de Composer Plus en su propio número de copias que conserva y puede eliminarlos.
236
255
  - **Restaurar** solo funciona en la consola de rescate, con dsh cerrado: sustituye todo el directorio home de dsh. El anterior se queda a su lado como `.dsh.pre-restore-<time>` hasta que lo elimines, así que el disco necesita espacio para los dos. Los chats conservan las rutas de sus proyectos: en otro equipo, un proyecto en otra ruta aparece como ausente hasta que vuelvas a añadirlo. Los enlaces simbólicos que apuntan fuera del directorio home de dsh (por ejemplo, skills enlazadas desde otra carpeta) vuelven como enlaces; sus destinos deben existir en ese equipo.
237
256
  - **Comprobación de registros de sesión** lee el registro más reciente de cada chat con las propias reglas de dsh sobre lo que se abre: una línea que no es JSON o que está fuera de orden solo cuenta como daño cuando después viene un final de turno (si no, dsh abre el chat sin las líneas desde ese punto, así que no aparece en la lista). No comprueba los eventos de un registro con las reglas de eventos del propio dsh, así que un registro que considera sano puede no abrirse después de una actualización de dsh. Una reparación toma la copia de una copia de seguridad: los mensajes posteriores a esa copia de seguridad se pierden en ese chat (el archivo dañado se queda a su lado). Un chat abierto en este dsh no se repara en Configuración: dsh lo tiene retenido.
@@ -264,7 +283,9 @@ Probado en dsh `0.2.0-rc.2` (escritorio y web) y `0.2.1-rc.2` (web). La CI ejecu
264
283
 
265
284
  **¿Puede el agente dejar de dar por terminado su propio trabajo, como en los bucles de verificación de la loop engineering?** Sí, con **Comprobación del objetivo** (activada de forma predeterminada): empieza un objetivo con `/goal`. Cuando el agente dice que el objetivo está completado, se ejecutan las pruebas del proyecto y una llamada independiente al modelo comprueba el objetivo frente al chat; si alguna falla, el objetivo sigue abierto y el agente lee el motivo. Define tu propio comando de prueba, un límite de tiempo o un límite de tokens con **Editar** en la fila **Comprobación del objetivo** bajo el objetivo.
266
285
 
267
- **¿Puede el agente recordar mis preferencias entre chats, como la memoria de DS Bot?** Sí, con **Memoria del proyecto** (desactivada de forma predeterminada): actívala en **Configuración → Composer Plus**. Después de cada turno, tus preferencias y decisiones duraderas se guardan como notas breves para el proyecto del chat, y cada chat nuevo de ese proyecto las lee. Pide al agente que recuerde algo y lo guarda al momento.
286
+ **¿Puede el agente recordar mis preferencias entre chats, como la memoria de DS Bot?** Sí, con **Memoria del proyecto** (desactivada de forma predeterminada): actívala en **Configuración → Composer Plus**. Después de cada turno, tus preferencias y decisiones duraderas se guardan como notas breves para el proyecto del chat, y cada chat nuevo de ese proyecto las lee. Pide al agente que recuerde algo y lo guarda al momento. Para ver o cambiar las notas, pulsa **Abrir memoria** en la misma fila y escribe qué cambiar.
287
+
288
+ **¿Podemos mis agentes y yo compartir un tablero de tareas, como en Kanzo?** Sí, con **Tablero de tareas** (activado de forma predeterminada): ábrelo en la barra lateral izquierda y añade tareas con **Nueva tarea**. En un chat, pide al agente que "tome la siguiente tarea del tablero": mueve la tarjeta a **En curso**, comenta lo que hizo y la mueve a **En revisión**. Marca una tarea como **Manual** para quedártela tú.
268
289
 
269
290
  **¿Puede dsh hacer copias de seguridad de mis chats y ajustes, como dsh-backup?** Sí: **Configuración → Composer Plus → Copia de seguridad → Hacer copia ahora**. Escribe el mismo formato de archivo comprimido en la misma carpeta (`~/Desktop/dsh-backups`), así que los archivos comprimidos de dsh-backup también aparecen y se pueden restaurar, y puedes desinstalar dsh-backup. Activa **Copia de seguridad automática** para hacer copias según un horario.
270
291
 
@@ -290,6 +311,8 @@ Probado en dsh `0.2.0-rc.2` (escritorio y web) y `0.2.1-rc.2` (web). La CI ejecu
290
311
 
291
312
  **¿Cómo veo solo los archivos que cambió un chat?** Barra lateral derecha → **Cambios** → **Este chat**. Haz clic en **␣** para ocultar los cambios que solo son espacios en blanco.
292
313
 
314
+ **¿Cómo evito que el agente ejecute `npm publish` o `git push --force`?** **Configuración → Composer Plus → Comandos bloqueados**: escribe `npm publish`, elige **bloquear** o **preguntar antes** y luego haz clic en **Añadir**. **bloquear** rechaza el comando y el agente te pregunta; **preguntar antes** muestra la tarjeta de aprobación cada vez. Archivos protegidos cubre las herramientas de archivos del agente; Comandos bloqueados cubre sus comandos de shell.
315
+
293
316
  **¿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, durante 1 hora por defecto; revoca el permiso desde el chip de la cabecera. Cambia el tiempo en **Configuración → Composer Plus → Permitir en este chat**.
294
317
 
295
318
  **Perdí mi iPhone. ¿Cómo evito que llegue a mi Mac?** Haz clic en **Conexión móvil**, abajo a la izquierda de la barra lateral, y haz clic en **Remove** junto a ese iPhone. Su clave deja de funcionar al instante; solo puede volver con un nuevo emparejamiento que apruebes en el Mac.
@@ -304,7 +327,7 @@ Probado en dsh `0.2.0-rc.2` (escritorio y web) y `0.2.1-rc.2` (web). La CI ejecu
304
327
 
305
328
  **¿Cómo recibo notificaciones de macOS / Windows cuando una tarea de dsh termina o necesita aprobación?** Deja activada **Notificaciones en segundo plano** (lo está de forma predeterminada) y permite las notificaciones de DeepSeek Harness en los ajustes del sistema operativo.
306
329
 
307
- **¿Puede dsh abrir por sí solo el chat que me hace una pregunta?** Sí, con **Abrir el chat en espera si estás inactivo** (activado por defecto): cuando un chat espera una respuesta, una aprobación o una revisión del plan y no usas dsh durante 30 segundos, dsh lo abre. Mientras escribes, te desplazas o mueves el ratón, espera.
330
+ **¿Puede dsh abrir por sí solo el chat que me hace una pregunta?** Sí, con **Abrir el chat en espera si estás inactivo** (activado por defecto): cuando un chat espera una respuesta, una aprobación o una revisión del plan y no usas dsh durante 30 segundos, dsh lo abre. Un chat que terminó un turno que aún no has leído (el punto verde) se abre de la misma forma, después de los naranjas. Mientras escribes, te desplazas o mueves el ratón, espera.
308
331
 
309
332
  **¿Cómo cambio la interfaz de DeepSeek Harness a turco, español, japonés…?** Configuración → Composer Plus → **Idioma de la aplicación**.
310
333
 
@@ -318,6 +341,8 @@ Probado en dsh `0.2.0-rc.2` (escritorio y web) y `0.2.1-rc.2` (web). La CI ejecu
318
341
 
319
342
  **¿Puedo enviar una foto desde mi iPhone?** Sí. En un chat de Tether, toca **+** junto al campo de mensaje → Camera, Photos (hasta 4) o Paste image. Las fotos llegan al chat del Mac como adjuntos de tu mensaje, así que el modelo las ve.
320
343
 
344
+ **¿Puede dsh ejecutar el siguiente comando sin volver a preguntar al modelo?** Sí, con **Pasos planificados** (desactivada de forma predeterminada): actívala en Configuración → Composer Plus. El modelo puede entonces planificar sus próximos comandos con una condición, por ejemplo «ejecuta las pruebas cuando la compilación pase», y Composer Plus ejecuta un paso sin una nueva llamada al modelo cuando el resultado cumple la condición. Las aprobaciones y el sandbox siguen igual.
345
+
321
346
  **¿Funciona con la app de escritorio?** Sí: Configuración → Plugins → **Añadir plugin** → `dsh-composer-plus`. Probado en dsh 0.2.0-rc.2 (escritorio y web) y 0.2.1-rc.2 (web).
322
347
 
323
348
  ## Desarrollo
@@ -343,6 +368,8 @@ PLAYWRIGHT=/path/to/playwright node test/browser-readme-anchors.mjs
343
368
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-keep-focus.mjs /path/to/dsh/lib/bin.js
344
369
  # Fit question card to window (fake model asks a long question at 1280 × 820): question, answers, Skip and Submit readable, height follows the window + its thumbnail
345
370
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-question-fit.mjs /path/to/dsh/lib/bin.js
371
+ # Fit chat header to window (fake model, subagent + background jobs, branch pill, grants chip): no overlap from 1280 to 320 px, wide header unchanged + its thumbnail
372
+ SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-header-fit.mjs /path/to/dsh/lib/bin.js
346
373
  # Mobile connect: switch on, QR popover, a fake iPhone pairs and calls dsh through the gateway, switch off + its thumbnail
347
374
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-mobile-connect.mjs /path/to/dsh/lib/bin.js
348
375
  # Resume after restart (fake slow model, real quit and start): a running chat and a goal continue, a stopped chat does not
@@ -380,6 +407,8 @@ PLAYWRIGHT=/path/to/playwright node test/browser-continue-queue.mjs /path/to/dsh
380
407
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-queue-stop-send.mjs /path/to/dsh/lib/bin.js
381
408
  # Edit queued message in place with images and files (slow fake model) + its thumbnail
382
409
  SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-queue-edit.mjs /path/to/dsh/lib/bin.js
410
+ # Task board: the page, the agent tools (fake model), drag and drop, search, the switch
411
+ SHOT=1 PLAYWRIGHT=/path/to/playwright node test/browser-task-board.mjs /path/to/dsh/lib/bin.js
383
412
  ```
384
413
 
385
414
  ```sh