Rust-ification 阶段,CI 只保留 Rust 相关: - rust-check.yml: cargo fmt + build + test (with STEP1A_REQUIRE_GPU=1 on Linux) + clippy + cargo-deny - wasm-bundle-check.yml: wasm32 target check 删除: - build-electron.yml: Electron desktop build (Rust 化后用 openpencil-shell-native) - ci.yml: TS type-check + Vitest + web build (Rust 化后已废) - docker.yml: TS Docker image (Rust 化后重做) - publish-cli.yml: npm packages (Rust 化后改 cargo publish)
59 KiB
| name | description | phase | trigger | priority | budget | category | ||||
|---|---|---|---|---|---|---|---|---|---|---|
| elements | N-tool element family reference — rows, containers, atoms, text/button primitives, composition, forms, controls (switch/checkbox/radio/tabs/segmented), state/feedback (empty_state/alert/toast/progress_bar), floating/nav (fab/breadcrumb/stepper), ratings & pagination (rating_stars/carousel_dots), inline primitives (link/kbd/price), content blocks (quote_block/code_block), design system (color_swatch). Each tool replaces a documented batch_design failure mode |
|
|
14 | 2400 | base |
ELEMENT TOOLS (schema-constrained alternatives to batch_design):
These narrow MCP tools emit well-known structures that batch_design frequently gets wrong on non-Claude models (overflow, wrong role, anti-pattern layout). Each is shape-locked — you pick the tool by matching intent, then supply only content.
MULTI-TOOL OUTPUT IS THE NORM, NOT THE EXCEPTION. A brief that names more than one component (a settings panel with 4 toggle rows, a team list with 5 members, a feed with 6 log entries, an onboarding screen with 4 step cards) MUST emit ONE <op_tool> block per component. The harness reads every <op_tool> tag in your output, so chain as many as the brief implies. Fall back to batch_design only when at least one component in the brief truly needs a custom shape no element tool covers — and then use a SINGLE batch_design for the WHOLE response, never as a per-component fallback mixed with element-tool calls (the harness drops the batch_design half whenever element calls share the response).
Multi-tool example — a "Notifications" settings section with a header + 4 toggle rows is 5 tool calls (1× add_section_header_v1 + 4× add_setting_row_v1), NOT 1 batch_design.
parent_id is REAL or OMITTED — never invented. Every add_*_v1 tool's parent_id arg must either (1) be omitted entirely so the new node lands at the page root (the safe default for full-page composite briefs), or (2) name a real existing node id you already received from a prior tool call. The cookbook recipes below use placeholders like <page> / <panel> / <sidebar> as DOCUMENTATION shorthand only — when YOU emit the call in your output, OMIT the parent_id field entirely.
❌ WRONG — these all crash with parent_id "X" not found in document because every id was made up by the model, not handed to you by a prior tool call:
add_activity_log_v1({ parent_id: "entry-1", actor: "Sarah", ... })— "entry-1" was never createdadd_setting_row_v1({ parent_id: "root", title: "Email" })— page root has no idadd_member_row_v1({ parent_id: "members-section", name: "Sarah" })— section-* placeholders are docs, not real ids- Same trap for any sequential name you might invent:
card-1/item-1/row-N/<page>/panel/canvas
✅ RIGHT — omit parent_id entirely; each call lands at the page root, which is what every full-page composite brief wants:
add_activity_log_v1({ actor: "Sarah", action: "approved deploy", timestamp: "2h ago", theme: "system" })add_setting_row_v1({ title: "Email notifications", trailing: { kind: "switch", on: true }, theme: "system" })add_member_row_v1({ name: "Sarah Lee", subtitle: "Designer", theme: "system" })
Theme handling — when to pass theme: 'system'
Default to theme: 'system' for every v1 tool call. This makes the output respect the user's design system (doc.variables / doc.themes):
- If user has seeded
applySemanticPalette(doc)or set custom token values, v1 'system' mode emits$color-*/$type-*/$spacing-*/$radius-*refs that resolve to user's design system at paint time. - If user has NOT seeded a design system, v1 'system' falls back to default palette values (byte-equivalent to v0 hex output via
DEFAULT_PALETTE_FALLBACK).
Pass theme: 'light' ONLY if:
- User explicitly asks for "light theme" output (rare — system mode handles light by default)
- Brief mentions a specific palette (e.g. "use Tailwind slate")
Pass theme: 'dark' ONLY if:
- User explicitly asks for "dark mode" / "dark theme"
- Brief is for a dark UI (e.g. video player overlay, terminal interface)
Use v0 tools (without _v1 suffix) ONLY when:
- The user explicitly requires byte-frozen output (rare — usually for downstream tooling that depends on stable bytes)
- A specific test fixture requires v0 byte-parity
For 99% of design generation, add_X_v1({ ..., theme: 'system' }) is correct.
Decision tree (per component — pick first match)
Rows (horizontal, in-card or scrolling):
- Row of items with title + subtitle + optional icon →
add_card_row_v1(scroll;theme: 'system'default — see "Theme handling" section) 1b. Byte-frozen escape hatch (rare — downstream tooling requiring stable bytes) →add_card_row_v0 - Row of items with small label + big numeric value →
add_metric_row_v1(scroll; no hardcoded colors; accepts theme for API consistency) 2b. Byte-frozen escape hatch →add_metric_row_v0 - Row of filter chips / category tabs (label + optional icon, active state) →
add_nav_chip_row_v1(scroll; no hardcoded colors; accepts theme for API consistency) 3b. Byte-frozen escape hatch →add_nav_chip_row_v0 - Non-scrolling 2-5 stats inline (auto-share width) →
add_stat_grid_v1(no explicit fills; accepts theme for API consistency) 4b. Byte-frozen escape hatch →add_stat_grid_v0
Containers and single elements:
- Section header (big title + optional "See all" action) →
add_section_header_v1(no hardcoded colors; accepts theme for API consistency) 5b. Byte-frozen escape hatch →add_section_header_v0 - Bottom tab bar (inline flow, 3-5 nav items) →
add_bottom_nav_v1(accepts theme for API consistency; output identical across themes) 6b. Byte-frozen escape hatch →add_bottom_nav_v0 - Mobile top bar (leading icon + centered title + trailing icon) →
add_top_nav_bar_v1(accepts theme; output identical — no hardcoded surface colors) 7b. Byte-frozen escape hatch →add_top_nav_bar_v0 - Icon-only button (44×44, hit-target safe) →
add_icon_button_v1(accepts theme for API consistency; output identical across themes) 8b. Byte-frozen escape hatch →add_icon_button_v0 - Apple-style progress ring with centered text →
add_activity_ring_v1(accepts theme for API consistency; output identical across themes) 9b. Byte-frozen escape hatch →add_activity_ring_v0
Atoms (1-2 node building blocks):
- Hairline separator between list rows / sections →
add_divider_v1(accepts theme for API consistency; output identical across themes) 10b. Byte-frozen escape hatch →add_divider_v0 - Short inline pill / tag / "NEW" / "BETA" / count badge →
add_badge_v1(accepts theme for API consistency; output identical across themes) 11b. Byte-frozen escape hatch →add_badge_v0 - Circular avatar (with optional initial / empty for later image fill) →
add_avatar_v1(accepts theme for API consistency; output identical across themes) 12b. Byte-frozen escape hatch →add_avatar_v0
Text + button primitives:
- Padding-based button with text (optional leading icon) →
add_text_button_v1(accepts theme; output identical — no hardcoded surface colors) 13b. Byte-frozen escape hatch →add_text_button_v0 - Heading with enforced fontSize/lineHeight per level + AUTO CJK script detection (SC/JP/KR) →
add_heading_v1(supportstheme: 'light' | 'dark' | 'system') 14b. Byte-frozen escape hatch →add_heading_v0 - Body text (Inter everywhere — CJK gets lineHeight 1.6 + letterSpacing 0, Latin 1.5) →
add_body_text_v1(accepts theme for API consistency; output identical across themes) 15b. Byte-frozen escape hatch →add_body_text_v0
Composition:
- Icon + text inline pair (menu items, breadcrumbs, status indicators) →
add_icon_label_v1(accepts theme for API consistency; output identical across themes) 16b. Byte-frozen escape hatch →add_icon_label_v0 - iOS/Material list row (leading icon + title/subtitle stack + trailing icon) →
add_list_row_v1(accepts theme for API consistency; output identical across themes) 17b. Byte-frozen escape hatch →add_list_row_v0
Forms:
- Search bar (height=44, cornerRadius=22, leading search icon) →
add_search_bar_v1(dark/system adds surface2 fill so bar is visible on dark bg) 18b. Byte-frozen escape hatch →add_search_bar_v0 - Form field (label + 48px input with optional affordance icons) →
add_form_field_v1(accepts theme for API consistency; output identical across themes) 19b. Byte-frozen escape hatch →add_form_field_v019c. Multi-line textarea (label + N-row input for notes / bio / feedback) →add_textarea_v1(accepts theme; output identical — no hardcoded surface colors) 19c-v0. Byte-frozen escape hatch →add_textarea_v019d. Dropdown select closed-state (label + 48px input w/ value text + chevron-down) →add_select_v1(placeholder → textSubtle in dark/system) 19d-v0. Byte-frozen escape hatch →add_select_v0
Controls (toggle / choice / tabs):
- iOS/Material toggle switch (51×31, thumb floats) →
add_switch_v1(iOS HIG values #34C759/#E5E5EA are builder-private per §3.4; all modes identical) 20b. Byte-frozen escape hatch →add_switch_v0 - Checkbox + inline label (20×20 box,
checkicon inside when checked) →add_checkbox_v1(accent fill checked, border token unchecked) 21b. Byte-frozen escape hatch →add_checkbox_v0 - Radio button + inline label (20×20 ring, dot inside when selected) →
add_radio_v1(accent brand-invariant; unselected ring → border in dark/system) 22b. Byte-frozen escape hatch →add_radio_v0 - Horizontal top tabs with underline on active (fontWeight 600 + 2px sibling rectangle underline) →
add_tabs_v1(#2563EB underline is brand accent per §3.4; all modes identical) 23b. Byte-frozen escape hatch →add_tabs_v0 - iOS pill-style segmented control (equal-width segments, active floats white) →
add_segmented_control_v1(track → surface2, active seg → surface, labels → textPrimary/textMuted) 24b. Byte-frozen escape hatch →add_segmented_control_v0
State / feedback:
- Empty state (icon + title + optional subtitle + optional CTA button, centered) →
add_empty_state_v1(accepts theme for API consistency; output identical across themes) 25b. Byte-frozen escape hatch →add_empty_state_v0 - Inline banner / callout (icon + message + optional close x, fill_container) →
add_alert_v1(accepts theme for API consistency; output identical across themes) 26b. Byte-frozen escape hatch →add_alert_v0 - Floating pill notification (dark fit_content pill) →
add_toast_v1(theme: 'system' default — see "Theme handling" section) 27b. Byte-frozen escape hatch →add_toast_v0 - Linear progress bar (fixed bar_width + value 0-100) →
add_progress_bar_v1(track → surface2 in dark/system; accent fill brand-invariant) 28b. Byte-frozen escape hatch →add_progress_bar_v0
Floating / nav / wizard:
- Floating action button (circular 56×56, icon centered) →
add_fab_v1(bg → accent in dark/system; icon always white) 29b. Byte-frozen escape hatch →add_fab_v0 - Breadcrumb trail with chevron separators (last crumb auto-active) →
add_breadcrumb_v1(accepts theme for API consistency; output identical across themes) 30b. Byte-frozen escape hatch →add_breadcrumb_v0 - Horizontal numbered stepper (circles + fill_container connectors) →
add_stepper_v1(pending fill → border; pending number → textMuted; accent + done-white stay hardcoded) 31b. Byte-frozen escape hatch →add_stepper_v0
Ratings & pagination:
- N-of-M star rating (filled + empty stars using lucide
star) →add_rating_stars_v1(no explicit colors; all modes identical — accepts theme for API consistency) 32b. Byte-frozen escape hatch →add_rating_stars_v0 - Carousel / slide dots (active becomes elongated pill, inactive circles) →
add_carousel_dots_v1(active=text-primary, inactive=border in dark/system modes) 33b. Byte-frozen escape hatch →add_carousel_dots_v0
Inline text primitives:
- Text link with optional trailing icon ("Learn more →") →
add_link_v1(accepts theme for API consistency; output identical across themes) 34b. Byte-frozen escape hatch →add_link_v0 - Keyboard shortcut glyph ("⌘ K" / "Ctrl + Shift + P") →
add_kbd_v1(key bg → surface2, stroke → border in dark/system) 35b. Byte-frozen escape hatch →add_kbd_v0 - Pricing typography ("$29/month": currency 20/500 + amount 40/700 + period 14/500) →
add_price_v1(no hardcoded colors; all modes identical — accepts theme for API consistency) 36b. Byte-frozen escape hatch →add_price_v0
Content blocks:
- Quoted passage with optional author attribution →
add_quote_block_v1(container bg → surface in dark/system) 37b. Byte-frozen escape hatch →add_quote_block_v0 - Preformatted code block (fill_container, wraps, gray-50 bg) →
add_code_block_v1(bg → surface2 in dark/system) 38b. Byte-frozen escape hatch →add_code_block_v0
Design-system:
- Color swatch (colored square + optional token label) →
add_color_swatch_v1(same tree; theme param for API consistency) 39b. Byte-frozen escape hatch →add_color_swatch_v0
Charts / data visualization:
- Bar-chart skeleton (one rectangle per value, bottom-aligned) →
add_chart_bars_v1(chart-1 token in dark/system) 40b. Line-chart skeleton (polyline + optional dots) →add_chart_line_v1(chart-1 token in dark/system) 40c. Pie-chart skeleton (colored ellipse slices via arc angles) →add_chart_pie_v1(chart-1..6 tokens in dark/system) 40d. Byte-frozen bar chart escape hatch →add_chart_bars_v040e. Byte-frozen line chart escape hatch →add_chart_line_v040f. Byte-frozen pie chart escape hatch →add_chart_pie_v0
Media / placeholder:
- Image placeholder (gray box + centered icon + optional caption — future image slot) →
add_image_placeholder_v1(bg → bgDeep, icon/label → textMuted in dark/system). Passimage_search_query(2-3 English keywords like "burger fries", "modern office") so the auto-search pass replaces the gray box with a relevant photo; without it the pipeline searches the label or a generic placeholder and lands a random stock image. 44b. Video placeholder (dark box + play icon + optional caption — future video embed) →add_video_placeholder_v1(dark bg/icon/caption are builder-private per §3.4; all modes identical) 44c. Byte-frozen image placeholder escape hatch →add_image_placeholder_v0(also acceptsimage_search_query) 44d. Byte-frozen video placeholder escape hatch →add_video_placeholder_v0
Social / UGC:
- Comment row (circular avatar + author/timestamp header + body) →
add_comment_v1(avatar bg → surface2, timestamp → textMuted in dark/system) 45b. Byte-frozen escape hatch →add_comment_v0
Chrome / modals:
- Modal dialog shell (dimmed backdrop + centered card + title — body composed separately) →
add_modal_shell_v1(supportstheme: 'light' | 'dark' | 'system') 46b. Byte-frozen escape hatch →add_modal_shell_v0
Status / presence:
- Status badge (small colored dot + short label, "● Online" pattern, tone-enum'd) →
add_status_badge_v1(tone colors are status semantics kept hardcoded; all modes identical) 47b. Byte-frozen escape hatch →add_status_badge_v0
Feedback / loading:
- Loading spinner (static ring + 3/4 arc) →
add_spinner_v1(track_color/active_color are caller params; accepts theme for API consistency; all modes identical) 48b. Byte-frozen escape hatch →add_spinner_v0 - Tooltip pill (dark pill + white text, hover-hint appearance) →
add_tooltip_v1(dark body #111827 is intentional inverted-contrast per §3.4; all modes identical) 49b. Byte-frozen escape hatch →add_tooltip_v0
Analytics / KPIs:
- KPI cell with trend arrow + change ("$12k ↑ 8%") →
add_metric_comparison_v1(label → textMuted; trend up → success, down → destructive, flat → textMuted) 50b. Byte-frozen escape hatch →add_metric_comparison_v0
Notifications:
- Notification list row (icon + title/timestamp header + optional body preview + optional unread dot) →
add_notification_row_v1(timestamp → textSubtle, body → textBody, unread dot → destructive) 51b. Byte-frozen escape hatch →add_notification_row_v0
Activity / history:
- Vertical timeline (dots + fixed 24px connectors + content; no padding/gap) →
add_timeline_v1(#2563EB active dot hardcoded per §3.4; inactive dot/connector → border, subtitle → textMuted) 41b. Byte-frozen escape hatch →add_timeline_v0
Calendars:
- Month calendar grid (weekday header + 7-col day rows, today/selected tint) →
add_calendar_grid_v1(header text, day numbers, selected/today fills respond to theme) 42b. Byte-frozen escape hatch →add_calendar_grid_v0
Loading / placeholder:
- Loading skeleton (N gray rectangles, last row ~60% width) →
add_skeleton_v1(row fill → surface2 in dark/system so bars are visible on dark bg) 43b. Byte-frozen escape hatch →add_skeleton_v0
Pagination:
- Pagination bar (numbered pills + prev/next arrows, Google-style ellipses for big ranges) →
add_pagination_v1(arrow/inactive → textBody, ellipsis → textMuted; active pill bg invariant, active text stays white) 52b. Byte-frozen escape hatch →add_pagination_v0
Collapsible content:
- FAQ / accordion item (question + chevron; expanded variant shows answer paragraph) →
add_faq_item_v1(chevron/answer → textMuted, divider → border in dark/system) 53b. Byte-frozen escape hatch →add_faq_item_v0
Tag / multi-value inputs:
- Chip input / tag input (pills + removable × + inline caret, wrap layout) →
add_chip_input_v1(chip bg → surface2, field bg → surface, placeholder → textSubtle) 54b. Byte-frozen escape hatch →add_chip_input_v0
Chart empty state:
- Empty chart placeholder (dashed tile in chart footprint; "No data yet" message) →
add_empty_chart_v1(theme: 'system' default — see "Theme handling" section) 55b. Byte-frozen escape hatch →add_empty_chart_v0
Menus / floating panels:
- Action / context menu panel (dropdown list of icon+label rows, destructive variant supported) →
add_action_menu_v1(surface, border, icon, label colors respond to theme) 56b. Byte-frozen escape hatch →add_action_menu_v0
Dates:
- Date picker CLOSED state (labeled input + "Jan 15, 2026" + trailing calendar icon) →
add_date_picker_v1(input bg → surface, stroke → border in dark/system) 57b. Byte-frozen escape hatch →add_date_picker_v0
Upload / file intake:
- File upload dropzone (dashed tile + cloud icon + "Drop files / click to browse") →
add_upload_dropzone_v1(bg → bgDeep, dashed border → border, icon → textMuted, title → textBody, subtitle → textMuted) 58b. Byte-frozen escape hatch →add_upload_dropzone_v0
Auth / verification:
- OTP / PIN code input (row of N square slots, 4..8 digits; blank / partial / full states) →
add_otp_input_v1(slot bg → surface, borders → border/borderStrong, digit → textPrimary; focused border = accent_color invariant) 59b. Byte-frozen escape hatch →add_otp_input_v0
Attachments:
- File attachment row (type-icon + filename + optional size + remove ×) →
add_attachment_row_v1(surface, text hierarchy, icon colors respond to theme) 60b. Byte-frozen escape hatch →add_attachment_row_v0
Messaging:
- Chat message bubble (left=from-others slate bg / right=from-self accent bg; optional author + timestamp) →
add_chat_bubble_v1(surface2 bg for left, accent bg for right, textMuted for author/timestamp) 61b. Byte-frozen escape hatch →add_chat_bubble_v0
Dashboard KPIs:
- Big-number stat card (standalone metric tile — label + huge value + optional delta/icon) →
add_stat_card_v1(bg → surface; border → border; label → textMuted; icon → textSubtle; value → textPrimary; delta tones stay hardcoded) 62b. Byte-frozen escape hatch →add_stat_card_v0
Auth / login:
- Social auth provider buttons ("Continue with Google / Apple / Microsoft", OAuth/SSO row, third-party sign-in) →
add_social_login_row_v1(button bg → surface; border → border; icon → textMuted; label → textPrimary in dark/system) 63b. Byte-frozen escape hatch →add_social_login_row_v0
Pricing / monetization:
- Pricing plan tier card (SaaS pricing table column: tier name + big price + feature list + CTA; emphasize the recommended tier with
emphasis="featured") →add_pricing_card_v1(card bg → surface, border → border; featured accent/CTA stay brand-invariant; text → textPrimary/textMuted/textBody) 64b. Byte-frozen escape hatch →add_pricing_card_v0
Input / forms:
-
Range slider (single-thumb horizontal slider showing current value: volume, opacity, brightness, price range) →
add_range_slider_v1(accent brand-invariant; thumb bg → surface; remaining → border; label → textPrimary; value → textMuted) 65b. Byte-frozen escape hatch →add_range_slider_v0 -
International phone number input with country-code prefix selector →
add_phone_input_v1(field bg → surface, stroke/divider → border, label → textBody, code → textPrimary, chevron → textMuted) 66b. Byte-frozen escape hatch →add_phone_input_v0 -
Input field with inline action button (newsletter signup, apply discount code, send chat message) →
add_input_with_action_v1(input bg → surface, stroke → border, text → textPrimary; button bg → accent (brand-invariant), button text → white in all modes) 67b. Byte-frozen escape hatch →add_input_with_action_v0
Compliance / disclosure:
- Cookie consent / GDPR / privacy banner (sticky bottom-of-page disclosure card with accept / decline / settings) →
add_cookie_banner_v1(card bg → surface, title → textPrimary, accept → accent in dark/system) 68b. Byte-frozen escape hatch →add_cookie_banner_v0
Desktop / dashboard rails:
- Persistent vertical sidebar (left rail with icon+label rows, optional brand title, active item gets pill bg) →
add_sidebar_nav_v1(bg → surface; title + active label → textPrimary; inactive → textMuted; active item bg → surface2) 69b. Byte-frozen escape hatch →add_sidebar_nav_v0
Presence / collaboration:
- Stacked avatar group (team / online users / "+N more" tile, white-ringed circles in a tight horizontal row) →
add_avatar_group_v1(ring, overflow bg/text respond to theme; brand avatar palette stays hardcoded) 70b. Byte-frozen escape hatch →add_avatar_group_v0
Tabular data:
- Desktop data-table row (N column-aligned cells in a single horizontal row, header / body / selected variants) →
add_data_table_row_v1(header text → textMuted, body → textPrimary, selected → bgDeep in dark/system) 71b. Byte-frozen escape hatch →add_data_table_row_v0
Filter / selection chips:
- Single closable tag chip (filter / applied criterion / category, optional × close icon, tone enum) →
add_tag_v1(tone bg/fg are status semantic colors per §3.4; all modes identical) 72b. Byte-frozen escape hatch →add_tag_v0
People / profile:
- Compact user card (avatar + name + optional role line, horizontal row) →
add_user_card_v1(name → textPrimary, role → textMuted; avatar bg #3B82F6 + initial white stay brand-invariant per §3.4) 73b. Byte-frozen escape hatch →add_user_card_v0 - Large profile header (centered avatar + name + optional handle/bio) →
add_profile_header_v1(name → textPrimary, handle → textMuted, bio → textBody; avatar bg #3B82F6 + initial white stay brand-invariant) 74b. Byte-frozen escape hatch →add_profile_header_v0
Side panels & docking:
- Slide-in drawer shell (full-height side panel with header) →
add_drawer_shell_v1(bg → surface, border → border token, title/icon → semantic tokens in dark/system) 75b. Byte-frozen escape hatch →add_drawer_shell_v0
Forms (open state) & toolbars:
- Open-state combobox / autocomplete (input + visible dropdown rows) →
add_combobox_v1(surface/border/surface2 tokens in dark/system) 76b. Byte-frozen escape hatch →add_combobox_v0 - Desktop toolbar (icon button row with optional dividers) →
add_toolbar_v1(surface → surface, border → border, active-bg → surface2, icon fills → textPrimary/textMuted) 77b. Byte-frozen escape hatch →add_toolbar_v0
Doc / inline feedback:
- Inline doc callout (tinted block with title + body, tone enum) →
add_callout_v1(tone-keyed bg/fg → semantic alert palette in dark/system modes) 78b. Byte-frozen escape hatch →add_callout_v0 - Inline status + action ("Comment deleted • Undo") →
add_inline_action_v1(icon/message → textBody, CTA → accent in dark/system) 79b. Byte-frozen escape hatch →add_inline_action_v0
Sharing / chart annotations:
- Social share button row (circular icon buttons + labels) →
add_share_row_v1(icon btn bg → surface2; icon/label → textMuted in dark/system) 80b. Byte-frozen escape hatch →add_share_row_v0 - Chart legend entry (color marker + label + optional value) →
add_legend_item_v1(label → textBody, value → textPrimary; marker color kept as-is) 81b. Byte-frozen escape hatch →add_legend_item_v0
Mail / inbox:
- Inbox / email list row (sender + subject + preview + unread dot) →
add_inbox_message_v1(primary → textPrimary, timestamp → textSubtle, preview → textMuted, unread dot → accent in dark/system) 82b. Byte-frozen escape hatch →add_inbox_message_v0
Settings / preferences:
- Settings menu row (icon + title + subtitle + trailing chevron / value / switch / badge) →
add_setting_row_v1(supportstheme: 'light' | 'dark' | 'system') 83b. Byte-frozen escape hatch →add_setting_row_v0
People / lists:
- Members / team list row (avatar + name + subtitle + role badge / kebab menu / status dot) →
add_member_row_v1(supportstheme: 'light' | 'dark' | 'system') 84b. Byte-frozen escape hatch →add_member_row_v0 - Pending invite list row (initial avatar + email/role + status pill + Resend action) →
add_invite_row_v1(avatar bg → surface2, text → textPrimary/textMuted, action → accent; status pills use alertColors in dark/system) 85b. Byte-frozen escape hatch →add_invite_row_v0
Faceted search / filter sidebar:
- Sidebar filter group (heading + checkbox-style option list with counts) →
add_filter_group_v1(title → textPrimary, label → textBody, box bg/stroke → surface/border in dark/system) 86b. Byte-frozen escape hatch →add_filter_group_v0
Audit / activity feed:
- Activity log entry (actor in bold + action + timestamp + tinted icon dot) →
add_activity_log_v1(supportstheme: 'light' | 'dark' | 'system') 87b. Byte-frozen escape hatch →add_activity_log_v0
Calendar:
- Single event card (month/day column + title + time + location) →
add_event_card_v1(card bg/stroke/date column → semantic tokens; accent strip + white text stay brand-invariant) 88b. Byte-frozen escape hatch →add_event_card_v0
Onboarding:
-
Numbered step card (circle/check + title + description) →
add_step_card_v1(title → textPrimary; desc → textMuted; incomplete ring bg → surface; accent stays hardcoded) 89b. Byte-frozen escape hatch →add_step_card_v0 -
None match → fall through to
batch_design
Disambiguation: if you need a ROW of 3 metrics that should NOT scroll (e.g. a stats strip inside a card), use add_stat_grid_v1, NOT add_metric_row_v1. The grid uses fill_container per cell so it never overflows; the metric row uses fixed-px cells + scroll wrapper.
When to use vs batch_design
PREFER an element tool when the spec says any of:
- "horizontal scrolling cards", "swipeable row", "chip row", "pills" →
add_card_row_v1(theme: 'system' default) - "metric tiles", "KPI cards", "dashboard stats" (SCROLLING row) →
add_metric_row_v1(theme: 'system' default) - "stats row", "3 metrics side by side", "summary bar" (NON-scrolling grid) →
add_stat_grid_v1(theme: 'system' default) - "category filter chips", "quick-access shortcuts" →
add_nav_chip_row_v1(theme: 'system' default) - "section title with See all / View more" →
add_section_header_v1(theme: 'system' default) - "bottom nav", "tab bar", "tabbar", "底部导航" →
add_bottom_nav_v1(theme: 'system' default) - "top bar", "app bar", "header with back button", "页面标题栏" →
add_top_nav_bar_v1(theme: 'system' default) - "icon-only button", "close button", "menu button" (toolbar-style) →
add_icon_button_v1(theme: 'system' default) - "activity ring", "progress ring", "circular progress", "Apple health ring" →
add_activity_ring_v1(theme: 'system' default) - "hairline divider", "separator", "row divider", "section separator" →
add_divider_v1(theme: 'system' default) - "badge", "pill", "tag", "NEW label", "count bubble" (≤16 Latin / ≤8 CJK chars) →
add_badge_v1(theme: 'system' default) - "avatar", "profile picture", "user circle", "initial bubble" →
add_avatar_v1(theme: 'system' default) - "primary button", "secondary button", "CTA", "submit button" (short label) →
add_text_button_v1(theme: 'system' default) - "hero headline", "section title", "card title" / 特定字号标题 →
add_heading_v1(theme: 'system' default; use"system"whenapplySemanticPalette(doc)is seeded) - "body paragraph", "description text", "intro copy" (包含 CJK 时尤其推荐) →
add_body_text_v1(theme: 'system' default) - "icon with label", "menu item (inline)", "breadcrumb segment", "status indicator text" →
add_icon_label_v1(theme: 'system' default) - "list item", "iOS list cell", "table row with chevron" →
add_list_row_v1(theme: 'system' default; settings rows specifically —add_setting_row_v1, which has switch / value / badge trailing variants) - "search bar", "search input", "filter search", "搜索栏" →
add_search_bar_v1(theme: 'system' default; adds surface2 fill in dark/system so bar is visible on dark bg) - "form field", "email input", "password field", "labeled input", "required field" →
add_form_field_v1(theme: 'system' default) - "textarea", "multi-line input", "notes field", "description box", "bio input", "feedback box", "多行输入", "备注" →
add_textarea_v1(theme: 'system' default) - "dropdown", "select", "picker", "combo box", "下拉选择", "选择器" →
add_select_v1(theme: 'system' default; placeholder → textSubtle in dark/system) - "skeleton", "loading placeholder", "shimmer", "loading state", "placeholder lines", "骨架屏", "加载中占位" →
add_skeleton_v1(theme: 'system' default; row fill → surface2 so bars are visible on dark bg) - "line chart", "trend chart", "折线图" →
add_chart_line_v1(theme: 'system' default) - "pie chart", "donut chart", "饼图" →
add_chart_pie_v1(theme: 'system' default) - "image placeholder", "photo slot", "upload zone", "hero image area", "cover placeholder", "图片占位" →
add_image_placeholder_v1(theme: 'system' default) - "video placeholder", "video slot", "play placeholder", "upcoming video", "视频占位" →
add_video_placeholder_v1(theme: 'system' default) - "comment", "reply", "feedback row", "review row", "评论" →
add_comment_v1(theme: 'system' default) - "modal", "dialog", "popup", "confirm dialog", "模态框", "弹窗" →
add_modal_shell_v1(theme: 'system' default; use"system"when the document hasapplySemanticPalette(doc)seeded) - "toast", "snackbar", "popup notification", "轻提示" →
add_toast_v1(theme: 'system' default; toasts use INVERTED contrast —"dark"gives a light pill with dark fg) - "empty chart", "no data chart", "chart placeholder", "empty analytics tile", "暂无数据", "空图表" →
add_empty_chart_v1(theme: 'system' default; use inside dark-theme dashboards so the empty slot doesn't punch a light rectangle into dark surfaces) - "status", "online indicator", "presence dot", "health status", "busy indicator", "状态", "在线" →
add_status_badge_v1(theme: 'system' default; tone colors are status semantics kept hardcoded) - "spinner", "loading spinner", "progress circle", "loader", "加载圈" →
add_spinner_v1(theme: 'system' default) - "tooltip", "hover hint", "help tip", "提示浮层" →
add_tooltip_v1(theme: 'system' default; dark body #111827 is intentional inverted-contrast) - "toggle", "switch", "on/off", "开关" →
add_switch_v1(theme: 'system' default; iOS HIG values kept hardcoded) - "checkbox", "agreement", "select option", "复选框" →
add_checkbox_v1(theme: 'system' default; accent fill checked, border token unchecked) - "radio", "single choice", "单选" →
add_radio_v1(theme: 'system' default; stack multiple in a vertical parent; accent stays brand-invariant) - "top tabs", "underline tabs", "secondary nav", "下划线 tab" →
add_tabs_v1(theme: 'system' default; #2563EB underline is brand accent per §3.4) - "segmented control", "iOS pill tabs", "filter toggle group", "iOS 分段控制" →
add_segmented_control_v1(theme: 'system' default; track → surface2; active seg → surface) - "empty state", "no results", "nothing here yet", "first-run state", "空状态" →
add_empty_state_v1(theme: 'system' default) - "alert", "callout", "banner", "notification bar", "告知条", "warning banner" →
add_alert_v1(theme: 'system' default) - "progress bar", "loading bar", "线性进度条", "linear progress" →
add_progress_bar_v1(theme: 'system' default; track → surface2; accent brand-invariant) - "FAB", "floating action button", "compose button", "新建按钮" →
add_fab_v1(theme: 'system' default; bg → accent; icon always white) - "breadcrumb", "nav path", "面包屑" →
add_breadcrumb_v1(theme: 'system' default) - "stepper", "progress steps", "wizard nav", "步骤条" →
add_stepper_v1(theme: 'system' default; pending fill → border; pending number → textMuted) - "rating", "review stars", "评分" →
add_rating_stars_v1(theme: 'system' default) - "carousel dots", "slide indicator", "轮播指示" →
add_carousel_dots_v1(theme: 'system' default) - "text link", "learn more", "inline link" →
add_link_v1(theme: 'system' default) - "keyboard shortcut", "hotkey", "⌘K", "快捷键" →
add_kbd_v1(theme: 'system' default; key bg → surface2, stroke → border in dark/system) - "price", "plan cost", "$29/month", "定价" →
add_price_v1(theme: 'system' default) - "quote", "testimonial quote", "引言" →
add_quote_block_v1(theme: 'system' default; container bg → surface in dark/system) - "code snippet", "code block", "代码块" →
add_code_block_v1(theme: 'system' default; bg → surface2 in dark/system) - "color swatch", "palette", "token", "色板" →
add_color_swatch_v1(theme: 'system' default) - "bar chart", "histogram skeleton", "weekly steps", "柱状图" →
add_chart_bars_v1(theme: 'system' default) - "timeline", "activity history", "vertical stepper", "时间线", "动态" →
add_timeline_v1(theme: 'system' default; #2563EB active dot hardcoded per §3.4) - "calendar", "date picker grid", "month view", "日历" →
add_calendar_grid_v1(theme: 'system' default) - "pagination", "page nav", "page numbers", "prev/next pages", "分页", "分页条" →
add_pagination_v1(theme: 'system' default) - "FAQ", "accordion", "collapsible item", "Q&A", "expandable row", "常见问题", "折叠面板" →
add_faq_item_v1(theme: 'system' default) - "chip input", "tag input", "multi-select field", "recipient list", "email chips", "标签输入", "多选标签" →
add_chip_input_v1(theme: 'system' default) - "action menu", "context menu", "dropdown menu", "more menu", "kebab menu", "action sheet", "下拉菜单", "操作菜单" →
add_action_menu_v1(theme: 'system' default) - "date picker", "date input", "date field", "due date", "picker closed", "日期选择器", "日期输入" →
add_date_picker_v1(theme: 'system' default; for the calendar grid shown after clicking, useadd_calendar_grid_v1) - "upload", "drop files here", "drag and drop", "file picker", "dropzone", "upload area", "上传区", "文件拖放" →
add_upload_dropzone_v1(theme: 'system' default; visually similar to empty-chart but semantically different — pick by intent) - "OTP", "PIN code", "verification code", "2FA code", "6-digit code", "enter code", "验证码", "PIN 码" →
add_otp_input_v1(theme: 'system' default) - "attachment", "attached file", "uploaded file", "file item", "file list row", "附件", "已上传文件" →
add_attachment_row_v1(theme: 'system' default; for upload-in-progress state, composeadd_progress_bar_v1below) - "chat message", "message bubble", "conversation row", "iMessage bubble", "chat UI", "聊天气泡", "消息气泡" →
add_chat_bubble_v1(theme: 'system' default; side="left" for from-others, side="right" for from-self) - "KPI card", "big number card", "metric tile", "stat widget", "featured metric", "关键指标卡", "数据大屏卡片" →
add_stat_card_v1(theme: 'system' default; distinct fromadd_stat_grid_v1which is multi-cell side-by-side) - "Continue with Google", "Sign in with Apple", "social login", "OAuth buttons", "SSO providers", "third-party login", "第三方登录", "社交登录", "OAuth 登录" →
add_social_login_row_v1(theme: 'system' default; orientation="vertical" for stacked full-width on mobile; orientation="horizontal" for the compact icon-only row) - "pricing card", "plan card", "SaaS tier", "subscription plan", "pricing tier", "billing card", "价格卡", "套餐卡", "定价卡片" →
add_pricing_card_v1(theme: 'system' default; set one tile'semphasis: "featured"to visually recommend it). For a 3-tier pricing section, call this 3× under the same parent section. - "slider", "range input", "volume control", "opacity slider", "brightness slider", "filter slider", "滑块", "滑动条", "音量条" →
add_range_slider_v1(theme: 'system' default; setshow_value=true+value_suffix="%"to render the readout). For a dual-handle range (min+max), still fall through to batch_design. - "phone input", "phone field", "international phone", "country code input", "+1 (555) ...", "电话号码", "手机号输入", "国际电话" →
add_phone_input_v1(theme: 'system' default; passcountry_flagfor emoji prefix). For a plain single-line text input without the country prefix, useadd_form_field_v1. - "newsletter signup", "subscribe form", "subscribe to newsletter", "promo code input", "apply discount", "send message input", "chat composer", "search with submit", "订阅", "应用优惠码", "发送消息" →
add_input_with_action_v1(theme: 'system' default; action_kind="text" for "Subscribe" pill button, action_kind="icon" for chat send arrow). - "cookie banner", "cookie consent", "GDPR banner", "CCPA banner", "privacy notice", "cookie disclosure", "cookie 提示", "隐私同意条" →
add_cookie_banner_v1(theme: 'system' default; setshow_settings_link: truefor fine-grained GDPR consent UX). Caller positions sticky-bottom; the tool emits the banner card itself. - "sidebar", "side nav", "sidebar nav", "left rail", "dashboard nav rail", "admin sidebar", "settings sidebar", "docs sidebar", "vertical nav", "侧边栏", "侧边导航", "左侧导航" →
add_sidebar_nav_v1(theme: 'system' default; passtitlefor a brand row above the items, mark current page withactive: trueon the item). - "stacked avatars", "avatar group", "avatar stack", "team avatars", "5 contributors", "online users", "+N more", "viewers row", "presence indicator", "成员头像", "团队头像", "在线用户", "头像组" →
add_avatar_group_v1(theme: 'system' default; renders up tomax_visibleringed avatar circles + a "+N" overflow tile). - "data table row", "table row", "table header row", "customer row", "order row", "report row", "transaction row", "users table", "数据表行", "表格行", "表头行" →
add_data_table_row_v1(theme: 'system' default; passheader: truefor the column-header row,selected: trueto tint a hover/selected body row). For row separators stackadd_divider_v1between rows. - "filter chip", "filter tag", "applied filter", "selected criterion", "category pill", "removable tag", "Status: Active ×", "可移除标签", "筛选标签" →
add_tag_v1(theme: 'system' default; single chip with optional × close icon, default removable=true; passtonefor accent / success / warning / error palettes). - "user card", "contact card", "people picker row", "user mini card", "用户卡片", "联系人卡片" →
add_user_card_v1(theme: 'system' default; compact fit_content tile, no trailing slot — used in lobbies / chip-style lists). - "members list", "team page row", "people row", "sharing dialog row", "user list with role", "team member row", "团队成员", "成员列表行" →
add_member_row_v1(theme: 'system' default; avatar + name + optional subtitle + trailing role badge / kebab menu / status dot). - "profile header", "profile hero", "about me block", "account header", "user profile page", "个人主页头部" →
add_profile_header_v1(theme: 'system' default; large centered avatar + display name + optional handle / bio). - "notification row", "notification item", "notification list cell", "通知行", "通知条目" →
add_notification_row_v1(theme: 'system' default) - "KPI cell", "trend metric", "metric comparison", "delta metric", "KPI 趋势", "趋势指标" →
add_metric_comparison_v1(theme: 'system' default) - "drawer", "side panel", "slide-in panel", "edit drawer", "detail panel", "抽屉", "侧滑面板" →
add_drawer_shell_v1(theme: 'system' default; full-height drawer with title + close ×; body composed via subsequent calls under its id). - "combobox", "autocomplete", "open dropdown", "command palette", "open select", "search with results", "自动补全", "下拉补全" →
add_combobox_v1(theme: 'system' default; OPEN-state input + dropdown with N suggestion rows; one row optionallyhighlighted: true). - "toolbar", "editor toolbar", "formatting toolbar", "kanban actions", "icon button row", "工具栏" →
add_toolbar_v1(theme: 'system' default; horizontal 36×36 icon buttons + optional vertical dividers). - "callout", "tip block", "doc note", "did you know", "info box", "提示框", "信息块" →
add_callout_v1(theme: 'system' default; tinted block with body + optional title + tone-driven leading icon: info / success / warning / danger / note). - "inline action", "Undo button inline", "Saved • Retry", "comment deleted undo", "inline feedback", "inline action row" →
add_inline_action_v1(theme: 'system' default; left message + right blue action label, NO floating). - "share row", "share to social", "share buttons", "post share", "send via", "分享按钮组" →
add_share_row_v1(theme: 'system' default; horizontal circular icon buttons each labeled below). - "chart legend", "legend item", "legend entry", "数据图例", "图例条目" →
add_legend_item_v1(theme: 'system' default) - "inbox row", "email row", "message list cell", "mail item", "email preview", "邮件条目", "收件箱条目" →
add_inbox_message_v1(theme: 'system' default) - "settings row", "preference row", "menu item with toggle", "settings list item", "设置项", "偏好项", "开关行" →
add_setting_row_v1(theme: 'system' default; icon + title/subtitle + trailing chevron/value/switch/badge). - "facet panel", "filter sidebar", "category checklist", "brand filter", "applied filters group", "搜索筛选侧栏", "分面筛选", "类目筛选" →
add_filter_group_v1(theme: 'system' default; heading + vertical checkbox-style option list with optional counts). - "pending invite", "invitation row", "team invite", "邀请列表行", "待接受邀请", "invitations table row" →
add_invite_row_v1(theme: 'system' default; initial avatar + email/role + status pill + trailing action). - "audit log row", "activity feed entry", "recent activity item", "audit entry", "审计日志条目", "活动记录", "操作日志行" →
add_activity_log_v1(theme: 'system' default; single line: optional tinted icon dot + " " + right-aligned timestamp). - "event card", "agenda item", "meeting tile", "upcoming event", "calendar event row", "日程卡片", "会议条目", "活动卡片" →
add_event_card_v1(theme: 'system' default; date column with month band + day number, then title + time + location). - "onboarding step", "how-it-works step", "tutorial step card", "setup checklist item", "操作步骤卡片", "教程步骤", "新手引导步骤" →
add_step_card_v1(theme: 'system' default; numbered circle / check + title + description, stacks vertically).
STILL use batch_design when (emit a SINGLE batch_design for the whole response — do NOT mix with element-tool calls):
- The brief's items are structurally heterogeneous (can't be uniformly described by a single items[] shape)
- The brief needs a custom container or layout that no element tool covers (e.g. a horizontal row of pricing cards with a specific gap, a scroll row + sibling content)
- The brief asks for unusual styling (custom fills, typography, theme variables) on top of a known structure
Common compositions (cookbook)
When the user asks for a recognizable screen pattern (login, signup, settings, paywall, dashboard tile row, support chat), STACK existing element tools under one parent rather than reaching for batch_design. The recipes below are by-frequency-of-real-use; each one fits in 4-7 tool calls.
Login screen (phone + password + social)
add_heading_v1({ parent_id: "<page>", content: "Welcome back", theme: "system" })
add_body_text_v1({ parent_id: "<page>", content: "Sign in to continue", theme: "system" })
add_phone_input_v1({ parent_id: "<page>", label: "Phone number", country_code: "+1", country_flag: "🇺🇸", required: true, theme: "system" })
add_form_field_v1({ parent_id: "<page>", label: "Password", required: true, theme: "system" })
add_text_button_v1({ parent_id: "<page>", label: "Sign in", theme: "system" })
add_link_v1({ parent_id: "<page>", label: "Forgot password?", theme: "system" })
add_divider_v1({ parent_id: "<page>", theme: "system" })
add_social_login_row_v1({ parent_id: "<page>", providers: [{ name: "Google" }, { name: "Apple" }], theme: "system" })
Signup form (email + password + agreement)
add_heading_v1({ parent_id: "<form>", content: "Create your account", theme: "system" })
add_form_field_v1({ parent_id: "<form>", label: "Email", required: true, theme: "system" })
add_form_field_v1({ parent_id: "<form>", label: "Password", required: true, theme: "system" })
add_form_field_v1({ parent_id: "<form>", label: "Confirm password", required: true, theme: "system" })
add_checkbox_v1({ parent_id: "<form>", label: "I agree to the Terms of Service", checked: false, theme: "system" })
add_text_button_v1({ parent_id: "<form>", label: "Sign up", theme: "system" })
Settings page (groups of setting rows)
add_section_header_v1({ parent_id: "<page>", title: "Account", theme: "system" })
add_setting_row_v1({ parent_id: "<page>", title: "Profile", leading_icon: "user", theme: "system" })
add_setting_row_v1({ parent_id: "<page>", title: "Email", leading_icon: "mail", trailing: { kind: "value", value: "you@acme.com" }, theme: "system" })
add_divider_v1({ parent_id: "<page>", theme: "system" })
add_section_header_v1({ parent_id: "<page>", title: "Notifications", theme: "system" })
add_setting_row_v1({ parent_id: "<page>", title: "Push notifications", leading_icon: "bell", trailing: { kind: "switch", on: true }, theme: "system" })
add_setting_row_v1({ parent_id: "<page>", title: "Email digest", leading_icon: "mail", trailing: { kind: "switch", on: false }, theme: "system" })
Team / members list (avatars + pending invitations)
add_section_header_v1({ parent_id: "<page>", title: "Members", theme: "system" })
add_body_text_v1({ parent_id: "<page>", content: "5 people", theme: "system" })
add_member_row_v1({ parent_id: "<page>", name: "Sarah Lee", subtitle: "sarah@acme.com", initial: "S", trailing: { kind: "role_badge", value: "Owner" }, theme: "system" })
add_member_row_v1({ parent_id: "<page>", name: "Marcus Chen", subtitle: "marcus@acme.com", initial: "M", trailing: { kind: "role_badge", value: "Admin" }, theme: "system" })
add_member_row_v1({ parent_id: "<page>", name: "Aiko Tanaka", subtitle: "aiko@acme.com", initial: "A", trailing: { kind: "role_badge", value: "Editor" }, theme: "system" })
add_member_row_v1({ parent_id: "<page>", name: "Raj Patel", subtitle: "raj@acme.com", initial: "R", trailing: { kind: "role_badge", value: "Editor" }, theme: "system" })
add_member_row_v1({ parent_id: "<page>", name: "Jordan Kim", subtitle: "jordan@acme.com", initial: "J", trailing: { kind: "role_badge", value: "Viewer" }, theme: "system" })
add_divider_v1({ parent_id: "<page>", theme: "system" })
add_section_header_v1({ parent_id: "<page>", title: "Pending invitations", theme: "system" })
add_invite_row_v1({ parent_id: "<page>", email: "leon@acme.com", role: "Editor", status: "pending", action_label: "Resend", theme: "system" })
Audit / activity feed (N log entries under a header)
add_section_header_v1({ parent_id: "<panel>", title: "Recent activity", theme: "system" })
add_body_text_v1({ parent_id: "<panel>", content: "Last 24 hours", theme: "system" })
add_activity_log_v1({ parent_id: "<panel>", actor: "Sarah Lee", action: "approved the production deploy", timestamp: "2h ago", icon: "check", tone: "success", theme: "system" })
add_activity_log_v1({ parent_id: "<panel>", actor: "Marcus Chen", action: "uploaded final-mockups.zip", timestamp: "3h ago", icon: "upload", tone: "info", theme: "system" })
add_activity_log_v1({ parent_id: "<panel>", actor: "Aiko Tanaka", action: "invited jordan@acme.com to the workspace", timestamp: "5h ago", icon: "user-plus", tone: "info", theme: "system" })
add_activity_log_v1({ parent_id: "<panel>", actor: "System", action: "rate-limited an IP after 50 failed sign-ins", timestamp: "8h ago", icon: "alert-triangle", tone: "warning", theme: "system" })
add_activity_log_v1({ parent_id: "<panel>", actor: "Raj Patel", action: "updated billing details", timestamp: "yesterday", icon: "settings", tone: "neutral", theme: "system" })
add_activity_log_v1({ parent_id: "<panel>", actor: "Sarah Lee", action: "deleted archive-2024.zip", timestamp: "yesterday", icon: "trash", tone: "danger", theme: "system" })
Faceted search filter sidebar (N filter groups stacked)
add_filter_group_v1({ parent_id: "<sidebar>", title: "Category", options: [{ label: "Apparel", count: 124, selected: true }, { label: "Footwear", count: 86 }, { label: "Bags", count: 41 }, { label: "Accessories", count: 67 }], theme: "system" })
add_filter_group_v1({ parent_id: "<sidebar>", title: "Brand", options: [{ label: "Nike", count: 32 }, { label: "Adidas", count: 28 }, { label: "Patagonia", count: 15, selected: true }, { label: "Arc'teryx", count: 9 }], theme: "system" })
Onboarding "How it works" (N step cards)
add_heading_v1({ parent_id: "<page>", content: "Get started in minutes", theme: "system" })
add_body_text_v1({ parent_id: "<page>", content: "Three steps to a smarter wallet.", theme: "system" })
add_step_card_v1({ parent_id: "<page>", number: 1, title: "Create your account", description: "Use your email and a strong password to sign up. No credit card required.", theme: "system" })
add_step_card_v1({ parent_id: "<page>", number: 2, title: "Connect your bank", description: "Link your account in seconds. We use 256-bit encryption to keep your data safe.", theme: "system" })
add_step_card_v1({ parent_id: "<page>", number: 3, title: "Set your goals", description: "Tell us what you want to save for — we'll do the rest.", theme: "system" })
add_step_card_v1({ parent_id: "<page>", number: 4, title: "You're all set", description: "You're ready to use the app. Tap below to continue.", completed: true, theme: "system" })
Pricing section (3 tiers, middle one featured)
add_pricing_card_v1({ parent_id: "<page>", tier: "Starter", price: "0", period: "/month", features: ["3 projects", "Community support"], theme: "system" })
add_pricing_card_v1({ parent_id: "<page>", tier: "Pro", price: "29", period: "/month", features: ["Unlimited projects", "Priority support", "Advanced analytics"], emphasis: "featured", theme: "system" })
add_pricing_card_v1({ parent_id: "<page>", tier: "Enterprise", price: "Custom", features: ["Dedicated support", "SSO", "SLA"], cta: "Contact sales", theme: "system" })
Dashboard KPI strip (4 stat cards)
add_stat_card_v1({ parent_id: "<page>", label: "Revenue", value: "$12.4k", icon: "trending-up", delta: "+8%", trend: "up", theme: "system" })
add_stat_card_v1({ parent_id: "<page>", label: "Active users", value: "1,284", icon: "users", delta: "+3%", trend: "up", theme: "system" })
add_stat_card_v1({ parent_id: "<page>", label: "Churn", value: "3.2%", icon: "user-minus", delta: "-0.4%", trend: "down", theme: "system" })
add_stat_card_v1({ parent_id: "<page>", label: "Sessions", value: "5,471", icon: "activity", theme: "system" })
OTP / 2FA verification screen
add_heading_v1({ parent_id: "<page>", content: "Enter verification code", theme: "system" })
add_body_text_v1({ parent_id: "<page>", content: "We sent a 6-digit code to +1 (555) 123-4567", theme: "system" })
add_otp_input_v1({ parent_id: "<page>", length: 6, digits: ["1", "2", "3"], focused_index: 3, theme: "system" })
add_text_button_v1({ parent_id: "<page>", label: "Verify", theme: "system" })
add_link_v1({ parent_id: "<page>", label: "Resend code", theme: "system" })
Support chat thread
add_chat_bubble_v1({ parent_id: "<thread>", message: "Hi! How can I help today?", side: "left", author: "Sarah", timestamp: "Just now", theme: "system" })
add_chat_bubble_v1({ parent_id: "<thread>", message: "My order hasn't arrived.", side: "right", timestamp: "2m", theme: "system" })
add_chat_bubble_v1({ parent_id: "<thread>", message: "Sorry to hear! Let me check on that.", side: "left", author: "Sarah", timestamp: "1m", theme: "system" })
add_attachment_row_v1({ parent_id: "<thread>", filename: "receipt.pdf", size: "240 KB", icon: "file-text", theme: "system" })
Empty inbox / first-run onboarding
add_empty_state_v1({ parent_id: "<page>", title: "No messages yet", subtitle: "When someone messages you, it'll show up here.", icon: "inbox", cta_label: "Find friends", theme: "system" })
Composition rules of thumb
- One parent for one row of siblings. Don't pass
parent_idof an unrelated container. - Order matters. Tools insert as the LAST child of
parent_id, so call sequence is render order top-to-bottom (vertical) or left-to-right (horizontal). - Don't mix element tools and
batch_designin the same output. Pick one strategy: chainadd_*_v1calls (preferred when every component fits an element tool) OR a singlebatch_designcovering the whole brief (when at least one component needs a custom shape). The corpus harness dropsbatch_designtags whenever element-tool calls share the response, so a mixed output silently loses its scaffolding.
Invariants you don't need to think about
The tool guarantees — you cannot break them from the input side:
- Wrapper structure (
scroll-row-wrapper+scroll-row+ fixed-width children) for row tools — overflow-safe bottom-tab-baris inline (no empty spacer sibling needed, do NOT add one)- Activity ring is frame+cornerRadius=size/2+stroke+centered text — NEVER emit ellipse+sibling text for rings
- Every emitted node has a unique id (you can reference it later)
- Roles are set (
card/metric-tile/nav-chip/nav-chip-active/bottom-tab-bar/nav-item/nav-item-active/activity-ring/stat-grid/stat-cell/section-header/section-header-title/section-header-action/top-nav-bar/nav-spacer/icon-button/divider/badge/avatar/button/heading/body/label/icon-label/list-row/list-row-text/search-bar/form-field/form-input/switch/switch-thumb/checkbox/checkbox-checked/checkbox-row/radio/radio-selected/radio-row/radio-dot/tabs/tab/tab-active/tab-underline/segmented-control/segment/segment-active/empty-state/empty-state-icon/empty-state-title/empty-state-subtitle/alert/alert-message/alert-close/toast/toast-message/progress-bar/progress-bar-fill/fab/breadcrumb/breadcrumb-item/breadcrumb-item-active/breadcrumb-separator/stepper/step/step-active/step-connector/step-connector-active/rating-stars/star-filled/star-empty/link/link-label/link-icon/kbd/kbd-key/kbd-glyph/kbd-separator/carousel-dots/dot/dot-active/price/price-currency/price-amount/price-period/quote-block/quote-text/quote-author/code-block/code/color-swatch/color-swatch-square/color-swatch-label/chart-bars/chart-bar/timeline/timeline-item/timeline-icon-column/timeline-dot/timeline-dot-active/timeline-connector/timeline-content/timeline-title/timeline-subtitle/calendar-grid/calendar-header-row/calendar-header/calendar-week/calendar-day/calendar-day-today/calendar-day-selected/calendar-day-empty)
Failure mode
If the tool throws, do NOT retry with the same arguments — the tool has already verified the failure is real (pre-check rejected the parent_id, or post-check detected a silent DSL no-op). Re-throwing from your side wastes tokens. Inspect the error message and either:
- Fix
parent_id(ensure the referenced node exists and has no"or\in its id) - Switch to
batch_designwith the structure taught inoverflow.md/layout.md