chromamark

ChromaMark for Python — render and build colored blocks, pills, collapsibles, fields, meters and inline diff on top of Markdown, with Jupyter display.


Keywords
chromamark, markdown, markdown-it, jupyter, report, agent, lint, cli, ai-agents, commonmark, gfm, llm, reporting, vscode-extension
License
MIT
Install
pip install chromamark==0.4.0

Documentation

ChromaMark

CI npm renderer npm cli npm conformance PyPI VS Code Marketplace Open VSX Code license Spec license

Markdown for AI-generated reports.

Start with the VS Code extension. It is the fastest way for humans and agents to evaluate agent output together: open a .cm report, compare its compact source with the rendered result, and use live diagnostics and quick fixes while the work is still in context. It is also available from Open VSX for VSCodium, Eclipse Theia, and other compatible editors.

Markdown was designed for people writing documents. Today, more and more reports are written by agents: deployment summaries, evaluations, code reviews, incident diagnostics, and CI results. The audience changed, but the format did not.

Note

Agent reports aren't prose

They communicate semantic state: status, severity, health, pass/fail, progress, metrics, structured fields, and expandable diagnostics.

Plain Markdown cannot express those concepts directly. Agents compensate with emoji conventions, raw HTML, or a different custom syntax in every project.

ChromaMark is a strict syntax superset of CommonMark + GFM that adds the semantic building blocks agent reports need while remaining readable anywhere Markdown already works. It adds meaning first; color is one renderer's way of making that meaning scannable.

Designed for AI from the ground up

  • Semantic, not decorative — encode success, danger, warnings, progress, fields, and details directly.
  • Token efficient — express report structure without verbose HTML.
  • Stream-safe — every opener precedes its content, so rendering can begin as tokens arrive.
  • Readable when truncated — unclosed blocks auto-close and incomplete constructs degrade to literal text.
  • Markdown-compatible — ordinary CommonMark and GFM continue to work.
  • Safe by default — no raw HTML or script execution is required.

ChromaMark feature gallery showing semantic blocks, pills, colored text, and progress meters

Why not HTML?

HTML solves presentation, but it makes the wrong tradeoffs for agent output:

  • expensive in tokens
  • noisy and fragile in plain text
  • awkward to stream incrementally
  • unsafe unless carefully sanitized
  • tedious for models and humans to author

The difference compounds across status-heavy reports. The same rendered badge, counted with the o200k_base tokenizer (GPT-4o/4.1/5-class):

Same PASS badge Source Tokens
ChromaMark pill [!ok PASS] 5
HTML span <span class="pill pill--ok">PASS</span> 12

A semantic callout shows the same ratio — ::: success / body / ::: is 10 tokens versus 22 for the <div class="callout…">…</div> equivalent.

📄 Read the spec · 🔄 Compatibility · 📐 Grammar · 🎨 Playground · 🖼️ Gallery

What it looks like on GitHub

Note

GitHub-native approximation

GitHub does not render ChromaMark directly. The example below is a transpiled approximation using GitHub Alerts, <kbd> badges, a text meter, and native details. For the full ChromaMark experience — theme-owned colors, styled meters, and rich containers — use the playground.

Tip

Deploy succeeded in 3m12s

Region eastus, 3/3 replicas ✅ healthy.

Build ✅ PASS · lint ⚠️ 12 · coverage █████████░ 87%

❌ Integration failures (3)

FAILED test_recon_merge_precedence — expected config to win

Open this exact source in the full playground.

ChromaMark source

