claude-skills/markdown-html
Claude 8f6734a205
feat(markdown-html): add md-review v2.10.2 — code-review markdown→2-col HTML
Adds the fourth skill to the markdown-html/ domain. The Tier-2 use case
from Shihipar's essay ("Code Review and PR Writeups"): a markdown PR
writeup with ```diff blocks and severity callouts becomes a single-file
2-column HTML review with top jump-nav, diff on the left, severity-tagged
annotation cards on the right, and a mandatory named reviewer footer.

Three stdlib tools pipeline together:

1. diff_parser.py — scans markdown for ```diff fenced blocks, parses each
   as a unified diff (--- a/file, +++ b/file, @@ -10,7 +10,8 @@,
   space/+/- body lines), assigns per-line numbers on both old (lo) and
   new (ln) sides, preserves the per-hunk @@ header context. Supports
   --infer-diff for unfenced blocks. Stdlib regex + state machine.

2. annotation_extractor.py — extracts severity callouts (GFM
   > [!BLOCKER] style) and inline markers (nit:, blocker:, etc.).
   Default convention BLOCKER/MAJOR/MINOR/NIT per Google's Code Review
   Developer Guide; overridable via --severity-convention. Attaches each
   annotation to the nearest preceding diff block by source-line index;
   unanchored annotations go to a "general comments" section. Also
   captures LGTM/approve markers separately as approvals.

3. review_html_renderer.py — emits single-file 2-col HTML. Top jump-nav
   lists every annotation with severity badge + 80-char preview + jump
   link + per-tier counts in heading. Each hunk-row is a CSS grid with
   diff on the left (per-line numbers, +/- marks, addition/deletion bg
   tints from --md-success/--md-warn via color-mix) and annotation cards
   on the right. WCAG-1.4.1-compliant severity badges (color + icon +
   aria-label + text — color is NEVER the sole signal); BLOCKER danger
   color computed by hue-rotating the design-system accent 120° toward
   red so it stays brand-coherent. Approval bar when LGTM markers
   present and no findings. Collapses to stacked on viewports < 900px.
   Mandatory --reviewer (refuses exit 3 otherwise — research-ops
   named-owner discipline). Refuses exit 4 if no hunks present (wrong
   skill → route to md-document). No Prism CDN (diff coloring conflicts
   with syntax highlighting).

Plus 3 references each citing 5-7 sources:
  - diff_rendering_canon.md — POSIX diff format + GitHub/GitLab UI +
    difftastic + SWE at Google ch. 9
  - severity_coding.md — WCAG 1.4.1 + Google review taxonomy + Don
    Norman Design of Everyday Things + NN/g color UX
  - pr_annotation_ux.md — convergent 2-col UX from GitHub / GitLab /
    Reviewable / CodeStream + SWE at Google + NN/g F-shape
1 template asset documenting the canonical 2-col review HTML shape.
/cs:md-review slash command with 4 pre-flight gates
(under-100-lines, no-onboarding, missing-reviewer, no-hunks) + pipeline
+ output digest.

Repo-level updates:
- markdown-html/.claude-plugin/plugin.json: skills array adds
  ./skills/md-review; version 2.10.1 → 2.10.2; description updated.
- .claude-plugin/marketplace.json: markdown-html-skills entry version
  and description; top-level counters 341 → 342 skills, 542 → 545 Python
  tools, 685 → 688 references, 88 → 89 slash commands; metadata.version
  2.10.1 → 2.10.2.
- Root CLAUDE.md: v2.10.2 release-notes block above v2.10.1.

Validation:
- check_plugin_json.py → OK
- sync-codex-skills.py --dry-run → 1 new symlink, documentation: 4 skills,
  total 343
- skill_description_validator.py → PASS (all 5 checks: present, length,
  third-person, trigger, action verb)
- skill_review_checklist_runner.py → 5/6 PASS (97 lines passes
  under-100-lines check; minor WARN on "user" vs "developer" terminology
  which are contextually distinct — converter operator vs review subject)
- All 3 tools pass --help and --sample
- Hard rules verified end-to-end:
    no --reviewer → exit 3 with refusal message
    no hunks → exit 4 with refusal message + md-document routing hint
    custom severity convention "critical,important,suggestion,nit" works
- Full pipeline on sample PR (2 diff blocks, 2 callouts) produces 11.3 KB
  single-file HTML with all 14 expected components (reviewer footer, PR
  title, aria-labels per WCAG 1.4.1, --md-danger computed color, modern
  color-mix tints, 2-col grid, 900px responsive collapse, both file
  paths, annotation cards, jump-nav, addition+deletion classes, Findings
  heading).

Coming in v2.10.3: md-slides — slide splitter + presenter-notes parser
+ arrow-key/space-bar nav + @media print for PDF export. Reuses
md-document's renderer scaffolding + design-system/scripts/config_loader.py.

