[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-deepgram-visual-feedback":3,"mdc-mf0n1z-key":32,"related-org-deepgram-visual-feedback":1163,"related-repo-deepgram-visual-feedback":1326},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":22,"repoUrl":23,"updatedAt":24,"license":25,"forks":26,"topics":27,"repo":28,"sourceUrl":30,"mdContent":31},"visual-feedback","display visual feedback in terminal","Use when you need to communicate with the human visually through the terminal. Examples: \"show a status panel\", \"display an overlay notification\", \"build a visual dashboard in the terminal\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"deepgram","Deepgram","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fdeepgram.png",[12,16,19],{"name":13,"slug":14,"type":15},"Dashboards","dashboards","tag",{"name":17,"slug":18,"type":15},"Visualization","visualization",{"name":20,"slug":21,"type":15},"UI Components","ui-components",5,"https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fwsh","2026-07-12T08:29:47.754069",null,2,[],{"repoUrl":23,"stars":22,"forks":26,"topics":29,"description":25},[],"https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fwsh\u002Ftree\u002FHEAD\u002Fskills\u002Fvisual-feedback","---\nname: visual-feedback\ndescription: >\n  Use when you need to communicate with the human visually through the terminal.\n  Examples: \"show a status panel\", \"display an overlay notification\",\n  \"build a visual dashboard in the terminal\".\n---\n\n> **IMPORTANT: EXECUTION CONTEXT**\n> This skill describes *what to do* — domain patterns and decision-making.\n> It does NOT describe *how* to call the API.\n>\n> 1. **If you have `wsh_*` tools** (check your toolkit for `wsh_send_input`,\n>    `wsh_get_screen`, etc.): use them directly. Operation names in this\n>    skill generally map to tool names (e.g., \"send input\" → `wsh_send_input`).\n>    When in doubt, list your available `wsh_*` tools.\n> 2. **If you do NOT have `wsh_*` tools**: you are in HTTP\u002Fcurl fallback mode.\n>    **DO NOT GUESS endpoints or CLI subcommands.**\n>    Load the full API reference first: search your workspace for\n>    `skills\u002Fcore\u002F` and read `SKILL.md`. It contains every endpoint\n>    with working curl examples and a bootstrap sequence.\n> 3. **Quick bootstrap**: `curl -sf --unix-socket ${XDG_RUNTIME_DIR:-\u002Ftmp}\u002Fwsh\u002Fdefault.http.sock http:\u002F\u002Flocalhost\u002Fhealth`\n>    — if that fails: `wsh server -L agent-$$ --ephemeral &` and retry.\n\n# wsh:visual-feedback — Communicating Visually\n\nYou can place text on the terminal screen to communicate\nwith the human. You have two tools: overlays and panels.\nChoosing the right one matters.\n\n## Overlays\n\nFloating text positioned at specific screen coordinates.\nThey sit on top of terminal content without affecting it.\n\n**Characteristics:**\n- Positioned at (x, y) — you choose exactly where\n- Can overlap terminal content and each other\n- Don't affect the PTY or its layout\n- Best for transient, contextual information\n- Can have explicit `width`, `height`, and `background`\n  making them opaque rectangles — not just floating text\n\n**Use for:** tooltips, warnings, quick tips, annotations,\nnotifications, contextual help near relevant output.\nWith explicit dimensions: windows, cards, dialogs,\nmodal panels — anything that needs a solid backdrop.\n\n## Panels\n\nDedicated screen regions at the top or bottom edge. They\n**shrink the PTY** — the terminal gets fewer rows, and\nprograms adapt to the reduced space.\n\n**Characteristics:**\n- Fixed to top or bottom\n- Have a height in rows\n- Carve out permanent space\n- Best for persistent information\n\n**Use for:** status bars, progress displays, context\nsummaries, dashboards, error explanations.\n\nPanels also support `background` fill, named spans with\n`id` fields for targeted updates, and region writes for\nplacing text at specific (row, col) offsets. These work\nthe same way as they do for overlays.\n\n## Choosing Between Them\n\nAsk two questions:\n\n1. **Is it tied to a screen position?** If the information\n   relates to a specific line or region of output, use an\n   overlay positioned near it. If it's ambient context,\n   use a panel.\n\n2. **How long should it live?** If it's relevant for a few\n   seconds or until the screen changes, use an overlay.\n   If it should persist across screen updates, use a panel.\n\n## Designing Effective Overlays\n\n### Positioning\nScreen coordinates are (x, y) where (0, 0) is the top-left\ncorner. x is the column, y is the row.\n\nPlace overlays near the content they relate to:\n- Error annotation → same row as the error, offset to the\n  right so it doesn't obscure the error text\n- Command hint → just below or above the command line\n- Notification → top-right corner, out of the way\n\nRead the screen dimensions from the screen response\n(`cols`, `rows`) to avoid placing overlays off-screen.\n\n### Sizing\nKeep overlay text short. One to three lines, under half\nthe screen width. If you need more space, use a panel or\nthe conversation instead.\n\nOverlays with explicit `width` and `height` create an\nopaque bounding box. The `background` color fills the\nentire rectangle, and spans and region writes render on\ntop of it. This turns overlays into window-like elements\nwith solid backgrounds — useful for dialogs, cards, and\nany UI that needs to cleanly cover terminal content.\n\n### Styling\nSpans support formatting attributes. Use them for\nvisual hierarchy:\n\n    {\"spans\": [\n      {\"text\": \"Warning: \", \"bold\": true, \"fg\": \"yellow\"},\n      {\"text\": \"this deletes 47 files\"}\n    ]}\n\n- **Bold** for labels, keywords, emphasis\n- **Color** for severity (red = danger, yellow = warning,\n  green = success, cyan = informational)\n- **Faint\u002Fdim** for secondary information\n\nUse the indexed color palette (0-7 for standard, 8-15 for\nbright) for broad terminal compatibility. Use RGB colors\nonly when you're confident the terminal supports them.\n\n### Named Spans\nSpans can have an `id` field. This lets you update a\nsingle span by its id instead of replacing all content\nin the overlay or panel.\n\n    {\"spans\": [\n      {\"id\": \"label\", \"text\": \"Status: \", \"bold\": true},\n      {\"id\": \"value\", \"text\": \"building\", \"fg\": \"yellow\"}\n    ]}\n\nLater, update just the \"value\" span:\n\n    update span \"value\" → {\"text\": \"complete\", \"fg\": \"green\"}\n\nThe \"label\" span stays untouched. This is good for:\n- Live-updating status fields that change frequently\n- Counters, timestamps, or progress percentages\n- Labels that change independently of surrounding text\n- Any element where you want to avoid redrawing\n  everything just to change one piece\n\n### Region Writes\nWrite styled text at specific (row, col) offsets within\nan overlay or panel. This turns them into 2D drawable\nsurfaces — not just a flat list of spans, but a canvas\nwhere you can place text at exact coordinates.\n\n    overlay (width: 40, height: 5, background: dark):\n\n    write at (0, 1):  \"Name\"     bold\n    write at (0, 15): \"Status\"   bold\n    write at (1, 1):  \"auth\"\n    write at (1, 15): \"● ok\"     green\n    write at (2, 1):  \"api\"\n    write at (2, 15): \"● slow\"   yellow\n\nRegion writes are good for:\n- Tables with aligned columns\n- Grids and structured layouts\n- Charts and diagrams\n- Any content where relative positioning matters\n\nRegion writes and spans coexist. Spans flow as inline\ncontent; region writes place content at absolute\npositions within the element. Use whichever model fits\nthe content.\n\n### Z-Order\nWhen overlays overlap, higher `z` values render on top.\nDefault is 0. Use z-order to layer related elements:\n\n    background context:  z=0\n    primary information:  z=1\n    urgent alert:         z=2\n\n### Lifecycle\nOverlays don't disappear on their own. You must manage them:\n- Store the ID returned on creation\n- Update content when information changes\n- Delete individual overlays when no longer relevant\n- Clear all overlays when cleaning up entirely\n\n## Designing Effective Panels\n\n### Layout\nPanels are rows of styled text at the top or bottom of the\nterminal. A 2-line panel at the bottom makes a natural\nstatus bar. A 3-line panel at the top works for context\nsummaries.\n\n    create panel (bottom, height: 2):\n      spans: [\n        {text: \" Status: \", bold},\n        {text: \"building\", fg: yellow},\n        {text: \"  |  \"},\n        {text: \"Branch: \", bold},\n        {text: \"feature\u002Fauth\"}\n      ]\n\n### Updating In Place\nPanels persist. When information changes, update the\nexisting panel rather than deleting and recreating.\nUse the panel's ID (returned on creation) to update\nits content in place.\n\nThis prevents flicker and keeps the panel stable.\n\n### Height Budget\nEvery row of panel height is a row stolen from the\nterminal. Be miserly:\n- 1 line for simple status\n- 2 lines for status + detail\n- 3 lines maximum in most cases\n\nOn a 24-row terminal, a 3-line panel costs 12% of the\nvisible area. Respect the human's screen space.\n\n## Visual Structure: Borders and Padding\n\nwsh renders your spans as-is. There are no built-in\nborders, padding, margins, or separators. If you want\nvisual structure, you build it from text characters.\n\n### Borders\nUse box-drawing characters for framed overlays:\n\n    {\"spans\": [\n      {\"text\": \"┌─ Warning ────────────┐\\n\"},\n      {\"text\": \"│ This will delete the │\\n\"},\n      {\"text\": \"│ entire build cache.  │\\n\"},\n      {\"text\": \"└──────────────────────┘\"}\n    ]}\n\n### Padding\nAdd spaces for breathing room:\n\n    {\"text\": \"  Status: running  \"}\n              ^^              ^^  padding\n\n### Separators\nUse `│` or `|` between inline elements:\n\n    {\"spans\": [\n      {\"text\": \" build: \"},\n      {\"text\": \"ok\", \"fg\": \"green\"},\n      {\"text\": \" │ tests: \"},\n      {\"text\": \"3 failed\", \"fg\": \"red\"},\n      {\"text\": \" │ lint: \"},\n      {\"text\": \"clean\", \"fg\": \"green\"},\n      {\"text\": \" \"}\n    ]}\n\n### Panel Separators\nA panel has no visible border separating it from the\nterminal content. Add your own with a full-width line:\n\n    {\"text\": \"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n\"}\n\nRead the terminal's `cols` value to size separators\nto the full width.\n\n## Composition Patterns\n\nIndividual overlays and panels are building blocks.\nCombining them creates richer experiences.\n\n### Status Bar + Contextual Annotations\nA persistent panel tracks overall state. Overlays\nprovide momentary context:\n\n    panel (bottom, 1 line):\n      \" ● monitoring  │  12 commands  │  2 errors \"\n\n    overlay (near error on row 15):\n      \"┌─ Suggestion ──────────────────┐\"\n      \"│ Try: cargo build --release    │\"\n      \"└───────────────────────────────┘\"\n\nThe panel stays. The overlay appears when relevant\nand disappears when the screen moves on.\n\n### Layered Overlays\nStack overlays with z-order for progressive detail.\nA compact label at z=0, expanded detail at z=1\nshown only when the human triggers it (via input\ncapture or a follow-up question):\n\n    z=0: \" ⚠ 3 warnings \"\n    z=1: \"┌─ Warnings ──────────────────┐\"\n         \"│ auth.rs:42  unused import   │\"\n         \"│ db.rs:17    deprecated call │\"\n         \"│ main.rs:3   dead code       │\"\n         \"└────────────────────────────-┘\"\n\n### Multi-Panel Dashboard\nUse top and bottom panels together. Top for context,\nbottom for status:\n\n    panel (top, 2 lines):\n      \"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\"\n      \" Project: wsh  Branch: master \"\n\n    panel (bottom, 1 line):\n      \" ● 3 sessions  │  build: ok  │  tests: running \"\n\nBe conservative. Two panels means the terminal loses\n3+ rows. Only use both when the information justifies it.\n\n### Temporary Overlays\nFor notifications that should appear briefly, create\nthe overlay and then delete it after a delay. You'll\nneed to manage the timing yourself:\n\n    create overlay → get id\n    (continue working)\n    after a few interaction cycles, delete the overlay\n\nThere's no built-in timer. The overlay lives until you\nremove it. Tie cleanup to your next interaction with\nthe terminal — when you next read the screen, check\nif any overlays are stale and remove them.\n\n## Pitfalls\n\n### Visual Clutter\nEvery overlay and panel competes for attention. If\neverything is highlighted, nothing is. Apply a strict\nbudget:\n- At most 1-2 panels active\n- At most 2-3 overlays visible simultaneously\n- If you need to show a new overlay and you're at your\n  limit, remove the least relevant one first\n\n### Stale Elements\nOverlays and panels don't expire. If you create an\noverlay saying \"build started\" and never remove it,\nit's still there 20 minutes later when the human has\nmoved on to something else entirely. Track what you've\ncreated and clean up proactively.\n\nKeep a mental inventory of your active visual elements.\nBefore creating a new one, ask: are any existing ones\nstale? Remove them first.\n\n### Overlapping Content\nAn overlay at (0, 5) that's 40 characters wide will\ncover whatever is on row 5. If that row contains\nimportant terminal output, you've hidden it. Strategies:\n- Position overlays at the right edge of the screen,\n  past where output typically ends\n- Use short overlays that don't span the full width\n- Prefer panels for information that shouldn't compete\n  with terminal content\n\n### Color Assumptions\nNot all terminals use the same color scheme. Indexed\ncolor 1 is \"red\" but the exact shade depends on the\nterminal's theme. More importantly, the terminal might\nhave a light or dark background. Don't rely on color\nalone to convey meaning — pair it with text labels\nor symbols:\n\n    Good:  {\"text\": \"✗ FAIL\", \"fg\": \"red\"}\n    Bad:   {\"text\": \"●\", \"fg\": \"red\"}\n\nThe word \"FAIL\" communicates even without color. A\nred dot is meaningless on a terminal where red is\nhard to see.\n\n### Coordinate Drift\nScreen content scrolls. An overlay pinned to row 10\nmade sense when the error was on row 10, but after\nthe human runs another command, row 10 is different\ncontent. Contextual overlays should be removed when\nthe screen changes significantly. Use the `epoch`\nfield in screen responses — if the epoch has changed\nsince you placed the overlay, re-evaluate whether it's\nstill positioned correctly.\n",{"data":33,"body":34},{"name":4,"description":6},{"type":35,"children":36},"root",[37,189,196,201,208,213,221,274,284,290,302,309,332,341,361,367,372,395,401,408,413,418,436,456,462,467,493,499,504,516,549,554,560,572,581,586,595,600,623,629,634,643,648,671,676,682,695,704,710,715,738,744,750,755,764,770,775,780,786,791,809,814,820,825,831,836,845,851,856,865,871,892,901,907,912,921,933,939,944,950,955,964,969,975,980,989,995,1000,1009,1014,1020,1025,1034,1039,1045,1051,1056,1074,1080,1085,1090,1096,1101,1119,1125,1130,1139,1144,1150],{"type":38,"tag":39,"props":40,"children":41},"element","blockquote",{},[42,70],{"type":38,"tag":43,"props":44,"children":45},"p",{},[46,53,55,61,63,68],{"type":38,"tag":47,"props":48,"children":49},"strong",{},[50],{"type":51,"value":52},"text","IMPORTANT: EXECUTION CONTEXT",{"type":51,"value":54},"\nThis skill describes ",{"type":38,"tag":56,"props":57,"children":58},"em",{},[59],{"type":51,"value":60},"what to do",{"type":51,"value":62}," — domain patterns and decision-making.\nIt does NOT describe ",{"type":38,"tag":56,"props":64,"children":65},{},[66],{"type":51,"value":67},"how",{"type":51,"value":69}," to call the API.",{"type":38,"tag":71,"props":72,"children":73},"ol",{},[74,124,163],{"type":38,"tag":75,"props":76,"children":77},"li",{},[78,92,94,100,102,108,110,115,117,122],{"type":38,"tag":47,"props":79,"children":80},{},[81,83,90],{"type":51,"value":82},"If you have ",{"type":38,"tag":84,"props":85,"children":87},"code",{"className":86},[],[88],{"type":51,"value":89},"wsh_*",{"type":51,"value":91}," tools",{"type":51,"value":93}," (check your toolkit for ",{"type":38,"tag":84,"props":95,"children":97},{"className":96},[],[98],{"type":51,"value":99},"wsh_send_input",{"type":51,"value":101},",\n",{"type":38,"tag":84,"props":103,"children":105},{"className":104},[],[106],{"type":51,"value":107},"wsh_get_screen",{"type":51,"value":109},", etc.): use them directly. Operation names in this\nskill generally map to tool names (e.g., \"send input\" → ",{"type":38,"tag":84,"props":111,"children":113},{"className":112},[],[114],{"type":51,"value":99},{"type":51,"value":116},").\nWhen in doubt, list your available ",{"type":38,"tag":84,"props":118,"children":120},{"className":119},[],[121],{"type":51,"value":89},{"type":51,"value":123}," tools.",{"type":38,"tag":75,"props":125,"children":126},{},[127,138,140,145,147,153,155,161],{"type":38,"tag":47,"props":128,"children":129},{},[130,132,137],{"type":51,"value":131},"If you do NOT have ",{"type":38,"tag":84,"props":133,"children":135},{"className":134},[],[136],{"type":51,"value":89},{"type":51,"value":91},{"type":51,"value":139},": you are in HTTP\u002Fcurl fallback mode.\n",{"type":38,"tag":47,"props":141,"children":142},{},[143],{"type":51,"value":144},"DO NOT GUESS endpoints or CLI subcommands.",{"type":51,"value":146},"\nLoad the full API reference first: search your workspace for\n",{"type":38,"tag":84,"props":148,"children":150},{"className":149},[],[151],{"type":51,"value":152},"skills\u002Fcore\u002F",{"type":51,"value":154}," and read ",{"type":38,"tag":84,"props":156,"children":158},{"className":157},[],[159],{"type":51,"value":160},"SKILL.md",{"type":51,"value":162},". It contains every endpoint\nwith working curl examples and a bootstrap sequence.",{"type":38,"tag":75,"props":164,"children":165},{},[166,171,173,179,181,187],{"type":38,"tag":47,"props":167,"children":168},{},[169],{"type":51,"value":170},"Quick bootstrap",{"type":51,"value":172},": ",{"type":38,"tag":84,"props":174,"children":176},{"className":175},[],[177],{"type":51,"value":178},"curl -sf --unix-socket ${XDG_RUNTIME_DIR:-\u002Ftmp}\u002Fwsh\u002Fdefault.http.sock http:\u002F\u002Flocalhost\u002Fhealth",{"type":51,"value":180},"\n— if that fails: ",{"type":38,"tag":84,"props":182,"children":184},{"className":183},[],[185],{"type":51,"value":186},"wsh server -L agent-$$ --ephemeral &",{"type":51,"value":188}," and retry.",{"type":38,"tag":190,"props":191,"children":193},"h1",{"id":192},"wshvisual-feedback-communicating-visually",[194],{"type":51,"value":195},"wsh:visual-feedback — Communicating Visually",{"type":38,"tag":43,"props":197,"children":198},{},[199],{"type":51,"value":200},"You can place text on the terminal screen to communicate\nwith the human. You have two tools: overlays and panels.\nChoosing the right one matters.",{"type":38,"tag":202,"props":203,"children":205},"h2",{"id":204},"overlays",[206],{"type":51,"value":207},"Overlays",{"type":38,"tag":43,"props":209,"children":210},{},[211],{"type":51,"value":212},"Floating text positioned at specific screen coordinates.\nThey sit on top of terminal content without affecting it.",{"type":38,"tag":43,"props":214,"children":215},{},[216],{"type":38,"tag":47,"props":217,"children":218},{},[219],{"type":51,"value":220},"Characteristics:",{"type":38,"tag":222,"props":223,"children":224},"ul",{},[225,230,235,240,245],{"type":38,"tag":75,"props":226,"children":227},{},[228],{"type":51,"value":229},"Positioned at (x, y) — you choose exactly where",{"type":38,"tag":75,"props":231,"children":232},{},[233],{"type":51,"value":234},"Can overlap terminal content and each other",{"type":38,"tag":75,"props":236,"children":237},{},[238],{"type":51,"value":239},"Don't affect the PTY or its layout",{"type":38,"tag":75,"props":241,"children":242},{},[243],{"type":51,"value":244},"Best for transient, contextual information",{"type":38,"tag":75,"props":246,"children":247},{},[248,250,256,258,264,266,272],{"type":51,"value":249},"Can have explicit ",{"type":38,"tag":84,"props":251,"children":253},{"className":252},[],[254],{"type":51,"value":255},"width",{"type":51,"value":257},", ",{"type":38,"tag":84,"props":259,"children":261},{"className":260},[],[262],{"type":51,"value":263},"height",{"type":51,"value":265},", and ",{"type":38,"tag":84,"props":267,"children":269},{"className":268},[],[270],{"type":51,"value":271},"background",{"type":51,"value":273},"\nmaking them opaque rectangles — not just floating text",{"type":38,"tag":43,"props":275,"children":276},{},[277,282],{"type":38,"tag":47,"props":278,"children":279},{},[280],{"type":51,"value":281},"Use for:",{"type":51,"value":283}," tooltips, warnings, quick tips, annotations,\nnotifications, contextual help near relevant output.\nWith explicit dimensions: windows, cards, dialogs,\nmodal panels — anything that needs a solid backdrop.",{"type":38,"tag":202,"props":285,"children":287},{"id":286},"panels",[288],{"type":51,"value":289},"Panels",{"type":38,"tag":43,"props":291,"children":292},{},[293,295,300],{"type":51,"value":294},"Dedicated screen regions at the top or bottom edge. They\n",{"type":38,"tag":47,"props":296,"children":297},{},[298],{"type":51,"value":299},"shrink the PTY",{"type":51,"value":301}," — the terminal gets fewer rows, and\nprograms adapt to the reduced space.",{"type":38,"tag":43,"props":303,"children":304},{},[305],{"type":38,"tag":47,"props":306,"children":307},{},[308],{"type":51,"value":220},{"type":38,"tag":222,"props":310,"children":311},{},[312,317,322,327],{"type":38,"tag":75,"props":313,"children":314},{},[315],{"type":51,"value":316},"Fixed to top or bottom",{"type":38,"tag":75,"props":318,"children":319},{},[320],{"type":51,"value":321},"Have a height in rows",{"type":38,"tag":75,"props":323,"children":324},{},[325],{"type":51,"value":326},"Carve out permanent space",{"type":38,"tag":75,"props":328,"children":329},{},[330],{"type":51,"value":331},"Best for persistent information",{"type":38,"tag":43,"props":333,"children":334},{},[335,339],{"type":38,"tag":47,"props":336,"children":337},{},[338],{"type":51,"value":281},{"type":51,"value":340}," status bars, progress displays, context\nsummaries, dashboards, error explanations.",{"type":38,"tag":43,"props":342,"children":343},{},[344,346,351,353,359],{"type":51,"value":345},"Panels also support ",{"type":38,"tag":84,"props":347,"children":349},{"className":348},[],[350],{"type":51,"value":271},{"type":51,"value":352}," fill, named spans with\n",{"type":38,"tag":84,"props":354,"children":356},{"className":355},[],[357],{"type":51,"value":358},"id",{"type":51,"value":360}," fields for targeted updates, and region writes for\nplacing text at specific (row, col) offsets. These work\nthe same way as they do for overlays.",{"type":38,"tag":202,"props":362,"children":364},{"id":363},"choosing-between-them",[365],{"type":51,"value":366},"Choosing Between Them",{"type":38,"tag":43,"props":368,"children":369},{},[370],{"type":51,"value":371},"Ask two questions:",{"type":38,"tag":71,"props":373,"children":374},{},[375,385],{"type":38,"tag":75,"props":376,"children":377},{},[378,383],{"type":38,"tag":47,"props":379,"children":380},{},[381],{"type":51,"value":382},"Is it tied to a screen position?",{"type":51,"value":384}," If the information\nrelates to a specific line or region of output, use an\noverlay positioned near it. If it's ambient context,\nuse a panel.",{"type":38,"tag":75,"props":386,"children":387},{},[388,393],{"type":38,"tag":47,"props":389,"children":390},{},[391],{"type":51,"value":392},"How long should it live?",{"type":51,"value":394}," If it's relevant for a few\nseconds or until the screen changes, use an overlay.\nIf it should persist across screen updates, use a panel.",{"type":38,"tag":202,"props":396,"children":398},{"id":397},"designing-effective-overlays",[399],{"type":51,"value":400},"Designing Effective Overlays",{"type":38,"tag":402,"props":403,"children":405},"h3",{"id":404},"positioning",[406],{"type":51,"value":407},"Positioning",{"type":38,"tag":43,"props":409,"children":410},{},[411],{"type":51,"value":412},"Screen coordinates are (x, y) where (0, 0) is the top-left\ncorner. x is the column, y is the row.",{"type":38,"tag":43,"props":414,"children":415},{},[416],{"type":51,"value":417},"Place overlays near the content they relate to:",{"type":38,"tag":222,"props":419,"children":420},{},[421,426,431],{"type":38,"tag":75,"props":422,"children":423},{},[424],{"type":51,"value":425},"Error annotation → same row as the error, offset to the\nright so it doesn't obscure the error text",{"type":38,"tag":75,"props":427,"children":428},{},[429],{"type":51,"value":430},"Command hint → just below or above the command line",{"type":38,"tag":75,"props":432,"children":433},{},[434],{"type":51,"value":435},"Notification → top-right corner, out of the way",{"type":38,"tag":43,"props":437,"children":438},{},[439,441,447,448,454],{"type":51,"value":440},"Read the screen dimensions from the screen response\n(",{"type":38,"tag":84,"props":442,"children":444},{"className":443},[],[445],{"type":51,"value":446},"cols",{"type":51,"value":257},{"type":38,"tag":84,"props":449,"children":451},{"className":450},[],[452],{"type":51,"value":453},"rows",{"type":51,"value":455},") to avoid placing overlays off-screen.",{"type":38,"tag":402,"props":457,"children":459},{"id":458},"sizing",[460],{"type":51,"value":461},"Sizing",{"type":38,"tag":43,"props":463,"children":464},{},[465],{"type":51,"value":466},"Keep overlay text short. One to three lines, under half\nthe screen width. If you need more space, use a panel or\nthe conversation instead.",{"type":38,"tag":43,"props":468,"children":469},{},[470,472,477,479,484,486,491],{"type":51,"value":471},"Overlays with explicit ",{"type":38,"tag":84,"props":473,"children":475},{"className":474},[],[476],{"type":51,"value":255},{"type":51,"value":478}," and ",{"type":38,"tag":84,"props":480,"children":482},{"className":481},[],[483],{"type":51,"value":263},{"type":51,"value":485}," create an\nopaque bounding box. The ",{"type":38,"tag":84,"props":487,"children":489},{"className":488},[],[490],{"type":51,"value":271},{"type":51,"value":492}," color fills the\nentire rectangle, and spans and region writes render on\ntop of it. This turns overlays into window-like elements\nwith solid backgrounds — useful for dialogs, cards, and\nany UI that needs to cleanly cover terminal content.",{"type":38,"tag":402,"props":494,"children":496},{"id":495},"styling",[497],{"type":51,"value":498},"Styling",{"type":38,"tag":43,"props":500,"children":501},{},[502],{"type":51,"value":503},"Spans support formatting attributes. Use them for\nvisual hierarchy:",{"type":38,"tag":505,"props":506,"children":510},"pre",{"className":507,"code":509,"language":51},[508],"language-text","{\"spans\": [\n  {\"text\": \"Warning: \", \"bold\": true, \"fg\": \"yellow\"},\n  {\"text\": \"this deletes 47 files\"}\n]}\n",[511],{"type":38,"tag":84,"props":512,"children":514},{"__ignoreMap":513},"",[515],{"type":51,"value":509},{"type":38,"tag":222,"props":517,"children":518},{},[519,529,539],{"type":38,"tag":75,"props":520,"children":521},{},[522,527],{"type":38,"tag":47,"props":523,"children":524},{},[525],{"type":51,"value":526},"Bold",{"type":51,"value":528}," for labels, keywords, emphasis",{"type":38,"tag":75,"props":530,"children":531},{},[532,537],{"type":38,"tag":47,"props":533,"children":534},{},[535],{"type":51,"value":536},"Color",{"type":51,"value":538}," for severity (red = danger, yellow = warning,\ngreen = success, cyan = informational)",{"type":38,"tag":75,"props":540,"children":541},{},[542,547],{"type":38,"tag":47,"props":543,"children":544},{},[545],{"type":51,"value":546},"Faint\u002Fdim",{"type":51,"value":548}," for secondary information",{"type":38,"tag":43,"props":550,"children":551},{},[552],{"type":51,"value":553},"Use the indexed color palette (0-7 for standard, 8-15 for\nbright) for broad terminal compatibility. Use RGB colors\nonly when you're confident the terminal supports them.",{"type":38,"tag":402,"props":555,"children":557},{"id":556},"named-spans",[558],{"type":51,"value":559},"Named Spans",{"type":38,"tag":43,"props":561,"children":562},{},[563,565,570],{"type":51,"value":564},"Spans can have an ",{"type":38,"tag":84,"props":566,"children":568},{"className":567},[],[569],{"type":51,"value":358},{"type":51,"value":571}," field. This lets you update a\nsingle span by its id instead of replacing all content\nin the overlay or panel.",{"type":38,"tag":505,"props":573,"children":576},{"className":574,"code":575,"language":51},[508],"{\"spans\": [\n  {\"id\": \"label\", \"text\": \"Status: \", \"bold\": true},\n  {\"id\": \"value\", \"text\": \"building\", \"fg\": \"yellow\"}\n]}\n",[577],{"type":38,"tag":84,"props":578,"children":579},{"__ignoreMap":513},[580],{"type":51,"value":575},{"type":38,"tag":43,"props":582,"children":583},{},[584],{"type":51,"value":585},"Later, update just the \"value\" span:",{"type":38,"tag":505,"props":587,"children":590},{"className":588,"code":589,"language":51},[508],"update span \"value\" → {\"text\": \"complete\", \"fg\": \"green\"}\n",[591],{"type":38,"tag":84,"props":592,"children":593},{"__ignoreMap":513},[594],{"type":51,"value":589},{"type":38,"tag":43,"props":596,"children":597},{},[598],{"type":51,"value":599},"The \"label\" span stays untouched. This is good for:",{"type":38,"tag":222,"props":601,"children":602},{},[603,608,613,618],{"type":38,"tag":75,"props":604,"children":605},{},[606],{"type":51,"value":607},"Live-updating status fields that change frequently",{"type":38,"tag":75,"props":609,"children":610},{},[611],{"type":51,"value":612},"Counters, timestamps, or progress percentages",{"type":38,"tag":75,"props":614,"children":615},{},[616],{"type":51,"value":617},"Labels that change independently of surrounding text",{"type":38,"tag":75,"props":619,"children":620},{},[621],{"type":51,"value":622},"Any element where you want to avoid redrawing\neverything just to change one piece",{"type":38,"tag":402,"props":624,"children":626},{"id":625},"region-writes",[627],{"type":51,"value":628},"Region Writes",{"type":38,"tag":43,"props":630,"children":631},{},[632],{"type":51,"value":633},"Write styled text at specific (row, col) offsets within\nan overlay or panel. This turns them into 2D drawable\nsurfaces — not just a flat list of spans, but a canvas\nwhere you can place text at exact coordinates.",{"type":38,"tag":505,"props":635,"children":638},{"className":636,"code":637,"language":51},[508],"overlay (width: 40, height: 5, background: dark):\n\nwrite at (0, 1):  \"Name\"     bold\nwrite at (0, 15): \"Status\"   bold\nwrite at (1, 1):  \"auth\"\nwrite at (1, 15): \"● ok\"     green\nwrite at (2, 1):  \"api\"\nwrite at (2, 15): \"● slow\"   yellow\n",[639],{"type":38,"tag":84,"props":640,"children":641},{"__ignoreMap":513},[642],{"type":51,"value":637},{"type":38,"tag":43,"props":644,"children":645},{},[646],{"type":51,"value":647},"Region writes are good for:",{"type":38,"tag":222,"props":649,"children":650},{},[651,656,661,666],{"type":38,"tag":75,"props":652,"children":653},{},[654],{"type":51,"value":655},"Tables with aligned columns",{"type":38,"tag":75,"props":657,"children":658},{},[659],{"type":51,"value":660},"Grids and structured layouts",{"type":38,"tag":75,"props":662,"children":663},{},[664],{"type":51,"value":665},"Charts and diagrams",{"type":38,"tag":75,"props":667,"children":668},{},[669],{"type":51,"value":670},"Any content where relative positioning matters",{"type":38,"tag":43,"props":672,"children":673},{},[674],{"type":51,"value":675},"Region writes and spans coexist. Spans flow as inline\ncontent; region writes place content at absolute\npositions within the element. Use whichever model fits\nthe content.",{"type":38,"tag":402,"props":677,"children":679},{"id":678},"z-order",[680],{"type":51,"value":681},"Z-Order",{"type":38,"tag":43,"props":683,"children":684},{},[685,687,693],{"type":51,"value":686},"When overlays overlap, higher ",{"type":38,"tag":84,"props":688,"children":690},{"className":689},[],[691],{"type":51,"value":692},"z",{"type":51,"value":694}," values render on top.\nDefault is 0. Use z-order to layer related elements:",{"type":38,"tag":505,"props":696,"children":699},{"className":697,"code":698,"language":51},[508],"background context:  z=0\nprimary information:  z=1\nurgent alert:         z=2\n",[700],{"type":38,"tag":84,"props":701,"children":702},{"__ignoreMap":513},[703],{"type":51,"value":698},{"type":38,"tag":402,"props":705,"children":707},{"id":706},"lifecycle",[708],{"type":51,"value":709},"Lifecycle",{"type":38,"tag":43,"props":711,"children":712},{},[713],{"type":51,"value":714},"Overlays don't disappear on their own. You must manage them:",{"type":38,"tag":222,"props":716,"children":717},{},[718,723,728,733],{"type":38,"tag":75,"props":719,"children":720},{},[721],{"type":51,"value":722},"Store the ID returned on creation",{"type":38,"tag":75,"props":724,"children":725},{},[726],{"type":51,"value":727},"Update content when information changes",{"type":38,"tag":75,"props":729,"children":730},{},[731],{"type":51,"value":732},"Delete individual overlays when no longer relevant",{"type":38,"tag":75,"props":734,"children":735},{},[736],{"type":51,"value":737},"Clear all overlays when cleaning up entirely",{"type":38,"tag":202,"props":739,"children":741},{"id":740},"designing-effective-panels",[742],{"type":51,"value":743},"Designing Effective Panels",{"type":38,"tag":402,"props":745,"children":747},{"id":746},"layout",[748],{"type":51,"value":749},"Layout",{"type":38,"tag":43,"props":751,"children":752},{},[753],{"type":51,"value":754},"Panels are rows of styled text at the top or bottom of the\nterminal. A 2-line panel at the bottom makes a natural\nstatus bar. A 3-line panel at the top works for context\nsummaries.",{"type":38,"tag":505,"props":756,"children":759},{"className":757,"code":758,"language":51},[508],"create panel (bottom, height: 2):\n  spans: [\n    {text: \" Status: \", bold},\n    {text: \"building\", fg: yellow},\n    {text: \"  |  \"},\n    {text: \"Branch: \", bold},\n    {text: \"feature\u002Fauth\"}\n  ]\n",[760],{"type":38,"tag":84,"props":761,"children":762},{"__ignoreMap":513},[763],{"type":51,"value":758},{"type":38,"tag":402,"props":765,"children":767},{"id":766},"updating-in-place",[768],{"type":51,"value":769},"Updating In Place",{"type":38,"tag":43,"props":771,"children":772},{},[773],{"type":51,"value":774},"Panels persist. When information changes, update the\nexisting panel rather than deleting and recreating.\nUse the panel's ID (returned on creation) to update\nits content in place.",{"type":38,"tag":43,"props":776,"children":777},{},[778],{"type":51,"value":779},"This prevents flicker and keeps the panel stable.",{"type":38,"tag":402,"props":781,"children":783},{"id":782},"height-budget",[784],{"type":51,"value":785},"Height Budget",{"type":38,"tag":43,"props":787,"children":788},{},[789],{"type":51,"value":790},"Every row of panel height is a row stolen from the\nterminal. Be miserly:",{"type":38,"tag":222,"props":792,"children":793},{},[794,799,804],{"type":38,"tag":75,"props":795,"children":796},{},[797],{"type":51,"value":798},"1 line for simple status",{"type":38,"tag":75,"props":800,"children":801},{},[802],{"type":51,"value":803},"2 lines for status + detail",{"type":38,"tag":75,"props":805,"children":806},{},[807],{"type":51,"value":808},"3 lines maximum in most cases",{"type":38,"tag":43,"props":810,"children":811},{},[812],{"type":51,"value":813},"On a 24-row terminal, a 3-line panel costs 12% of the\nvisible area. Respect the human's screen space.",{"type":38,"tag":202,"props":815,"children":817},{"id":816},"visual-structure-borders-and-padding",[818],{"type":51,"value":819},"Visual Structure: Borders and Padding",{"type":38,"tag":43,"props":821,"children":822},{},[823],{"type":51,"value":824},"wsh renders your spans as-is. There are no built-in\nborders, padding, margins, or separators. If you want\nvisual structure, you build it from text characters.",{"type":38,"tag":402,"props":826,"children":828},{"id":827},"borders",[829],{"type":51,"value":830},"Borders",{"type":38,"tag":43,"props":832,"children":833},{},[834],{"type":51,"value":835},"Use box-drawing characters for framed overlays:",{"type":38,"tag":505,"props":837,"children":840},{"className":838,"code":839,"language":51},[508],"{\"spans\": [\n  {\"text\": \"┌─ Warning ────────────┐\\n\"},\n  {\"text\": \"│ This will delete the │\\n\"},\n  {\"text\": \"│ entire build cache.  │\\n\"},\n  {\"text\": \"└──────────────────────┘\"}\n]}\n",[841],{"type":38,"tag":84,"props":842,"children":843},{"__ignoreMap":513},[844],{"type":51,"value":839},{"type":38,"tag":402,"props":846,"children":848},{"id":847},"padding",[849],{"type":51,"value":850},"Padding",{"type":38,"tag":43,"props":852,"children":853},{},[854],{"type":51,"value":855},"Add spaces for breathing room:",{"type":38,"tag":505,"props":857,"children":860},{"className":858,"code":859,"language":51},[508],"{\"text\": \"  Status: running  \"}\n          ^^              ^^  padding\n",[861],{"type":38,"tag":84,"props":862,"children":863},{"__ignoreMap":513},[864],{"type":51,"value":859},{"type":38,"tag":402,"props":866,"children":868},{"id":867},"separators",[869],{"type":51,"value":870},"Separators",{"type":38,"tag":43,"props":872,"children":873},{},[874,876,882,884,890],{"type":51,"value":875},"Use ",{"type":38,"tag":84,"props":877,"children":879},{"className":878},[],[880],{"type":51,"value":881},"│",{"type":51,"value":883}," or ",{"type":38,"tag":84,"props":885,"children":887},{"className":886},[],[888],{"type":51,"value":889},"|",{"type":51,"value":891}," between inline elements:",{"type":38,"tag":505,"props":893,"children":896},{"className":894,"code":895,"language":51},[508],"{\"spans\": [\n  {\"text\": \" build: \"},\n  {\"text\": \"ok\", \"fg\": \"green\"},\n  {\"text\": \" │ tests: \"},\n  {\"text\": \"3 failed\", \"fg\": \"red\"},\n  {\"text\": \" │ lint: \"},\n  {\"text\": \"clean\", \"fg\": \"green\"},\n  {\"text\": \" \"}\n]}\n",[897],{"type":38,"tag":84,"props":898,"children":899},{"__ignoreMap":513},[900],{"type":51,"value":895},{"type":38,"tag":402,"props":902,"children":904},{"id":903},"panel-separators",[905],{"type":51,"value":906},"Panel Separators",{"type":38,"tag":43,"props":908,"children":909},{},[910],{"type":51,"value":911},"A panel has no visible border separating it from the\nterminal content. Add your own with a full-width line:",{"type":38,"tag":505,"props":913,"children":916},{"className":914,"code":915,"language":51},[508],"{\"text\": \"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n\"}\n",[917],{"type":38,"tag":84,"props":918,"children":919},{"__ignoreMap":513},[920],{"type":51,"value":915},{"type":38,"tag":43,"props":922,"children":923},{},[924,926,931],{"type":51,"value":925},"Read the terminal's ",{"type":38,"tag":84,"props":927,"children":929},{"className":928},[],[930],{"type":51,"value":446},{"type":51,"value":932}," value to size separators\nto the full width.",{"type":38,"tag":202,"props":934,"children":936},{"id":935},"composition-patterns",[937],{"type":51,"value":938},"Composition Patterns",{"type":38,"tag":43,"props":940,"children":941},{},[942],{"type":51,"value":943},"Individual overlays and panels are building blocks.\nCombining them creates richer experiences.",{"type":38,"tag":402,"props":945,"children":947},{"id":946},"status-bar-contextual-annotations",[948],{"type":51,"value":949},"Status Bar + Contextual Annotations",{"type":38,"tag":43,"props":951,"children":952},{},[953],{"type":51,"value":954},"A persistent panel tracks overall state. Overlays\nprovide momentary context:",{"type":38,"tag":505,"props":956,"children":959},{"className":957,"code":958,"language":51},[508],"panel (bottom, 1 line):\n  \" ● monitoring  │  12 commands  │  2 errors \"\n\noverlay (near error on row 15):\n  \"┌─ Suggestion ──────────────────┐\"\n  \"│ Try: cargo build --release    │\"\n  \"└───────────────────────────────┘\"\n",[960],{"type":38,"tag":84,"props":961,"children":962},{"__ignoreMap":513},[963],{"type":51,"value":958},{"type":38,"tag":43,"props":965,"children":966},{},[967],{"type":51,"value":968},"The panel stays. The overlay appears when relevant\nand disappears when the screen moves on.",{"type":38,"tag":402,"props":970,"children":972},{"id":971},"layered-overlays",[973],{"type":51,"value":974},"Layered Overlays",{"type":38,"tag":43,"props":976,"children":977},{},[978],{"type":51,"value":979},"Stack overlays with z-order for progressive detail.\nA compact label at z=0, expanded detail at z=1\nshown only when the human triggers it (via input\ncapture or a follow-up question):",{"type":38,"tag":505,"props":981,"children":984},{"className":982,"code":983,"language":51},[508],"z=0: \" ⚠ 3 warnings \"\nz=1: \"┌─ Warnings ──────────────────┐\"\n     \"│ auth.rs:42  unused import   │\"\n     \"│ db.rs:17    deprecated call │\"\n     \"│ main.rs:3   dead code       │\"\n     \"└────────────────────────────-┘\"\n",[985],{"type":38,"tag":84,"props":986,"children":987},{"__ignoreMap":513},[988],{"type":51,"value":983},{"type":38,"tag":402,"props":990,"children":992},{"id":991},"multi-panel-dashboard",[993],{"type":51,"value":994},"Multi-Panel Dashboard",{"type":38,"tag":43,"props":996,"children":997},{},[998],{"type":51,"value":999},"Use top and bottom panels together. Top for context,\nbottom for status:",{"type":38,"tag":505,"props":1001,"children":1004},{"className":1002,"code":1003,"language":51},[508],"panel (top, 2 lines):\n  \"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\"\n  \" Project: wsh  Branch: master \"\n\npanel (bottom, 1 line):\n  \" ● 3 sessions  │  build: ok  │  tests: running \"\n",[1005],{"type":38,"tag":84,"props":1006,"children":1007},{"__ignoreMap":513},[1008],{"type":51,"value":1003},{"type":38,"tag":43,"props":1010,"children":1011},{},[1012],{"type":51,"value":1013},"Be conservative. Two panels means the terminal loses\n3+ rows. Only use both when the information justifies it.",{"type":38,"tag":402,"props":1015,"children":1017},{"id":1016},"temporary-overlays",[1018],{"type":51,"value":1019},"Temporary Overlays",{"type":38,"tag":43,"props":1021,"children":1022},{},[1023],{"type":51,"value":1024},"For notifications that should appear briefly, create\nthe overlay and then delete it after a delay. You'll\nneed to manage the timing yourself:",{"type":38,"tag":505,"props":1026,"children":1029},{"className":1027,"code":1028,"language":51},[508],"create overlay → get id\n(continue working)\nafter a few interaction cycles, delete the overlay\n",[1030],{"type":38,"tag":84,"props":1031,"children":1032},{"__ignoreMap":513},[1033],{"type":51,"value":1028},{"type":38,"tag":43,"props":1035,"children":1036},{},[1037],{"type":51,"value":1038},"There's no built-in timer. The overlay lives until you\nremove it. Tie cleanup to your next interaction with\nthe terminal — when you next read the screen, check\nif any overlays are stale and remove them.",{"type":38,"tag":202,"props":1040,"children":1042},{"id":1041},"pitfalls",[1043],{"type":51,"value":1044},"Pitfalls",{"type":38,"tag":402,"props":1046,"children":1048},{"id":1047},"visual-clutter",[1049],{"type":51,"value":1050},"Visual Clutter",{"type":38,"tag":43,"props":1052,"children":1053},{},[1054],{"type":51,"value":1055},"Every overlay and panel competes for attention. If\neverything is highlighted, nothing is. Apply a strict\nbudget:",{"type":38,"tag":222,"props":1057,"children":1058},{},[1059,1064,1069],{"type":38,"tag":75,"props":1060,"children":1061},{},[1062],{"type":51,"value":1063},"At most 1-2 panels active",{"type":38,"tag":75,"props":1065,"children":1066},{},[1067],{"type":51,"value":1068},"At most 2-3 overlays visible simultaneously",{"type":38,"tag":75,"props":1070,"children":1071},{},[1072],{"type":51,"value":1073},"If you need to show a new overlay and you're at your\nlimit, remove the least relevant one first",{"type":38,"tag":402,"props":1075,"children":1077},{"id":1076},"stale-elements",[1078],{"type":51,"value":1079},"Stale Elements",{"type":38,"tag":43,"props":1081,"children":1082},{},[1083],{"type":51,"value":1084},"Overlays and panels don't expire. If you create an\noverlay saying \"build started\" and never remove it,\nit's still there 20 minutes later when the human has\nmoved on to something else entirely. Track what you've\ncreated and clean up proactively.",{"type":38,"tag":43,"props":1086,"children":1087},{},[1088],{"type":51,"value":1089},"Keep a mental inventory of your active visual elements.\nBefore creating a new one, ask: are any existing ones\nstale? Remove them first.",{"type":38,"tag":402,"props":1091,"children":1093},{"id":1092},"overlapping-content",[1094],{"type":51,"value":1095},"Overlapping Content",{"type":38,"tag":43,"props":1097,"children":1098},{},[1099],{"type":51,"value":1100},"An overlay at (0, 5) that's 40 characters wide will\ncover whatever is on row 5. If that row contains\nimportant terminal output, you've hidden it. Strategies:",{"type":38,"tag":222,"props":1102,"children":1103},{},[1104,1109,1114],{"type":38,"tag":75,"props":1105,"children":1106},{},[1107],{"type":51,"value":1108},"Position overlays at the right edge of the screen,\npast where output typically ends",{"type":38,"tag":75,"props":1110,"children":1111},{},[1112],{"type":51,"value":1113},"Use short overlays that don't span the full width",{"type":38,"tag":75,"props":1115,"children":1116},{},[1117],{"type":51,"value":1118},"Prefer panels for information that shouldn't compete\nwith terminal content",{"type":38,"tag":402,"props":1120,"children":1122},{"id":1121},"color-assumptions",[1123],{"type":51,"value":1124},"Color Assumptions",{"type":38,"tag":43,"props":1126,"children":1127},{},[1128],{"type":51,"value":1129},"Not all terminals use the same color scheme. Indexed\ncolor 1 is \"red\" but the exact shade depends on the\nterminal's theme. More importantly, the terminal might\nhave a light or dark background. Don't rely on color\nalone to convey meaning — pair it with text labels\nor symbols:",{"type":38,"tag":505,"props":1131,"children":1134},{"className":1132,"code":1133,"language":51},[508],"Good:  {\"text\": \"✗ FAIL\", \"fg\": \"red\"}\nBad:   {\"text\": \"●\", \"fg\": \"red\"}\n",[1135],{"type":38,"tag":84,"props":1136,"children":1137},{"__ignoreMap":513},[1138],{"type":51,"value":1133},{"type":38,"tag":43,"props":1140,"children":1141},{},[1142],{"type":51,"value":1143},"The word \"FAIL\" communicates even without color. A\nred dot is meaningless on a terminal where red is\nhard to see.",{"type":38,"tag":402,"props":1145,"children":1147},{"id":1146},"coordinate-drift",[1148],{"type":51,"value":1149},"Coordinate Drift",{"type":38,"tag":43,"props":1151,"children":1152},{},[1153,1155,1161],{"type":51,"value":1154},"Screen content scrolls. An overlay pinned to row 10\nmade sense when the error was on row 10, but after\nthe human runs another command, row 10 is different\ncontent. Contextual overlays should be removed when\nthe screen changes significantly. Use the ",{"type":38,"tag":84,"props":1156,"children":1158},{"className":1157},[],[1159],{"type":51,"value":1160},"epoch",{"type":51,"value":1162},"\nfield in screen responses — if the epoch has changed\nsince you placed the overlay, re-evaluate whether it's\nstill positioned correctly.",{"items":1164,"total":1325},[1165,1181,1199,1213,1225,1237,1249,1260,1276,1290,1302,1314],{"slug":1166,"name":1166,"fn":1167,"description":1168,"org":1169,"tags":1170,"stars":1178,"repoUrl":1179,"updatedAt":1180},"deepclaw-voice","configure phone calls with Deepgram Voice","Set up phone calling to OpenClaw using Deepgram Voice Agent API",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1171,1174,1175],{"name":1172,"slug":1173,"type":15},"API Development","api-development",{"name":9,"slug":8,"type":15},{"name":1176,"slug":1177,"type":15},"Voice","voice",78,"https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fdeepclaw","2026-07-12T08:29:25.371332",{"slug":1182,"name":1182,"fn":1183,"description":1184,"org":1185,"tags":1186,"stars":1196,"repoUrl":1197,"updatedAt":1198},"1password","manage secrets with 1Password CLI","Set up and use 1Password CLI (op). Use when installing the CLI, enabling desktop app integration, signing in (single or multi-account), or reading\u002Finjecting\u002Frunning secrets via op.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1187,1190,1193],{"name":1188,"slug":1189,"type":15},"Automation","automation",{"name":1191,"slug":1192,"type":15},"CLI","cli",{"name":1194,"slug":1195,"type":15},"Security","security",23,"https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fdglabs-deepclaw","2026-07-12T08:28:49.991939",{"slug":1200,"name":1200,"fn":1201,"description":1202,"org":1203,"tags":1204,"stars":1196,"repoUrl":1197,"updatedAt":1212},"apple-notes","manage Apple Notes on macOS","Manage Apple Notes via the `memo` CLI on macOS (create, view, edit, delete, search, move, and export notes). Use when a user asks OpenClaw to add a note, list notes, search notes, or manage note folders.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1205,1206,1209],{"name":1191,"slug":1192,"type":15},{"name":1207,"slug":1208,"type":15},"Knowledge Management","knowledge-management",{"name":1210,"slug":1211,"type":15},"macOS","macos","2026-07-12T08:29:01.538106",{"slug":1214,"name":1214,"fn":1215,"description":1216,"org":1217,"tags":1218,"stars":1196,"repoUrl":1197,"updatedAt":1224},"apple-reminders","manage Apple Reminders via CLI","Manage Apple Reminders via the `remindctl` CLI on macOS (list, add, edit, complete, delete). Supports lists, date filters, and JSON\u002Fplain output.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1219,1220,1221],{"name":1191,"slug":1192,"type":15},{"name":1210,"slug":1211,"type":15},{"name":1222,"slug":1223,"type":15},"Task Management","task-management","2026-07-12T08:29:14.035414",{"slug":1226,"name":1226,"fn":1227,"description":1228,"org":1229,"tags":1230,"stars":1196,"repoUrl":1197,"updatedAt":1236},"bear-notes","manage Bear notes via CLI","Create, search, and manage Bear notes via grizzly CLI.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1231,1232,1233],{"name":1191,"slug":1192,"type":15},{"name":1207,"slug":1208,"type":15},{"name":1234,"slug":1235,"type":15},"Notes","notes","2026-07-12T08:28:51.246011",{"slug":1238,"name":1238,"fn":1239,"description":1240,"org":1241,"tags":1242,"stars":1196,"repoUrl":1197,"updatedAt":1248},"blogwatcher","monitor blogs and RSS feeds","Monitor blogs and RSS\u002FAtom feeds for updates using the blogwatcher CLI.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1243,1244,1245],{"name":1188,"slug":1189,"type":15},{"name":1191,"slug":1192,"type":15},{"name":1246,"slug":1247,"type":15},"Monitoring","monitoring","2026-07-12T08:29:02.762321",{"slug":1250,"name":1250,"fn":1251,"description":1252,"org":1253,"tags":1254,"stars":1196,"repoUrl":1197,"updatedAt":1259},"blucli","control BluOS audio playback","BluOS CLI (blu) for discovery, playback, grouping, and volume.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1255,1258],{"name":1256,"slug":1257,"type":15},"Audio","audio",{"name":1191,"slug":1192,"type":15},"2026-07-12T08:28:21.009637",{"slug":1261,"name":1261,"fn":1262,"description":1263,"org":1264,"tags":1265,"stars":1196,"repoUrl":1197,"updatedAt":1275},"bluebubbles","send and manage iMessages","Use when you need to send or manage iMessages via BlueBubbles (recommended iMessage integration). Calls go through the generic message tool with channel=\"bluebubbles\".",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1266,1269,1272],{"name":1267,"slug":1268,"type":15},"Communications","communications",{"name":1270,"slug":1271,"type":15},"iMessage","imessage",{"name":1273,"slug":1274,"type":15},"Messaging","messaging","2026-07-12T08:28:57.517914",{"slug":1277,"name":1277,"fn":1278,"description":1279,"org":1280,"tags":1281,"stars":1196,"repoUrl":1197,"updatedAt":1289},"camsnap","capture frames and clips from cameras","Capture frames or clips from RTSP\u002FONVIF cameras.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1282,1283,1286],{"name":1188,"slug":1189,"type":15},{"name":1284,"slug":1285,"type":15},"Camera","camera",{"name":1287,"slug":1288,"type":15},"Media","media","2026-07-12T08:28:28.096134",{"slug":1291,"name":1291,"fn":1292,"description":1293,"org":1294,"tags":1295,"stars":1196,"repoUrl":1197,"updatedAt":1301},"clawhub","manage agent skills with ClawHub","Use the ClawHub CLI to search, install, update, and publish agent skills from clawhub.com. Use when you need to fetch new skills on the fly, sync installed skills to latest or a specific version, or publish new\u002Fupdated skill folders with the npm-installed clawhub CLI.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1296,1299,1300],{"name":1297,"slug":1298,"type":15},"Agents","agents",{"name":1188,"slug":1189,"type":15},{"name":1191,"slug":1192,"type":15},"2026-07-12T08:28:30.589001",{"slug":1303,"name":1303,"fn":1304,"description":1305,"org":1306,"tags":1307,"stars":1196,"repoUrl":1197,"updatedAt":1313},"coding-agent","run coding agents for programmatic control","Run Codex CLI, Claude Code, OpenCode, or Pi Coding Agent via background process for programmatic control.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1308,1309,1310],{"name":1297,"slug":1298,"type":15},{"name":1188,"slug":1189,"type":15},{"name":1311,"slug":1312,"type":15},"Coding","coding","2026-07-12T08:29:08.6658",{"slug":1315,"name":1315,"fn":1316,"description":1317,"org":1318,"tags":1319,"stars":1196,"repoUrl":1197,"updatedAt":1324},"eightctl","control Eight Sleep pod settings","Control Eight Sleep pods (status, temperature, alarms, schedules).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1320,1321],{"name":1188,"slug":1189,"type":15},{"name":1322,"slug":1323,"type":15},"Hardware","hardware","2026-07-12T08:28:39.322181",73,{"items":1327,"total":1411},[1328,1341,1355,1366,1378,1388,1400],{"slug":1329,"name":1329,"fn":1330,"description":1331,"org":1332,"tags":1333,"stars":22,"repoUrl":23,"updatedAt":1340},"agent-orchestration","orchestrate multiple AI agents","Use when you need to launch and drive other AI agents (Claude Code, Aider, Codex, etc.) through their terminal interfaces via wsh. Examples: \"run multiple Claude Code sessions in parallel on different tasks\", \"feed a task to an AI agent and handle its approval prompts\", \"coordinate several AI agents working on subtasks of a larger project\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1334,1335,1336,1337],{"name":1297,"slug":1298,"type":15},{"name":1188,"slug":1189,"type":15},{"name":1191,"slug":1192,"type":15},{"name":1338,"slug":1339,"type":15},"Multi-Agent","multi-agent","2026-07-12T08:29:40.028618",{"slug":1342,"name":1342,"fn":1343,"description":1344,"org":1345,"tags":1346,"stars":22,"repoUrl":23,"updatedAt":1354},"cluster-orchestration","orchestrate sessions across federated clusters","Use when you need to manage sessions across multiple wsh servers in a federated cluster. Examples: \"distribute builds across several machines\", \"create sessions on a specific backend\", \"monitor health across a cluster of servers\", \"coordinate work across server boundaries\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1347,1350,1351],{"name":1348,"slug":1349,"type":15},"Architecture","architecture",{"name":1188,"slug":1189,"type":15},{"name":1352,"slug":1353,"type":15},"Engineering","engineering","2026-07-12T08:29:38.810244",{"slug":1356,"name":1356,"fn":1357,"description":1358,"org":1359,"tags":1360,"stars":22,"repoUrl":23,"updatedAt":1365},"core","authenticate and bootstrap wsh terminal operations","REQUIRED before any wsh terminal operation when you do NOT have wsh_* MCP tools. Contains the complete HTTP API reference with working curl examples, bootstrap sequence, and authentication guide. wsh has no CLI subcommands for programmatic use — do NOT run 'wsh \u003Cverb>' commands or guess endpoints. Load this skill first.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1361,1364],{"name":1362,"slug":1363,"type":15},"Authentication","authentication",{"name":1191,"slug":1192,"type":15},"2026-07-12T08:29:32.614733",{"slug":1367,"name":1367,"fn":1368,"description":1369,"org":1370,"tags":1371,"stars":22,"repoUrl":23,"updatedAt":1377},"core-mcp","bootstrap MCP terminal sessions","REQUIRED before any wsh terminal operation. Contains the complete MCP tool reference and bootstrap sequence for wsh_create_session, wsh_send_input, wsh_get_screen, wsh_send_and_read, wsh_send_keys, and all wsh_* tools. Do NOT guess wsh CLI commands or HTTP endpoints — use MCP tools or load this skill first.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1372,1373,1374],{"name":1188,"slug":1189,"type":15},{"name":1191,"slug":1192,"type":15},{"name":1375,"slug":1376,"type":15},"MCP","mcp","2026-07-12T08:29:45.869993",{"slug":1379,"name":1379,"fn":1380,"description":1381,"org":1382,"tags":1383,"stars":22,"repoUrl":23,"updatedAt":1387},"drive-process","interact with CLI programs via wsh","Use when you need to drive a CLI program through command-and-response interaction via wsh. Examples: \"run a build command and check the output\", \"interact with an installer that asks questions\", \"execute a sequence of shell commands and handle errors\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1384,1385,1386],{"name":1188,"slug":1189,"type":15},{"name":1191,"slug":1192,"type":15},{"name":1352,"slug":1353,"type":15},"2026-07-12T08:29:51.485222",{"slug":1389,"name":1389,"fn":1390,"description":1391,"org":1392,"tags":1393,"stars":22,"repoUrl":23,"updatedAt":1399},"generative-ui","build interactive terminal user interfaces","Use when you need to build dynamic, interactive terminal experiences on the fly. Examples: \"create a live dashboard in the terminal\", \"build an interactive file browser\", \"generate a custom TUI for this workflow\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1394,1395,1396],{"name":1191,"slug":1192,"type":15},{"name":1352,"slug":1353,"type":15},{"name":1397,"slug":1398,"type":15},"Frontend","frontend","2026-07-12T08:29:41.286933",{"slug":1401,"name":1401,"fn":1402,"description":1403,"org":1404,"tags":1405,"stars":22,"repoUrl":23,"updatedAt":1410},"infrastructure-ops","manage infrastructure across multiple servers","Use when you need to manage infrastructure across multiple servers interactively via wsh — deploying applications, configuring services, managing packages, performing rolling updates, and handling the prompts and judgment calls that declarative tools cannot. Examples: \"deploy this application across 10 servers with health checks between each\", \"upgrade packages across the fleet and handle diverse prompts\", \"inspect and modify configuration across servers\", \"roll back a failed deployment\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1406,1407],{"name":1191,"slug":1192,"type":15},{"name":1408,"slug":1409,"type":15},"Infrastructure","infrastructure","2026-07-12T08:29:57.659886",12]