AIWatcher Local is the whole loop for one developer on one machine. It reads the session history and git log your tools already wrote, so there is nothing to instrument and nothing to start collecting. No account, no key, no upload.
$ pipx install aiwatcher-local
$ aiwatcher setup
$ aiwatcher start --open-ui
Python 3.9+ · macOS, Linux, Windows · no declared dependencies
Most people should use pipx, which keeps AIWatcher in its own environment while putting the aiwatcher command on your path.
Recommended
pipx install aiwatcher-local
pipx ensurepath
Open a new terminal after ensurepath, then:
aiwatcher setup
aiwatcher doctor
aiwatcher start --open-ui
setup detects your local AI tools and prints copy-paste next steps — it is a readout, not an interactive menu, so there is no number to type. start --open-ui brings up the Console in your browser, the background Companion, and the small floating control on macOS and Windows. On macOS that control needs the Swift runtime, which comes with the Xcode Command Line Tools — xcode-select --install if you don’t have them. Everything else works without it, and Windows needs nothing extra.
If pipx is missing
| Platform | Command |
|---|---|
| macOS | brew install pipx |
| Ubuntu / Debian | sudo apt update && sudo apt install pipx |
| Windows PowerShell | py -3 -m pip install --user pipx |
On Windows, use py -3 -m pipx ... if the standalone pipx command is not available yet.
Or pip, inside a virtual environment
Do not install into the macOS, Homebrew, or Linux system Python. This keeps the environment somewhere durable instead of dropping a .venv into whichever project you happen to be in.
python3 -m venv ~/.venvs/aiwatcher-local
source ~/.venvs/aiwatcher-local/bin/activate
python -m pip install --upgrade aiwatcher-local
aiwatcher setup
aiwatcher start --open-ui
Activate that environment again before using aiwatcher in a new terminal. Use pipx if you would rather not.
Common install errors
| You saw | Fix |
|---|---|
| externally-managed-environment | Homebrew Python. Run brew install pipx and use pipx. Do not add --break-system-packages. |
| aiwatcher: command not found | Open a new terminal after ensurepath, or run ~/.local/bin/aiwatcher. |
| No module named pip | Run python3 -m ensurepip --upgrade (py -3 on Windows). |
| Python reports 2.x, or below 3.9 | Install Python 3.9 or newer. 3.10+ is recommended; Python 2 is not supported. |
The README carries the full table, including the py, git and distribution-name cases — Troubleshooting.
Keeping it current
| Install type | Update with |
|---|---|
| pipx | pipx upgrade aiwatcher-local |
| pip in a venv | python -m pip install --upgrade aiwatcher-local |
| uv tool | uv tool upgrade aiwatcher-local |
| Source clone | aiwatcher update --apply |
If you installed the original aiwatcher-cli 0.1.0 package, migrate once: pipx uninstall aiwatcher-cli then pipx install aiwatcher-local.
doctor is the honest one. It reports what AIWatcher can read on this machine and what it cannot, and it names the gaps rather than quietly dropping them.
$ aiwatcher doctor
AIWatcher Local doctor
Python: 3.14.7
Platform: darwin
Claude history: detected
Codex history: not detected
Claude project hook: not installed
Claude user hook: installed
Codex project hook: not installed
Codex user hook: not installed
Cursor project hook: not installed
Cursor user hook: not installed
Codex shell wrapper: not installed
Codex MCP config: not detected
Local state: ~/.aiwatcher/local-state.json
Surface coverage
[ten rows, reproduced in full below]
Privacy: private by default; AIWatcher does not upload prompts, source, or telemetry unless you explicitly configure a connected workflow.
The coverage block, collapsed above, is where it grades every surface it knows about. All four marks carry a distinct meaning:
Those are the best marks available, not what you will see on day one. A tool you have not installed reads ✗ Not detected until you install it — which is why Codex and Cursor show as missing in the output above while the grid lists what they can reach. AIWatcher does not claim silent protection on a surface it cannot verify. Where a tool has no hook point at all, the Console’s Plan tab gives you the same preflight as a paste-in widget.
On tools with a verified hook, every prompt gets a local risk score before it runs. Everywhere else, preflight it by hand from the terminal or the Console's Plan tab. Broad, vague, destructive or expensive work is flagged, and AIWatcher writes an intent-preserving version: the same request, scoped to what is actually needed.
A prompt that is risky in itself — destructive, vague, expensive — opens a local decision screen: use the tighter brief, edit it first, run the original anyway, or cancel. A prompt that is only broad gets the tighter brief added without interrupting you. Low-risk prompts pass straight through.
For Claude Code, AIWatcher can also review risky shell commands. It records the pattern, the reason, and the command itself with secrets redacted — connection strings, env-var secrets and token-like values become [redacted]. Enough to recognise what it stopped, without keeping your keys.
Try it before you install any hooks
aiwatcher preflight "Refactor the checkout flow and delete old auth secrets" \
--tool codex --cwd "$(pwd)"
Then turn on the gates you want
aiwatcher install-claude-hook --write --scope user --gate
aiwatcher install-codex-hook --write --scope user --gate
aiwatcher install-cursor-hook --write --scope user --gate
# Claude Code only: review risky shell commands too
aiwatcher install-claude-command-gate --write --scope user
Every installer prints the change it would make and only edits files when you pass --write. Send a small test prompt, then run aiwatcher hook-status — that proves a tool actually invoked AIWatcher, rather than trusting that it did.
One thing that surprises people reading that output: a prompt can be listed as risk high and still say added brief context (no popup). The score you see includes blast radius — how much of the repo the prompt reaches — but the decision to interrupt you is taken on the score without it. Reaching a lot of files is worth telling you about; on its own it is not worth stopping you for.
A background watcher that scans local sessions every 30 seconds and speaks up only when something is worth your attention. It is the part of the loop that happens while you are still in the work.
When a session is spending most of its budget re-sending history you already paid for, and a clean restart would keep the plot.
Work going round in circles, a long-running session, an idle one, and work that has been quietly waiting on you.
Run it on its own, without the Console
aiwatcher companion start # background, 30s scans
aiwatcher companion status
aiwatcher companion stop
aiwatcher companion tray install # menu-bar item
aiwatcher companion autostart install
The collapsed presence control sits in a screen corner you pick, and --presence-visibility decides when it is there at all: always, only while you are in an AI app, or only when it has something to say. --no-presence keeps the nudges and drops the control.
The same signals from the terminal
| Command | What it gives you |
|---|---|
| aiwatcher watch | Sessions ranked by which one needs you, not by which is loudest |
| aiwatcher processes --stale-only | Local AI runtimes that look stale or orphaned |
| aiwatcher statusline | Cost and context pressure inside the Claude Code status line |
| aiwatcher run -- npm test | Run a command, then summarise the session it belonged to |
This is the join nothing else makes. Your usage dashboard knows the spend and has never seen your repo; git knows every line and cannot tell you which session wrote it. AIWatcher reads both, locally, and puts them in one row.
$ aiwatcher changes --days 30
Cost per change - last 30 days, ranked by spend
Commit Cost Lines $/line Alive Subject
----------------------------------------------------------------------------------------
6897354652 $92.26 +290/-37 $0.28 73% feat(companion): draw the queue, the cou
d6f9779190 $70.37 +398/-14 $0.17 89% feat(companion): the meter and the chip
b1a257d578 $53.33 +168/-43 $0.25 92% feat(home,prove): finish the two surface
1d52849e22 $46.72 +252/-35 $0.16 74% feat(companion): a blocked session's but
740b86cf7e $44.16 +344/-8 $0.13 95% feat(first-run): meet a new machine with
693c3029c6 $43.72 +817/-267 $0.04 77% fix(update): ten findings from the revie
ed1a77ad9d $40.84 +235/-27 $0.16 76% feat(companion): catch the finish, calml
45a4e195fe $40.12 +55/-0 $0.73 86% feat(companion): the running arc
14 of 79 commits have no observed AI spend (hand-written, or committed more than 12h after the work).
77 commit(s) written by someone else were excluded: they arrived by fetch, so no spend on this machine belongs to them.
~ marks a commit that was rebased or amended. Cost is attributed by when the work was authored, not when git restamped it.
A blank means not measured, not 'gone'. It is a floor either way.
Unbanked: $806.85 of the last 30 days (37%) has no commit behind it ($1,374.16 reached one).
~/aiwatcher-local $791.67
~/aiwatcher-enterprise $8.20
~/getaiwatcher-site $6.97
Exploration that went nowhere, or work still uncommitted -- this cannot tell them apart.
That is this project’s own history, printed by the command you just installed. The Alive column is what share of each commit’s lines are still in the tree today.
A blank means not measured, not gone. Reformatting moves git blame, so a real figure is always at least this good and possibly better.
Spend with no commit behind it gets its own total. Exploration that went nowhere and work still uncommitted look identical from here, and the output says so rather than picking one.
One commit at a time
$ aiwatcher commit-receipt
AIWatcher receipt f3bf52034495 Put the Sessions table first and collapse wide a
This change $12.63 | +136/-30 lines | $0.08/line
100 model calls | claude-code
vs baseline $0.09/line median over 30 days (57 changes) -- this one is 1.2x cheaper than usual
Still unbanked $59.33 spent here in the last 2d has no commit behind it
Earlier work: 82% of the lines in your last 27 judged changes are still standing (a floor -- reformatting moves the blame).
Install it as a git hook and every commit prints its own receipt:
aiwatcher install-commit-hook --write
Close the loop yourself
| Command | What it does |
|---|---|
| aiwatcher outcome useful | Mark the last session useful, rework or abandoned |
| aiwatcher journal | A personal record of what you and your agents worked on |
| aiwatcher sessions | Recent sessions, searchable, with click-through detail |
| aiwatcher timeline | A privacy-safe event timeline for one session |
| aiwatcher log-decision | Record a decision and the alternative you rejected, while you remember why |
AIWatcher measures the yield. It does not claim to raise it — no tool can promise that, and the numbers above are worth something precisely because nothing is tuning them.
The cheapest fix for a bloated session is a fresh one, which people avoid because re-explaining the work costs more than the bloat. Fresh Start writes the brief for you.
| Command | What it does |
|---|---|
| aiwatcher handoff | Build a compact Fresh Start brief for continuing this work in a new session |
| aiwatcher resume | Find an earlier session and produce a continuation brief ready for your target tool |
| aiwatcher compactions | What each compaction actually saved, so the advice stays checkable |
| aiwatcher open-session | Reopen a session in the tool it belongs to |
The Console tracks these as receipts: when AIWatcher suggested a fresh session, what you chose, and whether a follow-up session was actually observed. Proof stays pending until that follow-up exists — a suggestion you took is not the same as a suggestion that worked.
Everything above is a command. All of it is also a view in a dashboard that AIWatcher serves from your own machine, on loopback, out of the Python standard library with no external assets.
aiwatcher start --open-ui, or aiwatcher ui for the Console alone.
It binds 127.0.0.1 and walks forward to the next free port if 8765 is taken. There is a read-only JSON summary at /api/summary for your own scripts, and aiwatcher mcp runs the whole thing as a stdio MCP server, so an agent can ask about your local history through a tool call instead of you pasting output at it.
Laptop footprint, measured on this repo
| Area | Observed |
|---|---|
| Published wheel | 597 KB (0.1.1 on PyPI) |
| Installed package | 2.2 MB of source, about 4.5 MB once Python caches bytecode |
| Declared dependencies | None |
| Idle Console process | Tens of MB RSS, near 0% CPU |
| Console + Companion | Near 0% CPU between scans |
It is a Python package with static assets, not a native daemon: nothing runs in the background until you start it or install login autostart. A Companion startup scan over a large local history peaks higher, then settles back to idle.
AIWatcher reads evidence your tools already wrote to your disk. Nothing new is instrumented, and nothing is generated by asking a model.
One file you can open, grep or delete. Prompt text from the prompt gate is never written down — that one keeps hashes only. A stopped command is kept, with its secrets redacted, so the receipt means something later.
The network stays off unless you run an update command, switch on update checks, or configure a connected workflow.
Optional AI Assist is the one exception: bounded context, only after you turn it on and pick a workflow that uses it.
If AIWatcher Local cannot explain what it reads and why, it should not read it.
You do not have to take any of that on trust. The source is Apache-2.0, the state file is one JSON document in your home directory, and every figure on this page came off a local file you have too.
Local is the developer-controlled loop for one machine, and it is meant to be useful with no signup, no cloud account, and no team admin involved.
What my agents did, which prompts were worth holding, and how much of what they wrote is still in my code.
Team policy, budgets and approvals, audit evidence, SSO and RBAC, managed deployment, central retention, org dashboards, and governance for agents running in production.
Enterprise features are additive. Local is not a locked demo and is never gated behind signup.
The Apache-2.0 licence covers the code. It does not grant rights to the AIWatcher name, logo, hosted service, or the Enterprise control plane.
One command, and the first run already has your history. Nothing to configure, nothing to start collecting.
Apache-2.0 · no account · no API key · works offline