Build interactive HTML widgets (simulators, explorers, calculators, UI mockups) inline in desktop conversations with render_widget.
78%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./resources/bundled-skills/gen-ui/SKILL.mdCopyright (c) 2026 KunAgent. Licensed under the MIT License.
Use render_widget to show a small interactive page inside the current desktop conversation. It is available only when the tool is advertised for this turn.
render_chart when advertised), or decoration.render_widget with title (short, user facing) and html (an HTML fragment). Use path instead of html only to re-render an existing .html file in the workspace.<style> and <script>. No <!doctype>, <html>, <head> or <body>.document.getElementById. Never depend on document.currentScript.mode: "wide" only for a full desktop application mockup or panels that must stay side by side. Everything else uses the default inline mode.fetch, XHR, WebSocket, forms that submit, window.open, or browser storage for important data. The page has no network access except static libraries.https://cdn.jsdelivr.net/npm/d3@7.9.0/dist/d3.min.js, https://cdn.jsdelivr.net/npm/echarts@5.6.0/dist/echarts.min.js, https://cdn.jsdelivr.net/npm/lucide@0.544.0/dist/umd/lucide.min.js. Use these exact URLs in a literal <script src="…">.--foreground, --muted-foreground, --card, --muted, --border, --brand, --destructive, --success, --warning, and --viz-series-1 … --viz-series-6 for data series..card, .stack, .row, .grid-2, .grid-3, .btn, .btn-primary, .badge, .form-label, .text-muted, .text-small, .tabular-nums, .viz-dotted-background. Form controls, tables and SVG text already follow the theme.--muted-foreground, never lighter. Use one accent for the primary measure; add series colors only for real categories.light-dark() when it should follow the theme) instead of the widget classes, and frame small mockups on .viz-dotted-background.ResizeObserver), and keep labels at 11px or larger.window.kun.widgetState is the last saved snapshot ({ modelContent, privateContent }) or null. Restore from it on load and on the kun:set_globals window event.window.kun.setWidgetState({ modelContent, privateContent }).catch(() => {}). The snapshot is at most 16 KiB. modelContent holds choices the user may ask about next (it is attached to their next message); privateContent holds view details worth restoring. Never save on load.await window.kun.sendFollowUpMessage({ prompt, title }) with the selected values in the prompt. The user may be asked to confirm.<a href="https://…"> anchors, or call window.kun.openExternal({ href }) from a click handler. Only http(s) URLs open..tabular-nums.KunAgent/Kun
0d84061
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.