Agent skill

Genui

by open-octo in open-octo/octo-agent

Render structured, glanceable, interactive UI in the chat instead of plain text — dashboards, stat cards, filterable tables, charts, choice panels, forms, quizzes.

MITAuto-check passedEducation

Install Genui

skills CLI
$ npx skills add open-octo/octo-agent --skill genui -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install open-octo/octo-agent genui --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/open-octo/octo-agent.git skills-src && mkdir -p .claude/skills && cp -r skills-src/internal/skills/defaults/genui .claude/skills/genui && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
genui
GitHub stars
125
Token cost
~4.1k tokens
SKILL.md length
2,372 words
Files
1
Skills in repo
40
Repo updated
First seen
Licence
MIT

At a glance

Render structured, glanceable, interactive UI in the chat instead of plain text — dashboards, stat cards, filterable tables, charts, choice panels, forms, quizzes.

  • Tasks that involve Quizzes and assessments
  • SKILL.md covers The two output surfaces, Node types, Prefer local interaction over… and Addressable panels and silent…, plus 3 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Genui is an agent skill from open-octo/octo-agent. Render structured, glanceable, interactive UI in the chat instead of plain text — dashboards, stat cards, filterable tables, charts, choice panels, forms, quizzes. Panels can carry an id so later turns update them in place, and most interaction resolves in the browser with no round-trip. Read this before calling renderui or emitting a octo-ui fence, so the spec you produce matches the node whitelist and caps the renderer actually enforces.

Its SKILL.md is about 4.1k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Education, covering Quizzes and assessments. The repository describes itself as: Open-source, single-binary, self-hosted AI agent — your models and data stay on your machine. A coding agent on par with Claude Code and a personal assistant lighter than… The licence is MIT.

When your agent uses it

  • Tasks that involve Quizzes and assessments

Example prompts

  • “/genui”

What it can do on your machine

Read from SKILL.md and the folder at commit fc1385f. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are json).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Genui loads about 4.1k tokens when it runs. Until then it costs about 113 tokens; SKILL.md has 2,372 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~113
When it runs · the whole SKILL.md, loaded when a task matches
~4.1k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from open-octo/octo-agent at commit fc1385f, republished under its MIT licence (© open-octo). 2,372 words, ~4,059 tokens.

