Skip to content

Agent Console

The operator’s half of an agent product: the approval queue it opens on, a run trace with tool calls, retries and cost, and the chat surface behind them.

6 routes6 pages · 20 blocks37 files · 5,462 lineslucide-reactAdded 10 Sept 2026

What's included

  • app/chat/page.tsx
  • app/globals.css
  • app/layout.tsx
  • app/login/page.tsx
  • app/not-found.tsx
  • app/page.tsx
  • and 10 more files
  • 6 pages it is built from, installed with it
  • Needs lucide-react

Works with

  • React
  • Next.js
  • Tailwind CSS
  • TypeScript

npx hoverlab init agent-console ./my-app

Or over MCP, from your editor's agent — no account needed.

License

Free to read, copy and install, for personal and non-commercial projects. Shipping it in client work or a paid product needs Pro ($79 once). The source lands in your repo and stops being ours — no attribution, nothing to upgrade.

Was this useful?

Every screen

Approvals

What needs a person, what has been waiting too long, and the rules that decided both.

Waiting for you

6 actions the agent will not take on its own · 2 must be opened individually

Actions awaiting approval. High-impact actions have no bulk checkbox and must be opened individually.
Select the 4 actions that can be approved in bulkActionAmountDeadline

Refund order 41822

Damaged on arrival · photo attached · customer since 2023

£38.00Auto-approves in 3h

Refund order 41830

Never delivered · carrier confirmed loss

£12.50Auto-approves in 3h

Refund order 41833

Duplicate charge · matched to payment intent pi_3Qk

£64.00Auto-approves in 6h

Close account for Meridian Foods

Requested by an admin · 41 users · 3 years of data

Deletes data — opens individually

—Open Close account for Meridian Foods

Refund order 41840

Late delivery · goodwill, within policy

£9.99Auto-approves in 12h

Issue account credit to Halden Group

Outage compensation · agent proposed 3 months

Above the bulk limit — opens individually

£4,200.00Open Issue account credit to Halden Group

Waiting on a person

Sorted by age, not arrival. A queue sorted newest-first buries the item that has been stuck longest, which is always the one that turns into the complaint.

What runs without asking

Approval prompts are trusted in proportion to how predictable they are. Someone who cannot say in advance which actions will stop and ask learns to approve everything.

Live components in your current theme — switch routes, or the phone icon to check the mobile layout. Colours are this template’s Slate palette, which ships in app/globals.css. Blue-grey neutrals and a primary dark enough to be ink. An operator console spends its colour on status, not on chrome, so the chrome has almost none.

Get it

37 files · .zip · nothing to configure · Pro

then

cd agent-console
npm install
npm run dev

The archive contains the whole project — routes, blocks, theme tokens, Tailwind and PostCSS config, tsconfig and a .gitignore. One runtime dependency, and no Hoverlab dependency at all: it is your code from the moment it unzips.

For AI

The component, its props, the design tokens it expects and the command that installs it — as one prompt. Paste it into Claude, Cursor, v0 or ChatGPT and what they build around it will match the rest of the catalog instead of inventing its own system.

See the prompt

Routes

PathPageFile
/Approvals Inboxapp/page.tsx
/runs/[id]Agent Run Detailapp/runs/[id]/page.tsx
/chatAI Assistant Screenapp/chat/page.tsx
/settingsAccount Settingsapp/settings/page.tsx
/loginSign-In Screenapp/login/page.tsx
404404 Pageapp/not-found.tsx

What you get

project root(8 files)

  • GETTING-STARTED.md
  • gitignore
  • next.config.ts
  • package.json
  • postcss.config.mjs
  • README.md
  • tailwind.config.ts
  • tsconfig.json

app/(8 files)

  • chat/page.tsx
  • globals.css
  • layout.tsx
  • login/page.tsx
  • not-found.tsx
  • page.tsx
  • runs/[id]/page.tsx
  • settings/page.tsx

components/(21 files)

  • agent-cost-breakdown.tsx
  • agent-retry-log.tsx
  • agent-thinking-trace.tsx
  • agent-tool-calls.tsx
  • ai-insight-cards.tsx
  • approval-policy-list.tsx
  • approval-queue.tsx
  • approval-request-card.tsx
  • auth-login-card.tsx
  • chat-prompt-bar.tsx
  • chat-streaming-answer.tsx
  • dashboard-shell.tsx
  • escalation-queue-list.tsx
  • knowledge-source-picker.tsx
  • not-found-404.tsx
  • settings-api-keys.tsx
  • settings-danger-zone.tsx
  • settings-nav-layout.tsx
  • settings-profile-form.tsx
  • settings-team-members.tsx
  • theme-provider.tsx

