Back to AIWatcher
FREE AND OPEN SOURCE · APACHE-2.0

Review the prompt. Watch the session. Measure what stayed.

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.

bash
$ pipx install aiwatcher-local
$ aiwatcher setup
$ aiwatcher start --open-ui

Python 3.9+ · macOS, Linux, Windows · no declared dependencies

START HERE

Install

Most people should use pipx, which keeps AIWatcher in its own environment while putting the aiwatcher command on your path.

Recommended

bash
pipx install aiwatcher-local
pipx ensurepath

Open a new terminal after ensurepath, then:

bash
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

PlatformCommand
macOSbrew install pipx
Ubuntu / Debiansudo apt update && sudo apt install pipx
Windows PowerShellpy -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.

bash
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 sawFix
externally-managed-environmentHomebrew Python. Run brew install pipx and use pipx. Do not add --break-system-packages.
aiwatcher: command not foundOpen a new terminal after ensurepath, or run ~/.local/bin/aiwatcher.
No module named pipRun python3 -m ensurepip --upgrade (py -3 on Windows).
Python reports 2.x, or below 3.9Install 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 typeUpdate with
pipxpipx upgrade aiwatcher-local
pip in a venvpython -m pip install --upgrade aiwatcher-local
uv tooluv tool upgrade aiwatcher-local
Source cloneaiwatcher update --apply

If you installed the original aiwatcher-cli 0.1.0 package, migrate once: pipx uninstall aiwatcher-cli then pipx install aiwatcher-local.

FIRST RUN

What the first run tells you

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.

console
$ 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:

✓Gate-capable — History is read and the surface accepts a hook. Install it, then prove it with hook-status.
◑Partly covered — Seen, but not fully measured or not fully verified.
○Companion only — No hook point, or one that has not proven itself yet. Preflight from the Plan tab.
✗Not detected — Not found on this machine, or found but not making any claims yet.
SURFACE COVERAGEthe best mark each surface can earn
✓Claude Code CLIAutomatic gate and history. Verify with aiwatcher hook-status.
◑Claude Desktop Code tabHistory seen; hook unverified until a Desktop prompt proves it fired.
○Claude Desktop chatCompanion only. Use the Plan tab or manual preflight before a risky prompt.
○claude.ai in a browserPrompt Companion, or the browser extension where available.
✓Codex CLI and TUINative hook plus rollout history, once /hooks and hook-status confirm it.
◑Codex DesktopCompanion only unless hook-status proves the hook fired.
◑CursorNative hook ships; treat Cursor numbers as coverage-limited until fixtures improve.
◑OllamaDetected but unmeasured. Preflight before expensive local-agent work.
✗ClineDetected when installed. No cost or session claims yet.
✗WindsurfDetected when installed. No cost or session claims yet.

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.

BEFORE THE RUN

Before the run: hold the prompt, not the aftermath

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.

PROMPT GATE
Your call, every time

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.

COMMAND GATE
Before a command runs

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

bash
aiwatcher preflight "Refactor the checkout flow and delete old auth secrets" \
  --tool codex --cwd "$(pwd)"

Then turn on the gates you want

bash
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.

DURING THE RUN

During the run: the Companion

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.

IT NOTICES
Context pressure

When a session is spending most of its budget re-sending history you already paid for, and a clean restart would keep the plot.

IT NOTICES
Loops and stalls

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

bash
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

CommandWhat it gives you
aiwatcher watchSessions ranked by which one needs you, not by which is loudest
aiwatcher processes --stale-onlyLocal AI runtimes that look stale or orphaned
aiwatcher statuslineCost and context pressure inside the Claude Code status line
aiwatcher run -- npm testRun a command, then summarise the session it belonged to
AFTER THE RUN

After the run: what the money actually produced

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.

console
$ 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.

IT IS A FLOOR
Never an accusation

A blank means not measured, not gone. Reformatting moves git blame, so a real figure is always at least this good and possibly better.

IT SAYS WHAT IT CANNOT SEE
The unbanked line

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

console
$ 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:

bash
aiwatcher install-commit-hook --write

Close the loop yourself

CommandWhat it does
aiwatcher outcome usefulMark the last session useful, rework or abandoned
aiwatcher journalA personal record of what you and your agents worked on
aiwatcher sessionsRecent sessions, searchable, with click-through detail
aiwatcher timelineA privacy-safe event timeline for one session
aiwatcher log-decisionRecord 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.

CONTINUITY

Starting over without losing the plot

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.

CommandWhat it does
aiwatcher handoffBuild a compact Fresh Start brief for continuing this work in a new session
aiwatcher resumeFind an earlier session and produce a continuation brief ready for your target tool
aiwatcher compactionsWhat each compaction actually saved, so the advice stays checkable
aiwatcher open-sessionReopen 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.

THE CONSOLE AND THE CLI

Two surfaces over the same local data

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.

127.0.0.1:8765loopback only
HomeActive AI work, context pressure, update status, and the Companion control.
PlanPaste a prompt before you send it. AIWatcher picks the route: rewrite, fork, Fresh Start, archive, or continue.
WatchContext bloat, runway pressure, and Fresh Start actions.
ControlThe gates, what they decided, and the workspace they cover.
ProveWhat the spend bought, what it did not, and how much can be judged yet.
Changes ledgerWhat each commit cost, and what that works out to per line.
ImproveReview evidence, choose a next step, and check what changed.
ProjectsLocal repos and folders absorbing AI coding work.
SessionsSearch sessions and continue prior work. Prompt text is shown to you, never uploaded.
Agent mapRecorded Codex and Claude Code relationships.
SettingsUpdates, AI Assist, trust, and install steps.

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

AreaObserved
Published wheel597 KB (0.1.1 on PyPI)
Installed package2.2 MB of source, about 4.5 MB once Python caches bytecode
Declared dependenciesNone
Idle Console processTens of MB RSS, near 0% CPU
Console + CompanionNear 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.

THE TRUST BOUNDARY

What it reads, stores, and sends

AIWatcher reads evidence your tools already wrote to your disk. Nothing new is instrumented, and nothing is generated by asking a model.

READS
~/.claude session historyCodex rollout historygit commits, diffs, blameprocess age, CPU, RAM
STORES
~/.aiwatcher/local-state.jsonreceipts, hashes, decisionsoutcomes and metadata

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.

SENDS
Nothing

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.

  • Local-only by default, and read-only.
  • No LLM API call unless you configure AI Assist yourself.
  • No phone-home telemetry.
  • No source code or prompt text in any summary.
  • Nothing leaves your machine by default. Update checks, and AI Assist once you turn it on and pick a provider, are the only exceptions.

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.

WHERE THE LINE IS

Local and Enterprise

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.

LOCAL ANSWERS
Was my own AI work worth it?

What my agents did, which prompts were worth holding, and how much of what they wrote is still in my code.

ENTERPRISE ADDS
The same question for an organization

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.

It reads what is already there.

One command, and the first run already has your history. Nothing to configure, nothing to start collecting.

$pipx install aiwatcher-local

Apache-2.0 · no account · no API key · works offline