Repository navigation
Releases: steven-pribilinskiy/polygit
Releases · steven-pribilinskiy/polygit
Release list
v3.24.1
v3.24.0
feat: the file explorer stops forgetting where you put it Its floating window kept a rect and clamped that rect back into the terminal on every render, so moving it never stuck: the geometry was session-only and every open reseeded it to 70%-centered. Position and size persist now. Which is only safe because the model changed underneath it. Clamp-and-write-back destroys a position the first time the terminal shrinks — the clamp overwrites the stored value, and growing the terminal again leaves the window where the small one forced it. That was survivable while the geometry lived and died with a single open; persisting it would have turned a transient annoyance into permanent loss. The window is now a corner plus an inset plus a size, resolved fresh each frame by `tuilith::float`, which clamps for the frame it draws and writes nothing back. It also retires a latent panic. `resize_floating_to` and `resize_floating_step` computed `bounds.x + bounds.width - floating_rect.x` on u16, which underflows for an origin outside the viewport — safe only while `clamp_floating` was guaranteed to have run first, an ordering convention between two functions in different files. There is no longer an origin that can be outside the viewport, because the only way to obtain one is to resolve it against the viewport it will be drawn in. That is the whole reason `float` went to tuilith rather than staying here, and porting the explorer is what makes the claim real rather than theoretical: two surfaces, one implementation, no convention to remember. Six duplicated geometry methods became calls into the shared component, and the four Alt+arrow arms collapsed into one delta lookup. Three tests carry it: the position survives a shrink and a re-grow, re-opening restores the geometry instead of reseeding, and resize/move are driven to their extremes against a 1x1 viewport without panicking. The tuilith side additionally implements the old clamp-and-store model inline and requires it to FAIL the first of those, so the pair distinguishes the designs rather than asserting the difference.
v3.23.0
feat: every metric in the perf panel explains itself The labels are abbreviations forced by a 23-cell box — `flush`, `backlog`, `dropped`, `overlay` — so the numbers were legible only to whoever wrote them. Dwell on a row and a popover names the channel, says what it measures, and says what a bad reading indicts: that flush is your emulator rather than this app, that a non-zero backlog is the coalescing working and not a fault, that a frame rate idling at exactly 20 is a floor imposed by the 50 ms poll and not a health signal. Channel rows carry p50/p95/p99, worst-in-window, all-time peak and sample count. The rate rows do not — a metric with no percentiles would need a line of zeros invented for it, and a line of zeros reads as a measurement. The popovers open away from the panel and are refused permission to flip. The panel draws last so its own cost stays out of the channels it reports, which means anything overlapping it is painted over; the side comes from which half of the screen the panel occupies, and flipping is the one thing that could throw a popover back across it. `HoverTip` grew a `flip` flag rather than the renderer special-casing an area, so the reason travels with the tip. Reuses the existing dwell machinery rather than building a second one: a `TooltipArea::Perf` variant and one match arm, gated on the master tooltip switch like `Info` and with no toggle of its own — the panel is already opt-in behind Ctrl+T, and a second switch would gate a thing you had to ask for twice. Verified by test rather than by eye, and the distinction matters: a unit test asserts every metric row registers a region inside the panel, on the row it describes, with its prose and its percentiles. The pty harness could NOT confirm the popover on screen — but a column header's tooltip, which predates this change, does not appear in that harness either, so the limitation is driving a one-second dwell through a pty and not a regression here.
v3.22.0
feat: the perf panel moves, remembers where you put it, and plots its…
v3.21.0
feat(coverage): build the selector in the panel, and preview where it…
v3.20.0
feat(coverage): the panel clones through the same engine as the command The panel still had its own sequential clone loop while `polygit clone` used the bounded one, so the two could drift on concurrency, skip reasons and destination — three things it is not obvious have drifted until a clone behaves differently depending on which surface started it. They are now one engine, and git::clone_repo, which nothing else called, is gone rather than left as a second way to do it. The panel also discovers the new clones into the repo list when the run finishes. Until now it only recomputed coverage, so a repo you had just cloned was invisible in the list it was cloned into until a restart. Ships as v3.20.0.
v3.19.1
fix: the perf overlay was charging its own weight to your terminal Three defects in the instrumentation itself, found while extending it. Each made the panel report something untrue, which is the only kind of bug a measuring tool cannot have — and every one of them was invisible from the outside, because a wrong number looks exactly like a right one. - The overlay's own render cost was billed to `flush`. It was excluded from `build` by being drawn after it, and the comment said "excluded from every channel above" — but the event loop computed `flush = whole_draw - build`, and `whole_draw` wraps the overlay. So the panel inflated the exact channel `verdict()` reads to conclude "TERMINAL FLUSH - the emulator is the slow part". It now times itself into an `overlay` row and a pure `attribute_frame` subtracts it. Measured with the panel open: 0.09 ms p95, which was going to the emulator's account. The residual limit is in the code and stands: the extra cells the panel puts in ratatui's diff ARE real work for the emulator. This removes our layout cost, not the emulator's cost of drawing us, so a panel-open `flush` is still slightly pessimistic. - `motion/s` and `event/s` were always the same number. Both counters were incremented on adjacent lines inside `if kind == Moved`, so no key, click, wheel, drag or resize was ever counted, and `backlog` described only motion coalescing rather than queue depth as its own doc claimed. Two rows on screen showing one fact. Every event now counts, carried to the next frame so the hot path takes no extra lock. Verified through a pty: six keypresses plus a quit now show as 4330 events against 4323 motions, where before the two totals were identical by construction. - The `[x]`'s hover highlight was dead. `apply_hover` set the style and the overlay then drew `Clear` over the same cells, which resets them - computed, then wiped. This is the "clickable but dead on hover" miss CLAUDE.md names by name, in the code that quotes the rule. The panel paints its own hover now, which also means the highlight cannot lag a frame behind a panel that has moved. The regression test asserts the background actually changes, and fails on the old implementation. Also: the panel is now opaque to the mouse. Only its `[x]` was hit-tested, so a click in the middle of it selected the repo row behind it and a drag near its edge grabbed the splitter underneath. Its whole rect is registered, like every other captured geometry. And the `build`/`palette`/`hover` docs now say those NEST rather than sum — `build` contains the other two, so a reader adding them up got a number that means nothing.
v3.19.0
feat: scrollbars get a column of their own, from a component that can…
v3.18.1
fix: icon glyphs keep their ink on their own background A copy button beside dim text came out half in its own hover highlight and half on the panel behind it. Thirteen glyphs do this, and the cause is not width — they advance one column and `unicode-width` is right about that, and so is a cursor-position report. No terminal monospace font covers them, so the fallback draws them 1.16 to 1.71 cells wide and the ink lands on the next cell, which belongs to the next span and carries whatever style that span brought. Every span that ends on one now carries the cell its ink lands on, and every click region, hover rect, dwell tooltip and column budget around an icon asks `icon_cols` rather than `UnicodeWidthStr::width`. The pad is a space inside the same span, never a wider measurement: claiming two columns for a one-column glyph would put every later region on the row a column right of where it is drawn, which is worse than what it fixes. The favourites column is two cells now. `★`/`☆` ink 1.42, and `pad_display` could not supply the overflow cell at a budget of 1 — the glyph already filled it, so the function returned early and the ink went onto the kebab gutter beside it. `🗖` and `🗗` were never two cells. They are single codepoints, which is what the icon-set rule tests, but their East_Asian_Width is N, so `unicode-width` reports 1. The comment beside them claimed 2 and said the button renderer "measures display width, so the 2-cell glyphs lay out correctly" — it does measure, which is exactly why the wrong number mattered. `🏷` is the same. `📋`, `🔗` and `❌` are EAW=W, genuinely two, and were always fine. The confirm modal had its pad on the wrong side: `" ⧉"` puts a space before a glyph whose ink spills after it. The `IconSet` comments are corrected with the code. The header justified the set by Geometric Shapes coverage, but `↯ ✗ ⚠ ★ ☆ ⧉ ↗ ✕` are Arrows, Dingbats and Misc Symbols — the rationale never covered the glyphs that overflow. Measured against Cascadia Mono and the Segoe UI Symbol it falls back to, by the screening script in the shefrd tree, and confirmed in a running instance: the Path row's escape stream now carries `⧉ ` inside one magenta run where the pad cell used to belong to the next.
v3.18.0
feat: Ctrl+T perf overlay + --perf report to find out why the UI feel…