SPRINKLE(1) — Persistent .shtml UI Panels

SYNOPSIS

sprinkle list
sprinkle open <name>
sprinkle close <name>
sprinkle refresh
sprinkle send <name> <json>
sprinkle chat <html>

DESCRIPTION

Sprinkles are persistent UI panels built from .shtml files. They live in /shared/sprinkles/<name>/<name>.shtml on the VFS. Sprinkles are created by scoops, outlive the scoops that created them, and are managed via the sprinkle shell command. They appear as tabs in the sidebar (standalone) or as additional panels (extension mode).

Sprinkles are discovered automatically by scanning the VFS. The priority root is /shared/sprinkles/, then the entire VFS. The sprinkle name is the basename without .shtml. Titles are extracted from data-sprinkle-title attributes, then <title> tags, falling back to the basename.

Add data-sprinkle-autoopen to any element in the .shtml to auto-open the sprinkle on first run.

RULES

LICK EVENTS

Button clicks and user interactions inside a sprinkle trigger lick events. Sprinkle licks always route to the cone first. The cone must NEVER handle a lick itself — always forward it to the owning scoop via feed_scoop.

Lick flow:

User clicks button in sprinkle
  → slicc.lick({action: "refresh", data: {...}})
  → lick event routed to cone
  → cone calls feed_scoop("dashboard", "Lick event on YOUR sprinkle...")
  → scoop processes the action
  → scoop pushes updates via: sprinkle send dashboard '{"key":"value"}'

PANEL SPRINKLES vs INLINE SPRINKLES

Panel sprinkles are persistent .shtml files on the VFS, opened via the sprinkle command. They have the full bridge API (lick, onUpdate, readFile, setState, getState, open, close) and survive across sessions.

Inline sprinkles are ```shtml code blocks in chat messages. They are rendered as sandboxed iframes after streaming completes. They have a minimal bridge (lick-only, no state persistence, no readFile). Inline sprinkle licks route to the cone as sprinkle lick events with sprinkleName "inline".

SPRINKLE CHAT

sprinkle chat renders a blocking inline HTML card in the chat. It waits for the user to click a button and returns the action as JSON. Use data-action attributes on buttons for callbacks.

sprinkle chat '<div class="sprinkle-action-card">
  <div class="sprinkle-action-card__header">Confirm?</div>
  <div class="sprinkle-action-card__actions">
    <button class="sprinkle-btn" data-action="cancel">Cancel</button>
    <button class="sprinkle-btn sprinkle-btn--primary" data-action="ok">OK</button>
  </div>
</div>'

Returns JSON like {"action":"ok","data":{}} on stdout. Can also receive HTML via stdin: echo "<div>...</div>" | sprinkle chat

BRIDGE API

Inside .shtml files, the bridge is available as both "slicc" and "bridge" in script tags and onclick attributes.

STYLE GUIDE

Use the built-in .sprinkle-* CSS classes. Do NOT write custom CSS. Theme variables and component rules are auto-injected into sprinkle iframes.

SUBCOMMANDS

EXAMPLES

# Create a sprinkle via scoop (cone does this)
scoop_scoop("dashboard")
feed_scoop("dashboard", "You own the sprinkle 'dashboard'.
1. Read /workspace/skills/sprinkles/style-guide.md
2. Write /shared/sprinkles/dashboard/dashboard.shtml
3. Run: sprinkle open dashboard
4. Stay ready for lick events — do NOT finish.")

# Push data to a sprinkle (scoop does this)
sprinkle send dashboard '{"scores":[95,87,72],"status":"ready"}'

# Forward a lick event (cone does this)
feed_scoop("dashboard", "Lick event on YOUR sprinkle 'dashboard':
Action: 'refresh'
Data: {\"id\": 42}
Process the action and push updates via sprinkle send.
Stay ready for more events.")

# Button with lick in .shtml
<button class="sprinkle-btn sprinkle-btn--primary"
  onclick="slicc.lick({action: 'refresh', data: {id: 42}})">
  Refresh
</button>

# Listen for updates in .shtml
<script>
slicc.on('update', function(data) {
  if (data.scores) renderScores(data.scores);
});
</script>

# Quick confirmation via sprinkle chat
sprinkle chat '<div class="sprinkle-action-card">
  <div class="sprinkle-action-card__header">Deploy to production?</div>
  <div class="sprinkle-action-card__actions">
    <button class="sprinkle-btn" data-action="cancel">Cancel</button>
    <button class="sprinkle-btn sprinkle-btn--primary" data-action="deploy">Deploy</button>
  </div>
</div>'

# Also opens sprinkles
open /shared/sprinkles/dashboard/dashboard.shtml

SEE ALSO

man scoops — Scoop management (scoop_scoop, feed_scoop, drop_scoop). man licks — External event system (webhooks, cron, sprinkle licks). /workspace/skills/sprinkles/style-guide.md — Full CSS component reference. /workspace/skills/sprinkles/SKILL.md — Sprinkle creation skill for scoops.