| name | lightjj |
| description | Interacts with a running lightjj instance (browser-based Jujutsu/jj viewer) via the `lightjj api` CLI. Reads diffs, posts inline review comments, posts doc-mode suggestions, and steers the user's view. Use when the user has lightjj running and wants the agent to review changes, annotate diffs, or comment on markdown docs. |
lightjj
lightjj is a browser-based UI for Jujutsu (jj)
version control. The browser is for the user — do NOT open URLs or screenshot
it. Use lightjj api to read and write through the same HTTP API the browser
uses. It auto-discovers the running instance, sets headers correctly, and works
in harnesses that denylist curl.
If no lightjj is running, ask the user to start it (lightjj in a jj repo) —
do not start it yourself.
Bootstrap
1. lightjj sessions # confirm a session exists, find its repo
2. lightjj api GET /tab/0/api/agent # full API contract (markdown) — read once
3. lightjj api GET /tab/0/api/capabilities # probe feature availability
GET /api/agent is the source of truth for endpoints, request/response schemas,
and the comment/suggestion model. Read it before guessing routes — it describes
the doc-comment store, the navigate endpoint, and the review-comment store.
Synopsis
lightjj api [flags] METHOD PATH [BODY]
METHOD GET | POST | PUT | DELETE | PATCH
PATH verbatim — most routes are tab-scoped: /tab/{N}/api/...
Root-only: /tabs, /api/config. Tab 0 is the launch repo.
BODY literal JSON | @file | "-" for stdin
Full reference (flags, exit codes): lightjj api --help / GET /api/agent.
Quote query strings — bare & backgrounds the shell:
lightjj api GET '/tab/0/api/file-show?revision=@&path=docs/DESIGN.md'
Common operations
lightjj api GET /tab/0/api/focus
lightjj api GET /tab/0/api/log
lightjj api GET '/tab/0/api/file-show?revision=@&path=src/main.go'
lightjj api GET '/tab/0/api/doc-comments?path=docs/DESIGN.md'
lightjj api POST /tab/0/api/doc-comments @comment.json
lightjj api POST /tab/0/api/navigate '{"file_path":"src/main.go","line":42}'
lightjj api POST /tab/0/api/navigate '{"change_id":"xyzabc","comment_id":"a1b2c3"}'
lightjj api GET '/tab/0/api/annotations?changeId=xyzabc'
lightjj api POST /tab/0/api/annotations '{"id":"a1","changeId":"xyzabc",
"filePath":"src/main.go","lineNum":42,"lineContent":"func main() {",
"comment":"missing error check","severity":"suggestion","author":"agent-name"}'
Review loop
A review is multi-turn — the user reads your comments, accepts some, marks
others won't-fix, and may post their own. Be a good participant:
-
Set author on everything you post. Both /api/annotations and
/api/doc-comments take an author field. Use a stable name (your harness
or model name). The UI renders agent comments with a ⟐ prefix and lets the
user hide-by-author. Without it, your comments look like the user's own and
you can't tell yours apart on re-read.
-
Read before writing. GET the existing comments for the file/change
before posting. The store upserts by id — a re-POST with a fresh UUID is
a duplicate, not an update. To update, re-POST with the same id.
-
Re-read after the user reviews. Poll /api/annotations?changeId=... or
/api/doc-comments?path=... and check resolution on the comments you
posted. "addressed" = accepted, "wontfix" = rejected, absent = still
open. There is no "review finished" signal — poll until your ids resolve,
or agree a convention with the user.
-
Respect won't-fix. Don't re-post a finding the user marked
resolution: "wontfix". They saw it and decided.
-
Don't write /api/focus. It's the frontend's report of what the user
is looking at — POSTing to it forges that report and lies to yourself on
the next read. Use /api/navigate to steer the user; /api/focus to
read where they are.
Multiple sessions / repos
Discovery matches the agent's cwd against each session's repo dir. If you're
inside the same repo lightjj was launched in, lightjj api ... just works. If
not:
lightjj sessions
lightjj api --repo /path/to/other GET /tab/0/api/log
lightjj api --addr 127.0.0.1:54321 GET /tab/0/api/log
A session run with lightjj --remote user@host:/repo is listed by sessions
but won't auto-match — its repo dir is a remote path. Use --addr.
Don't
- Don't
curl — the entire reason lightjj api exists is that harnesses
deny curl. It also won't auto-discover the port or set Content-Type.
- Don't run
jj commands directly when the user is reviewing in lightjj —
the snapshot loop will pick up your changes and the user's view will jump.
If you need to mutate, tell the user what you'd do and let them decide.
- Don't open the browser URL or screenshot the UI.
- Don't guess endpoint shapes —
lightjj api GET /tab/0/api/agent documents
all of them with example payloads.
Common errors
no running lightjj session matches <path> — lightjj isn't running in
this repo. Ask the user to start it, or pass --repo/--addr.
address ... is not loopback — --addr only accepts 127.0.0.1,
::1, or localhost. SSH tunnels: forward to a local port, then --addr 127.0.0.1:N.
multiple lightjj sessions match — two instances on the same repo.
lightjj sessions, then pick one with --addr.
- HTTP 200 but the body is HTML — you forgot the
/tab/N/ prefix; the
unprefixed path falls through to the SPA. Use /tab/0/api/....
- HTTP 400
Content-Type must be application/json — only happens with
curl; lightjj api sets it automatically when a body is present.
- HTTP 400
changeId required — /api/annotations uses camelCase query
params (changeId, id); /api/navigate uses snake_case body fields
(change_id, file_path). They predate each other — check /api/agent.