dsh-output-styles 0.4.0 → 0.4.2

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/CHANGELOG.md CHANGED
@@ -4,6 +4,33 @@ All notable changes to this project are documented in this file. The format
4
4
  follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the
5
5
  project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.4.2] - 2026-08-21
8
+
9
+ ### Changed
10
+
11
+ - **rc8 compatibility**: every `@deepseek-ai/dsh-*` dependency moves to
12
+ `0.1.0-rc.8` (devDependencies and the runtime storage dependencies pinned,
13
+ peer ranges `>=0.1.0-rc.8 <0.2.0`); the five README compatibility rows,
14
+ the `dshWorkshop` compatibility claim, and the compat workflow's rc8 pins
15
+ follow. Verified on a real rc8 profile: bundle install, row mount, and a
16
+ keyless headless run through the deterministic mock LLM (`SMOKE-OK`).
17
+
18
+ ### Fixed
19
+
20
+ - **Web picker submits through the rc8 command Remote**: the generated
21
+ `commands.execute` client signature gained the image-attachment batch —
22
+ the `/style` picker passes an empty batch, keeping every switch on the
23
+ host's durable command lifecycle.
24
+ - **rc8 `commands.execute` arity in tests and the loader runner**: the
25
+ integration harness and `scripts/loader-runner.mjs` pass the image batch
26
+ and the abort signal explicitly, matching the rc8 registry signature.
27
+
28
+ ## [0.4.1] - 2026-08-19
29
+
30
+ ### Fixed
31
+
32
+ - **Invariant companion survives hot-reload**: the inline invariant registration now holds the host registry's disposer through the inject scope's `ctx.effect` (the registry binds its own effect to the service context, so the returned disposer is the only unregistration path). Disposing the plugin fiber unregisters the companion and its `domain/changed` / `session/event` listeners; remounting re-registers cleanly instead of throwing `package "dsh-output-styles" is already registered`. Regression covered by a dispose-and-remount lifecycle test against a duplicate-strict registry.
33
+
7
34
  ## [0.4.0] - 2026-08-16
8
35
 
9
36
  ### Added
package/README.es.md CHANGED
@@ -2,66 +2,60 @@
2
2
 
3
3
  # 🎨 dsh-output-styles
4
4
 
5
- **El `outputStyles` de Claude Code para DeepSeek Harness** cambia el estilo de salida del modelo en tiempo de ejecución, por sesión y de forma duradera.
5
+ **`outputStyles` de Claude Code para DeepSeek Harness**: cambia el estilo de salida del modelo en tiempo de ejecución, por sesión, de forma duradera.
6
6
 
