snoop-cli 0.3.1 → 0.3.2
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 +106 -337
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -1,384 +1,153 @@
|
|
|
1
|
-
<
|
|
1
|
+
<div align="center">
|
|
2
2
|
<picture>
|
|
3
3
|
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/jzills/snoop/main/site/static/mark-dark.svg">
|
|
4
|
-
<img src="https://raw.githubusercontent.com/jzills/snoop/main/site/static/mark-light.svg" alt="" height="
|
|
4
|
+
<img src="https://raw.githubusercontent.com/jzills/snoop/main/site/static/mark-light.svg" alt="" height="56">
|
|
5
5
|
</picture>
|
|
6
|
-
|
|
7
|
-
</h1>
|
|
6
|
+
</div>
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
(`~/.claude/projects/**/*.jsonl`). You can keep it open in a second terminal
|
|
11
|
-
next to `claude` to watch a session live, or browse past sessions to see what
|
|
12
|
-
each prompt cost, how full the context is, which files changed, what the
|
|
13
|
-
subagents did and where the time went. The documentation is at
|
|
14
|
-
https://jzills.github.io/snoop/.
|
|
8
|
+
<div align="center">
|
|
15
9
|
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
# snoop
|
|
11
|
+
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<div align="center">
|
|
15
|
+
|
|
16
|
+
[](https://www.npmjs.com/package/snoop-cli)
|
|
17
|
+
[](https://pypi.org/project/snoop-cli/)
|
|
18
|
+
[](https://github.com/jzills/snoop/blob/main/LICENSE)
|
|
19
|
+
[](https://github.com/jzills/snoop/actions/workflows/ci.yml)
|
|
20
|
+
|
|
21
|
+
[Documentation](https://jzills.github.io/snoop/docs/) · [Install](https://jzills.github.io/snoop/docs/install/) · [Guides](https://jzills.github.io/snoop/docs/guides/) · [Keys](https://jzills.github.io/snoop/docs/reference/keys/)
|
|
22
|
+
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
A terminal viewer that keeps an eye on your Claude Code agents.
|
|
26
|
+
Watch every running session from one board, answer their permission prompts, comment on their diffs, and see what each prompt cost, without switching terminals.
|
|
27
|
+
|
|
28
|
+
<p align="center">
|
|
29
|
+
<img src="https://raw.githubusercontent.com/jzills/snoop/main/demo/demo.gif" alt="snoop showing the summary across sessions, a session's timeline with a turn's waterfall, an expanded subagent, the Files tab and Stats" width="800"/>
|
|
30
|
+
</p>
|
|
18
31
|
|
|
19
32
|
## Install
|
|
20
33
|
|
|
34
|
+
It runs on macOS, Linux and Windows, and every install method delivers the same prebuilt binary.
|
|
35
|
+
|
|
36
|
+
With [Homebrew](https://brew.sh), on macOS or Linux:
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
brew install jzills/tap/snoop
|
|
21
40
|
```
|
|
22
|
-
|
|
41
|
+
|
|
42
|
+
Or the install script, which checks the build against the release's checksums and installs it without `sudo`:
|
|
43
|
+
|
|
44
|
+
```sh
|
|
23
45
|
curl -fsSL https://jzills.github.io/snoop/install.sh | sh
|
|
24
|
-
npm install -g snoop-cli # or: pipx install snoop-cli
|
|
25
|
-
go install github.com/jzills/snoop/cmd/snoop@latest
|
|
26
46
|
```
|
|
27
47
|
|
|
28
|
-
|
|
48
|
+
Or from npm or PyPI, where the package is `snoop-cli` and the command is `snoop`:
|
|
29
49
|
|
|
50
|
+
```sh
|
|
51
|
+
npm install -g snoop-cli
|
|
52
|
+
pipx install snoop-cli
|
|
30
53
|
```
|
|
54
|
+
|
|
55
|
+
On Windows, use npm, PyPI or the PowerShell script:
|
|
56
|
+
|
|
57
|
+
```powershell
|
|
31
58
|
irm https://jzills.github.io/snoop/install.ps1 | iex
|
|
32
59
|
```
|
|
33
60
|
|
|
34
|
-
|
|
35
|
-
is named `snoop-cli`, since `snoop` was taken, and it carries the binary for
|
|
36
|
-
your platform, so nothing is downloaded or built when it installs. With
|
|
37
|
-
`uv`, run `uv tool install snoop-cli`.
|
|
61
|
+
See the [install guide](https://jzills.github.io/snoop/docs/install/) for more.
|
|
38
62
|
|
|
39
|
-
|
|
40
|
-
release's `SHA256SUMS`, and installs it to `~/.local/bin` without sudo. To
|
|
41
|
-
install somewhere else, set `SNOOP_INSTALL_DIR`, and to install a given
|
|
42
|
-
release instead of the newest, set `SNOOP_VERSION`, such as `v0.1.0`. The
|
|
43
|
-
PowerShell script does the same on Windows, installing to
|
|
44
|
-
`%LOCALAPPDATA%\Programs\snoop` and adding it to your `PATH`.
|
|
63
|
+
## Follow a session
|
|
45
64
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
archive holds the `snoop` executable, the license and this README.
|
|
65
|
+
Keep it open in a second terminal next to `claude`, and every prompt, reply, thinking block and tool call appears as it happens.
|
|
66
|
+
The right pane shows the selected item in full: the command, the diff, the subagent's prompt and result.
|
|
49
67
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
68
|
+
```sh
|
|
69
|
+
snoop --follow # the newest session in this directory, live
|
|
70
|
+
snoop # pick any past session
|
|
71
|
+
```
|
|
54
72
|
|
|
55
|
-
|
|
73
|
+
Each prompt shows its tokens, estimated cost and duration, and the header shows how full the context window is.
|
|
74
|
+
Selecting a prompt shows where its turn's time went, in a waterfall where parallel calls overlap.
|
|
75
|
+
Press `x` on an Agent call to expand its subagent's work inline, live while it runs.
|
|
56
76
|
|
|
57
|
-
|
|
58
|
-
snoop # pick a session (all projects)
|
|
59
|
-
snoop --follow # follow the newest session for this directory, live;
|
|
60
|
-
# switches automatically when a new session starts
|
|
61
|
-
snoop --live # every session at work right now, across projects
|
|
62
|
-
snoop 64f3ec44 # open by session id prefix (or a .jsonl path)
|
|
63
|
-
snoop --project DIR # treat DIR as the current project
|
|
64
|
-
snoop hooks install # let the Diff tab send comments to the agent
|
|
65
|
-
snoop --version
|
|
66
|
-
```
|
|
77
|
+
See the [following guide](https://jzills.github.io/snoop/docs/guides/following/) for more.
|
|
67
78
|
|
|
68
|
-
##
|
|
69
|
-
|
|
70
|
-
**Timeline:** The timeline shows every prompt, reply, thinking block and tool
|
|
71
|
-
call, one per line, with a blank line before each prompt so every turn
|
|
72
|
-
stands apart. A row in the same minute as the one above shows only its
|
|
73
|
-
seconds (`:42`). Tool rows show their duration and status (`✓` done, `✗`
|
|
74
|
-
error, `◌` running). Built-in tools (`▸`), skills (`✦`), MCP calls (`⇄`,
|
|
75
|
-
shown as `server·tool`) and subagents (`⤷`) each have their own color. The
|
|
76
|
-
right pane shows the selected item in full: Bash commands, Edit diffs, Write
|
|
77
|
-
content, agent prompts and results.
|
|
78
|
-
|
|
79
|
-
Each prompt row shows that turn's tokens, estimated cost (`≈`) and duration,
|
|
80
|
-
and compactions appear as `⟳ compacted (auto) 253k → 68k`. The header shows
|
|
81
|
-
how full the context window is (`ctx 142k/200k ▰▰▰▰▰▰▰▱▱▱ 71%`), turning to
|
|
82
|
-
the accent color at 70% and red at 90%. Selecting a prompt shows where its
|
|
83
|
-
turn's time went: totals, the five slowest tool calls, and a waterfall that
|
|
84
|
-
places each call by its start and end, so parallel calls overlap.
|
|
85
|
-
|
|
86
|
-
Pressing `x` on an Agent call expands its subagent inline, indented under a
|
|
87
|
-
`│` rule and kept live while it runs. Pressing `X` expands every subagent,
|
|
88
|
-
nested ones too. Search and filters reach into subagents, and a collapsed call
|
|
89
|
-
whose subagent has matches is kept and marked `●`.
|
|
90
|
-
|
|
91
|
-
**Tools:** The Tools tab groups every tool call by kind (built-in, skills,
|
|
92
|
-
MCP, subagents), then by name (tool, skill, MCP `server·tool`, subagent type),
|
|
93
|
-
then lists the individual calls, with counts, errors and average latency.
|
|
94
|
-
Selecting a group summarizes it in the right pane, and pressing `enter` on a
|
|
95
|
-
call jumps to it in the timeline.
|
|
96
|
-
|
|
97
|
-
**Files:** The Files tab lists every file the session and its subagents read,
|
|
98
|
-
edited or wrote, with read, edit and write counts and the lines added and
|
|
99
|
-
removed. Changed files come first, then files only read, each most recent
|
|
100
|
-
first. The right pane shows a file's history with every change as a diff,
|
|
101
|
-
which `n` and `N` step through, and pressing `enter` shows the latest change
|
|
102
|
-
in the timeline. Pressing `T` switches to a tree of folders, each with the
|
|
103
|
-
totals of its files. Changes made through Bash aren't tracked.
|
|
104
|
-
|
|
105
|
-
**Stats:** The Stats tab opens with the session's cost, duration, tokens (and
|
|
106
|
-
how many came from cache) and context. Below them, Turns lists each prompt's
|
|
107
|
-
time, tokens, cost and context, with a bar for its share of the cost and the
|
|
108
|
-
costliest prompt highlighted. Tools lists the tools used most, with errors
|
|
109
|
-
and average time, beside where the tokens went. Models lists each model with
|
|
110
|
-
its requests and cost.
|
|
111
|
-
|
|
112
|
-
Claude Code records a session's cost only when the session ends, so while it
|
|
113
|
-
runs, snoop estimates the cost from each request's tokens at the model's API
|
|
114
|
-
prices, and marks it `≈` and "estimated". Once the cost is recorded, snoop
|
|
115
|
-
splits each model's total across the prompts by token use, weighted by each
|
|
116
|
-
kind of token's price, so the prompt costs add up to the recorded total. The
|
|
117
|
-
estimate leaves out subagents' requests, and models without a known price
|
|
118
|
-
show tokens only.
|
|
119
|
-
|
|
120
|
-
## Many sessions at once
|
|
121
|
-
|
|
122
|
-
**Live board:** The live board, opened with `snoop --live` or by pressing `w`
|
|
123
|
-
in the picker, lists every session written in the last 30 minutes, across
|
|
124
|
-
projects, most urgent first.
|
|
125
|
-
|
|
126
|
-
| State | Meaning |
|
|
127
|
-
| --- | --- |
|
|
128
|
-
| `? asking` | the session asks for permission to use a tool, which you can answer here |
|
|
129
|
-
| `◌ waiting` | a tool call has had no result for `--stall` (30s), usually a permission prompt |
|
|
130
|
-
| `✓ your turn` | the turn ended, or you interrupted it |
|
|
131
|
-
| `● working` | replying, or running a tool or subagent (shown underneath) |
|
|
132
|
-
| `· idle` | no prompts yet, or nothing written for 10 minutes |
|
|
133
|
-
|
|
134
|
-
The board's header counts the sessions waiting on you (`1 waiting on you`).
|
|
135
|
-
Each row shows the project, the session, how full its context is, its cost
|
|
136
|
-
and when it last wrote. Press `enter` to open a session and `esc` to come
|
|
137
|
-
back, or `o` and `O` to sort by another column. Only sessions on the board are read, and after the first read, only
|
|
138
|
-
what they add.
|
|
139
|
-
|
|
140
|
-
**Answer permission prompts:** With snoop's hooks installed (see
|
|
141
|
-
[Review and comment](#review-and-comment)), a session that asks for
|
|
142
|
-
permission shows as `? asking` on the board, with the request in full under
|
|
143
|
-
the list: the command, the edit's diff, or the tool's input. Press `A` to
|
|
144
|
-
allow it once, or `D` to deny it, optionally with a reason that Claude sees.
|
|
145
|
-
Press `Y` to allow it and stop Claude Code asking again, the same as the
|
|
146
|
-
"don't ask again" choice in its own prompt: the board shows what that adds,
|
|
147
|
-
such as the rule `Bash(npm test)` in the project's local settings.
|
|
148
|
-
The same keys work in the session's own view, where its footer shows the
|
|
149
|
-
request. Claude Code's own prompt still appears in the session's terminal,
|
|
150
|
-
and whichever answer comes first wins.
|
|
151
|
-
|
|
152
|
-
The hook waits for an answer only while a live board or session view is
|
|
153
|
-
open, for at most 5 minutes (set with `snoop hooks install --ask-wait 10m`),
|
|
154
|
-
and answering in the terminal ends the wait at once.
|
|
155
|
-
|
|
156
|
-
**Reply when it's your turn:** When a session's turn ends, its row shows
|
|
157
|
-
`your turn`. Press `R` to type a reply and `enter` to send it, and the agent
|
|
158
|
-
carries on as if you'd typed it in its terminal. The same key works in the
|
|
159
|
-
session's own view, whose footer shows the agent's last message. In the
|
|
160
|
-
Timeline and Tools tabs, the reply is about the selected call or message: it
|
|
161
|
-
quotes it first, with a few lines of the call's result, so you can say "this
|
|
162
|
-
failed, try X" without copying anything. With the
|
|
163
|
-
hooks installed, a finished turn waits for a reply only while a live board or
|
|
164
|
-
session view is open, for as long as a permission request does, and typing in
|
|
165
|
-
the session's terminal ends the wait at once. A reply sent while the agent is
|
|
166
|
-
working reaches it after its current tool call, and one sent with no turn
|
|
167
|
-
waiting reaches it with your next prompt.
|
|
168
|
-
|
|
169
|
-
**Find:** Pressing `f` in the picker finds sessions by a file they read or
|
|
170
|
-
changed, a command they ran, or a prompt, subagents included. Every word must
|
|
171
|
-
match the same file, command or prompt. Each result shows what matched, and
|
|
172
|
-
opening it searches its timeline for the same words. Sessions are indexed by
|
|
173
|
-
the same background scan as the summary and cached with it.
|
|
79
|
+
## Watch every agent at once
|
|
174
80
|
|
|
175
|
-
|
|
81
|
+
The live board lists every session at work across your projects, with the ones waiting on you first.
|
|
176
82
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
left its base, committed or not, which is what a pull request would show plus
|
|
181
|
-
the work in progress, so you can review an agent's whole branch without
|
|
182
|
-
opening a PR. Files with changes since the last commit are tagged
|
|
183
|
-
`uncommitted`. The tab opens in Branch when the branch has commits of its own.
|
|
184
|
-
|
|
185
|
-
Unless you choose one, snoop compares with the closest of `develop`, `main`,
|
|
186
|
-
`master` and `trunk`, preferring `origin/` copies, since a local one may be
|
|
187
|
-
out of date. The line at the top of the tab names the base. Press `B` to pick
|
|
188
|
-
another base, which is saved for the branch in its git config
|
|
189
|
-
(`branch.<name>.snoopBase`), or set `git config snoop.base` for a whole
|
|
190
|
-
repository.
|
|
191
|
-
|
|
192
|
-
Files the session changed come first, and files changed by you or another
|
|
193
|
-
agent are dimmed. The tab refreshes as the session edits files or runs a
|
|
194
|
-
command, and `r` reads the diff again.
|
|
195
|
-
|
|
196
|
-
Press `tab` to move into a file's lines, then `c` to comment on a line. Press
|
|
197
|
-
`v` and move to select a range first, or press `C` to comment on the whole
|
|
198
|
-
file. Press `e` or `x` to edit or delete the comment under the cursor.
|
|
199
|
-
Comments wait until you press `S`, which sends them all at once. Each comment
|
|
200
|
-
names the file and lines and quotes the code, so the agent doesn't have to
|
|
201
|
-
reread the file.
|
|
202
|
-
|
|
203
|
-
Sending needs Claude Code hooks, which you add once:
|
|
83
|
+
<p align="center">
|
|
84
|
+
<img src="https://raw.githubusercontent.com/jzills/snoop/main/site/static/shots/ask.png" alt="The live board with one session asking to run a command, one whose turn ended and one working" width="800"/>
|
|
85
|
+
</p>
|
|
204
86
|
|
|
205
|
-
```
|
|
206
|
-
snoop
|
|
207
|
-
snoop hooks install --project # in ./.claude/settings.json instead
|
|
208
|
-
snoop hooks status # or uninstall
|
|
87
|
+
```sh
|
|
88
|
+
snoop --live --notify # every running session, with desktop notifications
|
|
209
89
|
```
|
|
210
90
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
finished keeps going. Replies sent with `R` travel the same way. The footer
|
|
215
|
-
shows when comments are delivered. Without the
|
|
216
|
-
hooks, `S` copies the comments to the clipboard instead. A fourth hook runs
|
|
217
|
-
when a session asks for permission, so the live board can
|
|
218
|
-
[answer it](#many-sessions-at-once). If you installed the hooks before that
|
|
219
|
-
hook existed, or before replies, `snoop hooks status` says so, and running
|
|
220
|
-
`snoop hooks install` again updates them.
|
|
221
|
-
|
|
222
|
-
The hooks are the only change snoop makes to Claude Code's settings, and
|
|
223
|
-
`snoop hooks uninstall` removes exactly those entries. Sent comments wait in a
|
|
224
|
-
`snoop/inbox` folder in your state directory (`~/.local/state` on Linux) until
|
|
225
|
-
a hook delivers them. Permission requests wait in `snoop/asks` beside it,
|
|
226
|
-
finished turns waiting for a reply are marked in `snoop/turns`, and open
|
|
227
|
-
snoops refresh a small `snoop/listening` file every 2 seconds, which is how
|
|
228
|
-
the hooks know to wait. A session that was already running may need a restart
|
|
229
|
-
before it uses the hooks.
|
|
230
|
-
|
|
231
|
-
## Summary across sessions
|
|
232
|
-
|
|
233
|
-
Pressing `s` in the session picker switches to a summary of the sessions
|
|
234
|
-
listed, so it follows `c` and the search. It shows sessions, prompts, tool
|
|
235
|
-
calls and the error rate, cost and tokens, a daily cost chart for the last 30
|
|
236
|
-
days, and the top tools, skills, MCP servers, subagent types and models with
|
|
237
|
-
their error rates. Every transcript is parsed in the background
|
|
238
|
-
(`scanning 12/48` in the header), and the results are cached in
|
|
239
|
-
`~/.cache/snoop/summaries.json` (the user cache directory), so later opens are
|
|
240
|
-
instant. Unreadable transcripts are counted and skipped.
|
|
91
|
+
When a session asks for permission, the request appears in full under the list.
|
|
92
|
+
Press `A` to allow it once, `Y` to always allow it, or `D` to deny it with a reason Claude sees.
|
|
93
|
+
When a session's turn ends, press `R` to reply, and the agent carries on as if you'd typed it in its terminal.
|
|
241
94
|
|
|
242
|
-
|
|
95
|
+
See the [live board guide](https://jzills.github.io/snoop/docs/guides/live-board/) for more.
|
|
243
96
|
|
|
244
|
-
|
|
245
|
-
over SSH, and in tmux with `set-clipboard on`. It copies the command for
|
|
246
|
-
Bash, the diff for edits, the content for Write, the full text of messages,
|
|
247
|
-
and the result for other tools. In the Files tab, it copies all of the file's
|
|
248
|
-
changes.
|
|
97
|
+
## Review and comment
|
|
249
98
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
Prompts become headings, tool calls become collapsible `<details>` blocks,
|
|
253
|
-
and subagent events are quoted under their call. You can also export from the
|
|
254
|
-
shell:
|
|
99
|
+
The Diff tab shows what a session changed, either since the last commit or across its whole branch.
|
|
100
|
+
Leave comments on a line, a range or a file, and press `S` to send them all to the agent, which picks them up mid-turn or keeps going after it finished.
|
|
255
101
|
|
|
256
|
-
|
|
257
|
-
snoop
|
|
258
|
-
|
|
102
|
+
<p align="center">
|
|
103
|
+
<img src="https://raw.githubusercontent.com/jzills/snoop/main/site/static/shots/diff.png" alt="The Diff tab with a comment under one line of a file's diff" width="800"/>
|
|
104
|
+
</p>
|
|
105
|
+
|
|
106
|
+
Replies, comments and answers to permission prompts reach the agent through Claude Code hooks, which you add once:
|
|
107
|
+
|
|
108
|
+
```sh
|
|
109
|
+
snoop hooks install
|
|
259
110
|
```
|
|
260
111
|
|
|
112
|
+
See the [review guide](https://jzills.github.io/snoop/docs/guides/review/) for more.
|
|
113
|
+
|
|
114
|
+
## Cost, files and time
|
|
115
|
+
|
|
116
|
+
The Stats tab breaks a session down by prompt, tool and model, and the Files tab lists every file it read or changed, each with its history as diffs.
|
|
117
|
+
In the session picker, press `s` for totals across sessions and a daily cost chart, or `f` to find sessions by a file they changed, a command they ran or a prompt.
|
|
118
|
+
|
|
119
|
+
See the [cost and context guide](https://jzills.github.io/snoop/docs/guides/cost-and-context/) for more.
|
|
120
|
+
|
|
261
121
|
## Alerts
|
|
262
122
|
|
|
263
|
-
While a session
|
|
264
|
-
|
|
123
|
+
While a session runs, the header flags a failed tool call, a stalled one, a finished turn, a compaction, a nearly full context or a permission request.
|
|
124
|
+
With `--notify`, the same alerts arrive as desktop notifications through your terminal or the system, over SSH and in WSL too.
|
|
125
|
+
With `--cost-alert 5` and `--long-turn 15m`, a runaway session gets flagged as well.
|
|
265
126
|
|
|
266
|
-
|
|
267
|
-
| --- | --- |
|
|
268
|
-
| `✗ error` | a tool call fails; the header counts unseen errors |
|
|
269
|
-
| `◌ waiting 30s on Bash` | a tool call has no result after `--stall` (default 30s), which may be a permission prompt, since those aren't recorded until answered |
|
|
270
|
-
| `✓ your turn` | Claude finishes |
|
|
271
|
-
| `⟳ compacted` | the context is compacted |
|
|
272
|
-
| `ctx 90%` | the context window passes 90% |
|
|
273
|
-
| `? Bash: npm test` | the session asks for permission (needs the hooks) |
|
|
274
|
-
| `$ cost passed $5.00` | with `--cost-alert 5`, the session's cost passes another $5 |
|
|
275
|
-
| `◌ turn running 15m00s` | with `--long-turn 15m`, a turn has run that long |
|
|
127
|
+
See the [alerts reference](https://jzills.github.io/snoop/docs/reference/alerts/) for more.
|
|
276
128
|
|
|
277
|
-
|
|
278
|
-
transcript when it opens never raise alerts.
|
|
129
|
+
## Copy and export
|
|
279
130
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
snoop --live --notify # a desktop notification when any session needs you
|
|
283
|
-
snoop --follow --bell --alerts error,stall,turn,compact,ctx,ask
|
|
284
|
-
snoop --stall 2m # 0 disables the waiting alert
|
|
285
|
-
snoop --live --notify --cost-alert 5 --long-turn 15m # catch a runaway session
|
|
286
|
-
```
|
|
131
|
+
Press `y` to copy the selected command, diff or message, over SSH too, or `e` to export the timeline to Markdown.
|
|
132
|
+
From the shell, `snoop export <session>` writes the whole session to stdout.
|
|
287
133
|
|
|
288
|
-
|
|
289
|
-
alert counts from what the session had spent when snoop opened it, and while
|
|
290
|
-
a session runs, its cost is an estimate from its tokens.
|
|
291
|
-
|
|
292
|
-
The live board raises the same alerts for every session on it, prefixed with
|
|
293
|
-
the project (`api: ✓ your turn`).
|
|
294
|
-
|
|
295
|
-
With `--notify`, snoop sends a desktop notification naming the session and
|
|
296
|
-
what happened (`api · Fix the flaky test` / `Your turn · finished after
|
|
297
|
-
2m10s`), so you can work elsewhere and come back when a session needs you. It
|
|
298
|
-
picks one way to deliver them:
|
|
299
|
-
|
|
300
|
-
| Where snoop runs | Notification |
|
|
301
|
-
| --- | --- |
|
|
302
|
-
| iTerm2, WezTerm, Ghostty, kitty | the terminal's own (clicking it focuses the tab) |
|
|
303
|
-
| over SSH | the terminal's own, so it shows on your machine, not the server |
|
|
304
|
-
| WSL | a Windows toast, through `powershell.exe` |
|
|
305
|
-
| macOS, other terminals | `osascript` |
|
|
306
|
-
| Linux desktop | `notify-send` |
|
|
307
|
-
| anywhere else | the terminal's own escape sequence (OSC 777) |
|
|
308
|
-
|
|
309
|
-
To override the choice, use `--notify=terminal` or `--notify=system`. In
|
|
310
|
-
tmux, let the terminal's own notifications through with
|
|
311
|
-
`set -g allow-passthrough on`.
|
|
312
|
-
|
|
313
|
-
Nothing is sent while snoop's window has focus (in terminals that report
|
|
314
|
-
focus). At most one notification goes out per session and alert a minute, and
|
|
315
|
-
several snoops watching the same session send one between them.
|
|
316
|
-
|
|
317
|
-
## Keys
|
|
318
|
-
|
|
319
|
-
Press `?` anywhere for the keys of the current screen. The full list follows.
|
|
320
|
-
|
|
321
|
-
| Key | Action |
|
|
322
|
-
| --- | --- |
|
|
323
|
-
| `↑↓` / `j k`, wheel | move (the wheel over the right pane scrolls it) |
|
|
324
|
-
| `enter` / `tab` | focus the detail pane (zoom it on narrow terminals) |
|
|
325
|
-
| `J K` / `ctrl+d ctrl+u` | scroll the detail pane |
|
|
326
|
-
| `/` | search text, commands, paths and results (all words must match) |
|
|
327
|
-
| `f` / `F` | cycle the filter: all, chat, tools, skills, mcp, agents, errors |
|
|
328
|
-
| `t` | show thinking blocks |
|
|
329
|
-
| `n` / `N` | next / previous prompt |
|
|
330
|
-
| `x` / `X` | expand a subagent inline / expand or collapse all |
|
|
331
|
-
| `a` | open the subagent transcript for an Agent call (`esc` returns) |
|
|
332
|
-
| `g G` | top / bottom (bottom re-enables following) |
|
|
333
|
-
| `1 2 3 4 5`, `[ ]` | switch tabs |
|
|
334
|
-
| `esc` | clear the search or filter, then go back |
|
|
335
|
-
| `!` | jump to the latest alert |
|
|
336
|
-
| `A` / `Y` / `D` | allow once / always allow / deny the session's permission request |
|
|
337
|
-
| `R` | reply to the session's agent, about the selected call or message in the Timeline and Tools |
|
|
338
|
-
| `y` / `e` | copy the selection / export the view to Markdown |
|
|
339
|
-
| `?` | every key for the current screen |
|
|
340
|
-
| `q` | quit |
|
|
341
|
-
|
|
342
|
-
In the Tools tab, `space` expands or collapses a group, `enter` on a call
|
|
343
|
-
shows it in the timeline, and `←` and `→` collapse and expand (`←` on a call
|
|
344
|
-
moves to its group). Pressing `E` expands everything (press it again to
|
|
345
|
-
reset), and a `/` search keeps only matching calls with their groups opened.
|
|
346
|
-
|
|
347
|
-
In the Files and Diff tabs, `T` switches between the list and a tree of
|
|
348
|
-
folders. In the tree, `space` and `enter` open or close a folder, `←` and `→`
|
|
349
|
-
close and open (`←` on a file moves to its folder), and `E` on a folder opens
|
|
350
|
-
it and every folder in it (press it again to close them). On a file, `E` does
|
|
351
|
-
the same for the whole tree. In the Files tab, `c` comments on the change at
|
|
352
|
-
the top of the detail pane, quoting it, `C` comments on the whole file, and
|
|
353
|
-
`S` sends them with the Diff tab's comments.
|
|
354
|
-
|
|
355
|
-
In the Diff tab, `b` switches between the uncommitted changes and the whole
|
|
356
|
-
branch, and `B` picks the branch's base. Press `tab` to move between the
|
|
357
|
-
files and their lines, and `J` and `K` to jump between hunks. The keys `c`,
|
|
358
|
-
`v`, `C`, `e`, `x` and `S` work as described in
|
|
359
|
-
[Review and comment](#review-and-comment).
|
|
360
|
-
|
|
361
|
-
In the picker, `/` starts a fuzzy search and `f` finds across sessions, and
|
|
362
|
-
`esc` clears either. Pressing `c` toggles this project only, `s` switches to
|
|
363
|
-
the summary, and `w` opens the live board. On the picker and the live board,
|
|
364
|
-
`o` sorts by the next column and `O` reverses the order. Search results stay
|
|
365
|
-
best match first until you choose a column.
|
|
134
|
+
See the [export guide](https://jzills.github.io/snoop/docs/guides/export/) for more.
|
|
366
135
|
|
|
367
136
|
## Notes
|
|
368
137
|
|
|
369
|
-
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
-
|
|
374
|
-
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
138
|
+
- It reads the transcripts Claude Code already writes and sends nothing anywhere.
|
|
139
|
+
The only change it makes to Claude Code's settings is the hooks, which `snoop hooks uninstall` removes.
|
|
140
|
+
- The transcript format is undocumented, and testing covers Claude Code 2.1.280 through 2.1.310.
|
|
141
|
+
Unknown records are ignored, so a new version may show less rather than break, and an [issue](https://github.com/jzills/snoop/issues) helps when something goes missing.
|
|
142
|
+
- A 75 MB transcript opens in about 150 ms.
|
|
143
|
+
- This independent project isn't affiliated with or endorsed by Anthropic.
|
|
144
|
+
Claude and Claude Code are trademarks of Anthropic.
|
|
145
|
+
|
|
146
|
+
## Contributing
|
|
378
147
|
|
|
379
|
-
|
|
380
|
-
|
|
148
|
+
Run `go run ./cmd/probe` to parse every local transcript and report timings.
|
|
149
|
+
The demo GIF and the site's screenshots are rendered from fictional sessions by `demo/render.sh` and `demo/shots.sh`, which need [vhs](https://github.com/charmbracelet/vhs).
|
|
381
150
|
|
|
382
151
|
## License
|
|
383
152
|
|
|
384
|
-
[MIT](https://github.com/jzills/snoop/blob/main/LICENSE)
|
|
153
|
+
Released under the [MIT License](https://github.com/jzills/snoop/blob/main/LICENSE).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "snoop-cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "A terminal viewer for Claude Code sessions: follow one live, or see what any past one cost, changed and spent its time on.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {"type": "git", "url": "git+https://github.com/jzills/snoop.git"},
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
"files": ["bin"],
|
|
11
11
|
"engines": {"node": ">=18"},
|
|
12
12
|
"optionalDependencies": {
|
|
13
|
-
"@jzills/snoop-cli-linux-x64": "0.3.
|
|
14
|
-
"@jzills/snoop-cli-linux-arm64": "0.3.
|
|
15
|
-
"@jzills/snoop-cli-darwin-x64": "0.3.
|
|
16
|
-
"@jzills/snoop-cli-darwin-arm64": "0.3.
|
|
17
|
-
"@jzills/snoop-cli-win32-x64": "0.3.
|
|
18
|
-
"@jzills/snoop-cli-win32-arm64": "0.3.
|
|
13
|
+
"@jzills/snoop-cli-linux-x64": "0.3.2",
|
|
14
|
+
"@jzills/snoop-cli-linux-arm64": "0.3.2",
|
|
15
|
+
"@jzills/snoop-cli-darwin-x64": "0.3.2",
|
|
16
|
+
"@jzills/snoop-cli-darwin-arm64": "0.3.2",
|
|
17
|
+
"@jzills/snoop-cli-win32-x64": "0.3.2",
|
|
18
|
+
"@jzills/snoop-cli-win32-arm64": "0.3.2"
|
|
19
19
|
}
|
|
20
20
|
}
|