Eidou Semantic Compose (Agent Entrypoint)
Agent entrypoint: this file (SKILL.md).
In-repo (dev): /.opencode/skill/eidou-usage-skill/SKILL.md
Installed (Linux/macOS): ~/.config/opencode/skill/eidou-usage/SKILL.md
Installed (Windows): %APPDATA%\opencode\skill\eidou-usage\SKILL.md
Use this skill at L1: provide semantic IntentSpec JSON and let compose.py generate valid EUIP.
Setup & Usage
Detect your script root first, then call compose/validate from there.
macOS / Linux (Bash/Zsh)
# Set path
export SKILL_DIR="packages/eidou-usage-skill/scripts" # In-repo
# export SKILL_DIR="$HOME/.config/opencode/skill/eidou-usage/scripts" # Installed
# Run
python3 "$SKILL_DIR/compose.py" --input intent.json
Windows (PowerShell)
# Set path
$env:SKILL_DIR = "packages\eidou-usage-skill\scripts" # In-repo
# $env:SKILL_DIR = "$env:APPDATA\opencode\skill\eidou-usage\scripts" # Installed
# Run
python "$env:SKILL_DIR\compose.py" --input intent.json
Core Rules
- Primary tool:
compose.py
- Validation gate:
validate.py
- Output must satisfy
projection -> field -> content and pass validate.py.
Reserved Close Action
- Use
_eidou_sys_close for buttons that should close the projection.
- Compose normalizes explicit close intents in action rows:
action: "close" -> _eidou_sys_close
action: "eidou:close" -> _eidou_sys_close
label: "Close" with missing/empty action -> _eidou_sys_close
- Non-close custom actions are preserved as provided.
CLI Contract
# stdin -> stdout
echo '{"pattern":"message","title":"Hi","message":"Yo"}' | \
python3 $SKILL_DIR/compose.py
# file input / file output
python3 $SKILL_DIR/compose.py --input intent.json --output ui.json
# validate-only dry run
python3 $SKILL_DIR/compose.py --input intent.json --validate-only
# stdin -> stdout
'{"pattern":"message","title":"Hi","message":"Yo"}' |
python "$env:SKILL_DIR\compose.py"
# file input / file output
python "$env:SKILL_DIR\compose.py" --input intent.json --output ui.json
# validate-only dry run
python "$env:SKILL_DIR\compose.py" --input intent.json --validate-only
Exit Codes
0: success
1: IntentSpec validation error
2: pattern not found
3: build error
4: EUIP validation error
Error Format (stderr JSON)
{"error":"PATTERN_NOT_FOUND","message":"Pattern 'x' not found","stage":"pattern_selection"}
stage values: input_parse, spec_validation, pattern_selection, build, euip_validation.
IntentSpec Basics
Common fields:
pattern (required)
title (required)
description (optional)
size (optional; width-class presets: compact, standard, wide; ratio presets: dashboard, card, widescreen, portrait, square; protocol presets: auto, sm, md, lg, xl, full; object: {"width":1024,"height":"auto"}; ratio object: {"ratio":"16:9","width":960,"maxWidth":1200,"base":"lg"})
theme (optional projection theme override)
Pattern-specific fields are below.
Pattern Catalog
| Pattern |
Purpose |
Required Fields |
form |
Collect user input |
fields |
data_table |
Show tabular records |
columns, rows |
confirmation |
Confirm dangerous action |
warning |
status_dashboard |
Show metrics overview |
metrics |
detail_view |
Show one entity details |
fields |
list |
Show vertical items |
items |
settings |
Grouped configuration controls |
groups |
message |
Simple info/status panel |
message |
profile |
Entity profile card |
name |
article |
Markdown article layout |
content |
chat |
Message stream with avatars |
messages |
terminal_output |
Terminal log with run status |
lines |
progress_tracker |
Multi-step pipeline tracker |
steps |
media_gallery |
Grid image gallery |
items |
chart |
Data visualization (line/bar/pie/area) |
variant, data |
Profile avatar behavior: profile always emits an avatar atom. avatar may be an object ({ "src": "...", ... }) or a string URL shorthand. Compose derives a 1-2 character fallback from name whenever avatar.fallback is missing and sets alt to <name> avatar when not provided.
Default sizing note: media_gallery defaults to a ratio size (16:9, width 1024, maxWidth 1200) to keep image-heavy content stable without oversized auto windows.
Compose layouts default to fit-content style hybrid sizing ({"width":...,"height":"auto"}) to avoid wasted vertical whitespace.
Compose Pattern (Build Your Own)
Use "pattern": "compose" to assemble custom UIs from building blocks.
Each block in body[] is a { "use": "<block_name>", ...params } directive.
{
"pattern": "compose",
"title": "Server Dashboard",
"layout": "sidebar",
"size": "dashboard",
"body": [
{ "slot": "main", "use": "chart_panel", "variant": "line", "data": [{"month": "Jan", "revenue": 4200}] },
{ "slot": "side", "use": "metric_card", "label": "CPU", "value": "73%" },
{ "slot": "side", "use": "metric_card", "label": "Mem", "value": "2.1GB" }
]
}
Layout Presets
Pick a layout to control how blocks are arranged spatially.
Assign blocks to named slots. Multiple blocks in the same slot stack vertically.
If no slot is specified, blocks go to the first slot of the layout.
| Layout |
Slots |
Default Size |
Description |
stack |
main |
auto |
Vertical stack (default). All blocks top-to-bottom. |
sidebar |
main, side |
{"width":1024,"height":"auto"} |
2/3 main + 1/3 side rail. |
split |
left, right |
{"width":1024,"height":"auto"} |
50/50 equal halves. |
grid-2x2 |
slot-a, slot-b, slot-c, slot-d |
{"width":640,"height":"auto"} |
2x2 equal grid. |
bento |
slot-a, slot-b, slot-c |
{"width":1024,"height":"auto"} |
1 large (slot-a spans 2x2) + 2 small. |
hero |
hero, content |
{"width":480,"height":"auto"} |
Large hero area + content below. |
triple |
left, center, right |
{"width":1024,"height":"auto"} |
Three equal columns. |
dashboard |
metrics, main, footer |
{"width":1024,"height":"auto"} |
KPI row + main + optional footer. |
Use explicit size (for example "dashboard") when you want a semantic ratio preset instead of fit-content defaults.
Layout ASCII Diagrams
sidebar:
+------------------+--------+
| main | side |
+------------------+--------+
Note: If main contains a single chart_panel, it is vertically centered in the available height.
Multi-block content (profiles, docs) stays top-aligned.
bento:
+------------------+--------+
| | slot-b |
| slot-a +--------+
| | slot-c |
+------------------+--------+
dashboard:
+---------------------------+
| metrics metrics metrics |
+---------------------------+
| main |
+---------------------------+
| footer |
+---------------------------+
Size Presets
Control window dimensions with semantic size names.
Explicit size always overrides the layout's fit-content default.
Most patterns default to a width-class preset (fit-content height).
Use ratio presets only for media/visual compositions where aspect stability matters.
sm/md/lg/xl are fixed pixel protocol presets (both axes fixed) and often less ideal for content-heavy windows.
Width-class presets (fixed width, height fits content):
| Name |
Output |
Ideal For |
compact |
{"width":360,"height":"auto"} |
Toasts, confirms, small dialogs |
standard |
{"width":480,"height":"auto"} |
Forms, cards, profiles (THE default) |
wide |
{"width":720,"height":"auto"} |
Tables, multi-column, articles |
For 1024-wide content, use explicit {"width":1024,"height":"auto"} or compose layout defaults (sidebar/split/dashboard already provide this).
Ratio presets (fixed aspect ratio canvas):
| Name |
Output |
Ideal For |
dashboard |
16:9, 1024px |
Multi-chart, metrics overview |
card |
4:3, 480px |
Single card visualization |
widescreen |
21:9, 1024px |
Comparison, wide chart layouts |
portrait |
3:4, 480px |
Tall visual story flow |
square |
1:1, 640px |
Grid-heavy visual content |
You can also use raw sizes: auto, sm, md, lg, xl, full, hybrid objects ({"width":1024,"height":"auto"}), or ratio objects.
Molecules (Small Functional Units)
| Block |
Purpose |
Required |
Optional |
labeled_field |
Label + input control |
label, name |
type, placeholder, default, error, options |
action_row |
Row of buttons |
actions[] |
(each action: label, action, variant) |
key_value |
Key-value pair |
key, value |
copyable |
metric_card |
Single metric display |
label, value |
trend, status, progress |
status_badge |
Status indicator |
label |
status, icon |
avatar_header |
Avatar + name + subtitle |
name |
subtitle, avatar, icon |
empty_state |
No-data placeholder |
title |
description, icon, action |
alert_box |
Inline notification |
message |
variant (info/warning/error/success), title |
search_box |
Search input with icon |
name |
placeholder, action |
divider |
Visual separator |
(none) |
(none) |
text_block |
Text content |
content |
variant (h1/h2/h3/body/label/mono) |
markdown_block |
Rendered markdown |
content |
(none) |
chart_with_header |
Chart with title + badge |
title, variant, data[] |
badge, + chart props |
chart_legend_card |
Series legend indicator |
label, value |
color, trend |
chart_stat_row |
Stat row for chart context |
label, value |
(none) |
Organisms (Functional Sections)
| Block |
Purpose |
Required |
Optional |
form_section |
Group of form fields |
fields[] |
actions[], description |
data_table |
Tabular data |
columns[], rows[] |
row_actions[], empty_message |
metrics_row |
Grid of metric cards |
metrics[] |
(none) |
detail_section |
Key-value detail group |
fields[] |
avatar |
settings_group |
Toggle/select settings |
title, settings[] |
actions[] |
chat_log |
Message stream |
messages[] |
actions[] |
terminal_panel |
Terminal output |
lines[] |
status, progress, actions[] |
step_tracker |
Multi-step progress |
steps[] |
actions[] |
media_grid |
Image grid |
items[] |
actions[] |
chart_panel |
Data visualization |
variant, data[] |
xKey, yKeys, actions[] |
chart_dashboard |
Multi-chart grid + metrics |
charts[] |
metrics[], columns, actions[] |
chart_detail |
Chart + stats breakdown |
title, variant, data[] |
stats[], actions[], + chart props |
list_section |
Vertical item list |
items[] |
actions[], empty_message |
Recipes (Suggested Combos)
- Dashboard:
layout: "dashboard" with metrics_row in metrics + chart_panel in main
- Sidebar Analysis:
layout: "sidebar" with chart_panel in main + metric_cards in side
- Comparison:
layout: "split" with chart_panel in left + chart_panel in right
- Bento Overview:
layout: "bento" with main chart in slot-a + metrics in slot-b/slot-c
- KPI Grid:
layout: "grid-2x2" with metric_card in each slot
- Hero Feature:
layout: "hero" with chart_panel in hero + text_block in content
- Simple Stack: no layout (default) with
text_block + action_row
- Form + Preview:
form_section + markdown_block (stack layout)
Compose One-Liners
{"pattern":"compose","title":"Quick","body":[{"use":"text_block","content":"Hello"},{"use":"action_row","actions":[{"label":"OK","action":"ok"}]}]}
{"pattern":"compose","title":"Dashboard","layout":"sidebar","size":"dashboard","body":[{"slot":"main","use":"chart_panel","variant":"pie","data":[{"cat":"A","val":60},{"cat":"B","val":40}]},{"slot":"side","use":"metric_card","label":"Total","value":"100"}]}
{"pattern":"compose","title":"KPIs","layout":"grid-2x2","size":"square","body":[{"slot":"slot-a","use":"metric_card","label":"CPU","value":"73%"},{"slot":"slot-b","use":"metric_card","label":"RAM","value":"2.1GB"},{"slot":"slot-c","use":"metric_card","label":"Disk","value":"45%"},{"slot":"slot-d","use":"metric_card","label":"Net","value":"120Mbps"}]}
Semantic Field Type Mapping
When building form/settings controls:
text, email, password, number, textarea -> input
select -> select
toggle -> switch
checkbox -> checkbox
radio -> radiogroup
readonly -> text
hidden -> omitted
- unknown type -> fallback to
text input
Minimal Examples
{
"pattern": "form",
"title": "Create Contact",
"fields": [
{"name": "name", "label": "Name", "type": "text"},
{"name": "email", "label": "Email", "type": "email"}
],
"actions": [{"label": "Save", "action": "submit", "variant": "primary"}]
}
One-line skeletons for quick authoring:
message: {"pattern":"message","title":"Welcome","message":"..."}
data_table: {"pattern":"data_table","title":"T","columns":[{"key":"x"}],"rows":[{"x":"1"}]}
confirmation: {"pattern":"confirmation","title":"Delete","warning":"..."}
status_dashboard: {"pattern":"status_dashboard","title":"Health","metrics":[{"label":"CPU","value":"73%"}]}
detail_view: {"pattern":"detail_view","title":"Detail","fields":[{"label":"Name","value":"Alice"}]}
list: {"pattern":"list","title":"Logs","items":[{"primary":"Started"}]}
settings: {"pattern":"settings","title":"Prefs","groups":[{"title":"General","settings":[{"name":"x","label":"X","type":"toggle"}]}]}
profile: {"pattern":"profile","title":"Agent","name":"Souta"}
article: {"pattern":"article","title":"Notes","content":"## Hello"}
chat: {"pattern":"chat","title":"Session","messages":[{"sender":"S","content":"hi"}]}
terminal_output: {"pattern":"terminal_output","title":"Build","lines":["$ bun run build"]}
progress_tracker: {"pattern":"progress_tracker","title":"Pipeline","steps":[{"label":"Build","status":"complete"}]}
media_gallery: {"pattern":"media_gallery","title":"Shots","items":[{"src":"https://example.com/1.png"}]}
chart: {"pattern":"chart","title":"Revenue","variant":"line","data":[{"month":"Jan","revenue":4200}]}
Recommended Workflow
# compose then validate
echo '<intent_spec_json>' | \
python3 $SKILL_DIR/compose.py | \
python3 $SKILL_DIR/validate.py -
# compose then validate
'<intent_spec_json>' |
python "$env:SKILL_DIR\compose.py" |
python "$env:SKILL_DIR\validate.py" -
Use this flow for every generated widget before calling show_widget.
If this skill doc conflicts with schema, schema wins:
specification/v0_1/json/root.json
specification/v0_1/json/components.json
specification/v0_1/json/events.json
specification/v0_1/json/theme.json
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: eidou-usage3description: Agent entrypoint for semantic UI composition via compose.py. Use when this capability is needed.4---56# Eidou Semantic Compose (Agent Entrypoint)78> Agent entrypoint: this file (`SKILL.md`).9>10> **In-repo** (dev): `/.opencode/skill/eidou-usage-skill/SKILL.md`11> **Installed** (Linux/macOS): `~/.config/opencode/skill/eidou-usage/SKILL.md`12> **Installed** (Windows): `%APPDATA%\opencode\skill\eidou-usage\SKILL.md`1314Use this skill at L1: provide semantic IntentSpec JSON and let `compose.py` generate valid EUIP.1516## Setup & Usage1718Detect your script root first, then call compose/validate from there.1920<!-- SKILL_VARIANT:unix:start -->21### macOS / Linux (Bash/Zsh)2223```bash24# Set path25export SKILL_DIR="packages/eidou-usage-skill/scripts" # In-repo26# export SKILL_DIR="$HOME/.config/opencode/skill/eidou-usage/scripts" # Installed2728# Run29python3 "$SKILL_DIR/compose.py" --input intent.json30```31<!-- SKILL_VARIANT:unix:end -->3233<!-- SKILL_VARIANT:windows:start -->34### Windows (PowerShell)3536```powershell37# Set path38$env:SKILL_DIR = "packages\eidou-usage-skill\scripts" # In-repo39# $env:SKILL_DIR = "$env:APPDATA\opencode\skill\eidou-usage\scripts" # Installed4041# Run42python "$env:SKILL_DIR\compose.py" --input intent.json43```44<!-- SKILL_VARIANT:windows:end -->4546## Core Rules4748- Primary tool: `compose.py`49- Validation gate: `validate.py`50- Output must satisfy `projection -> field -> content` and pass `validate.py`.5152### Reserved Close Action5354- Use `_eidou_sys_close` for buttons that should close the projection.55- Compose normalizes explicit close intents in action rows:56 - `action: "close"` -> `_eidou_sys_close`57 - `action: "eidou:close"` -> `_eidou_sys_close`58 - `label: "Close"` with missing/empty `action` -> `_eidou_sys_close`59- Non-close custom actions are preserved as provided.6061## CLI Contract6263<!-- SKILL_VARIANT:unix:start -->64```bash65# stdin -> stdout66echo '{"pattern":"message","title":"Hi","message":"Yo"}' | \67 python3 $SKILL_DIR/compose.py6869# file input / file output70python3 $SKILL_DIR/compose.py --input intent.json --output ui.json7172# validate-only dry run73python3 $SKILL_DIR/compose.py --input intent.json --validate-only74```75<!-- SKILL_VARIANT:unix:end -->7677<!-- SKILL_VARIANT:windows:start -->78```powershell79# stdin -> stdout80'{"pattern":"message","title":"Hi","message":"Yo"}' |81 python "$env:SKILL_DIR\compose.py"8283# file input / file output84python "$env:SKILL_DIR\compose.py" --input intent.json --output ui.json8586# validate-only dry run87python "$env:SKILL_DIR\compose.py" --input intent.json --validate-only88```89<!-- SKILL_VARIANT:windows:end -->9091### Exit Codes9293- `0`: success94- `1`: IntentSpec validation error95- `2`: pattern not found96- `3`: build error97- `4`: EUIP validation error9899### Error Format (stderr JSON)100101```json102{"error":"PATTERN_NOT_FOUND","message":"Pattern 'x' not found","stage":"pattern_selection"}103```104105`stage` values: `input_parse`, `spec_validation`, `pattern_selection`, `build`, `euip_validation`.106107## IntentSpec Basics108109Common fields:110111- `pattern` (required)112- `title` (required)113- `description` (optional)114- `size` (optional; width-class presets: `compact`, `standard`, `wide`; ratio presets: `dashboard`, `card`, `widescreen`, `portrait`, `square`; protocol presets: `auto`, `sm`, `md`, `lg`, `xl`, `full`; object: `{"width":1024,"height":"auto"}`; ratio object: `{"ratio":"16:9","width":960,"maxWidth":1200,"base":"lg"}`)115- `theme` (optional projection theme override)116117Pattern-specific fields are below.118119## Pattern Catalog120121| Pattern | Purpose | Required Fields |122|---|---|---|123| `form` | Collect user input | `fields` |124| `data_table` | Show tabular records | `columns`, `rows` |125| `confirmation` | Confirm dangerous action | `warning` |126| `status_dashboard` | Show metrics overview | `metrics` |127| `detail_view` | Show one entity details | `fields` |128| `list` | Show vertical items | `items` |129| `settings` | Grouped configuration controls | `groups` |130| `message` | Simple info/status panel | `message` |131| `profile` | Entity profile card | `name` |132| `article` | Markdown article layout | `content` |133| `chat` | Message stream with avatars | `messages` |134| `terminal_output` | Terminal log with run status | `lines` |135| `progress_tracker` | Multi-step pipeline tracker | `steps` |136| `media_gallery` | Grid image gallery | `items` |137| `chart` | Data visualization (line/bar/pie/area) | `variant`, `data` |138139Profile avatar behavior: `profile` always emits an `avatar` atom. `avatar` may be an object (`{ "src": "...", ... }`) or a string URL shorthand. Compose derives a 1-2 character fallback from `name` whenever `avatar.fallback` is missing and sets `alt` to `<name> avatar` when not provided.140141Default sizing note: `media_gallery` defaults to a ratio size (`16:9`, width `1024`, maxWidth `1200`) to keep image-heavy content stable without oversized auto windows.142Compose layouts default to fit-content style hybrid sizing (`{"width":...,"height":"auto"}`) to avoid wasted vertical whitespace.143144## Compose Pattern (Build Your Own)145146Use `"pattern": "compose"` to assemble custom UIs from building blocks.147Each block in `body[]` is a `{ "use": "<block_name>", ...params }` directive.148149```json150{151 "pattern": "compose",152 "title": "Server Dashboard",153 "layout": "sidebar",154 "size": "dashboard",155 "body": [156 { "slot": "main", "use": "chart_panel", "variant": "line", "data": [{"month": "Jan", "revenue": 4200}] },157 { "slot": "side", "use": "metric_card", "label": "CPU", "value": "73%" },158 { "slot": "side", "use": "metric_card", "label": "Mem", "value": "2.1GB" }159 ]160}161```162163### Layout Presets164165Pick a layout to control how blocks are arranged spatially.166Assign blocks to named slots. Multiple blocks in the same slot stack vertically.167If no `slot` is specified, blocks go to the first slot of the layout.168169| Layout | Slots | Default Size | Description |170|---|---|---|---|171| `stack` | `main` | `auto` | Vertical stack (default). All blocks top-to-bottom. |172| `sidebar` | `main`, `side` | `{"width":1024,"height":"auto"}` | 2/3 main + 1/3 side rail. |173| `split` | `left`, `right` | `{"width":1024,"height":"auto"}` | 50/50 equal halves. |174| `grid-2x2` | `slot-a`, `slot-b`, `slot-c`, `slot-d` | `{"width":640,"height":"auto"}` | 2x2 equal grid. |175| `bento` | `slot-a`, `slot-b`, `slot-c` | `{"width":1024,"height":"auto"}` | 1 large (slot-a spans 2x2) + 2 small. |176| `hero` | `hero`, `content` | `{"width":480,"height":"auto"}` | Large hero area + content below. |177| `triple` | `left`, `center`, `right` | `{"width":1024,"height":"auto"}` | Three equal columns. |178| `dashboard` | `metrics`, `main`, `footer` | `{"width":1024,"height":"auto"}` | KPI row + main + optional footer. |179180Use explicit `size` (for example `"dashboard"`) when you want a semantic ratio preset instead of fit-content defaults.181182#### Layout ASCII Diagrams183184**sidebar:**185```186+------------------+--------+187| main | side |188+------------------+--------+189```190191Note: If `main` contains a single `chart_panel`, it is vertically centered in the available height.192Multi-block content (profiles, docs) stays top-aligned.193194**bento:**195```196+------------------+--------+197| | slot-b |198| slot-a +--------+199| | slot-c |200+------------------+--------+201```202203**dashboard:**204```205+---------------------------+206| metrics metrics metrics |207+---------------------------+208| main |209+---------------------------+210| footer |211+---------------------------+212```213214### Size Presets215216Control window dimensions with semantic size names.217Explicit `size` always overrides the layout's fit-content default.218219Most patterns default to a **width-class** preset (fit-content height).220Use **ratio** presets only for media/visual compositions where aspect stability matters.221`sm`/`md`/`lg`/`xl` are fixed pixel protocol presets (both axes fixed) and often less ideal for content-heavy windows.222223**Width-class presets** (fixed width, height fits content):224225| Name | Output | Ideal For |226|---|---|---|227| `compact` | `{"width":360,"height":"auto"}` | Toasts, confirms, small dialogs |228| `standard` | `{"width":480,"height":"auto"}` | Forms, cards, profiles (THE default) |229| `wide` | `{"width":720,"height":"auto"}` | Tables, multi-column, articles |230231For 1024-wide content, use explicit `{"width":1024,"height":"auto"}` or compose layout defaults (sidebar/split/dashboard already provide this).232233**Ratio presets** (fixed aspect ratio canvas):234235| Name | Output | Ideal For |236|---|---|---|237| `dashboard` | 16:9, 1024px | Multi-chart, metrics overview |238| `card` | 4:3, 480px | Single card visualization |239| `widescreen` | 21:9, 1024px | Comparison, wide chart layouts |240| `portrait` | 3:4, 480px | Tall visual story flow |241| `square` | 1:1, 640px | Grid-heavy visual content |242243You can also use raw sizes: `auto`, `sm`, `md`, `lg`, `xl`, `full`, hybrid objects (`{"width":1024,"height":"auto"}`), or ratio objects.244245### Molecules (Small Functional Units)246247| Block | Purpose | Required | Optional |248|---|---|---|---|249| `labeled_field` | Label + input control | `label`, `name` | `type`, `placeholder`, `default`, `error`, `options` |250| `action_row` | Row of buttons | `actions[]` | *(each action: `label`, `action`, `variant`)* |251| `key_value` | Key-value pair | `key`, `value` | `copyable` |252| `metric_card` | Single metric display | `label`, `value` | `trend`, `status`, `progress` |253| `status_badge` | Status indicator | `label` | `status`, `icon` |254| `avatar_header` | Avatar + name + subtitle | `name` | `subtitle`, `avatar`, `icon` |255| `empty_state` | No-data placeholder | `title` | `description`, `icon`, `action` |256| `alert_box` | Inline notification | `message` | `variant` (info/warning/error/success), `title` |257| `search_box` | Search input with icon | `name` | `placeholder`, `action` |258| `divider` | Visual separator | *(none)* | *(none)* |259| `text_block` | Text content | `content` | `variant` (h1/h2/h3/body/label/mono) |260| `markdown_block` | Rendered markdown | `content` | *(none)* |261| `chart_with_header` | Chart with title + badge | `title`, `variant`, `data[]` | `badge`, + chart props |262| `chart_legend_card` | Series legend indicator | `label`, `value` | `color`, `trend` |263| `chart_stat_row` | Stat row for chart context | `label`, `value` | *(none)* |264265### Organisms (Functional Sections)266267| Block | Purpose | Required | Optional |268|---|---|---|---|269| `form_section` | Group of form fields | `fields[]` | `actions[]`, `description` |270| `data_table` | Tabular data | `columns[]`, `rows[]` | `row_actions[]`, `empty_message` |271| `metrics_row` | Grid of metric cards | `metrics[]` | *(none)* |272| `detail_section` | Key-value detail group | `fields[]` | `avatar` |273| `settings_group` | Toggle/select settings | `title`, `settings[]` | `actions[]` |274| `chat_log` | Message stream | `messages[]` | `actions[]` |275| `terminal_panel` | Terminal output | `lines[]` | `status`, `progress`, `actions[]` |276| `step_tracker` | Multi-step progress | `steps[]` | `actions[]` |277| `media_grid` | Image grid | `items[]` | `actions[]` |278| `chart_panel` | Data visualization | `variant`, `data[]` | `xKey`, `yKeys`, `actions[]` |279| `chart_dashboard` | Multi-chart grid + metrics | `charts[]` | `metrics[]`, `columns`, `actions[]` |280| `chart_detail` | Chart + stats breakdown | `title`, `variant`, `data[]` | `stats[]`, `actions[]`, + chart props |281| `list_section` | Vertical item list | `items[]` | `actions[]`, `empty_message` |282283### Recipes (Suggested Combos)284285- **Dashboard**: `layout: "dashboard"` with `metrics_row` in `metrics` + `chart_panel` in `main`286- **Sidebar Analysis**: `layout: "sidebar"` with `chart_panel` in `main` + `metric_card`s in `side`287- **Comparison**: `layout: "split"` with `chart_panel` in `left` + `chart_panel` in `right`288- **Bento Overview**: `layout: "bento"` with main chart in `slot-a` + metrics in `slot-b`/`slot-c`289- **KPI Grid**: `layout: "grid-2x2"` with `metric_card` in each slot290- **Hero Feature**: `layout: "hero"` with `chart_panel` in `hero` + `text_block` in `content`291- **Simple Stack**: no layout (default) with `text_block` + `action_row`292- **Form + Preview**: `form_section` + `markdown_block` (stack layout)293294### Compose One-Liners295296```json297{"pattern":"compose","title":"Quick","body":[{"use":"text_block","content":"Hello"},{"use":"action_row","actions":[{"label":"OK","action":"ok"}]}]}298```299300```json301{"pattern":"compose","title":"Dashboard","layout":"sidebar","size":"dashboard","body":[{"slot":"main","use":"chart_panel","variant":"pie","data":[{"cat":"A","val":60},{"cat":"B","val":40}]},{"slot":"side","use":"metric_card","label":"Total","value":"100"}]}302```303304```json305{"pattern":"compose","title":"KPIs","layout":"grid-2x2","size":"square","body":[{"slot":"slot-a","use":"metric_card","label":"CPU","value":"73%"},{"slot":"slot-b","use":"metric_card","label":"RAM","value":"2.1GB"},{"slot":"slot-c","use":"metric_card","label":"Disk","value":"45%"},{"slot":"slot-d","use":"metric_card","label":"Net","value":"120Mbps"}]}306```307308## Semantic Field Type Mapping309310When building form/settings controls:311312- `text`, `email`, `password`, `number`, `textarea` -> `input`313- `select` -> `select`314- `toggle` -> `switch`315- `checkbox` -> `checkbox`316- `radio` -> `radiogroup`317- `readonly` -> `text`318- `hidden` -> omitted319- unknown type -> fallback to `text` input320321## Minimal Examples322323```json324{325 "pattern": "form",326 "title": "Create Contact",327 "fields": [328 {"name": "name", "label": "Name", "type": "text"},329 {"name": "email", "label": "Email", "type": "email"}330 ],331 "actions": [{"label": "Save", "action": "submit", "variant": "primary"}]332}333```334335One-line skeletons for quick authoring:336337- `message`: `{"pattern":"message","title":"Welcome","message":"..."}`338- `data_table`: `{"pattern":"data_table","title":"T","columns":[{"key":"x"}],"rows":[{"x":"1"}]}`339- `confirmation`: `{"pattern":"confirmation","title":"Delete","warning":"..."}`340- `status_dashboard`: `{"pattern":"status_dashboard","title":"Health","metrics":[{"label":"CPU","value":"73%"}]}`341- `detail_view`: `{"pattern":"detail_view","title":"Detail","fields":[{"label":"Name","value":"Alice"}]}`342- `list`: `{"pattern":"list","title":"Logs","items":[{"primary":"Started"}]}`343- `settings`: `{"pattern":"settings","title":"Prefs","groups":[{"title":"General","settings":[{"name":"x","label":"X","type":"toggle"}]}]}`344- `profile`: `{"pattern":"profile","title":"Agent","name":"Souta"}`345- `article`: `{"pattern":"article","title":"Notes","content":"## Hello"}`346- `chat`: `{"pattern":"chat","title":"Session","messages":[{"sender":"S","content":"hi"}]}`347- `terminal_output`: `{"pattern":"terminal_output","title":"Build","lines":["$ bun run build"]}`348- `progress_tracker`: `{"pattern":"progress_tracker","title":"Pipeline","steps":[{"label":"Build","status":"complete"}]}`349- `media_gallery`: `{"pattern":"media_gallery","title":"Shots","items":[{"src":"https://example.com/1.png"}]}`350- `chart`: `{"pattern":"chart","title":"Revenue","variant":"line","data":[{"month":"Jan","revenue":4200}]}`351352## Recommended Workflow353354<!-- SKILL_VARIANT:unix:start -->355```bash356# compose then validate357echo '<intent_spec_json>' | \358 python3 $SKILL_DIR/compose.py | \359 python3 $SKILL_DIR/validate.py -360```361<!-- SKILL_VARIANT:unix:end -->362363<!-- SKILL_VARIANT:windows:start -->364```powershell365# compose then validate366'<intent_spec_json>' |367 python "$env:SKILL_DIR\compose.py" |368 python "$env:SKILL_DIR\validate.py" -369```370<!-- SKILL_VARIANT:windows:end -->371372Use this flow for every generated widget before calling `show_widget`.373374If this skill doc conflicts with schema, schema wins:375376- `specification/v0_1/json/root.json`377- `specification/v0_1/json/components.json`378- `specification/v0_1/json/events.json`379- `specification/v0_1/json/theme.json`380381---382> Converted and distributed by [TomeVault](https://tomevault.io/claim/meowfia-dev) — claim your Tome and manage your conversions.383<!-- tomevault:4.0:skill_md:2026-04-14 -->