Dashboard

Web UI started by serve. Use it to finish setup, add repositories, run init / sync, tune auto-review, watch jobs, and manage remote review tokens. Webhooks and the job worker run in the same process as the UI.

What it is for

flowchart TD login[Sign in] --> setup["Get started (/setup)"] setup --> add[/repos/new/] add --> init[Init job on Activity] init --> ready[Repo overview] ready --> auto[Repo settings: auto-review] ready --> pr[Pull requests: manual review] ready --> tok[Settings: remote tokens] tok --> remote[Developers: review --remote]
Goal Where to go
First-time server setup Get started on home or /setup, then Settings
Onboard a repo Add repository, wait on Activity
Refresh guides after main moves Repo Overview or Settings (Sync), or a cron schedule in repo Settings (Scheduled sync)
Team laptops without local init Settings remote tokens, repo Remote tab
Debug a failed job Activity job detail

Before you open

Check Why
serve is running Dashboard is not a separate install
Dashboard URL from startup log Default http://localhost:<port>/
Password or GitHub sign-in See Sign in and serve: Sign in
Browser on a host that can reach the server Same network or VPN as production
A webhook URL GitHub can reach The repo Overview warns when it cannot

/dashboard redirects to /.

Webhook reachability

A fresh serve defaults to http://localhost:<port>/github/webhook, which GitHub cannot route to, so automatic reviews silently never arrive. Every repo Overview states this: a bad-address notice when the configured webhook URL host is loopback, 0.0.0.0, or a private range, and a "No webhook delivery yet" notice when nothing has been received. Both name the current URL and link to Settings.

Once a delivery has arrived, the page shows Last webhook delivery instead. The check only inspects the host. A single-label internal name and any public host pass, and serve and set still accept every URL they did before.

Adding a repository

Add repository runs the same read-only probe the CLI runs, server side, then shows the recommended init command with an estimated job count, token range, time and cost. Nothing is written until Add and start init is pressed, and that confirmation stores the plan's flags, limits and sources for the repo before the init job is queued, so the run matches what was approved.

The estimate says whether it used this repository's recorded jobs or the cm-dx-lab calibration, and whether it priced dollars from OpenRouter. See probe for how the recommendation is derived.

The same step asks who gets a review. It lists the review policy templates with a sentence each. The server default is selected and you decide. Leaving it on the server default keeps the repository following it.

Sign in

Open http://<host>:<port>/.

  • Password: printed once on the first serve start, or set with --password=.... Change it in Settings.
  • GitHub (optional): Continue with GitHub for the one allowed user. OAuth setup lives on serve.

Sessions use an HttpOnly, SameSite=Lax cookie (Secure on HTTPS).

Get started (/setup)

Onboarding checklist: models and API key, GitHub access, GitHub App. Each step links to Settings to fix gaps.

The home page carries the same idea as a Finish setup card until an install is complete: models and API key, GitHub App, webhook reachable (see Webhook reachability), first repository, first review, and CLI connected (a remote token exists). Each row links to the settings card that fixes it, the header shows how many are done, and the card disappears once all six are. A fresh install therefore says what to do next on its landing page, not only on /setup.

This page is not in the top bar. After sign-in, open http://<host>:<port>/setup, or use the Finish setup card on the home page. You can skip it and configure the same items under Settings at any time.

Routes

Top bar: Activity, Usage (/analytics), Settings, signed-in user.

