dsh-output-styles 0.3.2 → 0.4.1

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,27 @@ 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.1] - 2026-08-19
8
+
9
+ ### Fixed
10
+
11
+ - **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.
12
+
13
+ ## [0.4.0] - 2026-08-16
14
+
15
+ ### Added
16
+
17
+ - **Renderer registry (`output.render.*` protocol)**: `ctx.outputRenderers` service with reversible `register()` / `list()` / `resolve()` / `renderText()`. A renderer is `{ id, match (tool/content-type), priority, presenter }` — the presenter is a pure function (args → display data, no DOM). Every render request passes the `output.render/before` waterfall first (listeners transform `{ text, context }` and must call `next()`), then the rule table, then matching renderers in priority order. Built-in renderers: `concise` and `step-by-step`.
18
+ - **Per-session/per-tool style rules**: `rules: [{ match: { tool, contentType, session }, style, priority }]` in Config and the new `output-style-rules` settings section (validated at write time; unknown renderer ids fail loudly at render time).
19
+ - **`/export` command**: renders the current session's message surface (official `deriveEventMessage` projection) to Markdown or sanitized HTML through the renderer pipeline — `/export [markdown|html] [--renderer=<id>]`. Every render keeps `{ original, rendered, rendererId, changed }`, so rendered output and its session-log source reconstruct together.
20
+ - `sanitizeText` / `toMarkdown` / `toHtml` / `renderExport` pure functions with extreme-case coverage (tags, control characters, huge inputs).
21
+ - Renderer protocol reference: `docs/renderer-protocol.md` (+ 中文).
22
+
23
+ ### Changed
24
+
25
+ - `/style` command and per-session persistence are fully unchanged (0.3.x compatible).
26
+ - Five-language READMEs: renderer protocol section, two new Config rows, `/export` reference; test count updated to 107.
27
+
7
28
  ## [0.3.2] - 2026-08-15
8
29
 
9
30
  ### Fixed
