## sinelaw/fresh — v0.4.7…v0.4.9

_124 commits._

### Features
- **feat(mouse): pan the tab strip when the wheel is over it** (9e1dfb8)
- **feat(orchestrator): open a new workspace before its worktree exists** (ce537b2)
- **Add 4 missing CLI guide keys to bg.json** (92eafef)
- **Sync bg.json with upstream: add 31 new keys (per-buffer toggles, update actions)** (54c601c)
- **Add real Bulgarian tranlsations to code-tour plugin** (e47ef62)
- **Regenerate config-schema: add bg locale to enum** (72d998e)
- **Add Bulgarian locale** (2bd6e51)
- **Add Bulgarian interface messages translaion** (3b44061)
- **cli: support vim-style +N line arguments (fresh +50 file.txt)** (edabd28)
- **update: never install a pre-release unless asked, and add --pre** (54db632)
- **i18n: align the new update strings with each locale's existing terminology** (37bd9e0)
- **scripts: add try-self-update.sh for exercising the updater by hand** (91e2ca9)
- **feat(update): fresh never runs another package manager** (f35cc48)
- **feat(update): verify release artifacts against the GitHub attestation** (62c5fa5)
- **feat(install): default to the self-updating universal build, add --method** (a919243)
- **Reach the whole New-Workspace dialog from a script, over SSH too** (8dda093)
- **Pin the orchestrator's new plugin verbs to what the dock renders** (73185fb)

### Fixes
- **fix(update): judge an endpoint override by where it points, not who set it** (34f3e69)
- **fix(release): write sidecars in the format sha256sum -c reads** (c037684)
- **Fix flaky two-server completion test by waiting for both servers** (0029e4a)
- **fix(code-tour): open every step into one target pane** (437c057)
- **fix(layout): derive the editor content area from the chrome actually drawn** (5d2e94e)
- **fix(layout): seed split viewports from the pane they are painted into** (f7f4c8e)
- **fix(plugins): push geometry only, never the plugin resize hook, from a plugin command** (cb2098e)
- **fix(plugins): reflow layout when a plugin panel creates a split** (c8088c1)
- **fix(orchestrator): make the dock's highlight span the row it highlights** (699c3d6)
- **fix(mouse): stop routing wheel events over chrome to the focused pane** (9b37c18)
- **fix(orchestrator): keep focus put when an adopted workspace finishes building** (cb54eb1)
- **fix(settings): let the wheel scroll the search results without moving the selection** (9095d88)
- **i18n(bg): sync with upstream keys and fix broken placeholders** (8ec9c43)
- **Fix i18n: add missing bg keys, code-tour bg section, sync key mismatches** (6f5872b)
- **Add bg locale to plugin i18n files and fix locale count test** (99c8228)
- **fix: make the mouse wheel scroll prompt dropdowns without moving the selection** (6a9596f)
- **fix: land the dropdown scrollbar thumb on the row that was clicked** (16fb032)
- **fix: show a scrollbar when a prompt dropdown hides entries** (db6d9c4)
- **fix: scroll prompt-line input horizontally so the cursor stays visible** (44645a8)
- **fix: keep --no-restore gating to workspace files only** (e5bcaa1)
- **fix: don't persist or restore per-file state for .git-internal files** (58bf4b7)
- **fix: honor --no-restore in mid-session workspace checkpoints** (2f0c964)
- **fix: never leave a UtilityDock role on the sole root leaf** (5621a52)
- **fix(indent): require Python's colon before the on-type dedent fires** (d4ff6c8)
- **fix(indent): dedent a line live when typing completes a dedent trigger** (8e96a7f)
- **fix(indent): indent braceless control-flow bodies in TS/JS** (88942ac)
- **fix CI: rustfmt, keymap-pinned tests, keymap-independent scene parity** (5dbd483)
- **fix(indent): don't pull deeper indent onto blank line above unindented sibling** (8608cd3)
- **fix: keep the cursor anchored to its text through format-on-save** (a2d1968)
- **fix(install): record tarball provenance even when the archive has no receipt** (c21fc94)

