Agent skill

Doc Writer

by mitchdenny in mitchdenny/hex1b

Guidelines for producing accurate and maintainable documentation for the Hex1b TUI library.

MITAuto-check passedDevelopment

Install Doc Writer

skills CLI
$ npx skills add mitchdenny/hex1b --skill doc-writer -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install mitchdenny/hex1b doc-writer --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/mitchdenny/hex1b.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.github/skills/doc-writer .claude/skills/doc-writer && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
doc-writer
GitHub stars
178
Token cost
~8.7k tokens
SKILL.md length
2,551 words
Files
7
Skills in repo
7
Repo updated
First seen
Licence
MIT

At a glance

Guidelines for producing accurate and maintainable documentation for the Hex1b TUI library.

  • Works in 2 steps: XML API Documentation → End-User Documentation
  • Writing XML API documentation comments
  • SKILL.md covers Documentation Types, Related Widgets, Documentation Workflow and Quality Checklist, plus 4 more sections
  • Runs C# scripts from its folder; calls dotnet and npm

What it does

Doc Writer is an agent skill from mitchdenny/hex1b. Guidelines for producing accurate and maintainable documentation for the Hex1b TUI library. Use when writing XML API documentation comments, creating end-user guides, or updating existing documentation.

Its SKILL.md is about 8.7k tokens, which your agent loads only when the skill is triggered. The skill folder holds 8 other files (for example `ansi-generator/README.md` and `static-generator/README.md`).

It sits in Development, covering Technical documentation and Technical writing. It works with C#. The repository describes itself as: The .NET Terminal Application Stack. The licence is MIT.

When your agent uses it

  • Writing XML API documentation comments
  • Creating end-user guides
  • Updating existing documentation

Example prompts

  • “Use the doc-writer skill to guideline for producing accurate and maintainable documentation for the Hex1b TUI library”
  • “/doc-writer”

Workflow steps

2 steps, taken from the step headings in SKILL.md.

  1. XML API Documentation
  2. End-User Documentation

What it can do on your machine

