Skip to content

leeguooooo/htmldock

Repository files navigation

htmldock

Team document hub for HTML generated by AI coding agents. Drop HTML files into any repo; htmldock auto-uploads, indexes, and serves them with team-scoped auth and public share links — all on Cloudflare's edge.

Inspired by Thariq Shihipar's The Unreasonable Effectiveness of HTML"As agents have become more powerful, markdown has become a restricting format … HTML can convey much richer information." Thariq made the case; htmldock is the team-shaped place to put the output.

Release License Stack Built with

Live demo · Skill for Claude Code / Codex · CLI install · Self-host


Why htmldock

In May 2026 Thariq Shihipar published The Unreasonable Effectiveness of HTML, arguing that as AI coding agents got more capable, HTML started beating Markdown as their output format. HTML carries the information density agents need — SVG diagrams, tables, styled callouts, interactive sliders, embedded screenshots — while Markdown reduces everything to bullet lists and ASCII boxes.

Within weeks Claude Code / Cursor / Codex / OpenHands users were turning out HTML design specs, code reviews, runbooks, dashboards, and learning notes by the bucket. And then they hit the next problem: where do these files live for a team to read?

  • Markdown wikis (Notion, Confluence, GitBook) re-render HTML to their own model and strip styling.
  • GitHub previews of .html blobs render as source, not the page.
  • Pastebins / Gists are personal, not team-scoped, and don't index for search.
  • S3 + static hosting has no auth, no sharing, no UI.

htmldock is the missing piece downstream of Thariq's premise: a single-purpose HTML doc hub built for the AI-agent workflow. Every HTML your agent generates lands on a team-readable URL with one CLI call, indexed for full-text search, sharable with a public token when needed — and nothing else fights for screen space.

How it feels

# Set up once
htmldock login                     # OAuth via Lark
htmldock init                      # writes .htmldock.toml (team, project, etc.)

# Day-to-day: agent writes HTML, htmldock auto-publishes
claude "draft a runbook for the new auth migration" → docs/auth-migration.html
# → PostToolUse hook fires → htmldock push (silent, in background)
# → https://htmldock.example.com/d/142

# Or manually, anytime
htmldock push docs/auth-migration.html
htmldock list --tree
htmldock share 142 --ttl-days 30
htmldock delete 142

Features

  • Team / project routing. Documents are grouped under team slugs and project slugs (e.g. acme-infra / billing-api / oauth-migration.html). Git remote stays as metadata; usernames never end up in URLs.
  • Generate-and-upload via skill. A bundled skills.sh skill installs a PostToolUse hook into any agent runner (Claude Code, Codex, …), so HTML files written by the agent are uploaded automatically.
  • Three visibility levels. team (default), public-allowed (allows generating tokenized public links), private-strict (only the author can read).
  • Hard delete. htmldock delete <id> and htmldock project delete <team>/<project> remove R2 + D1 + share tokens in one shot. No recycle bin.
  • Full-text search. D1's FTS5 over title + body text. Tokens, HTML tags, and entities stripped on write.
  • Public share tokens. 128-bit unguessable, opt-in TTL, served from a separate content origin with Referrer-Policy: no-referrer and X-Robots-Tag: noindex.
  • Origin isolation. Uploaded HTML loads from a content origin without session cookies, so untrusted user CSS/JS can't pivot to the app/API.
  • Tree depth cap. Display paths limited to 3 segments (including filename), enforced server-side. Keeps the index tree always one-screen-readable.
  • Cloudflare-native. Workers + D1 (SQLite) + R2 (object storage) + Pages. Free tier covers most teams; usage-based after that.

Architecture

┌──────────────────┐                       ┌──────────────────────┐
│  Claude Code     │  PostToolUse hook     │  Team member browser │
│  Cursor / Codex  │ ──┐  detects *.html   │  / external viewer   │
└──────────────────┘   │                   └────────┬─────────────┘
                       ▼                            │
              ┌─────────────────┐                   │
              │  htmldock CLI   │                   │
              │  (Bun, single   │ ─── PAT auth ──┐  │ Lark session cookie
              │   binary)       │                │  │ or /p/<token>
              └─────────────────┘                ▼  ▼
                                         ┌───────────────────────────┐
                                         │ Cloudflare Workers (Hono) │
                                         │ • /api/docs, /api/teams   │
                                         │ • /api/search, /api/share │
                                         │ • /d/<id>, /p/<token>     │
                                         └────────┬──────────┬───────┘
                                                  ▼          ▼
                                              ┌──────┐   ┌─────────────┐
                                              │  R2  │   │  D1 (SQLite)│
                                              │ HTML │   │ + FTS5      │
                                              └──────┘   └─────────────┘

