A macOS research instrument for AI coding agents. It shows, live, which files your agents (Claude Code & Codex) read, edit, and search — plus a replay timeline, A/B comparison, cross-session aggregates, and an experiment runner to compare how harnesses (with their native models) actually work a codebase.
Agents touch files in bursts too fast to follow in a terminal. Foveal makes their attention visible — files light up in the tree (blue = read, amber = edit, purple = search), the active file is tracked, and you can replay a whole session — then measures it: tokens, turns, cache-hit rate, tool durations, edit churn, command pass-rate, and the git diff each run actually produced.
Both agents already write timestamped JSONL transcripts to disk
(~/.claude/projects/<slug>/*.jsonl, ~/.codex/sessions/.../rollout-*.jsonl).
Foveal tails those — zero config, nothing to install into the agent —
normalizes every tool call into a FileAccessEvent, correlates each session to
the terminal that launched it, records to SQLite, and drives the UI. The same
"apply event" reducer powers both live highlighting and replay.
~/.claude, ~/.codex JSONL ──tail──▶ AgentAdapter ──▶ CorrelationEngine ──▶ EventStore (SQLite)
│
agent:event │ (IPC)
▼
decorationStore ──▶ file tree badges · editor flash · replay
- Editor: Monaco · Terminal: xterm.js + node-pty · Shell: Electron + React + Zustand
- Main process owns node-pty, chokidar watchers, JSONL parsing, correlation, and the store.
- See
~/.claude/plans/i-want-to-create-purrfect-hejlsberg.mdfor the full design.
pnpm install # builds native modules against Electron's ABI (postinstall)
pnpm dev # launch with HMR
pnpm typecheck # tsc on renderer + main
pnpm test # vitest (parser + correlation unit/integration)Open a workspace, then hit + claude / + codex in the terminal panel (or run them yourself) and watch the tree light up. Use the REPLAY bar at the bottom to replay a recorded session.
pnpm dist # electron-vite build + electron-builder → release/*.dmgThe packaging config (electron-builder.yml, build/entitlements.mac.plist)
sets the hardened runtime and unpacks the native modules. To sign + notarize,
set these before pnpm dist and flip notarize: true in electron-builder.yml:
export CSC_LINK=... CSC_KEY_PASSWORD=... # Developer ID Application cert
export APPLE_ID=... APPLE_APP_SPECIFIC_PASSWORD=... APPLE_TEAM_ID=...(Drop a build/icon.icns to replace the default Electron icon.)
src/main/ Electron main: pty, fs, agents (adapters), correlation, store, ipc
src/preload/ contextBridge → window.foveal
src/renderer/ React UI: editor, terminal, file tree, sessions, replay + Zustand stores
src/shared/ FileAccessEvent model, IPC channels, types
test/ vitest specs + an Electron-ABI live integration harness