@misha_misha/agentwatch 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,11 +2,16 @@
2
2
 
3
3
  # agentwatch
4
4
 
5
- **See what every AI coding agent on your machine is doing — in one terminal.**
5
+ **Local observability + control plane for every AI coding agent on your machine.**
6
6
 
7
- Local-only observability for Claude Code, OpenClaw, and Cursor all the
8
- tool calls, file reads & writes, shell commands, prompts, responses, costs,
9
- and permissions, in a single timeline.
7
+ A terminal live-tail *and* a browser dashboard one process, one event
8
+ stream, served from `localhost`. Unified timeline across Claude Code,
9
+ Codex, Gemini CLI, Cursor, Hermes, and OpenClaw. Token + cost accounting,
10
+ compaction + anomaly detection, hybrid search, SVG call graphs,
11
+ monaco-style diff attribution, agent-aware replay ("what would the agent
12
+ say if I edited the prompt?"), policy editor, MCP server agents can query
13
+ their own history from, and an OpenTelemetry exporter with `gen_ai.*`
14
+ semantic conventions. All local. No cloud. No telemetry. No sign-in.
10
15
 
11
16
  [![npm](https://img.shields.io/npm/v/@misha_misha/agentwatch.svg)](https://www.npmjs.com/package/@misha_misha/agentwatch)
12
17
  [![CI](https://github.com/mishanefedov/agentwatch/actions/workflows/ci.yml/badge.svg)](https://github.com/mishanefedov/agentwatch/actions/workflows/ci.yml)
@@ -15,21 +20,17 @@ and permissions, in a single timeline.
15
20
 
16
21
  </div>
17
22
 
18
- <!--
19
- Hero demo GIF — recorded on a real machine, ~30s, showing:
20
- 1. `npm i -g @misha_misha/agentwatch`
21
- 2. `agentwatch` launches, events streaming
22
- 3. Press `?` → hotkey reference
23
- 4. Press `P` → projects grid → Enter → sessions → Enter → scoped timeline
24
- 5. Press Enter on a Bash event → full stdout + duration
25
- 6. Press `p` → permissions view with flagged risks
26
- -->
27
-
28
23
  <div align="center">
29
- <img src="./docs/demo.gif" alt="agentwatch demo" width="820"
30
- onerror="this.style.display='none'" />
24
+ <img src="./docs/timeline.png" alt="agentwatch web UI — unified timeline across 5 agents, each in its own workspace" width="1100" />
25
+ <br />
26
+ <img src="./docs/event-detail.png" alt="agentwatch event detail view — full command, tool I/O, usage + cost" width="1100" />
31
27
  </div>
32
28
 
29
+ **The TUI is the live tail. The web UI is where you drill in** — projects,
30
+ sessions, token charts, compaction sparklines, SVG call graphs, diff
31
+ attribution, replay, anomaly triage, policy editing. Both run in one
32
+ process. Press `w` in the TUI to open the browser.
33
+
33
34
  ---
34
35
 
35
36
  ## Table of contents
@@ -37,23 +38,16 @@ and permissions, in a single timeline.
37
38
  - [Why this exists](#why-this-exists)
38
39
  - [Install](#install)
39
40
  - [First 60 seconds](#first-60-seconds)
41
+ - [Agent coverage](#agent-coverage)
40
42
  - [Features](#features)
41
- - [Live multi-agent timeline](#live-multi-agent-timeline)
42
- - [Event detail pane](#event-detail-pane)
43
- - [Subagent drilldown](#subagent-drilldown)
44
- - [Project and session navigation](#project-and-session-navigation)
45
- - [Full-text search](#full-text-search)
46
- - [Per-agent permission surface](#per-agent-permission-surface)
47
- - [Per-session cost with cache accounting](#per-session-cost-with-cache-accounting)
48
- - [Desktop notifications](#desktop-notifications)
49
- - [Yank to clipboard](#yank-to-clipboard)
50
43
  - [Keyboard reference](#keyboard-reference)
51
- - [What agentwatch reads](#what-agentwatch-reads)
52
44
  - [Configuration](#configuration)
45
+ - [What agentwatch reads](#what-agentwatch-reads)
46
+ - [MCP server mode](#mcp-server-mode)
47
+ - [OpenTelemetry exporter](#opentelemetry-exporter)
53
48
  - [How it compares](#how-it-compares)
54
49
  - [Limitations](#limitations)
55
50
  - [Non-goals](#non-goals)
56
- - [Roadmap](#roadmap)
57
51
  - [Architecture](#architecture)
58
52
  - [Development](#development)
59
53
  - [Security](#security)
@@ -63,27 +57,50 @@ and permissions, in a single timeline.
63
57
 
64
58
  ## Why this exists
65
59
 
66
- You're running three AI coding agents on one laptop. Claude Code in a
67
- terminal, Cursor as your IDE, OpenClaw churning on long-running tasks.
68
- Every one of them has its own log file in a different place, its own
69
- permission model, its own idea of what a "session" is. None of them tells
70
- you what the others are doing.
60
+ You run three AI coding agents on one laptop. Claude Code in a terminal,
61
+ Codex alongside it, Cursor as your IDE, maybe Gemini CLI for a quick
62
+ review, maybe an OpenClaw sub-agent churning on a long task. Every one of
63
+ them has its own log file, its own permission model, its own idea of what
64
+ a "session" is. None of them tells you what the others are doing.
71
65
 
72
66
  When something goes wrong — a file rewritten unexpectedly, a spend spike,
73
- an `rm` you don't remember running — you're piecing it together from three
67
+ an `rm` you don't remember running — you're piecing it together from five
74
68
  JSONLs and guessing.
75
69
 
76
- [`claude-devtools`](https://github.com/matt1398/claude-devtools) solves
77
- this beautifully for Claude Code. **agentwatch does the same thing for the
78
- whole multi-agent stack, in the terminal, with zero infra.**
70
+ [`claude-devtools`](https://github.com/matt1398/claude-devtools) does this
71
+ well for Claude Code. **agentwatch does it for the whole multi-agent
72
+ stack, in the terminal, with zero infrastructure and zero network.**
79
73
 
80
- - Single timeline: every agent's tool call, file op, shell exec, prompt,
81
- response
82
- - Per-agent attribution: `[auraqu] Bash: git log --oneline` or `[content_agent / sub:ab3c99fc] WebFetch: https://…`
83
- - One unified permissions view: Claude allow/deny, Cursor approval mode,
84
- OpenClaw sub-agents
85
- - Local-only by design. No cloud. No telemetry. No sign-in. `lsof` will
86
- show you there's nothing outbound.
74
+ ---
75
+
76
+ ## Why this over `claude-devtools` if you run multiple agents?
77
+
78
+ Short, factual diff. `claude-devtools` is a great tool for Claude-only
79
+ workflows — if you only use Claude Code, it's probably the better pick.
80
+ agentwatch is the answer when you run more than one agent on the same
81
+ machine and want one timeline + one cost ledger + one alerting surface
82
+ across all of them.
83
+
84
+ | What | claude-devtools | **agentwatch** |
85
+ | -------------------------------------------- | ----------------------- | ------------------------------------- |
86
+ | Claude Code coverage | ✅ full | ✅ full |
87
+ | Codex coverage | ❌ | ✅ tokens + tools + cost + compaction |
88
+ | Gemini CLI coverage | ❌ | ✅ tokens + tools + cost |
89
+ | OpenClaw coverage | ❌ | ✅ tokens + cost |
90
+ | Hermes Agent coverage | ❌ | ✅ tokens + tools + cost (SQLite) |
91
+ | Cursor coverage | ❌ | 🟡 config level |
92
+ | Per-agent budget alarms | ❌ | ✅ session + daily caps |
93
+ | Statistical anomaly detection (loops / spikes) | rule-based only | ✅ MAD z-score + period-1-to-4 loops |
94
+ | OpenTelemetry exporter (`gen_ai.*`) | ❌ | ✅ Jaeger / Tempo / Grafana ready |
95
+ | MCP server — agents query their own history | ❌ | ✅ 5 tools over stdio |
96
+ | User-defined regex/threshold triggers | ❌ | ✅ live-reloaded |
97
+ | Install | Homebrew / Electron ~150 MB | `npm i -g` · 220 KB · TUI |
98
+ | Data boundary | local | local |
99
+
100
+ If "every agent on one pane of glass + programmatic access via MCP +
101
+ pipeline-friendly OTel" matches your setup, agentwatch is the tool.
102
+ If you're Claude-only and want the Electron polish, `claude-devtools`
103
+ is still excellent.
87
104
 
88
105
  ---
89
106
 
@@ -97,56 +114,112 @@ agentwatch
97
114
  Requires:
98
115
 
99
116
  - **Node ≥ 20** (tested on 20 + 22 in CI)
100
- - **macOS or Linux** (Windows is intentionally out of scope for v0)
117
+ - **macOS or Linux** (Windows intentionally out of scope for v0.x)
101
118
 
102
- agentwatch is published under the `@misha_misha` npm scope — the unscoped
103
- `agentwatch` name was already taken by a different tool from CyberArk.
104
- Once installed the binary on your `$PATH` is simply `agentwatch`.
119
+ Published under the `@misha_misha` npm scope — the unscoped `agentwatch`
120
+ name was already taken by a CyberArk tool. The installed binary on your
121
+ `$PATH` is simply `agentwatch`.
105
122
 
106
123
  ---
107
124
 
108
125
  ## First 60 seconds
109
126
 
110
127
  ```bash
111
- # 1. Sanity-check that agentwatch sees your installed AI agents
112
- agentwatch doctor
128
+ agentwatch doctor # detects installed agents + readiness
129
+ agentwatch # TUI live-tail + web UI at http://127.0.0.1:3456
130
+ agentwatch serve # web UI only (remote boxes / server cron)
131
+ agentwatch mcp # runs the MCP stdio server (for agents, not humans)
132
+ agentwatch --help
113
133
  ```
114
134
 
115
- You should see something like:
135
+ Flags:
136
+
137
+ - `--no-web` — TUI only, don't start the web server
138
+ - `--port <n>` / `--host <addr>` — override web server bind
139
+ - `AGENTWATCH_PORT=… AGENTWATCH_HOST=…` — env equivalents
140
+
141
+ `doctor` output looks like:
116
142
 
117
143
  ```
118
144
  workspace: /Users/you/IdeaProjects
119
145
 
120
146
  agents:
121
- ● Claude Code installed
122
- config: /Users/you/.claude/settings.json
123
- Codex not detected
124
- config: /Users/you/.codex/config.toml
125
- ● Cursor installed
126
- config: /Users/you/.cursor/mcp.json
127
- Gemini CLI installed
128
- config: /Users/you/.gemini/settings.json
129
- ● OpenClaw installed
130
- config: /Users/you/.openclaw
147
+ ● Claude Code installed (events captured)
148
+ Codex installed (events captured)
149
+ Gemini CLI installed (events captured)
150
+ Hermes Agent installed (events captured)
151
+ ● Cursor installed (config-level only)
152
+ OpenClaw installed (events captured)
153
+ Aider not detected
154
+ ○ Cline (VS Code) not detected
131
155
  ```
132
156
 
133
- Then:
157
+ Launch `agentwatch` and every event your agents emit streams in. The TUI
158
+ shows a live tail; the web UI at `http://127.0.0.1:3456` is where you
159
+ drill in — projects, sessions, token charts, SVG call graphs, diff
160
+ attribution, prompt replay, trends. Press `w` in the TUI to open it.
161
+
162
+ ### Web UI map
163
+
164
+ | Route | What it is |
165
+ | ------------------------------------ | ------------------------------------------------------- |
166
+ | `/` | Live timeline (SSE-streamed) with agent + type filters |
167
+ | `/projects` | Grid of detected projects + cost + session counts |
168
+ | `/projects/:name` | Sessions table for one project |
169
+ | `/sessions/:id` | Chronological event list · export .md / .json |
170
+ | `/sessions/:id/tokens` | Stacked-area token chart per turn |
171
+ | `/sessions/:id/compaction` | Context fill % over time + compaction markers |
172
+ | `/sessions/:id/graph` | Call graph (d3-hierarchy SVG) — click nodes to drill |
173
+ | `/sessions/:id/diffs` | Writes paired with the prompt that triggered them |
174
+ | `/sessions/:id/replay` | Edit prompt → re-run the agent in single-turn exec |
175
+ | `/search` | Unified search (live / cross / semantic) |
176
+ | `/agents` | Grid of every supported agent + install status |
177
+ | `/permissions` | Per-agent permission config |
178
+ | `/cron` | OpenClaw cron jobs + heartbeats |
179
+ | `/trends` | Cost, cache-hit ratio, events per agent (30d default) |
180
+ | `/settings/{budgets,anomaly,triggers}` | Form editors for `~/.agentwatch/*.json` |
181
+
182
+ `⌘K` / `Ctrl+K` opens the command palette.
183
+ `/` focuses the timeline filter.
134
184
 
135
- ```bash
136
- # 2. Launch the TUI
137
- agentwatch
138
- ```
139
-
140
- You land in the live timeline. Everything your agents do from this moment
141
- on streams in. The last ~64 KB of each active session is backfilled so you
142
- have immediate context.
185
+ ---
143
186
 
144
- - Press **`?`** — see every hotkey
145
- - Press **`P`** — open the projects grid (one card per workspace)
146
- - Use Claude Code in another terminal and watch events appear
147
- - Press **Enter** on a row to see the full content (file diff, full Bash
148
- output, full prompt text, extended thinking)
149
- - Press **`q`** — quit, your shell scrollback is restored
187
+ ## Agent coverage
188
+
189
+ What actually works per agent, as of v0.0.3. Features not listed here
190
+ work across every agent (timeline, export, syntax highlighting, notifications,
191
+ triggers, search, stale detection, clipboard yank).
192
+
193
+ | Feature | Claude Code | Codex | Gemini CLI | Cursor | OpenClaw | Hermes |
194
+ | ------------------------------ | :---------: | :---: | :--------: | :----: | :------: | :----: |
195
+ | Live events on timeline | ✅ | ✅ | ✅ | 🟡 | ✅ | ✅ |
196
+ | Token usage + cost | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
197
+ | Tool call + result pairing | ✅ | ✅ | ✅ | ❌ | 🟡 | ✅ |
198
+ | Per-turn token attribution | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
199
+ | Budget alarms (session + day) | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
200
+ | Anomaly detection (cost/loops) | ✅ | ✅ | ✅ | 🟡 | ✅ | ✅ |
201
+ | Compaction visualizer | ✅ | ✅ | ❌ | — | ❌ | ❌ |
202
+ | Permissions view | ✅ | ✅ | ✅ | ✅ | ✅ | — |
203
+ | Cross-session search | ✅ | ✅ | ✅ | ❌ | ❌ | 🟡 |
204
+ | Subagent drilldown | ✅ | — | 🟡 | — | 🟡 | 🟡 |
205
+ | Replay (agent-aware exec) | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ |
206
+ | Agent memory file overhead | `CLAUDE.md` | `AGENTS.md` | `GEMINI.md` | `.cursorrules` | `OPENCLAW.md` | `SOUL.md` |
207
+ | OTel span coverage | ✅ | ✅ | ✅ | 🟡 | ✅ | 🟡 |
208
+ | MCP server exposes history | ✅ | ✅ | ✅ (raw) | ❌ | ❌ | ❌ |
209
+
210
+ - **Cursor** exposes config state (MCP servers, `.cursorrules`, approval
211
+ mode, sandbox) but its actual AI activity lives in a SQLite database we
212
+ haven't parsed yet. A thin read-only adapter is a follow-up.
213
+ - **Gemini CLI** doesn't persist context-compaction markers to disk, so
214
+ compaction detection is Claude + Codex only.
215
+ - **OpenClaw** doesn't persist tool_result content or compaction markers
216
+ to its JSONL — structural limit of what's on disk, not an adapter gap.
217
+ - **[Hermes Agent](https://github.com/NousResearch/hermes-agent)** (by
218
+ Nous Research — the OpenClaw successor with a closed learning loop)
219
+ persists sessions to `~/.hermes/state.db` (SQLite + FTS5). The adapter
220
+ polls the DB over chokidar + 2s safety-net and emits the full
221
+ session/prompt/response/tool-call stream. Replay re-runs single turns
222
+ via `hermes chat -q <prompt> -Q --max-turns 1`.
150
223
 
151
224
  ---
152
225
 
@@ -154,130 +227,173 @@ have immediate context.
154
227
 
155
228
  ### Live multi-agent timeline
156
229
 
157
- The main screen. Every event your agents emit, in reverse-chronological
158
- order by event timestamp (not arrival order backfill from different
159
- session files is sorted correctly). Columns: time · agent · type ·
160
- `[project / sub-agent]` summary · duration · error flag.
230
+ Main screen. Every event your agents emit, ordered by event timestamp (not
231
+ arrival order, so backfill from different sessions merges correctly).
232
+ Columns: time · agent · type · `[project]` summary · duration · error.
161
233
 
162
234
  ```
163
- 09:54:01 openclaw response [content_agent] <think> Checked the knowledge base
235
+ 09:54:01 openclaw response [content_agent] <think> Checked the KB
164
236
  09:52:53 claude-code response [auraqu] Commit bddc363. q now exits instantly…
165
- 09:52:48 claude-code tool_call [auraqu] Bash: git log -5 · 12ms
237
+ 09:52:48 codex shell_exec [dataset_research] ls -la · 12ms
166
238
  09:52:43 claude-code tool_call [auraqu] Edit: src/ui/App.tsx · 7ms
167
- 09:51:51 claude-code tool_call [auraqu] Agent: Competitive landscape 2026 ▸ 52 child events
168
- 09:28:06 claude-code prompt [mishanefedov] I mean what's the link, do I go through…
239
+ 09:51:51 gemini file_write [landing] write_file: public/llms.txt
240
+ 09:51:51 claude-code tool_call [auraqu] Agent: Competitive landscape 52 child events
169
241
  ```
170
242
 
171
- Event types: `prompt`, `response`, `tool_call`, `shell_exec`, `file_read`,
172
- `file_write`, `file_change`, `session_start`. Each gets a risk-based color
173
- (green / yellow / orange / red) so destructive shell execs and sensitive
174
- file writes jump out visually.
243
+ Rows with an anomaly fire a red `◎` prefix on the type column.
175
244
 
176
245
  ### Event detail pane
177
246
 
178
- Press **`Enter`** on any focused row. Opens a full-screen pane with:
247
+ Press **`Enter`** on any row. Opens a full-screen pane with:
179
248
 
180
- - Event metadata (time, agent, type, tool, path, cmd)
181
- - **Tokens / cost / duration** breakdown — `in=6 cache_create=25508 cache_read=16827 out=353` · `cost: $0.08 (claude-opus-4-6)` · `duration: 151ms`
182
- - **Tool result** — stdout / stderr for Bash, full file content for Read,
183
- search matches for Grep
184
- - **Full text** untruncated prompt or response
185
- - **Extended thinking** block when present
186
- - **Tool input** — JSON-pretty for Task / WebFetch / Grep arguments
249
+ - Metadata (time, agent, type, tool, path, cmd)
250
+ - Tokens / cost / duration (`in=6 cache_create=25508 cache_read=16827 out=353` · `$0.08 (claude-opus-4-6)` · `151ms`)
251
+ - Tool result — stdout for Bash, file content for Read/Write, search matches for Grep — with syntax highlighting inferred from the tool + file extension
252
+ - Full prompt or response text
253
+ - Extended thinking block when present
254
+ - Tool input JSON
187
255
 
188
256
  Scrollable with `↑↓` or `j/k`. `esc` closes.
189
257
 
190
258
  ### Subagent drilldown
191
259
 
192
- Parent `Agent` tool_use events show `▸ 52 child events`. Press **`x`** on
193
- one to scope the timeline to only that subagent's inner tool calls every
194
- Bash, WebFetch, Grep, Read it ran during that Task. `X` unscopes.
260
+ Parent `Agent` tool_use events show `▸ 52 child events`. Press **`x`** to
261
+ scope the timeline to only that subagent's inner tool calls. `X` unscopes.
262
+ Applies to Claude Code (Task tool) and partially to OpenClaw (per-agent
263
+ delegation) and Gemini (subagent sessions).
195
264
 
196
- This is the only multi-agent-observability feature claude-devtools has that
197
- agentwatch matches *and* extends — because we cover non-Claude agents too.
198
-
199
- ### Project and session navigation
265
+ ### Project + session navigation
200
266
 
201
267
  ```
202
- P projects grid (every workspace across every agent)
203
- pick one, Enter
204
-
205
- sessions list (grouped Today / Yesterday / Last 7d / Older)
206
- ↓ pick one, Enter
207
-
208
- scoped timeline (only events from this session)
268
+ P projects grid (one workspace per row, across all agents)
269
+ enter sessions list (grouped Today / Yesterday / 7d / Older)
270
+ enter → scoped timeline
209
271
  ```
210
272
 
211
- Projects grid aggregates across agents: one row per filesystem path, with
212
- per-agent session counts, total cost, last activity. Sessions list shows
213
- the first user prompt + event count + duration + cost per session.
214
- `esc` always walks back one level.
273
+ Projects grid aggregates across agents: per-agent session counts, total
274
+ cost, last activity. `esc` walks back one level.
215
275
 
216
- ### Full-text search
276
+ ### Cross-session search (`?`)
217
277
 
218
- Press **`/`**. Type a query. The timeline narrows to matches against
219
- summary, path, cmd, tool, agent, full text, or extended thinking. Live
220
- match count shown below the timeline. `esc` clears.
278
+ Press **`?`** fuzzy-substring search across every session file on disk
279
+ (`~/.claude`, `~/.codex`, `~/.gemini`). Uses ripgrep if installed, falls
280
+ back to a native scan. Enter on a hit scopes the timeline to that session.
221
281
 
222
- ```
223
- / Bash: rm → filters to every Bash with "rm" in its command
282
+ Different from in-buffer search:
283
+ - **`/`** search the 500-event live buffer
284
+ - **`?`** — search every session file ever written
285
+
286
+ ### Per-session cost with cache accounting
287
+
288
+ Naive token counters are 3–10× wrong on Claude because `cache_read` is
289
+ billed at 10% of input and `cache_creation` at 125%. agentwatch ships a
290
+ per-model rate table (Claude opus/sonnet/haiku, GPT-5 / GPT-5-mini,
291
+ Gemini 2.5 Pro/Flash) and computes true USD cost per turn. Cost shows:
292
+
293
+ - Per-agent total in the side panel
294
+ - Per-event in the detail pane
295
+ - Per-session in the sessions list
296
+ - Aggregate in the session's token attribution view (`[t]`)
297
+
298
+ ### Per-turn token attribution (`[t]`)
299
+
300
+ Inside a scoped session, press **`t`**. Stacked bar per turn showing:
301
+
302
+ - `user` — the preceding prompt (tokenized with `gpt-tokenizer`)
303
+ - `memory file` — CLAUDE.md / AGENTS.md / GEMINI.md / .cursorrules / etc., read from the session's cwd
304
+ - `tool I/O` — tool_input JSON + tool_result text
305
+ - `thinking` — extended thinking block
306
+ - `input (fresh)` / `cache read` / `cache create` / `output` — exact from the model's own usage record
307
+
308
+ ### Compaction visualizer (`[C]`)
309
+
310
+ Inside a scoped session, press **`C`**. Horizontal bar of context fill %
311
+ across turns, with `⋈` markers where the agent auto-compacted. Selected
312
+ compaction shows before / after token counts and the dropped-token delta.
313
+ Works on Claude Code (via `isCompactSummary`) and Codex (via
314
+ `event_msg/turn_truncated`).
315
+
316
+ ### Budget alarms
317
+
318
+ `~/.agentwatch/budgets.json`:
319
+
320
+ ```json
321
+ { "perSessionUsd": 5, "perDayUsd": 20 }
224
322
  ```
225
323
 
226
- ### Per-agent permission surface
324
+ Red banner in the Header when either cap is crossed; OS notification
325
+ fires once per crossing. No kill switch — we don't control agents; we
326
+ just shout.
227
327
 
228
- Press **`p`**. Scrollable view of:
328
+ ### Anomaly detection
229
329
 
230
- - **Claude Code** allow / deny / `defaultMode`, plus flagged risks:
231
- `Bash(*)` allows arbitrary shell; missing `~/.ssh` / `.aws` / `.gnupg`
232
- denies; auto or bypass mode surfaces as red.
233
- - **Cursor** — approval mode, sandbox state, allow/deny counts, MCP server
234
- list, discovered `.cursorrules` file paths.
235
- - **OpenClaw** — default workspace + per-sub-agent breakdown (name, emoji,
236
- model, workspace).
330
+ Three detectors, all fully local, all running on the 500-event buffer:
237
331
 
238
- Gemini CLI is documented and omitted it exposes no permission model
239
- beyond auth.
332
+ - **MAD z-score outliers** on cost, duration, and input tokens per agent
333
+ (`|z| > 3.5` by default — tune in `~/.agentwatch/anomaly.json`)
334
+ - **Stuck-loop detector** with periods 1–4 — catches `A-A-A-…` and
335
+ `A-B-A-B-…` "apologize and retry" loops
336
+ - Per-session rollup + OS notification on first flag + timeline `◎` marker
337
+ + `[D]` to dismiss the banner
240
338
 
241
- ### Per-session cost with cache accounting
339
+ ### User-defined notification triggers
242
340
 
243
- Naive token summers are **3–10× wrong** on Claude because `cache_read` is
244
- billed at 10% of input while `cache_creation` is billed at 125%. agentwatch
245
- embeds a per-model rate table (opus-4-6, sonnet-4-6, haiku-4-5) and
246
- computes true USD cost per turn.
341
+ `~/.agentwatch/triggers.json` live-reloaded via chokidar:
342
+
343
+ ```json
344
+ [
345
+ { "match": "curl .* \\| (bash|sh)", "title": "pipe-to-shell", "body": "{{agent}}: {{cmd}}" },
346
+ { "type": "file_write", "pathMatch": "^/etc/", "title": "/etc write" },
347
+ { "thresholdUsd": 0.5, "title": "expensive turn", "body": "cost {{cost}}" }
348
+ ]
349
+ ```
247
350
 
248
- - Per-agent total cost shows in the side panel
249
- - Per-event cost shows in the detail pane
250
- - Per-session cost shows in the sessions list
351
+ Placeholders: `{{agent}} {{type}} {{cmd}} {{path}} {{tool}} {{summary}} {{cost}}`.
251
352
 
252
353
  ### Desktop notifications
253
354
 
254
- Fires only for events that happen **after** the TUI was launched (backfill
255
- is silent). Rate-limited to one alert per rule per 60s.
355
+ Built-in alerts fire on sensitive events `.env` access, `~/.ssh` /
356
+ `~/.aws` / `~/.gnupg` paths, `rm -rf`, `sudo`, `curl | sh`, tool errors,
357
+ budget breach, anomaly. Rate-limited (60s per rule key). Silent during
358
+ backfill.
256
359
 
257
- Triggers built-in:
360
+ Platform dispatch: `osascript` on macOS, `notify-send` on Linux,
361
+ PowerShell `MessageBox` on Windows. Zero third-party dependencies.
258
362
 
259
- - `.env` file read or write
260
- - `~/.ssh`, `~/.aws`, `~/.gnupg` paths touched
261
- - `rm -rf`, `sudo`, `curl | sh` in shell_exec
262
- - Tool errors (`is_error: true`)
363
+ ### Per-agent permission surface (`[p]`)
263
364
 
264
- Platform dispatch: `osascript` on macOS, `notify-send` on Linux,
265
- PowerShell fallback on Windows. Zero dependencies.
365
+ Scrollable view showing:
366
+
367
+ - **Claude Code** — allow / deny / defaultMode; flagged risks (`Bash(*)`, missing `.ssh` denies, `auto` / `bypass` modes in red)
368
+ - **Codex** — config.toml projects + trust_level; latest session's sandbox_policy, approval_policy, writable_roots, network_access, model
369
+ - **Gemini CLI** — auth type, selected model, tool allow/block lists, trusted folders
370
+ - **Cursor** — approval mode, sandbox state, MCP servers, discovered `.cursorrules`
371
+ - **OpenClaw** — default workspace + per-sub-agent (name, emoji, model, workspace)
372
+
373
+ ### Session export (`[e]`)
266
374
 
267
- Custom regex triggers (e.g. "alert on any `psql.*prod`") are planned for
268
- v0.5.
375
+ From a session list or scoped timeline, press **`e`**. Writes
376
+ `./agentwatch-export/<agent>-<session>-<ts>.md` (human-readable transcript
377
+ with tool calls as fenced blocks) and `.json` (raw events). Path copied to
378
+ clipboard.
269
379
 
270
- ### Yank to clipboard
380
+ ### Syntax highlighting in the detail pane
271
381
 
272
- Press **`y`** on any focused event. Copies the most useful payload:
382
+ `cli-highlight` (tiny ANSI highlighter) applies to:
383
+ - Tool input JSON
384
+ - Tool result when the tool is Bash or the file extension is known (`.ts`, `.py`, `.rs`, `.go`, etc.)
385
+ - Fenced blocks in user/assistant text
273
386
 
274
- - Tool result content if available (the actual stdout / file body)
275
- - Otherwise full text (prompt / response)
276
- - Otherwise cmd / path / summary
387
+ ### Stale-session detection
277
388
 
278
- macOS `pbcopy`, Linux `wl-copy` / `xclip` / `xsel`, Windows `clip`.
279
- Confirmation flashes in green at the footer (`✓ copied 4,210 chars`) or red
280
- if no clipboard tool is available.
389
+ Sessions and projects idle for > 5 minutes render dimmed with a `⊘ stale`
390
+ badge. Un-greys on the next event.
391
+
392
+ ### Clipboard yank (`[y]`)
393
+
394
+ Copies the most useful payload (tool result > full text > cmd / path /
395
+ summary). Uses `pbcopy`, `wl-copy` / `xclip` / `xsel`, or `clip`.
396
+ Confirmation flashes at the footer.
281
397
 
282
398
  ---
283
399
 
@@ -292,8 +408,8 @@ Press **`?`** anytime to open this inside the TUI.
292
408
  | `↑ ↓` / `j k` | move selection in the timeline |
293
409
  | `Enter` | open event detail pane |
294
410
  | `esc` | close current view / clear selection |
295
- | `P` | projects grid — every workspace on this machine |
296
- | `Enter` on project | sessions list for that project (by date) |
411
+ | `P` | projects grid |
412
+ | `Enter` on project | sessions list for that project |
297
413
  | `Enter` on session | scoped timeline for that session |
298
414
  | `q` / `Ctrl-C` | quit |
299
415
 
@@ -301,107 +417,182 @@ Press **`?`** anytime to open this inside the TUI.
301
417
 
302
418
  | Key | Action |
303
419
  | ---- | ------------------------------------------------------------ |
304
- | `/` | full-text search (summary, path, cmd, tool, text, thinking) |
305
- | `f` | cycle agent filter (Claude only OpenClaw only → …) |
420
+ | `/` | in-buffer search (last 500 events) |
421
+ | `?` | cross-session search (every session file on disk) |
422
+ | `f` | cycle agent filter |
306
423
  | `a` | toggle agent side panel |
307
424
  | `x` | drill selected Agent event into its subagent run |
308
425
  | `X` | unscope subagent |
309
426
  | `A` | clear project filter |
427
+ | `Z` | clear all filters |
310
428
 
311
429
  ### Actions
312
430
 
313
431
  | Key | Action |
314
432
  | --------- | ------------------------------------------- |
315
433
  | `y` | yank selected event content to clipboard |
434
+ | `e` | export current session to `.md` + `.json` |
316
435
  | `space` | pause / resume live event stream |
317
436
  | `c` | clear event buffer |
437
+ | `D` | dismiss the current anomaly banner |
318
438
 
319
- ### Info views
439
+ ### Info overlays (only in a scoped session)
320
440
 
321
- | Key | Action |
322
- | ------ | --------------------------------------------------------- |
323
- | `p` | permissions view (Claude + Cursor + OpenClaw) |
324
- | `↑↓` | scroll inside permissions or detail pane |
441
+ | Key | Action |
442
+ | ------ | ----------------------------------------- |
443
+ | `t` | per-turn token attribution |
444
+ | `C` | context compaction visualizer |
445
+ | `p` | permissions view (works anywhere) |
446
+
447
+ ---
448
+
449
+ ## Configuration
450
+
451
+ Four config files, all optional. Loaded on startup; triggers reload live.
452
+
453
+ | File | Purpose |
454
+ | -------------------------------- | -------------------------------------------------------- |
455
+ | `~/.agentwatch/triggers.json` | User-defined notification rules (live-reloaded) |
456
+ | `~/.agentwatch/budgets.json` | `perSessionUsd` / `perDayUsd` spend caps |
457
+ | `~/.agentwatch/anomaly.json` | `zScore`, `loopWindow`, `loopMinRepeats`, `minSamples` |
458
+
459
+ Environment variables:
460
+
461
+ | Variable | Default | Purpose |
462
+ | ------------------------------ | --------------------------- | ----------------------------------------------------- |
463
+ | `WORKSPACE_ROOT` | `~/IdeaProjects` (fallback) | Where the generic filesystem watcher looks for edits |
464
+ | `AGENTWATCH_CONTEXT_WINDOW` | `200000` | Tokens per window — used by compaction % calculation |
465
+ | `AGENTWATCH_OTLP_ENDPOINT` | unset | Enables the OTel exporter when set |
466
+ | `NO_COLOR` | unset | Standard honoring: disables ANSI colors if set |
467
+
468
+ Workspace fallback chain (used when `WORKSPACE_ROOT` isn't set):
469
+ `~/IdeaProjects` → `~/src` → `~/code` → `~/Projects` → `~/dev` → `$HOME`.
325
470
 
326
471
  ---
327
472
 
328
473
  ## What agentwatch reads
329
474
 
330
- Everything is read-only. agentwatch writes to exactly two places: your
331
- terminal, and the clipboard (on explicit `y`).
475
+ Read-only. agentwatch writes to exactly two places: your terminal and the
476
+ clipboard (on explicit `y`) / disk (on explicit `e` to export).
477
+
478
+ | Path | What |
479
+ | ------------------------------------------------------------ | ---------------------------------------- |
480
+ | `~/.claude/projects/**/*.jsonl` | Claude Code session transcripts |
481
+ | `~/.claude/projects/**/subagents/*.jsonl` | Claude Code Task-spawned subagents |
482
+ | `~/.claude/settings.json` | Claude permissions |
483
+ | `~/.codex/sessions/**/rollout-*.jsonl` | Codex session transcripts |
484
+ | `~/.codex/config.toml` | Codex permissions + trust levels |
485
+ | `~/.gemini/tmp/**/chats/*.json` | Gemini CLI transcripts + tool calls |
486
+ | `~/.gemini/settings.json` + `trustedFolders.json` | Gemini permissions |
487
+ | `~/.openclaw/agents/*/sessions/*.jsonl` | OpenClaw sub-agent sessions |
488
+ | `~/.openclaw/logs/config-audit.jsonl` + `openclaw.json` | OpenClaw config audit + agent roster |
489
+ | `~/.hermes/state.db` (SQLite) | Hermes Agent sessions + messages |
490
+ | `~/.cursor/{mcp.json, cli-config.json, ide_state.json}` | Cursor config state |
491
+ | Any `.cursorrules` / `.cursor/rules/*.mdc` under WORKSPACE | Cursor project rules |
492
+ | `{CLAUDE,AGENTS,GEMINI,OPENCLAW}.md` + `.windsurfrules` etc. | Per-agent memory files for token attribution |
493
+ | `~/.agentwatch/*.json` | User config (triggers / budgets / anomaly) |
494
+ | `$WORKSPACE_ROOT` tree | Filesystem change events |
495
+
496
+ `SECURITY.md` carries the authoritative list and details of what is *not* read.
497
+
498
+ ---
499
+
500
+ ## MCP server mode
501
+
502
+ Run agentwatch as an MCP server so other agents can query their own
503
+ history. Install:
504
+
505
+ ```bash
506
+ claude mcp add agentwatch -- npx -y @misha_misha/agentwatch mcp
507
+ # or edit ~/.claude.json / ~/.cursor/mcp.json manually
508
+ ```
509
+
510
+ Tools exposed:
332
511
 
333
- | Path | What |
334
- | --------------------------------------------- | ----------------------------------- |
335
- | `~/.claude/projects/**/*.jsonl` | Claude Code session transcripts |
336
- | `~/.claude/projects/**/subagents/*.jsonl` | Claude Code Task-spawned subagents |
337
- | `~/.claude/settings.json` | Claude permissions |
338
- | `~/.openclaw/agents/*/sessions/*.jsonl` | OpenClaw sub-agent sessions |
339
- | `~/.openclaw/logs/config-audit.jsonl` | OpenClaw config audit trail |
340
- | `~/.openclaw/openclaw.json` | OpenClaw agent roster |
341
- | `~/.cursor/{mcp.json, cli-config.json, ide_state.json}` | Cursor state |
342
- | Any `.cursorrules` under `$WORKSPACE_ROOT` | Cursor project rules |
343
- | `$WORKSPACE_ROOT` tree (default `~/IdeaProjects`) | Filesystem change events |
512
+ | Tool | Args | Returns |
513
+ | ------------------------- | --------------------------------- | ----------------------------------------------------- |
514
+ | `list_recent_sessions` | `limit?: 1-100` | `[{agent, sessionId, project, lastActivity, sizeBytes}]` |
515
+ | `get_session_events` | `sessionId`, `maxBytes?: 1K-10M` | Raw JSONL (tail-capped) for that session |
516
+ | `search_sessions` | `query`, `limit?: 1-50` | `[{session, agent, line}]` substring hits |
517
+ | `get_tool_usage_stats` | `sessionId?`, `limit?: 1-500` | Per-tool counts, totalDurationMs, errorCount |
518
+ | `get_session_cost` | `sessionId` | `{totalCostUsd, turns, tokens, byModel}` |
344
519
 
345
- The SECURITY.md file carries the authoritative list and the details on
346
- what is *not* read.
520
+ See [`docs/features/mcp-server.md`](./docs/features/mcp-server.md).
347
521
 
348
522
  ---
349
523
 
350
- ## Configuration
524
+ ## OpenTelemetry exporter
351
525
 
352
- No config file yet — every behavior has a sensible default and the
353
- scope is deliberately narrow. Two environment variables:
526
+ Set `AGENTWATCH_OTLP_ENDPOINT=http://localhost:4318/v1/traces` to emit
527
+ OTLP/HTTP spans for every agent event. Uses the OpenTelemetry GenAI
528
+ semantic conventions so any consumer (Jaeger, Tempo, Honeycomb, Grafana)
529
+ can interpret the data without custom dashboards.
354
530
 
355
- | Variable | Default | Purpose |
356
- | ----------------- | ----------------------------------- | ------------------------------------------------------- |
357
- | `WORKSPACE_ROOT` | `~/IdeaProjects` (fallback chain) | Where the generic filesystem watcher looks for edits |
358
- | `NO_COLOR` | unset | Standard honoring: disables ANSI colors if set |
531
+ Attributes emitted:
359
532
 
360
- The workspace fallback chain (used when `WORKSPACE_ROOT` isn't set) is:
361
- `~/IdeaProjects` → `~/src` `~/code` `~/Projects` `~/dev` → `$HOME`.
533
+ - `gen_ai.system` (anthropic | openai | google | cursor | …)
534
+ - `gen_ai.operation.name` (chat | tool_use | context_compaction | …)
535
+ - `gen_ai.request.model` / `gen_ai.response.model`
536
+ - `gen_ai.usage.input_tokens` / `gen_ai.usage.output_tokens`
537
+ - `gen_ai.tool.name` / `gen_ai.tool.call.id`
538
+ - `error.type` on tool errors
539
+ - `agentwatch.session.id` / `agentwatch.cost_usd`
540
+ - `agentwatch.cache_read_tokens` / `agentwatch.cache_create_tokens` / `agentwatch.cache_hit_ratio`
541
+ - `agentwatch.context.fill_pct`
542
+ - `agentwatch.risk_score`
362
543
 
363
- Per-user config files and per-adapter toggles land in v0.5 alongside
364
- custom notification triggers and budget alarms.
544
+ OTel deps are loaded dynamically only when the env var is set — zero
545
+ runtime cost when disabled.
365
546
 
366
547
  ---
367
548
 
368
549
  ## How it compares
369
550
 
370
- | | agentwatch | claude-devtools | Unfucked | Langfuse / Phoenix |
371
- | -------------------------------- | ----------------------------------- | -------------------------- | -------------------------- | -------------------------------- |
372
- | Runs locally only | | | | self-host possible |
373
- | Multi-agent | Claude + OpenClaw + Cursor | Claude only | agent-agnostic, file-only | production LLM apps |
374
- | Per-agent event attribution | | | (file-level only) | N/A |
375
- | Permission surface view | (Claude + Cursor + OpenClaw) | | | |
376
- | Cost with cache-hit accounting | | | | |
377
- | Subagent drilldown | | | | (LangChain) |
378
- | Install | `npm i -g` | Homebrew / Electron | Homebrew / Rust binary | Docker + Postgres |
379
- | UI | TUI (ink) | Electron + web standalone | CLI only | Web |
380
- | Bundle size | ~50 KB source | ~150 MB Electron app | ~10 MB Rust binary | Postgres + app |
381
- | Telemetry | none | none | none | opt-in |
551
+ | | **agentwatch** | claude-devtools | Claudex | ccflare | Langfuse / Phoenix |
552
+ | ---------------------------------- | ---------------------------------------------- | --------------------- | --------------------- | ------------------ | ---------------------------- |
553
+ | Runs locally only | | | | ✅ | self-host possible |
554
+ | Multi-agent | Claude, Codex, Gemini, Cursor (config), OpenClaw | Claude only | Claude only | Claude only | production LLM apps |
555
+ | Real token + cost with cache | | | 🟡 | (proxy-level) | |
556
+ | Per-turn token attribution | ✅ | | | | |
557
+ | Compaction visualizer | | | | | |
558
+ | **Anomaly detection** | **✅ MAD + stuck-loop** | rule-based only | | ❌ | |
559
+ | **Budget alarms w/ OS notification** | **✅** | ❌ | ❌ | | |
560
+ | **User triggers (regex/threshold)** | **✅ live-reload** | ❌ | | | |
561
+ | **OTel exporter (gen_ai.*)** | **✅** | ❌ | | | (its own format) |
562
+ | MCP server (self-query) | | | | ❌ | ❌ |
563
+ | Permission surface view | ✅ 5 agents | ❌ | ❌ | ❌ | ❌ |
564
+ | Subagent drilldown | ✅ | ✅ | ❌ | ❌ | ✅ (LangChain-specific) |
565
+ | Install | `npm i -g` | Homebrew / Electron | `npm i -g` | Bun repo | Docker + Postgres |
566
+ | UI | TUI (Ink) | Electron + standalone | Web UI | Web + TUI | Web |
567
+ | Telemetry | none | none | none | none | opt-in |
568
+
569
+ Three moats are genuinely unique: **anomaly detection** (statistical, not
570
+ rule-based), **budget alarms**, and **OTel with gen_ai.* conventions**.
382
571
 
383
572
  ---
384
573
 
385
574
  ## Limitations
386
575
 
387
- - **Backfill isn't unbounded.** agentwatch reads the last ~64 KB of each
388
- session file on startup. Older events still live in your jsonl — open
389
- them directly if you need deeper history.
390
- - **Cursor activity is config-level only.** Cursor stores its full AI
391
- activity in a SQLite DB we don't parse yet. We capture config changes +
392
- recently-viewed files as a live signal. Full activity parsing is planned.
393
- - **Gemini CLI and Codex aren't instrumented yet.** Detection works in
394
- `agentwatch doctor`; events don't land in the timeline. Follows in v0.4
395
- and v0.5.
396
- - **macOS and Linux only.** Windows isn't supported in v0. chokidar edge
397
- cases and notification dispatch need more testing before we promise it.
398
- - **Subagent correlation is best-effort.** We match parent `Agent`
399
- tool_use to its subagent jsonl via the `agentId` in the `tool_result`
400
- payload. If Claude Code changes that convention upstream, drilldown
401
- needs an adapter tweak.
402
- - **The timeline window is 40 rows + header.** Scrolling deep into older
403
- events doesn't smoothly extend the window yet; use the projects → sessions
404
- drilldown or `/` search to find older events.
576
+ - **agentwatch is a viewer, not a daemon.** It captures events only while
577
+ the TUI is running. A background-capture daemon is planned.
578
+ - **Backfill is bounded.** On launch we read the last ~4 MB of each
579
+ active session file (roughly hundreds of events). For long gaps on
580
+ very active sessions, earliest events may fall out of the backfill
581
+ window. Keep agentwatch open in a tmux pane for zero gaps.
582
+ - **Cursor activity is config-level only.** Cursor's AI activity lives in
583
+ a SQLite database we don't parse yet. We capture config changes +
584
+ `.cursorrules` + MCP servers + `.cursor/rules/*.mdc`. Full activity
585
+ parsing is a follow-up.
586
+ - **Gemini and OpenClaw have data-structure gaps.** Gemini CLI doesn't
587
+ persist compaction markers to disk. OpenClaw doesn't persist
588
+ tool_result content or compaction markers. Not fixable from our side.
589
+ - **Windsurf, Aider, Cline** are detected but not instrumented yet.
590
+ - **macOS and Linux only.** Windows needs more chokidar + notifier
591
+ testing before we promise it.
592
+ - **tokenizer is cl100k_base (gpt-tokenizer)**, which is ~5% off for
593
+ Claude. Exact tokens for input / cache / output come from the model's
594
+ own usage record; the ~5% approximation only affects the user /
595
+ thinking / tool I/O / memory-file categories in the attribution view.
405
596
 
406
597
  ---
407
598
 
@@ -411,84 +602,44 @@ Hard scope boundaries so agentwatch stays small and maintainable.
411
602
 
412
603
  - **Not cloud. Not SaaS. Not ever.**
413
604
  - **Not an agent itself.** It watches agents; it doesn't take actions.
414
- - **Not production LLM-app tracing.** [Langfuse](https://langfuse.com)
415
- owns that.
605
+ - **Not production LLM-app tracing.** [Langfuse](https://langfuse.com) owns that.
416
606
  - **Not enterprise compliance.** Anthropic's Compliance API covers that.
417
- - **Not orchestration.** Use [Mission Control](https://github.com/MeisnerDan/mission-control)
418
- or [Stoneforge](https://stoneforge.ai) for running agents in parallel.
607
+ - **Not orchestration.** Use Mission Control / Stoneforge for running agents in parallel.
419
608
  - **Not memory.** Use [claude-mem](https://github.com/thedotmack/claude-mem).
420
- - **Not governance / policy enforcement.** Use [DashClaw](https://github.com/ucsandman/DashClaw)
421
- or [Castra](https://github.com/amangsingh/castra).
422
-
423
- ---
424
-
425
- ## Roadmap
426
-
427
- The full, ticket-level roadmap lives in the [Linear project](https://linear.app/auraqu/project/agentwatch-748d6aa1c20a).
428
- Headlines:
429
-
430
- ### v0.4 — parity mop-up
431
-
432
- - 7-category token attribution (CLAUDE.md / skills / mentions / tool I/O / thinking / team / user)
433
- - Context compaction visualizer
434
- - Syntax highlighting in detail pane
435
- - Markdown + JSON session export
436
- - Stale-session detection (dim after 5 min idle)
437
- - UX polish: breadcrumbs, consistent `esc`, home key, first-run tour
438
-
439
- ### v0.5 — moats
440
-
441
- - User-defined regex / threshold notification triggers
442
- - Budget alarms with hard spend caps
443
- - OpenTelemetry exporter with rich semantic conventions
444
- - Cross-session ripgrep-fast search
445
- - MCP server mode — agent self-query (`get_timeline`, `get_cost`,
446
- `search_sessions`)
447
- - **Web UI companion** — `agentwatch serve` on localhost:3456, same
448
- adapters, Preact-based renderer with inline diffs and stacked token bars
449
-
450
- ### v1.0 — ambitious
451
-
452
- - Semantic session search ("the session where I broke the build")
453
- - Diff-attribution (file change → prompt that caused it)
454
- - Cross-agent session correlation (Claude → Cursor stitched)
455
- - Tauri desktop app (3-5 MB bundle, not Electron)
456
- - Anomaly detection (stuck loops, cost spikes, error bursts)
457
-
458
- Feature requests: [GitHub issues](https://github.com/mishanefedov/agentwatch/issues).
459
- Before opening one, please skim the roadmap — most ideas are already
460
- tracked.
609
+ - **Not governance / policy enforcement.** Use DashClaw / Castra.
461
610
 
462
611
  ---
463
612
 
464
613
  ## Architecture
465
614
 
466
- TypeScript monorepo shape. Three-layer mental model:
615
+ TypeScript monorepo. Three-layer mental model:
467
616
 
468
617
  ```
469
- ┌─────────────────────────────────────────────────────┐
470
- │ TUI layer (ink / React)
471
- │ Timeline · EventDetail · Permissions · Projects
472
- │ Sessions · AgentPanel · HelpView
473
- └───────────────▲─────────────────────────────────────┘
474
- EventSink.emit / enrich
475
- ┌───────────────┴─────────────────────────────────────┐
476
- Adapter layer (per agent)
477
- │ claude-code · openclaw · cursor · fs-watcher │
478
- └───────────────▲─────────────────────────────────────┘
479
- │ files read-only
480
- ┌───────────────┴─────────────────────────────────────┐
481
- OS (log files, config files, clipboard, notifier)
482
- └─────────────────────────────────────────────────────┘
618
+ ┌─────────────────────────────────────────────────────────────┐
619
+ │ TUI layer (ink / React)
620
+ │ Timeline · EventDetail · Permissions · Projects
621
+ │ Sessions · Tokens · Compaction · CrossSearch · Header
622
+ │ │
623
+ MCP server (stdio — programmatic, not a UI) │
624
+ │ list_recent_sessions · get_session_events │
625
+ search_sessions · get_tool_usage_stats · get_session_cost
626
+ └─────────────────────────▲───────────────────────────────────┘
627
+ │ EventSink.emit / enrich
628
+ ┌─────────────────────────┴───────────────────────────────────┐
629
+ │ Adapter layer (one per agent) │
630
+ claude-code · codex · gemini · cursor · openclaw · hermes
631
+ │ fs-watcher (generic) │
632
+ └─────────────────────────▲───────────────────────────────────┘
633
+ │ files read-only
634
+ ┌─────────────────────────┴───────────────────────────────────┐
635
+ │ OS (log files, config files, clipboard, notifier) │
636
+ └─────────────────────────────────────────────────────────────┘
483
637
  ```
484
638
 
485
- - Adapters read files, translate raw log lines into a canonical
486
- `AgentEvent`, emit through an `EventSink`.
487
- - The sink's `enrich(id, patch)` lets an adapter update a previously-
488
- emitted event (e.g. when a Claude `tool_result` arrives late and needs
489
- to attach duration + output to the original `tool_use`).
490
- - The TUI is a pure reducer over the event buffer. Filtering, search,
491
- scope are all derived views — no mutation.
639
+ - Adapters read files, translate raw log lines into canonical `AgentEvent`s, emit through an `EventSink`.
640
+ - `EventSink.enrich(id, patch)` lets an adapter update a previously-emitted event (e.g. when a tool_result arrives late and needs to attach duration + output to the original tool_use).
641
+ - The TUI is a pure reducer over the event buffer. Filtering, search, scope are derived views no mutation.
642
+ - The MCP server is a peer of the TUI: it reads the same session files on demand, via its own scan (no shared in-memory state with the TUI). This is a known duplication; see Linear for the refactor ticket.
492
643
 
493
644
  See `src/schema.ts` for the canonical event shape.
494
645
 
@@ -501,31 +652,18 @@ git clone https://github.com/mishanefedov/agentwatch.git
501
652
  cd agentwatch
502
653
  npm install
503
654
  npm run dev # launch the TUI directly from source (tsx)
504
- npm test # vitest, 14 tests
655
+ npm test # vitest 97 tests
505
656
  npm run typecheck # strict TypeScript
506
657
  npm run build # tsup → dist/
507
658
  ```
508
659
 
509
- See [CONTRIBUTING.md](./CONTRIBUTING.md) for the contribution workflow,
510
- issue triage policy, and what's in scope for PRs.
511
-
512
- ## Docs
660
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for the contribution workflow.
513
661
 
514
- In-depth documentation lives in `docs/`:
662
+ ### Docs
515
663
 
516
- - **[`docs/features/`](./docs/features/)** — one spec per feature:
517
- what it does, how to invoke, inputs, outputs, failure modes,
518
- interactions. 12 files covering timeline, detail pane, subagent
519
- drilldown, projects + sessions navigation, search, permissions,
520
- cost accounting, notifications, clipboard yank, filesystem watcher,
521
- agent detection.
522
- - **[`docs/testing/`](./docs/testing/)** — manual test procedures per
523
- feature, plus a 15-minute pre-release walkthrough
524
- ([`TEST-SCRIPT.md`](./docs/testing/TEST-SCRIPT.md)).
525
- - **[`docs/use-cases/`](./docs/use-cases/)** — real-world scenarios:
526
- multi-agent triage on a monorepo, cost-overrun investigation,
527
- security audit, stuck-loop detection, subagent post-mortem, .env
528
- leak alert.
664
+ - **[`docs/features/`](./docs/features/)** — feature specs (scope, inputs, outputs, failure modes). Being extended feature-by-feature.
665
+ - **[`docs/testing/`](./docs/testing/)** manual test procedures + a pre-release walkthrough.
666
+ - **[`docs/use-cases/`](./docs/use-cases/)** multi-agent triage, cost-overrun investigation, security audit, stuck-loop detection, subagent post-mortem, .env leak alert.
529
667
 
530
668
  ---
531
669
 
@@ -533,9 +671,9 @@ In-depth documentation lives in `docs/`:
533
671
 
534
672
  Local-first is a hard invariant.
535
673
 
536
- - **Zero network calls.** Verify with `lsof -i -p $(pgrep -n agentwatch)`.
674
+ - **Zero network calls** unless you explicitly set `AGENTWATCH_OTLP_ENDPOINT` (to a host *you* chose, OTel output only).
537
675
  - **Zero telemetry.** Not opt-in, not opt-out — simply not there.
538
- - **All files read-only** except clipboard (on `y`) and terminal output.
676
+ - **All files read-only** except the clipboard (on `y`) and `./agentwatch-export/` (on `e`).
539
677
  - Every path agentwatch reads is documented in [SECURITY.md](./SECURITY.md).
540
678
 
541
679
  Report vulnerabilities privately: `misha@auraqu.com` or via a
@@ -551,7 +689,6 @@ MIT © Misha Nefedov. See [LICENSE](./LICENSE).
551
689
 
552
690
  <div align="center">
553
691
 
554
- If agentwatch saves you a debugging hour, a ⭐ on the repo makes the effort
555
- worth it.
692
+ If agentwatch saves you a debugging hour, a ⭐ on the repo makes the effort worth it.
556
693
 
557
694
  </div>