Configuration
Everything you can tune lives in ai-ops-dashboard.config.ts. The file exports a single config: AiOpsDashboardConfig object. It's re-read on every render in dev, and at build time for production.
Schema reference
export type AiOpsDashboardConfig = {
product: ProductInfo
theme: "dark" | "warm" | "paper" | string
projectRoot?: string
defaultTab?: PanelId
refreshSeconds: number
panels: PanelDefinition<any>[]
banner?: BannerDefinition
footer?: ComponentType<{ context: PanelLoaderContext }>
branding?: {
logo?: ReactNode
accent?: string
showPoweredBy?: boolean
}
}product
Identity strings rendered in the header and <head>.
| Field | Type | Required | What it does | |---|---|---|---| | title | string | yes | Big title in the header. Also <title>. | | tagline | string | yes | One-liner under the title. | | description | string | yes | <meta name="description"> content. | | eyebrow | string | no | Small uppercase chip rendered above the title. E.g. "Internal", "Preview". |
theme
A string keying a CSS preset registered in app/globals.css. Three ship by default:
"dark"โ slate background, blue accent. Default."warm"โ amber-toned, paper-feel."paper"โ light, minimal, print-feel.
To register a custom theme, add a data-theme="<name>" block to app/globals.css:
[data-theme="midnight"] {
--color-bg: #06080f;
--color-bg-elev: #0d1220;
--color-fg: #e3e8f5;
--color-fg-muted: #8b94aa;
--color-fg-soft: #5a647d;
--color-accent: #6ea8ff;
--color-accent-soft: #95c1ff;
--color-success: #4ade80;
--color-warning: #fbbf24;
--color-danger: #f87171;
--color-border: #1d2538;
}Then reference it in config: theme: "midnight". See panels.md for the CSS variables panels rely on.
projectRoot
Path relative to the config file, used to resolve data sources. Defaults to "." (project root). Set it to "../my-real-project" if you want one AI Operations Dashboard install to monitor a sibling project.
defaultTab
Panel id that loads when no ?tab= query param is present. Defaults to the first panel in panels[].
defaultTab: "overview" // must match a panel.id belowrefreshSeconds
Auto-refresh cadence in seconds. The dashboard is read-only, so a hard refresh re-runs every panel loader and shows the latest data.
120โ every 2 minutes. Good default for live monitoring.0โ disabled. The page is static until you reload.30โ aggressive; only useful if your data files change minute-to-minute.
Implemented via <meta http-equiv="refresh"> in SSR mode and via a periodic fetch in static mode.
panels
Ordered array of PanelDefinition objects. The order here is the order they appear in the tab strip. Drop a panel by removing its entry; add a custom one by importing it and pushing into the array. Full panel API: panels.md. (The array below is an illustrative subset, not the full default set โ the default config ships all 12 built-ins.)
panels: [
overview,
plan,
sprints,
activity,
pending,
log,
postmortems,
usage,
scheduled,
myCustomPanel,
]banner
Optional top-of-page banner. Ships with spendBanner which reads data/usage.json and surfaces a colored bar when daily spend crosses a threshold.
banner: spendBanner // shipped
banner: undefined // disabled
banner: myBanner // your own โ see lib/panels/types.ts BannerDefinitionfooter
Optional React component rendered below all panels. Receives the same PanelLoaderContext as panels (project root, current time, search params).
branding
branding: {
logo: <img src="/logo.svg" alt="Acme" className="h-6" />,
accent: "#ff6b6b", // overrides --color-accent
showPoweredBy: false, // hide "Powered by AI Operations Dashboard" footer link
}The "Powered by AI Operations Dashboard" line in the footer is required on the free tier. Paid licenses can set showPoweredBy: false.
Complete example
import type { AiOpsDashboardConfig } from "@/lib/panels/types"
import { panel as overview } from "@/components/panels/overview-panel"
import { panel as plan } from "@/components/panels/plan-panel"
import { panel as activity } from "@/components/panels/activity-panel"
import { panel as pending } from "@/components/panels/pending-panel"
import { panel as usage } from "@/components/panels/usage-panel"
import { spendBanner } from "@/components/dashboard/spend-banner"
export const config: AiOpsDashboardConfig = {
product: {
title: "Acme HQ",
tagline: "What's shipping this week.",
description: "Acme internal operator dashboard.",
eyebrow: "Internal",
},
// Theme: dark / warm / paper, or a custom name registered in globals.css.
theme: "warm",
// Default tab. Must match one of the panel ids below.
defaultTab: "overview",
// Refresh every 60 seconds. Set to 0 to disable.
refreshSeconds: 60,
// Order = tab strip order. Drop or reorder freely.
panels: [overview, plan, activity, pending, usage],
// Top spend banner. Set to undefined to hide.
banner: spendBanner,
branding: {
accent: "#d97706",
showPoweredBy: false, // requires a paid license
},
}Multiple configs
Common pattern: one ai-ops-dashboard.config.prod.ts and one ai-ops-dashboard.config.dev.ts, swapped in CI:
cp ai-ops-dashboard.config.prod.ts ai-ops-dashboard.config.ts && npm run buildThe examples/ folder ships three starter configs (ai-project-tracker, indie-product-ops, personal-os). Each is a ~30-line drop-in. See examples/README.md.
Next
- panels.md โ write your own panel.
- deployment.md โ ship it.
- faq.md โ common questions.