### Backend
- **Bump version to 0.4.9** (c1e9962)
- **CHANGELOG.md** (938ecc2)
- **Wait on a real switch signal in the dock order-stability test** (3699686)
- **Update blog post** (7bdff35)
- **Bump version to 0.4.8** (22ad039)
- **More blogpost tweaks** (5526fbc)
- **blog update** (c3ae1db)
- **blog: I hate packaging my software for Linux** (4aa2f1a)
- **lsp: stop warning about the cancellations we requested ourselves** (3f851b4)
- **lsp: keep the highlight on popups this module did not build** (317f33e)
- **lsp: resolve a completion against the server that offered it** (6046951)
- **lsp: keep the highlight on the picked completion while typing narrows the list** (5979172)
- **lsp: accept the completion the user picked, not the first row sharing its label** (1e5c270)
- **hover: suppress mouse hover while a modal overlay covers the editor** (6d21927)
- **lsp: advertise completion resolveSupport + labelDetails so servers offer auto-import candidates** (85305a0)
- **Added some more Bulgarian translations** (180b41d)
- **Remove stale update.popup_update key from bg.json** (5e5aaec)
- **Bulgarian i18n added to the builtin plugins as well** (46b4069)
- **Lock help manual to LF line endings via .gitattributes** (fe1e2cc)
- **config: let users declare which files are too ephemeral to remember** (d556e96)
- **vi mode: cover dot-repeat of the insert commands end to end** (4d356b0)
- **vi mode: make `.` replay the insert command, not the buffer between cursors** (7fe25e6)
- **tests: pin down why the clearInterval barrier is a barrier** (08f3fd3)
- **tests: stop plugin e2e tests racing the plugin thread** (a7a8140)
- **cli: make malformed ssh:// URLs a hard error, never a local file** (d4e88b1)
- **settings e2e: cover scrolled-search mouse flows and scalar control clicks** (4978b11)
- **settings: let the wheel reach the first/last search result** (2b8796d)
- **settings: hit-test scrolled search results in absolute index space** (d79f29d)
- **keybindings: log config entries dropped for unparseable key names** (0919b22)
- **input-parser: resolve a lone ESC-] / ESC-[ to Alt+] / Alt+[ on idle** (0b695c2)
- **input: context-specific keybindings outrank global ones (#2941)** (6098457)
- **Revert "refactor(indent): drop look-back/look-ahead for empty lines, use cursor's own indent"** (9a65d77)
- **Four small fixes: bun.lock JSONC highlighting, TS 7 tsconfigs, Ctrl+H docs, Rust LSP command name (#2946)** (66f17e0)
- **release: check everything checkable before anything is published** (446cd82)
- **release: test the updater being shipped, not just the one that shipped last** (066563f)
- **release: prove a release can be updated to before promoting it** (cc128a8)
- **update: detect a cargo install from cargo's own markers, drop hand-rolled base64** (78e380b)
- **scripts: refuse a stale binary, and state the attestation verdict** (223a22f)
- **i18n: translate the two renamed update strings into every locale** (4dc819f)
- **Build the web UI's synthetic events with the parser's Event type** (8f6ff3d)
- **Let the keymap pick between a chord's physical and typed readings** (3a1fda6)
- **Report the 0x1F byte as Ctrl+/ so the chord works outside kitty** (bdc697f)
- **Wait for the word-diff emphasis the test asserts, not for the text around it** (c1b50f6)
- **Translate the Review Diff strings that shipped as English placeholders** (768ec8e)
- **Let a review action's confirmation outlive the refresh it triggers** (37c1c97)
- **Don't reject before the caller can catch** (2d4fc30)
- **Cover the archive verbs and the SSH create's shared validation** (fe34511)
- **Let a script drive the dock, not just create workspaces** (df8c05c)
- **Assert the search-bar tests from the screen, not the model** (39fd897)
- **Keep the search bar open while F3 steps through matches** (a6384d8)

### Tests
- **test(mouse): keep the wheel-over-chrome test warning-free on Windows** (88701ae)
- **test(orchestrator): update dock coverage for the new default density and menu chrome** (8bbd2a4)
- **test: assert these fixes the way a user sees them, not through the model** (a531fef)
- **test: skip plugin loading in property-test harnesses to fix CI timeout** (4b5f501)
- **test(update): strip the test binary and keep the fixture out of /tmp** (9f7dd42)
- **test(update): drive the real `fresh` binary instead of a stand-in** (87b2da2)
- **test(update): run musl on PRs, and add a hermetic end-to-end update test** (6d4c13d)

### Docs
- **docs(changelog): note the code-tour target-pane fix** (7f396e9)
- **docs(changelog): cover the post-#2964 fixes in the 0.4.8 notes** (8237b05)
- **docs(changelog): restore tagged v0.4.7 section, add v0.4.8 notes** (81bb822)
- **docs: ssh:// arguments never fall back to local files** (4fe7cc7)
- **docs: add proposed long-term fix design for keybinding shadowing** (49d9fef)
- **docs: reproduce issue #2941 — global bindings shadow context-specific ones** (fde0595)
- **docs: correct build.rs and §7.5, which still described the path check** (8ac6b9c)
- **docs: order the phase list 6 before 7** (52d1e7a)
- **docs: correct the gzip-vs-xz size claim with the measured numbers** (97dbfc0)

### Chore
- **style: keep the new persistence comments to what the code can't say** (4d75b04)
- **refactor: layer input handling as a pure decision core + Editor shell** (b8cc07c)
- **refactor(indent): drop look-back/look-ahead for empty lines, use cursor's own indent** (2b37525)
- **ci: lint workflows, so a release-pipeline typo fails in a PR** (5c0d61c)
- **ci: fail the release if an archive cannot be self-updated to** (3033ed1)
- **build(musl): publish .tar.xz alongside .tar.gz for one release cycle** (44ce8ad)
- **build(musl): keep the universal archive gzipped, and teach the engine gzip** (b6e197c)
- **refactor(update): drop the path heuristic; provenance is recorded or unknown** (fa7dba0)
- **build(musl): ship a self-update receipt and switch the archive to .tar.xz** (98014cf)
- **build: move web-ui/ into crates/fresh-editor/ so it ships with the crate** (af742c1)
- **build: assemble the web-ui page only under the `web` feature** (7b43d0a)

_Recap by [Repo Wrapped](https://repowrapped.com/gh/sinelaw/fresh?utm_source=github-action)._