Generate and render a pixel-precise ASCII TUI Front UI Framework component with complete output blocks (TUI_RENDER, COMPONENT_SPEC, PENCIL_SPEC, PENCIL_BATCH_DESIGN) for Pencil MCP drawing workflows. Use when the user asks to create a front UI in a terminal UI, text-based interface, or Pencil MCP project.
Produce TUI designs that are accurate enough to be treated like product design artifacts:
batch_design operations (chunked to ≤25 ops).For any request, output these blocks in this order:
...monospace-only text...
{
"id": "cmp_x",
"name": "ComponentName",
"type": "tui-component",
"bbox": { "topPx": 0, "leftPx": 0, "widthPx": 0, "heightPx": 0 },
"zIndex": 0,
"layout": { "paddingPx": 0, "gapPx": 0, "align": "left", "valign": "top" },
"style": {
"fillColor": "#ffffff",
"textColor": "#111111",
"strokeColor": "#dddddd",
"strokeThickness": 1,
"cornerRadius": 8,
"opacity": 1
},
"typography": { "fontFamily": "Inter", "fontSize": 14, "fontWeight": 400, "lineHeight": 20 },
"overflow": { "mode": "truncate", "ellipsis": "…", "maxLines": 1 },
"state": { "focused": false, "disabled": false, "loading": false, "error": null },
"hotkeys": []
}
{
"canvas": { "widthPx": 390, "heightPx": 844, "backgroundColor": "#ffffff" },
"grid": { "cellWidthPx": 8, "cellHeightPx": 16 },
"nodes": [],
"components": []
}
CALL 1:
root=G()
screen=I(root,{type:"frame",name:"Screen"})
U(screen,{width:390,height:844,x:0,y:0})
CALL 2:
...up to 25 ops...
grid.cellWidthPx = 8grid.cellHeightPx = 16leftPx = col * cellWidthPxtopPx = row * cellHeightPxwidthPx = cols * cellWidthPxheightPx = rows * cellHeightPxpageWidthCols.truncate: cut and append …wrap: break lines and keep indentationclip: cut without … (avoid unless required)┌ ┐ └ ┘─ │├ ┤ ┬ ┴ ┼[Title] + state tags (e.g., Disabled, Loading)Keys: ...noColor switch and honor NO_COLOR=1 as a hard disable.COMPONENT_SPEC and PENCIL_SPEC, always represent colors as hex.<up>/<down>/<left>/<right><enter><esc><tab>get_editor_state(include_schema=false) to find the active .pen file and selection.open_document("new").batch_design(filePath, operations) to apply PENCIL_BATCH_DESIGN.
snapshot_layout(filePath, maxDepth=2, problemsOnly=true).get_screenshot(filePath, nodeId) for the page frame.Important: the exact positioning property names may differ by schema (e.g. x/y vs left/top). If unknown, retrieve guidelines first (e.g., get_guidelines(topic="design-system")) and adapt the update keys in U(...) accordingly.
┌──────────────────────────────────────────────────────────────┐
│ [Card] │
├──────────────────────────────────────────────────────────────┤
│ Title: Account Overview │
│ Balance: $2,340.18 │
│ Status: Active │
└──────────────────────────────────────────────────────────────┘
{
"id": "cmp_card_1",
"name": "Card",
"type": "tui-card",
"bbox": { "topPx": 48, "leftPx": 24, "widthPx": 342, "heightPx": 160 },
"zIndex": 1,
"layout": { "paddingPx": 16, "gapPx": 8, "align": "left", "valign": "top" },
"style": {
"fillColor": "#ffffff",
"textColor": "#111111",
"strokeColor": "#e5e7eb",
"strokeThickness": 1,
"cornerRadius": 12,
"opacity": 1
},
"typography": { "fontFamily": "Inter", "fontSize": 14, "fontWeight": 400, "lineHeight": 20 },
"overflow": { "mode": "wrap", "ellipsis": "…", "maxLines": 4 },
"state": { "focused": false, "disabled": false, "loading": false, "error": null },
"hotkeys": []
}
{
"canvas": { "widthPx": 390, "heightPx": 844, "backgroundColor": "#ffffff" },
"grid": { "cellWidthPx": 8, "cellHeightPx": 16 },
"nodes": [
{
"id": "node_screen",
"type": "frame",
"name": "Screen",
"topPx": 0,
"leftPx": 0,
"widthPx": 390,
"heightPx": 844,
"style": { "fillColor": "#ffffff" },
"children": ["node_card_bg", "node_card_title", "node_card_body"]
},
{
"id": "node_card_bg",
"type": "rect",
"name": "Card/Background",
"topPx": 48,
"leftPx": 24,
"widthPx": 342,
"heightPx": 160,
"style": { "fillColor": "#ffffff", "strokeColor": "#e5e7eb", "strokeThickness": 1, "cornerRadius": 12 }
},
{
"id": "node_card_title",
"type": "text",
"name": "Card/Title",
"topPx": 64,
"leftPx": 40,
"widthPx": 310,
"heightPx": 24,
"text": "Account Overview",
"style": { "textColor": "#111111" },
"typography": { "fontFamily": "Inter", "fontSize": 16, "fontWeight": 600, "lineHeight": 24 }
},
{
"id": "node_card_body",
"type": "text",
"name": "Card/Body",
"topPx": 96,
"leftPx": 40,
"widthPx": 310,
"heightPx": 96,
"text": "Balance: $2,340.18\nStatus: Active",
"style": { "textColor": "#111111" },
"typography": { "fontFamily": "Inter", "fontSize": 14, "fontWeight": 400, "lineHeight": 20 }
}
],
"components": [
{
"id": "cmp_card_1",
"name": "Card",
"bbox": { "topPx": 48, "leftPx": 24, "widthPx": 342, "heightPx": 160 },
"zIndex": 1
}
]
}
CALL 1:
root=G()
screen=I(root,{type:"frame",name:"Screen"})
U(screen,{width:390,height:844,x:0,y:0})
CALL 2:
cardBg=I(screen,{type:"rect",name:"Card/Background"})
U(cardBg,{x:24,y:48,width:342,height:160,fillColor:"#ffffff",strokeColor:"#e5e7eb",strokeThickness:1,cornerRadius:12})
cardTitle=I(screen,{type:"text",name:"Card/Title",content:"Account Overview"})
U(cardTitle,{x:40,y:64,width:310,height:24,textColor:"#111111",fontFamily:"Inter",fontSize:16,fontWeight:600})
cardBody=I(screen,{type:"text",name:"Card/Body",content:"Balance: $2,340.18\\nStatus: Active"})
U(cardBody,{x:40,y:96,width:310,height:96,textColor:"#111111",fontFamily:"Inter",fontSize:14,fontWeight:400})
┌──────────────────────────────────────────────────────────────┐
│ [Input] │
├──────────────────────────────────────────────────────────────┤
│ Email ! │
│ [ [email protected]______________________________ ] │
│ Error: Please enter a valid email │
└──────────────────────────────────────────────────────────────┘
{
"id": "cmp_input_email",
"name": "Input",
"type": "tui-input",
"bbox": { "topPx": 240, "leftPx": 24, "widthPx": 342, "heightPx": 132 },
"zIndex": 2,
"layout": { "paddingPx": 16, "gapPx": 8, "align": "left", "valign": "top" },
"style": {
"fillColor": "#ffffff",
"textColor": "#111111",
"strokeColor": "#ef4444",
"strokeThickness": 1,
"cornerRadius": 12,
"opacity": 1
},
"typography": { "fontFamily": "Inter", "fontSize": 14, "fontWeight": 400, "lineHeight": 20 },
"overflow": { "mode": "truncate", "ellipsis": "…", "maxLines": 1 },
"state": { "focused": true, "disabled": false, "loading": false, "error": "Please enter a valid email" },
"hotkeys": ["<tab>", "<enter>", "<esc>"]
}
{
"canvas": { "widthPx": 390, "heightPx": 844, "backgroundColor": "#ffffff" },
"grid": { "cellWidthPx": 8, "cellHeightPx": 16 },
"nodes": [],
"components": [
{
"id": "cmp_input_email",
"name": "Input",
"bbox": { "topPx": 240, "leftPx": 24, "widthPx": 342, "heightPx": 132 },
"zIndex": 2
}
]
}
CALL 1:
root=G()
screen=I(root,{type:"frame",name:"Screen"})
U(screen,{width:390,height:844,x:0,y:0})
CALL 2:
field=I(screen,{type:"rect",name:"Input/Field"})
U(field,{x:24,y:240,width:342,height:132,fillColor:"#ffffff",strokeColor:"#ef4444",strokeThickness:1,cornerRadius:12})
label=I(screen,{type:"text",name:"Input/Label",content:"Email"})
U(label,{x:40,y:256,width:310,height:20,textColor:"#111111",fontFamily:"Inter",fontSize:14,fontWeight:600})
value=I(screen,{type:"text",name:"Input/Value",content:"[email protected]"})
U(value,{x:40,y:284,width:310,height:20,textColor:"#111111",fontFamily:"Inter",fontSize:14,fontWeight:400})
err=I(screen,{type:"text",name:"Input/Error",content:"Error: Please enter a valid email"})
U(err,{x:40,y:312,width:310,height:20,textColor:"#ef4444",fontFamily:"Inter",fontSize:12,fontWeight:400})
┌──────────────────────────────────────────────────────────────┐
│ [Profile] │
├──────────────────────────────────────────────────────────────┤
│ Name: Ada Lovelace │
│ Role: Engineer │
├──────────────────────────────────────────────────────────────┤
│ [Rate] * * * * . (4/5) │
├──────────────────────────────────────────────────────────────┤
│ Keys: <tab> next <enter> edit <esc> back │
└──────────────────────────────────────────────────────────────┘
{
"id": "cmp_page_profile",
"name": "Page",
"type": "tui-page",
"bbox": { "topPx": 0, "leftPx": 0, "widthPx": 390, "heightPx": 844 },
"zIndex": 0,
"layout": { "paddingPx": 24, "gapPx": 16, "align": "left", "valign": "top" },
"style": { "fillColor": "#ffffff", "textColor": "#111111", "strokeColor": "#e5e7eb", "strokeThickness": 0, "cornerRadius": 0, "opacity": 1 },
"typography": { "fontFamily": "Inter", "fontSize": 14, "fontWeight": 400, "lineHeight": 20 },
"overflow": { "mode": "wrap", "ellipsis": "…", "maxLines": 0 },
"state": { "focused": false, "disabled": false, "loading": false, "error": null },
"hotkeys": ["<tab>", "<enter>", "<esc>"]
}
{
"canvas": { "widthPx": 390, "heightPx": 844, "backgroundColor": "#ffffff" },
"grid": { "cellWidthPx": 8, "cellHeightPx": 16 },
"nodes": [],
"components": [
{ "id": "cmp_profile_header", "name": "Header", "bbox": { "topPx": 24, "leftPx": 24, "widthPx": 342, "heightPx": 88 }, "zIndex": 1 },
{ "id": "cmp_rate_1", "name": "Rate", "bbox": { "topPx": 128, "leftPx": 24, "widthPx": 342, "heightPx": 64 }, "zIndex": 2 }
]
}
CALL 1:
root=G()
screen=I(root,{type:"frame",name:"Profile"})
U(screen,{width:390,height:844,x:0,y:0})
CALL 2:
headerBg=I(screen,{type:"rect",name:"Header/Background"})
U(headerBg,{x:24,y:24,width:342,height:88,fillColor:"#ffffff",strokeColor:"#e5e7eb",strokeThickness:1,cornerRadius:12})
name=I(screen,{type:"text",name:"Header/Name",content:"Name: Ada Lovelace"})
U(name,{x:40,y:40,width:310,height:20,textColor:"#111111",fontFamily:"Inter",fontSize:14,fontWeight:600})
role=I(screen,{type:"text",name:"Header/Role",content:"Role: Engineer"})
U(role,{x:40,y:64,width:310,height:20,textColor:"#111111",fontFamily:"Inter",fontSize:14,fontWeight:400})
rateBg=I(screen,{type:"rect",name:"Rate/Background"})
U(rateBg,{x:24,y:128,width:342,height:64,fillColor:"#ffffff",strokeColor:"#e5e7eb",strokeThickness:1,cornerRadius:12})
rateText=I(screen,{type:"text",name:"Rate/Text",content:"* * * * . (4/5)"})
U(rateText,{x:40,y:152,width:310,height:20,textColor:"#111111",fontFamily:"Inter",fontSize:14,fontWeight:400})