Read from SKILL.md and the folder at commit e2335bd. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships script files (C#), which the agent can run.

    Shell commands in SKILL.md call:

    • dotnet
    • npm

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • learn.microsoft.com
    • vitepress.dev

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Doc Writer loads about 8.7k tokens when it runs. Until then it costs about 53 tokens; SKILL.md has 2,551 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~53
When it runs · the whole SKILL.md, loaded when a task matches
~8.7k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from mitchdenny/hex1b at commit e2335bd, republished under its MIT licence (© mitchdenny). 2,551 words, ~8,678 tokens.

Download SKILL.mdSave it as .claude/skills/doc-writer/SKILL.md (or your agent's skills folder). This skill also uses 6 other files; get the full folder from GitHub.
name
doc-writer
description
Guidelines for producing accurate and maintainable documentation for the Hex1b TUI library. Use when writing XML API documentation comments, creating end-user guides, or updating existing documentation.

Documentation Writer Skill

This skill provides guidelines for AI coding agents to help maintainers produce accurate and easy-to-maintain documentation for the Hex1b project. The repository contains two primary types of documentation, each serving different audiences and following different conventions.

Documentation Types

1. XML API Documentation

Location: C# source files in src/Hex1b/
Audience: Library consumers, API reference generators, IDE intellisense users
Format: XML doc comments (///)
Build Setting: GenerateDocumentationFile is enabled in src/Hex1b/Hex1b.csproj

Purpose

XML documentation comments provide:

  • Inline help in IDEs (IntelliSense, code completion)
  • Generated API reference documentation
  • Contract documentation for public APIs
  • Usage examples for complex APIs
Best Practices for XML Documentation
1. Document All Public APIs

Required for:

  • Public classes, structs, records, enums
  • Public properties and fields
  • Public methods and constructors
  • Public events and delegates

Example:

csharp
/// <summary>
/// Represents a color that can be used in the terminal.
/// </summary>
public readonly struct Hex1bColor
{
    /// <summary>
    /// Creates a color from RGB values.
    /// </summary>
    /// <param name="r">Red component (0-255)</param>
    /// <param name="g">Green component (0-255)</param>
    /// <param name="b">Blue component (0-255)</param>
    /// <returns>A new Hex1bColor instance with the specified RGB values.</returns>
    public static Hex1bColor FromRgb(byte r, byte g, byte b) => new(r, g, b);
}
2. Write Clear, Concise Summaries
  • Start with a verb (e.g., "Creates", "Gets", "Sets", "Calculates")
  • Keep it to one or two sentences
  • Describe what it does, not how it does it
  • Use third person ("Creates a widget" not "Create a widget")

Good:

csharp
/// <summary>
/// Creates a Layout that wraps a single child widget with clipping enabled.
/// </summary>

Bad:

csharp
/// <summary>
/// This method will take the child widget and wrap it in a layout.
/// The layout uses the clipMode parameter which defaults to Clip.
/// </summary>
3. Document Parameters and Return Values

Always document:

  • <param> for each parameter
  • <returns> for non-void methods
  • <exception> for thrown exceptions (when applicable)
  • <typeparam> for generic type parameters

Example:

csharp
/// <summary>
/// Arranges child widgets vertically within the given constraints.
/// </summary>
/// <param name="constraints">The size constraints for layout.</param>
/// <param name="children">The child widgets to arrange.</param>
/// <returns>The total size required for all children.</returns>
/// <exception cref="ArgumentNullException">Thrown when children is null.</exception>
public Size ArrangeVertical(Constraints constraints, Hex1bWidget[] children)
4. Include Usage Examples for Complex APIs

Use <example> and <code> tags for key APIs within the Hex1b framework. Examples should be consise yet contain sufficient context to help developers understand how they are used. For examples that use Hex1bApp to create sample applications favor the use of the fluent API since that is the intended usage pattern.

csharp
/// <summary>
/// The main entry point for building terminal UI applications.
/// </summary>
/// <example>
/// <para>Create a minimal Hex1b application:</para>
/// <code>
/// using Hex1b;
/// 
/// var app = new Hex1bApp(ctx =&gt;
///     ctx.VStack(v => [
///         v.Text("Hello, Hex1b!"),
///         v.Button("Quit", e => e.Context.RequestStop())
///     ])
/// );
/// 
/// await app.RunAsync();
/// </code>
/// </example>

Note: HTML-encode special characters in code examples:

  • < becomes &lt;
  • > becomes &gt;
  • & becomes &amp;
5. Use Remarks for Additional Context

Use <remarks> for:

  • Implementation details that affect usage
  • Performance considerations
  • Related concepts or cross-references
csharp
/// <summary>
/// The main entry point for building terminal UI applications.
/// </summary>
/// <remarks>
/// Hex1bApp manages the render loop, input handling, focus management, and reconciliation
/// between widgets (immutable declarations) and nodes (mutable render state).
/// 
/// State management is handled via closures - simply capture your state variables
/// in the widget builder callback.
/// </remarks>
public class Hex1bApp : IDisposable, IAsyncDisposable

Use <see> and <seealso> to link to related types:

csharp
/// <summary>
/// Theme elements for Scroll widgets.
/// </summary>
/// <seealso cref="ScrollPanelWidget"/>
/// <seealso cref="Hex1bTheme"/>
public static class ScrollTheme
7. Internal APIs Can Have Lighter Documentation

Internal APIs (marked with internal) should still be documented but can be less formal:

  • Brief summary is sufficient
  • Skip examples unless complex
  • Note: The project suppresses CS1591 warnings for missing XML docs via <NoWarn>$(NoWarn);CS1591</NoWarn>
8. Maintain Consistency with Existing Documentation

Review existing XML documentation in the codebase to match:

  • Tone and style
  • Level of detail
  • Terminology (e.g., "widget" vs "control", "terminal" vs "console")
2. End-User Documentation

Location: src/content/
Audience: Hex1b library users (developers building TUI applications)
Format: Markdown with VitePress components
Build System: VitePress (static site generator)

Documentation Structure

This is the curernt documentation structure. As the documentation structure evolves, this should be updated to assist future agent development efforts.

src/content/
├── index.md                    # Landing page
├── api/
│   └── index.md               # API reference overview
├── guide/
│   ├── getting-started.md     # Tutorial walkthrough
│   ├── first-app.md           # Quick start
│   ├── widgets-and-nodes.md   # Core concepts
│   ├── layout.md              # Layout system
│   ├── input.md               # Input handling
│   ├── testing.md             # Testing guide
│   ├── theming.md             # Theming guide
│   └── widgets/               # Per-widget documentation
│       ├── text.md
│       ├── button.md
│       ├── textbox.md
│       ├── list.md
│       ├── stacks.md
│       ├── containers.md
│       └── navigator.md
├── deep-dives/                # Advanced topics
└── gallery.md                 # Examples showcase
Best Practices for End-User Documentation
1. Use Progressive Disclosure

Structure documentation from simple to complex:

  1. Getting Started: Simple, working examples
  2. Guide: Core concepts and common patterns
  3. Deep Dives: Advanced topics and internals

Example: The getting-started.md file walks through building a todo app in 5 progressive steps, each adding new concepts.

2. Include Working Code Examples

Every code example should:

  • Be complete and runnable (or clearly marked as a snippet)
  • Use realistic, meaningful variable names
  • Follow the project's coding conventions
  • Be tested to ensure accuracy

Good:

csharp
using Hex1b;

var state = new CounterState();

var app = new Hex1bApp(ctx =>
    ctx.Border(b => [
        b.Text($"Button pressed {state.Count} times"),
        b.Button("Click me!").OnClick(_ => state.Count++)
    ], title: "Counter Demo")
);

await app.RunAsync();

class CounterState
{
    public int Count { get; set; }
}

Bad (incomplete, won't compile):

csharp
var button = new Button();
button.Click = () => count++;
3. Use VitePress Components

The site uses custom VitePress components for rich content:

  • <TerminalCommand command="..." /> - Show CLI commands
  • <CodeBlock lang="csharp" :code="variable" /> - Code with syntax highlighting
  • <TerminalDemo example="..." title="..." /> - Interactive terminal demos
  • ::: tip / ::: warning / ::: danger - Callout boxes

Example:

markdown
::: tip Generating Full API Docs
Full API documentation can be generated from XML doc comments using tools like DocFX or xmldocmd.

```bash
dotnet build /p:GenerateDocumentationFile=true
xmldocmd src/Hex1b/bin/Release/net10.0/Hex1b.dll docs/api

:::


##### 4. Live Terminal Demos

The documentation site includes a WebSocket-based terminal that can run live code examples. This gives developers an interactive preview of how their code will behave when run locally.

**Location**: `src/Hex1b.Website/Examples/`  
**Component**: `<TerminalDemo example="..." title="..." />`

###### How It Works

1. The Hex1b.Website project hosts WebSocket endpoints that run actual Hex1b applications
2. Each example in `src/Hex1b.Website/Examples/` implements `IGalleryExample`
3. The VitePress documentation uses the `<TerminalDemo>` component to connect to these endpoints
4. Users can interact with the live terminal directly in their browser

###### Code Duplication

Example code in the documentation may be **duplicated** from the main code samples with minor modifications:

- **Why**: The WebSocket terminal environment has slightly different requirements than running locally (e.g., terminal size handling, connection lifecycle)
- **What changes**: Usually minor adjustments to initialization, cleanup, or terminal configuration
- **Goal**: Give developers an accurate preview of runtime behavior, even if the hosted code differs slightly from the documented snippet

**Example structure**:

src/Hex1b.Website/Examples/ ├── CounterExample.cs # Live demo version ├── TodoExample.cs # Live demo version └── ...


The documentation code block shows the "clean" version a developer would write locally, while the `Examples/` folder contains the WebSocket-compatible version.

###### When to Create Live Demos

✅ **Good candidates for live demos**:
- Interactive widgets (buttons, text boxes, lists)
- Layout examples showing responsive behavior
- Input handling demonstrations
- Theming examples

❌ **Not suitable for live demos**:
- Examples using `Hex1bTerminal` for testing (headless/mock terminals)
- Examples that require local file system access
- Performance benchmarks or stress tests
- Examples with external dependencies

###### Registering Examples in Program.cs

**IMPORTANT**: After creating WebSocket example files, you must register them in `src/Hex1b.Website/Program.cs`. Examples will not be available in the live demos until registered.

Add a line for each example in the appropriate section:

```csharp
// Register [Widget name] widget documentation examples
builder.Services.AddSingleton<IGalleryExample, YourNewExample>();

Look for existing example registrations grouped by feature area and add your new examples in the corresponding section. If documenting a new widget, create a new comment section for clarity.

Keeping Examples in Sync

When updating documentation examples that have live demos:

  1. Update the documentation code block first
  2. Apply equivalent changes to the Examples/ implementation
  3. Register the example in Program.cs (if new)
  4. Test the live demo to ensure it still works
  5. Note any intentional differences in comments within the Examples/ file
4. Explain Concepts, Not Just APIs

Don't just describe what methods exist—explain:

  • Why a feature exists
  • When to use it
  • How it fits into the bigger picture

Example from widgets-and-nodes.md:

markdown
## Why This Matters

1. **State Preservation**: Focus doesn't jump around when the UI re-renders
2. **Performance**: Only changed parts of the tree get updated
3. **Simplicity**: You describe the UI declaratively; Hex1b figures out the transitions
5. Use Visual Aids

Include:

  • ASCII diagrams for architecture
  • Tables for comparisons
  • Trees for hierarchical concepts

Example:

markdown
| Layer | Type | Mutability | Purpose |
|-------|------|------------|---------|
| **Widget** | `record` | Immutable | Describes the desired UI |
| **Node** | `class` | Mutable | Manages state, renders to terminal |
6. Maintain a Consistent Voice
  • Use second person ("you") when addressing the reader
  • Use active voice ("Create a widget" not "A widget is created")
  • Be conversational but professional
  • Use emojis sparingly (mainly in headings: ✨, 📋, 🚀, etc.)

Create a documentation graph:

  • Link from tutorials to reference docs
  • Link from reference docs to tutorials
  • Link between related concepts
  • Include "Next Steps" sections

Example from getting-started.md:

markdown
## Next Steps

- [Widgets & Nodes](/guide/widgets-and-nodes) - Understand the core architecture
- [Layout System](/guide/layout) - Master the constraint-based layout
- [Input Handling](/guide/input) - Learn about keyboard shortcuts and focus
- [Theming](/guide/theming) - Customize the appearance of your app
8. Keep Examples Focused

Each example should demonstrate one concept:

  • Don't mix multiple new concepts in a single example
  • Build on previous examples incrementally
  • Extract complex examples to separate files in samples/
9. Update Documentation When Changing Code

Documentation changes should accompany code changes:

  • New widget → New guide/widgets/*.md file
  • API change → Update relevant guide docs
  • Breaking change → Update migration guide (if exists)
10. Test Your Documentation

Before finalizing documentation:

  • Copy/paste code examples and verify they compile
  • Run code examples to ensure they work as described
  • Check that links aren't broken
  • Verify VitePress components render correctly
Widget Documentation Template

When documenting widgets in guide/widgets/, follow this consistent structure to ensure users can quickly find what they need.

📖 Canonical Example: See guide/widgets/text.md for a fully-realized example demonstrating all the patterns described below, including:

  • External .cs snippet files with ?raw imports
  • Live demos with <CodeBlock> for full examples
  • Static previews with <StaticTerminalPreview> for visual variations
  • Proper section structure and related widgets links
Required Sections
  1. Title - Widget name as heading
  2. Basic Usage - Complete, runnable example with Hex1bApp setup
  3. Features/Behavior - Widget-specific capabilities with demos where applicable
  4. Related Widgets - Links to related documentation
CRITICAL: Update Navigation Sidebar

IMPORTANT: After creating a new widget documentation file, you MUST add it to the navigation sidebar in src/content/.vitepress/config.ts.

  1. Open src/content/.vitepress/config.ts
  2. Find the 'Widgets' section under sidebar: { '/guide/': [...] }
  3. Add a new entry for your widget: { text: 'WidgetName', link: '/guide/widgets/widget-name' }
  4. Keep the list alphabetically sorted by the text property

Failure to update the navigation means users cannot discover the new documentation through the sidebar!

Optional Sections

Include these when they add clear value:

  • API Reference - Include when there are non-obvious parameters, enums, or extension methods to document. For simple widgets with self-explanatory APIs, the XML documentation is sufficient.
Live Terminal Demos for Widget Docs

Widget documentation benefits from live terminal demos using the <CodeBlock> component. However, choose the appropriate demo type based on the widget's nature.

When to Use Live Demos vs Static Previews
Use Live Demo (<CodeBlock>)Use Static Preview (<StaticTerminalPreview>)
Interactive widgets (buttons, text boxes)Display-only widgets (text, layout)
User input demonstration neededShowing specific visual states
Responsive behavior on resizeCode snippet with visual result
Focus/navigation demonstrationsDocumenting multiple variations

Live demos are best when:

  • There is some interactive element on the screen (buttons, inputs, lists)
  • Resizing the terminal results in responsive behavior worth demonstrating
  • Focus navigation or keyboard handling is a key feature

Static previews are best when:

  • The widget is purely visual with no interaction
  • You're showing multiple variations of the same feature
  • The code snippet is a partial example (not full Hex1bApp setup)
⚠️ REQUIRED: Interactive Examples for All Interactive Widgets

Every widget documentation page with interactive elements MUST include:

  1. At least one working interactive demo via <CodeBlock example="..."> component
  2. A corresponding example class in src/Hex1b.Website/Examples/
  3. Registration in src/Hex1b.Website/Program.cs

This is NOT optional. Documentation without working interactive demos is incomplete. When writing widget docs:

  • Create the example .cs file in src/Hex1b.Website/Examples/
  • Register the example in Program.cs with builder.Services.AddSingleton<IGalleryExample, YourExample>()
  • Add the example="example-id" attribute to <CodeBlock> in the markdown
  • Test the demo by clicking "Run in browser" on the documentation page

Verification: After writing documentation, navigate to the page in a browser and click "Run in browser" to confirm the demo works.

Creating Live Demos
  1. Create WebSocket example files in src/Hex1b.Website/Examples/ for each demo
  2. Use the <CodeBlock> component with the example attribute linking to the example Id
  3. Define code in <script setup> at the top of the markdown file

Example structure for widget docs:

markdown
<script setup>
const basicCode = \`using Hex1b;
using Hex1b.Widgets;

var app = new Hex1bApp(ctx => Task.FromResult<Hex1bWidget>(
    ctx.VStack(v => [
        v.WidgetMethod("example")
    ])
));

await app.RunAsync();\`
</script>

# WidgetName

Brief description.

## Basic Usage

<CodeBlock lang="csharp" :code="basicCode" command="dotnet run" example="widget-basic" exampleTitle="Widget - Basic Usage" />

Creating the WebSocket example file (src/Hex1b.Website/Examples/WidgetBasicExample.cs):

csharp
using Hex1b;
using Hex1b.Widgets;
using Microsoft.Extensions.Logging;

namespace Hex1b.Website.Examples;

public class WidgetBasicExample(ILogger<WidgetBasicExample> logger) : Hex1bExample
{
    private readonly ILogger<WidgetBasicExample> _logger = logger;

    public override string Id => "widget-basic";  // Must match example attribute in CodeBlock
    public override string Title => "Widget - Basic Usage";
    public override string Description => "Demonstrates basic widget usage";

    public override Func<Hex1bWidget> CreateWidgetBuilder()
    {
        _logger.LogInformation("Creating widget basic example");

        return () =>
        {
            var ctx = new RootContext();
            return ctx.VStack(v => [
                v.WidgetMethod("example")
            ]);
        };
    }
}
Key Principles

Always use the fluent API:

  • ✅ ctx.Text("Hello") or v.Text("Hello")
  • ❌ new TextBlockWidget("Hello") - Do not show direct widget construction

Basic Usage must include Hex1bApp:

csharp
using Hex1b;
using Hex1b.Widgets;

var app = new Hex1bApp(ctx => Task.FromResult<Hex1bWidget>(
    ctx.Text("Hello, World!")
));

await app.RunAsync();

Show widgets in context - Demonstrate usage within layout containers:

csharp
var app = new Hex1bApp(ctx => Task.FromResult<Hex1bWidget>(
    ctx.VStack(v => [
        v.Text("Title"),
        v.Text("Description")
    ])
));
Template Structure

The following template shows the recommended structure. Adapt it based on the widget's complexity:

markdown
<script setup>
const basicCode = \`using Hex1b;
using Hex1b.Widgets;

var app = new Hex1bApp(ctx => Task.FromResult<Hex1bWidget>(
    ctx.WidgetMethod("example")
));

await app.RunAsync();\`
</script>

# WidgetName

Brief description of what the widget does.

## Basic Usage

<CodeBlock lang="csharp" :code="basicCode" command="dotnet run" example="widget-basic" exampleTitle="Widget - Basic Usage" />

## [Feature Section(s)]

Document widget-specific features with focused examples.

Store code snippets as external `.cs` files and import them with `?raw`:

```markdown
<script setup>
import featureSnippet from './snippets/widget-feature.cs?raw'
</script>

<StaticTerminalPreview svgPath="/svg/widget-feature.svg" :code="featureSnippet" />

##### Mirror Warning for Code Samples

When a documentation code sample mirrors a WebSocket example, add a warning comment to remind maintainers to keep them in sync:

```markdown
<!-- 
⚠️ MIRROR WARNING: This code sample mirrors the WebSocket example in:
   src/Hex1b.Website/Examples/WidgetBasicExample.cs
   Keep both files in sync when making changes.
-->

Place this comment directly before the code block or <script setup> section.

Static SVG/HTML Previews

For static previews with interactive cell inspection, use the Static Generator to create SVG and HTML files. These offer:

  • Crisp SVG rendering: Sharp vector graphics at any resolution
  • Interactive HTML inspector: Hover over cells to see character, color, and attribute details
  • Minimal embed mode: Clean presentation for documentation iframes
Static Generator Template Location

A template console application is provided at:

.github/skills/doc-writer/static-generator/
├── StaticGenerator.csproj  # Project file (references Hex1b)
├── Program.cs              # Template with GenerateSnapshot helper
└── README.md               # Detailed usage instructions
Show full SKILL.md (1,070 more words)Show less
Step-by-Step Workflow for Agents

IMPORTANT: Do NOT modify the template files directly. Always copy to a temporary location first.

Step 1: Create working directory inside workspace

bash
mkdir -p .tmp-static-gen
cp .github/skills/doc-writer/static-generator/* .tmp-static-gen/

Step 2: Fix the project reference path

The template uses a relative path for the original location. Update the project reference in .tmp-static-gen/StaticGenerator.csproj:

bash
# Change the ProjectReference Include path from:
#   Include="../../../../src/Hex1b/Hex1b.csproj"
# To:
#   Include="../src/Hex1b/Hex1b.csproj"

Step 3: Modify Program.cs in the working copy

Edit .tmp-static-gen/Program.cs and replace the contents of GenerateSnapshots() with your specific widget:

csharp
static async Task GenerateSnapshots(string outputDir)
{
    // Example: Generate a text widget with wrapping
    await GenerateSnapshot(outputDir, "text-wrap-demo", "Text Wrapping Demo", 50, 5,
        ctx => ctx.VStack(v => [
            v.Text(
                "This long paragraph demonstrates how text wrapping works in Hex1b. " +
                "When content exceeds the available width, it automatically breaks " +
                "at word boundaries."
            ).Wrap()
        ]));
}

Step 4: Run the generator

bash
cd .tmp-static-gen
dotnet run -- output

Step 5: Verify the output

Check that the files were created:

bash
ls -la output/
# Should contain: text-wrap-demo.svg

Step 6: Copy to public assets

bash
cp output/*.svg ../src/content/public/svg/

Step 7: Clean up

bash
cd ..
rm -rf .tmp-static-gen

Step 8: Use in documentation

Create a snippets folder alongside your markdown and add the code as a .cs file:

guide/widgets/
├── your-widget.md
└── snippets/
    └── text-wrap-demo.cs

Then import and use it in your markdown:

markdown
<script setup>
import wrapSnippet from './snippets/text-wrap-demo.cs?raw'
</script>

<StaticTerminalPreview svgPath="/svg/text-wrap-demo.svg" :code="wrapSnippet" />
GenerateSnapshot Function Signature
csharp
await GenerateSnapshot(
    outputDir,      // Always use "output"
    "filename",     // Name without extension (creates .svg)
    "Description",  // For console output only
    width,          // Terminal columns
    height,         // Terminal rows
    ctx => widget   // Widget builder using RootContext
);
StaticTerminalPreview Component

The <StaticTerminalPreview> component displays code with an expandable "View output" panel. Clicking the chevron icon slides open a panel showing the rendered terminal output.

This component uses Shiki for syntax highlighting with line numbers, matching the styling of the main <CodeBlock> component.

Usage (recommended - external .cs files with ?raw import):

Store code snippets as external .cs files in a snippets/ folder alongside your markdown, then import them using Vite's ?raw suffix:

guide/widgets/
├── text.md
└── snippets/
    ├── text-truncate.cs
    ├── text-wrap.cs
    └── text-ellipsis.cs
markdown
<script setup>
import truncateSnippet from './snippets/text-truncate.cs?raw'
import wrapSnippet from './snippets/text-wrap.cs?raw'
import ellipsisSnippet from './snippets/text-ellipsis.cs?raw'
</script>

<StaticTerminalPreview svgPath="/svg/text-truncate.svg" :code="truncateSnippet" />

Benefits of external files:

  • Real .cs files with proper syntax highlighting in your editor
  • Easier to maintain and edit
  • Avoids VitePress markdown processing issues
  • Cleaner markdown files

Props:

PropTypeDefaultDescription
svgPathstringrequiredPath to .svg file relative to public folder
codestring(from slot)Code to display (use with ?raw imports)
languagestring"csharp"Language for syntax highlighting

Features:

  • Shiki syntax highlighting with line numbers (matching CodeBlock.vue)
  • Chevron icon in header to expand/collapse output
  • Inline slide-out panel (no overlay or iframe)
  • SVG scales to fill available width
  • Cell hover tooltips showing character info, colors, and attributes (parsed from SVG DOM)
  • Consistent styling with main documentation code blocks

Note: The component parses cell data directly from the SVG's DOM structure (using data-x, data-y attributes and element properties). No separate HTML file is needed.

TerminalSvgOptions
OptionDefaultDescription
ShowCellGridfalseShow grid lines between cells
ShowPixelGridfalseShow pixel-level grid
DefaultBackground#0f0f1aBackground color
DefaultForeground#e0e0e0Text color
FontFamilyCascadia Code stackMonospace font
FontSize14Font size in pixels
CellWidth9Cell width in pixels
CellHeight18Cell height in pixels
Avoiding Cursor in SVG Output

IMPORTANT: Unless your code sample specifically demonstrates cursor/mouse behavior, disable the cursor in generated SVGs. A random cursor block appearing in documentation screenshots confuses readers.

The Hex1bTerminalSnapshot.ToSvg() method includes cursor position by default. To hide the cursor, cast to IHex1bTerminalRegion:

csharp
// Cast to IHex1bTerminalRegion to use the overload without cursor
var svg = ((IHex1bTerminalRegion)snapshot).ToSvg(svgOptions);

The template's GenerateSnapshot function already uses this approach by default.

Only include the cursor when documenting cursor-related features (e.g., TextBox focus states, cursor shapes).

Common Widget Patterns
csharp
// Simple text
await GenerateSnapshot(outputDir, "text-simple", "Simple", 40, 3,
    ctx => ctx.Text("Hello, World!"));

// Text with overflow
await GenerateSnapshot(outputDir, "text-ellipsis", "Ellipsis", 50, 3,
    ctx => ctx.Text("Very long text here...").Ellipsis().FixedWidth(30));

// VStack layout
await GenerateSnapshot(outputDir, "layout-vstack", "VStack", 60, 10,
    ctx => ctx.VStack(v => [
        v.Text("Header"),
        v.Text(""),
        v.Text("Body content")
    ]));

// Border with content
await GenerateSnapshot(outputDir, "border-demo", "Border", 40, 6,
    ctx => ctx.Border(b => [
        b.Text("Content inside border")
    ], title: "Title"));

Documentation Workflow

For New Features
  1. Write XML docs as you write the code

    • Document public APIs inline with implementation
    • Use <summary>, <param>, <returns>, <remarks>
    • Add <example> for non-obvious usage
  2. Create or update end-user guides

    • Add widget documentation to guide/widgets/
    • Update relevant tutorial sections
    • Add usage examples to getting-started.md if appropriate
For Bug Fixes
  1. Check if documentation needs updates

    • Does the bug fix change behavior documented in guides?
    • Do code examples need updating?
  2. Update affected documentation

    • Fix incorrect examples
    • Clarify ambiguous descriptions
    • Add warnings about common pitfalls
For Breaking Changes
  1. Update XML docs to reflect new signatures/behavior
  2. Update all affected guides with new patterns
  3. Add migration notes explaining the change
  4. Update or deprecate old examples

Quality Checklist

Before considering documentation complete:

XML Documentation
  • All public types have <summary> tags
  • All public methods have parameter and return documentation
  • Complex APIs include usage examples
  • Cross-references use <see> and <seealso> tags
  • No HTML-encoding errors in code examples
End-User Documentation
  • Code examples compile and run
  • Examples are complete (or clearly marked as snippets)
  • Markdown formatting is correct
  • VitePress components are used appropriately
  • Internal links work (relative paths are correct)
  • The documentation follows the project's voice and style
  • Related documentation is cross-linked
  • Content build verification passed (see below)

Documentation Build Verification

CRITICAL: Before completing documentation work, verify that the VitePress content build succeeds. This catches issues like dead links, missing files, or syntax errors before deployment.

Verification Step

Run the Aspire content build pipeline:

bash
cd /path/to/hex1b
aspire do build-content

This executes the deployment pipeline step that builds the static resources from the VitePress site. The build must succeed before documentation changes are complete.

Expected output on success:

✓ PIPELINE SUCCEEDED

If the build fails, proceed to the diagnostic step below.

Diagnostic Step

If aspire do build-content fails, run the underlying npm build command directly to see the detailed error message:

bash
cd src/content
npm install  # Ensure dependencies are installed
npm run build

This is the step most likely to fail inside aspire do build-content. The npm build output provides detailed error messages explaining:

  • Dead links (references to non-existent pages)
  • Missing files
  • Syntax errors in markdown
  • VitePress configuration issues

Common issues to fix:

  • Dead links: Remove or fix links to pages that don't exist
  • Missing imports: Ensure all referenced snippets exist in snippets/ folders
  • Invalid frontmatter: Check YAML syntax in <script setup> sections
  • Broken component references: Verify all VitePress components are used correctly

If you see an error like:

Found dead link /guide/widgets/nonexistent in file guide/widgets/mywidget.md

Either:

  1. Remove the dead link from the documentation
  2. Create the missing page if it should exist
  3. Fix the link path if it's incorrect

After fixing issues, re-run both verification commands to ensure the build succeeds.

Common Pitfalls to Avoid

XML Documentation

❌ Don't repeat the member name in the summary

csharp
/// <summary>
/// ButtonWidget is a widget for buttons.
/// </summary>

✅ Do describe what it does

csharp
/// <summary>
/// An interactive button that responds to Enter, Space, or mouse clicks.
/// </summary>

❌ Don't use implementation details in public API docs

csharp
/// <summary>
/// Sets the internal _label field to the specified value.
/// </summary>

✅ Do describe the effect

csharp
/// <summary>
/// Sets the text displayed on the button.
/// </summary>
End-User Documentation

❌ Don't assume prior knowledge

markdown
Use reconciliation to update nodes efficiently.

✅ Do explain concepts

markdown
When you call `SetState()`, Hex1b diffs the new widget tree against existing nodes
and updates only what changed. This reconciliation process preserves focus and scroll
state while keeping your UI responsive.

❌ Don't use code snippets without context

csharp
.OnClick(_ => count++)

✅ Do provide complete, runnable examples

csharp
var state = new CounterState();
var app = new Hex1bApp(ctx =>
    ctx.Button("Increment").OnClick(_ => state.Count++)
);

Tools and Resources

For XML Documentation
  • Visual Studio: IntelliSense shows XML docs while typing
  • Rider: Similar XML doc support
  • xmldocmd: Generate markdown from XML docs (dotnet tool install -g xmldocmd)
  • DocFX: Microsoft's documentation generator
For End-User Documentation
  • VitePress: Static site generator (configured in src/content/.vitepress/)
  • Markdown Preview: Any Markdown-capable editor
  • Vale: Prose linter (optional, for style consistency)
Documentation References

Summary

Good documentation:

  1. Serves its audience: API docs for developers, guides for users
  2. Is accurate: Code examples compile and run
  3. Is complete: Covers common scenarios and edge cases
  4. Is consistent: Follows established patterns and style
  5. Is maintained: Updated alongside code changes

When in doubt, look at existing documentation in the repository and match its style, tone, and level of detail.

© mitchdenny, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 6 other files in .github/skills/doc-writer of mitchdenny/hex1b.

  • SKILL.md
  • ansi-generator/AnsiGenerator.csproj
  • ansi-generator/Program.cs
  • ansi-generator/README.md
  • static-generator/Program.cs
  • static-generator/README.md
  • static-generator/StaticGenerator.csproj

Open the folder on GitHubat commit e2335bd

Compare with similar skills

Doc Writer next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Doc Writer compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Doc Writer this skillmitchdenny/hex1b178—~8.7kAutomated safety check: PassMIT
Technical Writerfinos/morphir213—~4.4kAutomated safety check: PassApache-2.0
Diataxis Docs Writercalf-ai/calfkit-sdk1491 repos~3kAutomated safety check: PassApache-2.0
Create Skill Samplepnp/copilot-prompts892—~3.1kAutomated safety check: PassMIT
Docsbrickbots/PiFinder250—~6.2kAutomated safety check: PassGPL-3.0
ScottPlot Cookbook RecipeScottPlot/ScottPlot6.8k—~384Automated safety check: PassMIT

Similar skills

  • Technical Writer

    finos/morphir

    Assists with writing and maintaining Morphir technical documentation.

    213 GitHub stars~4.4k tokensUpdated today
    DevelopmentAuto-check passed
  • Diataxis Docs Writer

    calf-ai/calfkit-sdk

    Write or improve software documentation using the Diátaxis framework — four documentation types (tutorials, how-to guides, reference, explanation), each serving a different user need.

    149 GitHub starsUsed in 1 repo~3k tokens
    DevelopmentAuto-check passed
  • Create Skill Sample

    pnp/copilot-prompts

    This skill should be used when the user asks to "create a new skill sample", "add a skill", "scaffold a new skill", "contribute a skill", "create a GitHub Copilot skill", "build a custom skill", or…

    892 GitHub stars~3.1k tokensUpdated 3 days ago
    DevelopmentAuto-check passed
  • Docs

    brickbots/PiFinder

    Author and edit PiFinder's user-facing documentation in the project's house style.

    250 GitHub stars~6.2k tokensUpdated yesterday
    DevelopmentAuto-check passed
  • ScottPlot Cookbook Recipe

    ScottPlot/ScottPlot

    Adds or extends a ScottPlot Cookbook recipe for a given plottable, in the right PlotTypes category and in the style of neighboring recipes.

    6.8k GitHub stars~384 tokensUpdated 1 mo ago
    DevelopmentAuto-check passed
  • Update the streamlit/docs repo for a new Streamlit release. An agent skill from streamlit/docs.

    178 GitHub stars~4k tokensUpdated today
    DevelopmentAuto-check passed

More from mitchdenny/hex1b

  • API Reviewer

    mitchdenny/hex1b

    Guidelines for reviewing API design in the Hex1b codebase. An agent skill from mitchdenny/hex1b.

    178 GitHub stars~4k tokensUpdated today
    Auto-check passed
  • Surface Benchmarker

    mitchdenny/hex1b

    Guidelines for running and interpreting Surface API performance benchmarks.

    178 GitHub stars~3.1k tokensUpdated today
    Auto-check passed
  • Doc Tester

    mitchdenny/hex1b

    Agent for validating Hex1b documentation against actual library behavior.

    178 GitHub stars~9.5k tokensUpdated today
    Auto-check passed
  • Test Fixer

    mitchdenny/hex1b

    Agent for diagnosing and fixing flaky terminal UI tests in the Hex1b test suite.

    178 GitHub stars~6.5k tokensUpdated today
    Auto-check passed
  • Widget Creator

    mitchdenny/hex1b

    Step-by-step guide for creating new widgets in the Hex1b TUI library.

    178 GitHub stars~7.6k tokensUpdated today
    Auto-check passed
  • Writing Unit Tests

    mitchdenny/hex1b

    Guidelines for writing unit tests in the Hex1b TUI library. An agent skill from mitchdenny/hex1b.

    178 GitHub stars~7k tokensUpdated today
    Auto-check passed

Works with

Categories

Questions about Doc Writer

What does Doc Writer do?

Guidelines for producing accurate and maintainable documentation for the Hex1b TUI library. Doc Writer is an agent skill from mitchdenny/hex1b. Guidelines for producing accurate and maintainable documentation for the Hex1b TUI library.

When should I use Doc Writer?

Doc Writer fits situations like: writing XML API documentation comments; creating end-user guides; updating existing documentation.

How do I install Doc Writer in Claude Code?

Run `npx skills add mitchdenny/hex1b --skill doc-writer -a claude-code`. Or copy the skill folder (.github/skills/doc-writer in mitchdenny/hex1b) into .claude/skills/doc-writer in your project. Claude Code loads it when a task matches its description.

How do I install Doc Writer in Codex?

Run `npx skills add mitchdenny/hex1b --skill doc-writer -a codex`. Or copy the skill folder (.github/skills/doc-writer in mitchdenny/hex1b) into .agents/skills/doc-writer in your project. Codex loads it when a task matches its description.

Can I use Doc Writer in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add mitchdenny/hex1b --skill doc-writer -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/doc-writer, .gemini/skills/doc-writer, .github/skills/doc-writer and .opencode/skills/doc-writer in your project.

What does Doc Writer need to run?

Going by SKILL.md and its folder, Doc Writer needs C# for the scripts in its folder and the command-line tools its instructions call (dotnet and npm).

Does Doc Writer access the network?

SKILL.md names 2 domains. As links in the text: learn.microsoft.com and vitepress.dev. This is read from the text; nothing was executed.

Is Doc Writer safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Doc Writer use?

Doc Writer is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Doc Writer use?

About 8.7k tokens (SKILL.md is roughly 35k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Doc Writer?

Skills that share tags, products or a category with Doc Writer: Technical Writer (finos/morphir, 213 stars), Diataxis Docs Writer (calf-ai/calfkit-sdk, 149 stars), Create Skill Sample (pnp/copilot-prompts, 892 stars) and Docs (brickbots/PiFinder, 250 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Doc Writer?

mitchdenny (a GitHub user) maintains it in mitchdenny/hex1b, which has 178 GitHub stars. The repository holds 7 skills in this directory. The repository was last updated on October 9, 2026.

Source: mitchdenny/hex1b on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.