Download SKILL.mdSave it as .claude/skills/genui/SKILL.md (or your agent's skills folder).
name
genui
description
Render structured, glanceable, interactive UI in the chat instead of plain text — dashboards, stat cards, filterable tables, charts, choice panels, forms, quizzes. Panels can carry an id so later turns update them in place, and most interaction resolves in the browser with no round-trip. Read this before calling render_ui or emitting a ```octo-ui fence, so the spec you produce matches the node whitelist and caps the renderer actually enforces.

GenUI

GenUI lets you describe a small UI tree as JSON — cards, stats, tables, lists, badges, progress bars, callouts, charts, code blocks, and form controls — and have it render as real components in the chat instead of you writing the same information out as prose or a markdown table. There are two ways to emit a spec; which one to use depends on what you're building and where the reply is going. Read "The two output surfaces" before picking.

The two output surfaces

1. The render_ui tool. Call it with {"spec": {"title"?: string, "items": GenuiNode[]}}. Read-only components only — no buttons, no inputs. The tool validates and clamps your spec server-side and returns it on the same channel other tools use for rich result cards, so it renders as a tool-result card in the Web UI. This is the only surface available in every transport, but "every transport" doesn't mean "the card is visible everywhere": IM and the TUI never show tool-result cards at all — they show only your plain-text reply for that turn. If you call render_ui in an IM or TUI conversation, follow it with a plain-text reply that stands on its own; don't assume the user saw the card.

**2. An inline ```octo-ui fence in your reply text.** Write a fenced code block with the language tag octo-ui whose body is a GenUI spec (same shape as render_ui's spec argument). This is the only surface that supports the interactive node types (see below), and it renders as a live component tree inline with the rest of your markdown — but **only in a Web UI chat session**. IM and the TUI cannot render a component tree, so they replace the fence with a plain placeholder line before the user ever sees it. There is no reliable signal available to you, in the turn itself, telling you which transport you're replying into — so decide whether to use an inline fence from ordinary conversational context (has the user been interacting with a visual UI this session? did they mention a phone/chat app?), and when genuinely unsure, prefer the render_ui tool plus a self-contained plain-text reply over an inline fence, since the tool path degrades safely everywhere and the fence does not.

Node types

A spec is {title?: string, items: GenuiNode[]}. Every node is a JSON object discriminated by its type field.

Read-only nodes (both surfaces)

These render from both the render_ui tool card and an inline octo-ui fence.

typeFieldsNotes
texttext: string, tone?: "default"|"muted"|"danger"Plain paragraph
row / colgap?: number, children: GenuiNode[]Flex layout container. gap is clamped to 0–64
cardtitle?: string, children: GenuiNode[]Bordered group
listitems: (string | {label: string, value?: string})[]Bulleted list
tablecolumns: string[], rows: (string|number)[][]Renders with the same styling as a markdown table
keyvalueitems: {label: string, value: string}[]Two-column definition list
statlabel: string, value: string, delta?: string, tone?: "up"|"down"|"neutral"Metric card
badgetext: string, tone?: "default"|"success"|"warning"|"danger"|"info"Small pill
progressvalue: number (0–100), label?: stringProgress bar. value is clamped into range
callouttone?: "info"|"success"|"warning"|"danger", title?: string, text?: stringAlert box
dividernoneA rule between groups
codecode: string, lang?: stringMonospaced excerpt. Highlighted for javascript, typescript, go, python, bash, json, xml; any other lang renders as plain monospace rather than failing
linktext: string, href: stringOpens in a new tab. Only http://, https://, mailto: and tel: are accepted — anything else drops the whole node, since a link that cannot be followed still looks like one. Omit text and the href is shown instead
collapsibletitle: string, children: GenuiNode[], open?: booleanFoldable section. open seeds the first render only — after that the user's toggle wins, and it survives a reload
plotplot: "bar"|"line"|"area"|"pie", series: {name?: string, points: {label: string, value: number}[]}[], stacked?: boolean, legend?: boolean, xLabel?: string, yLabel?: string, height?: numberSee the plot notes below

Notes on plot: the x axis is the union of every series' labels in first-appearance order, so series need not agree on their labels or their length. A label a series has no point for is a gap: line breaks there rather than diving to zero, while bar/area draw it as zero. pie uses series[0] and ignores the rest. Under stacked, negative values are clamped to zero. Colours are assigned automatically and follow the user's theme — there is no colour field, and there is no type for colour or CSS anywhere in this table.

link is the only node carrying a URL, and it is the way to send the user somewhere — don't put a button on it, which would cost a whole turn just to hand back a link. There is no 3D node, and no diagram node: a flowchart or sequence diagram is a ```mermaid fence in the reply's own markdown, which the Web UI draws in place. Don't invent fields outside this table — anything not listed here is stripped before it reaches the renderer (see "Caps and what happens past them").

Interactive nodes (inline fence only)

These only work inside an inline ```octo-ui fence — the render_ui tool drops any of these types like any other unrecognized type, since its tool-card output has no path back to you for a click or a field change.

typeFieldsNotes
buttonlabel: string, action: string, payload?: object, variant?: "primary"|"default"|"danger"Fires the [octo-ui-action] feedback below
inputfield: string, label?: string, placeholder?: string, value?: stringAlways a plain text input — there is no inputType field, and one you send anyway is silently dropped; never render a password-style field here
selectfield: string, label?: string, options: {label: string, value: string}[], value?: string
checkbox / switchfield: string, label?: string, checked?: boolean
radiofield: string, label?: string, options: {label: string, value: string}[], value?: string
tabstabs: {label: string, children: GenuiNode[]}[]Each tab's children can be any node type, including nested interactive ones
sliderfield: string, min: number, max: number, step?: number, label?: string, value?: numbermax must exceed min or the node is dropped. step defaults to a hundredth of the range
numberfield: string, min?: number, max?: number, step?: number, label?: string, value?: numberA numeric input. Separate from input on purpose — input has no type switch at all, so no password-style field can exist
textareafield: string, label?: string, placeholder?: string, value?: string, rows?: numberLong free text; rows clamps to 2–12
quizfield: string, question: string, options: {label: string, value: string}[], correct: string, explanation?: stringScored in the browser the moment the user picks. The answer is visible in the page source, so use it as a comprehension aid, not an assessment

A field's current value is tracked live as the user changes it, independent of any button — when a button fires, the feedback message below carries the value of every field in the same fence at that moment, not just the button's own data.

Prefer local interaction over a round-trip

Most interaction should never reach you. A tab switch, a filter, a fold, a quiz answer, a slider drag — all of these resolve in the browser with no message and no turn, if you ship the data they need up front. Reach for a button only when the panel genuinely cannot answer by itself: fetching data it doesn't have, or taking a real-world action.

Three mechanisms make that possible, and they cost you nothing but a field:

visibleWhen — any node may carry a condition and render only when it holds:

json
{"type": "text", "text": "…", "visibleWhen": {"field": "mode", "equals": "advanced"}}

The condition is one of two families. Equality: equals, in (an array), or not — use exactly one; if you send several, only the first of that order survives. Range: any combination of gt, gte, lt, lte, all of which must hold, so {"gte": 10, "lt": 100} is the interval you would expect. A field the user has not touched compares as the empty string, and fails every range predicate — so a range-gated node stays hidden until its slider moves, which is usually what you want.

table.filterBy — {"field": "q", "column": "name"} filters the rows already in the table by an input's value, case-insensitively. column must name one of the table's own columns.

table.sortable — true makes the headers clickable, cycling unsorted → ascending → descending. A column sorts numerically when every cell in it is a number, lexicographically otherwise.

An input with nothing reading it is a control that does nothing. Every slider/number you add should be named by a visibleWhen or a filterBy, and every textarea should sit next to a submit button.

Show full SKILL.md (976 more words)Show less

Addressable panels and silent updates

Give a spec an id when the user is expected to act on it more than once:

json
{"id": "sales", "title": "Sales", "items": [ … ]}

An id is 1–64 characters of letters, digits, _ and -, unique within the conversation. A panel without one is a one-shot — correct for a summary nobody will touch again.

An id changes what happens when the user acts on the panel. Their action arrives with a panel key:

[octo-ui-action] {"panel": "sales", "action": "refresh", "fields": {"range": "30d"}}

Neither that message nor your reply to it is drawn in the conversation. Your reply replaces the panel in place, wherever it already sits.

For that to work your reply must be exactly one ```octo-ui fence carrying the same id, and nothing else — no sentence before it, no sign-off after it. Any prose turns the reply into an ordinary visible message, which is a correct fallback when you really do need to say something, but means the panel does not update in place. Choose one:

  • Updating the panel? Emit the fence alone.
  • Need to explain, refuse, or ask something? Write normally — say it, and include a fresh fence if the panel should also change.

Re-sending a panel inside an ordinary reply is not an error: it re-presents the panel at that point in the conversation, which is right when you are bringing it back up after other discussion.

Interaction state (field values, selected tab, fold state) belongs to the panel id and survives a page reload. When you send a new version of a panel, values whose fields still exist are kept and the rest are dropped — so a refreshed dashboard stays under the filter the user set.

The [octo-ui-action] feedback convention

When a user acts on a GenUI component you rendered earlier (clicks a button, submits a field, picks an option), their action reaches you as a normal new user turn whose text begins with the literal prefix [octo-ui-action] , followed by a JSON object:

[octo-ui-action] {"action": "refresh", "fields": {"range": "7d"}, "payload": {}}
  • action — the action name the interactive node declared.
  • fields — the current value of every interactive field the user has set (text inputs, selections, checkboxes) at the time they triggered the action.
  • payload — any fixed extra data you attached to that action when you rendered it.

Treat this exactly like any other user message: read the JSON and figure out what changed. Don't echo the raw JSON back to the user; respond to what it means.

How to answer depends on whether the envelope carries a panel key:

  • With panel — the strict form above applies: reply with exactly one fence carrying that id and no other text, and the panel updates in place with nothing added to the conversation. Prose makes it an ordinary visible reply instead.
  • Without panel — the panel was anonymous, so there is nothing to update in place. Reply however the change calls for: a fresh octo-ui fence, a render_ui call, or plain text.

Caps and what happens past them

Both the tool path and the inline-fence path enforce the same structural caps. Respect them yourself rather than relying on the renderer to catch an oversized spec — going over a cap doesn't fail your call, it silently trims:

  • Max tree depth: 8
  • Max total nodes per spec: 200
  • Max string field length: 500 characters (labels, text, badge text, etc.)
  • Max table cell length: 2000 characters
  • Max table rows: 500
  • Max table columns: 50
  • Max list/keyvalue items: 200
  • Max select/radio/quiz options: 50
  • Max tabs entries: 8
  • Max code / textarea default text: 5000 characters
  • Max plot series: 8; max points per series: 100
  • Max link href: 2000 characters — an over-long one drops the node rather than being truncated into a link pointing elsewhere
  • textarea rows: clamped to 2–12
  • A button's payload object: also depth- and width-capped (same depth limit as the node tree; up to 50 keys/entries per level), but that budget is separate from — not subtracted from — the 200-node total above.

An unrecognized type (including an interactive type sent through the render_ui tool, which only accepts the read-only table) causes just that node — and its subtree — to be dropped; its siblings still render. A spec with no valid items array is the one case that fails the render_ui tool call outright with an error you can see and retry.

Boundary with artifacts (write_file / edit_file / show_artifact)

GenUI and the Artifacts panel look similar from the outside — both let you produce something other than plain text — but they solve different problems, and routing the wrong content through the wrong one produces a bad result that won't error, it'll just look wrong:

  • Use write_file/edit_file/show_artifact when the output is a deliverable that should survive this reply: a document, a standalone interactive page, an image — something the user might reopen, export, or refer back to later, independent of this conversation turn.
  • Use render_ui/octo-ui for disposable structure inside this one reply that the user might act on right now — a quick comparison, a status summary, a small form — that has no reason to exist as a file.

The same line separates a plot node from a charting artifact. A chart the user is about to filter belongs in the panel. A visualization that is itself the deliverable — something needing a heatmap, a sankey, a map, brush-and-zoom, or a charting library's full expressiveness — belongs in an artifact, where you can write a real page with real code.

Never route a report-sized document or a large dataset through a GenUI table or list node just because the user asked for "a table." The guard caps above are enforced by silent truncation, not by a rejection you'd notice: a 900-row table becomes a 500-row table with no error, no warning in your tool result, and no indication to you that anything was cut. If the content genuinely doesn't fit inside a normal reply, that's the signal it belongs in a written artifact instead, not a signal to compress it into a GenUI node and hope the caps are generous enough.

© open-octo, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in internal/skills/defaults/genui of open-octo/octo-agent.

Open the folder on GitHubat commit fc1385f

Compare with similar skills

Genui next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Genui compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Genui this skillopen-octo/octo-agent125—~4.1kAutomated safety check: PassMIT
DeepTutor CLIHKUDS/DeepTutor41k—~2.8kAutomated safety check: PassApache-2.0
AI Engineering Placement Quizrohitg00/ai-engineering-from-scratch66k—~2kAutomated safety check: PassMIT
Codebase to Coursezarazhangrui/codebase-to-course5.7k—~4.4kAutomated safety check: PassNone
AI Engineering Phase Quizrohitg00/ai-engineering-from-scratch66k—~2.1kAutomated safety check: PassMIT
Scholar EvaluationK-Dense-AI/claude-scientific-writer2.4k2 repos~2.9kAutomated safety check: NotesMIT

Similar skills

  • DeepTutor CLI

    HKUDS/DeepTutor

    Teaches the agent to set up and run DeepTutor from the command line: chat and capabilities, knowledge bases, partners, memory, sessions, notebooks and the server or Web app.

    41k GitHub stars~2.8k tokensUpdated today
    EducationAuto-check passed
  • AI Engineering Placement Quiz

    rohitg00/ai-engineering-from-scratch

    Runs a 10-question quiz across five areas to place a learner in the AI Engineering from Scratch curriculum, so they skip what they already know.

    66k GitHub stars~2k tokensUpdated yesterday
    EducationAuto-check passed
  • Codebase to Course

    zarazhangrui/codebase-to-course

    Turns a codebase into an interactive single-page HTML course for non-technical learners, with scroll modules, animated diagrams, quizzes and plain-English code translations.

    5.7k GitHub stars~4.4k tokensUpdated 6 mo ago
    EducationAuto-check passed
  • AI Engineering Phase Quiz

    rohitg00/ai-engineering-from-scratch

    Quizzes you on a completed phase of the AI Engineering from Scratch course, taking a phase number or name and mapping it to that phase's directory.

    66k GitHub stars~2.1k tokensUpdated yesterday
    EducationAuto-check passed
  • Scholar Evaluation

    K-Dense-AI/claude-scientific-writer

    Provide qualitative-first, evidence-traceable developmental review of scholarly works and audit low-stakes research-assessment rubrics with optional local quality controls.

    2.4k GitHub starsUsed in 2 repos~2.9k tokens
    EducationAuto-check: notes
  • Evaluation

    guanyang/open-agent-hub

    This skill should be used when building agent evaluation systems: deterministic checks, regression suites, multi-dimensional rubrics, quality gates, production monitoring, baseline comparison, and…

    975 GitHub starsUsed in 2 repos~4.2k tokens
    EducationAuto-check passed

More from open-octo/octo-agent

All 40 skills in this repo
  • Image Gen

    open-octo/octo-agent

    Acquire images as files — generate them with an AI image model (14 providers: OpenAI/gpt-image, Gemini, Qwen, Zhipu, Volcengine, Stability, FLUX, Ideogram, MiniMax, and more), search openly-licensed…

    125 GitHub stars~3.1k tokensUpdated today
    Auto-check: notes
  • Office XLSX

    open-octo/octo-agent

    Create, read, and edit Excel (.xlsx) spreadsheets programmatically with openpyxl — cell values, formulas, styling (fonts/fills/borders/alignment/number formats), merged cells, multiple sheets…

    125 GitHub stars~1.8k tokensUpdated today
    Auto-check: notes
  • Artifact Design

    open-octo/octo-agent

    Design guidance for any HTML/Markdown file shown in octo's Artifacts panel — reports, dashboards, architecture/system diagrams, generated UIs, slide-style pages, 3D scenes.

    125 GitHub stars~2.7k tokensUpdated today
    Auto-check passed
  • Code Review

    open-octo/octo-agent

    Review local code changes. An agent skill from open-octo/octo-agent.

    125 GitHub stars~942 tokensUpdated today
    Auto-check passed
  • Ppt Master

    open-octo/octo-agent

    AI-driven multi-format SVG content generation system. An agent skill from open-octo/octo-agent.

    125 GitHub stars~23k tokensUpdated today
    Auto-check: warnings
  • Config Setup

    open-octo/octo-agent

    Configure octo's global settings through guided conversation — set up AI model endpoints (providers, API keys, models), adjust agent defaults (reasoning effort, permission mode, coauthor, workspace…

    125 GitHub stars~3.3k tokensUpdated today
    Auto-check passed

Categories

Questions about Genui

What does Genui do?

Render structured, glanceable, interactive UI in the chat instead of plain text — dashboards, stat cards, filterable tables, charts, choice panels, forms, quizzes. Genui is an agent skill from open-octo/octo-agent. Render structured, glanceable, interactive UI in the chat instead of plain text — dashboards, stat cards, filterable tables, charts, choice panels, forms, quizzes.

When should I use Genui?

Genui fits situations like: tasks that involve Quizzes and assessments.

How do I install Genui in Claude Code?

Run `npx skills add open-octo/octo-agent --skill genui -a claude-code`. Or copy the skill folder (internal/skills/defaults/genui in open-octo/octo-agent) into .claude/skills/genui in your project. Claude Code loads it when a task matches its description.

How do I install Genui in Codex?

Run `npx skills add open-octo/octo-agent --skill genui -a codex`. Or copy the skill folder (internal/skills/defaults/genui in open-octo/octo-agent) into .agents/skills/genui in your project. Codex loads it when a task matches its description.

Can I use Genui in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add open-octo/octo-agent --skill genui -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/genui, .gemini/skills/genui, .github/skills/genui and .opencode/skills/genui in your project.

What does Genui need to run?

SKILL.md names no scripts, command-line tools or credentials: Genui is instructions for the agent only.

Does Genui access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Genui safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Genui use?

Genui is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Genui use?

About 4.1k tokens (SKILL.md is roughly 16k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Genui?

Skills that share tags, products or a category with Genui: DeepTutor CLI (HKUDS/DeepTutor, 41k stars), AI Engineering Placement Quiz (rohitg00/ai-engineering-from-scratch, 66k stars), Codebase to Course (zarazhangrui/codebase-to-course, 5.7k stars) and AI Engineering Phase Quiz (rohitg00/ai-engineering-from-scratch, 66k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Genui?

open-octo (a GitHub organization) maintains it in open-octo/octo-agent, which has 125 GitHub stars. The repository holds 40 skills in this directory. The repository was last updated on October 8, 2026.

Source: open-octo/octo-agent on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.