r-markdown-cli 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -11975,7 +11975,7 @@ async function createPreviewServer(file, options = {}) {
11975
11975
 
11976
11976
  // packages/cli/src/index.js
11977
11977
  var USAGE = `
11978
- Rich Markdown (rmd) CLI v0.2.0
11978
+ Rich Markdown (rmd) CLI v0.1.1
11979
11979
 
11980
11980
  Usage:
11981
11981
  rmd <command> [options]
@@ -12045,7 +12045,7 @@ async function main(argv = process.argv.slice(2), io = defaultIo()) {
12045
12045
  return 0;
12046
12046
  }
12047
12047
  if (command === "--version" || command === "-v") {
12048
- io.stdout(`rmd v0.2.0
12048
+ io.stdout(`rmd v0.1.1
12049
12049
  `);
12050
12050
  return 0;
12051
12051
  }
@@ -12131,8 +12131,9 @@ function parseInitArgs(args) {
12131
12131
  function resolveSkillSource(platform) {
12132
12132
  const __dirname2 = dirname2(fileURLToPath2(import.meta.url));
12133
12133
  const candidates = [
12134
- resolve2(__dirname2, "../assets/skills", platform),
12135
- resolve2(__dirname2, "../../../skills", platform)
12134
+ resolve2(__dirname2, "../skills", platform),
12135
+ resolve2(__dirname2, "../../../skills", platform),
12136
+ resolve2(__dirname2, "../assets/skills", platform)
12136
12137
  ];
12137
12138
  return candidates.find((candidate) => existsSync(candidate));
12138
12139
  }
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "r-markdown-cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "rmd": "dist/cli.js"
7
7
  },
8
8
  "files": [
9
9
  "dist",
10
+ "skills",
10
11
  "README.md"
11
12
  ],
