Skip to content
Kura

Prompt Queue

experimental

Stack of follow-up prompts queued while an agent works: reorder, edit inline, remove, or Send now to steer. Renders nothing when empty.

@kura-ui/react/prompt-queueCopy for agentsMarkdownRegistry JSON

Two queued prompts

minimal

Queued2

Sends when the agent finishes this turn
  1. When tests pass, update the auth section of the README
  2. Don't touch src/legacy/ — it's deleted next sprint

Alt plus arrow keys or Space then arrows to reorder. Enter to edit, Delete to remove, Control or Command plus Enter to send now.

Controlled, with steering

Attachments, a prompt that arrives after mount, and Send now reported below.

full

Queued3

Sends when Kura finishes running pnpm test
  1. Use the refreshSession() helper instead of calling fetch('/api/session') directlysession-flow.png
  2. Don't touch src/legacy/ — it's being deleted next sprint
  3. When tests pass, update the auth section of the README and link the migration guideMIGRATION.md+1

Alt plus arrow keys or Space then arrows to reorder. Enter to edit, Delete to remove, Control or Command plus Enter to send now.

Hover a prompt, or focus it and use Alt+↑/↓, Enter, Delete and ⌘↵.

Tray

Rounded on top only, tucked onto the input below.

variant

Queued2

Sends when the agent finishes this turn
  1. Use the refreshSession() helper instead of calling fetch('/api/session') directlysession-flow.png
  2. Don't touch src/legacy/ — it's being deleted next sprint

Alt plus arrow keys or Space then arrows to reorder. Enter to edit, Delete to remove, Control or Command plus Enter to send now.

Above a composer

Messages sent while the agent works are queued; Send now steers.

composition

Run pnpm test --filter web

Elapsed
–:––
Run running

Queued2

Sends after this turn
  1. Use the refreshSession() helper instead of calling fetch('/api/session') directlysession-flow.png
  2. Don't touch src/legacy/ — it's being deleted next sprint

Alt plus arrow keys or Space then arrows to reorder. Enter to edit, Delete to remove, Control or Command plus Enter to send now.

Installation

npx shadcn@latest add https://kuro.abstergo.fyi/r/prompt-queue.json

Copies the source into components/kura/prompt-queue with its dependencies (kura-theme, button, icon-button, kura-motion, use-controllable-state, use-reduced-motion, utils). Tokens come from the kura-theme item.

When to use it

Use it for

  • The user types follow-ups while an agent is mid-turn (Claude Code / Codex queued messages) and they should send in order when it finishes.
  • Letting the user steer: interrupt the agent and send one queued prompt immediately.
  • Directly above a composer (variant='tray') so queued prompts read as part of the input.

Reach for something else when

  • Suggested prompts the user has not written — use prompt-suggestions.
  • The prompt input itself — use composer (and put PromptQueue above it).
  • Work the agent plans to do — use task-list.

Props

PropTypeDefaultDescription
itemsQueuedPrompt[]—Queued prompts in send order (controlled): { id, text, attachments?: { name, type?: 'image' | 'file' }[] }.
defaultItemsQueuedPrompt[]—Initial prompts when uncontrolled.
onItemsChange(items: QueuedPrompt[]) => void—Called with the whole new list after a reorder, edit, remove or Send now. Fires on every step while dragging.
onSendNow(item: QueuedPrompt) => void—Steer: interrupt the agent and send this prompt now. The prompt is removed from the queue first. Without it no Send now button renders.
titleReact.ReactNode"Queued"Header title; the count follows it.
hintReact.ReactNode"Sends when the agent finishes this turn"Secondary header text, e.g. 'Sends when Kura finishes running pnpm test'. null hides it.
variant"panel" | "tray""panel"panel = standalone card; tray = sunken, rounded on top only, meant to sit flush on top of a Composer (inset it with className='mx-3').

All native attributes of the root element, className and ref pass through.

Anatomy

  1. PromptQueueRoot with `data-variant`.data-slot="prompt-queue"
  2. HeaderTitle, count and prompt-queue-hint.data-slot="prompt-queue-header"
  3. ItemFocusable <li> (`data-state` = editing | dragging): index (grip on hover), text, attachments, actions.data-slot="prompt-queue-item"
  4. HandleDrag grip shown in place of the index on hover (pointer only; keyboard uses Alt+arrows or Space).data-slot="prompt-queue-handle"
  5. TextOne truncated line; the full text is the title tooltip.data-slot="prompt-queue-text"
  6. AttachmentsFirst attachment's icon and name in mono, then '+N'.data-slot="prompt-queue-attachments"
  7. ActionsMove up, Move down, Edit, Remove and prompt-queue-send ('Send now'); shown on hover/focus, always on touch.data-slot="prompt-queue-actions"
  8. EditorAuto-growing textarea replacing the row while editing, with Cancel/Save.data-slot="prompt-queue-editor"

Accessibility

  • Role: list (ol) of focusable items
  • The list is labelled by the title and described by visually hidden keyboard help. Items use a roving tabindex (one Tab stop) and are named '2 of 3: <text>'.
  • A polite status region announces moves ('Moved to position 1 of 3'), removals and Send now. Actions are icon buttons with tooltips.
  • Escape in the editor cancels without reaching the composer's own Escape (stop) handler.
  • Reduced motion: Reorders jump into place instead of sliding; the drag still follows the pointer.
KeysAction
ArrowUp / ArrowDownMove focus between prompts
Alt+ArrowUp / Alt+ArrowDownMove the focused prompt up / down
Space, then arrows, then SpaceGrab, move and drop (Escape restores)
Enter / F2Edit inline (Enter saves, Shift+Enter newline, Escape cancels)
Delete / BackspaceRemove
Mod+EnterSend now

Notes for agents

  • When the agent finishes a turn, shift the first item off `items` and send it yourself — the component never sends on its own.
  • onSendNow means 'interrupt and send': stop the current turn in your harness before sending.
  • Keep ids stable across edits; reordering and focus rely on them.
  • Empty queue renders only a visually hidden status region, so you can leave it mounted above the composer.