diff options
| author | user <user@clank> | 2026-08-13 16:32:42 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-08-13 16:32:42 +0200 |
| commit | 694b9757423e8ed4b4bb0b57d4f8640687cc034c (patch) | |
| tree | 35b95a1020faca329fc8bbdd42a35a34c1205990 | |
| parent | sl0p: account for the split button in the title-alignment test (diff) | |
| download | sl0ppi-694b9757423e8ed4b4bb0b57d4f8640687cc034c.tar.gz sl0ppi-694b9757423e8ed4b4bb0b57d4f8640687cc034c.tar.xz sl0ppi-694b9757423e8ed4b4bb0b57d4f8640687cc034c.zip | |
docs: handover
Where the split-button work stopped, what is open, the traps that cost time, and
how to verify pane/layout/mouse work on a real session rather than in the test
harness.
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | docs/HANDOVER.md | 156 |
2 files changed, 158 insertions, 0 deletions
@@ -51,5 +51,7 @@ make release # tests, then a static musl tarball make publish # upload it to sl0ppi.sl0p.foo ``` +Picking up where the last session stopped: [docs/HANDOVER.md](docs/HANDOVER.md). + See [docs/roadmap.md](docs/roadmap.md), [docs/architecture.md](docs/architecture.md), [docs/cli-design.md](docs/cli-design.md) and [FORKS.md](FORKS.md). diff --git a/docs/HANDOVER.md b/docs/HANDOVER.md new file mode 100644 index 0000000..467c29b --- /dev/null +++ b/docs/HANDOVER.md @@ -0,0 +1,156 @@ +# Handover + +Written at the end of a long session. Start here. + +## Pick this up first: the `+` split button does not render + +**Feature:** a `+` at the right end of every pane's title line; clicking it +splits that pane. Shipped in 0.1.7 (hover-gated) and 0.1.8 (always drawn). + +**Status: the click works, the button is invisible on a live session.** + +- clicking those 3 columns splits the pane — verified by injecting real SGR + mouse events into an attached client's pty (`1 -> 2 panes`; clicking the title + or mid-frame correctly does nothing) +- the button renders in **265 unit snapshots** +- it has never once been seen on a real session + +Two wrong diagnoses so far, both mine: + +1. "It's hover-gated and hover is broken" → removed the gate in 0.1.8, still + invisible. (`mouse_is_hovering_over_pane` does appear to be false live, but + that was not the only problem.) +2. "The click test proves the feature" → it does not. The hit-test is purely + geometric and never consults the renderer, so it kept working while nothing + was drawn. + +**The strong lead, untested:** every snapshot uses zellij's DEFAULT frame +config. The live config does not: + +```kdl +pane_frames { rounded_corners true; title_alignment "center"; gap 1; padding 0 0 0 0 } +``` + +`render_title_right_side` is called from **three** different title builders +(`zellij-server/src/ui/pane_boundaries_frame.rs`, lines ~889, ~915, ~983) with +different `max_length` budgets. The snapshots only ever exercised the +left-aligned path; `title_alignment "center"` takes another one. + +**Ten-second check before writing any code:** set `title_alignment "left"` in +`~/.config/sl0ppij/config.kdl` on the test box, re-attach, look for the `+`. If +it appears, that is the bug confirmed. + +**Then:** add a frame unit test using the live config's alignment/rounded/gap +settings — the reproduction that was missing all along — and fix whichever +builder drops the button. + +Code involved: + +| what | where | +|---|---| +| render + geometry | `ui/pane_boundaries_frame.rs`: `render_split_button`, `split_button_columns`, `SPLIT_BUTTON_*` | +| click | `tab/mouse_handler.rs`: `intercept_split_button_click` | + +Not drawn on floating panes on purpose: the PIN control owns that corner and is +hit-tested by its drawn position, so anything to its right moves it out from +under the pointer (`test_ctrl_click_on_floating_pin_button_toggles_pin`). + +## Where the project is + +Everything is committed and pushed to `ssh://git@git.sl0p.foo:39327/srv/git/sl0ppi.git`. +Released artifacts are at <https://sl0ppi.sl0p.foo> (currently 0.1.8). + +| phase | state | +|---|---| +| monorepo, 3 vendored forks with history | done | +| rename (sl0ppij coexists with zellij) | done | +| portable config | done | +| tarball + installer, verified in a clean room | done | +| `sl0ppi` CLI MVP (`up`/`ls`/`open`/`close`/`init`/`print`/`doctor`) | done | +| site + release scripts (no CI, by choice) | done | + +`make` for targets, `make test` for both suites, `make release && make publish` +to cut and upload a version, `packaging/publish.sh` verifies against the live +URL afterwards. + +## Open, in the order I would do them + +1. **The `+` rendering** (above). +2. **Phantom client on headless `sl0ppi up`.** `attach --create-background` + leaves one client in the session forever, so every pane frame shows + `MY FOCUS AND:`. Worked around by creating the session *by attaching* when + there is a tty; the headless path still leaks. Ruled out: the CLI-action + clients, and the creating client exiting too early (making it wait for a + server ack changed nothing). `screen.remove_client()` does clear + `connected_clients` with no early return, so instrument + `ScreenInstruction::RemoveClient` on a debug build to find where it is lost. + Cheap alternative: give the headless path its own pty (`script -qec`) and + kill the client afterwards — killed clients demonstrably do not leak. +3. **bun is the AVX2 build.** Caused `Illegal instruction` on a plain KVM guest. + One line in `packaging/fetch-vendor.sh`: `bun-linux-x64-baseline.zip`. +4. **`pir` needs python3 + fzf**, neither shipped. The fix is folding it into + `sl0ppi agent --resume` (already designed in `docs/cli-design.md`). +5. **Tab overflow.** `sl0ppi open <name>` wants to be a fuzzy picker once a root + has a dozen projects. +6. Button polish: shift/right-click for the other split direction; reuse + `status_bar_button_style` so it looks pressable. + +Fixed this session, for context: client ids were recycled (silently ate ~25% of +`zellij action` output), suspended panes spammed resize errors, responsive +layouts resolved against `visible_panes_count()` and never really expanded, +runtime `new-tab` dropped pane/tab purposes, and generated sessions had no tab +bar. See `docs/roadmap.md` for each with its measurements. + +## Traps worth knowing (all cost me time here) + +- **`pkill -f` / `pgrep -f` match your own shell's command line.** I killed my + own script three times, and twice killed the user's live clients. Match on + `comm` instead: `ps -eo pid,comm,args | awk '$2=="sl0ppij"'`. +- **Test sessions live in the runtime dir**, not `TMPDIR`. Only + `SL0PPIJ_SOCKET_DIR` isolates them. A stale session called `dev` was silently + reused across tests. +- **`INSTA_FORCE_UPDATE=1` churns hundreds of snapshots** (strips + `assertion_line`, trailing newlines). Update per-test with + `INSTA_UPDATE=always cargo test ... <test_name>` and verify the diff contains + only what you expect. +- **git paths in loops**: `git diff --name-only` prints repo-root-relative + paths; running `git checkout --` on them from inside `sl0ppij/` silently + fails. +- **Single-line KDL needs `;` between nodes.** `tab x { pane }` will not parse; + emit multi-line. +- **A tab template destroys tab purposes** — identity is a tab `purpose`, and + templating replaces the tab's root layout. That is why `sl0ppi` inlines the + template into each tab instead of emitting `default_tab_template`. +- **The tab test harness does no rendering**, so `panes_to_hide` is always empty + and stack-related bugs cannot be reproduced in it. Use a scripted pty. +- **Clean up test sessions.** A background-created session I left behind is what + produced a "MY FOCUS" bug report from the user. + +## Access + +- test box: `ssh root@10.10.10.130` (Debian, 2 vCPU; where every live check ran) +- prod: `ssh root@sl0p.foo`; nginx config lives in `~/dev/sl0pday/nginx/sl0p.conf`, + deployed with `./deploy.sh nginx/sl0p.conf` (that repo has **no** git remote) +- `sl0ppi.sl0p.foo` currently answers **401 to everyone except 87.209.3.148** + (our egress). Lift by deleting the `geo` block and the `if` in the vhost. +- new git repos: `ssh root@sl0p.foo git-new-repo <name>` +- releases need `cargo-zigbuild` + the `ziglang` python module (both installed); + `protoc` 25.1 is in `~/.local/bin` for `cargo xtask proto`. + +## How to verify things here + +Unit tests are necessary and have repeatedly been insufficient — three of this +session's bugs passed them. For anything touching panes, layouts or the mouse, +drive a real session: + +```python +# pty at a chosen size; resize or inject SGR mouse events mid-session +pid, fd = pty.fork() +if pid == 0: os.execvp("sl0ppi", ["sl0ppi"]) +fcntl.ioctl(fd, termios.TIOCSWINSZ, struct.pack("HHHH", rows, cols, 0, 0)) +os.write(fd, b"\x1b[<0;COL;ROWM") # left press, 1-based coords +``` + +then read the truth back out of `sl0ppij -s <session> action list-panes --json` +(x, y, cols, rows per pane — two panes sharing a rect means a stack) and strip +ANSI from the pty output before grepping for glyphs. |