See design.html for the full design spec (rendered in any browser).

CLI

Install

curl -fsSL https://raw.githubusercontent.com/leeguooooo/htmldock/main/scripts/install.sh | bash

Installs the latest binary into ~/.local/bin/htmldock. Override with HTMLDOCK_REPO=<owner>/htmldock for self-hosted forks, or HTMLDOCK_VERSION=v0.5.0 to pin.

Use

htmldock login                              # browser OAuth flow → PAT in ~/.config/htmldock/config.toml
htmldock team list                          # see teams you belong to
htmldock team create acme-infra "Acme Infra"
htmldock init                               # interactive: pick team, write .htmldock.toml

htmldock push docs/spec.html                # uploads, prints clickable URL
htmldock push docs/spec.html --public       # also generates a 30-day share link
htmldock list --tree                        # see the module tree for the current project

htmldock share 142 --ttl-days 7
htmldock delete 142 --yes
htmldock project delete acme-infra/old-thing --yes

.htmldock.toml lives at the repo root and is the source of truth for that repo's sync behavior:

team           = "acme-infra"            # required
project_slug   = "billing-api"           # optional; defaults to repo basename
sync           = true                    # whether the hook auto-uploads
visibility     = "team"                  # team | public-allowed | private-strict
module_root    = "docs"                  # only HTML under this prefix is uploaded
ignore         = ["draft/**", "scratch/*.html"]
auto_module    = true                    # let the agent choose a module prefix

Agent skill

Platform-agnostic. Works with Codex, Claude Code, and anything else skills.sh supports.

npx skills add leeguooooo/htmldock --skill htmldock -g

What the skill does:

  1. Installs the htmldock CLI binary automatically if missing.
  2. Tells the agent to reuse existing module path prefixes before inventing new ones (so docs cluster by topic, not date).
  3. Caps tree depth at 3 (server enforces too).
  4. Wires a PostToolUse hook so Write *.html in any opted-in repo (sync = true in .htmldock.toml) is uploaded automatically.

Scope to one agent with -a codex or -a claude. Omit -a to register for every detected runner.

Self-host

You can run htmldock on your own Cloudflare account in under 10 minutes.

git clone https://github.com/leeguooooo/htmldock
cd htmldock
bun install        # only needed for type-checking + tests
bunx wrangler login

# Create resources (one-time)
bunx wrangler d1 create htmldock                   # paste id into wrangler.toml
bunx wrangler r2 bucket create htmldock-docs

# Apply schema
bunx wrangler d1 migrations apply htmldock --remote

# Secrets
bunx wrangler secret put HMAC_SECRET           # any 32+ random bytes
bunx wrangler secret put LARK_CLIENT_ID        # for OAuth login
bunx wrangler secret put LARK_CLIENT_SECRET

bunx wrangler deploy

After deploying, allowlist https://<your-host>/api/auth/lark/callback inside your Lark app. Sign in once with /api/auth/lark, then htmldock config set-token <pat> --server https://<your-host> from the CLI.

Status

Area State
Backend (Workers + D1 + R2) shipping
CLI (Bun single-binary) v0.5.0 — team / delete / project delete
Dashboard minimal warm-paper SSR; redesign in progress
Lark OAuth working
Cloudflare Access SSO deferred (team membership is enough for MVP)
Doc versioning / rollback not in v1 — R2 keys overwrite
Comments / @ mentions not in v1

Roadmap: see open issues; design rationale lives in design.html.

Contributing

Bug reports, PRs, and design feedback welcome — open an issue or DM @leeguooooo. Local checks before pushing:

bun test
bunx tsc --noEmit

License

MIT. See LICENSE.

Related reading


Built for teams that ship documentation as fast as their agents can write it.

About

Team HTML doc hub for AI coding agents — generate HTML in Claude Code / Codex / Cursor, auto-upload to a private Cloudflare-backed reader with team auth, full-text search, and public share links.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors