Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 53 additions & 25 deletions .claude/commands/think-in-html.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,71 @@
# /think-in-html

Generate an interactive HTML explainer from code, thinking transcripts, or text. The output is a single self-contained `.html` file that anyone can open in a browser — no server, no dependencies.
Generate an interactive HTML explainer from code, thinking transcripts, or text. The output is a single self-contained `.html` file that anyone can open in a browser — no server, no dependencies. **Every explainer is authored fresh — a different design and a different interactive model each time.**

## Arguments

$ARGUMENTS — the target to analyze. Can be a file path, folder path, or a description of what to analyze. Optionally prefix with `--mode code|thinking|text` (defaults to `code`).
$ARGUMENTS — the target to analyze (a file path, folder, or a description of what to explain).
Optional flags:
- `--mode code|thinking|text` — the kind of input (default `code`).
- `--blocks` — use the legacy template engine (schema-validated teaching blocks + preset skins) instead of freeform. Use only when the user explicitly wants the templated output.
- `-o <path>` — output file (default `output.html`).

## Steps
## Default flow — Freeform (author the whole page on the fly)

1. **Determine mode.** Parse `$ARGUMENTS` for `--mode`. Default to `code` if not specified.
This is the default. You design and build a complete, bespoke, interactive HTML file for
THIS subject — its own layout, its own visual system, its own interactive logic. **No two
outputs should look alike, and the interactive part must be driven by the subject's real
logic**, not decoration.

2. **Read the instructions.** Read these files from the project root (or from wherever `core/` lives):
- `core/instructions/ANALYZE.md` — how to think like a teacher and compose a lesson
- `core/instructions/mode-{mode}.md` — mode-specific guidance
1. **Read the instructions.** Read `core/instructions/FREEFORM.md` (the quality rubric,
the "make the core mechanic tangible" mandate, the variety requirement, and the hard
self-contained safety constraints). Also read `core/instructions/mode-{mode}.md` for
input-type guidance.

3. **Read the schema.** Read `core/schema/analysis.schema.json` to understand the block contract (`schemaVersion: 2`).
2. **Read the target thoroughly.** Understand the real logic, constants, names, and edge
cases. If it's a folder, pick the single most teachable flow — don't try to cover
everything.

4. **Think like a teacher, then compose.** Don't pour the code into a fixed template. Decide
the best way to teach THIS subject — pick a real-world analogy if one helps — and compose an
ordered list of teaching blocks (`hook`, `analogy`, `flow`, `steps`, `concept`, `code`,
`compare`, `aha`, `quiz`, `recap`, `glossary`) that fits. Every lesson should feel bespoke.
3. **Pick the core mechanic to make tangible.** Decide the one dynamic the reader should
be able to *play with*, and design a small working model of it that reimplements the
subject's real rule (same formula/thresholds/states).

5. **Emit analysis JSON.** Write valid JSON to `analysis.json` in the project root. It MUST
conform to the schema (a non-empty `blocks` array; every block has a known `type`). You may
set a default `meta.skin`, but the viewer can switch skins live regardless.
4. **Choose a bespoke design direction** from the domain — palette, layout, type, and a
recurring motif — deliberately different from anything you've produced before.

6. **Build the HTML.** Run:
5. **Write the single `.html`** to the output path with everything inline (CSS + JS), the
required CSP `<meta>`, system fonts, and any imagery as inline SVG / `data:` URIs.
Escape anything echoed verbatim from the source. No network at runtime.

6. **Validate self-containment:**
```
node core/build/inline.mjs analysis.json -o output.html
node core/build/check-html.mjs output.html
```
Fix every error it reports and re-check until it passes.

7. **Report.** Tell the user where the file is and, in one line, what the interactive
centerpiece lets them do.

## Legacy flow — Blocks (`--blocks`)

Only when the user explicitly asks for the templated engine:

7. **Report.** Tell the user where the output file is, and that they can switch the visual skin
(Aurora / Storybook / Blueprint / Terminal, plus 🎲 Surprise me) live in the top-right.
1. Read `core/instructions/ANALYZE.md` and `core/schema/analysis.schema.json`.
2. Compose an ordered `blocks` array (`hook`, `analogy`, `flow`, `steps`, `concept`,
`code`, `compare`, `aha`, `quiz`, `recap`, `glossary`) and an optional bespoke `design`
theme (ANALYZE.md → *Step 3*).
3. Write `analysis.json`, then `node core/build/inline.mjs analysis.json -o output.html`.
4. Report the output path; the reader can switch skins live in the 🎨 picker.

## Important

