U-tag click-to-navigate (parity with C bro MAUS)The C Bro pager supports the mouse: SGR mouse tracking (bro/MAUS.{h,c} — MAUSEnable/MAUSDisable/MAUSParse), a left-click on a U-tagged token navigates to that token's URI, the wheel scrolls, and m toggles mouse on/off. The JS (jab) pager (be/view/bro.js, be/views/bro/{bro,pager}.js) renders the very same hunks — including the U click-target tags — but has NO mouse handling at all (no SGR mouse mode, no click/wheel/button parse; confirmed by grep 2026-06-26: only SGR colour code is present). So the links the hunks already carry are dead in jab. Goal: bring the jab pager to mouse-nav parity with C bro. Method: Issues.
bro/MAUS.h/MAUS.c drive SGR mouse tracking; the U tok32 tag is an
invisible click target — a left-click on the preceding token opens its URI
(view-stack push). m toggles mouse; the wheel scrolls. Tests bro/test/MAUS.c,
bro/test/NAV.c. Spec in Bro.be/view/bro.js (the tag→SGR painter, which DOES handle the U tag for
colour) + be/views/bro/pager.js — renders U targets but never enables mouse
mode nor parses mouse events. Zero mouse/SGR-mouse/click/wheel/button hits in the
JS pager source.U tag carries the URI
the pager would open (Bro: "left-click … navigates to its URI"). Only the input
handling is missing — this is a pager-side gap, not a producer change.U-tagged token opens/navigates to that token's URI (view-stack
push, like C bro); the wheel scrolls; m toggles mouse on/off.ESC[<b;x;yM/m`); reuse the existing U`-tag click-target metadata in the hunk
stream — NO new hunk format, producers unchanged.be/view + be/views/bro); restore terminal mode on every exit path.MOUSE_ON/MOUSE_OFF (1000+1006)
bracket Pager.run (try/finally restores on every exit), and _feed splits SGR
ESC[<…M/m from keys. The GAP was the cell→U-URI lookup: _mouse ignored col and
navigated the HUNK banner URI, not the clicked token's U-target._screenToByte(row,col) (JS twin of C bro_screen_to_byte: walks the display
row skipping U-hidden cells so col counts emitted codepoints) + _uriAt(hunk,off)
(next-token-is-U → its hidden text bytes ARE the URI, TOK.h tok32Val). _mouse
now: wheel (btn 64/65) scrolls ±3; left-press → _uriAt → _runSpell (push), else
falls back to the row's hunk URI. m toggles this.mouse (writes the SGR bracket).m) as the
parity target (read bro/MAUS.c, bro/test/MAUS.c, bro/test/NAV.c, BRO.c).Pager.run try/finally); left untouched. m now also writes the bracket live.U click-target URI under the cursor → navigate (push):
_screenToByte + _uriAt in be/views/bro/pager.js.m toggle (this.mouse, gates _mouse).be-js-bro-universal xfail still red.7bb581ac (mouse-nav epic), fc5d63fd (BRO-005/006 consumer + view U-links), 579b251f (header band), 4febec96 (whole single-U line clickable) + be/test 80906f7a. The "STOPPED before commit" notes below are historical.579b251f) Fix: be/views/bro/pager.js — _mouse rewrite + new
_screenToByte/_uriAt/_toggleMouse, this.mouse field, m key (0x6d). The
SGR enable/restore + _feed parse were already present (JAB-030); the new code is
the cell→U-URI lookup that makes the carried links live.
_mouse (pager.js:346), _screenToByte (:372), _uriAt (:400),
_toggleMouse (:415), m key (:254), this.mouse (:89).tty.openpty), fed ESC[<0;2;2M over a hunk whose body
row carries a hidden U target cat:doc2.txt → asserted driveSpell ran with that
URI + a view-stack push (pty-uclick-*); ESC[<65;5;5M wheel-down scrolls
(pty-wheel-down). Headless driver.js asserts _uriAt, the U-click push/fallback,
wheel ±, and m toggle (12 checks). Repro-first: confirmed the test fails (no
_uriAt) before the fix.be-js-bro-universal stale
WILL_FAIL xfail (test prints PASS, exit 0 — flipped by ctest; not my files, not a
regression). STOPPED before commit per the gate.579b251f) FOLLOW-UP: pager hunk-header had NO pale-yellow band (only
[1m bold) while core/emit.js + C bro draw every header with it. Fix:
be/views/bro/pager.js _banner (:189) now opens theme.bannerOpen()
(BANNER_SGR 48;5;230 bg), space-FILLS to cols, closes theme.bannerClose()
(ESC[0m); imports the theme (:16). Plain (non-tty) path unchanged; mouse-nav
(_mouse/_uriAt/_screenToByte/m) preserved.48;5;230 + space-fill to
width 40 + ESC[0m close, body row unbanded (band-* checks); RED before (no bg,
no fill), GREEN after. Test be/test/bro/pager/pty.js; ctest be-js-bro-pager
Passed. STOPPED before commit.4febec96 + be/test 80906f7a) FOLLOW-UP: MULTI-ROW clickability — in jab log: only the
8-char sha (the one token before its U) navigated; a click on the row's
date/summary/author or its soft-wrap tail returned null → the bulk of every
commit row read as a dead link (<50% of cells clickable). Producer is FINE
(jab log: --tlv: each sha8 L-token is followed by its U commit:?<sha>);
the bug was the CONSUMER _uriAt. Root cause: it only tested toks[ti+1]==U.
then falls back to the line's lone U via new _lineUri (:432) — the WHOLE
logical line (incl. wrap rows) is clickable iff the line has exactly ONE U
(log/ls/commit/diff); cat's many-U-per-line word links stay token-precise.be/test/bro/rowclick/ builds a 3-commit log,
clicks rows 1/2/3 at the sha AND non-sha columns + a wrap-tail — each resolves
to its commit:?<sha>; RED before (screenRow 2 col 9 … null), GREEN after.
Drove the real jab log: binary over a pty: sha/summary/author/tail all open
the commit. driver.js+pty.js (BRO-005 mouse-nav + band) still green. be/
ctest: 73/74 (only the pre-existing be-js-bro-universal stale xfail red).
STOPPED before commit.