diff options
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..3ca6eff --- /dev/null +++ b/README.md @@ -0,0 +1,125 @@ +<img src="web/assets/bemtevi.svg" width="96" align="right" alt=""> + +# notevi + +A code reader that remembers. Read files and grep through `notevi`, pin notes to +line ranges, and every one of those calls is appended as a single JSON line to +an **append-only JSONL log** kept in a **private jj commit**. Not your working +copy. Not your history. + +Two front ends over that one log — a CLI and a local web app. Both read it, both +write to it. Use either. Use only one. + +The bem-te-vi calls all day and keeps a bright crown patch hidden under a plain +black cap. Same idea: the notes are always there, never in the way. + +## Install + +```sh +go build -o ~/.local/bin/notevi . +``` + +Needs `jj` (the repo must be a jj workspace) and `rg` for working-copy greps. + +## From the shell + +```sh +notevi read src/lib.rs # whole file, line-numbered +notevi read src/lib.rs:120-180 # just the range +notevi grep 'fn resolve' src/ # regex over the working copy + +notevi note -f src/lib.rs:143 -t invariant "holds only under the bank lock" +notevi note -reply 12 "no — see the early return above" + +notevi query -op note # replay the log, oldest first +notevi query -file accounts_db # everything touching a path +``` + +Add `-r REV` to any of them to work at another revision — any jj revset, default +`@`. Every entry records the full change **and** commit id, so a note stays +pinned to the exact bytes it was about even after the change is rewritten. +Notes take an optional `-t KIND` (`fn`, `struct`, `invariant`, whatever you +want) and can reply to each other by number. + +## From the browser + +```sh +notevi web # dashboard: every sidecar under ~ +notevi web -repo . # one repo, http://127.0.0.1:4200 +``` + +**This is not a viewer.** Click a line, type, and the note is appended to the +same JSONL log `notevi note` writes to — same numbering, same permalinks, at the +exact change and commit you are looking at, attributed to your username. Reply +to notes, thread them, filter by file, text, kind, author, model, session, +change or date range. Never open the CLI and you lose nothing. + +What it shows: + +- the repo tree with per-reader coverage, and sources highlighted by tree-sitter + with coverage-tinted line numbers — the colors mix where readers overlap +- every note pinned to its lines, plus a notes-only mode across the whole repo +- who is reading right now, refreshed every few seconds +- ad-hoc jj queries over the repo +- every Zed and Helix theme installed on the machine, previewed live as you + arrow through the picker + +The dashboard scans `~` for repositories, and can start a sidecar in a jj repo +or add colocated jj to a Git one — so a project can begin in the browser too. +It writes no registry and no scan cache. + +```sh +notevi web -repo . -out site # static export: hand it to someone +``` + +The export is a plain directory of HTML. Tree, coverage, highlighting, notes, +filters and the file finder all still work with no server; writing notes, live +activity and jj queries do not, because there is nothing running. + +## The log + +One file, `notevi-log.jsonl`, only ever appended to. Lines are never edited and +never deleted: a note you got wrong is superseded by a later note, not rewritten, +so the trace stays a faithful record of what was believed when. Which also means +you can skip the tooling entirely: + +```sh +jj file show -r 'exactly(notevi_log, 1)' -- notevi-log.jsonl | + jq -c 'select(.op == "note") | {file, start, text}' +``` + +That file lives in one anonymous commit whose parent is `root()`, described +`private: notevi log`. The repo-local revset alias `notevi_log` names it and +`git.private-commits` keeps it from being pushed. Each append is a new revision +of that commit, so the evolog is the log's own history: + +```sh +jj evolog -r 'exactly(notevi_log, 1)' --reversed -p --git +``` + +Appends are serialized and go through an isolated `jj run`; your `@` is never +snapshotted or moved. There is no bookmark and no push — **a fresh clone will +not have your notes.** Back up the jj repo, or export the site. + +## If a coding agent is the one running it + +`notevi` notices. It reads the harness environment (Claude Code, Codex, Hermes), +falling back to walking the process tree, and adds session id, model and +reasoning effort to every entry it writes. Nothing to configure; a human at a +shell just gets entries without those fields. + +That turns the trace into a record of what an agent actually looked at before it +told you something. The web view colors coverage per reader, so overlapping +work is visible, and each note links to the conversation turn it came from. + +`constrain/` goes further and makes `notevi` the *only* way to read: a Claude +Code `PreToolUse` hook and a codex execpolicy ruleset that deny +`cat`/`rg`/`sed`/`jj file show`/`git show`/… and point the agent at +`notevi -doc`. Agents converge on it with zero instructions. See +`constrain/README.txt`. + +## Coming from `vr` / `vrsite` + +Same tool, one binary. Old sidecars (`vr_log`, `vr-log.jsonl`) are still +recognized and renamed in place on first write; `notevi migrate DIR...` does it +up front. |