https://claude.ai/code/session_01BK2KoQot1U7J5oSosrCQdc
2026-06-03 05:43:45 +00:00
..
.claude-plugin feat(markdown-html): add md-review v2.10.2 — code-review markdown→2-col HTML 2026-06-03 05:43:45 +00:00
agents feat(markdown-html): add v2.10.0 foundation — orchestrator + design-system 2026-05-29 14:19:06 +00:00
commands feat(markdown-html): add md-review v2.10.2 — code-review markdown→2-col HTML 2026-06-03 05:43:45 +00:00
skills feat(markdown-html): add md-review v2.10.2 — code-review markdown→2-col HTML 2026-06-03 05:43:45 +00:00
CLAUDE.md feat(markdown-html): add v2.10.0 foundation — orchestrator + design-system 2026-05-29 14:19:06 +00:00
README.md feat(markdown-html): add v2.10.0 foundation — orchestrator + design-system 2026-05-29 14:19:06 +00:00

markdown-html — Markdown to interactive HTML converter

"I generated a 200-line implementation plan in Claude Code last month. Markdown. … I skimmed the first 20 lines, scrolled past the diagram I could not actually parse, and closed the file. I never read the rest." — Thariq Shihipar, Claude Code HTML output (Medium, 2026)

Convert long markdown files in a Claude project into single-file, lightly-interactive HTML that respects your brand. One-time design-system onboarding captures brand primary + accent + typography + layout style + default save location. Every conversion reads that config and renders consistently.

Status — v2.10.0 (foundation)

Skill Purpose Status
markdown-html-orchestrator Routes long markdown → converter sub-skill (context: fork) ✓ live
design-system Onboarding wizard + WCAG-AA-validated brand palette + shared config ✓ live
md-document Long-form: sticky TOC + collapsibles + search + code-copy + scrollspy v2.10.1 (next PR)
md-review Code review: 2-col diff + severity-tagged margin annotations + jump-nav v2.10.1 (next PR)
md-slides Slide deck: arrow-key nav + presenter mode + print-to-PDF v2.10.1 (next PR)

Quick start

# 1. One-time onboarding (10 questions, ~60 seconds)
python3 markdown-html/skills/design-system/scripts/onboard.py

# 2. (or zero-touch defaults for first-test)
python3 markdown-html/skills/design-system/scripts/onboard.py --defaults

# 3. Inspect the saved config
python3 markdown-html/skills/design-system/scripts/config_loader.py --status

# 4. Classify a markdown file and see the routing decision
python3 markdown-html/skills/markdown-html-orchestrator/scripts/doctype_classifier.py \
    --input ./my-report.md --output json \
  | python3 markdown-html/skills/markdown-html-orchestrator/scripts/route_explainer.py

# 5. Resolve where it would save (foundation; converters in v2.10.1)
python3 markdown-html/skills/markdown-html-orchestrator/scripts/output_path_resolver.py \
    --input ./my-report.md --doctype document

Slash commands

  • /cs:markdown-html <path>.md — top-level router (classify + route + recommend)
  • /cs:grill-markdown-html <path>.md — Matt-style 5-question grill before conversion
  • /cs:design-system — surface the onboarding wizard

Hard rules

  1. Refuses input < 100 lines — markdown still wins below the threshold (Shihipar). Keep short docs as markdown.
  2. Refuses without onboarding — without a captured brand, output renders with placeholder defaults. Run onboarding once.
  3. Refuses unwritable save location — onboarding asks where to save; the orchestrator honors it; collisions get suffixed (-2, -3, …).
  4. Single-file HTML only — all CSS + JS inline. The only external CDN entries are Google Fonts + Prism.js. No build step, no bundler, no JS framework.
  5. Never silently chain — "convert this AND make slides AND a code review" is three operations, asked explicitly.
  6. WCAG AA enforced — body-text contrast must reach 4.5:1. Onboarding refuses any combination that fails.

Distinct from

  • Anthropic Playground plugin (/playground) — builds interactive prompt-tuning controls (sliders, knobs, prompt-copy-back). Different tool entirely.
  • marketing/landing/ — generates landing pages from scratch. Doesn't take markdown input.
  • engineering/handoff/ + productivity/handoff/ — session continuity briefs. Different artifact type.

File layout

markdown-html/
├── .claude-plugin/
│   └── plugin.json
├── agents/
│   └── cs-markdown-html-orchestrator.md
├── commands/
│   ├── cs-markdown-html.md          # router
│   ├── cs-design-system.md          # onboarding surface
│   └── cs-grill-markdown-html.md    # 5-question grill
└── skills/
    ├── markdown-html-orchestrator/  # context: fork
    │   ├── SKILL.md
    │   ├── scripts/
    │   │   ├── doctype_classifier.py
    │   │   ├── route_explainer.py
    │   │   └── output_path_resolver.py
    │   └── references/
    │       ├── information_density_canon.md
    │       ├── orchestrator_routing_patterns.md
    │       └── single_file_html_discipline.md
    └── design-system/
        ├── SKILL.md
        ├── scripts/
        │   ├── onboard.py
        │   ├── config_loader.py
        │   └── brand_palette_validator.py
        ├── references/
        │   ├── design_token_canon.md
        │   ├── wcag_accessibility.md
        │   └── typography_pairing.md
        └── assets/
            └── design_system_schema.json

License

MIT. See repo LICENSE.

Spec

Thariq Shihipar — Claude Code HTML output: Why Markdown Lost and How to Switch (Medium, 2026). The plugin operationalizes the article's central claim — markdown collapses past ~100 lines for agent-generated artifacts; HTML restores density, clarity, shareability, and lightweight interaction.