12
13
  "workspaces": [
@@ -0,0 +1,132 @@
1
+ ---
2
+ name: rich-markdown
3
+ description: Generate Rich Markdown (.rmd) source and self-contained interactive HTML artifacts. Use when the user asks for rmd, Rich Markdown, rich interactive Markdown, token-efficient rich docs, shareable AI documents, charts, sliders, copy/export blocks, flow diagrams, timelines, kanban boards, collapsible details, carousels, embeds, math blocks, comparison reports, PR explainers, tunable prototypes, project status reports, or any rich document that should remain readable as Markdown but render as a polished interactive HTML page.
4
+ ---
5
+
6
+ # Rich Markdown
7
+
8
+ Use this skill when the user wants a rich, readable, interactive document
9
+ instead of plain Markdown or hand-written HTML. The local renderer
10
+ (`packages/cli`) turns `.rmd` source into a self-contained HTML artifact that
11
+ renders in Claude's chat / desktop sandbox, in any browser, or as an offline file.
12
+
13
+ ## Why .rmd over plain Markdown or HTML
14
+
15
+ - Source stays close to Markdown — diff-friendly, AI-friendly, low-token.
16
+ - The renderer adds charts, layouts, sliders, exports, flows, timelines, etc.
17
+ without forcing you to write SVG/CSS/JS.
18
+ - One source file, one self-contained HTML. No external assets needed for
19
+ Claude-rendered artifacts.
20
+
21
+ ## Output Choice (decide before writing)
22
+
23
+ | User intent | What to produce |
24
+ |---|---|
25
+ | Wants source only | `.rmd` file, no HTML build |
26
+ | Wants something to view / share / archive | `.rmd` + `--mode self-contained` HTML |
27
+ | Wants smallest artifact + has network | `.rmd` + `--mode cdn` HTML |
28
+ | Wants inspectable assets they can host themselves | `.rmd` + `--mode split` directory |
29
+ | Wants to demo locally during the session | `rmd open` preview server |
30
+
31
+ When unsure, default to source `.rmd` plus a `self-contained` HTML build.
32
+
33
+ ## Workflow
34
+
35
+ 1. Decide the smallest useful block set from `references/blocks.md`. Use
36
+ plain Markdown for narrative; use `:::` blocks only when they add density,
37
+ structure, or interaction.
38
+
39
+ 2. Write the `.rmd` file. Always include a YAML frontmatter with at least
40
+ `title`. Suggested location: `examples/<short-name>.rmd`.
41
+
42
+ 3. Validate the source with the Bash tool:
43
+
44
+ ```bash
45
+ npm run rmd -- validate path/to/doc.rmd
46
+ ```
47
+
48
+ If validation fails, fix the source. Do not return a file that fails
49
+ validation.
50
+
51
+ 4. Build the artifact:
52
+
53
+ ```bash
54
+ # Default: single self-contained HTML
55
+ npm run rmd -- build path/to/doc.rmd --mode self-contained --out path/to/doc.html
56
+
57
+ # CDN-loaded variant (small artifact, requires network at view time)
58
+ npm run rmd -- build path/to/doc.rmd --mode cdn --version 0.1.0 --out path/to/doc.html
59
+
60
+ # Split directory (HTML + JS + CSS as separate files)
61
+ npm run rmd -- build path/to/doc.rmd --mode split --out path/to/dist/index.html
62
+ ```
63
+
64
+ 5. (Optional) Local preview during the session:
65
+
66
+ ```bash
67
+ npm run rmd -- open path/to/doc.rmd --port 0 --host 127.0.0.1 --no-open true
68
+ ```
69
+
70
+ The CLI prints the bound URL. Use `--no-open true` so the agent does not
71
+ try to launch a desktop browser.
72
+
73
+ 6. Return the generated HTML file path to the user. If self-contained, the
74
+ file alone is the deliverable.
75
+
76
+ ## Rules (these are hard constraints)
77
+
78
+ - **No styling in source.** Never write colors, pixel sizes, fonts, or layout
79
+ CSS into `.rmd`. Use semantic attributes like `emphasis=primary` and let
80
+ the theme decide visuals. (Themes can change; source must not.)
81
+
82
+ - **Diff-clean edits.** One semantic change should touch only nearby lines.
83
+ Don't reorder unrelated attributes or rewrite a whole file for a small fix.
84
+
85
+ - **Validate before shipping.** Validation failures are not warnings. Fix
86
+ the source before returning the artifact.
87
+
88
+ - **Plain Markdown for fragile content.** Use plain Markdown — code blocks,
89
+ tables, blockquotes — for anything you're unsure how to express in `.rmd`.
90
+ Don't invent block names.
91
+
92
+ - **Self-contained for sandboxes.** If the user will view the artifact inside
93
+ Claude's sandbox, in email, or anywhere external assets can't be fetched,
94
+ use `--mode self-contained`. `split` mode will not load in those contexts.
95
+
96
+ ## Block Selection Cheatsheet
97
+
98
+ Map the user's intent to the smallest block set that delivers value:
99
+
100
+ | Intent | Blocks |
101
+ |---|---|
102
+ | Compare options / approaches | `grid` + `chart` + `callout` |
103
+ | PR / code review explainer | `diff` + `tabs` + `callout` |
104
+ | Tunable prototype (params + copy back to chat) | `slider` + `export` |
105
+ | Release / workflow | `flow` + `callout` + `timeline` |
106
+ | Project status report | `chart` + `timeline` + `kanban` |
107
+ | Research brief | `chart` + `grid` + `details` |
108
+ | Showcase / gallery | `carousel` + `grid layout=masonry` |
109
+ | Long doc with collapsible appendix | `details` + `tabs` |
110
+ | Math / formal explanation | `math` + `callout` |
111
+
112
+ The 14 supported blocks (v0.2): `chart`, `grid`, `callout`, `slider`,
113
+ `export`, `flow`, `diff`, `tabs`, `timeline`, `kanban`, `details`, `carousel`,
114
+ `embed`, `math`. Full reference: `references/blocks.md`.
115
+
116
+ ## Default Recipe
117
+
118
+ For Claude-visible rich output:
119
+
120
+ 1. Write `examples/<short-name>.rmd` with appropriate blocks.
121
+ 2. `npm run rmd -- validate examples/<short-name>.rmd`
122
+ 3. `npm run rmd -- build examples/<short-name>.rmd --mode self-contained --out examples/<short-name>.html`
123
+ 4. Return `examples/<short-name>.html` as the deliverable.
124
+
125
+ See `examples/` in this skill for two ready-to-study patterns:
126
+ - `examples/decision-report.rmd` — comparison + chart + callout
127
+ - `examples/tunable-config.rmd` — slider + export + flow
128
+
129
+ ## References
130
+
131
+ - `references/blocks.md` — all 14 block types with attributes and examples
132
+ - `references/artifacts.md` — build modes, validation, frontmatter tips
@@ -0,0 +1,64 @@
1
+ ---
2
+ title: "Storage Tier Decision Report"
3
+ theme: default
4
+ share: team
5
+ description: "Comparison of hot/warm/cold storage strategies for the analytics pipeline."
6
+ ---
7
+
8
+ # Storage Tier Decision Report
9
+
10
+ We need to pick a storage strategy for the analytics pipeline that handles
11
+ ~3 TB/day. Three candidates evaluated against latency, cost, and operational
12
+ complexity.
13
+
14
+ ## Candidates
15
+
16
+ :::grid 3
17
+ ### Hot only
18
+ All data on NVMe SSD.
19
+ **Pros**: lowest read latency (≈2 ms).
20
+ **Cons**: $$$ per TB; capacity ceiling reached in ~6 months.
21
+ ---
22
+ ### Tiered (hot + cold)
23
+ Recent 7 days on SSD, older on object storage.
24
+ **Pros**: 70% cost reduction, latency unchanged for typical queries.
25
+ **Cons**: needs lifecycle automation; cold-restore latency 30-60 s.
26
+ ---
27
+ ### Cold only
28
+ Everything on object storage with index cache.
29
+ **Pros**: cheapest; effectively unlimited.
30
+ **Cons**: P95 read latency 1.5 s, breaks the SLA for live dashboards.
31
+ :::
32
+
33
+ ## Cost vs Latency
34
+
35
+ :::chart bar title="Monthly cost (k$) vs P95 read latency (ms)" y="cost(k$)" y2="P95(ms)" legend=top
36
+ HotOnly 48 2
37
+ Tiered 14 2
38
+ ColdOnly 3 1500
39
+ :::
40
+
41
+ ## Recommendation
42
+
43
+ :::callout tip title="Pick Tiered"
44
+ Tiered storage hits the SLA, costs roughly a third of hot-only, and the
45
+ lifecycle automation is a one-time investment we already use for backups.
46
+ :::
47
+
48
+ ## Rollout Plan
49
+
50
+ :::flow direction=lr
51
+ Spec -> Review -> Migrate cold path -> Enable lifecycle -> Monitor
52
+ Migrate cold path -> Issue -> Pause and audit
53
+ :::
54
+
55
+ ## Risk Register
56
+
57
+ :::details title="Operational risks and mitigations"
58
+ 1. **Cold restore stalls during peak query**: cap concurrent restore jobs;
59
+ surface a "restoring" badge in the UI so users don't retry.
60
+ 2. **Lifecycle policy misfires and deletes hot data**: dry-run mode for first
61
+ 7 days; alert on >1% delta vs expected size.
62
+ 3. **Object storage region outage**: keep last 24h of cold data mirrored to a
63
+ second region; documented failover runbook.
64
+ :::
@@ -0,0 +1,53 @@
1
+ ---
2
+ title: "Rate Limiter Config — Tune & Copy"
3
+ theme: default
4
+ share: private
5
+ description: "Adjust the token-bucket parameters and copy the resulting YAML."
6
+ ---
7
+
8
+ # Rate Limiter Config — Tune & Copy
9
+
10
+ Drag the sliders to tune the token-bucket rate limiter. The export button
11
+ below copies the matching YAML config straight to your clipboard.
12
+
13
+ ## Parameters
14
+
15
+ :::slider name=capacity label="Bucket capacity" min=10 max=2000 step=10 default=200 unit=req
16
+ :::
17
+
18
+ :::slider name=refill_rate label="Refill rate" min=1 max=500 step=1 default=50 unit=req/s
19
+ :::
20
+
21
+ :::slider name=burst_window label="Burst window" min=1 max=120 step=1 default=10 unit=s
22
+ :::
23
+
24
+ ## Generated YAML
25
+
26
+ :::export label="Copy YAML config" format=text
27
+ rate_limiter:
28
+ type: token_bucket
29
+ capacity: {{capacity | int}}
30
+ refill_rate: {{refill_rate | int}}
31
+ burst_window_seconds: {{burst_window | int}}
32
+ :::
33
+
34
+ ## How requests flow
35
+
36
+ :::flow direction=lr
37
+ Request -> Bucket has token? -> Allow
38
+ Bucket has token? -> Refill check -> Allow
39
+ Bucket has token? -> Refill check -> Reject 429
40
+ :::
41
+
42
+ ## Tradeoffs
43
+
44
+ :::callout warning title="Watch the burst window"
45
+ A wide burst window smooths short spikes but lets sustained overload through
46
+ longer. If your downstream is fragile, prefer narrow windows even at the cost
47
+ of more 429s.
48
+ :::
49
+
50
+ :::callout tip title="Sane starting point"
51
+ For most APIs, capacity ≈ 4× refill rate, burst window ≈ 10 s. Adjust from
52
+ there based on observed P99 incident shape.
53
+ :::
@@ -0,0 +1,118 @@
1
+ # Rich Markdown Artifacts
2
+
3
+ ## Source First
4
+
5
+ Always write `.rmd` source first. It is the canonical artifact and must remain
6
+ readable in plain Markdown tools. The HTML build is a derived view that can
7
+ be regenerated any time.
8
+
9
+ ## Three Build Modes
10
+
11
+ The CLI supports three output modes via `--mode`. Pick based on where the
12
+ artifact will be viewed.
13
+
14
+ ### self-contained (default)
15
+
16
+ ```bash
17
+ npm run rmd -- build path/to/doc.rmd --mode self-contained --out path/to/doc.html
18
+ ```
19
+
20
+ Single HTML file with the renderer, theme CSS, runtime, and `.rmd` source all
21
+ inlined. Zero external dependencies. Best for:
22
+
23
+ - Claude desktop / chat sandbox (the artifact has to be self-contained)
24
+ - Email attachments
25
+ - Offline / archival
26
+ - S3 / static-host one-click sharing
27
+ - Any place where the consumer cannot install or fetch the renderer
28
+
29
+ Tradeoff: file size is larger (~50–150 KB) because the renderer is inlined.
30
+
31
+ ### cdn
32
+
33
+ ```bash
34
+ npm run rmd -- build path/to/doc.rmd --mode cdn --version 0.1.0 --out path/to/doc.html
35
+ ```
36
+
37
+ Small HTML shell containing only the `.rmd` source plus a script tag pointing
38
+ at a pinned CDN version of the renderer. Best for:
39
+
40
+ - Blog posts, Notion, web pages where the renderer can be fetched from CDN
41
+ - When the artifact itself must be small (token economy)
42
+
43
+ Requires `--version` to be a complete semver (e.g. `0.1.0`); `latest` is rejected
44
+ because sandboxed viewers must not depend on a moving CDN target.
45
+
46
+ ### split
47
+
48
+ ```bash
49
+ npm run rmd -- build path/to/doc.rmd --mode split --out path/to/dist/index.html
50
+ ```
51
+
52
+ Writes the HTML alongside `rmd.min.js` and `themes/<theme>.css` as separate
53
+ files in the same directory. Best for:
54
+
55
+ - Local development / hot reload
56
+ - Custom hosting where you want to serve the renderer from your own origin
57
+ - Inspecting the generated assets
58
+
59
+ Cannot be opened in sandboxed environments (Claude artifact, email) because
60
+ the relative asset paths will 404.
61
+
62
+ ## Validation
63
+
64
+ Always validate before building or returning to the user:
65
+
66
+ ```bash
67
+ npm run rmd -- validate path/to/doc.rmd
68
+ ```
69
+
70
+ Validation prints `ok` on success or a list of `path: message` lines on failure.
71
+ If validation fails, fix the source and re-run. Do not ship a file that fails
72
+ validation — the renderer may degrade silently to plain code blocks.
73
+
74
+ ## Recommended Default
75
+
76
+ For most Claude-driven requests:
77
+
78
+ ```bash
79
+ npm run rmd -- validate examples/my-doc.rmd
80
+ npm run rmd -- build examples/my-doc.rmd --mode self-contained --out examples/my-doc.html
81
+ ```
82
+
83
+ Return the path `examples/my-doc.html`.
84
+
85
+ ## Local Preview During the Session
86
+
87
+ When the user wants to interact with the artifact while you iterate:
88
+
89
+ ```bash
90
+ npm run rmd -- open path/to/doc.rmd --port 0 --host 127.0.0.1 --no-open true
91
+ ```
92
+
93
+ The CLI prints the bound URL. Use `--no-open true` so the agent does not try
94
+ to launch a desktop browser.
95
+
96
+ ## Frontmatter Tips
97
+
98
+ Every `.rmd` should start with a frontmatter block. Useful fields:
99
+
100
+ ```yaml
101
+ ---
102
+ title: Quarterly Roadmap # Required for sharing & metadata
103
+ theme: default # Theme id; only `default` ships today
104
+ share: private # private / team / public
105
+ description: Short summary... # Used by share cards / OG
106
+ lang: zh-CN # BCP 47 — affects type/font defaults
107
+ ---
108
+ ```
109
+
110
+ Unknown fields are kept but ignored. Custom fields should use the `x-` prefix
111
+ to mark them as non-core (e.g. `x-team: backend`).
112
+
113
+ ## Iteration Loop
114
+
115
+ When the user asks for revisions, re-run validate and build only — do not
116
+ rewrite unrelated parts of the source. The skill optimizes for clean diffs;
117
+ preserve the user's existing block structure unless they explicitly ask
118
+ otherwise.
@@ -0,0 +1,334 @@
1
+ # Rich Markdown Blocks (v0.2)
2
+
3
+ Complete reference for the 14 blocks supported by the current renderer
4
+ (`packages/blocks-core`). Use the smallest set that conveys meaning. Prefer
5
+ plain Markdown for narrative.
6
+
7
+ Identifiers are case-sensitive. Attribute order does not matter; positional
8
+ arguments come immediately after the block name.
9
+
10
+ ---
11
+
12
+ ## chart
13
+
14
+ Compact data visualization. Each line is `{label} {value} [{value2} ...]`,
15
+ space-separated. Multi-value rows become multi-series.
16
+
17
+ ```rmd
18
+ :::chart bar title="P99 latency (ms)" emphasis=primary
19
+ TokenBucket 23
20
+ LeakyBucket 19
21
+ SlidingWindow 41
22
+ :::
23
+ ```
24
+
25
+ Types (positional, required): `bar`, `line`, `pie`, `scatter`, `radar`, `area`,
26
+ `donut`, `heatmap`. `pie` requires single value per row.
27
+
28
+ | attribute | values | default | notes |
29
+ |---|---|---|---|
30
+ | `title` | string | empty | chart title |
31
+ | `x` / `y` / `y2` | string | null | axis labels (use `y2` for dual axis) |
32
+ | `legend` | `top` / `bottom` / `left` / `right` / `none` | `bottom` | legend position |
33
+ | `tooltip` | `true` / `false` | `true` | hover tooltip |
34
+ | `emphasis` | `primary` / `secondary` / `none` | `none` | theme-controlled accent |
35
+
36
+ Multi-series + dual axis:
37
+
38
+ ```rmd
39
+ :::chart area title="Revenue vs MAU" y="Revenue($M)" y2="MAU(K)" legend=top
40
+ Q1_2025 120 40
41
+ Q2_2025 150 45
42
+ Q3_2025 180 60
43
+ Q4_2025 240 85
44
+ :::
45
+ ```
46
+
47
+ ---
48
+
49
+ ## grid
50
+
51
+ Multi-column layout. Cells separated by `---` on their own line.
52
+
53
+ ```rmd
54
+ :::grid 3
55
+ ### Option A
56
+ Fast, simple.
57
+ ---
58
+ ### Option B
59
+ Flexible, heavier.
60
+ ---
61
+ ### Option C
62
+ Safe, slower.
63
+ :::
64
+ ```
65
+
66
+ Positional: column count (1–12) or comma-separated responsive breakpoints
67
+ (e.g. `1,2,4` for mobile/tablet/desktop).
68
+
69
+ | attribute | values | default | notes |
70
+ |---|---|---|---|
71
+ | `gap` | `sm` / `md` / `lg` | `md` | column spacing |
72
+ | `layout` | `default` / `masonry` | `default` | masonry uses CSS columns (no JS) |
73
+
74
+ `grid` cannot nest inside another `grid`. Maximum 12 cells.
75
+
76
+ ---
77
+
78
+ ## callout
79
+
80
+ Emphasized note, decision, or warning.
81
+
82
+ ```rmd
83
+ :::callout tip title="Recommendation"
84
+ Pick token bucket for burst-friendly traffic.
85
+ :::
86
+ ```
87
+
88
+ Positional kind: `info` / `tip` / `warning` / `danger` / `success`.
89
+ Optional `title`.
90
+
91
+ ---
92
+
93
+ ## slider
94
+
95
+ Reader-adjustable number. Pair with `export` to copy the tuned value back.
96
+
97
+ ```rmd
98
+ :::slider name=capacity min=10 max=1000 step=10 default=200 unit=req
99
+ :::
100
+ ```
101
+
102
+ Range slider (two values):
103
+
104
+ ```rmd
105
+ :::slider name=qps_range label="QPS window" min=10 max=1000 step=10 default=100,500 scale=log marks=10,100,500,1000
106
+ :::
107
+ ```
108
+
109
+ Required: `name` (matches `^[a-zA-Z_][a-zA-Z0-9_]*$`), `min`, `max` (`max > min`).
110
+
111
+ | attribute | type | default | notes |
112
+ |---|---|---|---|
113
+ | `step` | number > 0 | `1` | |
114
+ | `default` | number or `n,m` | `min` | range slider when comma value |
115
+ | `unit` | string | empty | suffix shown after value |
116
+ | `label` | string | name | display label |
117
+ | `scale` | `linear` / `log` / `pow` | `linear` | |
118
+ | `marks` | comma-separated numbers | empty | discrete snap points |
119
+
120
+ Slider names must be unique per document. Block body must be empty.
121
+
122
+ ---
123
+
124
+ ## export
125
+
126
+ Copy/export template. References slider values with `{{name}}` and supports
127
+ `{{name | int}}` formatting.
128
+
129
+ ```rmd
130
+ :::export label="Copy config" format=text
131
+ rate_limiter:
132
+ capacity: {{capacity | int}}
133
+ refill_rate: {{refill_rate | int}}
134
+ :::
135
+ ```
136
+
137
+ | attribute | values | default | notes |
138
+ |---|---|---|---|
139
+ | `label` | string | `复制` | button text |
140
+ | `format` | `text` / `markdown` / `json` | `text` | clipboard MIME |
141
+
142
+ Unknown variables render as `[未定义:name]` and warn in the console.
143
+
144
+ ---
145
+
146
+ ## flow
147
+
148
+ Directed flow with linear and branching paths.
149
+
150
+ ```rmd
151
+ :::flow direction=lr
152
+ Design -> Review -> Canary -> Full rollout
153
+ Canary -> Incident -> Rollback
154
+ :::
155
+ ```
156
+
157
+ Each line: `Node -> Node -> ...`. Same-name nodes merge.
158
+ `direction`: `lr` (default) or `tb`.
159
+
160
+ ---
161
+
162
+ ## diff
163
+
164
+ Unified-diff style. `+` add, `-` remove, leading space context.
165
+ `@注: ...` adds an inline note (placed at end of `+`/`-` line).
166
+
167
+ ```rmd
168
+ :::diff lang=python title="Limiter change"
169
+ - @rate_limit(window=60, max=100)
170
+ + @token_bucket(capacity=200, refill=50) @注: adds burst protection
171
+ :::
172
+ ```
173
+
174
+ ---
175
+
176
+ ## tabs
177
+
178
+ Multiple views in one area. `@label` on its own line starts a panel.
179
+
180
+ ```rmd
181
+ :::tabs default=Summary
182
+ @Summary
183
+ Plain-language explanation.
184
+ @Details
185
+ Implementation details.
186
+ :::
187
+ ```
188
+
189
+ Cannot nest inside another `tabs`.
190
+
191
+ ---
192
+
193
+ ## timeline
194
+
195
+ Vertical or horizontal sequence of dated events.
196
+
197
+ ```rmd
198
+ :::timeline
199
+ @ 2026-01-01 [title="Kickoff"] [status="success"]
200
+ Initial planning done, team formed.
201
+
202
+ @ 2026-03-15 [title="v0.1"] [status="success"]
203
+ Core parser shipped.
204
+
205
+ @ 2026-05-10 [title="v0.2"] [status="pending"]
206
+ Advanced blocks + masonry grid.
207
+ :::
208
+ ```
209
+
210
+ Each item begins with `@ {time} [title="..."] [status="..."]` on its own line.
211
+ Body is normal Markdown until the next `@`.
212
+
213
+ `status`: `success` / `warning` / `danger` / `pending` / `default`.
214
+ `direction`: `vertical` (default) or `horizontal`.
215
+
216
+ ---
217
+
218
+ ## kanban
219
+
220
+ Columns of cards. `@ {column title}` on its own line starts a column.
221
+
222
+ ```rmd
223
+ :::kanban
224
+ @ Todo
225
+ - [ ] Write the report
226
+ - [ ] Run perf tests
227
+
228
+ @ In progress
229
+ - [x] Update parser
230
+ - [x] Refactor theme
231
+
232
+ @ Done
233
+ * All conformance tests pass
234
+ * Carousel uses pure CSS
235
+ :::
236
+ ```
237
+
238
+ Use lists (Markdown task lists or bullets) for cards.
239
+
240
+ ---
241
+
242
+ ## details
243
+
244
+ Collapsible block. Wraps a native `<details>`.
245
+
246
+ ```rmd
247
+ :::details title="Architecture changelog" open=true
248
+ 1. Parser: custom rule dispatch on top of markdown-it.
249
+ 2. Validator: 20+ new rules for new tree shapes.
250
+ 3. Renderer: pure HTML output, no React/Vue dependency.
251
+ :::
252
+ ```
253
+
254
+ | attribute | values | default |
255
+ |---|---|---|
256
+ | `title` | string | empty |
257
+ | `open` | `true` / `false` | `false` |
258
+
259
+ ---
260
+
261
+ ## carousel
262
+
263
+ Touch / scroll-snap carousel. Cells separated by `---`.
264
+
265
+ ```rmd
266
+ :::carousel autoplay=true interval=4000
267
+ ### Slide 1
268
+ First content
269
+ ---
270
+ ### Slide 2
271
+ Second content
272
+ :::
273
+ ```
274
+
275
+ | attribute | values | default |
276
+ |---|---|---|
277
+ | `autoplay` | `true` / `false` | `false` |
278
+ | `interval` | number (ms) | `3000` |
279
+
280
+ ---
281
+
282
+ ## embed
283
+
284
+ Embed external media (video, map, app). Aspect ratio is theme-controlled.
285
+
286
+ ```rmd
287
+ :::embed type=video id="https://www.youtube.com/embed/XXXX" aspect-ratio="16/9"
288
+ :::
289
+ ```
290
+
291
+ | attribute | values | default |
292
+ |---|---|---|
293
+ | `type` | `video` / `map` / `iframe` | `unknown` |
294
+ | `id` | URL or external id | empty |
295
+ | `aspect-ratio` | `16/9` / `4/3` / etc. | null |
296
+
297
+ Block body is ignored.
298
+
299
+ ---
300
+
301
+ ## math
302
+
303
+ LaTeX math block. Renderer outputs as math container; the active theme
304
+ decides whether to typeset (KaTeX/MathJax) or fall back to monospace.
305
+
306
+ ```rmd
307
+ :::math
308
+ \mathcal{L} = \sum_{i=1}^{N} \left( y_i \log(\hat{y}_i) + (1-y_i) \log(1-\hat{y}_i) \right)
309
+ :::
310
+ ```
311
+
312
+ ---
313
+
314
+ ## Choosing Blocks
315
+
316
+ | Goal | Suggested blocks |
317
+ |---|---|
318
+ | Compare options | `grid` + `chart` + `callout` |
319
+ | Explain a PR | `diff` + `tabs` + `callout` |
320
+ | Tunable prototype | `slider` + `export` |
321
+ | Release / workflow | `flow` + `callout` + `timeline` |
322
+ | Status report | `chart` + `timeline` + `kanban` |
323
+ | Research brief | `chart` + `grid` + `callout` + `details` |
324
+ | Long doc with appendix | `details` + `tabs` |
325
+ | Visual gallery | `carousel` + `grid layout=masonry` |
326
+ | Math / formal | `math` + `callout` |
327
+
328
+ ## Don't
329
+
330
+ - Don't add CSS, color, pixel, or font attributes — they belong to the theme.
331
+ - Don't nest `grid` in `grid`, or `tabs` in `tabs`.
332
+ - Don't put body content inside `:::slider` or `:::embed`.
333
+ - Don't invent positional arguments beyond what's listed here.
334
+ - Don't use experimental block names that aren't in this file.
@@ -0,0 +1,92 @@
1
+ ---
2
+ name: rich-markdown
3
+ description: Generate Rich Markdown (.rmd) documents and self-contained Rich Markdown HTML artifacts for AI-authored reports, plans, comparisons, PR explanations, prototypes, research briefs, timelines, kanbans, and tunable interactive demos. Use when the user asks for rmd, Rich Markdown, rich interactive Markdown, token-efficient rich docs, shareable AI documents, charts, sliders, export/copy blocks, flow diagrams, timelines, kanban boards, collapsible details, carousels, embeds, math blocks, or wants a Codex response rendered with the local Rich Markdown renderer.
4
+ ---
5
+
6
+ # Rich Markdown
7
+
8
+ Use this skill when the user wants a rich, readable, interactive document
9
+ instead of plain Markdown or hand-written HTML. The local renderer
10
+ (`packages/cli`) turns `.rmd` source into a self-contained HTML artifact.
11
+
12
+ ## Output Choice
13
+
14
+ - User wants a file or artifact: write a `.rmd` file first, then build HTML.
15
+ - User wants something viewable inside Codex or shareable as one file:
16
+ build a self-contained HTML artifact from the `.rmd`.
17
+ - User wants source only: output `.rmd` source, do not build HTML.
18
+ - User wants a multi-file site (assets they can inspect or host): use `--mode split`.
19
+
20
+ ## Workflow
21
+
22
+ 1. Choose the smallest useful block set from `references/blocks.md`.
23
+ Plain Markdown for narrative, `:::` blocks only when they add density,
24
+ structure, or interaction.
25
+ 2. Write the `.rmd` to a sensible path under `examples/` (or wherever the
26
+ user asks). Always include a YAML frontmatter with at least `title`.
27
+ 3. Validate the source. Fail fast if the parser reports issues:
28
+
29
+ ```bash
30
+ npm run rmd -- validate path/to/doc.rmd
31
+ ```
32
+
33
+ 4. Build for the chosen consumption mode:
34
+
35
+ ```bash
36
+ # Single self-contained HTML — best default for Codex Desktop / sharing
37
+ npm run rmd -- build path/to/doc.rmd --mode self-contained --out path/to/doc.html
38
+
39
+ # CDN-loaded variant — small artifact, requires network at view time
40
+ npm run rmd -- build path/to/doc.rmd --mode cdn --version 0.1.0 --out path/to/doc.html
41
+
42
+ # Split mode — index.html + rmd.min.js + themes/<name>.css for inspection / hosting
43
+ npm run rmd -- build path/to/doc.rmd --mode split --out path/to/dist/index.html
44
+ ```
45
+
46
+ 5. For local interactive preview (will start a local HTTP server):
47
+
48
+ ```bash
49
+ npm run rmd -- open path/to/doc.rmd --port 0 --no-open true
50
+ ```
51
+
52
+ 6. Report the generated HTML path back to the user.
53
+
54
+ ## Rules
55
+
56
+ - Never put colors, pixels, fonts, or layout styling into `.rmd`. Use
57
+ `emphasis=primary|secondary|none` and let the theme decide visuals.
58
+ - Keep source diff clean: one semantic edit should touch only nearby lines.
59
+ Do not reorder unrelated attributes or rewrite whole files for tiny changes.
60
+ - Unknown or fragile content (rare formats, edge cases) must fall back to
61
+ plain Markdown rather than invented block names.
62
+ - Use `:::slider` + `:::export` whenever the reader should tune values and
63
+ copy the result back to Codex or to code.
64
+ - Validation failures are not warnings: fix the source, do not ship the file.
65
+
66
+ ## Block Selection Cheatsheet
67
+
68
+ Map the user's intent to the smallest block set that delivers value:
69
+
70
+ | Intent | Blocks |
71
+ |---|---|
72
+ | Compare options / approaches | `grid` + `chart` + `callout` |
73
+ | PR / code review explainer | `diff` + `tabs` + `callout` |
74
+ | Tunable prototype | `slider` + `export` |
75
+ | Release / workflow | `flow` + `callout` + `timeline` |
76
+ | Project status report | `chart` + `timeline` + `kanban` |
77
+ | Research brief | `chart` + `grid` + `details` |
78
+ | Showcase / gallery | `carousel` + `grid layout=masonry` |
79
+ | Long doc with appendix | `details` + `tabs` |
80
+ | Math / formal explanation | `math` + `callout` |
81
+
82
+ Full block reference: `references/blocks.md`.
83
+ Build mode reference: `references/artifacts.md`.
84
+
85
+ ## Default Recipe
86
+
87
+ For Codex-visible rich output:
88
+
89
+ 1. Write `examples/<short-name>.rmd` with appropriate blocks.
90
+ 2. `npm run rmd -- validate examples/<short-name>.rmd`
91
+ 3. `npm run rmd -- build examples/<short-name>.rmd --mode self-contained --out examples/<short-name>.html`
92
+ 4. Return `examples/<short-name>.html` as the deliverable.
@@ -0,0 +1,8 @@
1
+ interface:
2
+ display_name: "Rich Markdown"
3
+ short_description: "Generate interactive .rmd documents"
4
+ brand_color: "#2563EB"
5
+ default_prompt: "Use $rich-markdown to create a self-contained interactive .rmd HTML report."
6
+
7
+ policy:
8
+ allow_implicit_invocation: true
@@ -0,0 +1,107 @@
1
+ # Rich Markdown Artifacts
2
+
3
+ ## Source First
4
+
5
+ Always write `.rmd` source first. It is the canonical artifact and must remain
6
+ readable in plain Markdown tools. The HTML build is a derived view.
7
+
8
+ ## Three Build Modes
9
+
10
+ The CLI supports three output modes via `--mode`. Pick based on where the
11
+ artifact will be viewed.
12
+
13
+ ### self-contained (default)
14
+
15
+ ```bash
16
+ npm run rmd -- build path/to/doc.rmd --mode self-contained --out path/to/doc.html
17
+ ```
18
+
19
+ Produces a single HTML file with the renderer, theme CSS, runtime, and `.rmd`
20
+ source all inlined. Zero external dependencies. Best for:
21
+
22
+ - Codex Desktop (loads inside the app sandbox)
23
+ - Email attachments
24
+ - Offline / archival
25
+ - S3 / static-host one-click sharing
26
+ - Any place where the consumer cannot install or fetch the renderer
27
+
28
+ Tradeoff: file size is larger (~50–150 KB) because the renderer ships in-line.
29
+
30
+ ### cdn
31
+
32
+ ```bash
33
+ npm run rmd -- build path/to/doc.rmd --mode cdn --version 0.1.0 --out path/to/doc.html
34
+ ```
35
+
36
+ Produces a small HTML shell containing only the `.rmd` source and a script tag
37
+ pointing at a pinned CDN version. Best for:
38
+
39
+ - Blog posts / Notion / web pages where the renderer can be fetched from CDN
40
+ - Cases where token economy of the artifact itself matters most
41
+
42
+ Requires `--version` to be a complete semver (e.g. `0.1.0`); `latest` is rejected
43
+ because sandboxed viewers must not depend on a moving CDN target.
44
+
45
+ ### split
46
+
47
+ ```bash
48
+ npm run rmd -- build path/to/doc.rmd --mode split --out path/to/dist/index.html
49
+ ```
50
+
51
+ Writes the HTML alongside `rmd.min.js` and `themes/<theme>.css` as separate
52
+ files. Best for:
53
+
54
+ - Local development / hot reload
55
+ - Custom hosting where you want to serve the renderer from your own origin
56
+ - Inspecting the generated assets
57
+
58
+ Cannot be opened in sandboxed environments (Codex Desktop artifact, email)
59
+ because relative asset paths will 404.
60
+
61
+ ## Validation
62
+
63
+ Always validate before building or returning to the user:
64
+
65
+ ```bash
66
+ npm run rmd -- validate path/to/doc.rmd
67
+ ```
68
+
69
+ If validation fails, fix the source. Do not ship a file that fails validation.
70
+
71
+ ## Recommended Default for Codex
72
+
73
+ For most Codex-driven requests:
74
+
75
+ ```bash
76
+ npm run rmd -- validate examples/my-doc.rmd
77
+ npm run rmd -- build examples/my-doc.rmd --mode self-contained --out examples/my-doc.html
78
+ ```
79
+
80
+ Return the path `examples/my-doc.html`.
81
+
82
+ ## Local Preview
83
+
84
+ When the user wants to interact with the artifact during the session:
85
+
86
+ ```bash
87
+ npm run rmd -- open path/to/doc.rmd --port 0 --host 127.0.0.1 --no-open true
88
+ ```
89
+
90
+ The CLI prints the bound URL. Use `--no-open true` so the agent does not try
91
+ to launch a desktop browser.
92
+
93
+ ## Frontmatter Tips
94
+
95
+ Every `.rmd` should start with a frontmatter block. Useful fields:
96
+
97
+ ```yaml
98
+ ---
99
+ title: Quarterly Roadmap # Required for sharing & metadata
100
+ theme: default # Theme id; only `default` ships today
101
+ share: private # private / team / public
102
+ description: Short summary... # Used by share cards / OG
103
+ lang: zh-CN # BCP 47 — affects type/font defaults
104
+ ---
105
+ ```
106
+
107
+ Unknown fields are kept but ignored; custom fields should use `x-` prefix.
@@ -0,0 +1,321 @@
1
+ # Rich Markdown Blocks (v0.2)
2
+
3
+ These are the blocks supported by the current renderer (`packages/blocks-core`).
4
+ Use the smallest set that conveys meaning. Prefer plain Markdown for narrative.
5
+
6
+ Identifiers (block names, slider variable names) are case-sensitive.
7
+ Attribute order does not matter; positional arguments come immediately after the
8
+ block name.
9
+
10
+ ## chart
11
+
12
+ Compact data visualization. Each line is `{label} {value} [{value2} ...]`.
13
+ Values are space-separated. Multi-value rows become multi-series.
14
+
15
+ ```rmd
16
+ :::chart bar title="P99 latency (ms)" emphasis=primary
17
+ TokenBucket 23
18
+ LeakyBucket 19
19
+ SlidingWindow 41
20
+ :::
21
+ ```
22
+
23
+ Types (positional, required): `bar`, `line`, `pie`, `scatter`, `radar`, `area`,
24
+ `donut`, `heatmap`. `pie` requires single value per row.
25
+
26
+ Attributes:
27
+
28
+ | name | values | default | notes |
29
+ |---|---|---|---|
30
+ | `title` | string | empty | chart title |
31
+ | `x` / `y` / `y2` | string | null | axis labels (use `y2` for dual axis) |
32
+ | `legend` | `top` / `bottom` / `left` / `right` / `none` | `bottom` | legend position |
33
+ | `tooltip` | `true` / `false` | `true` | hover tooltip |
34
+ | `emphasis` | `primary` / `secondary` / `none` | `none` | theme-controlled accent |
35
+
36
+ Multi-series example:
37
+
38
+ ```rmd
39
+ :::chart area title="Revenue vs MAU" y="Revenue($M)" y2="MAU(K)" legend=top
40
+ Q1_2025 120 40
41
+ Q2_2025 150 45
42
+ Q3_2025 180 60
43
+ Q4_2025 240 85
44
+ :::
45
+ ```
46
+
47
+ ## grid
48
+
49
+ Multi-column layout. Cells separated by `---` on their own line.
50
+
51
+ ```rmd
52
+ :::grid 3
53
+ ### Option A
54
+ Fast, simple.
55
+ ---
56
+ ### Option B
57
+ Flexible, heavier.
58
+ ---
59
+ ### Option C
60
+ Safe, slower.
61
+ :::
62
+ ```
63
+
64
+ Positional: column count (1–12) or comma-separated responsive breakpoints
65
+ (e.g. `1,2,4` for mobile/tablet/desktop).
66
+
67
+ Attributes:
68
+
69
+ | name | values | default | notes |
70
+ |---|---|---|---|
71
+ | `gap` | `sm` / `md` / `lg` | `md` | column spacing |
72
+ | `layout` | `default` / `masonry` | `default` | masonry uses CSS columns (no JS) |
73
+
74
+ `grid` cannot nest inside another `grid`. Maximum 12 cells.
75
+
76
+ ## callout
77
+
78
+ Emphasized note, decision, or warning.
79
+
80
+ ```rmd
81
+ :::callout tip title="Recommendation"
82
+ Pick token bucket for burst-friendly traffic.
83
+ :::
84
+ ```
85
+
86
+ Positional kind: `info` / `tip` / `warning` / `danger` / `success`.
87
+ Optional `title` attribute.
88
+
89
+ ## slider
90
+
91
+ Reader-adjustable number with optional range/log/marks. Pair with `export`.
92
+
93
+ ```rmd
94
+ :::slider name=capacity min=10 max=1000 step=10 default=200 unit=req
95
+ :::
96
+ ```
97
+
98
+ Range slider (two values):
99
+
100
+ ```rmd
101
+ :::slider name=qps_range label="QPS window" min=10 max=1000 step=10 default=100,500 scale=log marks=10,100,500,1000
102
+ :::
103
+ ```
104
+
105
+ Required: `name` (matches `^[a-zA-Z_][a-zA-Z0-9_]*$`), `min`, `max` (`max > min`).
106
+
107
+ Attributes:
108
+
109
+ | name | type | default | notes |
110
+ |---|---|---|---|
111
+ | `step` | number > 0 | `1` | |
112
+ | `default` | number or `n,m` | `min` | range slider when comma value |
113
+ | `unit` | string | empty | suffix shown after value |
114
+ | `label` | string | name | display label |
115
+ | `scale` | `linear` / `log` / `pow` | `linear` | |
116
+ | `marks` | comma-separated numbers | empty | discrete snap points |
117
+
118
+ Slider names must be unique per document. Block body must be empty.
119
+
120
+ ## export
121
+
122
+ Copy/export template. References slider values with `{{name}}` and supports
123
+ `{{name | int}}` formatting.
124
+
125
+ ```rmd
126
+ :::export label="Copy config" format=text
127
+ rate_limiter:
128
+ capacity: {{capacity | int}}
129
+ refill_rate: {{refill_rate | int}}
130
+ :::
131
+ ```
132
+
133
+ Attributes:
134
+
135
+ | name | values | default | notes |
136
+ |---|---|---|---|
137
+ | `label` | string | `复制` | button text |
138
+ | `format` | `text` / `markdown` / `json` | `text` | clipboard MIME |
139
+
140
+ Unknown variables render as `[未定义:name]` and warn in the console.
141
+
142
+ ## flow
143
+
144
+ Directed flow with linear and branching paths.
145
+
146
+ ```rmd
147
+ :::flow direction=lr
148
+ Design -> Review -> Canary -> Full rollout
149
+ Canary -> Incident -> Rollback
150
+ :::
151
+ ```
152
+
153
+ Each line: `Node -> Node -> ...`. Same-name nodes merge.
154
+ `direction`: `lr` (default) or `tb`.
155
+
156
+ ## diff
157
+
158
+ Unified-diff style. `+` add, `-` remove, leading space context.
159
+ `@注: ...` adds an inline note (placed at end of `+`/`-` line).
160
+
161
+ ```rmd
162
+ :::diff lang=python title="Limiter change"
163
+ - @rate_limit(window=60, max=100)
164
+ + @token_bucket(capacity=200, refill=50) @注: adds burst protection
165
+ :::
166
+ ```
167
+
168
+ ## tabs
169
+
170
+ Multiple views in one area. `@label` on its own line starts a panel.
171
+
172
+ ```rmd
173
+ :::tabs default=Summary
174
+ @Summary
175
+ Plain-language explanation.
176
+ @Details
177
+ Implementation details.
178
+ :::
179
+ ```
180
+
181
+ Cannot nest inside another `tabs`.
182
+
183
+ ## timeline
184
+
185
+ Vertical or horizontal sequence of dated events.
186
+
187
+ ```rmd
188
+ :::timeline
189
+ @ 2026-01-01 [title="Kickoff"] [status="success"]
190
+ Initial planning done, team formed.
191
+
192
+ @ 2026-03-15 [title="v0.1"] [status="success"]
193
+ Core parser shipped.
194
+
195
+ @ 2026-05-10 [title="v0.2"] [status="pending"]
196
+ Advanced blocks + masonry grid.
197
+ :::
198
+ ```
199
+
200
+ Each item begins with `@ {time} [title="..."] [status="..."]` on its own line.
201
+ Body is normal Markdown until the next `@`.
202
+
203
+ `status`: `success` / `warning` / `danger` / `pending` / `default`.
204
+ `direction`: `vertical` (default) or `horizontal`.
205
+
206
+ ## kanban
207
+
208
+ Columns of cards. `@ {column title}` on its own line starts a column.
209
+
210
+ ```rmd
211
+ :::kanban
212
+ @ Todo
213
+ - [ ] Write the report
214
+ - [ ] Run perf tests
215
+
216
+ @ In progress
217
+ - [x] Update parser
218
+ - [x] Refactor theme
219
+
220
+ @ Done
221
+ * All conformance tests pass
222
+ * Carousel uses pure CSS
223
+ :::
224
+ ```
225
+
226
+ Use lists (Markdown task lists or bullets) for cards.
227
+
228
+ ## details
229
+
230
+ Collapsible block. Wraps a native `<details>`.
231
+
232
+ ```rmd
233
+ :::details title="Architecture changelog" open=true
234
+ 1. Parser: custom rule dispatch on top of markdown-it.
235
+ 2. Validator: 20+ new rules for new tree shapes.
236
+ 3. Renderer: pure HTML output, no React/Vue dependency.
237
+ :::
238
+ ```
239
+
240
+ Attributes:
241
+
242
+ | name | values | default |
243
+ |---|---|---|
244
+ | `title` | string | empty |
245
+ | `open` | `true` / `false` | `false` |
246
+
247
+ ## carousel
248
+
249
+ Touch / scroll-snap carousel. Cells separated by `---`.
250
+
251
+ ```rmd
252
+ :::carousel autoplay=true interval=4000
253
+ ### Slide 1
254
+ First content
255
+ ---
256
+ ### Slide 2
257
+ Second content
258
+ ---
259
+ ### Slide 3
260
+ Third content
261
+ :::
262
+ ```
263
+
264
+ Attributes:
265
+
266
+ | name | values | default |
267
+ |---|---|---|
268
+ | `autoplay` | `true` / `false` | `false` |
269
+ | `interval` | number (ms) | `3000` |
270
+
271
+ ## embed
272
+
273
+ Embed external media (video, map, app). Theme-controlled aspect ratio.
274
+
275
+ ```rmd
276
+ :::embed type=video id="https://www.youtube.com/embed/XXXX" aspect-ratio="16/9"
277
+ :::
278
+ ```
279
+
280
+ Attributes:
281
+
282
+ | name | values | default |
283
+ |---|---|---|
284
+ | `type` | `video` / `map` / `iframe` | `unknown` |
285
+ | `id` | URL or external id | empty |
286
+ | `aspect-ratio` | `16/9` / `4/3` / etc. | null |
287
+
288
+ Block body is ignored.
289
+
290
+ ## math
291
+
292
+ LaTeX math block. Renderer outputs as math container; the active theme decides
293
+ whether to typeset (KaTeX/MathJax) or fall back to monospace.
294
+
295
+ ```rmd
296
+ :::math
297
+ \mathcal{L} = \sum_{i=1}^{N} \left( y_i \log(\hat{y}_i) + (1-y_i) \log(1-\hat{y}_i) \right)
298
+ :::
299
+ ```
300
+
301
+ ## Choosing Blocks
302
+
303
+ | Goal | Suggested blocks |
304
+ |---|---|
305
+ | Compare options | `grid` + `chart` + `callout` |
306
+ | Explain a PR | `diff` + `tabs` + `callout` |
307
+ | Tunable prototype | `slider` + `export` |
308
+ | Release / workflow | `flow` + `callout` + `timeline` |
309
+ | Status report | `chart` + `timeline` + `kanban` |
310
+ | Research brief | `chart` + `grid` + `callout` + `details` |
311
+ | Long doc with collapsible appendix | `details` + `tabs` |
312
+ | Visual gallery / showcase | `carousel` + `grid masonry` |
313
+ | Math / formal explanation | `math` + `callout` |
314
+
315
+ ## Don't
316
+
317
+ - Don't add CSS, color, pixel, or font attributes — they belong to the theme.
318
+ - Don't nest `grid` in `grid`, or `tabs` in `tabs`.
319
+ - Don't put body content inside `:::slider` or `:::embed`.
320
+ - Don't invent new positional arguments beyond what's listed here.
321
+ - Don't use experimental block names that aren't in this file.