diff options
| author | Gabriel Schneider <[email protected]> | 2026-08-02 23:43:08 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-08-03 09:54:39 -0300 |
| commit | 5ec72f8723d795d0b02d7e9ebb9f555f0c7e6a2e (patch) | |
| tree | f12f4b700fff4ff6f7e818d2a542672ba0b8d76e /README.md | |
| parent | a9263daee9413c5eff3c1f1bebcd224442fd8685 (diff) | |
| download | notevi-5ec72f8723d795d0b02d7e9ebb9f555f0c7e6a2e.tar.gz notevi-5ec72f8723d795d0b02d7e9ebb9f555f0c7e6a2e.zip | |
rebrand to notevi: one CLI over the jj sidecar
vr and vrsite become a single binary. vrsite/ folds into a web package in
one module (0x4200.cafe/notevi); "notevi web" serves and exports exactly
what vrsite did, and "notevi read/grep/note/query" is unchanged.
The sidecar is renamed with it: notevi_log, notevi-log.jsonl, and the
description "private: notevi log". The pre-rebrand names are still
recognized, so an old repository opens and reads; it is renamed in place
on the first write, or up front with "notevi migrate DIR...".
That rename cannot be a single mv inside jj run. jj only auto-tracks a
*new* file in the run working copy below a size limit it does not take
from the command line, so writing a whole log under a name the change has
never held is silently dropped while jj reports success. ensureLogFile
creates the file empty first and lets every later byte be a modification
of a tracked file, which snapshots at any size; that also fixes the same
latent bug when importing a large legacy vr-log.jsonl.
Adds a bem-te-vi mark (favicon and nav brand) and a README.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
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. |
