# Changelog

All notable changes to agentwatch are documented here. Format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project
adheres to [Semantic Versioning](https://semver.org/).

**What counts as breaking?** CLI flags, the `agentwatch doctor` output contract,
and the canonical event schema (`src/schema.ts`). Adapter internals and TUI
layout can change freely within a minor version.

## [Unreleased]

## [0.1.2] — 2026-05-26

### Performance
- **TUI and the in-process web UI (`w`) no longer stall on large histories.**
  On a ~1GB history the web UI went from minutes to open down to a couple of
  seconds. Several costs that pegged the shared event loop are gone:
  - Budget + anomaly rollups recompute on a ~2.5s tick instead of on every event
    (keys like `q` stopped responding before; the live timeline still updates
    instantly).
  - The budget rollup now aggregates in SQL (~20ms) instead of pulling up to 50k
    rows into JS (~1s) on every tick.
  - Adapter initial-scan backfill drains one file per macrotask, so HTTP/SSE stay
    responsive during startup instead of blocking on a file-read storm.
  - Stale (>48h) session files are skipped on startup only when the store already
    has their history — a fresh/empty/unavailable store still backfills fully, so
    there is no first-run data loss.

## [0.1.1] — 2026-05-26

### Performance
- **Web dashboard opens ~10x faster on large installs.** `serve` now seeds the
  timeline from the SQLite store on startup (~0.5s to responsive) instead of
  blocking the event loop on every session file's backfill. On a ~1 GB history
  the first `/api/events` call dropped from ~12s to ~1.4s.
- Adapters now start on the next tick (server answers requests first) and the
  per-file backfill window shrank from 4 MB to 512 KB — history comes from the
  store, so the backfill only needs to cover the gap since the last run.
- `/api/events` `limit` is clamped to 2,000 to avoid multi-hundred-MB responses.

## [0.1.0] — 2026-05-03

### Added — v0.1 foundation

- **SQLite event store** (AUR-263) at `~/.agentwatch/events.db` — replaces
  the 4 MB rolling backfill with a persistent indexed store. WAL mode
  + `synchronous=NORMAL` + FTS5 virtual table over prompt/response/
  thinking/tool_result/summary. Migrations are versioned (`schema_version`
  table). Three tables: `events` (canonical AgentEvent), `sessions`
  (auto-aggregated via trigger on event insert: cost, ts range, count,
  project), `tool_calls` (tool, duration, error). Bench: ingests 10k
  events in ~430ms on M1 air.
- **`agentwatch prune --older-than-days N`** — drops events older than
  the cutoff (default 90 days), VACUUMs the DB on non-trivial prunes,
  prints the resulting size.
- **Search history mode** — `POST /api/search` with `mode: "history"`
  hits the FTS5 index for full-history matches (vs the live ring buffer
  or the JSONL cross-scan). Returns FTS-ranked snippets.
- **Background daemon** (AUR-262) — `agentwatch daemon start | stop |
  status | logs` installs a launchd LaunchAgent (macOS) or a systemd
  user unit (Linux) that runs the adapter pipeline 24/7, writing every
  event into `~/.agentwatch/events.db`. The TUI and `agentwatch serve`
  are now read clients of the same store, so events captured overnight
  are visible the moment you open them. PID file + start-time at
  `~/.agentwatch/daemon.{pid,started_at}`; log at
  `~/.agentwatch/daemon.log` with a 10 MB single-slot rotation; PID
  re-acquire is stale-PID-aware (process-alive probe).
- **Per-event activity classifier** (AUR-264) — every event lands with
  `details.category` ∈ {coding, debugging, exploration, planning,
  refactor, testing, docs, chat, config, review, devops, research}.
  Heuristic ladder over file-extension / tool-name / shell-command /
  prompt+response keyword signals; argmax wins. Schema v2 adds a
  `category` column + index. New routes:
  `GET /api/sessions/:id/activity`, `GET /api/projects/:name/activity`.
- **Git-correlation yield views** (AUR-265) — pairs commits with the
  sessions whose `[first_ts, last_ts + 30min]` window contains the
  commit's author date, then surfaces $/commit, $/line-changed, total
  insertions/deletions/files. Per-project view also returns a sorted
  "spend without commit" list of sessions that burned dollars but
  produced no commits in window. Worktree de-dup via `gitCommonDir()`.
  Read-only: git verbs are allow-listed (`log`, `rev-parse`, `worktree`,
  `show`, `diff`, `blame`, `status`, `config`, `branch`, `remote`).
  New routes: `GET /api/sessions/:id/yield`,
  `GET /api/projects/:name/yield`.
- **Claude Code native hooks adapter** (AUR-266) — agentwatch can
  register itself as a Claude hook and receive events ~1–2s faster
  than the JSONL transcript, with no sub-event drops. Translates
  every known Claude hook type (SessionStart, SessionEnd,
  UserPromptSubmit, PreToolUse, PostToolUse, Stop, SubagentStop,
  PreCompact, PostCompact, Notification) into the canonical
  AgentEvent shape; unknown future types fall through to a generic
  `tool_call` so new releases don't silently drop. CLI: `agentwatch
  hooks {install | uninstall | status}`. Settings stanzas are tagged
  with `[agentwatch-managed]` so uninstall only removes our entries
  and preserves user-configured hooks. A 5-second `(sessionId,
  toolUseId)` dedup window drops the duplicate JSONL copy when both
  paths fire. `agentwatch doctor` now reports
  `claude code hooks: installed | not-installed | partial`.

### Changed

- **EventSink wired through the store** in both TUI and `serve` modes —
  every emit/enrich is now mirrored to SQLite. Failures are logged once
  and never propagated; the in-memory pipeline remains the source of
  truth for the live SSE stream.

### Docs

- **ROADMAP.md** — v0.1 → v1.0 direction, milestone gates, scope
  commitments.
- **glama.json + Glama badges** — MCP-registry profile so agentwatch
  shows up in Glama's directory.

## [0.0.5] — 2026-05-01

### Added
- **Externalized pricing** via `~/.agentwatch/pricing.json` (AUR-216) — per-model
  rates can be overridden without rebuilding the binary; the in-tree defaults
  are loaded as a fallback when the file is absent.
- **OpenClaw `toolResult` pairing** (AUR-217) — toolResult turns now back-fill
  the originating toolCall with output, duration, and error flag, matching
  Claude/Codex parity.
- **Unparseable JSONL lines surfaced** as a structured `parse_error` event
  (AUR-228) instead of being silently swallowed; you now see when an adapter
  is choking on malformed input.

### Fixed
- **Partial JSONL lines preserved across reads** (AUR-227) — a chunk boundary
  in the middle of a line no longer truncates the event; tail buffer holds
  the partial line until the newline arrives.
- **Version no longer drifts between `package.json` and runtime** — `--version`
  reads `package.json` instead of a hardcoded constant.
- **`bin/agentwatch.js` is executable** in the published tarball
  (a `chmod +x` was missing from the build).

### Docs
- Documented that Gemini CLI and OpenClaw do not persist compaction markers
  to disk (AUR-214) — this is a structural limit of what those agents write,
  not a missing adapter feature.

## [0.0.3] — 2026-04-15

### Added — full multi-agent + moats wave

- **M5 parity-with-claude-devtools** — token attribution per turn
  (gpt-tokenizer cl100k_base; CLAUDE.md / AGENTS.md / GEMINI.md /
  .cursorrules / .windsurfrules / OPENCLAW.md as memory-file overhead),
  context compaction visualizer (`C`), syntax highlighting in detail
  pane (`cli-highlight`), session export to markdown + JSON (`e`),
  stale-session detection (`⊘ stale` after 5 min idle).
- **M6 differentiation moats** — user-defined regex / threshold
  notification triggers in `~/.agentwatch/triggers.json` (live-reloaded),
  per-session and per-day budget alarms in `~/.agentwatch/budgets.json`
  (banner + OS notification on breach), MCP server mode (`agentwatch mcp`)
  exposing 5 tools (`list_recent_sessions`, `get_session_events`,
  `search_sessions`, `get_tool_usage_stats`, `get_session_cost`),
  OpenTelemetry exporter (`AGENTWATCH_OTLP_ENDPOINT`) with `gen_ai.*`
  semantic conventions, cross-session search across every JSONL/JSON
  on disk.
- **M7 anomaly detection + semantic search** — MAD z-score outliers
  on cost / duration / tokens (configurable in
  `~/.agentwatch/anomaly.json`), period-1-to-4 stuck-loop detector,
  per-session aggregation with banner + dismiss (`D`) + timeline `◎`
  marker. Hybrid semantic search (`?` then `s`) using
  `bge-small-en-v1.5` (q8) via `@huggingface/transformers` v3 + SQLite
  FTS5 + Reciprocal Rank Fusion. First-run consent prompt before any
  download.
- **Codex adapter** — full session parsing including
  `function_call` / `function_call_output` pairing (toolResult,
  duration, error flag), `event_msg/token_count` enrichment, model
  capture from `session_meta` + `turn_context`, GPT-5 / GPT-5-mini
  cost rates.
- **Gemini adapter** — full token usage from each `gemini` message,
  `toolCalls[]` parsing into file_read / file_write / shell_exec /
  tool_call with inline functionResponse output, gemini-2.5-pro / flash
  cost rates.
- **OpenClaw adapter** — surfaces the precomputed `usage` + `cost`
  block from each assistant message (cacheWrite → cacheCreate map).
- **Codex + Gemini permission views** — `~/.codex/config.toml` projects
  + sandbox_policy from latest session's `turn_context`,
  `~/.gemini/settings.json` auth + tools allow/block + trusted folders.

### Changed
- README rewritten end-to-end to match shipped reality.
- Per-event cost / OTel spans now use the `gen_ai.*` OpenTelemetry
  semantic conventions instead of agentwatch-only attribute names.
- Codex / Gemini / OpenClaw memory files (AGENTS.md, GEMINI.md,
  .cursorrules, OPENCLAW.md) are read for token-attribution overhead
  alongside the existing CLAUDE.md.

### Performance
- Event dispatches coalesced at 16 ms during backfill — 500 emits
  collapse to 1 batched merge, removing render thrash on launch.
- All derived passes (anomaly, budget, projectIndex, sessionRows,
  childCountByAgentId) wrapped in `useMemo` — no longer recomputed
  on every keypress.
- Anomaly scoring now precomputes per-agent histories once instead of
  `slice + filter` per event.

### Behavior
- The generic file-system watcher of `WORKSPACE_ROOT` is now opt-in
  via `AGENTWATCH_WATCH_WORKSPACE=1`. On large monorepos it could
  exhaust inotify / take seconds to establish watches. Agent events
  (Claude / Codex / Gemini / OpenClaw) are unaffected.
- `q` / Ctrl-C now restore stdin raw mode reliably — the shell no
  longer freezes for ~1 minute after exit.

### Cancelled (with documented reasoning in Linear)
- Diff-attribution (AUR-182), cross-agent session correlation
  (AUR-183), replay mode (AUR-184). See ticket descriptions for the
  research record.

## [0.0.2] — 2026-04-14

### Added — claude-devtools parity (v0.3 feature wave)
- **Event detail pane** (`Enter`) — full-screen view of any event with
  tokens, cost, duration, tool input, tool result, full text, extended
  thinking. Scrollable with `↑↓` / `j k`.
- **Full-text search** (`/`) — narrows the timeline by summary / path /
  cmd / tool / agent / full text / thinking. Live match count.
- **Projects grid** (`P`) — one row per workspace on your machine,
  per-agent event counts, total cost, last-active time.
- **Sessions list** — bucketed by Today / Yesterday / Last 7 days /
  Older. Each row: agent tag, first user prompt, event count,
  duration, cost, error flag.
- **Scoped session timeline** — Enter a session to filter the main
  timeline to just that session's events.
- **Subagent drilldown** (`x`) — scope the timeline to the inner tool
  calls of a selected `Agent` spawn. `X` unscopes. Parent events show
  `▸ N child events` suffix.
- **Subagent JSONL ingestion** — `~/.claude/projects/*/SESSION/subagents/agent-*.jsonl`
  is now captured (previously invisible; 8.5k events surfaced on a
  typical dev machine).
- **Per-session cost with cache-hit accounting** — per-model rates
  (opus-4-6, sonnet-4-6, haiku-4-5) correctly weighting
  `cache_creation_input_tokens` (125%) and `cache_read_input_tokens`
  (10%). Naive summers are 3–10x wrong without this.
- **tool_use ↔ tool_result pairing** — captures duration, full output
  content, error flag for every Claude tool call.
- **Desktop notifications** — built-ins fire for `.env` access,
  `~/.ssh`/`.aws`/`.gnupg` paths, `rm -rf` / `sudo` / `curl | sh`, and
  tool errors. Rate-limited, backfill-silent.
- **Yank to clipboard** (`y`) — copies the most useful payload (tool
  result > full text > cmd > path) via `pbcopy` / `wl-copy` / `xclip`
  / `clip`.
- **Help overlay** (`?`) — grouped keybindings reference from any view.
- **Breadcrumb header** — surfaces active view + every active scope
  (project, session, subagent, agent, search).
- **Per-agent permission viewer** extended to Cursor (approval mode,
  sandbox, allow/deny, MCP servers, `.cursorrules`) and OpenClaw
  (default workspace, per-sub-agent model + workspace).

### Added — scaffold / discipline
- **CONTRIBUTING.md**, **SECURITY.md**, **CODE_OF_CONDUCT.md**.
- **Issue + PR templates** (bug, feature, adapter request).
- **`0` = home** — reset all filters / scopes / modals.
- **`Z` = clear filters** — replaces the confusing `A` case-variant.
- **`esc` = go back one level** — consistent across every view.

### Fixed
- **Claude adapter was reading zero events.** chokidar v4 dropped glob
  support; the `${dir}/**/*.jsonl` pattern never fired. Now watches
  the projects dir recursively with a path regex. Reveals thousands of
  events that were invisible in 0.0.1.
- **EMFILE crash** after ~30s of real use. Reduced FS watcher depth
  from 8 → 3, expanded ignores (coverage, `.venv`, `__pycache__`,
  `.turbo`, lock files), replaced Cursor's recursive workspace watcher
  with a one-shot shallow discovery + per-file watcher. All adapters
  silently swallow EMFILE / ENOSPC / EACCES instead of crashing.
- **`q` felt laggy** — chokidar's close waits on pending FDs. We now
  force `process.exit(0)` on quit.
- **Timeline rendered in arrival order**. Backfill arrived out of
  order. Now binary-inserted by event timestamp — strict
  reverse-chronological.
- **Empty-content events polluted the timeline.** Assistant messages
  with neither text nor tool_use are now suppressed.
- **Clipboard + notifier EBADF inside the TUI** — Ink's raw-mode TTY
  broke inherited stdio on spawnSync. Explicit pipe / ignore stdio on
  all child process calls.
- **fs-watcher double-counted Claude writes.** Introduced a
  module-scoped `recentAgentWrites` cache; fs-watcher skips paths
  an agent wrote within the last 5s.

### Changed
- Event `summary` now includes `[project]` prefix (Claude: extracted
  from session path; OpenClaw: from `cwd` in `session_start`; Cursor:
  path heuristic).
- Assistant tool_use events now extract real payload into summary
  instead of literal `tool_call`: `Bash: git log`, `Read: src/auth.ts`,
  `Task: refactor parser`, etc.
- Classification: Bash tool_use is now `shell_exec` (not `tool_call`)
  with elevated risk scoring for destructive commands.

### Notes
- Not cloud. Not an agent. Not telemetry-enabled. Zero outbound
  network calls.
- macOS + Linux. Windows intentionally out of scope for v0.
- Codex and Gemini adapters are intentionally deferred.

## [0.0.1] — 2026-04-14

### Fixed
- **Claude adapter silently reading zero events.** chokidar v4 dropped glob
  support; the `${dir}/**/*.jsonl` pattern never fired. Now watches the
  projects dir recursively with a path-regex filter. Live smoke surfaced
  thousands of events where 0.0.1 showed none.
- **EMFILE crash** after ~30 seconds of real use. Reduced FS watcher depth
  from 8 → 3, expanded the ignore list (coverage, `.venv`, `__pycache__`,
  `.turbo`, lock files), and replaced Cursor's recursive workspace watcher
  with a one-shot shallow discovery + per-file watcher. All adapters now
  silently swallow EMFILE / ENOSPC / EACCES instead of crashing.
- **`q` felt laggy.** chokidar's close waits on pending FDs; we now force
  `process.exit(0)` on quit so the shell returns immediately.
- **Timeline rendered in arrival order** (backfill out of order). Events
  are now binary-inserted by `ts` so the view is strictly reverse-
  chronological regardless of which file arrived first.
- **Empty-content events polluted the timeline.** Assistant messages with
  no text and no tool_use, and user turns made up only of tool_results,
  are now suppressed.

### Added
- **Project prefix on every event** — `[example]`, `[api]`,
  `[reachout]`. Claude events derive the project from the session path;
  OpenClaw tracks cwd per session from `session_start`; Cursor uses path
  heuristics. Finally makes it possible to see *where* each agent is
  working at a glance.
- **Rich Claude tool_use summaries** — Bash tool uses render as
  `Bash: <command>` with correct `shell_exec` type and risk scoring;
  Read/Write/Edit/MultiEdit render as `<Tool>: <path>`; Grep/Glob include
  the pattern; Task includes the description; WebFetch includes the URL.
- **Sticky column header** at the top of the timeline (`TIME / AGENT /
  TYPE / EVENT`).
- **Alt-screen buffer** — agentwatch now takes over the viewport on
  startup and restores the shell scrollback on exit. Standard TUI
  behaviour (lazygit / k9s / htop).

## [0.0.1] — 2026-04-14

### Added
- Claude Code adapter — tails `~/.claude/projects/**/*.jsonl` and emits
  structured `prompt`, `response`, `tool_call`, `file_read`, `file_write`,
  and `shell_exec` events.
- OpenClaw adapter — watches `~/.openclaw/agents/*/sessions/*.jsonl` across
  all sub-agents (content, research, docs, main) and surfaces session
  starts, model changes, messages, and tool calls with sub-agent
  attribution in the `tool` field. Also watches `config-audit.jsonl`
  with elevated risk scoring for config writes.
- Cursor adapter — config-level visibility over `~/.cursor/{mcp.json,
  cli-config.json, ide_state.json}` plus any project-level `.cursorrules`
  files. Emits file-read events for recently-viewed files tracked by the
  Cursor IDE.
- Workspace filesystem watcher — chokidar over `$WORKSPACE_ROOT` (default
  `~/IdeaProjects`) with sensible ignores.
- Agent detector — surfaces Claude Code, Codex, Cursor, Gemini CLI, and
  OpenClaw based on their config-directory presence.
- Permission surface viewer (Claude) — hotkey `p` opens a full-screen view
  of `~/.claude/settings.json` (+ project-level overrides), rendering the
  allow/deny lists, `defaultMode`, and flags for `Bash(*)`, missing
  `~/.ssh`/`.aws`/`.gnupg` denies, and auto/bypass modes.
- Ink TUI — live timeline with agent, event-type, and risk-score colouring;
  per-agent side panel; hotkeys `q`, `a`, `f`, `p`, `space`, `c`.
- `agentwatch doctor` — prints detected agents, config paths, and the
  workspace root.
- Risk-score heuristic — shell execs with destructive commands, writes to
  `.env` / `.ssh` / `.aws` / `.gnupg` score highest.
- Backfill — each adapter reads the last ~64 KB of a log on first
  discovery so the TUI shows immediate context.

### Notes
- Not cloud. Not an agent. Not production LLM-app tracing. Zero telemetry.
- Codex and Gemini adapters are intentionally deferred to a future release.