package/README.es.md CHANGED
@@ -2,64 +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)
9
11
  [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
10
- [![DSH](https://img.shields.io/badge/deepseek--harness-0.1.0--rc.6-4d6bfe.svg)](#)
11
- [![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178c6.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)
14
+ [![npm version](https://img.shields.io/npm/v/dsh-output-styles)](https://www.npmjs.com/package/dsh-output-styles)
15
+ [![npm downloads](https://img.shields.io/npm/dm/dsh-output-styles)](https://www.npmjs.com/package/dsh-output-styles)
12
16
 
13
- 🌐 [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)
14
18
 
15
19
  </div>
16
20
 
17
21
  ---
18
22
 
19
- `/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.
20
-
21
- ## ✨ Características
23
+ ## Compatibility
22
24
 
23
- | | |
25
+ | Surface | Status |
24
26
  |---|---|
25
- | 🗂️ **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. |
26
- | ⌨️ **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. |
27
- | 💾 **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. |
28
- | 🧩 **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. |
29
- | 🎭 **`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. |
30
- | 📌 **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. |
31
- | 🔁 **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. |
32
- | 📚 **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`). |
33
- | 🔄 **Recarga en caliente** | Los cambios en los archivos de estilo se detectan sin reiniciar (`watchStyles: false` para desactivarlo). |
34
- | ⚙️ **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`. |
35
- | 🖱️ **Selector web** | Una entrada `dsh.client` (`dsh-output-styles/client`) decora el comando `/style` del host con un selector emergente basado en proyecciones. |
36
- | 📊 **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. |
37
- | 🧯 **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. |
38
- | 🌐 **Documentación en cinco idiomas** | EN · 中文 · 日本語 · 한국어 · Español. |
39
-
40
- ## 🚀 Inicio rápido
27
+ | Harness | DeepSeek Harness `0.1.0-rc.6` |
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
41
46
 
42
47
  ```sh
43
- # 1. Instalar el paquete es una capa de bundle, así que un comando compone
44
- # storage + storage-json + storage-domain + la fila del plugin:
45
- dsh plugin --profile <name> add dsh-output-styles
46
-
47
- # 2. Arrancar y cambiar
48
- dsh --profile <name>
49
- /style # → output style off y luego una línea por estilo
50
- /style concise # → switched to concise
51
- /style Diagrams first # → los nombres con espacios también funcionan
52
- /style off # → de vuelta al valor por defecto del proyecto
53
- ```
48
+ # 1. install the bundle into your profile
49
+ dsh plugin --profile web add "github:PerryLink/dsh-output-styles#main"
54
50
 
55
- 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
56
53
 
57
- ```yaml
58
- - id: output-styles-client
59
- name: 'dsh-output-styles/client'
54
+ # 2. restart and verify the row
55
+ dsh --profile web --dump-config | grep -A3 'id: output-styles'
60
56
  ```
61
57
 
62
- ## 🎬 Demo
58
+ ## Demo
63
59
 
64
60
  ```
65
61
  You > /style
@@ -74,129 +70,177 @@ You > /style
74
70
  You > /style concise
75
71
  switched to concise
76
72
 
77
- You > Preséntate en una sola frase.
78
- 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 编码代理。
79
75
  ```
80
76
 
81
- ## 🧠 Cómo funciona
77
+ ## How it works
82
78
 
83
79
  ```mermaid
84
80
  flowchart LR
85
- U[Escribes /style concise] --> C[registro de comandos]
86
- C -->|command/run registrado| L[(log de sesión)]
87
- 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)]
88
84
  D --> R[OutputStyleRuntime]
89
- R -->|cuerpo en cada ensamblado| S[sección systemPrompt orden 90]
90
- S --> M[Petición al modelo]
91
- 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]
92
88
  ```
93
89
 
94
- 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).
95
91
 
96
- ## ⚙️ Configuración
92
+ ## Install & uninstall
97
93
 
98
- 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`.
99
98
 
100
- | Campo | Defecto | Significado |
101
- |---|---|---|
102
- | `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. |
103
- | `maxStyleChars` | `4000` | Presupuesto del cuerpo del estilo (puntos de código, ≥ 1); los cuerpos más largos se truncan con un marcador. |
104
- | `defaultStyle` | `''` | Estilo para las sesiones que nunca eligieron uno (y no existe un valor por defecto en ajustes); `''` = sin estilo. |
105
- | `compatJson` | `true` | Carga las entradas JSON `outputStyles` de Claude Code (objetos individuales o matrices). |
106
- | `sectionOrder` | `90` | Orden de la sección inyectada (0 = persona, 100–199 = guía de herramientas). |
107
- | `truncationMarker` | `"\n\n[style truncated]"` | Marcador añadido en el punto de truncado. |
108
- | `includeBuiltins` | `true` | Incluye el `styles/` incluido en el paquete como la capa de menor prioridad. |
109
- | `watchStyles` | `true` | Recarga la biblioteca cuando un archivo de estilo cambia en disco. |
99
+ ## Configuration
110
100
 
111
- ## 📚 Biblioteca de estilos
101
+ Todos los parámetros son campos Schemastery `Config` (modificables desde cordis.yml). Los valores inválidos fallan la carga.
112
102
 
113
- <details>
114
- <summary><code>styles/concise.md</code></summary>
103
+ | Key | Default | Meaning |
104
+ |---|---|---|
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 |
115
127
 
116
- ```markdown
117
- ---
118
- name: concise
119
- description: Terse, direct answers — minimal prose, no preamble.
120
- whenToUse: Daily coding work, tool-heavy sessions, or when prompt length matters.
121
- keep-coding-instructions: true
122
- ---
128
+ ## Command reference
123
129
 
124
- You are in the concise output style for this conversation.
125
- - Lead with the direct answer; skip preamble, restatements, and filler.
126
- - 回答语言跟随用户语言:中文提问用中文回答,英文提问用英文回答。
127
- ```
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) |
128
140
 
129
- </details>
141
+ ## Style library
130
142
 
131
- Campos del frontmatter:
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`).
132
144
 
133
- | Campo | Defecto | Significado |
145
+ | Field | Default | Meaning |
134
146
  |---|---|---|
135
- | `name` | nombre del archivo | Objetivo del cambio; letras, dígitos, espacios y guiones (sin espacio inicial/final; `off` está reservado). |
136
- | `description` | — (obligatorio) | Una frase mostrada en los listados y en el selector. |
137
- | `whenToUse` | — | Guía opcional añadida a los listados. |
138
- | `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). |
139
- | `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 |
140
152
 
141
- <details>
142
- <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.
143
154
 
144
- ```json
145
- { "name": "explain", "description": "Explain like a teacher.", "prompt": "Teach in small steps." }
146
- ```
155
+ ## Renderer protocol
147
156
 
148
- 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.
149
158
 
150
- </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.
151
163
 
152
- ## ⌨️ Referencia de comandos
164
+ ## Web picker
153
165
 
154
- | Entrada | Resultado |
155
- |---|---|
156
- | `/style` | Lista la selección actual + una línea por estilo (nombre — descripción) |
157
- | `/style concise` | Cambia (escritura duradera), `switched to concise` |
158
- | `/style Diagrams first` | Los nombres de varias palabras son todo el resto |
159
- | `/style off` | Restaura el valor por defecto del proyecto (valor por defecto de ajustes, luego `defaultStyle`) |
160
- | `/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.
161
167
 
162
- ## 🖱️ Selector web
168
+ ## Differences from Claude Code
163
169
 
164
- 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` |
165
178
 
166
- ## 🔍 Verificación de conflictos
179
+ ## Conflict check
167
180
 
168
- 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.
169
182
 
170
- ## 🆚 Diferencias con Claude Code
183
+ ## Permissions & data
171
184
 
172
- | | Claude Code | dsh-output-styles |
173
- |---|---|---|
174
- | Archivos de estilo | `.claude/output-styles` en los niveles usuario/proyecto/gestionado | Directorios `stylesDir` + `styles/` incluido, gana el directorio posterior |
175
- | Estilos personalizados | Markdown, frontmatter `name`/`description`/`keep-coding-instructions`/`force-for-plugin` | Los mismos campos (`force-for-plugin` aceptado literalmente, `force` como alias) + `whenToUse` |
176
- | JSON heredado | Matriz `outputStyles` en `settings.json` | Se carga tal cual (`compatJson: true`) |
177
- | Entrada en vigor | Tras `/clear` o una sesión nueva | Inmediatamente — el system prompt se reensambla en cada petición |
178
- | Subagentes | Los estilos no se aplican | Igual — las sesiones de los subagentes mantienen sus propios prompts |
179
- | 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.
180
188
 
181
- ## 🧪 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
182
202
 
183
203
  ```sh
184
204
  pnpm install
185
205
  pnpm run typecheck # ambos proyectos tsc
186
- pnpm test # vitest — 93 pruebas
187
- pnpm run verify # typecheck + pruebas + verificación autocontenida (puerta de prepublishOnly)
188
- 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)
189
209
  pnpm pack # tarball para dsh plugin add
190
210
  ```
191
211
 
192
- 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.
193
213
 
194
- 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
195
215
 
196
- ## 📄 Licencia
216
+ `deepseek-harness`, `dsh`, `dsh-plugin`, `output-style`, `output-styles`, `claude-code`
197
217
 
198
- [Apache-2.0](LICENSE) © 2026 dsh-output-styles contributors
218
+ ## Contributors
199
219
 
200
- ---
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.
221
+
222
+ ## PerryLink DSH Plugin Family
201
223
 
202
- <sub>Topics: `dsh` · `dsh-plugin` · `deepseek-harness` · `output-styles` · `claude-code`</sub>
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:
225
+
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