- The JSON must pass schema validation. If `inline.mjs` reports errors, fix the JSON and rebuild.
- Use `textContent`-safe strings — never include raw HTML in `plain` or `technical` fields.
- The `plain` field is teacher voice: explain like the reader has never seen code before.
- `technical` is optional — only include it when there's meaningful extra detail.
- Keep the walkthrough linear and narrated — each step should feel like "and then..."
- Quiz questions test understanding, not trivia. Always explain the answer.
- **Freeform must pass `check-html.mjs`** — if it flags an external resource, inline it (or
use a `data:` URI) and re-check. The file must work fully offline.
- **Different every time.** If your draft resembles a hero + card grid you've used before,
choose a different structure. Let the subject pick the shape.
- **Real logic, not a cartoon.** The interactive model must reflect the source's actual
behavior — read the code and use its real constants and names.
- **Teacher voice.** Explain like the reader is smart but new to this; gloss jargon in
plain English.
- A worked reference at the intended quality bar:
`examples/novus-pricing-desk.freeform.html`. Study it, then build something different.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ output/
/*.analysis.json

.vii/

# Local-only planning docs (not pushed)
/LANDING-PLAN.md
60 changes: 44 additions & 16 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,62 @@

A tool-agnostic engine that turns code, AI thinking transcripts, or text into self-contained interactive HTML explainers.

## Architecture
There are two generation modes. **Freeform is the default.**

### Freeform mode (default) — the AI authors the whole page on the fly

```
target input → AI reads core/instructions/FREEFORM.md → writes a bespoke output.html → check-html.mjs validates self-containment
```

The AI designs and builds a complete, unique, interactive HTML explainer per subject —
its own layout, visual system, and an interactive model of the subject's core mechanic.
No two outputs look alike. The only hard invariant is that the file is a single
self-contained artifact that works offline.

- `core/instructions/FREEFORM.md` — the rubric: "make the core mechanic tangible", the
variety mandate, and the hard self-contained safety constraints.
- `core/build/check-html.mjs` — zero-dep validator that rejects any external resource
load (external `<script>/<link>/<img>`, `@import`, remote `url()`), requires the CSP
meta and a doctype. This is the gate that replaces schema validation for freeform.
- `examples/*.freeform.html` — worked references at the intended quality bar (e.g.
`novus-pricing-desk.freeform.html`).

### Blocks mode (`--blocks`) — legacy templated engine

```
target input → AI reads core/instructions/ → analysis.json (schema-validated) → HTML shell renders it → one output.html
target → AI reads core/instructions/ANALYZE.md → analysis.json (schema-validated) → HTML shell renders it → one output.html
```

- `core/template/` — the HTML+CSS+JS renderer (shell.html, app.js, styles.css)
- `core/schema/analysis.schema.json` — the contract between LLM output and the renderer
- `core/instructions/` — portable instructions any AI tool reads to produce analysis JSON
- `core/build/inline.mjs` — zero-dep Node script that inlines everything into one .html
- `adapters/` — thin per-tool configs (Claude Code, Cursor, Codex, etc.)
- `core/template/` — the tested HTML+CSS+JS renderer (shell.html, app.js, styles.css)
- `core/schema/analysis.schema.json` — the contract between block JSON and the renderer
- `core/build/inline.mjs` — zero-dep script that inlines everything into one .html
- Supports an AI-authored `design` theme (ANALYZE.md → Step 3) plus 4 preset skins.

`adapters/` — thin per-tool configs (Claude Code, Cursor, Codex, etc.).

## Commands

- `/think-in-html <target>` — generate an interactive HTML explainer for the given file/folder
- `/think-in-html <target>` — freeform bespoke explainer (default)
- `/think-in-html <target> --blocks` — legacy templated explainer

## Build
## Build / validate

No dependencies to install. To build an output from an existing analysis.json:
No dependencies to install.

```
node core/build/inline.mjs analysis.json -o output.html
node core/build/check-html.mjs output.html # freeform: verify self-contained
node core/build/inline.mjs analysis.json -o output.html # blocks: build from JSON
```

## Key rules

- The LLM only emits structured JSON, never raw HTML. The tested shell renders it.
- All content injected into the DOM must be escaped (textContent, not innerHTML with raw data).
- The `plain` field uses teacher voice — no jargon without a glossary entry.
- `technical` fields are optional — they fall back to `plain` when absent.
- Output must be a single self-contained .html with no external dependencies.
- **Freeform is the default and should look different every time.** The interactive
centerpiece must reflect the source's real logic (real constants/thresholds/states),
not decoration.
- Output must be a single self-contained `.html` with no external dependencies, and must
pass `check-html.mjs`. Include the CSP `<meta>`; use system fonts + inline SVG/`data:` URIs.
- Escape anything echoed verbatim from the source (textContent / HTML-escape) — never
build DOM from an unescaped source string. No inline `on*=` handlers, no `eval`.
- **Blocks mode only:** the LLM emits schema JSON (never raw HTML) and the tested shell
renders it; `plain` is teacher voice, `technical` is optional and falls back to `plain`.
2 changes: 1 addition & 1 deletion PUBLISHING.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ You need an [npmjs.com](https://www.npmjs.com/signup) account.
npm login

# 2. Confirm what will be published — should list only:
# bin/ core/ adapters/ README.md LICENSE package.json
# bin/ core/ adapters/ examples/ README.md LICENSE package.json
npm pack --dry-run

# 3. Publish (the name `think-in-html` is unscoped and public)
Expand Down
Loading
Loading