Debugging tools
The Cmd+. overlay, react-scan, the layout outline, and the agentation tracer — when each one is the right tool.
apps/web ships several in-app debug tools, gated on
isDebugCapableEnvironment() (true for development and preview, false
for production unless the master debug switch is on).
The Cmd+. overlay
The chord menu is the entry point.
apps/web/src/components/labs/debug-overlay/debug-overlay.tsx
implements it. Press Cmd+. on macOS (Ctrl+. on Windows/Linux) anywhere in
the running web app to open the menu.
Root keys
| Key | Action |
|---|---|
t | Theme (light / dark / system) |
i | Invalidate (drop React Query caches) |
c | Clear cache (more aggressive) |
m | Mock mode toggle (turns MSW on/off) |
s | Session toggle (sign in/out shortcut) |
r | Reset onboarding |
f | Feature flags |
d | Dev tools submenu |
d submenu (dev-capable environments only)
| Key | Action |
|---|---|
s | react-scan — highlight re-renders |
o | Layout outline — outline: 1px solid red on every element |
a | Agentation — agent action tracer |
Toggling a dev tool auto-flips the master debug switch on. Settings → Debug is still the canonical "off" surface (with the 10-tap profile-tab gesture as discoverable backup if you've forgotten the keyboard shortcut).
react-scan
react-scan (catalog
react-scan: ^0.5.3) is a runtime that paints colored borders on components
that re-rendered. Useful when:
- A scroll feels janky
- A typing handler is laggy
- You suspect a parent component is re-rendering on every state change
Read the screen as: red = many re-renders, yellow = some, green = few.
Find the unexpected red elements and figure out why their props or context
are changing. Common culprits: inline object literals as props, missing
useMemo on a derived value, context provider whose value identity isn't
stable.
Toggle via Cmd+. → d → s.
Layout outline
A outline: 1px solid red injected on every DOM element. Useful for:
- Spotting accidental margins / padding
- Finding zero-width or zero-height containers that shouldn't be empty
- Confirming a flex / grid container's children are where you think they are
Toggle via Cmd+. → d → o. Disable when done; outlines bleed into screen
recordings.
Agentation tracer
agentation (catalog
agentation: ^3.0.2) records agent-driven UI actions for replay. The dev
tools toggle enables a UI overlay that shows the recorded action stream
inline.
Mostly useful for debugging Claude Code / Cursor / WebDriver-style automation
of apps/web — if the agent's clicks are landing in the wrong place, the
tracer shows what coordinates and selectors it tried.
Settings → Debug surface
Even with the keyboard chord, the "master debug switch" surfaces in Settings → Debug. This page:
- Shows the current environment label (
development/preview/production) so QA can confirm which build they're on - Holds individual dev-tool toggles in a UI form (no keyboard chord)
- Has the discoverable on/off for the master switch
If a teammate doesn't know about Cmd+., the 10-tap profile-tab gesture in the production app's navbar reveals the Settings → Debug entry without the chord. Both paths converge on the same overlay.
What gets shown in production
By default, none of the debug tools run in production. The master switch is
off, and isDebugCapableEnvironment() is false.
But the switch itself is reachable in production (via the 10-tap gesture
or directly via /settings/debug). Toggling it on a production session
opens the same Cmd+. overlay — useful for live-debugging a customer-reported
issue on prod data without redeploying.
Console-side debug
apps/web/src/lib/env.ts exports getEnvironment(). From the browser
console:
// In any apps/web tab, in the devtools console:
window.__today_env__
// 'development' | 'preview' | 'production'(That global is wired up in dev/preview only; it doesn't ship in prod bundles.)
When the overlay doesn't open
- In the docs sites (
dev-docs,webview-bridge-docs, design-system/docs) — these are Fumadocs apps, not theapps/webshell. They don't mount the overlay. If you need to debug a docs site, use the browser's own devtools. - In
apps/admin— admin has a different overlay set (less developed). Seeapps/admin/src/components/labs/...for the admin-specific tools. - In production with master switch off — the chord is a no-op. Flip the switch in Settings → Debug first.
Related env detection
getEnvironment() returns 'development' | 'preview' | 'production'
resolved at module load (stable across SSR / hydration). Documented in
Architecture → Environment detection
(PR-CB3) with the OnboardingRedirectGuard interaction.
Deployment
Five Vercel projects, four owned by GitHub Actions prebuilt deploys and one on Vercel's Git Integration. CI gates every Actions-owned deploy before it ships.
Three-tier domains
t.ai, todayai.dev, today.ai — development / preview / production. How URL resolution branches on environment in packages/auth-client.