Every file is listed. The 20 files in components/ are the blocks the pages import — each one has its own page if you want to read it on its own.

Project files

Everything except the blocks. Opens on app/globals.css — the file that makes the rest look right, since every block styles itself with bg-card and text-muted-foreground rather than literal colours.

app/globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;

/**
 * Design tokens — the Slate palette.
 *
 * Blue-grey neutrals and a primary dark enough to be ink. An operator console spends its colour on status, not on chrome, so the chrome has almost none.
 *
 * This file is the reason a pasted block looks right. Every block and page
 * styles itself with semantic classes — `bg-card`, `text-muted-foreground`,
 * `border-border` — rather than literal colours, so they inherit whatever
 * you define here instead of fighting it. Change a value below and every
 * section in the project moves with it. Change the hue on `--primary` and
 * `--ring` together and you have rebranded the site.
 *
 * Values are bare HSL channels, not `hsl(...)` calls. That is what lets
 * Tailwind compose them with an alpha suffix: `bg-primary/10` expands to
 * `hsl(var(--primary) / 0.1)`, which is impossible if the variable already
 * carries its own function wrapper.
 *
 * Every foreground/background pair below clears WCAG AA (4.5:1) in both
 * themes. If you retune one, check the pair rather than trusting the eye —
 * mid-lightness accents are the ones that fail.
 */

@layer base {
  :root {
    --background: 216 24% 98%;
    --foreground: 216 32% 10%;
    --card: 0 0% 100%;
    --card-foreground: 216 32% 10%;
    --popover: 0 0% 100%;
    --popover-foreground: 216 32% 10%;
    --primary: 216 20% 26%;
    --primary-foreground: 216 24% 98%;
    --secondary: 216 20% 94%;
    --secondary-foreground: 216 32% 18%;
    --muted: 216 18% 95%;
    --muted-foreground: 216 12% 40%;
    --accent: 196 45% 92%;
    --accent-foreground: 198 55% 18%;
    --destructive: 0 72% 45%;
    --destructive-foreground: 0 0% 100%;
    --border: 216 16% 89%;
    --input: 216 16% 89%;
    --ring: 216 20% 26%;

    --radius: 0.375rem;
  }

  .dark {
    --background: 216 28% 6%;
    --foreground: 216 14% 96%;
    --card: 216 24% 9%;
    --card-foreground: 216 14% 96%;
    --popover: 216 24% 9%;
    --popover-foreground: 216 14% 96%;
    --primary: 216 14% 96%;
    --primary-foreground: 216 32% 10%;
    --secondary: 216 18% 15%;
    --secondary-foreground: 216 14% 96%;
    --muted: 216 18% 15%;
    --muted-foreground: 216 10% 66%;
    --accent: 196 32% 17%;
    --accent-foreground: 196 50% 84%;
    --destructive: 0 62% 52%;
    --destructive-foreground: 0 0% 100%;
    --border: 216 16% 18%;
    --input: 216 16% 18%;
    --ring: 216 14% 96%;
  }
}

@layer base {
  * {
    @apply border-border;
  }

  body {
    @apply bg-background text-foreground antialiased;
  }

  /**
   * Global motion opt-out.
   *
   * Blocks guard their own animations with Tailwind's `motion-safe:`, but
   * third-party CSS and anything you add later will not. This is the
   * backstop: it neutralises every animation and transition on the page
   * for users who have asked the OS for reduced motion, rather than
   * relying on each author to remember.
   */
  @media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
      scroll-behavior: auto !important;
    }
  }
}

More Full Product

Pro
Open the full page for this template

SaaS Starter

The signed-in half

The whole thing: marketing site, sign-in, dashboard, customer list, settings and billing. Eight routes, one runtime dependency.

8 routes8 pages30 blocksIris
Pro
Open the full page for this template

AI Assistant

The streaming answer, with its citations

An agent product’s working surface: transcript, reasoning, tool calls and the approval card, with sign-in and settings around it. Wiring a model in is your half.

4 routes4 pages14 blocksOrchid