dsh-doctor
asdf17128
Find what your DeepSeek Harness (dsh) patches silently broke — dead patches, config fields dropped by whole-config repla…
PROJECT TOPICS
PROJECT README
Claude Code outputStyles for DeepSeek Harness — switch the model's output style at runtime, per session, durably.
/style concise — and every reply from now on is terse. /style step-by-step — and the model narrates numbered steps. /style off — back to the project default. One command per session, persisted across restarts, zero changes to the agent loop.
| 🗂️ Style library | One Markdown file per style (styles/*.md); frontmatter for metadata, body = the model directive. name defaults to the file name and may contain spaces (Diagrams first). Six built-ins ship in the box, including Claude Code-parity proactive and learning. |
⌨️ /style command |
No argument lists styles (with descriptions) + current selection; /style <name> switches; /style off restores the project default. The whole remainder after /style is the style name. |
| 💾 Session-scoped persistence | The choice lives in the output_style storage domain, keyed by sessionId — two sessions never interfere, and the choice survives restarts. |
| 🧩 System-prompt injection | A systemPrompt.section() contribution (order 90) injects the current session's style body at every assembly; bodies are truncated at a configurable budget. |
🎭 Claude Code keep-coding-instructions |
Styles with keep-coding-instructions: false (the default, like Claude Code) replace the whole system prompt — for styles that leave software engineering behind. |
| 📌 Forced styles | Claude Code's force-for-plugin (alias force) applies a style unconditionally, overriding any session selection; two forced styles fail the load. |
| 🔁 Claude Code compatibility | Loads outputStyles JSON collections ({ name, description, prompt }), single entries or settings.json-style arrays; unparseable entries are skipped with a warning. |
| 📚 Layered directories | stylesDir is a list; later directories override earlier ones (bundled styles/ is the lowest layer, disable with includeBuiltins: false). |
| 🔄 Hot reload | Style-file changes are picked up without restarting (watchStyles: false to opt out). |
| ⚙️ Project default over settings | Sessions that never selected one fall back to output-style.style from the DSH settings seam, then to defaultStyle. |
| 🖱️ Web picker | A dsh.client entry (dsh-output-styles/client) decorates the host /style command with a projection-backed popup picker. |
| 📊 Session projection | A style projection ({ options, currentValue }) for the Web UI, folded from settled commands in the session log. |
| 🎨 *Renderer registry (`output.render.`)** | ctx.outputRenderers lets any plugin register a presenter — { id, match (tool/content-type), presenter, priority } — applied through the output.render/before waterfall (listeners must next()). Built-in renderers: concise, step-by-step. Registration is reversible and owned by the caller's ctx.effect. |
| 🧾 Per-session/per-tool rules | rules: [{ match: { tool: 'bash' }, style: 'concise' }] — first matching rule (by priority) names the renderer; match.session scopes a rule to one session. Editable through the output-style-rules settings section. |
📤 /export |
Renders the current session's message surface to Markdown or sanitized HTML through the render pipeline (/export [markdown|html] [--renderer=<id>]); every render keeps its original text beside the rendered one, and the original always stays reconstructable from the session log. |
| 🧯 Fail loud, skip cleanly | Misconfiguration throws at load; a bad style file is skipped with a warning and never breaks the profile. |
| 🌐 Five-language docs | EN · 中文 · 日本語 · 한국어 · Español. |
# 1. Install — the package is a bundle layer, so one command composes
# storage + storage-json + storage-domain + the plugin row:
dsh plugin --profile <name> add dsh-output-styles
# 2. Boot and switch
dsh --profile <name>
/style # → output style off, then one line per style
/style concise # → switched to concise
/style Diagrams first # → names with spaces work too
/style off # → back to the project default
The layer is idempotent over web profiles (insert-by-id replaces same-id rows), which compose storage in box. For the Web picker, add the client row to the profile:
- id: output-styles-client
name: 'dsh-output-styles/client'
You > /style
output style off
concise — Terse, direct answers — minimal prose, no preamble. (Daily coding work, tool-heavy sessions, or when prompt length matters.)
explanatory — Educational answers with short "Insights" that teach as you work. (Learning a codebase, onboarding, …)
formal — Formal, precise prose with complete sentences and defined terms. (Reports, documentation, release notes, …)
learning — Collaborative learn-by-doing mode with short "Insights" and small hands-on steps for the user. (Pairing, onboarding, …)
proactive — Execute immediately, assume reasonable defaults, and prefer action over planning. (Routine multi-step work, …)
step-by-step — Numbered reasoning steps with explicit intermediate results. (Debugging, design decisions, …)
You > /style concise
switched to concise
You > 请只用一句话介绍你自己。
AI > 我是运行在 DeepSeek Harness 插件化平台上、基于 deepseek-v4-pro 模型的 AI 编码代理。
flowchart LR
U[You type /style concise] --> C[command registry]
C -->|command/run logged| L[(session log)]
C -->|put {style, source}| D[(output_style domain)]
D --> R[OutputStyleRuntime]
R -->|body at every assembly| S[systemPrompt section order 90]
S --> M[Model request]
M -->|full system prompt| H[request/header logged]
Everything the model sees is reconstructable from the session log — no new session event type, no agent-loop changes. The style name comes from command/run, the exact injected text from request/header, and the provenance marker { kind: 'plugin', plugin: 'dsh-output-styles' } rides in the domain record. Styles apply to the main conversation only; subagent sessions keep their own prompts (matching Claude Code).
Every tunable is a validated Schemastery Config field (invalid values fail the load):
| Field | Default | Meaning |
|---|---|---|
stylesDir |
[] |
Style-library directories, resolved against cwd; later entries override earlier ones. [] = the bundled styles/ only. A bare string is a single-directory list. |
maxStyleChars |
4000 |
Style-body budget (code points, ≥ 1); longer bodies are truncated with a marker. |
defaultStyle |
'' |
Style for sessions that never selected one (and no settings default exists); '' = no style. |
compatJson |
true |
Load Claude Code outputStyles JSON entries (single objects or arrays). |
sectionOrder |
90 |
Order of the injected section (0 = persona, 100–199 = tool guidance). |
truncationMarker |
"\n\n[style truncated]" |
Marker appended at the truncation point. |
includeBuiltins |
true |
Include the package's bundled styles/ as the lowest-priority layer. |
watchStyles |
true |
Reload the library when a style file changes on disk. |
rules |
[] |
Per-session/per-tool render rules: [{ match: { tool?, contentType?, session? }, style, priority? }] — style names a renderer id (built-ins mirror the style names). |
enableExport |
true |
Register the /export command (Markdown/HTML session export, renderer-aware). |
styles/concise.md---
name: concise
description: Terse, direct answers — minimal prose, no preamble.
whenToUse: Daily coding work, tool-heavy sessions, or when prompt length matters.
keep-coding-instructions: true
---
You are in the concise output style for this conversation.
- Lead with the direct answer; skip preamble, restatements, and filler.
- 回答语言跟随用户语言:中文提问用中文回答,英文提问用英文回答。
Frontmatter fields:
| Field | Default | Meaning |
|---|---|---|
name |
file name | Switch target; letters, digits, spaces, and hyphens (no leading/trailing space; off is reserved). |
description |
— (required) | One sentence shown in listings and the picker. |
whenToUse |
— | Optional guidance appended to listings. |
keep-coding-instructions |
false |
Keep the harness prompt (identity, persona, tool guidance) when true; replace it entirely when false (Claude Code semantics). |
force-for-plugin |
false |
Claude Code's field: apply unconditionally, overriding any session selection; force is accepted as an alias, and at most one style may set it. |
outputStyles JSON (compatJson: true){ "name": "explain", "description": "Explain like a teacher.", "prompt": "Teach in small steps." }
Entries accept keep-coding-instructions and force-for-plugin exactly as Claude Code writes them. Legacy settings.json arrays ([{ … }, { … }]) load as-is; bad entries are skipped with a warning.
| Input | Outcome |
|---|---|
/style |
List current selection + one line per style (name — description) |
/style concise |
Switch (durable write), switched to concise |
/style Diagrams first |
Multi-word names are the whole remainder |
/style off |
Restore the project default (settings default, then defaultStyle) |
/style nope |
error: unknown output style "nope" (available: …) |
/export |
Render the current session to Markdown through the renderer pipeline |
/export html |
Render to sanitized HTML |
/export --renderer=concise |
Render with one renderer forced (rules bypassed) |
The output.render.* protocol turns the presentation layer into an extension point. A renderer is a pure presenter — presenter(text, context) maps args to display data, never touches the DOM — matched by tool name and content type, ordered by priority:
// Third-party plugin registering a custom renderer (register() returns the disposer)
ctx.effect(() => ctx.outputRenderers.register({
id: 'sql-table',
name: 'SQL table compactor',
description: 'Truncates oversized SQL result sets to the head plus a row count.',
match: [{ tool: 'sql', contentType: 'text' }],
priority: 20,
presenter: (text, context) => compactRows(text, 50),
}))
output.render/before ({ text, context }) — listeners transform the request and must call next(); returning without it short-circuits the pipeline.rules: [{ match: { tool: 'bash' }, style: 'concise' }] names the renderer for matching requests (tool, content type, or exact session); ties break by priority, then rule order. Rules live in cordis.yml and the output-style-rules settings section.concise (whitespace compaction + budget truncation) and step-by-step (consistent step numbering) — ids mirror the two headline style names.{ original, rendered, rendererId, changed }. The rendered text is what surfaces; the original text is the session log itself, and the render application is deterministic — so rendered output and its source always reconstruct together.The dsh.client entry decorates the host /style command's bare invocation with a popup picker: an "off" row plus one row per library style (description · whenToUse), the active row marked. Picking submits /style <name> through the command Remote, so every switch keeps the host's durable command lifecycle and the style projection stays the single displayed fact. The picker follows the Web UI's shipped zh/en locale pair.
Screened against the DSH ecosystem before development (2026-08 snapshot): no style/output-style repository under topic:dsh-plugin, no output-style category in the four major awesome lists, and no entry in the dsh-hub catalog. The closest neighbors — dsh-soul-md (persona) and dsh-claude-marketplace (output styles explicitly deferred to v0.2+) — are adjacent, not conflicting.
| Claude Code | dsh-output-styles | |
|---|---|---|
| Style files | .claude/output-styles at user/project/managed levels |
stylesDir directories + bundled styles/, later directory wins |
| Custom styles | Markdown, frontmatter name/description/keep-coding-instructions/force-for-plugin |
Same fields (force-for-plugin accepted verbatim, force as alias) + whenToUse |
| Legacy JSON | outputStyles array in settings.json |
Loaded verbatim (compatJson: true) |
| Taking effect | After /clear or a new session |
Immediately — the system prompt re-assembles per request |
| Subagents | Styles do not apply | Same — subagent sessions keep their own prompts |
| Switching | /config menu or outputStyle setting (the /output-style command was removed in v2.1.91) |
/style command + Web picker + settings output-style.style |
pnpm install
pnpm run typecheck # both tsc projects
pnpm test # vitest — 107 tests
pnpm run verify # typecheck + tests + self-contained (the prepublishOnly gate)
pnpm run build # lib/ artifacts (host + client bundles)
pnpm pack # tarball for dsh plugin add
Releases: pushing a v* tag whose suffix matches the package.json version triggers the Publish workflow — full verification, then an npm publish with provenance. Any npm publish also passes the verify gate through prepublishOnly.
Structure follows the omdsh-dev/plugin-template: src/index.ts (plugin metadata), src/config.ts (schema), src/runtime.ts (runtime service + activation), src/invariant.ts (invariants), src/client/ (Web picker), styles/ (built-ins).
Thanks to everyone who helped build this project:
Found a bug or an idea? Open an issue or send a pull request — contributions in any language are welcome.
This project is one of the 15 DeepSeek Harness plugins maintained by PerryLink. If this one helps you, the others likely will too:
| Plugin | One-liner |
|---|---|
| dsh-mcp-panel | Read-only MCP runtime panel: /mcp command + Settings tab with status, tools and errors |
| dsh-doublecheck | Engineering-discipline guard: requirements grill, test gates, adversary review |
| dsh-background-agents | Durable background child agents with a Web UI sidebar, messaging and interrupt |
| dsh-lsp-actions | LSP diagnostics, formatting, completion, code actions and rename over language servers |
| dsh-output-styles | Claude Code outputStyles-equivalent runtime style switching |
| dsh-checkpoint-rewind | Claude Code /rewind-equivalent: snapshots, session forks, one-shot restore |
| dsh-permission-rules | Claude Code-style declarative allow/deny/ask permission rules with audit |
| dsh-auto-review | Second-model auto-review on the approval chain, fail-closed by default |
| dsh-memento | Approval-gated cross-session memory: ctx.memory seam + SQLite + memory tool |
| dsh-skill-pack-security | Security-audit skill pack: secret scan, dependency and supply-chain review |
| dsh-session-pin | Pin sessions in the Web sidebar with durable ordering |
| dsh-composer-history | Terminal-style input history for the web composer: arrows, Ctrl+R search |
| dsh-github | GitHub PR/issues integration for DSH, every write gated by approval |
| dsh-plugin-guide | Plugin-development knowledge base as an on-demand agent skill |
| dsh-claude-move | Migrate Claude Code sessions, memory, skills and CLAUDE.md into DSH |
Apache-2.0 © 2026 dsh-output-styles contributors
Topics: dsh · dsh-plugin · deepseek-harness · output-styles · claude-code
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。