Tip
Subscribe to Releases: In GitHub, use Watch -> Custom -> Releases for this repository
to get a daily notification with the previous day's Ghostty tip changes.
Note
This changelog summarizes Ghostty tip nightly builds. It is auto-updated every 3 hours by GitHub Actions and shows a rolling 7-day window by default.
Entries are grouped by UTC day and combine commits across all successful runs for each day.
Last updated: September 3, 2026 at 07:40 UTC.
Runs: 1, 2
Summary: 2 runs • 7 commits • 3 authors
e01e75bterminal: don't touch me! keep the page pool free list unobtrusive (@mitchellh)This replaces the `std.heap.MemoryPool` used for page buffers with a custom pool called `UntouchedPool`. This keeps its free list in a side array and never reads/writes items until `create()`. This means that demand-driven allocations (like mmaped pages) don't incur physical costs until they're actually used. The standard `std.heap.MemoryPool` uses an intrusive linked list for its items which causes every item to be touched, which forces a full page-in of memory. It turns out we also had a lot of assertions and logic to work around this in various ways (size of rows, asserting we overwrite the free list entry, etc.) that we can now remove because of this. For an 80x24 terminal on macOS (16 KB pages): | Per terminal | Before | After | |------------------------------|----------|----------| | Page-list memory dirty | 128 KiB | 48 KiB | | Process phys_footprint delta | 143 KiB | 62 KiB | | Page-list virtual size | 2208 KiB | 1600 KiB | The remaining 48 KB is the active page, because we sprinkle metadata around the page which forces every page to be paged in. I'm going to follow this up with some work trying to move all our metadata to the front of the page so we only page one in until the rest is needed, but not sure if its achievable. Micro-benchmarks on the pool show that its twice the speed (slower) to create/free due to the side list, but in an actual `+terminal-stream` benchmark churning through pages, there is no measurable difference. I think its a good trade.31bdcd5terminal: don't touch me! keep the page pool free list unobtrusive (#14130) (@mitchellh)This replaces the `std.heap.MemoryPool` used for page buffers with a custom pool called `UntouchedPool`. This keeps its free list in a side array and never reads/writes items until `create()`. This means that demand-driven allocations (like mmaped pages) don't incur physical costs until they're actually used. The standard `std.heap.MemoryPool` uses an intrusive linked list for its items which causes every item to be touched, which forces a full page-in of memory. It turns out we also had a lot of assertions and logic to work around this in various ways (size of rows, asserting we overwrite the free list entry, etc.) that we can now remove because of this. For an 80x24 terminal on macOS (16 KB pages): | Per terminal | Before | After | |------------------------------|----------|----------| | Page-list memory dirty | 128 KiB | 48 KiB | | Process phys_footprint delta | 143 KiB | 62 KiB | | Page-list virtual size | 2208 KiB | 1600 KiB | The remaining 48 KB is the active page, because we sprinkle metadata around the page which forces every page to be paged in. I'm going to follow this up with some work trying to move all our metadata to the front of the page so we only page one in until the rest is needed, but not sure if its achievable. Micro-benchmarks on the pool show that its twice the speed (slower) to create/free due to the side list, but in an actual `+terminal-stream` benchmark churning through pages, there is no measurable difference. I think its a good trade.5dfb672surface: restore mouse_shape when modifier overrides end (@j-c-m)hard-coded .default & .text overrode a previously set OSC22 pointer shape, this was a regression introduced in 6e8ed4e8b.6674aa3surface: update keyToMouseShape tests to expect mouse_shape (@j-c-m)Update the tests to expect the mouse_shape back, not the hardcoded .default or .text3a766ccsurface: show .text (i-beam) while shift is held without mouse tracking (@j-c-m)I think this is the expected behavoir when a custom OSC22 pointer is set. Once shift is released it will return to mouse_shape (whatever the pointer was before shit held).0fb6d29SurfaceMouse: simplify keyToMouseShape (@vancluever)keyToMouseShape was initially designed with more of a transition table model in mind to handle key presses/overrides based on very specific cursor states. This never materialized, so I think it's safe to just simply the process of handling overrides and/or passing along the current cursor state from the terminal in the event of key presses. Also removed a test that is essentially a duplicate of one before it now (returning current surface shape in the event of no overrides).6000034surface: restore application mouse shape after modifier overrides (#14128) (@mitchellh)This fixes a regression of 9a6469743 introduced in 6e8ed4e8b. With this fix the mouse pointer will be restored to the previous (which could have be set to something else via OSC22), not a hardcoded .text or .default. It also will change the cursor to a text selection if shift is held even without mouse tracking, I think this is the expected behavior when a cursor is set via OSC22. (Kitty additionaly, once you start selecting changes to text (I-beam), this would be a follow-up if we desire to behave like kitty with OSC22 pointers).
Runs: 1, 2
Summary: 2 runs • 31 commits • 8 authors
807a51eupdated localization file (andrejd-magix)36015c9updated revision date (andrejd-magix)ee10453fix unclosed quote (andrejd-magix)59141adadd eu translation (@erral)58aa59dUpdate po/eu.po (@erral)6a51526Update po/eu.po (@erral)4c731b5Update po/eu.po (@erral)4ffec4bUpdate po/eu.po (@erral)f407316Update po/eu.po (@erral)applying but both eskuma and eskuina are OK.63039a6update (@erral)f184d3cupdate (@erral)4da902bupdate (@erral)9801423update (@erral)7520175more fixes (@erral)3b8141fos/open: consume the newline when draining opener stderr (@jzillmann)takeDelimiterExclusive never consumes the delimiter: it tosses only the exclusive length, so the '\n' stays buffered. Once the spawned opener writes a single line to stderr, every subsequent call returns an empty slice without advancing the stream, and openThread's loop spins forever - one pinned core per affected open(), logging empty "open stderr=" warnings at tens of thousands of messages per second for the lifetime of the process. The thread also never reaches exe.wait(), so the child is never reaped. Read inclusively instead (which does consume the delimiter) and trim the '\n' for logging. Repro: open a link whose handler writes to stderr, e.g. an OSC 8 link with an unknown scheme; watch a core disappear and the unified log flood with "os-open: open stderr=". See discussion #14100.372d691i18n: complete eu translation (#14095) (@trag1c)e212b73Update mk localization for v1.4 (#14088) (@trag1c)Addressing #13766 for mk.349f026os/open: consume the newline when draining opener stderr (#14125) (@mitchellh)Fixes the runaway-thread bug reported in #14100 (vouched there). `openThread` drains the spawned opener's stderr with `takeDelimiterExclusive('\n')`. That function tosses only the exclusive length, so the `'\n'` is never consumed. Once the child writes one line to stderr, every subsequent call returns an empty slice without advancing the stream: the `while (true)` loop spins forever — one pinned core per affected `open()`, logging empty `os-open: open stderr=` warnings at tens of thousands of messages per second for the lifetime of the process — and `exe.wait()` is never reached, so the child is never reaped. This change reads inclusively (`takeDelimiterInclusive`, which does consume the delimiter) and trims the `'\n'` for logging. Observed in the wild embedding libghostty on macOS: several days of uptime accumulated six leaked opener threads at ~70% of a core each (~4.4 cores), from six link clicks whose `/usr/bin/open` wrote to stderr. After the fix, the same workload shows zero `os-open` log traffic and no leaked threads. Repro without the fix: open a link whose handler writes to stderr (e.g. an OSC 8 link with an unknown scheme), then watch a core pin and `log stream --predicate 'subsystem == "com.mitchellh.ghostty"'` flood. **AI disclosure** (per `AI_POLICY.md`): the bug was diagnosed and this patch drafted with Claude Code (thread sampling, log analysis, and reading the Zig 0.16 `std.Io.Reader` source to confirm `takeDelimiterExclusive`/`takeDelimiterInclusive` toss semantics). I reviewed the analysis and the change, understand both, and verified the fix in a production build of the embedding app.2ba7576build(deps): bump flatpak/flatpak-github-actions/flatpak-builder (@dependabot[bot])Bumps [flatpak/flatpak-github-actions/flatpak-builder](https://github.com/flatpak/flatpak-github-actions) from 6.7 to 6.8. - [Release notes](https://github.com/flatpak/flatpak-github-actions/releases) - [Commits](https://github.com/flatpak/flatpak-github-actions/compare/401fe28a8384095fc1531b9d320b292f0ee45adb...79327416609af08178ad73b352877e51450790b3) --- updated-dependencies: - dependency-name: flatpak/flatpak-github-actions/flatpak-builder dependency-version: '6.8' dependency-type: direct:production update-type: version-update:semver-minor ...7358067build(deps): bump cachix/cachix-action (@dependabot[bot])Bumps [cachix/cachix-action](https://github.com/cachix/cachix-action) from 5f2d7c5294214f71b873db4b969586b980625e71 to 38b082610b782e7e93e209c35fd730d399dee866. - [Release notes](https://github.com/cachix/cachix-action/releases) - [Changelog](https://github.com/cachix/cachix-action/blob/master/RELEASE.md) - [Commits](https://github.com/cachix/cachix-action/compare/5f2d7c5294214f71b873db4b969586b980625e71...38b082610b782e7e93e209c35fd730d399dee866) --- updated-dependencies: - dependency-name: cachix/cachix-action dependency-version: 38b082610b782e7e93e209c35fd730d399dee866 dependency-type: direct:production ...310797dmacOS: fix cascading without affecting other new-window behaviours (@bo2themax)a8b0855macOS: fix cascading for HiddenTitlebarTerminalWindow (@bo2themax)5d6615fbash: upgrade to bash-preexec 0.7.0 (@jparise)https://github.com/rcaloras/bash-preexec/releases/tag/0.7.0 We only source bash-preexec for bash < 4.4, so most of this release is inert for us: the PS0 function-substitution hook (bash >= 5.3) and the array PROMPT_COMMAND handling (bash >= 5.1) are never reached. What we do pick up is the simpler install string, per-prompt re-adjustment of PROMPT_COMMAND when something else modifies it, preservation of $? and $_ on early returns, and the first-command preexec fix. We continue to carry one local modification: __bp_adjust_histcontrol stays disabled in the DEBUG trap hook so the user's HISTCONTROL is respected (#2269). The original justification was that we didn't use the preexec command argument, which is no longer true because we use it for the window title. The comment now explains the current reasoning: our bash >= 4.4 integration also uses `history 1` without adjusting HISTCONTROL and accepts the same inaccuracy for space-prefixed commands, so the legacy path is kept consistent with it.aafacb1macOS: fix flickering when creating new tab with glass style (@bo2themax)fec89f2macOS: fix flickering when creating new tab with glass style (#14121) (@mitchellh)A regression from #13985. https://github.com/user-attachments/assets/cc7d76d7-7d86-4566-921c-a6531ce4087d ### AI Disclosure Used Claude to investigate, I reviewed and tested.0c1909dbash: upgrade to bash-preexec 0.7.0 (#14120) (@mitchellh)https://github.com/rcaloras/bash-preexec/releases/tag/0.7.0 We only source bash-preexec for bash < 4.4, so most of this release is inert for us: the PS0 function-substitution hook (bash >= 5.3) and the array PROMPT_COMMAND handling (bash >= 5.1) are never reached. What we do pick up is the simpler install string, per-prompt re-adjustment of PROMPT_COMMAND when something else modifies it, preservation of $? and $_ on early returns, and the first-command preexec fix. We continue to carry one local modification: __bp_adjust_histcontrol stays disabled in the DEBUG trap hook so the user's HISTCONTROL is respected (#2269). The original justification was that we didn't use the preexec command argument, which is no longer true because we use it for the window title. The comment now explains the current reasoning: our bash >= 4.4 integration also uses `history 1` without adjusting HISTCONTROL and accepts the same inaccuracy for space-prefixed commands, so the legacy path is kept consistent with it. *AI Usage:* I asked Fable 5.1 to run a verification pass after my manual upgrade, and it confirmed the expected behavior.084316amacOS: fix cascading without affecting other new-window behaviours (#14118) (@mitchellh)Found another regression when investigating #14107 after the last fix. This regression appears on macOS 15 and 26 as well: **New window by Shortcuts.app or service menu while a window is visible would create a tab**. It appears that for `new-window` triggered by Shortcuts/Service, a small delay is needed to avoid automatic tabbing. It's either removing `NSWindow.userTabbingPreference == .always` completely or adding another "delay" for cascading. The latter should be better. Also fixes another cascading for `macos-titlebar-style = hidden` previously missed.41004c6build(deps): bump cachix/cachix-action from 5f2d7c5294214f71b873db4b969586b980625e71 to 38b082610b782e7e93e209c35fd730d399dee866 (#14116) (@mitchellh)Bumps [cachix/cachix-action](https://github.com/cachix/cachix-action) from 5f2d7c5294214f71b873db4b969586b980625e71 to 38b082610b782e7e93e209c35fd730d399dee866. <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/cachix/cachix-action/blob/master/RELEASE.md">cachix/cachix-action's changelog</a>.</em></p> <blockquote> <h1>Release</h1> <ol> <li> <p>Create and push a new tag:</p> <pre lang="console"><code>git tag v17 git push origin v17 </code></pre> </li> <li> <p>Wait for CI to pass.</p> </li> <li> <p><a href="https://github.com/cachix/cachix-action/releases/new">Create a release</a> for the new tag.</p> </li> <li> <p>Move the major version tag to the latest release:</p> <pre lang="console"><code>git tag -fa v17 git push origin v17 --force </code></pre> </li> </ol> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/cachix/cachix-action/commit/38b082610b782e7e93e209c35fd730d399dee866"><code>38b0826</code></a> dev: cleanup tests and dev files</li> <li><a href="https://github.com/cachix/cachix-action/commit/0fe030c2864be690428363af3bc7016b7b1925d8"><code>0fe030c</code></a> dist</li> <li><a href="https://github.com/cachix/cachix-action/commit/792dafcfd01b48d3df8424b641db396602252fc3"><code>792dafc</code></a> deps: bump dependencies</li> <li><a href="https://github.com/cachix/cachix-action/commit/b690244fb5c76a5486c33b0fbbc6fd55c857d1fe"><code>b690244</code></a> ci: improve Nix compatibility test coverage</li> <li><a href="https://github.com/cachix/cachix-action/commit/f495f3ffa2f3810a92e5cc0abc2c5d6a2a07ec82"><code>f495f3f</code></a> Merge pull request <a href="https://redirect.github.com/cachix/cachix-action/issues/217">#217</a> from cachix/dependabot/github_actions/actions/checkout-7</li> <li><a href="https://github.com/cachix/cachix-action/commit/9ee3c77d45d24a8b7557d22cbba3454f2a4f8a7b"><code>9ee3c77</code></a> chore(deps): bump actions/checkout from 6 to 7</li> <li>See full diff in <a href="https://github.com/cachix/cachix-action/compare/5f2d7c5294214f71b873db4b969586b980625e71...38b082610b782e7e93e209c35fd730d399dee866">compare view</a></li> </ul> </details> <br /> Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details>dd167ccbuild(deps): bump flatpak/flatpak-github-actions/flatpak-builder from 6.7 to 6.8 (#14115) (@mitchellh)Bumps [flatpak/flatpak-github-actions/flatpak-builder](https://github.com/flatpak/flatpak-github-actions) from 6.7 to 6.8. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/flatpak/flatpak-github-actions/releases">flatpak/flatpak-github-actions/flatpak-builder's releases</a>.</em></p> <blockquote> <h2>v6.8</h2> <ul> <li>Add saveCache flag</li> <li>Add ability to override artifact name</li> <li>Add buildDebugBundle flag</li> <li>Update tests, documentation and dependencies</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/flatpak/flatpak-github-actions/commit/79327416609af08178ad73b352877e51450790b3"><code>7932741</code></a> Update all dependencies and regenerate dist</li> <li><a href="https://github.com/flatpak/flatpak-github-actions/commit/09e3d61868ecd92a1c5b298a31bcc4bae17ae217"><code>09e3d61</code></a> readme: Don't specify setting cache key to github.sha (<a href="https://redirect.github.com/flatpak/flatpak-github-actions/issues/261">#261</a>)</li> <li><a href="https://github.com/flatpak/flatpak-github-actions/commit/23e622281a14ba5350ce2ab1ae700ac7d08cc841"><code>23e6222</code></a> Update runtime versions and docker images to latest</li> <li><a href="https://github.com/flatpak/flatpak-github-actions/commit/a3ab43f58191aa8dc105e572c0a62eaac0a7555a"><code>a3ab43f</code></a> flatpak-builder: Add saveCache flag</li> <li><a href="https://github.com/flatpak/flatpak-github-actions/commit/8e357b1556f526e3642244bdf1a6d585be36de54"><code>8e357b1</code></a> ci: Remove unnecessary 'needs' from debug bundle job</li> <li><a href="https://github.com/flatpak/flatpak-github-actions/commit/26e19caa3a954b1d36898a0e239a67d8e856f99c"><code>26e19ca</code></a> ci: Add test for artifact-name</li> <li><a href="https://github.com/flatpak/flatpak-github-actions/commit/06d246b4d5459d93c166243236f8a086d5578746"><code>06d246b</code></a> flatpak-builder: Add ability to override artifact name</li> <li><a href="https://github.com/flatpak/flatpak-github-actions/commit/a2622647717d8185d0f8cf01bb1ea2341e357ae0"><code>a262264</code></a> ci: Add job that uses build-debug-bundle</li> <li><a href="https://github.com/flatpak/flatpak-github-actions/commit/f7362292df659c06960a8c0dc309ab5990454a29"><code>f736229</code></a> flatpak-builder: Add buildDebugBundle flag</li> <li><a href="https://github.com/flatpak/flatpak-github-actions/commit/3b10954431df173eb3b564bb9adfddf3842ff91c"><code>3b10954</code></a> ci: Update actions to versions using Node 24</li> <li>See full diff in <a href="https://github.com/flatpak/flatpak-github-actions/compare/401fe28a8384095fc1531b9d320b292f0ee45adb...79327416609af08178ad73b352877e51450790b3">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details>06178eeterminal/search: resume a complete search when history is prepended (@mitchellh)A search that had already exhausted a screen's PageList never picked up history pages prepended afterwards by incremental snapshot restore. The lower level PageListSearch and so on could already handle this, we just needed to let it know that more history existed to search. This fixes that.b0481f5terminal/search: resume a complete search when history is prepended (#14123) (@mitchellh)A search that had already exhausted a screen's PageList never picked up history pages prepended afterwards by incremental snapshot restore. The lower level PageListSearch and so on could already handle this, we just needed to let it know that more history existed to search. This fixes that.
Runs: 1, 2
Summary: 2 runs • 7 commits • 4 authors
38c984ebuild(deps): bump softprops/action-gh-release from 3.0.2 to 3.0.3 (@dependabot[bot])Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 3.0.2 to 3.0.3. - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/3d0d9888cb7fd7b750713d6e236d1fcb99157228...efb35369e0ad2afab669f228072c1b0d510eae64) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-version: 3.0.3 dependency-type: direct:production update-type: version-update:semver-patch ...d4a5ff5macOS: fix window cascading (@bo2themax)d2e2488build(deps): bump softprops/action-gh-release from 3.0.2 to 3.0.3 (#14098) (@mitchellh)Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 3.0.2 to 3.0.3. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/softprops/action-gh-release/releases">softprops/action-gh-release's releases</a>.</em></p> <blockquote> <h2>v3.0.3</h2> <p><code>3.0.3</code> is a maintenance release with updated dependencies. It also safely classifies malformed GitHub API errors to avoid secondary failures (<a href="https://redirect.github.com/softprops/action-gh-release/issues/822">#822</a>).</p> <h2>What's Changed</h2> <h3>Bug fixes 🐛</h3> <ul> <li>fix: safely classify GitHub API errors by <a href="https://github.com/chenrui333"><code>@chenrui333</code></a> in <a href="https://redirect.github.com/softprops/action-gh-release/pull/822">softprops/action-gh-release#822</a></li> </ul> <h3>Other Changes 🔄</h3> <ul> <li>dependency updates</li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md">softprops/action-gh-release's changelog</a>.</em></p> <blockquote> <h2>3.0.3</h2> <p><code>3.0.3</code> is a maintenance release with updated dependencies. It also safely classifies malformed GitHub API errors to avoid secondary failures (<a href="https://redirect.github.com/softprops/action-gh-release/issues/822">#822</a>).</p> <h2>What's Changed</h2> <h3>Bug fixes 🐛</h3> <ul> <li>fix: safely classify GitHub API errors by <a href="https://github.com/chenrui333"><code>@chenrui333</code></a> in <a href="https://redirect.github.com/softprops/action-gh-release/pull/822">softprops/action-gh-release#822</a></li> </ul> <h3>Other Changes 🔄</h3> <ul> <li>dependency updates</li> </ul> <h2>3.0.2</h2> <p><code>3.0.2</code> is a patch release focused on release reliability and compatibility. It reuses existing draft releases when publishing prereleases, supports replacing release assets on Gitea, hardens streamed asset uploads, and provides clearer release-creation diagnostics. It also includes TypeScript, coverage, and tooling maintenance merged since <code>3.0.1</code>.</p> <p>This release fixes <a href="https://redirect.github.com/softprops/action-gh-release/issues/795">#795</a>, <a href="https://redirect.github.com/softprops/action-gh-release/issues/438">#438</a>, and <a href="https://redirect.github.com/softprops/action-gh-release/issues/803">#803</a>. The upload transport hardening covers the historical failure reported in <a href="https://redirect.github.com/softprops/action-gh-release/issues/790">#790</a>, although current hosted Node 24 runners did not reproduce it naturally. The diagnostics work is related to <a href="https://redirect.github.com/softprops/action-gh-release/issues/786">#786</a> and does not claim a reproducible release-creation fix.</p> <h2>What's Changed</h2> <h3>Exciting New Features 🎉</h3> <ul> <li>feat: improve release error reporting and test coverage by <a href="https://github.com/chenrui333"><code>@chenrui333</code></a> in <a href="https://redirect.github.com/softprops/action-gh-release/pull/813">softprops/action-gh-release#813</a></li> </ul> <h3>Bug fixes 🐛</h3> <ul> <li>fix: publish existing draft releases as prereleases by <a href="https://github.com/godfengliang"><code>@godfengliang</code></a> in <a href="https://redirect.github.com/softprops/action-gh-release/pull/801">softprops/action-gh-release#801</a></li> <li>fix: upload small checksum assets reliably by <a href="https://github.com/chenrui333"><code>@chenrui333</code></a> in <a href="https://redirect.github.com/softprops/action-gh-release/pull/815">softprops/action-gh-release#815</a></li> <li>fix: replace existing release assets on Gitea by <a href="https://github.com/chenrui333"><code>@chenrui333</code></a> in <a href="https://redirect.github.com/softprops/action-gh-release/pull/816">softprops/action-gh-release#816</a></li> <li>fix: clarify release creation 404 errors by <a href="https://github.com/chenrui333"><code>@chenrui333</code></a> in <a href="https://redirect.github.com/softprops/action-gh-release/pull/817">softprops/action-gh-release#817</a></li> </ul> <h3>Other Changes 🔄</h3> <ul> <li>chore(deps): upgrade TypeScript to 7 by <a href="https://github.com/chenrui333"><code>@chenrui333</code></a> in <a href="https://redirect.github.com/softprops/action-gh-release/pull/812">softprops/action-gh-release#812</a></li> <li>chore(deps): remove unused TypeScript tooling by <a href="https://github.com/chenrui333"><code>@chenrui333</code></a> in <a href="https://redirect.github.com/softprops/action-gh-release/pull/814">softprops/action-gh-release#814</a></li> <li>dependency, Node 24 pin, and CI maintenance merged since <code>3.0.1</code></li> </ul> <h2>3.0.1</h2> <ul> <li>maintenance release with updated dependencies</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/softprops/action-gh-release/commit/efb35369e0ad2afab669f228072c1b0d510eae64"><code>efb3536</code></a> release 3.0.3 (<a href="https://redirect.github.com/softprops/action-gh-release/issues/840">#840</a>)</li> <li><a href="https://github.com/softprops/action-gh-release/commit/6441963a7597ab67f36fea0287a7ae58a9bfd8fe"><code>6441963</code></a> chore(deps): bump the npm group with 2 updates (<a href="https://redirect.github.com/softprops/action-gh-release/issues/839">#839</a>)</li> <li><a href="https://github.com/softprops/action-gh-release/commit/e5ee6bc58a36b838b92fc1217f2e4b414b5abcc8"><code>e5ee6bc</code></a> chore(deps): bump esbuild from 0.28.1 to 0.28.2 in the npm group (<a href="https://redirect.github.com/softprops/action-gh-release/issues/837">#837</a>)</li> <li><a href="https://github.com/softprops/action-gh-release/commit/d1e66170d32c9ec7bbcb7fae044d3d686ce304d3"><code>d1e6617</code></a> chore(deps): bump undici from 6.27.0 to 6.28.0 (<a href="https://redirect.github.com/softprops/action-gh-release/issues/831">#831</a>)</li> <li><a href="https://github.com/softprops/action-gh-release/commit/64037519ba20f54c01bc1dc90342c929aac5a2fa"><code>6403751</code></a> chore(deps): bump the npm group with 2 updates (<a href="https://redirect.github.com/softprops/action-gh-release/issues/835">#835</a>)</li> <li><a href="https://github.com/softprops/action-gh-release/commit/7c7184b6876126a5df15adc5b679dc450a393725"><code>7c7184b</code></a> chore(deps): bump postcss from 8.5.19 to 8.5.25 (<a href="https://redirect.github.com/softprops/action-gh-release/issues/833">#833</a>)</li> <li><a href="https://github.com/softprops/action-gh-release/commit/0f3f0d2943676d58f9698b3ab590c2056023d77d"><code>0f3f0d2</code></a> chore(deps): bump brace-expansion from 5.0.8 to 5.0.9 (<a href="https://redirect.github.com/softprops/action-gh-release/issues/832">#832</a>)</li> <li><a href="https://github.com/softprops/action-gh-release/commit/77fb938f2f95e717ce6705d2909af527263360a0"><code>77fb938</code></a> chore(deps): bump prettier from 3.9.5 to 3.9.6 in the npm group (<a href="https://redirect.github.com/softprops/action-gh-release/issues/830">#830</a>)</li> <li><a href="https://github.com/softprops/action-gh-release/commit/5a6f51711ce2ba103b78f5e9550f810679f11e0e"><code>5a6f517</code></a> chore(deps): bump brace-expansion from 5.0.7 to 5.0.8 (<a href="https://redirect.github.com/softprops/action-gh-release/issues/828">#828</a>)</li> <li><a href="https://github.com/softprops/action-gh-release/commit/a3c91c98f80000f5b06c7fc0327c54f51c6ab7d8"><code>a3c91c9</code></a> chore(deps): bump the github-actions group with 2 updates (<a href="https://redirect.github.com/softprops/action-gh-release/issues/825">#825</a>)</li> <li>Additional commits viewable in <a href="https://github.com/softprops/action-gh-release/compare/3d0d9888cb7fd7b750713d6e236d1fcb99157228...efb35369e0ad2afab669f228072c1b0d510eae64">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details>b7a680bmacOS: fix window cascading (#14106) (@mitchellh)Regression from https://github.com/ghostty-org/ghostty/pull/13722451e224macOS: clean up for #14106 (@bo2themax)3c1ef5bmacOS: clean up for #14106 (#14111) (@mitchellh)I don't know what happened to me, but I didn't notice that I should delete this20abdb5Update VOUCHED list (#14101) (@ghostty-vouch[bot])Triggered by [discussion comment](https://github.com/ghostty-org/ghostty/discussions/14100#discussioncomment-18229353) from @jcollie. Vouch: @jzillmann
Runs: 1, 2, 3, 4, 5
Summary: 5 runs • 60 commits • 8 authors
300a0dfAdd the Serbian and Serbian Latin translations (@kostich)74e0bfdRegister code ownership (@kostich)7aa4767Add new translations to locales file (@kostich)635abb7Update po/sr.po (@kostich)e8ba5d2Standardize how config/setting/preference is translated (@kostich)1ae448cFix translation of sequences (@kostich)2a0371bApply batched suggestions from code review (@kostich)17a2474Use the correct accusative form for inanimata (@kostich)e3969abAlign translations for current and to left/right (@kostich)84c8e7dAlign translation for Focus (@kostich)a542359libghostty: use caller allocation on native freestanding (@Uzaaft)Native freestanding targets have neither an OS page allocator nor a usable default SMP allocator. Use the allocator supplied through libghostty for terminal page storage and make a missing C allocator fail with out-of-memory instead of instantiating hosted allocation machinery. Document that native freestanding C callers must supply an allocator for allocating operations.3376153build: support native freestanding libghostty-vt (@Uzaaft)Native freestanding targets cannot emit shared libraries and do not provide an OS page size, stack unwinder, hosted SIMD dependencies, or filesystem-backed Kitty graphics. Build only the static artifact for those targets, define the minimum alignment used for terminal pages, disable hosted-only defaults, and install the public headers with the archive.10b7158ci: cross-compile freestanding libghostty-vt (@Uzaaft)fc7bfa6ci: move freestanding build into test workflow (@Uzaaft)028af92terminal: clarify page allocator fallback (@Uzaaft)e8709b1Merge remote-tracking branch 'upstream/main' into add-serbian-translation (@kostich)90f7759Fix HTML/URL acronyms as agreed (@kostich)8bf7e51Regenerate sr@latin.po from sr.po (@kostich)5e02d00ci: require freestanding libghostty-vt builds (@Uzaaft)458f079Use the informal form (@kostich)2c854a1freestanding support (#14076) (@mitchellh)149c9f5terminal: extract whole-terminal search orchestration from the search thread (@mitchellh)32601cdterminal/c: add search wrapper implementing the whole-terminal search API (@mitchellh)cdef14aRemove X-Generator from the sr.po file (@kostich)f0c918fterminal/c: allow freeing a search and its terminal in any order (@mitchellh)f920291libghostty: add ghostty_search_* terminal search C API (@mitchellh)674abd8example: add c-vt-search demonstrating the terminal search C API (@mitchellh)76d9fcelibghostty: set the search needle via ghostty_search_set, drop GhosttySearchOptions (@mitchellh)4b51f52libghostty: add terminal search API (#14097) (@mitchellh)This exposes the terminal search API through libghostty C and Zig APIs. This was previously available through the Zig APIs but forced our threading model. I've now extracted the full terminal search state to a new `terminal.search.TerminalSearch` structure so threading isn't forced. The C API is completely new. ## Example (C) ```c GhosttySearch search; ghostty_search_new(NULL, &search, terminal); GhosttyString needle = { (const uint8_t *)"error", 5 }; ghostty_search_set(search, GHOSTTY_SEARCH_OPT_NEEDLE, &needle); ghostty_search_run(search); // Find bar chrome: "k of n" size_t total, idx; ghostty_search_get(search, GHOSTTY_SEARCH_DATA_TOTAL_MATCHES, &total); // Enter: select the next match (wraps, scrolls the viewport if needed) ghostty_search_set(search, GHOSTTY_SEARCH_OPT_SELECT_NEXT, NULL); ghostty_search_get(search, GHOSTTY_SEARCH_DATA_SELECTED_INDEX, &idx); ghostty_search_free(search); ```8168115Add Serbian translation (#13842) (@00-kat)## Summary - Adds Serbian translations for both Cyrillic (`sr`) and Latin (`sr@latin`) scripts, registered in `src/os/i18n_locales.zig` and `CODEOWNERS`. - `po/sr@latin.po` is generated from `po/sr.po` with `msgfilter recode-sr-latin` and should not be translated by hand. - Replaces the closed #13030; strings are rebased onto current `main`. Cc @slowdub for a review. EDIT: AI disclosure: I used Cursor (Grok 4.6) for mechanical repo work only, not for writing the Serbian translations. The agent fetched ghostty-org/ghostty, branched from current main, ran msgmerge on po/sr.po against the template, generated po/sr@latin.po with msgfilter recode-sr-latin, registered sr / sr@latin in src/os/i18n_locales.zig and CODEOWNERS, rebased my three commits onto later main, pushed the branch, and opened this PR (I had intended to open the PR myself, s***** thing ignored my instructions). I translated and reviewed sr.po and the Latin file is a recode of that catalog, not a separate translation since Serbian Cyrillic can be perfectly transcoded to the Latin script via [recode-sr-latin](https://linux.die.net/man/1/recode-sr-latin).d23af9eMerge branch 'ghostty-org:main' into main (@mohshami)80b8e49Merge branch 'ghostty-org:main' into main (@mohshami)5546750Merge branch 'ghostty-org:main' into main (@mohshami)1510d2bMerge branch 'ghostty-org:main' into main (@mohshami)b5817a3Merge branch 'ghostty-org:main' into main (@mohshami)f6244f7Merge branch 'ghostty-org:main' into main (@mohshami)320ba75Merge branch 'ghostty-org:main' into main (@mohshami)1054be4Merge branch 'ghostty-org:main' into main (@mohshami)6758251Merge branch 'ghostty-org:main' into main (@mohshami)768bc2eMerge branch 'ghostty-org:main' into main (@mohshami)4c696b9Merge branch 'ghostty-org:main' into main (@mohshami)9af9348Merge from upstream (@mohshami)58f43d5Merge branch 'ghostty-org:main' into main (@mohshami)c8c4526Merge branch 'ghostty-org:main' into main (@mohshami)81d28beMerge branch 'ghostty-org:main' into main (@mohshami)5f54958terminal: fix living item over-count in RefCountedSet.addWithId (@mitchellh)Reported in https://github.com/ghostty-org/ghostty/discussions/14064 I validated this myself manually. The zero-ref branch of `addWithIdContext` incremented `living` unconditionally even if `upsert` resolved the value to an item that was already alive under a different ID. This would cause `living` to be invalid for each time this happened and the downstream effect was that `count()` drifted. I couldn't find any crashing or invalid effect except that this caused requested style memory to be over-provisioned.abac4c2Merge branch 'ghostty-org:main' into main (@mohshami)0dc2032Merge branch 'ghostty-org:main' into main (@mohshami)0254a7fMerge branch 'ghostty-org:main' into main (@mohshami)dfccdb2Implement needed modifications for issue #12600 (@mohshami)For middle-click-action * Kept the option "primary-paste" instead of "paste-primary" to keep backwards compatibility * Added the option "clipboard-paste" For copy-on-select * Added the both, none and primary options Updated config documentation Run zig fmt Move true/false options for copy-on-select to the compatibility handler Update src/config/Config.zig Update src/config/Config.zig Update src/config/Config.zig Update src/config/Config.zig Update src/config/Config.zig Update src/config/Config.zig Update src/Surface.zig Update src/Surface.zig Update src/config/Config.zig Update src/config/Config.zig Update src/config/Config.zig Update src/config/Config.zig Update src/config/Config.zig Update src/Surface.zig Update src/Surface.zig Reorder switch items Apply comment from kat Remove redundent codee80ce2eFix build error (@mohshami)f6113eaImplement needed modifications for issue #12600, more flexible copy-on-select and middle-click-action (#12604) (@mitchellh)For middle-click-action * Kept the option "primary-paste" instead of "paste-primary" to keep backwards compatibility * Added the option "clipboard-paste" For copy-on-select * Added the both, none and primary options Updated config documentation Note: No AI was used, Even though I don't know Zig, I looked at the code and the modifications seemed easy enough Closes #12600c290639terminal: fix living item over-count in RefCountedSet.addWithId (#14081) (@mitchellh)Reported in https://github.com/ghostty-org/ghostty/discussions/14064 I validated this myself manually. The zero-ref branch of `addWithIdContext` incremented `living` unconditionally even if `upsert` resolved the value to an item that was already alive under a different ID. This would cause `living` to be invalid for each time this happened and the downstream effect was that `count()` drifted. I couldn't find any crashing or invalid effect except that this caused requested style memory to be over-provisioned. cc @qwerasd205 since its ref counted set, but I did this work manually ❤️0525c18i18n: adjust and extend Ukrainian translation (@chernetskyi)c50288ci18n: address comments for Ukrainian translation (@chernetskyi)2a51bdfi18n: return Ghostty to Ukrainian translation (@chernetskyi)1026a00i18n: adjust Ukrainian translations (@chernetskyi)d4d8f62i18n: adjust and extend Ukrainian translation (#13854) (@trag1c)e8aa098Update VOUCHED list (#14092) (@ghostty-vouch[bot])Triggered by [discussion comment](https://github.com/ghostty-org/ghostty/discussions/14091#discussioncomment-18212381) from @pluiedev. Denounce: @thomas-trijindevec3e384Sync CODEOWNERS vouch list (#14090) (@ghostty-vouch[bot])Sync CODEOWNERS owners with vouch list. ## Added Users - @jakeriksen - @Kleshzz
Runs: 1, 2, 3, 4, 5, 6
Summary: 6 runs • 15 commits • 7 authors
c181983build: update Sparkle to 2.9.6 and pin SPM (@bo2themax)7fd93e0build: update Sparkle to 2.9.6 and pin SPM (#14082) (@mitchellh)3e2c0fagtk: do not warn when gtk-xft-dpi is -1 (@mgsloan)Before this change, ghostty frequently logs the following warning, even though a `gtk-xft-dpi` value of `-1` is valid and indicates default scaling. ``` warning(gtk_ghostty_surface): gtk-xft-dpi has invalid value (-1), using default ``` From [the gtk docs](https://docs.gtk.org/gtk4/property.Settings.gtk-xft-dpi.html): > The font resolution, in 1024 * dots/inch. > > -1 to use the default value.860cfb1Address review feedback (@mgsloan)8af6897gtk: do not warn when gtk-xft-dpi is -1 (#14085) (@jcollie)Before this change, ghostty frequently logs the following warning, even though a `gtk-xft-dpi` value of `-1` is valid and indicates default scaling. ``` warning(gtk_ghostty_surface): gtk-xft-dpi has invalid value (-1), using default ``` From [the gtk docs](https://docs.gtk.org/gtk4/property.Settings.gtk-xft-dpi.html): > The font resolution, in 1024 * dots/inch. > > -1 to use the default value.6d850feUpdate VOUCHED list (#14084) (@ghostty-vouch[bot])Triggered by [discussion comment](https://github.com/ghostty-org/ghostty/discussions/14083#discussioncomment-18204946) from @jcollie. Vouch: @mgsloan97f57edrenderer: vsync unfocused surfaces while dirty (@j-c-m)6ae1784f4 Unfocused surfaces stopped the CVDisplayLink and encoded a GPU frame on every PTY wakeup. A burst of close writes became that many Metal submits instead of one vsync. Keep the link running while the surface is visible and dirty or animating, whether or not it is focused. Idle surfaces still park. Focus continues to gate cursor blink, custom-shader animation, and QoS.166d2febuild: update Sparkle to 2.9.4 (@Svector-anu)090fca4terminal/kitty: validate POSIX shared memory names (@mitchellh)Update shared memory name validation according to the new spec: https://github.com/kovidgoyal/kitty/commit/22042970cf3a4668d02a1a7bcccca778ec864c217035647build: update Sparkle to 2.9.4 (#14072) (@mitchellh)Update the macOS Sparkle dependency from 2.9.0 to 2.9.4. This keeps the Swift package resolution and all tag/tip release workflow downloads aligned on the same version. Sparkle 2.9.2 included fixes for GHSA-g3hp-f6mg-559v and GHSA-hg88-v3cw-3qrh; 2.9.4 is the current stable release. Validation: - verified the 2.9.4 release contains `Sparkle-for-Swift-Package-Manager.zip` - verified the lockfile revision matches the 2.9.4 tag - `jq empty` on `Package.resolved` - `git diff --check` I could not run Xcode package resolution locally because the active developer directory is Command Line Tools rather than a full Xcode installation.ec7929cterminal/kitty: validate POSIX shared memory names (#14080) (@mitchellh)Update shared memory name validation according to the new spec: https://github.com/kovidgoyal/kitty/commit/22042970cf3a4668d02a1a7bcccca778ec864c2183c5671renderer: vsync unfocused surfaces while dirty (#14068) (@mitchellh)A follow on for #14035, we can now fix a long standing effiency/performance bug now that we park the display link while idle. This actually could cause "animated" un-focused windows to use more GPU than their focused counterparts. (AI Agent interfaces seem to love animation). 6ae1784f4 Unfocused surfaces stopped the CVDisplayLink and encoded a GPU frame on every PTY wakeup. A burst of close writes became that many Metal submits instead of one vsync. Keep the link running while the surface is visible and dirty or animating, whether or not it is focused. Idle surfaces still park.98cd670Update VOUCHED list (#14079) (@ghostty-vouch[bot])Triggered by [discussion comment](https://github.com/ghostty-org/ghostty/discussions/14078#discussioncomment-18203195) from @jcollie. Vouch: @and-rs094d175deps: Update iTerm2 color schemes (@mitchellh)0a76c31Update iTerm2 colorschemes (#14077) (@jcollie)Upstream release: https://github.com/mbadolato/iTerm2-Color-Schemes/releases/tag/release-20260824-153547-75c93ee
Runs: 1, 2
Summary: 2 runs • 5 commits • 3 authors
7b47213Update VOUCHED list (#14074) (@ghostty-vouch[bot])Triggered by [comment](https://github.com/ghostty-org/ghostty/issues/14072#issuecomment-5463405035) from @bo2themax. Vouch: @Svector-anu6cd684dgtk: fix stale pointers to property bindings (@dkinzler)Previously, the property binding created in `Surface.bindIsSplit` would get freed automatically when the source object (the SplitTree widget) got finalized. A subsequent call to `bindIsSplit` could then cause a crash by using the stale pointer to the binding. This bug could e.g. be triggered by dragging the surface from a single-surface tab to another tab. We now create an extra reference to the binding object so that Surface essentially owns the binding and is responsible for freeing it. Updated the binding in `SurfaceScrolledWindow` to use the same pattern. That one was probably fine, because the binding is only created once, but let's be safe.caf48a4main: fix inverted allow_stack_tracing condition (@jcollie)The Zig 0.16.0 update dropped the negation from the std default (!strip_debug_info), disabling stack traces in every unstripped build. AI disclosure: Claude Fable was used to diagnose the problem and find the fix. Commit message was written by me. Claude-Session: https://claude.ai/code/session_01QfzQME46DQXwMWa43bQaa3069497egtk: fix stale pointers to property bindings (#14065) (@jcollie)Fixes #14037 where dragging the surface from a tab with just a single surface to another tab causes a crash. The cause of the crash is a stale pointer to the property binding created in `Surface.bindIsSplit`. When the surface is moved, `SplitTree.moveSplit` first updates the two split tree data structures of the source/target tab and then calls `bindIsSplit` to bind the `is-split` property of the moved surface to the `SplitTree` widget in the target tab. When `bindIsSplit` is called, the `SplitTree` widget in the source tab has already been destroyed (because the source tab is now empty) which causes the old binding to be freed automatically and the pointer `Surface.is_split_binding` becomes stale. `bindIsSplit` then tries to run `is_split_binding.unbind()` which causes the crash. When you create a binding with `bindProperty`, the binding itself owns the initially created reference and it gets freed when the source or target object of the binding is finalized. To prevent this, we now create an extra reference to the binding object so that the Surface widget owns it and is responsible for freeing it. The binding can still get severed automatically, but the binding object itself will not be destroyed. This is the solution mentioned in the [GObject docs](https://docs.gtk.org/gobject/method.Object.bind_property.html). Alternatively, using a WeakRef for the pointer would have also worked. Updated the binding in `SurfaceScrolledWindow` to use the same pattern. That one was probably fine, because the binding should only be created once, but it doesn't hurt to be safe. I reproduced the crash on KDE, on Hyprland I just got a glib critical error message about the invalid pointer. That probably has to do with what exactly happens to the freed memory, or maybe differing versions. #### AI Disclosure Code and comments were written by myself, used GPT5.6 in researching gobject binding lifecycles.3baff3amain: fix inverted allow_stack_tracing condition (#14069) (@jcollie)The Zig 0.16.0 update dropped the negation from the std default (!strip_debug_info), disabling stack traces in every unstripped build. AI disclosure: Claude Fable was used to diagnose the problem and find the fix. Commit message was written by me. Claude-Session: https://claude.ai/code/session_01QfzQME46DQXwMWa43bQaa3
Runs: 1, 2
Summary: 2 runs • 4 commits • 3 authors
777929amacOS: review windows when closing multiple tabs (@bo2themax)4540d49macOS: review windows when closing multiple tabs (#14062) (@mitchellh)We can also make close undoable when quitting, i'll add it as a follow up pr. <img width="573" height="450" alt="Xnip2026-08-28_19-25-02" src="https://github.com/user-attachments/assets/3b4f34f4-9ee6-4180-beb7-f90e98c8aa40" />eb722cbterminal: mark the previous row dirty when clearing its spacer head (@fornwall)Erasing a wrapped wide character at the start of a row (ECH or DCH) also clears the spacer head it left at the end of the previous row, but that row was never marked dirty. With both rows visible, an incremental render kept the stale spacer head on screen until something unrelated redrew that row. The clearing happens in the row-start branch of splitCellBoundary. clearCells doesn't do dirty tracking, and both callers only mark the cursor row, so mark the previous row at the point it's mutated. The added dirty assertions fail without the fix.76e568bterminal: mark the previous row dirty when clearing its spacer head (#14054) (@mitchellh)Erasing a wrapped wide character at the start of a row (`ECH` or `DCH`) also clears the spacer head it left at the end of the previous row, but that row was never marked dirty. With both rows visible, an incremental render kept the stale spacer head on screen until something unrelated redrew that row. The clearing happens in the row-start branch of `splitCellBoundary`. `clearCells` doesn't do dirty tracking, and both callers only mark the cursor row, so mark the previous row at the point it's mutated. The added dirty assertions fail without the fix. ## AI Disclaimer Claude did the heavy lifting - identifying the root cause, generating code and description. I reviewed and iterated on it to move around and tweak tests, comments and reduce verboseness. Verified the end user visible behaviour improvement with a script that coloured the wide character, which made the stale rendering visible until a switch to the alt screen and back cleared it it.