7
- [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
8
- [![CI](https://github.com/PerryLink/dsh-output-styles/actions/workflows/ci.yml/badge.svg)](https://github.com/PerryLink/dsh-output-styles/actions/workflows/ci.yml)
7
+ *`/style concise` — y a partir de ahora toda respuesta es concisa. `/style off` — de vuelta al valor por defecto del proyecto.*
8
+
9
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
10
+ [![DSH plugin](https://img.shields.io/badge/dsh-plugin-✅-green)](https://github.com/topics/dsh-plugin)
11
+ [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
12
+ [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-output-styles/ci.yml?branch=main&label=CI)](https://github.com/PerryLink/dsh-output-styles/actions)
13
+ [![Version](https://img.shields.io/github/v/tag/PerryLink/dsh-output-styles?label=version)](https://github.com/PerryLink/dsh-output-styles/releases)
9
14
  [![npm version](https://img.shields.io/npm/v/dsh-output-styles)](https://www.npmjs.com/package/dsh-output-styles)
10
15
  [![npm downloads](https://img.shields.io/npm/dm/dsh-output-styles)](https://www.npmjs.com/package/dsh-output-styles)
11
- [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
12
- [![DSH](https://img.shields.io/badge/deepseek--harness-0.1.0--rc.6-4d6bfe.svg)](#)
13
- [![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178c6.svg)](#)
14
16
 
15
- 🌐 [English](README.md) · [中文](README.zh.md) · [日本語](README.ja.md) · [한국어](README.ko.md) · [Español](README.es.md)
17
+ [English](README.md) · [简体中文](README.zh.md) · [Español](README.es.md) · [Português](README.pt.md) · [हिन्दी](README.hi.md)
16
18
 
17
19
  </div>
18
20
 
19
21
  ---
20
22
 
21
- `/style concise` — y todas las respuestas siguientes serán concisas. `/style step-by-step` — y el modelo narra pasos numerados. `/style off` — de vuelta al valor por defecto del proyecto. Un comando por sesión, persistente entre reinicios y con cero cambios en el bucle del agente.
23
+ ## Compatibility
22
24
 
23
- ## Características
24
-
25
- | | |
25
+ | Surface | Status |
26
26
  |---|---|
27
- | 🗂️ **Biblioteca de estilos** | Un archivo Markdown por estilo (`styles/*.md`); frontmatter para los metadatos, cuerpo = la directiva del modelo. `name` toma por defecto el nombre del archivo y puede contener espacios (`Diagrams first`). Se incluyen seis estilos integrados, entre ellos `proactive` y `learning`, en paridad con Claude Code. |
28
- | ⌨️ **Comando `/style`** | Sin argumentos lista los estilos (con descripciones) + la selección actual; `/style <name>` cambia; `/style off` restaura el valor por defecto del proyecto. Todo el resto tras `/style` es el nombre del estilo. |
29
- | 💾 **Persistencia por sesión** | La elección vive en el dominio de almacenamiento `output_style`, con clave sessionId: dos sesiones nunca interfieren y la elección sobrevive a los reinicios. |
30
- | 🧩 **Inyección en el system prompt** | Una contribución `systemPrompt.section()` (orden 90) inyecta el cuerpo del estilo de la sesión actual en cada ensamblado; los cuerpos se truncan según un presupuesto configurable. |
31
- | 🎭 **`keep-coding-instructions` de Claude Code** | Los estilos con `keep-coding-instructions: false` (el valor por defecto, como Claude Code) reemplazan todo el system prompt — para estilos que dejan atrás la ingeniería de software. |
32
- | 📌 **Estilos forzados** | El campo `force-for-plugin` de Claude Code (alias `force`) aplica un estilo incondicionalmente, anulando cualquier selección de sesión; dos estilos forzados hacen fallar la carga. |
33
- | 🔁 **Compatibilidad con Claude Code** | Carga colecciones JSON `outputStyles` (`{ name, description, prompt }`), entradas individuales o matrices estilo `settings.json`; las entradas no analizables se omiten con un aviso. |
34
- | 📚 **Directorios en capas** | `stylesDir` es una lista; los directorios posteriores anulan los anteriores (el `styles/` incluido es la capa más baja; desactívalo con `includeBuiltins: false`). |
35
- | 🔄 **Recarga en caliente** | Los cambios en los archivos de estilo se detectan sin reiniciar (`watchStyles: false` para desactivarlo). |
36
- | ⚙️ **Valor por defecto del proyecto sobre ajustes** | Las sesiones que nunca eligieron uno recurren a `output-style.style` de los ajustes de DSH y, a continuación, a `defaultStyle`. |
37
- | 🖱️ **Selector web** | Una entrada `dsh.client` (`dsh-output-styles/client`) decora el comando `/style` del host con un selector emergente basado en proyecciones. |
38
- | 📊 **Proyección de sesión** | Una proyección `style` (`{ options, currentValue }`) para la Web UI, plegada a partir de los comandos asentados en el log de sesión. |
39
- | 🧯 **Fallo ruidoso, omisión limpia** | La configuración incorrecta lanza al cargar; un archivo de estilo defectuoso se omite con un aviso y nunca rompe el perfil. |
40
- | 🌐 **Documentación en cinco idiomas** | EN · 中文 · 日本語 · 한국어 · Español. |
41
-
42
- ## 🚀 Inicio rápido
27
+ | Harness | DeepSeek Harness `0.1.0-rc.8` |
28
+ | Node | `^22.19.0 || >=24.0.0` |
29
+ | Platforms | Todas (host + cliente web) |
30
+ | Model | Cualquiera (inyección en el prompt del sistema) |
31
+
32
+ ## What you get
33
+
34
+ `dsh-output-styles` es el equivalente de `outputStyles` de Claude Code para DeepSeek Harness: un comando `/style` que cambia el estilo de salida del modelo en tiempo de ejecución, persistido por sesión e inyectado en cada ensamblado del prompt.
35
+
36
+ - **Librería de estilos** — un archivo Markdown por estilo (`styles/*.md`); frontmatter para metadatos, cuerpo = la directiva del modelo. Seis estilos integrados (`concise`, `explanatory`, `formal`, `learning`, `proactive`, `step-by-step`), incluidos `proactive` y `learning` con paridad Claude Code.
37
+ - **Comando `/style`** sin argumento lista los estilos (con descripciones) más la selección actual; `/style <name>` cambia; `/style off` restaura el valor por defecto del proyecto.
38
+ - **Persistencia por sesión** la elección vive en el dominio de almacenamiento `output_style`, indexada por sessionId, y sobrevive a los reinicios.
39
+ - **Inyección en el prompt del sistema** una contribución `systemPrompt.section()` (orden `sectionOrder`) inyecta el cuerpo del estilo actual en cada ensamblado, truncado a un presupuesto configurable.
40
+ - **Paridad Claude Code** — `keep-coding-instructions`, `force-for-plugin` (alias `force`), compatibilidad JSON `outputStyles`, directorios `stylesDir` por capas, recarga en caliente y fallback del proyecto sobre la costura de settings de DSH.
41
+ - **Registro de renderers (`output.render.*`)** — `ctx.outputRenderers` permite a cualquier plugin registrar un presenter puro, aplicado a través de la cascada `output.render/before`; renderers integrados `concise` y `step-by-step`.
42
+ - **Reglas por sesión/por herramienta** — `rules: [{ match: { tool: 'bash' }, style: 'concise' }]` nombran el renderer para solicitudes coincidentes; editables mediante la sección de settings `output-style-rules`.
43
+ - **`/export`** — renderiza la sesión actual a Markdown o HTML saneado a través de la tubería de render; cada render conserva el texto original junto al renderizado.
44
+
45
+ ## Quick start
43
46
 
44
47
  ```sh
45
- # 1. Instalar el paquete es una capa de bundle, así que un comando compone
46
- # storage + storage-json + storage-domain + la fila del plugin:
47
- dsh plugin --profile <name> add dsh-output-styles
48
-
49
- # 2. Arrancar y cambiar
50
- dsh --profile <name>
51
- /style # → output style off y luego una línea por estilo
52
- /style concise # → switched to concise
53
- /style Diagrams first # → los nombres con espacios también funcionan
54
- /style off # → de vuelta al valor por defecto del proyecto
55
- ```
48
+ # 1. install the bundle into your profile
49
+ dsh plugin --profile web add "github:PerryLink/dsh-output-styles#main"
56
50
 
57
- La capa es idempotente sobre los perfiles web (la inserción por id reemplaza las filas con el mismo id), que componen `storage` de fábrica. Para el selector web, añade la fila del cliente al perfil:
51
+ # or from npm (published releases)
52
+ dsh plugin --profile web add dsh-output-styles
58
53
 
59
- ```yaml
60
- - id: output-styles-client
61
- name: 'dsh-output-styles/client'
54
+ # 2. restart and verify the row
55
+ dsh --profile web --dump-config | grep -A3 'id: output-styles'
62
56
  ```
63
57
 
64
- ## 🎬 Demo
58
+ ## Demo
65
59
 
66
60
  ```
67
61
  You > /style
@@ -76,142 +70,177 @@ You > /style
76
70
  You > /style concise
77
71
  switched to concise
78
72
 
79
- You > Preséntate en una sola frase.
80
- AI > Soy un agente de codificación de IA que se ejecuta sobre la plataforma de plugins DeepSeek Harness y se basa en el modelo deepseek-v4-pro.
73
+ You > 请只用一句话介绍你自己。
74
+ AI > 我是运行在 DeepSeek Harness 插件化平台上、基于 deepseek-v4-pro 模型的 AI 编码代理。
81
75
  ```
82
76
 
83
- ## 🧠 Cómo funciona
77
+ ## How it works
84
78
 
85
79
  ```mermaid
86
80
  flowchart LR
87
- U[Escribes /style concise] --> C[registro de comandos]
88
- C -->|command/run registrado| L[(log de sesión)]
89
- C -->|put {style, source}| D[(dominio output_style)]
81
+ U[You type /style concise] --> C[command registry]
82
+ C -->|command/run logged| L[(session log)]
83
+ C -->|put {style, source}| D[(output_style domain)]
90
84
  D --> R[OutputStyleRuntime]
91
- R -->|cuerpo en cada ensamblado| S[sección systemPrompt orden 90]
92
- S --> M[Petición al modelo]
93
- M -->|system prompt completo| H[request/header registrado]
85
+ R -->|body at every assembly| S[systemPrompt section order 90]
86
+ S --> M[Model request]
87
+ M -->|full system prompt| H[request/header logged]
94
88
  ```
95
89
 
96
- Todo lo que ve el modelo es reconstruible desde el log de sesión — sin nuevos tipos de eventos de sesión ni cambios en el bucle del agente. El nombre del estilo viene de `command/run`, el texto inyectado exacto de `request/header`, y el marcador de procedencia `{ kind: 'plugin', plugin: 'dsh-output-styles' }` viaja en el registro del dominio. Los estilos se aplican solo a la conversación principal; las sesiones de los subagentes mantienen sus propios prompts (igual que Claude Code).
90
+ Todo lo que el modelo ve es reconstruible desde el registro de sesión — sin un nuevo tipo de evento de sesión, sin cambios en el agent-loop. El nombre del estilo viene de `command/run`, el texto exacto inyectado de `request/header`, y el marcador de procedencia `{ kind: 'plugin', plugin: 'dsh-output-styles' }` viaja en el registro del dominio. Los estilos se aplican solo a la conversación principal; las sesiones de subagente conservan sus propios prompts (igual que Claude Code).
97
91
 
98
- ## ⚙️ Configuración
92
+ ## Install & uninstall
99
93
 
100
- Todo ajuste es un campo `Config` de Schemastery validado (los valores inválidos fallan la carga):
94
+ - **canal git** (último `main`): `dsh plugin --profile web add "github:PerryLink/dsh-output-styles#main"` el script `prepare` compila solo con dependencias de producción.
95
+ - **canal npm** (versiones publicadas): `dsh plugin --profile web add dsh-output-styles`.
96
+ - **canal tarball**: `pnpm pack` en este repo, luego `dsh plugin --profile web add ./dsh-output-styles-<version>.tgz`.
97
+ - **desinstalar**: `dsh plugin --profile web remove dsh-output-styles`.
101
98
 
102
- | Campo | Defecto | Significado |
99
+ ## Configuration
100
+
101
+ Todos los parámetros son campos Schemastery `Config` (modificables desde cordis.yml). Los valores inválidos fallan la carga.
102
+
103
+ | Key | Default | Meaning |
103
104
  |---|---|---|
104
- | `stylesDir` | `[]` | Directorios de la biblioteca de estilos, resueltos contra cwd; las entradas posteriores anulan las anteriores. `[]` = solo el `styles/` incluido. Una cadena simple es una lista de un solo directorio. |
105
- | `maxStyleChars` | `4000` | Presupuesto del cuerpo del estilo (puntos de código, ≥ 1); los cuerpos más largos se truncan con un marcador. |
106
- | `defaultStyle` | `''` | Estilo para las sesiones que nunca eligieron uno (y no existe un valor por defecto en ajustes); `''` = sin estilo. |
107
- | `compatJson` | `true` | Carga las entradas JSON `outputStyles` de Claude Code (objetos individuales o matrices). |
108
- | `sectionOrder` | `90` | Orden de la sección inyectada (0 = persona, 100–199 = guía de herramientas). |
109
- | `truncationMarker` | `"\n\n[style truncated]"` | Marcador añadido en el punto de truncado. |
110
- | `includeBuiltins` | `true` | Incluye el `styles/` incluido en el paquete como la capa de menor prioridad. |
111
- | `watchStyles` | `true` | Recarga la biblioteca cuando un archivo de estilo cambia en disco. |
112
- | `rules` | `[]` | Reglas de renderizado por sesión/herramienta: `[{ match: { tool?, contentType?, session? }, style, priority? }]` — `style` nombra un id de renderer (los integrados coinciden con los nombres de estilo). |
113
- | `enableExport` | `true` | Registrar el comando `/export` (exportación de sesión a Markdown/HTML, con renderers). |
114
-
115
- ## 🎨 Protocolo de renderers
116
-
117
- El protocolo `output.render.*` convierte la capa de presentación en un punto de extensión. Un renderer es un **presenter puro** — `presenter(text, context)` mapea argumentos a datos de presentación y nunca toca el DOM — emparejado por nombre de herramienta y tipo de contenido, ordenado por prioridad. Los plugins de terceros se registran con `ctx.outputRenderers.register({ id, match, priority, presenter })` (register devuelve el disposer, propiedad del ctx.effect del llamador). Cada renderizado pasa primero por el waterfall `output.render/before` (los listeners deben llamar `next()`), luego por la tabla de reglas (por sesión/herramienta: `rules: [{ match: { tool: 'bash' }, style: 'concise' }]`, editable en la sección de ajustes `output-style-rules`). Renderers integrados: `concise` (compresión de espacios + truncado con presupuesto) y `step-by-step` (numeración uniforme de pasos). Auditabilidad: cada resultado lleva `{ original, rendered, rendererId, changed }`; el original es el propio registro de sesión y la aplicación de renderers es determinista. `/export [markdown|html] [--renderer=<id>]` exporta la sesión actual por el mismo pipeline. Especificación completa: docs/renderer-protocol.md (inglés) / docs/renderer-protocol.zh.md.
118
- ## 📚 Biblioteca de estilos
119
-
120
- <details>
121
- <summary><code>styles/concise.md</code></summary>
122
-
123
- ```markdown
124
- ---
125
- name: concise
126
- description: Terse, direct answers — minimal prose, no preamble.
127
- whenToUse: Daily coding work, tool-heavy sessions, or when prompt length matters.
128
- keep-coding-instructions: true
129
- ---
105
+ | `stylesDir` | `[]` | Directorios de la librería, resueltos contra cwd; las entradas posteriores sobrescriben las anteriores. `[]` = solo los `styles/` integrados |
106
+ | `maxStyleChars` | `4000` | Presupuesto del cuerpo del estilo (≥ 1); los cuerpos más largos se truncan con un marcador |
107
+ | `defaultStyle` | `''` | Estilo para sesiones que nunca eligieron uno (y sin valor por defecto en settings); `''` = sin estilo |
108
+ | `compatJson` | `true` | Cargar entradas JSON `outputStyles` de Claude Code (objetos sueltos o arrays) |
109
+ | `sectionOrder` | `90` | Orden de la sección inyectada (0 = persona, 100–199 = guía de herramientas) |
110
+ | `truncationMarker` | `"\n\n[style truncated]"` | Marcador añadido en el punto de truncado |
111
+ | `includeBuiltins` | `true` | Incluir los `styles/` del paquete como capa de menor prioridad |
112
+ | `watchStyles` | `true` | Recargar la librería cuando un archivo de estilo cambia en disco |
113
+ | `rules` | `[]` | Reglas de render por sesión/herramienta: `[{ match: { tool?, contentType?, session? }, style, priority? }]` |
114
+ | `enableExport` | `true` | Registrar el comando `/export` (exportación de sesión Markdown/HTML, consciente del renderer) |
115
+
116
+ ## Tools & surfaces
117
+
118
+ | Surface | Kind | Notes |
119
+ |---|---|---|
120
+ | `/style` | command | Lista estilos, cambia o restaura el valor por defecto del proyecto |
121
+ | `/export` | command | Renderiza la sesión actual a Markdown o HTML saneado |
122
+ | `output_style` | storage domain | Elección de estilo por sesión, indexada por sessionId |
123
+ | `systemPrompt.section()` | contribution | Inyecta el cuerpo del estilo actual en cada ensamblado |
124
+ | `output.render.*` | renderer registry | `ctx.outputRenderers` + la cascada `output.render/before` |
125
+ | `style` | projection | `{ options, currentValue }` plegado desde comandos asentados |
126
+ | Web picker | client entry | `dsh-output-styles/client` decora `/style` con un selector emergente |
130
127
 
131
- You are in the concise output style for this conversation.
132
- - Lead with the direct answer; skip preamble, restatements, and filler.
133
- - 回答语言跟随用户语言:中文提问用中文回答,英文提问用英文回答。
134
- ```
128
+ ## Command reference
135
129
 
136
- </details>
130
+ | Input | Outcome |
131
+ |---|---|
132
+ | `/style` | Lista la selección actual + una línea por estilo (nombre — descripción) |
133
+ | `/style concise` | Cambia (escritura durable), `switched to concise` |
134
+ | `/style Diagrams first` | Los nombres de varias palabras son el resto completo |
135
+ | `/style off` | Restaura el valor por defecto del proyecto (default de settings, luego `defaultStyle`) |
136
+ | `/style nope` | `error: unknown output style "nope" (available: …)` |
137
+ | `/export` | Renderiza la sesión actual a Markdown a través de la pipeline de render |
138
+ | `/export html` | Renderiza a HTML saneado |
139
+ | `/export --renderer=concise` | Renderiza forzando un renderer (reglas omitidas) |
137
140
 
138
- Campos del frontmatter:
141
+ ## Style library
139
142
 
140
- | Campo | Defecto | Significado |
143
+ Un archivo Markdown por estilo; frontmatter para metadatos, cuerpo = la directiva del modelo. `name` toma por defecto el nombre del archivo y puede contener espacios (`Diagrams first`).
144
+
145
+ | Field | Default | Meaning |
141
146
  |---|---|---|
142
- | `name` | nombre del archivo | Objetivo del cambio; letras, dígitos, espacios y guiones (sin espacio inicial/final; `off` está reservado). |
143
- | `description` | — (obligatorio) | Una frase mostrada en los listados y en el selector. |
144
- | `whenToUse` | — | Guía opcional añadida a los listados. |
145
- | `keep-coding-instructions` | `false` | Conserva el prompt del harness (identidad, persona, guía de herramientas) cuando es `true`; lo reemplaza por completo cuando es `false` (semántica de Claude Code). |
146
- | `force-for-plugin` | `false` | Campo oficial de Claude Code: se aplica incondicionalmente, anulando cualquier selección de sesión; `force` es un alias y como máximo un estilo puede activarlo. |
147
+ | `name` | nombre del archivo | Destino del cambio; letras, dígitos, espacios y guiones (`off` está reservado) |
148
+ | `description` | — (obligatorio) | Una frase mostrada en listados y el selector |
149
+ | `whenToUse` | — | Guía opcional añadida a los listados |
150
+ | `keep-coding-instructions` | `false` | Mantener el prompt del harness cuando `true`; reemplazarlo cuando `false` (semántica Claude Code) |
151
+ | `force-for-plugin` | `false` | Aplicar incondicionalmente, sobrescribiendo cualquier selección de sesión; `force` es un alias, a lo sumo un estilo puede fijarlo |
147
152
 
148
- <details>
149
- <summary>JSON de Claude Code <code>outputStyles</code> (<code>compatJson: true</code>)</summary>
153
+ Con `compatJson: true`, las entradas JSON `outputStyles` de Claude Code (`{ name, description, prompt }`) cargan junto a los estilos Markdown; las entradas no analizables se omiten con una advertencia.
150
154
 
151
- ```json
152
- { "name": "explain", "description": "Explain like a teacher.", "prompt": "Teach in small steps." }
153
- ```
155
+ ## Renderer protocol
154
156
 
155
- Las entradas aceptan `keep-coding-instructions` y `force-for-plugin` exactamente como los escribe Claude Code. Las matrices heredadas de `settings.json` (`[{ }, { }]`) se cargan tal cual; las entradas incorrectas se omiten con un aviso.
157
+ El protocolo `output.render.*` convierte la presentación en un punto de extensión. Un renderer es un **presenter puro** — `presenter(text, context)` mapea argumentos a datos de visualización, nunca toca el DOM emparejado por nombre de herramienta y tipo de contenido, ordenado por prioridad.
156
158
 
157
- </details>
159
+ - **Waterfall primero**: toda solicitud de render pasa por `output.render/before` (`{ text, context }`); los listeners deben llamar `next()`.
160
+ - **Rules**: `rules: [{ match: { tool: 'bash' }, style: 'concise' }]` nombra el renderer para solicitudes coincidentes; los empates se resuelven por `priority` y luego por orden de regla.
161
+ - **Built-ins**: `concise` (compactación de espacios + truncado por presupuesto) y `step-by-step` (numeración de pasos consistente).
162
+ - **Auditabilidad**: cada resultado de render lleva `{ original, rendered, rendererId, changed }`; el texto renderizado es lo que se muestra, el original sigue siendo reconstruible desde el registro de sesión.
158
163
 
159
- ## ⌨️ Referencia de comandos
164
+ ## Web picker
160
165
 
161
- | Entrada | Resultado |
162
- |---|---|
163
- | `/style` | Lista la selección actual + una línea por estilo (nombre — descripción) |
164
- | `/style concise` | Cambia (escritura duradera), `switched to concise` |
165
- | `/style Diagrams first` | Los nombres de varias palabras son todo el resto |
166
- | `/style off` | Restaura el valor por defecto del proyecto (valor por defecto de ajustes, luego `defaultStyle`) |
167
- | `/style nope` | `error: unknown output style "nope" (available: …)` |
166
+ La entrada `dsh.client` decora la invocación desnuda del comando `/style` con un selector emergente: una fila "off" más una fila por estilo de la librería (`description · whenToUse`), con la fila activa marcada. Elegir envía `/style <name>` a través del Remote de comandos, de modo que cada cambio conserva el ciclo de vida durable del comando host. El selector sigue el par de idiomas `zh`/`en` de la Web UI.
168
167
 
169
- ## 🖱️ Selector web
168
+ ## Differences from Claude Code
170
169
 
171
- La entrada `dsh.client` decora la invocación sin argumentos del comando `/style` del host con un selector emergente: una fila «off» más una fila por estilo de la biblioteca (`description · whenToUse`), con la fila activa marcada. Al elegir se envía `/style <name>` a través del Remote de comandos, de modo que cada cambio conserva el ciclo de vida duradero de comandos del host y la proyección `style` sigue siendo el único dato mostrado. Los textos del selector siguen el par de idiomas `zh`/`en` que incluye la Web UI.
170
+ | | Claude Code | dsh-output-styles |
171
+ |---|---|---|
172
+ | Archivos de estilo | `.claude/output-styles` en niveles usuario/proyecto/gestionado | directorios `stylesDir` + `styles/` integrados, gana el directorio posterior |
173
+ | Estilos personalizados | Markdown, frontmatter `name`/`description`/`keep-coding-instructions`/`force-for-plugin` | Mismos campos (`force-for-plugin` aceptado textualmente, `force` como alias) + `whenToUse` |
174
+ | JSON heredado | array `outputStyles` en `settings.json` | Cargado textualmente (`compatJson: true`) |
175
+ | Cuándo entra en vigor | Después de `/clear` o una sesión nueva | Inmediatamente — el prompt del sistema se reensambla por solicitud |
176
+ | Subagentes | Los estilos no se aplican | Igual — las sesiones de subagente conservan sus propios prompts |
177
+ | Cambio | menú `/config` o ajuste `outputStyle` (el comando `/output-style` se eliminó en v2.1.91) | comando `/style` + Web picker + settings `output-style.style` |
172
178
 
173
- ## 🔍 Verificación de conflictos
179
+ ## Conflict check
174
180
 
175
- Se contrastó con el ecosistema DSH antes del desarrollo (instantánea 2026-08): ningún repositorio `style`/`output-style` bajo [topic:dsh-plugin](https://github.com/topics/dsh-plugin), ninguna categoría de output-style en las cuatro [listas awesome](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin) principales, y ninguna entrada en el [catálogo dsh-hub](https://github.com/omdsh-dev/dsh-hub-workshop). Los vecinos más cercanos — [dsh-soul-md](https://github.com/Scorp1o117/dsh-soul-md) (persona) y [dsh-claude-marketplace](https://github.com/ben7am1n/dsh-claude-marketplace) (estilos de salida diferidos explícitamente a v0.2+) — son adyacentes, no conflictivos.
181
+ Filtrado contra el ecosistema DSH antes del desarrollo (instantánea 2026-08): ningún repositorio `style`/`output-style` bajo [topic:dsh-plugin](https://github.com/topics/dsh-plugin), ninguna categoría de output-style en las cuatro principales [awesome lists](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin), y ninguna entrada en el [catálogo dsh-hub](https://github.com/omdsh-dev/dsh-hub-workshop). Los vecinos más cercanos — [dsh-soul-md](https://github.com/Scorp1o117/dsh-soul-md) (persona) y [dsh-claude-marketplace](https://github.com/ben7am1n/dsh-claude-marketplace) (estilos de salida diferidos explícitamente a v0.2+) — son adyacentes, no conflictivos.
176
182
 
177
- ## 🆚 Diferencias con Claude Code
183
+ ## Permissions & data
178
184
 
179
- | | Claude Code | dsh-output-styles |
180
- |---|---|---|
181
- | Archivos de estilo | `.claude/output-styles` en los niveles usuario/proyecto/gestionado | Directorios `stylesDir` + `styles/` incluido, gana el directorio posterior |
182
- | Estilos personalizados | Markdown, frontmatter `name`/`description`/`keep-coding-instructions`/`force-for-plugin` | Los mismos campos (`force-for-plugin` aceptado literalmente, `force` como alias) + `whenToUse` |
183
- | JSON heredado | Matriz `outputStyles` en `settings.json` | Se carga tal cual (`compatJson: true`) |
184
- | Entrada en vigor | Tras `/clear` o una sesión nueva | Inmediatamente — el system prompt se reensambla en cada petición |
185
- | Subagentes | Los estilos no se aplican | Igual — las sesiones de los subagentes mantienen sus propios prompts |
186
- | Cambio | Menú `/config` o ajuste `outputStyle` (el comando `/output-style` se eliminó en v2.1.91) | Comando `/style` + selector web + ajustes `output-style.style` |
185
+ - **Permissions**: el manifiesto de workshop declara `fs:read`, `fs:watch`, `storage:read`, `storage:write` y `settings:read`.
186
+ - **Data**: la elección de estilo vive en el dominio de almacenamiento `output_style` (indexada por sessionId); no se persiste otro estado, sin solicitudes de red.
187
+ - **Session log**: el nombre del estilo viene de `command/run`, el texto exacto inyectado de `request/header`; el marcador de procedencia `{ kind: 'plugin', plugin: 'dsh-output-styles' }` viaja en el registro del dominio.
187
188
 
188
- ## 🧪 Desarrollo
189
+ ## Security boundaries
190
+
191
+ - **Solo servicios públicos.** Contribuye `systemPrompt`, comandos, almacenamiento y settings; sin cambios en engine / agent-loop / apiproxy / UI oficial.
192
+ - **Visible para el modelo ⟺ registrado.** Todo lo que el modelo ve es reconstruible desde el registro de sesión — sin un nuevo tipo de evento de sesión, sin cambios en el agent-loop.
193
+ - **Original siempre conservado.** Cada render (y `/export`) conserva el texto original junto al renderizado; para la exportación HTML se usa HTML saneado.
194
+
195
+ ## Known limitations
196
+
197
+ - **Solo conversación principal.** Los estilos se aplican a la conversación principal; las sesiones de subagente conservan sus propios prompts (igual que Claude Code).
198
+ - **Truncado.** Los cuerpos de estilo más largos que `maxStyleChars` se truncan con un marcador.
199
+ - **Archivos omitidos.** Un archivo de estilo defectuoso se omite con una advertencia y nunca rompe el profile.
200
+
201
+ ## Development
189
202
 
190
203
  ```sh
191
204
  pnpm install
192
205
  pnpm run typecheck # ambos proyectos tsc
193
- pnpm test # vitest — 93 pruebas
194
- pnpm run verify # typecheck + pruebas + verificación autocontenida (puerta de prepublishOnly)
195
- pnpm run build # artefactos lib/ (bundles de host + cliente)
206
+ pnpm test # vitest — 107 tests
207
+ pnpm run verify # typecheck + tests + self-contained (la puerta de prepublishOnly)
208
+ pnpm run build # artefactos lib/ (bundles host + client)
196
209
  pnpm pack # tarball para dsh plugin add
197
210
  ```
198
211
 
199
- Lanzamientos: hacer push de una etiqueta `v*` cuyo sufijo coincida con la versión de `package.json` dispara el flujo Publish — verificación completa y publicación en npm (con provenance). Cualquier `npm publish` también pasa la puerta `verify` vía `prepublishOnly`.
212
+ Lanzamientos: empujar una etiqueta `v*` cuyo sufijo coincide con la versión de `package.json` dispara el workflow Publish — verificación completa y luego publicación a npm con procedencia.
200
213
 
201
- La estructura sigue [omdsh-dev/plugin-template](https://github.com/omdsh-dev/plugin-template): `src/index.ts` (metadatos del plugin), `src/config.ts` (esquema), `src/runtime.ts` (servicio de runtime + activación), `src/invariant.ts` (invariantes), `src/client/` (selector web), `styles/` (estilos integrados).
214
+ ## Topics
202
215
 
203
- ## 👥 Contribuyentes
216
+ `deepseek-harness`, `dsh`, `dsh-plugin`, `output-style`, `output-styles`, `claude-code`
204
217
 
205
- Gracias a todas las personas que han contribuido a este proyecto:
218
+ ## Contributors
206
219
 
207
- - [@PerryLink](https://github.com/PerryLink) — autor y mantenedor: arquitectura del plugin, biblioteca de estilos, instalación del bundle, selector web, documentación en cinco idiomas y herramientas de CI/publicación.
220
+ - [@PerryLink](https://github.com/PerryLink) — autor y mantenedor: arquitectura del plugin, librería de estilos, instalación de bundle, Web picker, documentación en cinco idiomas y herramientas de CI/lanzamiento.
208
221
 
209
- ¿Encontraste un error o tienes una idea? Abre un [issue](https://github.com/PerryLink/dsh-output-styles/issues) o envía un [pull request](https://github.com/PerryLink/dsh-output-styles/pulls) — las contribuciones en cualquier idioma son bienvenidas.
222
+ ## PerryLink DSH Plugin Family
210
223
 
211
- ## 📄 Licencia
224
+ Este proyecto es uno de los [15 plugins de DeepSeek Harness](https://github.com/PerryLink) mantenidos por [PerryLink](https://github.com/PerryLink). Si este te ayuda, los demás probablemente también:
212
225
 
213
- [Apache-2.0](LICENSE) © 2026 dsh-output-styles contributors
214
-
215
- ---
216
-
217
- <sub>Topics: `dsh` · `dsh-plugin` · `deepseek-harness` · `output-styles` · `claude-code`</sub>
226
+ | Plugin | One-liner |
227
+ |---|---|
228
+ | [dsh-mcp-panel](https://github.com/PerryLink/dsh-mcp-panel) | Read-only MCP runtime panel: /mcp command + Settings tab with status, tools and errors |
229
+ | [dsh-doublecheck](https://github.com/PerryLink/dsh-doublecheck) | Engineering-discipline guard: requirements grill, test gates, adversary review |
230
+ | [dsh-background-agents](https://github.com/PerryLink/dsh-background-agents) | Durable background child agents with a Web UI sidebar, messaging and interrupt |
231
+ | [dsh-lsp-actions](https://github.com/PerryLink/dsh-lsp-actions) | LSP diagnostics, formatting, completion, code actions and rename over language servers |
232
+ | **[dsh-output-styles](https://github.com/PerryLink/dsh-output-styles)** | Claude Code outputStyles-equivalent runtime style switching |
233
+ | [dsh-checkpoint-rewind](https://github.com/PerryLink/dsh-checkpoint-rewind) | Claude Code /rewind-equivalent: snapshots, session forks, one-shot restore |
234
+ | [dsh-permission-rules](https://github.com/PerryLink/dsh-permission-rules) | Claude Code-style declarative allow/deny/ask permission rules with audit |
235
+ | [dsh-auto-review](https://github.com/PerryLink/dsh-auto-review) | Second-model auto-review on the approval chain, fail-closed by default |
236
+ | [dsh-memento](https://github.com/PerryLink/dsh-memento) | Approval-gated cross-session memory: ctx.memory seam + SQLite + memory tool |
237
+ | [dsh-skill-pack-security](https://github.com/PerryLink/dsh-skill-pack-security) | Security-audit skill pack: secret scan, dependency and supply-chain review |
238
+ | [dsh-session-pin](https://github.com/PerryLink/dsh-session-pin) | Pin sessions in the Web sidebar with durable ordering |
239
+ | [dsh-composer-history](https://github.com/PerryLink/dsh-composer-history) | Terminal-style input history for the web composer: arrows, Ctrl+R search |
240
+ | [dsh-github](https://github.com/PerryLink/dsh-github) | GitHub PR/issues integration for DSH, every write gated by approval |
241
+ | [dsh-plugin-guide](https://github.com/PerryLink/dsh-plugin-guide) | Plugin-development knowledge base as an on-demand agent skill |
242
+ | [dsh-claude-move](https://github.com/PerryLink/dsh-claude-move) | Migrate Claude Code sessions, memory, skills and CLAUDE.md into DSH |
243
+
244
+ ## License
245
+
246
+ [Apache License 2.0](LICENSE) © 2026 dsh-output-styles contributors