Monitoring coding agents without letting an app write to your config
Most apps that watch coding agents do it by putting a command into the agent's settings file, and several do it on first launch without asking. That file also holds your permissions, your hooks and your status line. Here is what you can know without anything being written, what a hook adds, and exactly what is written, where, when you decide to add one.
The short answer
Two tiers. With nothing written anywhere, Notchmeter 0.9.0 reads the login each tool already saved on the Mac and makes that tool's own read-only status request, reads the transcripts the tools already keep for the cost, and lists the sessions running in your terminals from what your own processes and the agents' own files say, each marked as detected. That tells you what each plan has left, when it resets, what the work is costing and which sessions are running. The moment a turn ends, that an agent is waiting for you, and answering it from the notch need the agent to say so, which is what a hook is. Notchmeter adds one only when you press the button, after a timestamped backup, merged so nothing of yours changes; after that, unless you turn it off, it keeps its own entries up to date at launch. Removing it is deleting its entries or restoring the backup.
How apps in this space find out what your agents are doing
| Approach | Who does it, in their own words | What you give up |
|---|---|---|
| Write hooks on first launch | Vibe Notch: "Hooks install automatically on first launch." Notchi: "it auto-installs Claude Code and Codex hooks on first launch." Buddi: "Hooks install automatically on first launch." | A command in your agent's config that you did not approve line by line |
| Never write anything | agent-notch: "No hooks, no APIs, no accounts." | Turn ends seen late, no waits, no answering; its README puts the lag at up to about 33 seconds |
| You change your own environment | AppGram's AgentNotch: you set OTEL_EXPORTER_OTLP_ENDPOINT and it receives the agents' telemetry | Nothing written for you, but the telemetry is only what the agent exports |
| Write only on your click | Notchmeter | Until you add the hook, sessions are detected rather than reported: their working is a guess, no wait is ever shown, and there is no answering |
The risk is real enough that AgentNotch's changelog, read the same day, records: "Live Prompts can no longer overwrite your agent's configuration, and every write leaves a backup." Backups and merges are the minimum; asking first is the point.
Tier one: nothing written
Every meter and the Cost card work with nothing written anywhere. Each reads, and never writes:
- The login its tool already saved on the Mac: Claude Code's Keychain item or credentials file, Codex's
auth.json, Cursor's editor state, Gemini CLI'soauth_creds.json, Copilot's config folder. With it Notchmeter makes the same read-only status request that tool's own app makes. The token is read into memory for that request and never refreshed, stored, logged or forwarded. - The transcripts and logs the tools already keep: the
usagelines of Claude Code's and Cowork's transcripts and of Codex's session rollouts, for the Cost card; Cursor's own usage export, for its spend; and modification times alone, to decide how often to poll.
That is enough for what each plan has left, when each window resets, the pace, the run-out and the spend, every figure labelled with where it came from. It is enough to list a session, and no more, and 0.9.0 says which is which: with no hook installed the Sessions card lists the Claude Code, Codex, Cursor, Gemini CLI and Copilot sessions running in your terminals (this user's processes with a terminal, Claude Code's own session file and the tail of its transcript for the title, model and branch, and OpenCode's from its database), each marked detected, with working a guess from the agent's own status, a transcript written in the last thirty seconds, or its CPU. Three things still need the agent to say so, which is what a hook is:
- That a session exists for certain, and which project it is in when no process and no file says: a detected row is a guess from the outside, and the hook's row replaces it the moment the hook speaks.
- When a turn ends. agent-notch, which watches processes and transcripts and writes nothing, puts it plainly: "only the agent knows when its turn ends."
- That an agent is waiting for you, and answering it. There is no channel back to the agent without a hook.
A detected session can know that it is running, its project, its terminal and, for Claude Code, its title, model and branch; it cannot know that a turn has ended or that the agent is waiting, so it never shows a wait and never lights a finish, and the card ends with the one line that says what the hook adds: exact turn ends and answering from the notch. It is on by default (Settings › Assistants › Sessions › Find sessions without the hook), it reads and never writes, and the rules are in docs/accuracy.md.
Tier two: the hook, on your click
A hook is the agent telling Notchmeter what happened, the moment it happens: a turn started, a turn ended, a permission is waiting, a question has options. That is what makes the waiting dot, the finished tick, the news in the notch and answering from the notch possible. Here is exactly how it is written.
- Only when you press it. Each assistant's page in Settings has its hook's Add button, and Show snippet… if you would rather paste it yourself; Settings › Integrations › Hooks lists where every assistant's hook stands, with a way to its page. The first launch offers the Claude Code hook once, as a button. No hook is ever installed without that click; after it, the app keeps the entries you installed up to date at launch unless you turn that off (below).
- A backup first, beside the file:
settings.json.bak-yyyyMMdd-HHmmss(orhooks.json.bak-…). - A merge, not a rewrite. Notchmeter's entry is appended under each event that lacks one. Hooks already there, their matchers and their order are kept, and so are the file's permissions. Nothing is written when every event already has the entry. A file that is not a JSON object is left untouched, and the button says why.
| Assistant | File | How it is written |
|---|---|---|
| Claude Code | ~/.claude/settings.json | Merged into your file |
| Codex | ~/.codex/hooks.json | Merged; and Codex runs no new or changed hook until you trust it in /hooks, so nothing takes effect without you in any case |
| Cursor | ~/.cursor/hooks.json | Merged; an existing version is never overwritten |
| Gemini CLI | ~/.gemini/settings.json | Merged; a file with comments in it is refused, because rewriting it would strip them |
| GitHub Copilot CLI | ~/.copilot/hooks/notchmeter.json | Notchmeter's own file; nothing of yours is touched |
| Kimi Code | ~/.kimi/config.toml | Its own [[hooks]] tables appended to your file as text, so your comments, key order and spacing stay exactly as they were; a file that already defines hooks another way is refused |
| OpenCode | ~/.config/opencode/plugins/notchmeter.js | Notchmeter's own plugin file; nothing of yours is touched, and OpenCode's sessions and spend are read from its database without it |
The one write that is not a click
If you move the app, a hook you installed points at the old path and goes quiet; if you update to a version that listens for more events, the entry you installed is out of date. So by default the app repairs its own entries at launch: after the same backup, it points them at the running copy and adds an entry for any event the current version listens for, leaves every other hook untouched, and never does it from a copy running out of a build folder. It never adds a hook for an assistant you have not installed one for. After a repair, Codex runs the changed entries only once you trust them again in /hooks, and the OpenCode plugin updates itself. If you want no write at all after the one you pressed, turn off Repair an out-of-date hook at launch in Settings › Integrations › Hooks, and use the Repair button on the assistant's page when you choose to.
The status line and the plugin
Install status line… sets Claude Code's statusLine after the same backup. A status line you already had is kept: Notchmeter runs yours with the same input and passes its output through, so Claude Code's bar still shows your line. The Claude Code plugin installs no hook and no status line; those stay a button in Settings.
What the hook sends
The event's name, the session id, the project folder's name, the branch and the permission mode; where the hook's own terminal is (the terminal app, its tab or pane id, the tty, tmux and kitty ids), so a click on a session can bring that terminal forward; the first line of a prompt, which the app drops on arrival unless Show what a session is working on is on, and the items of the session's task list, whose words it drops the same way; the model, where the assistant names one; and for a permission, the tool's name and a bounded summary, never the raw input. Claude Code's transcript path never leaves the command. Cursor's does, since 0.9.13: Cursor's hooks never report its to-do list, so the app reads the list from the conversation's transcript. It goes over a Unix socket on the Mac that accepts a connection only from a copy of Notchmeter whose code signature matches, and it fails open: with the app not running, or anything wrong, the agent carries on as if no hook existed. docs/hooks.md lists every field for every assistant.
Undoing it
- Claude Code: delete the groups whose command contains
Notchmeter … --hookfrom~/.claude/settings.json, and thestatusLineentry, restoring your own if Notchmeter chained it; or restore the.bakcopy. - Codex, Cursor, Gemini CLI: delete the entries whose command contains
--hook --tool codex,--tool cursoror--tool gemini, or restore the backup. - Kimi Code: delete the
[[hooks]]tables whose command contains--hook --tool kimifrom~/.kimi/config.toml, or restore the backup. - OpenCode: delete
~/.config/opencode/plugins/notchmeter.js. - Copilot CLI: delete
~/.copilot/hooks/notchmeter.jsonand restart Copilot.
Switching an assistant off in Notchmeter, or quitting it, also stops its hook having any effect; the command still runs and exits at once.
Choosing
If you want to know what each plan has left and what the work is costing, tier one is enough and nothing is written. If you want to see your sessions, know the moment an agent needs you, and answer it without finding the terminal, add the hook for that one assistant. You can start with the first and add the second later, one assistant at a time, and take it out again whenever you like.
Sources
- docs/hooks.md: installing, the files, the backups, Repair, the socket and removal.
- docs/privacy.md: every file the meters read and every request they make, and docs/roadmap.md for what is planned and not shipped.
- READMEs read 2026-09-24: Vibe Notch, Notchi, Buddi, agent-notch, AppGram/agentnotch.
- AgentNotch, changelog, read 2026-09-24.