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
| 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.
Sign in
Open http://<host>:<port>/.
- Password: printed once on the first
servestart, 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 |
/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 |
/repos/:owner/:repo/settings |
Auto-review, skip rules, scope, remove repo |
/activity |
Live and recent jobs (refreshes about every 5 seconds) |
/activity/:id |
Single job log |
/analytics |
Usage for 7, 30, or 90 days |
/settings |
Global models, GitHub, App (Create GitHub App), webhook URL, remote limits and tokens |
Per-repo sidebar: Overview, Pull requests, Remote, Knowledge, Settings.
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, token, high model (reviews and synthesis), low model (history extraction) |
| GitHub | gh or PAT for init/sync and server-side Git reads |
| Defaults | Auth and include/limit defaults for new work |
| Server | Webhook URL shown to GitHub, queue and timeout knobs |
| Remote review | cmr_… tokens (secret shown once, with copy), per-token concurrency, sync timeout |
| 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.
UI behavior
- Failed API calls show a toast and Retry.
- Toggles roll back if save fails.
serve --inject-500(orCM_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.
servelogs 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.
- Stop
serve. npm install -g co-maintainer@latest- Start
serveagain with the same data directory.
Restart after upgrading. Details also on serve: Updating.