::: info GitHub-native approximation
GitHub does not render ChromaMark directly. The example below is a **transpiled
approximation** using GitHub Alerts, `<kbd>` badges, a text meter, and native
details. For the full ChromaMark experience — theme-owned colors, styled meters,
and rich containers — use the [playground](https://cjfravel-dev.github.io/ChromaMark/playground/).
:::

::: success Deploy succeeded in 3m12s
Region `eastus`, 3/3 replicas [!ok healthy].
:::

Build [!pass] · lint [!warn 12] · coverage [=success 87%]

::: details danger Integration failures (3)
FAILED test_recon_merge_precedence — expected config to win
:::
Feature Syntax
Colored block ::: warning Title … :::
Colored pill [!success PASS], [!fail 3]
Collapsible ::: details open Summary … :::
Fields (key/value) ::: fields … :::
Colored text [.danger critical]
Progress meter [=success 87%]
Inline diff {++add++} {--del--} {~~a~>b~~}

Everything draws from one semantic color vocabulary — success/ok/pass, danger/error/fail, warning/warn, info/note, tip/hint, muted/skip — with a color=#hex escape hatch. Colors are theme-owned, so output adapts to light/dark automatically.

Applications can also use safe built-in presets (ocean, sunset, monochrome, and GitHub light/dark) or constrained semantic overrides through the theme API, without accepting arbitrary CSS.

Quick start (webpage)

One CDN import and an attribute — the library injects its own theme and renders every target. No build step, no CSS to copy.

Already shipping MarkdownIt? Use the browser-slim entry to keep ChromaMark plugin rules, DOM hooks, and themes while excluding the parser library.

<script src="https://cdn.jsdelivr.net/npm/@chromamark/renderer@0.4.2/dist/chromamark.min.js"
        data-chromamark-auto></script>

<div class="chromamark">
::: success
All 247 tests passed.
:::
</div>

Prefer to drive it yourself? Skip data-chromamark-auto and call the hook:

<script src=".../chromamark.min.js"></script>
<script>
  ChromaMark.injectTheme();            // add the stylesheet once
  ChromaMark.renderElement('#report'); // render a specific section
</script>

Auto-render targets any <script type="text/chromamark">, .chromamark, or [data-chromamark] element on the page.

Keep the page lean by loading the ChromaMark from an external file — like an external script or stylesheet — with data-chromamark-src:

<div data-chromamark-src="report.cm"></div>
<script src=".../chromamark.min.js" data-chromamark-auto></script>

Quick start (Node / bundler)

npm install @chromamark/renderer
import { render } from '@chromamark/renderer';        // string → HTML
const html = render('::: success\nAll good [!ok pass]\n:::');

// …or as a markdown-it plugin:
import MarkdownIt from 'markdown-it';
import chromamark from '@chromamark/renderer';
const md = new MarkdownIt().use(chromamark);

VS Code

The chromamark-vscode extension renders ChromaMark in the built-in Markdown preview, highlights its syntax, and reports live lint diagnostics with quick fixes for .cm files. .cm files are treated as Markdown. Press F5 from the repo to try it. Install it from the VS Code Marketplace or Open VSX.

For LLMs & agents

ChromaMark is designed to be emitted by AI agents as plain text. Drop docs/llms.txt into a system prompt to teach a model the full syntax in a few hundred tokens. One gotcha worth repeating: don't wrap pills in backticks`[!pass]` renders as literal code, not a pill. Guard against that (and other silent mistakes) in CI with chromamark lint.

Coding assistants that understand skills can install the authoring reference directly from this repo:

npx skills add cjfravel-dev/ChromaMark

This adds a self-activating chromamark-authoring skill (generated from docs/llms.txt) that teaches the agent when and how to write .cm.

Built for streaming

Agents emit token-by-token and sometimes get cut off mid-thought. ChromaMark is designed so a truncated document still renders cleanly — no HTML-style broken tags, no lost content:

  • An unclosed ::: success block auto-closes at end of input and still renders in full.
  • A half-written pill like [!pass degrades to readable literal text, not garbage.
  • Every construct's opener precedes its content, so a renderer can begin styling with no lookahead.

This is the thing HTML can't do gracefully and plain Markdown can't do at all. See the streaming contract in SPEC §12.

For live token feeds, the incremental streaming API commits stable blocks, reparses only the mutable tail, and patches only that tail in the browser while guaranteeing exact final HTML.

Safety & sanitization

Agent output is untrusted input, so ChromaMark is safe by default:

  • Raw HTML is escaped by default. The preconfigured renderer runs markdown-it with html: false, so a <script> in agent output renders as literal text. The plugin respects its host's HTML setting consistently; enabling raw HTML is appropriate only for trusted or separately sanitized input.
  • No CSS injection. color= accepts only hex literals or plain color names; functional forms (e.g. url(...), expression(...)) are rejected.
  • No script execution. No construct requires or permits <script>, event handlers, or javascript: URLs.

Details in SPEC §2–3.

Command line

Compile .cm files to self-contained HTML (theme inlined, no CDN) with @chromamark/cli:

npx @chromamark/cli build report.cm        # → report.html
npx @chromamark/cli build docs/ -o site/   # a whole tree

Or transpile to GitHub-native GFM for pull requests, issues, READMEs, and Actions summaries — callouts become Alerts, details/tables stay native, and pills become tone-aware <kbd> badges:

npx @chromamark/cli github report.cm
cat report.cm | npx @chromamark/cli github

See the GitHub export mapping.

Or render straight to a color terminal — tones become ANSI colors, pills become bracketed icon chips ([✓ PASS]), blocks get a colored left bar. Handy for CI logs and agent CLIs; honors NO_COLOR:

npx @chromamark/cli render report.cm       # ANSI to your terminal
cat report.cm | npx @chromamark/cli render # from stdin

Or lint a document in CI to catch the mistakes the format otherwise hides silently — a pill wrapped in backticks, a typo'd tone, an unclosed block:

npx @chromamark/cli lint report.cm         # exits non-zero on problems

Python & Jupyter

The chromamark Python package renders ChromaMark to the same HTML and displays it inline in notebooks:

from chromamark import display_chromamark, ChromaDoc
display_chromamark("::: success\nRun complete [=success 100%]\n:::")

Python-only environments also get the cross-runtime lint workflow:

chromamark lint report.cm

Repository layout

ChromaMark/
├── README.cm                   canonical source for generated README.md
├── SPEC.md                     the specification (written in ChromaMark)
├── docs/                       llms.txt, grammar.ebnf, integrations roadmap, logo assets
├── conformance/                public corpus, schema, and runner protocol
├── examples/demo.cm            a sample document exercising every construct
├── packages/
│   ├── renderer/               @chromamark/renderer — HTML, GitHub GFM, ANSI, lint, browser
│   ├── cli/                    @chromamark/cli — build, GitHub export, ANSI, lint
│   ├── conformance/            @chromamark/conformance — fixtures, schema, runner
│   ├── python/                 chromamark (pip) — renderer, builder, Jupyter
│   └── vscode/                 chromamark-vscode — preview + highlighting
├── eval/                       LLM-conformance eval harness (measures llms.txt)
└── scripts/build-site.mjs      builds the GitHub Pages site

Development

Third-party renderer authors can install the public conformance kit:

npm install --save-dev @chromamark/conformance

It ships the versioned exact-HTML corpus, JSON Schema, typed JavaScript runner, and a language-neutral protocol.

npm ci
npm test                                     # renderer test suite (node:test)
npm test --workspace @chromamark/cli         # CLI tests (build, render, lint)
npm run test:eval                            # eval harness tests
npm run test:scripts                         # repository workflow/docs tests
npm run lint                                 # ESLint
packages/python/.venv/bin/python -m ruff check packages/python/src packages/python/tests
npm run coverage                             # combined JS/Python coverage
npm run eval                                 # offline LLM-conformance demo
npm run build --workspace @chromamark/renderer   # bundle dist/ for the browser/CDN
npm run build:readme                         # README.cm → GitHub-native README.md
npm run build:site                           # build the Pages site into _site/

See Contributing, the Code of Conduct, Security, the changelog, and the release guide for the complete workflow.

Prior art & credits

ChromaMark builds on well-designed standards rather than reinventing them:

  • CommonMark + GitHub Flavored Markdown — the base syntax ChromaMark extends without redefining.
  • CriticMarkup (© 2013 Gabe Weatherhead & Erik Hess, Apache-2.0) — the inline change-tracking syntax ({++add++}, {--del--}, {~~a~>b~~}) ChromaMark adopts for diffs. Our parser is an original, independent implementation.
  • markdown-it and markdown-it-py — the pluggable Markdown engines the JS and Python renderers extend.

License

ChromaMark uses a deliberate code/specification split:

  • Software: MIT License.
  • Specification: CC BY-SA 4.0, with attribution to the CommonMark and GitHub Flavored Markdown specifications it builds upon.

See third-party notices for dependency and prior-art attribution.

Citation

Published work can cite ChromaMark using CITATION.cff, which preserves the project name, canonical repository, and author attribution.