--- name: glyph license: MIT compatibility: "Claude Code 2.1.277+." description: "Render an answer as ASCII art plus semantic emojis inline with no setup questions: one render per reply, verdict first. Use for any answer with shape: status, inventories, audits, budgets, comparisons, rankings, pipelines, 'what is using X', or any ad-hoc 'show me X visually' ask. Not for definitions, conceptual explanations, or one-liner asks. For a full multi-artifact plan playground, use visualize-plan instead." user-invocable: true disable-model-invocation: false context: inherit allowed-tools: "Read Grep Glob AskUserQuestion" argument-hint: "[--chat|--ask|--page] [--eli5] [--decide] [--signoff] [topic-to-render]" effort: low metadata: category: document-asset-creation version: "3.2.0" author: "OrchestKit" complexity: "low" tags: "ascii, diagrams, visualization, box-drawing, terminal, quick" --- # Glyph Render the answer as ASCII art plus semantic emojis, inline, immediately. All output renders in a monospace terminal with no external tools. **Core principle:** Encode information into structure, not decoration. Every diagram element should communicate something meaningful. ## Execution (run this, do not ask first) **A human asking "how do I use this" gets a URL, not a paraphrase:** https://orchestkit.yonyon.ai/docs/reference/skills/glyph#examples (what it draws, the two picks, three real renders, the exact invocation; generated from this skill's `examples/_featured.md`, so it cannot drift from the skill). The whole point is speed, so there is no setup phase. **Already loaded means render, not hand off.** Once this file is loaded, draw the answer here. Do not call the Skill tool for `glyph`, `/glyph`, or `/ork:glyph`. A second invocation loads a skill again and re-runs the planning step. The 2026-09-15 Devin transcript showed "Invoked skill glyph" then "Invoked skill ork:glyph", one render stacked on another. Whether that re-entry is also why the Thoughts text repeated is not verified here; do not re-enter either way. The front door does not delegate. A user may have a personal skill also named `glyph` (`/glyph`); it lives in a separate namespace, may call this skill for its chat route, and is never called from here (`references/dials.md`, "Personal skills named glyph"). **With no argument, the topic is the current conversation.** Measured over a real 13-prompt session: zero asks supplied a self-contained topic, and the one direct invocation passed nothing at all. `glyph` on its own means "render where we are right now": the open work, the decision just reached, the state of the thing being discussed. Render that; do not ask what to draw. Given a topic (or the conversation, when none is given): 0. **Resolve the two dials, then announce them in one line.** Surface is chat, ask or page (default chat); audience is operator or novice (default operator). A flag beats inference: `--chat`, `--ask`, `--page`, `--eli5`, `--decide`, `--signoff`. Print exactly `→ chat · operator` (surface, then audience) and a blank line before the answer. Inference rules, the ask guardrail and the `--decide` shapes: `Read("references/dials.md")`. 1. **Render immediately.** Do NOT call `AskUserQuestion` to pick a format (the ask surface and `--signoff` are the only questions this skill asks), do NOT call `TaskCreate`, do NOT spawn an `Agent`. Choose the form yourself from the topic shape and draw it. Asking first defeats the skill. 2. **Pick the form from the shape of the data**, using the pattern library below: | Topic shape | Form | |---|---| | inventory, audit, budget, "what is using X" | **inventory render** (`templates/inventory.md`): header meter, traffic-light sections, icon / label / bar / value / action rows, totals, arithmetic summary, caveats | | state / progress / health | status box + bar meters | | A vs B, options, trade-offs | comparison table or side-by-side boxes (one narrow table in a non-TTY surface) | | steps, pipeline, hand-offs | left-to-right flow with `──▶` | | containment, layers, layout | nested boxes / tree | | ranked list, scores, counts | table + bar meters | | over time | sparkline or milestone track | | triage open issues, what is left, categorize the backlog | **triage page** (`templates/triage.html`). Not an inline render. | | explainer page, NOW vs IDEAL, "show it moving" (page route only) | **JS art piece** on the page (`references/js-art.md`). Chat stays ASCII. | 3. **Emit inline in the reply, except the triage page.** Never write a file unless the user asked for one. The triage row above is the exception: that answer is `templates/triage.html`, not an inline render. Every other answer stays in the reply. 4. **Use the closed status set, the domain-icon legend and the box-drawing vocabulary** defined in `rules/visual-style.md` (shipped with this skill) and `tokens.json` (`icons.*`). Status icons pair with a word (✅ done, ❌ failed, ⚠️ warning, 🔴 high risk, ℹ️ caveat). Domain icons (🐳 docker, 📦 package, 🧪 test, ...) go one per row in the leading column so they scan as a legend; never inside a prose sentence, never in chains. 5. **Stay inside the budget: ONE render per reply, up to about 50 lines, every line 76 cells or fewer.** Two competing renders in one reply is flooding. Above 50 lines it is a page, not a chat answer. The 2026-08-09 budget (12 lines, 40 percent) over-corrected and was reset by operator word on 2026-09-17; the history is in `rules/visual-style.md`. 6. **Verdict first, then the render, then what the numbers told me.** One prose line states the point before the render. After the render, two or three bold-led bullets say what is not obvious from the chart. If the reader has to parse the render to find out what happened, the reply failed. 7. **Stay honest.** If a number is unknown, print `?` rather than inventing one. A confident-looking chart built on guesses is worse than prose. 8. **Match the width to the host.** A render that fits a terminal wraps into a wall in a host that reflows text: CI logs, chat widgets, VS Code chat, web transcripts, agent desktops. Read the surface from the environment the same way you already infer audience and surface: with a terminal (TTY), render as below; without one, cap every diagram line at 72 columns, and render key/value or comparison data as one narrow table or a vertical list, never side-by-side columns. The line budget does not change. Measured failure the rule prevents: a side-by-side key/value board for 5 rows lands at 113 columns, and `scripts/render-ascii.sh key-value` renders the narrow form of the same data (GH-4159). **When NOT to use this skill:** if the deliverable is a multi-section HTML playground, a persisted plan artifact, or any file output other than the triage page, use `visualize-plan` instead. Glyph is the cheap inline path; visualize-plan is the full pipeline. The triage page stays here. **Triage is a page, every time.** Asks shaped like "triage open issues", "what is left", or "categorize this for me" use `templates/triage.html` and no other layout. This overrides the inline-only rule and the visualize-plan handoff: the page is glyph's, then `/page-serve PATH`. Fill issues from one snapshot, `gh issue list --state open --json number,title,labels,milestone`. Put every gh-sourced string in the hidden snapshot textarea as one base64 blob of the JSON, not as raw JSON and not in the lane markup or the raw dump. A title that contains `.localhost/` route, with a stop) instead of a bare file path or a hand-started `python3 -m http.server`. Keep a 10-line excerpt in chat next to the URL. The old escape hatch fired on artifact TYPE only, so an over-budget inline reply never tripped it. **JS art is for pages; chat stays ASCII.** When the answer is already a page (an explainer, a NOW vs IDEAL plan), the page carries one animated piece above its first beat: an inline ``, a Now/Ideal toggle, a Play/Pause button, and a text alt on the canvas. Build it from `references/js-art.md`: paste one pattern (flow dots, gate, before/after meter, or real-data bars from a JSON array in the page), then the kernel. `draw(ctx, t, mode)` is pure, so `window.seek(t)` can capture any frame to mp4 or gif; `prefers-reduced-motion` gets one still frame and no animation loop; no `Math.random`, no network. A piece that shows measured numbers draws `?` for a value you do not have. Never put JS art in a chat reply. ## Render anatomy (the v3 reference shape) The shape below is the default for anything inventory-like (disk, spend, backlog, dependencies, hooks, "what is using X"). Draw it top to bottom; drop a part only when the data has nothing for it. The full template with the column widths is `templates/inventory.md`; the worked example is in `examples/_featured.md`. ``` 🖥️ MACINTOSH HD · /System/Volumes/Data header: icon, subject [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░] headline meter used 355 G free 73 G 83 % full · 460 G total numbers under it ──────────────────────────────────────────────── light rule 🟢 SAFE, pure caches; nothing lost, tools refill them traffic-light word ──────────────────────────────────────────────── 🐳 Docker dangling images+build cache ▓▓▓▓░░░ 14.5 G docker prune 🌐 Chrome caches (Google + Island) ▓▓░░░░░ 8.9 G browsers refill 📦 npm cache ~/.npm ▓▓░░░░░ 6.2 G npm cache clean ── 45.3 G per-section total 🟢 safe 45 G + 🟡 regenerable 41 G ≈ 87 G → free 73 G → ~159 G ℹ️ Docker.raw shows 432 G but is sparse: 37 G real. caveat line ``` Parts, in order: 1. **Header line**: one domain icon, the subject, `·`, the path or scope. 2. **Headline meter**: `[▓▓▓░░]` with the numbers printed on the line under it. 3. **Sections**: opened by a light rule `────` and a traffic-light word (🟢 SAFE, 🟡 REGENERABLE, 🔴 ASK FIRST, or the domain's own words). 4. **Rows**: icon, label, bar `▓▓▓░░`, value, one-word action, aligned in columns. One domain icon per row, leading column. 5. **`── total`** line per section, right-aligned under the values. 6. **Summary line** that shows the arithmetic, so the reader can check it. 7. **`ℹ️` caveat lines** for the numbers that lie (sparse files, shared caches, double counts). `?` for a number you do not have. 8. Then prose: two or three bold-led bullets, "what the numbers told me". The vocabulary is closed. Status icons come from `tokens.json` `icons.status` (plus `risk` and `ranking`); row icons from `icons.domain`. Add there, not ad hoc. No emoji chains, no emoji in prose sentences, no full-width rules, no "★ Insight" blocks, no mermaid in chat, no em or en dashes. ## Box-Drawing Character Reference This block intentionally shows multiple sets together as a key. Authors should use ONE set per real diagram; the `single-set` lint rule enforces this on production diagrams. ``` default: ┌─┐ │ └─┘ ├─┤ ┬ ┴ ┼ emphasis: ┏━┓ ┃ ┗━┛ ┣━┫ ┳ ┻ ╋ title: ╔═╗ ║ ╚═╝ ╠═╣ ╦ ╩ ╬ soft: ╭─╮ │ ╰─╯ portable: +-+ | +-+ +-+ + + + Arrows: → ← ↑ ↓ ─> <─ ──> <── Blocks: █ ▓ ░ ▏▎▍▌▋▊▉ Status: ● ○ ✓ ✗ ⚠ ◆ ◇ ▶ ▷ ↑↓→ ▓▒░ (closed-set vocab, see rules) ``` ### Set Conventions (D8: intent-driven naming) Tokens live in `tokens.json`. Names describe USE not APPEARANCE. | Set | Characters | Use For | |-----|-----------|---------| | `default` `─│` | Normal boxes and connectors | Most diagrams | | `emphasis` `━┃` | Headers, focus, draw the eye | Key components, outer frames | | `title` `═║` | Document titles | §0-style banners only | | `soft` `╭╮╰╯ ─│` | Status cards, ambient UI | Diff blocks | | `portable` `+-\|` | NO_COLOR / CI / bare TTY | Fallback | Rename codemod (D8): old `light/heavy/double/rounded/ascii-fallback` → new names above. Old names accepted with warning for one minor release. ### Status Glyph Vocabulary Closed-set v1 of 11 semantic glyphs (`●○✓✗⚠◆◇▶▷ ↑↓→ ▓▒░`). Single source of truth: see `rules/status-glyph-vocabulary.md`. Add-a-glyph process in `CONTRIBUTING.md`. ## Diagram Patterns ### Architecture Diagrams ``` ┌────────┐ ┌────────┐ │Frontend│─>│Backend │ │React 19│ │FastAPI │ └────────┘ └───┬────┘ ┌───┴──────┐ │PostgreSQL│ └──────────┘ ``` ### File Trees with Annotations ``` src/ ├── api/ │ ├── routes.py [M] +45 -12 !! high-traffic path │ └── schemas.py [M] +20 -5 ├── services/ │ └── billing.py [A] +180 ** new file └── tests/ └── test_billing.py [A] +120 ** new file Legend: [A]dd [M]odify [D]elete !! Risk ** New ``` ### Progress Bars ``` [████████░░] 80% Complete + Design (2 days) + Backend (5 days) ~ Frontend (3 days) - Testing (pending) ``` ### Swimlane / Timeline Diagrams ``` Backend ===[Schema]======[API]===========================[Deploy]====> | | ^ | +------blocks------+ | | | | Frontend ------[Wait]--------[Components]=======[Integration]=+ === Active work --- Blocked/waiting | Dependency ``` ### Blast Radius (Concentric Rings) ``` Ring 3: Tests (8 files) +-------------------------------+ | Ring 2: Transitive (5) | | +------------------------+ | | | Ring 1: Direct (3) | | | | +--------------+ | | | | | CHANGED FILE | | | | | +--------------+ | | | +------------------------+ | +-------------------------------+ ``` ### Comparison Tables ``` BEFORE AFTER ┌──────────┐ ┌─────────┐ │Monolith │ │Service A│──┐ │(all-in-1)│ └─────────┘ │ ┌───────┐ └──────────┘ ┌─────────┐ ├─>│Shared │ │Service B│──┘ │Queue │ └─────────┘ └───────┘ ``` ### Reversibility Timeline ``` Phase 1 [================] FULLY REVERSIBLE (add column) Phase 2 [================] FULLY REVERSIBLE (new endpoint) Phase 3 [============....] PARTIALLY (backfill) --- POINT OF NO RETURN --- Phase 4 [........????????] IRREVERSIBLE (drop column) ``` ## Key Rules | Rule | Description | |------|-------------| | Font | Always monospace; box-drawing requires fixed-width | | Weight | Standard for normal, Heavy for emphasis, Double for titles | | Arrows | `─>`, `──>`, or `│` with `v`/`^` for direction | | Alignment | Right-pad labels to match column widths | | Annotations | `!!` for risk, `**` for new, `[A/M/D]` for change type | | Width | 76 cells or fewer in a terminal; at most 72 per line in a non-TTY surface, as one narrow table or vertical list (GH-4159) | | Nesting | Max 3 levels of box nesting before readability degrades | ## When to Use Each Pattern | Pattern | Use Case | |---------|----------| | Layered boxes | System architecture, deployment topology | | Concentric rings | Blast radius, impact analysis | | Timeline bars | Reversibility, migration phases | | Swimlanes | Execution order, parallel work streams | | Annotated trees | File change manifests, directory structures | | Comparison tables | Cross-layer consistency, before/after | | Progress bars | Status tracking, completion metrics | | Inventory render | Disk, spend, backlog, dependency audits; anything with sections and totals | ## Done sign-off (`--signoff`) With `--signoff`, the render is the last thing before the gate: lead with any failure, then ask the one sign-off question from `Read("../../shared/rules/done-signoff.md")` with its three labels unchanged ("Accept done", "Show me the evidence", "Not satisfied"). In a non-interactive run, print the verdict and skip the question. ## Related Skills - `verify`: grades the work, then ends with the same done sign-off - `brainstorm`: Design exploration where diagrams communicate ideas - `architecture-patterns`: System architecture that benefits from ASCII diagrams - `code-review-playbook`: Review comments with inline diagrams