Changelog
User-visible changes per release. Protocol archaeology lives in
plans/; this file is for "what's new for me".
0.12.2 — 2026-09-08
- Headless
stateexposes request-scoped tree and search outcomes, accepted entry/hit counts, truncation and typed errors. Empty success is distinct from failure; retained trees are identified separately during a reload.settleremains the wait, not a success predicate. - Direct repository startup and warm recents no longer infer an organization lookup from every owner. Personal and organization history is preserved without eager probes; explicit built-in GitHub owner listing resolves the account type before choosing its endpoint.
- Tree/owner successes and failures are guarded before state or focus changes. Obsolete replies cannot overwrite a newer repository/ref/reload or a replacement provider's results; an ancillary owner error cannot cover a ready tree.
- Search failures have a durable, scrollable body, including beside expanded hits. Partial results survive a failed stream and remain incomplete. Editing an unsubmitted query cannot relabel or restyle its existing results. Unsupported global search is refused without calling the provider.
- Provider guidance distinguishes package versions, JSON-RPC
2.0, wire major1and additive spec v1.6, with precise capability defaults and compatibility evidence requirements. No new handshake/minor negotiation is introduced. - External-provider compatibility matrices, opt-in inspection and RHEL 8.10
certification remain roadmap work. This release does not claim new
rootle-bbgithubor RHEL validation.
0.12.1 — 2026-09-08
- Fixed updater command ownership:
rootle updateupdates the application and managed providers;rootle self-updateupdates only the application;rootle provider updaterefreshes provider metadata only. Provider commands now have a real namespace. Conflicting UI/maintenance arguments are rejected rather than silently ignored. - Upgrading a v0.12.0 tarball: run
rootle --updateonce to install this fix, then userootle self-updatefor application-only updates. - Commit diff
/now searches the focused diff without jumping to the sidebar.n/Nstep matches; Esc cancels an edit or clears committed highlights before leaving the diff. Search ranges preserve Unicode bytes. dis the single commit-detail key in repository and file history. File-history Enter still opens the historical file.yyanks a commit URL from the files/message pane, or a revision-pinned line URL from a source row. Deleted lines use the first parent and old rename path.Ycopies source text or the full commit message.- Changed files are grouped in an expanded, directory-first hierarchy. Filters retain needed ancestors and match both sides of a rename. Directory headings never count as selectable files.
- Diff/message page keys and
?help now register in their owning pane; context-specific hints distinguish file filtering from diff search.
0.12.0 — 2026-09-08
- Repository-wide history:
␣ hfrom a selected or browsed repository, thenEnterto inspect a commit. File history remains under␣ p h. Log replies and failures are guarded by repository, revision, scope and request generation. - Commit files remain in a sidebar beside the message or diff.
Tabswitches focus in either view; file stepping respects the active filter. Messages reuse the preview component with cached, scrollable prose layout. - Commit diffs use Tree-sitter foregrounds beneath origin and changed-span background tints. Old/new hunk sides are highlighted independently, including renamed-file language changes; omitted context is not invented. Palette changes restyle prepared diffs without refetching.
- Fresh profiles have no seeded organizations or repositories. Search is the entry point; genuine user recents are retained.
- Shared modal input prompts switch from
❯to●in NORMAL mode. - Native provider implementations no longer expose
default_orgs. The stdio wire protocol remains v1.6.
0.11.0 — 2026-09-07
Syntax highlighting and headless waits
- Replaced Syntect with statically linked Tree-sitter grammars. Whole-file parsing preserves multiline context; Markdown fences and HTML scripts highlight their embedded languages. Palette changes recolor cached files without recompiling grammar queries. TOML, YAML and TSX are supported.
--headlessnow documents its directives in--help.settle [ms]tracks workers and queued follow-ups instead of guessing from 400ms of silence. The default bound is 10 seconds; timeouts fail the run with a nonzero exit before later frames or state records are sampled.
Diagnostic sessions
--log/--log=ALLcreates a private session log;--log-file PATHandROOTLE_TRACE=PATHselect a new JSONL file. Existing files are refused, not overwritten or appended. CLI flags also work with provider commands.- Input, actions, post-transition state, actual cell grids/cursors/resize, worker outcomes and rejection reasons, RPC traffic metadata, HTTP/cache, config, update, editor and clipboard activity share one bounded writer. Operation IDs and provider session/request IDs connect the evidence.
- Metadata omits typed text, file contents, rendered glyphs and provider
stderr.
--log-contentexplicitly enables sensitive UI/stderr capture. Authorization headers, environment values, command argument vectors and RPC/HTTP bodies are never automatically recorded. - Captures have byte/event/record limits and explicit completion markers; write/queue/cap failures surface without writing over the TUI. Panic capture is best-effort and bounded. Headless draws retain their terminal buffers, and stderr capture cannot wait forever on an inherited pipe.
0.10.0 — 2026-09-07
Commit inspection and shared foundations
- Six-crate workspace —
rootleowns the application;rootle-providerowns the seam and identities;rootle-stdiothe transport;rootle-githubREST/cache;rootle-managerinstallation;rootle-diffchecked patches. All publish in dependency order. - Stable identity — typed repo/sha/ref values, domain-tagged request generations, and entity-scoped VISUAL marks replace ambiguous strings and unrelated counter comparisons.
- One list engine — refs, keybindings, settings, clone lists, history and commit files share filtering, selection and scrolling. Multi-line entries and headers no longer masquerade as item indices. Binding tables supply dispatch and hints, including real multi-key sequences; modeline modes follow the current input owner.
- Checked provider lifecycle — ten safety invariants, type correctness and two fairness-qualified temporal properties in the bounded TLA+ model. Four kept faults must violate their expected invariant. Generated production-router checks and real-child tests bridge the model to Rust; this is not an unbounded refinement proof.
- Transport fixes — unsolicited partials cannot extend an ordinary call's read deadline; progressive search uses the recovery gate; stale readers cannot damage a replacement; failed handshakes stop the child before joining its reader; waiters do not ride repeated rebuilds indefinitely.
- The commit viewer (protocol v1.6
repo/commit) — from the history lens,dinspects the commit itself: full message, changed files with/filtering, per-file unified deltas with old/new line gutters, origin-tinted rows, intra-line emphasis,]f/[ffile stepping, and the Esc ladder back to history. BlameEnterstill composes. Everything read-only, per the 0016 boundary. - Palette-correct diffs — light and dark palettes derive quiet row tints and stronger changed spans; explicit color overrides win.
- Rendering polish — full commit messages scroll independently; Unicode emphasis respects both sides; malformed/truncated patches remain explicit; help binding counts are width-fitted rather than clipped after one digit.
0.9.3 — 2026-09-04
Fixed
- A background success no longer erases a fresh error: e.g.
rootle owner/nopeshowed its 404 for a blink until the unrelated org warm-up landed and cleared the status line. Success now clears only its own loading marker. (Breaker round 3, GitHub provider.)
0.9.2 — 2026-09-04
Fixed
- A malformed or unreadable config is no longer silently ignored:
startup falls back to defaults but says so, sticky — "config
malformed/unreadable (…) — using defaults". (Breaker round 2.)
0.9.1 — 2026-09-04
Fixed
- A failed blob fetch (binary file, dead endpoint) no longer regresses to a permanent "loading…" placeholder on re-select — the error is cached and re-shown, and ␣ r retries. Stale failures no longer clobber the file you moved to. (Found by the headless breaker.)
- The "blame…" modeline transient clears when the blame lands.
- Popups enforce a size floor: at tiny viewports the search popup no longer guillotines its results box or leaks cells past the border.
0.9.0 — 2026-09-04
Added
--headless SCRIPT(plans/0023): a scripted, deterministic driver for the TUI —keys/settle/frame/statesteps in, cell-grid frames and state JSON out. No terminal, no PTY, no timing heuristics; the same input path the TUI uses. For tests, reviews, and agent-driven stress runs (-reads the script from stdin,ROOTLE_HEADLESS_COLS/ROWSsize the viewport).- macOS behavioral CI: the full e2e suite (headless + PTY) now runs natively on a macOS runner every push — not just release builds.
- Verified releases: every release tarball now carries GitHub build
provenance, verifiable with
gh attestation verify <tarball> -R rootledev/rootle. The release smoke also proves each shipped binary renders (headless), not just links.
Fixed
- XDG base dirs are honored on macOS too: config/state/cache/data
live at
~/.config|~/.local/state|~/.cache|~/.local/shareas the docs promise — not~/Library/…(caught by the new macOS CI job; settings write-back silently landed there before).
0.8.7 — 2026-08-29
Added
- Mid-session provider death is honest too: a restart-failure streak surfaces once — sticky notice, warning-tinted forge chip — until the provider recovers (instead of transient per-request errors).
0.8.6 — 2026-08-29
Added
- Fallbacks are never quiet: a degraded provider (spawn failure, bad config, tarball-kind, missing data dir) leaves a sticky modeline notice naming the provider and cause — transient statuses overlay but never erase it, and the forge chip tints warning until the declaration succeeds.
- The provider health prompt: when the configured provider won't
start, rootle asks —
rretry once,gbrowse github (sticky notice stays),eedit the config in your editor. Kinds that can't be retried (plain-HTTP tarball refs) offerg/eonly.
0.8.5 — 2026-08-29
Added
- Search-pane
yworks in the repo search popup too —ynow yanks the selected repo or org URL; every context honors or names its keys (the keymap tables gained a conformance test: every advertised row resolves to a real action).
Changed
- Architecture pass (0021):
app/mod.rs1929 → 606 lines; workers, browser, preview, global-search and theme split along their seams (workers/search/lenses/lifecycle, browser/lenses/blobs, preview/lens/motion, global_search/pane, theme/palettes) — pure moves, zero behavior change. - rootle-gitlab answers requests concurrently (v1.3): slow requests (tree fetches, blame walks) no longer stall previews behind them; transcripts stay id-tagged and line-atomic. rootle-gitlab ≥ this release carries it.
0.8.4 — 2026-08-28
Added
rootle updatesweeps providers too: every managed, unpinned, releases-tracked provider upgrades through the same verified flow, pinned and install-and-pin sources report untouched, and one dead forge fails only itself. brew/cargo/mise installs get the sweep as well — providers live outside the app's channel.- Declarative providers:
[provider] kind = "gitlab"(or any receipt name /owner/reposlug) resolves at startup; a missing one asks (y install · n browse github instead), installs checksum-verified, and hot-swaps. Optionaltag/shapins lock the build.provider usewrites the declaration — no more absolute paths in synced configs. - The preview header band dresses every file with its last commit
(
sha · subject · author · date, ambient and memoized) — not just at-commit views. - The grep/find expanded pane speaks the preview-submode grammar:
yyanks the cursor-anchored URL,:Njumps by line,bruns the blame lens. Query matches chip in the pane too, boundary-aware. - Find's current match is bold+underlined —
n/Nreads at a glance on any palette.
Fixed
- Scoped greps no longer show a quiet zero when GitHub's code index omits the repo (young/low-activity repos): rootle falls back to a local grep over the default-branch tarball — real line numbers, real blob shas.
- GitHub blame works again: upstream removed the GraphQL
Blob.blamefield; blame is now a bounded commits-walk over REST (parallel detail fetches, session cache). - Match chips survive comment-span boundaries: a needle split across syntax spans chips instead of vanishing.
0.8.3 — 2026-08-28
Added
rootle updateshows staged progress — resolved, downloading (spinner), verified, extracted, swapped, a timed0.8.2 → 0.8.3summary, and a link to the changelog anchor for what's new.- Quitting a session whose binary was updated in a shell prints
vX.Y.Z installed — relaunch for itafter the terminal restores.
Fixed
- The update toast nags once per version per 24h instead of on every
launch — the
↑ vX.Y.Zmodeline chip remains the persistent notice, and it never replaces a busy status line. The startup check is skipped entirely in CI, on dumb terminals, and when stdout isn't a terminal.
0.8.2 — 2026-08-28
Added
- Preview header band: the full path rides every file preview;
at-commit it dresses with
sha · subject · author · date. - vim visual-lines in file panes (
vin the␣ psubmode and a search hit's expanded pane): motions extend the selection,Ycopies it (the cursor line by default),yyanks a#L3-L7range URL. - The search query field restyles grammar tokens (qualifier key/value, quoted literals, negation markers take syntax colors).
Fixed
- The leader layer raises over the preview submode.
0.8.1 — 2026-08-28
Fixed
- Open-at-commit views keep syntax highlighting (highlighting reads
the real path; the
@ shamarker stays title-only) and the restore no longer keeps the marker title. - fs reference adapter: trees at a ref list directories (git ls-tree
needs
-t) — the demo render caught undrillable columns.
0.8.0 — 2026-08-28
Added
- Revision awareness (protocol v1.5):
␣ bswitches branches/tags (rootle owner/repo@reftoo),␣ p hfile history with open-at-commit,␣ p bblame lens with run margins, permalinks anchored to commit shas (yin the history lens). - The preview submode (
␣ p): the pane focuses and zooms; vim vertical motions (counts,gg/G,ctrl-d/u/f/b,{/},%,zt/zz/zb,:<line>); find-in-file returns to the submode;n/Ncycle matches there. - Modeline: state-only with a
? keysaffordance; transient modes get a one-line hint strip glued above it. Chip separator is a pipe by default —[ui] separator = "caret"restores❯; Nerd Font still draws powerline arrows.[ui]rows are live-editable in:settings. rootle update— self-update for install.sh/tarball installs (checksum-verified, atomic); brew/cargo/mise installs get their channel's command instead. Modeline notice↑ vX.Y.Zwhen a newer release exists (24h-cached, one startup call, silent offline;[update] check = falsedisables).
0.7.1 — 2026-08-27
Added
- Search results render as decorated boxes: the filename rides the top
rule, the match badge closes it right,
│gutters between the rails; follows[ui] border.
0.7.0 — 2026-08-27
Added
- Search grammar (protocol v1.2-UX): quoted literals,
-/NOTnegation,language:qualifier; client-side subtraction withfiltered N/unfiltered:honesty chips in the results title. - Full-file preview: Enter on a search hit expands to the whole file
at the match line;
/finds inside it; Esc folds back. - Facet chips: per-repo and per-language filters computed from the streaming result set — zero backend cost.
- Protocol v1.4:
limitbounded compute onsearch/code; richerorg/repositems (description/private/archived/pushed_at) — the clone wizard sorts by push date and greys archived repos. - Provider manager: plain-HTTP artifact-host installs (checksum
sidecar mandatory);
update/upgradetrack only releases-API sources — plain-HTTP and--pathinstalls are install-and-pin. - forge-conformance: the canonical provider gate (37 numbered cases), wired into rootle's, rootle-gitlab's, and rootle-bitbucket's CI.
Fixed
- rootle-gitlab learned v1.3 streaming; rootle-bitbucket's branch-keyed tree cache stopped serving the first-fetched tree forever (both caught by the conformance suite).
0.6.0 — 2026-08-27
Added
- Protocol v1.3:
$/partialstreaming search with inactivity deadlines, provider-declared modeline icons, per-hit line anchors, path-only hits, index freshness (index.as_of),file_searchcapability split. - Chrome: powerline modeline (Nerd Font opt-in), bat-style gutters,
fzf prompts,
[ui] border/[ui] nerd_font.