Path Purpose
/ Repository list, Finish setup checklist until complete, Add repository, auto-review toggles (they only apply to repositories on Simple switches)
/setup Same checklist as above (direct URL)
/repos/new Pick an App-installed repo, Preview the plan, then confirm to start init
/repos/:owner/:repo Overview, 30-day stats, drift Update now, recent PRs, webhook reachability and last delivery
/repos/:owner/:repo/pulls Open PR list with a Review button each, paged review history, manual Review by number when webhooks fail
/repos/:owner/:repo/pulls/:n Findings and cost for one PR
/repos/:owner/:repo/remote Remote CLI reviews for this repo (last 30 days)
/repos/:owner/:repo/knowledge Generated guides, Sync, Clear
/repos/:owner/:repo/settings Who gets a review (the review policy), review scope, codegraph, commit watch issues and pushes in a row, analysis limits, schedule, remove repo
/repos/:owner/:repo/pushes Commit watch push reviews: range, App or CI, status, findings by severity, issues opened, cost
/activity Live and recent jobs (refreshes about every 5 seconds) and Pull requests we skipped, with the rule that skipped each and Review now for one that is waiting
/activity/:id Single job log
/analytics Usage for 7, 30, or 90 days
/settings Global models, GitHub, App (Create GitHub App), webhook URL, review policy default, remote limits, tokens and key policy

Per-repo tabs: Overview, Pull requests, Knowledge, Remote reviews, Pushes, Repository settings. The overview carries the Commit watch card.

PR titles are not stored in app.db, so lists show #number only.

Settings (global)

Single page with sections (anchor links in the sidebar):

Section What you configure
Models and API key Provider (OpenRouter, OpenAI or Anthropic, see AI providers), token, high model (reviews and synthesis), low model (history extraction). No model is pre-filled
GitHub gh or PAT for init/sync and server-side Git reads
Defaults Auth and include/limit defaults for new work, and the review policy template new repositories start with
Server Webhook URL shown to GitHub, queue and timeout knobs
Remote review cmr_… tokens (secret shown once, with copy), per-token concurrency, sync timeout, and the Client key policy (BYOK), see your own key
Access Password vs GitHub sign-in toggles (mirrors serve flags)
Password Change the dashboard password and sign out other sessions
About Version and source link

Saving PAT, App key, or OAuth values is validated against GitHub first. Bad scopes return 422 and nothing is stored.

Who gets a review

Each repository has a Who gets a review card under its Settings. It is where the review policy lives. The summary under In short says in plain sentences what the current choice does, and it updates as you edit the rules. Save stays off while the policy is not valid and the message says what to fix. A repository on Simple switches shows the three switches it had before. One on a policy shows How reviews run, which holds only the review scope and codegraph.

On Activity, Pull requests we skipped names the rule that decided, and a pull request that is waiting for a request has a Review now button.

Custom review instructions

Each repository also has a Custom review instructions card under its Settings. The text is added to the reviewer's built-in instructions for every review of that repository, as a CUSTOM REVIEW INSTRUCTIONS section. Leave it blank for none. Maximum characters caps the text, defaults to 8000, and 0 or -1 means no limit. The command line form and the per-run flags are on Review.

Clearing knowledge

Knowledge carries a Clear knowledge card: it deletes that repository's guides and saved settings, and a checkbox also drops the cached evidence (pull request listings, costs, clones and worktrees). The next Sync builds the knowledge from scratch. See Caching: Clearing.

Settings ends with Clear all knowledge, which does the same for every repository on the server. Repository records, review history and tokens stay. Both actions ask about work in flight first: queued jobs are canceled, a running review can be stopped, and a running sync is waited out because it cannot be interrupted. Nothing is deleted until that question is answered.

UI behavior

  • Failed API calls show a toast and Retry.
  • Toggles roll back if save fails.
  • serve --inject-500 (or CM_INJECT_500=1) forces mutating /api/* calls except login to fail, for testing error UI.

Linux

Linux (WSL included) is the recommended platform for serve and the dashboard:

  • SQLite FFI, advisory locks, and POSIX signals behave more predictably.
  • Windows is supported but treated as unstable.
  • serve logs a one-line warning when not on Linux.

Updating

Forward-only app.db migrations. Do not downgrade the CLI after a newer version has run.

  1. Stop serve.
  2. npm install -g co-maintainer@latest
  3. Start serve again with the same data directory.

Restart after upgrading. Details also on serve: Updating.