The Unreasonable Effectiveness of HTML — as an open skill for every AI coding agent.
Bloom is a per-session sticky skill that makes flat markdown bloom into rich, self-contained .html artifacts. Drop it into any AI coding agent and reports, reviews, plans, design docs, and interactive editors come back as single .html files you can open, click around, and export from — because diffs, diagrams, status reports, and design comparisons are spatial information that loses meaning when flattened into prose.
Supported harnesses (the skill is a single markdown file; copy it to whatever your agent reads):
- Claude Code —
.claude/skills/bloom/(sticky session skill) - Codex CLI (OpenAI) —
AGENTS.md - Codex App (OpenAI web/desktop) —
AGENTS.mdon the linked GitHub repo - Factory Droid —
droids/bloom.md - Gemini CLI (Google) —
GEMINI.md - OpenCode (sst) —
AGENTS.md - Cursor —
.cursorrulesor.cursor/rules/bloom.mdc - GitHub Copilot CLI —
AGENTS.md
Plus Windsurf, Aider, GitHub Copilot for VS Code, Continue, Replit Agent, Pi, and any other system-prompt-aware agent.
Type /bloom once and every substantial artifact for the rest of the session becomes a self-contained .html file. Reserved files like README.md, CLAUDE.md, and AGENTS.md stay valid markdown and gain a richer .html companion next to them. Type /bloom-off to go back to plain markdown.
| Flat markdown | Self-contained HTML |
|---|---|
| Three approaches as three scroll-overs | Side-by-side cards with tradeoff tables |
| A diff you scroll through | Annotated diff with severity chips and jump links |
| "Imagine a four-column layout" | Live rendered variants you can actually see |
| "Think about the easing curve" | Animation sandbox with a slider |
| A checklist in a PR description | A triage board you can drag and export |
| A paragraph about token values | Living design system with swatches you copy from |
This skill captures the patterns from The Unreasonable Effectiveness of HTML and makes them reproducible across every agent harness.
See examples/ for worked artifacts:
pr-review-example.html— annotated PR review with risk chips, per-file cards, and a next-steps checklistincident-report-example.html— SEV-2 postmortem with timeline, root cause, impact, and action itemsdesign-system-example.html— living token reference with copyable color chips and a composed preview
Installation differs by harness. If you use more than one, install Bloom separately for each one. Each install is sticky once activated in a session and stays on until you turn it off or the session ends.
Every harness section below leads with the manual install — it works today, with no marketplace dependency. A "Planned marketplace install" subsection is included where one is being prepared, clearly marked as not yet live.
Works today: manual install
Copy the packaged skill into your project (or ~/.claude/skills/):
cp -r .claude/skills/bloom /path/to/your-project/.claude/skills/bloomOr drop the whole plugin into a project that uses .claude-plugin/:
cp -r plugins/bloom /path/to/your-project/.claude/plugins/bloomActivate per session with /bloom, /bloom-on, or by saying "bloom on" / "let it bloom". Deactivate with /bloom-off.
Planned marketplace install — not yet live
Bloom is queued for submission to Anthropic's official plugin marketplace. Until then, prefer the manual install above. The local Bloom marketplace listing also exists (.claude-plugin/marketplace.json); once Anthropic's marketplace ingestion is live for community plugins, this will be a one-liner. Do not paste speculative /plugin install commands until that listing is verified.
Works today: manual install
cp droids/bloom.md /path/to/your-project/AGENTS.md
# or, globally:
cp droids/bloom.md ~/.codex/AGENTS.mdIf you already have an AGENTS.md, append the contents of droids/bloom.md to it instead of replacing it.
Planned marketplace install — not yet live
Bloom is planned for submission to the openai/plugins marketplace. Until that listing exists, use the manual install above.
Works today: manual install
Commit AGENTS.md (copied from droids/bloom.md) to the GitHub branch you connect to the Codex app:
cp droids/bloom.md AGENTS.md
git add AGENTS.md && git commit -m "Add Bloom skill" && git pushPlanned marketplace install — not yet live
Once Bloom is listed in the Codex app's plugin sidebar, install will be a single click. Until then, use the manual install above.
Works today: manual install
# Project-scoped:
mkdir -p .factory/droids && cp droids/bloom.md .factory/droids/
# Personal:
mkdir -p ~/.factory/droids && cp droids/bloom.md ~/.factory/droids/Planned marketplace install — not yet live
Once Bloom is published to a Factory plugin marketplace, register and install will be a two-liner. Not live yet.
Works today: manual install
cp droids/bloom.md GEMINI.md
# or globally:
cp droids/bloom.md ~/.gemini/GEMINI.mdPlanned marketplace install — not yet live
gemini extensions install <repo> may work for some Gemini CLI builds, but the install path has not been validated against the current Gemini CLI release. Until verified, use the manual install above.
Works today: manual install
cp droids/bloom.md /path/to/your-project/AGENTS.mdOptional helper: ask OpenCode itself to follow plugins/bloom/INSTALL.opencode.md.
Planned marketplace install — not yet live
OpenCode's plugin marketplace ingestion is evolving; once a verified install exists, it will replace this manual step.
Works today: manual install
mkdir -p .cursor/rules && cp droids/bloom.md .cursor/rules/bloom.mdc
# or paste the contents of droids/bloom.md into .cursorrulesPlanned marketplace install — not yet live
If/when Cursor exposes a /add-plugin bloom command, it will be added here. Not live yet.
Works today: manual install
cp droids/bloom.md /path/to/your-project/AGENTS.mdPlanned marketplace install — not yet live
Copilot's plugin marketplace install path has not been verified. Use the manual install above.
See docs/harness-setup.md for Windsurf, Aider, GitHub Copilot for VS Code, Continue, Replit Agent, Pi, and any system-prompt-aware agent. The same trigger commands (/bloom, "bloom on", /bloom-off) work everywhere once the skill text is loaded into the harness.
Once activated, bloom is sticky for the rest of the session. You don't re-invoke it per turn — every substantial artifact comes back as an .html file until you deactivate.
Activate (any of these)
| Slash | Phrase | File marker |
|---|---|---|
/bloom |
"bloom on" | .bloom file at repo root |
/bloom-on |
"let it bloom" | (auto-enables at session start) |
/bloom-mode |
"activate bloom" |
Deactivate (any of these)
| Slash | Phrase |
|---|---|
/bloom-off |
"bloom off" |
/no-bloom |
"stop bloom" |
/bloom-mode-off |
"exit bloom" |
Where artifacts land
- Free-standing artifacts (status reports, reviews, plans) →
./bloom/<date>-<slug>.html - Companion to a reserved
.md(e.g.,README.md) → sibling.htmlnext to it (README.html) - The
.mdstays canonical so harnesses and GitHub keep working
What gets produced as HTML
Reports, reviews, comparisons, documentation, plans, explainers, diagrams, slide decks, postmortems, triage boards, flag/prompt editors — anything you'd otherwise dump as a wall of markdown.
What stays plain text
One-line answers, tool status updates, errors, short clarifying questions, commit messages, shell output. Bloom adds richness where it helps and stays out of the way where it doesn't.
Bloom/
├── README.md # This file
├── LICENSE # MIT
├── .claude-plugin/
│ └── marketplace.json # Bloom marketplace listing
├── plugins/
│ └── bloom/
│ ├── .claude-plugin/
│ │ └── plugin.json # Bloom plugin manifest
│ ├── skills/
│ │ └── bloom/
│ │ └── SKILL.md # Plugin-packaged skill
│ └── INSTALL.opencode.md # OpenCode install instructions
├── .claude/
│ └── skills/
│ └── bloom/
│ └── SKILL.md # Claude Code skill (manual install)
├── droids/
│ └── bloom.md # Canonical cross-harness skill
├── docs/
│ ├── harness-setup.md # Per-agent setup guides
│ ├── categories.md # The 9 document categories explained
│ ├── design-system.md # Token reference (v1)
│ ├── design-system-v2.md # Dark mode, motion tokens, Tabs, Modal
│ ├── construction-rules.md # The 12 rules for producing HTML
│ ├── construction-rules-v2.md # Rule 9 revision for templates
│ ├── security.md # Security hardening guide
│ ├── public-readiness.md # Public-readiness checklist
│ └── release-checklist.md # Release process
├── bloom-validator/ # Zero-dep TypeScript CLI
│ ├── README.md
│ ├── package.json
│ ├── src/
│ │ ├── index.ts # CLI entry (bloom-validate)
│ │ ├── parser.ts
│ │ ├── reporter.ts
│ │ ├── rule-registry.ts # All active rules in one place
│ │ └── rules/ # One file per rule
│ └── tests/ # node:test suite + fixtures
├── templates/ # Production-quality templates
│ ├── annotated-pr-review.html
│ ├── exploration-code-approaches.html
│ ├── incident-timeline.html
│ ├── status-report.html
│ ├── status-report-v2.html
│ └── skeletons/ # Starter scaffolds (clearly labeled)
│ ├── accessibility-report.html
│ ├── api-documentation.html
│ ├── architecture-decision.html
│ ├── dependency-audit.html
│ ├── design-review.html
│ ├── migration-plan.html
│ ├── monthly-review.html
│ ├── onboarding-guide.html
│ ├── sprint-retro.html
│ └── weekly-digest.html
├── examples/ # Fully worked artifacts
│ ├── pr-review-example.html
│ ├── incident-report-example.html
│ ├── design-system-example.html
│ └── feature-flag-editor-example.html
└── .github/
└── workflows/
└── ci.yml # Validator tests + artifact validation
Templates and skeletons are different:
- Templates (
templates/*.html) are production-quality. Real semantic structure, print styles, focus styles, ready to drop content into. - Skeletons (
templates/skeletons/*.html) are starter scaffolds. Each opens with a comment marking it as a skeleton and usesdata-template="<slot>"markers instead of placeholder text. Replace the slots before publishing.
Every file in templates/ and examples/ passes bloom-validator.
| # | Category | What it replaces | Key pattern |
|---|---|---|---|
| 1 | Exploration & Planning | Multiple prose descriptions | Side-by-side cards, tradeoff tables, recommendations |
| 2 | Code Review | Terminal diff dumps | Annotated diffs with risk chips, severity tags, jump links |
| 3 | Design | "Imagine a palette" | Living swatches, type scales, component variant matrices |
| 4 | Prototyping | "Think about how this animates" | Easing sliders, clickable flows, CSS copy-paste |
| 5 | Diagrams & Illustrations | ASCII art / Mermaid links | Inline SVG with download buttons, interactive flowcharts |
| 6 | Slide Decks | "Let me describe the slide" | Arrow-key navigable <section> slides |
| 7 | Research & Learning | Walls of explanation text | Collapsible steps, tabbed configs, interactive demos, glossary sidebars |
| 8 | Reports | Status emails nobody reads | Timeline cards, stat bands, inline bar charts |
| 9 | Custom Editors | "Prioritize these in a doc" | Drag boards with markdown export, flag toggles with copy-diff, prompt editors with live preview |
All templates use CSS custom properties from the same warm palette. See docs/design-system.md for the full reference and docs/design-system-v2.md for dark-mode tokens (via prefers-color-scheme), motion tokens (durations + easings), and the Tabs / Modal component patterns.
| Token | Value | Usage |
|---|---|---|
--ivory |
#FAF9F5 |
Page background |
--slate |
#141413 |
Headings, strong text |
--clay |
#D97757 |
Primary accent, CTAs, warnings |
--oat |
#E3DACC |
Warm fills, hover states |
--olive |
#788C5D |
Success, secondary accent |
--white |
#FFFFFF |
Card backgrounds |
--gray-100 |
#F0EEE6 |
Subtle fills, code blocks |
--gray-300 |
#D1CFC5 |
Borders, dividers |
--gray-500 |
#87867F |
Captions, muted labels |
--gray-700 |
#3D3D3A |
Body text |
Typography tokens:
| Token | Stack |
|---|---|
--serif |
ui-serif, Georgia, "Times New Roman", serif |
--sans |
system-ui, -apple-system, "Segoe UI", Roboto, sans-serif |
--mono |
ui-monospace, "SF Mono", Menlo, Monaco, Consolas, monospace |
All templates follow the security guidelines in docs/security.md:
- No external dependencies (CDN links, fonts, scripts)
- No
eval(),Function(), or dynamic code execution - No
innerHTMLwith user-controlled content (usetextContentor DOM APIs) - No network requests from generated files
- Content Security Policy compatible
- No
data:URIs for executable content - All event handlers use
addEventListener, not inlineon*attributes
The validator enforces all of these via the security-hardening rule.
bloom-validator/ is a zero-dependency TypeScript CLI that checks any .html file against Bloom's construction and security rules. It uses Node ≥ 22.6 native TypeScript type-stripping — no build step, no dependencies.
# Validate a single file
node bloom-validator/src/index.ts path/to/file.html
# JSON output
node bloom-validator/src/index.ts path/to/file.html --json
# Multiple files at once
node bloom-validator/src/index.ts a.html b.html c.html
# Validate every template, skeleton, and example in this repo
# (Node resolves the file list, so this works on Bash, Zsh, PowerShell, and CMD.)
cd bloom-validator && npm run validate-allExit codes: 0 clean, 1 errors found, 2 invalid usage.
The validator currently enforces 13 rules:
no-external-depsno-hardcoded-hexsemantic-htmlprint-media-queryheading-hierarchyviewport-metano-dialog-apislang-attributefocus-visibleresponsive-imagesno-empty-elementsno-inline-styles-except-rootsecurity-hardening(bundlesno-eval,innerHTML-with-variable,no-network,no-inline-handlers,no-data-html-uri,no-javascript-uri, and two more — seebloom-validator/README.md)
Every template under templates/ and every artifact under examples/ passes this validator on every push (see .github/workflows/ci.yml).
See docs/construction-rules.md for the full checklist, and docs/construction-rules-v2.md for the Rule 9 revision that lets templates ship plausible default content with data-template="<slot>" markers instead of [BRACKET] placeholders. Summary:
- Single file — All HTML, CSS, JS in one
.htmlfile - CSS custom properties — Use the palette tokens, never hard-code colors
- Semantic HTML —
<header>,<main>,<section>,<article>,<nav>,<aside>,<details> - Inline JS only — Minimal, no frameworks, no build step
- Responsive —
max-widthwrappers,clamp()type,@mediabreakpoints - Export mechanism — "Copy as markdown/JSON/diff" button on every editor
- Print-friendly — Key content readable without JS;
@media printblock - Accessible —
aria-label,role, heading hierarchy, focus states - No placeholder content — Every word specific and real (or marked via
data-template=) - Viewport meta — Always include
<meta name="viewport"> - Progressive enhancement — Core content visible without JS
- No
alert()/prompt()/confirm()— Use inline UI
- Fork this repo
- Create a feature branch
- Add or improve templates, docs, or the skill itself
- Run the validator against every template, skeleton, and example:
cd bloom-validator && npm run validate-all
- Run the validator's own tests:
cd bloom-validator && npm test
- Open a PR
See docs/public-readiness.md for the checklist this repo holds itself to, and docs/release-checklist.md for the per-release process.
MIT — see LICENSE.
Patterns and philosophy from The Unreasonable Effectiveness of HTML by the original author.