affectUI › Components › Agents

Running Now

A live status of background agent tasks for a header or sidebar – one quiet pill, "3 running · 2 need you"; open it for the tasks with a filling ring, the step each is on and its steps, Pause and Resume, and Open on the ones that wait for you.

Part of affectUI Pro. Install: npx shadcn@latest add https://www.affectui.com/r/running-now.json · Import from @/components/ui/running-now

When to use

  • An app header or sidebar that should always say what the agents are doing in the background – and whether any of it waits for you
  • Pausing, resuming or opening a task from anywhere, without going to a full task list

When not to use

  • The full list of tasks with filters and details – use the Agent / Tasks screen
  • One run step by step – use Agent Monitor or Trace Waterfall
  • A decision with its context – use Approval Gates or Decision Inbox

Usage

import { RunningNow, type RunningTask } from "@/components/ui/running-now";

const tasks: RunningTask[] = [
  { id: "ingest", title: "Ingest pipeline", step: "Embedding chunks", done: 2, total: 4, state: "running" },
  { id: "refund", title: "Refund review", step: "Approve a $240 refund to Acme", done: 1, total: 3, state: "needs-you" },
  { id: "deps", title: "Dependency upgrade", step: "Running 212 tests", done: 1, total: 4, state: "paused" },
];

export function Header() {
  return (
    <header>
      <RunningNow tasks={tasks} onPause={pause} onResume={resume} onOpen={openTask} onOpenAll={() => navigate("/tasks")} />
    </header>
  );
}

Props

NameTypeDefaultDescription
tasksRunningTask[]{ id, title, step, done, total, state } – in the order they should be listed; the list keeps that order, so rows never swap places
state"running" | "paused" | "needs-you" | "done"Per task – running shows Pause, paused shows Resume, needs-you shows a badge and Open, done a full blue ring
onPause / onResume(id) => voidThe icon button on a running or paused row
onOpen(id) => voidA click on a row, or Open on a task that needs you
onOpenAll() => voidShows the "Open Tasks" footer and runs on click
defaultOpenbooleanfalseStarts open
open / onOpenChangeboolean / (open) => voidControl the popover from outside
align"start" | "end""end"Which edge of the trigger the popover lines up with – end for a header's right side, start for a sidebar
labelsPartial<RunningNowLabels>Every word: title, running, needsYou, needsYouOne (for exactly one – "1 needs you"; falls back to your needsYou), needsYouBadge, paused, pausedCount (the trigger when only paused tasks are left – "5 paused"), done, pause, resume, open, openAll, empty, idle (nothing at all – "No tasks running")
classNamestringExtra class on the root

Keyboard

  • Enter / Space: On the trigger: opens the list and moves to the first task, or closes it
  • ↓ / ↑: On the trigger: opens the list and moves to the first or the last task
  • ↑ / ↓ / Home / End: Moves between the tasks – from a row or from its button
  • Tab: From a task to its Pause, Resume or Open button, then on to the next task
  • Esc: Closes the list and puts focus back on the trigger

Accessibility

  • The trigger says the whole summary – "Background tasks: 3 running, 2 need you" – and has aria-haspopup, aria-expanded and aria-controls
  • The list is a dialog named "Background tasks"; a click outside or tabbing out of it closes it
  • Each row is a button that reads its title, state, step and steps – "Ingest pipeline – running. Embedding chunks. 2 of 4 steps"
  • Every icon button names its task – "Pause Ingest pipeline", "Open Refund review – needs you"
  • A polite live region says when a task starts waiting for you or finishes
  • Focus never drops to the page: Pause and Resume keep it on the same button, and when a task finishes (or leaves the list) it moves to that row or the nearest one
  • Focus rings show for the keyboard only (:focus-visible), in light and dark

Responsive

  • Every row is 52px in every state – a step that changes, a badge that comes or goes never moves another row
  • The popover is 348px wide and never wider than the screen minus 32px, so it fits a 375px phone
  • Touch screens get 36px buttons, a 36px trigger and 56px rows
  • The list scrolls inside the popover after five and a half rows – the half row shows there is more – and stays clear of short screens
  • On a phone narrower than 360px, or with four-digit counts below 420px, the trigger keeps only the numbers when both counts show; its label still reads the full summary
  • Right-to-left: the popover lines up with the logical edge, titles and steps follow their own direction
  • Dark mode built in: switches when an ancestor (usually <html>) has the class dark or data-theme="dark"

Requirements

  • React 19

Related

  • Agent Monitor – One agent at work, as a card – its current step with a clock and the bill so far, a time strip and the finished steps with the logo of each tool, a click on any of them for the details; the exact command when it needs your OK; folds into a small bar with the tools it has used
  • Approval Gates – The approval requests of an agent run as a stack of cards – the one to decide now on top with who asks, what exactly and why, the diff or arguments on it; approve, reject or change it first, and it drops into the decided list while the next rises – open ones hold the steps behind them
  • Agent Fleet – Several agents side by side – each card sums up its sub-agents, and a click opens its tree to the right while the last one folds back into its card
  • Agent Queue – The work waiting for your agents, and how fast it moves – jobs drop into a live queue, glide into free worker slots as growing bars and land in Done or Failed, while a depth chart shows the backlog build up when a rate limit pauses the workers and drain when they resume