summaryrefslogtreecommitdiff
path: root/vrsite/main.go
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-07-30 17:05:12 -0300
committerGabriel Schneider <[email protected]>2026-07-30 17:56:23 -0300
commit8ec4e135e318c7799b2576a8729493c063da4a97 (patch)
treeab37cdbb7f478eb996264cf941891f127f303c85 /vrsite/main.go
parentcb05c363045bf0e7af5858f6d7bc26f026fa9d70 (diff)
downloadnotevi-8ec4e135e318c7799b2576a8729493c063da4a97.tar.gz
notevi-8ec4e135e318c7799b2576a8729493c063da4a97.zip
Diffstat (limited to 'vrsite/main.go')
-rw-r--r--vrsite/main.go60
1 files changed, 56 insertions, 4 deletions
diff --git a/vrsite/main.go b/vrsite/main.go
index 0a525be..5f9b1ef 100644
--- a/vrsite/main.go
+++ b/vrsite/main.go
@@ -21,6 +21,7 @@ import (
"os"
"os/user"
"path/filepath"
+ "strings"
"time"
)
@@ -32,6 +33,45 @@ func fatal(format string, a ...any) {
os.Exit(1)
}
+const usageText = `vrsite — the reading room for vr trace logs.
+
+vr logs every file a coding agent reads, greps and notes, one JSON line each,
+keyed to the jj change the code was read at. vrsite serves that log: the repo
+tree with per-agent read coverage, syntax-highlighted sources, the notes agents
+left, the conversation each note was written in, and jj queries over the repo.
+
+usage:
+ vrsite -log FILE -repo DIR [-addr HOST:PORT] [-user NAME]
+ serve it, at http://127.0.0.1:4200 by default
+ vrsite -log FILE -repo DIR -out DIR [-watch]
+ write a static copy instead — no server, so no comments, no live
+ activity, no jj queries; the focus toggle, filters and file finder
+ still work, and it holds the one change the log points at
+
+starting on a new project:
+ 1. the project must be a jj repo — in an existing git one:
+ jj git init --colocate
+ 2. give the agents vr and one log for the repo:
+ export VR_LOG=$PWD/vr-log.jsonl
+ and tell them to read with it; constrain/AGENTS.md in the vr repo is a
+ drop-in brief that does, and constrain/ can also enforce it
+ 3. let them work, then:
+ vrsite -log $PWD/vr-log.jsonl -repo $PWD
+
+A log belongs to one repository. Entries carry the jj change id they were
+recorded at, and vrsite reads the code at those changes, so a log from another
+repo has nothing to show here. Point -repo at the repository the agents ran in.
+
+Notes written in the browser are appended to the same log, under -user, at the
+change being read. Nothing else is ever written: the repository is only read,
+and the app keeps no state of its own.
+
+Session transcripts (the conversation behind a note) are looked up by session
+id under -transcripts; Claude Code and Codex are found automatically.
+
+flags:
+`
+
func main() {
logPath := flag.String("log", "", "vr trace log (jsonl)")
repo := flag.String("repo", "", "jj repo the trace was recorded in")
@@ -43,13 +83,25 @@ func main() {
lightPath := flag.String("light-theme", defaultTheme("light"), "zed theme json for the light scheme (default: discovered, else embedded One Light)")
lightName := flag.String("light-theme-name", "", "theme name inside the light family")
title := flag.String("title", "vr trace", "site title")
+ roots := flag.String("transcripts", strings.Join(defaultTranscriptRoots(), ","),
+ "comma-separated roots to look for harness session transcripts in")
watch := flag.Bool("watch", false, "with -out: watch the trace log and rebuild after changes settle")
debounce := flag.Duration("debounce", 10*time.Minute, "quiet period before a watched rebuild")
+ flag.Usage = func() {
+ fmt.Fprint(flag.CommandLine.Output(), usageText)
+ flag.PrintDefaults()
+ }
flag.Parse()
if *logPath == "" || *repo == "" {
- fatal("usage: vrsite -log FILE -repo DIR [-addr HOST:PORT] [-user NAME]\n" +
- " vrsite -log FILE -repo DIR -out DIR [-watch] [-debounce 10m]\n" +
- " shared: [-theme zed.json] [-theme-name N] [-light-theme f] [-title T]")
+ missing := "-log and -repo are required"
+ if *logPath != "" {
+ missing = "-repo is required: the repository the log was recorded in"
+ } else if *repo != "" {
+ missing = "-log is required: the jsonl file vr appends to"
+ }
+ fmt.Fprintf(os.Stderr, "vrsite: %s\n\n", missing)
+ flag.Usage()
+ os.Exit(2)
}
repoAbs, err := filepath.Abs(*repo)
if err != nil {
@@ -65,7 +117,7 @@ func main() {
if *watch {
fatal("-watch is for -out builds; the served app already follows the log")
}
- serve(*addr, *logPath, repoAbs, *title, username(*who), theme, light)
+ serve(*addr, *logPath, repoAbs, *title, username(*who), strings.Split(*roots, ","), theme, light)
return
}
build := func() { buildSite(*logPath, repoAbs, *out, *title, theme, light) }