From harness
Render a long-form or visually-structured response as a single self-contained HTML file and open it in the browser, instead of printing >50 lines to the terminal. Use when the response would benefit from diagrams (Mermaid or Graphviz), wide tables, side-by-side comparisons, diffs, callouts, or collapsible detail. Triggers on phrases like "rich response", "open this in the browser", "render as HTML", "give me a doc", "diagram this", or whenever the response would otherwise exceed roughly 50 lines of terminal output.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness:rich-responseThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
| Variable | Value | Notes |
| Variable | Value | Notes |
|---|---|---|
| RENDER_CMD | <skill-dir>./render.sh | One-shot: substitute → validate → serve. Body on stdin, prints path. |
| TEMPLATE_PATH | <skill-dir>./template.html | Reference only — RENDER_CMD reads it. Read this to learn the primitives. |
| OUTPUT_DIR | /tmp | Where the rendered file lives |
Write the body fragment to a temporary source file first, then pipe that file into RENDER_CMD. This makes long rich responses easy to inspect and edit before rerendering. Agent never emits template boilerplate.
cat > /tmp/rich-response-body.html <<'HTML'
<h2>Section heading</h2>
<p>Body content as semantic HTML using the primitives above.</p>
<div class="callout">Important point.</div>
<pre class="mermaid">
flowchart LR
A --> B
</pre>
HTML
RENDER_CMD "<title>" < /tmp/rich-response-body.html
For updates, edit /tmp/rich-response-body.html, then rerun only:
RENDER_CMD "<title>" < /tmp/rich-response-body.html
<<'HTML' (single quotes around HTML) when creating the body file. Stops bash from expanding $variables or backticks inside the body./tmp/rich-<slug>.html). Reusing the same title updates the same rendered file and localhost URL. To override, pass it as the second arg: RENDER_CMD "<title>" /tmp/custom.html < /tmp/rich-response-body.html.RENDER_CMD runs validate.sh, then serve.sh, then prints the chosen output path on stdout. Validate/serve output goes to stderr.After it returns: one-line chat reply pointing at the rendered file. No long recap — the doc IS the answer.
TEMPLATE_PATH is a single self-contained HTML file:
prefers-color-scheme — Dawn colors from pi/themes/rose-pine-dawn.json in light mode and Moon colors from pi/themes/rose-pine-moon.json in dark mode.<pre> blocks (auto-attached on load).@11 tag = latest 11.x) is loaded from CDN only if the page contains a <pre class="mermaid"> block.@viz-js/viz, Graphviz compiled to WebAssembly) is loaded from CDN only if the page contains a <pre class="graphviz"> block. No local dot binary is required.{{TITLE}} (appears twice — <title> and <h1>) and {{BODY}}.Write the body in plain semantic HTML. The template styles these:
<h1>–<h4>, <p>, <ul>/<ol>, <a>, <hr>, <blockquote><code> inline; <pre><code>…</code></pre> block (copy button auto-added)<table><thead><tr><th>…</th></tr></thead><tbody>…</tbody></table><details><summary>Title</summary>…</details><small>…</small> or <span class="muted">…</span><span class="badge">label</span>Utility classes added by the template:
| Class | Purpose |
|---|---|
.callout | Info box (blue). Add warn, error, or success. |
.callout-title | Bold first line inside a callout. |
.grid-2 | Two-column responsive grid; collapses on narrow. |
.diff on <pre> | Use <span class="add">…</span> / <span class="del">…</span> lines |
.no-wrap on <pre> | Preserve horizontal scrolling for tree-like layouts or aligned output. |
.mermaid on <pre> | Renders content as a Mermaid diagram. |
.graphviz on <pre> | Renders DOT content as a Graphviz SVG diagram. |
.tabs | Tab group. See Tabs below. |
CSS-only (no JS), up to 5 panels per group. Each group needs a unique name on the radio inputs. Structure: labels first, then panels, in matching order.
<div class="tabs">
<label class="tab"><input type="radio" name="api" checked />cURL</label>
<label class="tab"><input type="radio" name="api" />Node</label>
<label class="tab"><input type="radio" name="api" />Python</label>
<div class="tab-panel">
<pre><code class="language-bash">curl …</code></pre>
</div>
<div class="tab-panel">
<pre><code class="language-js">await fetch(…)</code></pre>
</div>
<div class="tab-panel">
<pre><code class="language-python">requests.get(…)</code></pre>
</div>
</div>
Opt-in. Add class="language-xxx" on the <code> element inside a <pre>. The template lazy-loads highlight.js only when at least one such block exists; token colors are inline CSS variables mapped from the active Rose Pine Dawn/Moon Pi theme. Common values: language-bash, language-js, language-ts, language-python, language-html, language-css, language-json, language-sql, language-yaml, language-rust, language-go.
<pre><code class="language-js">
const x = await fetch('/api')
</code></pre>
Plain <pre><code>…</code></pre> (no language class) stays unhighlighted — useful for terminal output or non-code text. <pre> blocks wrap long lines by default; add class="no-wrap" when horizontal scrolling is better for tree-like layouts, ASCII UI mockups, or fixed-column output.
Use <pre class="mermaid">…</pre>. Theme follows OS dark/light automatically. See the mermaid skill for syntax pitfalls — multi-space alignment, reserved IDs (End, class, etc.), label quoting. Don't HTML-entity-encode arrows inside the <pre> (-->, not -->).
Use <pre class="graphviz">…</pre> with DOT source. The template lazy-loads @viz-js/viz from jsDelivr and renders directly in the browser via WebAssembly, matching the Mermaid approach: no npm install, no build step, and no dependency on dot in PATH.
<pre class="graphviz">
digraph G {
rankdir=LR;
node [shape=box, style="rounded,filled", fillcolor="#f4ede8"];
Start -> Validate -> Render -> Serve;
}
</pre>
Prefer browser-side Graphviz for rich responses. Use a local dot -Tsvg step only if the CDN/WASM path is unsuitable for a specific document (for example, strict offline use or needing a Graphviz feature not supported by @viz-js/viz). Don't HTML-entity-encode arrows inside the <pre> (->, not ->).
TEMPLATE_PATH. RENDER_CMD reads it; if it needs updating that's a separate change.<html>, <head>, <style>, etc.) on stdin. Only the body fragment.<<'HTML') — body must not be subject to bash expansion.<table>, <details>, <blockquote>, etc. rather than <div> soup.RENDER_CMD exited 0 and printed the output path on stdout.serving http://localhost:… line appeared on stderr.npx claudepluginhub codethread/agents --plugin harnessCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.