Skip to content

Sync fork with upstream Ghostty main#14

Open
lawrencecchen wants to merge 750 commits intomainfrom
task-sync-upstream-main
Open

Sync fork with upstream Ghostty main#14
lawrencecchen wants to merge 750 commits intomainfrom
task-sync-upstream-main

Conversation

@lawrencecchen
Copy link

@lawrencecchen lawrencecchen commented Mar 16, 2026

Summary

  • rebase the cmux Ghostty fork onto current ghostty-org/ghostty main at a2b2b883e
  • reapply the retained cmux patch stack for OSC 99 notifications, resize stale-frame handling, keyboard copy-mode selection, Pure prompt redraws, and the theme picker helper hooks
  • keep the fork work on a review branch instead of updating main directly

Testing

  • zig build -Demit-xcframework=true -Demit-macos-app=false -Dxcframework-target=universal -Doptimize=ReleaseFast

Summary by cubic

Rebased the cmux Ghostty fork onto upstream ghostty-org/ghostty main and reapplied our patch stack (OSC 99, resize stale-frame, keyboard copy-mode, Pure prompt redraws, theme picker helpers). Changes are staged on this review branch; main is unchanged.

  • New Features

    • macOS AppleScript support with windows/tabs/terminals, focus/split/new/close, and input commands.
    • New ghostty-vt terminal and formatter C APIs with examples (C and Zig).
    • Expanded tests and CI workflow updates (action pins, Vouch sync), plus SwiftLint config.
    • Build improvements: CLI helper step, theme/vendor updates, and Nix/Flatpak/Snap adjustments.
  • Migration

    • C API: include/ghostty/vt/result.h replaced by include/ghostty/vt/types.h (update includes).
    • Enum updates: macOS non-native fullscreen values renamed to GHOSTTY_FULLSCREEN_MACOS_*; SGR attribute tags realigned.
    • Build (example): zig build -Demit-xcframework=true -Demit-macos-app=false -Dxcframework-target=universal -Doptimize=ReleaseFast

Written for commit 51ba49a. Summary will update on new commits.

jcollie and others added 30 commits March 4, 2026 14:04
…11169)

This reverts commit ee4c6f8.

This breaks standard `zig build run` from a dev shell in Nix/NixOS. I
think we need to rethink some of the protections here, possibly only to
apply to packaging/release modes or something.

cc @jcollie
Fixes ghostty-org#8208

Split-tree updates currently clear `tree_bin` and then wait for every surface
to become parentless before rebuilding. That leaves the split area blank for
one or more frames, which is the visible flicker during split create/close/
resize/equalize actions.

Keep the previous widget tree attached until the idle rebuild runs, then
swap in the rebuilt tree in one step. During rebuild, reuse existing
leaf widgets by detaching and reparenting them into the new `GtkPaned` 
hierarchy instead of recreating wrappers for every leaf.

This removes the parent-settling rebuild path and avoids transient blank
frames while preserving debounced rebuild behavior.
…-org#11170)

Fixes ghostty-org#8208

Split-tree updates currently clear `tree_bin` and then wait for every
surface to become parentless before rebuilding. That leaves the split
area blank for one or more frames, which is the visible flicker during
split create/close/ resize/equalize actions.

Keep the previous widget tree attached until the idle rebuild runs, then
swap in the rebuilt tree in one step. During rebuild, reuse existing
leaf widgets by detaching and reparenting them into the new `GtkPaned`
hierarchy instead of recreating wrappers for every leaf.

This removes the parent-settling rebuild path and avoids transient blank
frames while preserving debounced rebuild behavior.
…ty-org#10809)

Fixes: ghostty-org#8862
Fixes: ghostty-org#10716

This adds the machinery to pass configuration settings received over
DBus down to the GObject Surface so that that configuration information
can be used to override some settings from the current "live" config
when creating a new window. Currently it's only possible to override
`--working-directory`, `--command`, and `--title`. `-e` on the `ghostty
+new-window` CLI works as well.

Adding more overridable settings is possible, but being able to fully
override any possible setting would better be served with a major revamp
of how Ghostty handles configs, which is way out of scope at the moment.
Triggered by
[comment](ghostty-org#11175 (comment))
from @jcollie.

Vouch: @douglas

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Triggered by [discussion
comment](ghostty-org#11164 (comment))
from @mitchellh.

Vouch: @Michielvk

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This was introduced in ghostty-org#10611. This doesn't fix all of the current
Windows build problems, but at least fixes one that I introduced.
This was introduced in ghostty-org#10611. This doesn't fix all of the current
Windows build problems, but at least fixes one that I introduced.
Fixes ghostty-org#11177

Use per-search Oniguruma match params (retry_limit_in_search) in
StringMap-backed link detection to avoid pathological backtracking hangs
on very long lines.

The units are ticks in the internal loop so its kind of opaque but
this seems to still match some very long URLs. The test case in question
was a 169K character line (which is now rejected).
…hostty-org#11181)

Fixes ghostty-org#11177

Use per-search Oniguruma match params (retry_limit_in_search) in
StringMap-backed link detection to avoid pathological backtracking hangs
on very long lines.

The units are ticks in the internal loop so its kind of opaque but this
seems to still match some very long URLs. The test case in question was
a 169K character line (which is now rejected).
Adds support for the Vietnamese language
…hostty-org#11185)

I encountered an issue related to
ghostty-org#8641 and
ghostty-org#8647, but in `zsh` instead
of `bash`.

One of my aliases is:

```bash
alias sudo='sudo '
```

Which causes following error when sourcing the zsh shell integrations:

```shell
source /usr/share/ghostty/shell-integration/zsh/ghostty-integration
/usr/share/ghostty/shell-integration/zsh/ghostty-integration:149: defining function based on alias `sudo'
/usr/share/ghostty/shell-integration/zsh/ghostty-integration:233: parse error near `()'
```
Triggered by
[comment](ghostty-org#11190 (comment))
from @00-kat.

Vouch: @AnthonyZhOon

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Triggered by [discussion
comment](ghostty-org#11184 (comment))
from @mitchellh.

Vouch: @mac0ne

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Some more fixes to get Windows building again. `zig build` on
x64_64-windows now succeeds but `zig build test` fails in
`src/terminal/page.zig` because Zig/Windows lacks a POSIX `mmap`
implementation.
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.19.2 to 7.0.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](docker/build-push-action@10e90e3...d08e5c3)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
…tty-org#11199)

Bumps
[docker/build-push-action](https://github.com/docker/build-push-action)
from 6.19.2 to 7.0.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/docker/build-push-action/releases">docker/build-push-action's
releases</a>.</em></p>
<blockquote>
<h2>v7.0.0</h2>
<ul>
<li>Node 24 as default runtime (requires <a
href="https://github.com/actions/runner/releases/tag/v2.327.1">Actions
Runner v2.327.1</a> or later) by <a
href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a
href="https://redirect.github.com/docker/build-push-action/pull/1470">docker/build-push-action#1470</a></li>
<li>Remove deprecated <code>DOCKER_BUILD_NO_SUMMARY</code> and
<code>DOCKER_BUILD_EXPORT_RETENTION_DAYS</code> envs by <a
href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a
href="https://redirect.github.com/docker/build-push-action/pull/1473">docker/build-push-action#1473</a></li>
<li>Remove legacy export-build tool support for build summary by <a
href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a
href="https://redirect.github.com/docker/build-push-action/pull/1474">docker/build-push-action#1474</a></li>
<li>Switch to ESM and update config/test wiring by <a
href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a
href="https://redirect.github.com/docker/build-push-action/pull/1466">docker/build-push-action#1466</a></li>
<li>Bump <code>@​actions/core</code> from 1.11.1 to 3.0.0 in <a
href="https://redirect.github.com/docker/build-push-action/pull/1454">docker/build-push-action#1454</a></li>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.62.1 to 0.79.0 in
<a
href="https://redirect.github.com/docker/build-push-action/pull/1453">docker/build-push-action#1453</a>
<a
href="https://redirect.github.com/docker/build-push-action/pull/1472">docker/build-push-action#1472</a>
<a
href="https://redirect.github.com/docker/build-push-action/pull/1479">docker/build-push-action#1479</a></li>
<li>Bump minimatch from 3.1.2 to 3.1.5 in <a
href="https://redirect.github.com/docker/build-push-action/pull/1463">docker/build-push-action#1463</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/build-push-action/compare/v6.19.2...v7.0.0">https://github.com/docker/build-push-action/compare/v6.19.2...v7.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/docker/build-push-action/commit/d08e5c354a6adb9ed34480a06d141179aa583294"><code>d08e5c3</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/build-push-action/issues/1479">#1479</a>
from docker/dependabot/npm_and_yarn/docker/actions-t...</li>
<li><a
href="https://github.com/docker/build-push-action/commit/cbd2dff9a0f0ef650dcce9c635bb2f877ab37be5"><code>cbd2dff</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/build-push-action/commit/f76f51f12900bb84aa9d1a498f35870ef1f76675"><code>f76f51f</code></a>
chore(deps): Bump <code>@​docker/actions-toolkit</code> from 0.78.0 to
0.79.0</li>
<li><a
href="https://github.com/docker/build-push-action/commit/7d03e66b5f24d6b390ab64b132795fd3ef4152c8"><code>7d03e66</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/build-push-action/issues/1473">#1473</a>
from crazy-max/rm-deprecated-envs</li>
<li><a
href="https://github.com/docker/build-push-action/commit/98f853d923dd281a3bcbbb98a0712a91aa913322"><code>98f853d</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/build-push-action/commit/cadccf6e8c7385c86d9cb0800cf07672645cc238"><code>cadccf6</code></a>
remove deprecated envs</li>
<li><a
href="https://github.com/docker/build-push-action/commit/03fe8775e325e34fffbda44c73316f8287aea372"><code>03fe877</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/build-push-action/issues/1478">#1478</a>
from docker/dependabot/github_actions/docker/setup-b...</li>
<li><a
href="https://github.com/docker/build-push-action/commit/827e36650e1fa7386d09422b5ba3c068fdbe0a1d"><code>827e366</code></a>
chore(deps): Bump docker/setup-buildx-action from 3 to 4</li>
<li><a
href="https://github.com/docker/build-push-action/commit/e25db879d025485a4eebd64fea9bb88a43632da6"><code>e25db87</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/build-push-action/issues/1474">#1474</a>
from crazy-max/rm-export-build-tool</li>
<li><a
href="https://github.com/docker/build-push-action/commit/1ac2573b5c8b4e4621d5453ab2a99e83725242bd"><code>1ac2573</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/build-push-action/issues/1470">#1470</a>
from crazy-max/node24</li>
<li>Additional commits viewable in <a
href="https://github.com/docker/build-push-action/compare/10e90e3645eae34f1e60eeb005ba3a3d33f178e8...d08e5c354a6adb9ed34480a06d141179aa583294">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=docker/build-push-action&package-manager=github_actions&previous-version=6.19.2&new-version=7.0.0)](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>
This is an update to address common agentic issues I run into,
but the `build.nu` script may be generally helpful to people using
the Nix env since `xcodebuild` is broken by default in Nix due to the
compiler/linker overrides Nix shell does.
mitchellh and others added 25 commits March 14, 2026 15:42
)

This adds an initial C API for terminals and formatting. There is a new
example that shows how to use this.

With these APIs in place, users of the C API can now create a terminal,
pass raw VT streams to it, and dump the terminal viewport to various
formats. As noted in the docs, **the formatter API is not a rendering
API**, it isn't high performance enough for that. But it's a simpler API
to implement than the render state API so I started with that.

Both APIs are purposely fairly minimal, we're just setting the stage for
future functionality.

## Example

```c
#include <ghostty/vt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
  GhosttyTerminal term;
  GhosttyTerminalOptions opts = { .cols = 80, .rows = 24, .max_scrollback = 0 };
  ghostty_terminal_new(NULL, &term, opts);

  const char *input = "Hello, \033[1mBold\033[0m World!\r\nLine 2\r\n";
  ghostty_terminal_vt_write(term, (const uint8_t *)input, strlen(input));

  GhosttyFormatterTerminalOptions fmt = GHOSTTY_INIT_SIZED(GhosttyFormatterTerminalOptions);
  fmt.emit = GHOSTTY_FORMATTER_FORMAT_PLAIN;
  fmt.trim = true;

  GhosttyFormatter fmtr;
  ghostty_formatter_terminal_new(NULL, &fmtr, term, fmt);

  uint8_t *buf;
  size_t len;
  ghostty_formatter_format_alloc(fmtr, NULL, &buf, &len);
  fwrite(buf, 1, len, stdout);

  free(buf);
  ghostty_formatter_free(fmtr);
  ghostty_terminal_free(term);
}
```

## New APIs

| Function | Description |
|----------|-------------|
| `ghostty_terminal_new` | Create a new terminal instance |
| `ghostty_terminal_free` | Free a terminal instance |
| `ghostty_terminal_reset` | Full reset of the terminal (RIS) |
| `ghostty_terminal_resize` | Resize the terminal to given dimensions |
| `ghostty_terminal_vt_write` | Write VT-encoded data to the terminal |
| `ghostty_terminal_scroll_viewport` | Scroll the terminal viewport |
| `ghostty_formatter_terminal_new` | Create a formatter for a terminal's
active screen |
| `ghostty_formatter_format_buf` | Format into a caller-provided buffer
|
| `ghostty_formatter_format_alloc` | Format into an allocated buffer |
| `ghostty_formatter_free` | Free a formatter instance |

## Future

- Obviously need to expose a lot more from the terminal:
  * Read current set modes
  * Read cursor information
  * Read screen information
  * etc...
- Need an optional callback system so that `vt_write` can invoke
callbacks for side effect sequences like clipboards, title setting,
responses, etc.
- `terminal.RenderState` C API so that people can build high performance
renderers on top of libghostty-vt

And so on...
Change `window-padding-balance` from `bool` to an enum with three
values:

- `false` - no balancing (default, unchanged)
- `true` - balance with vshift that caps top padding and shifts excess
  to bottom (existing behavior, unchanged)
- `equal` - balance whitespace equally on all four sides

This gives users who prefer truly equal padding a way to opt in without
changing the default behavior.
…1491)

Change `window-padding-balance` from `bool` to an enum with three
values:

- `false` - no balancing (default, unchanged)
- `true` - balance with vshift that caps top padding and shifts excess
to bottom (existing behavior, unchanged)
- `equal` - balance whitespace equally on all four sides

This gives users who prefer truly equal padding a way to opt in without
changing the default behavior.
Expose the key encoder Options.fromTerminal function to the C API as
ghostty_key_encoder_setopt_from_terminal. This lets C callers sync all
terminal-derived encoding options (cursor key application mode, keypad
mode, alt escape prefix, modifyOtherKeys, and Kitty flags) in a single
call instead of setting each option individually.
Expose the key encoder Options.fromTerminal function to the C API as
ghostty_key_encoder_setopt_from_terminal. This lets C callers sync all
terminal-derived encoding options (cursor key application mode, keypad
mode, alt escape prefix, modifyOtherKeys, and Kitty flags) in a single
call instead of setting each option individually.
Triggered by [discussion
comment](ghostty-org#11041 (comment))
from @mitchellh.

Vouch: @davidsanchez222

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Triggered by [discussion
comment](ghostty-org#11250 (comment))
from @mitchellh.

Vouch: @PowerUser64

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Triggered by [discussion
comment](ghostty-org#11237 (comment))
from @mitchellh.

Vouch: @cadebrown

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Move mouse event encoding logic from Surface.zig into a new
input/mouse_encode.zig file.

The new file encapsulates event filtering (shouldReport),
button code computation, viewport bounds checking, motion
deduplication, and all five wire formats (X10, UTF-8, SGR,
urxvt, SGR-pixels). This makes the encoding independently
testable and adds unit tests covering each format and edge
case.

Additionally, Surface `mouseReport` can no longer fail, since the only
failure mode is no buffer space which should be impossible. Updated
the signature to remove the error set.
…1538)

Move mouse event encoding logic from Surface.zig into a new
input/mouse_encode.zig file.

The new file encapsulates event filtering (shouldReport), button code
computation, viewport bounds checking, motion deduplication, and all
five wire formats (X10, UTF-8, SGR, urxvt, SGR-pixels). This makes the
encoding independently testable and adds unit tests covering each format
and edge case.

Additionally, Surface `mouseReport` can no longer fail, since the only
failure mode is no buffer space which should be impossible. Updated the
signature to remove the error set.
Triggered by
[comment](ghostty-org#11518 (comment))
from @jparise.

Vouch: @j0hnm4r5

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@coderabbitai
Copy link

coderabbitai bot commented Mar 16, 2026

Important

Review skipped

Too many files!

This PR contains 298 files, which is 148 over the limit of 150.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: aa8b784a-9f26-409a-89c1-ce296b44f7ae

📥 Commits

Reviewing files that changed from the base of the PR and between b9989c1 and 51ba49a.

⛔ Files ignored due to path filters (2)
  • dist/linux/com.mitchellh.ghostty.metainfo.xml.in is excluded by !**/dist/**
  • flake.lock is excluded by !**/*.lock
📒 Files selected for processing (298)
  • .agents/commands/gh-issue
  • .agents/skills/writing-commit-messages/SKILL.md
  • .github/VOUCHED.td
  • .github/workflows/flatpak.yml
  • .github/workflows/milestone.yml
  • .github/workflows/nix.yml
  • .github/workflows/release-tag.yml
  • .github/workflows/release-tip.yml
  • .github/workflows/snap.yml
  • .github/workflows/test.yml
  • .github/workflows/update-colorschemes.yml
  • .github/workflows/vouch-check-issue.yml
  • .github/workflows/vouch-check-pr.yml
  • .github/workflows/vouch-manage-by-discussion.yml
  • .github/workflows/vouch-manage-by-issue.yml
  • .github/workflows/vouch-sync-codeowners.yml
  • .gitignore
  • .prettierignore
  • .swiftlint.yml
  • AGENTS.md
  • CODEOWNERS
  • CONTRIBUTING.md
  • HACKING.md
  • build.zig
  • build.zig.zon
  • build.zig.zon.bak
  • build.zig.zon.json
  • build.zig.zon.nix
  • build.zig.zon.txt
  • example/c-vt-formatter/README.md
  • example/c-vt-formatter/build.zig
  • example/c-vt-formatter/build.zig.zon
  • example/c-vt-formatter/src/main.c
  • example/zig-formatter/src/main.zig
  • example/zig-vt-stream/src/main.zig
  • flake.nix
  • flatpak/zig-packages.json
  • include/ghostty.h
  • include/ghostty/vt.h
  • include/ghostty/vt/formatter.h
  • include/ghostty/vt/key.h
  • include/ghostty/vt/key/encoder.h
  • include/ghostty/vt/key/event.h
  • include/ghostty/vt/osc.h
  • include/ghostty/vt/result.h
  • include/ghostty/vt/sgr.h
  • include/ghostty/vt/terminal.h
  • include/ghostty/vt/types.h
  • macos/.swiftlint.yml
  • macos/AGENTS.md
  • macos/Ghostty-Info.plist
  • macos/Ghostty.sdef
  • macos/Ghostty.xcodeproj/project.pbxproj
  • macos/Ghostty.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
  • macos/GhosttyUITests/GhosttyCustomConfigCase.swift
  • macos/GhosttyUITests/GhosttyWindowPositionUITests.swift
  • macos/Sources/App/macOS/AppDelegate+Ghostty.swift
  • macos/Sources/App/macOS/AppDelegate.swift
  • macos/Sources/App/macOS/MainMenu.xib
  • macos/Sources/App/macOS/ghostty-bridging-header.h
  • macos/Sources/App/macOS/main.swift
  • macos/Sources/Features/About/AboutController.swift
  • macos/Sources/Features/About/AboutView.swift
  • macos/Sources/Features/About/AboutViewModel.swift
  • macos/Sources/Features/About/CyclingIconView.swift
  • macos/Sources/Features/App Intents/CloseTerminalIntent.swift
  • macos/Sources/Features/App Intents/CommandPaletteIntent.swift
  • macos/Sources/Features/App Intents/Entities/CommandEntity.swift
  • macos/Sources/Features/App Intents/Entities/TerminalEntity.swift
  • macos/Sources/Features/App Intents/GetTerminalDetailsIntent.swift
  • macos/Sources/Features/App Intents/InputIntent.swift
  • macos/Sources/Features/App Intents/IntentPermission.swift
  • macos/Sources/Features/App Intents/KeybindIntent.swift
  • macos/Sources/Features/App Intents/NewTerminalIntent.swift
  • macos/Sources/Features/App Intents/QuickTerminalIntent.swift
  • macos/Sources/Features/AppleScript/AppDelegate+AppleScript.swift
  • macos/Sources/Features/AppleScript/Ghostty.Input.Mods+AppleScript.swift
  • macos/Sources/Features/AppleScript/ScriptInputTextCommand.swift
  • macos/Sources/Features/AppleScript/ScriptKeyEventCommand.swift
  • macos/Sources/Features/AppleScript/ScriptMouseButtonCommand.swift
  • macos/Sources/Features/AppleScript/ScriptMousePosCommand.swift
  • macos/Sources/Features/AppleScript/ScriptMouseScrollCommand.swift
  • macos/Sources/Features/AppleScript/ScriptRecord.swift
  • macos/Sources/Features/AppleScript/ScriptSurfaceConfiguration.swift
  • macos/Sources/Features/AppleScript/ScriptTab.swift
  • macos/Sources/Features/AppleScript/ScriptTerminal.swift
  • macos/Sources/Features/AppleScript/ScriptWindow.swift
  • macos/Sources/Features/ClipboardConfirmation/ClipboardConfirmationController.swift
  • macos/Sources/Features/ClipboardConfirmation/ClipboardConfirmationView.swift
  • macos/Sources/Features/Colorized Ghostty Icon/ColorizedGhosttyIcon.swift
  • macos/Sources/Features/Command Palette/CommandPalette.swift
  • macos/Sources/Features/Command Palette/TerminalCommandPalette.swift
  • macos/Sources/Features/Custom App Icon/AppIcon.swift
  • macos/Sources/Features/Custom App Icon/ColorizedGhosttyIcon.swift
  • macos/Sources/Features/Custom App Icon/ColorizedGhosttyIconImage.swift
  • macos/Sources/Features/Custom App Icon/ColorizedGhosttyIconView.swift
  • macos/Sources/Features/Custom App Icon/DockTilePlugin.swift
  • macos/Sources/Features/Custom App Icon/Extensions/Notification+AppIcon.swift
  • macos/Sources/Features/Custom App Icon/Extensions/UserDefaults+AppIcon.swift
  • macos/Sources/Features/Global Keybinds/GlobalEventTap.swift
  • macos/Sources/Features/QuickTerminal/QuickTerminalController.swift
  • macos/Sources/Features/QuickTerminal/QuickTerminalPosition.swift
  • macos/Sources/Features/QuickTerminal/QuickTerminalScreen.swift
  • macos/Sources/Features/QuickTerminal/QuickTerminalScreenStateCache.swift
  • macos/Sources/Features/QuickTerminal/QuickTerminalSize.swift
  • macos/Sources/Features/QuickTerminal/QuickTerminalSpaceBehavior.swift
  • macos/Sources/Features/QuickTerminal/QuickTerminalWindow.swift
  • macos/Sources/Features/Secure Input/SecureInput.swift
  • macos/Sources/Features/Secure Input/SecureInputOverlay.swift
  • macos/Sources/Features/Services/ServiceProvider.swift
  • macos/Sources/Features/Settings/ConfigurationErrorsController.swift
  • macos/Sources/Features/Splits/SplitTree.swift
  • macos/Sources/Features/Splits/SplitView.Divider.swift
  • macos/Sources/Features/Splits/SplitView.swift
  • macos/Sources/Features/Splits/TerminalSplitTreeView.swift
  • macos/Sources/Features/Terminal/BaseTerminalController.swift
  • macos/Sources/Features/Terminal/TerminalController.swift
  • macos/Sources/Features/Terminal/TerminalRestorable.swift
  • macos/Sources/Features/Terminal/TerminalTabColor.swift
  • macos/Sources/Features/Terminal/TerminalView.swift
  • macos/Sources/Features/Terminal/TerminalViewContainer.swift
  • macos/Sources/Features/Terminal/Window Styles/HiddenTitlebarTerminalWindow.swift
  • macos/Sources/Features/Terminal/Window Styles/TerminalWindow.swift
  • macos/Sources/Features/Terminal/Window Styles/TitlebarTabsTahoeTerminalWindow.swift
  • macos/Sources/Features/Terminal/Window Styles/TitlebarTabsVenturaTerminalWindow.swift
  • macos/Sources/Features/Terminal/Window Styles/TransparentTitlebarTerminalWindow.swift
  • macos/Sources/Features/Update/UpdateBadge.swift
  • macos/Sources/Features/Update/UpdateController.swift
  • macos/Sources/Features/Update/UpdateDelegate.swift
  • macos/Sources/Features/Update/UpdateDriver.swift
  • macos/Sources/Features/Update/UpdatePill.swift
  • macos/Sources/Features/Update/UpdatePopoverView.swift
  • macos/Sources/Features/Update/UpdateSimulator.swift
  • macos/Sources/Features/Update/UpdateViewModel.swift
  • macos/Sources/Ghostty/FullscreenMode+Extension.swift
  • macos/Sources/Ghostty/Ghostty.Action.swift
  • macos/Sources/Ghostty/Ghostty.App.swift
  • macos/Sources/Ghostty/Ghostty.Config.swift
  • macos/Sources/Ghostty/Ghostty.ConfigTypes.swift
  • macos/Sources/Ghostty/Ghostty.Input.swift
  • macos/Sources/Ghostty/Ghostty.Surface.swift
  • macos/Sources/Ghostty/GhosttyPackage.swift
  • macos/Sources/Ghostty/GhosttyPackageMeta.swift
  • macos/Sources/Ghostty/NSEvent+Extension.swift
  • macos/Sources/Ghostty/Package.swift
  • macos/Sources/Ghostty/Surface View/InspectorView.swift
  • macos/Sources/Ghostty/Surface View/SurfaceDragSource.swift
  • macos/Sources/Ghostty/Surface View/SurfaceGrabHandle.swift
  • macos/Sources/Ghostty/Surface View/SurfaceProgressBar.swift
  • macos/Sources/Ghostty/Surface View/SurfaceScrollView.swift
  • macos/Sources/Ghostty/Surface View/SurfaceView+Transferable.swift
  • macos/Sources/Ghostty/Surface View/SurfaceView.swift
  • macos/Sources/Ghostty/Surface View/SurfaceView_AppKit.swift
  • macos/Sources/Ghostty/Surface View/SurfaceView_UIKit.swift
  • macos/Sources/Helpers/AnySortKey.swift
  • macos/Sources/Helpers/AppInfo.swift
  • macos/Sources/Helpers/Backport.swift
  • macos/Sources/Helpers/ExpiringUndoManager.swift
  • macos/Sources/Helpers/Extensions/Array+Extension.swift
  • macos/Sources/Helpers/Extensions/EventModifiers+Extension.swift
  • macos/Sources/Helpers/Extensions/NSAppearance+Extension.swift
  • macos/Sources/Helpers/Extensions/NSApplication+Extension.swift
  • macos/Sources/Helpers/Extensions/NSColor+Extension.swift
  • macos/Sources/Helpers/Extensions/NSPasteboard+Extension.swift
  • macos/Sources/Helpers/Extensions/NSScreen+Extension.swift
  • macos/Sources/Helpers/Extensions/NSView+Extension.swift
  • macos/Sources/Helpers/Extensions/NSWindow+Extension.swift
  • macos/Sources/Helpers/Extensions/NSWorkspace+Extension.swift
  • macos/Sources/Helpers/Extensions/OSColor+Extension.swift
  • macos/Sources/Helpers/Extensions/ObjectIdentifier+Extension.swift
  • macos/Sources/Helpers/Extensions/String+Extension.swift
  • macos/Sources/Helpers/Extensions/Transferable+Extension.swift
  • macos/Sources/Helpers/Extensions/UserDefaults+Extension.swift
  • macos/Sources/Helpers/Fullscreen.swift
  • macos/Sources/Helpers/LastWindowPosition.swift
  • macos/Sources/Helpers/MetalView.swift
  • macos/Sources/Helpers/ObjCExceptionCatcher.h
  • macos/Sources/Helpers/ObjCExceptionCatcher.m
  • macos/Sources/Helpers/PermissionRequest.swift
  • macos/Sources/Helpers/TabTitleEditor.swift
  • macos/Tests/ColorizedGhosttyIconTests.swift
  • macos/Tests/Ghostty/ConfigTests.swift
  • macos/Tests/Ghostty/ShellTests.swift
  • macos/Tests/NSPasteboardTests.swift
  • macos/Tests/NSScreenTests.swift
  • macos/Tests/Terminal/TerminalViewContainerTests.swift
  • macos/Tests/Update/ReleaseNotesTests.swift
  • macos/Tests/Update/UpdateStateTests.swift
  • macos/Tests/Update/UpdateViewModelTests.swift
  • macos/build.nu
  • nix/devShell.nix
  • nix/package.nix
  • nix/pkgs/blessed.nix
  • nix/pkgs/ucs-detect.nix
  • nix/pkgs/wcwidth.nix
  • pkg/afl++/LICENSE
  • pkg/afl++/afl.c
  • pkg/afl++/build.zig
  • pkg/afl++/build.zig.zon
  • pkg/android-ndk/build.zig
  • pkg/android-ndk/build.zig.zon
  • pkg/dcimgui/build.zig
  • pkg/dcimgui/ext.cpp
  • pkg/dcimgui/main.zig
  • pkg/highway/build.zig
  • pkg/highway/build.zig.zon
  • pkg/macos/animation.zig
  • pkg/oniguruma/main.zig
  • pkg/oniguruma/match_param.zig
  • pkg/oniguruma/regex.zig
  • pkg/simdutf/build.zig
  • pkg/simdutf/build.zig.zon
  • pkg/utfcpp/build.zig
  • pkg/utfcpp/build.zig.zon
  • po/README_TRANSLATORS.md
  • po/bg.po
  • po/bg_BG.UTF-8.po
  • po/ca.po
  • po/ca_ES.UTF-8.po
  • po/de.po
  • po/de_DE.UTF-8.po
  • po/es_AR.UTF-8.po
  • po/es_AR.po
  • po/es_BO.UTF-8.po
  • po/es_BO.po
  • po/es_ES.po
  • po/fr.po
  • po/fr_FR.UTF-8.po
  • po/ga.po
  • po/ga_IE.UTF-8.po
  • po/he.po
  • po/he_IL.UTF-8.po
  • po/hr.po
  • po/hr_HR.UTF-8.po
  • po/hu.po
  • po/hu_HU.UTF-8.po
  • po/id.po
  • po/id_ID.UTF-8.po
  • po/it.po
  • po/it_IT.UTF-8.po
  • po/ja.po
  • po/ja_JP.UTF-8.po
  • po/kk.po
  • po/ko_KR.UTF-8.po
  • po/ko_KR.po
  • po/lt.po
  • po/lt_LT.UTF-8.po
  • po/lv.po
  • po/lv_LV.UTF-8.po
  • po/mk.po
  • po/mk_MK.UTF-8.po
  • po/nb.po
  • po/nb_NO.UTF-8.po
  • po/nl.po
  • po/nl_NL.UTF-8.po
  • po/pl.po
  • po/pl_PL.UTF-8.po
  • po/pt_BR.UTF-8.po
  • po/pt_BR.po
  • po/ru.po
  • po/ru_RU.UTF-8.po
  • po/tr.po
  • po/tr_TR.UTF-8.po
  • po/uk.po
  • po/uk_UA.UTF-8.po
  • po/vi.po
  • po/zh_CN.UTF-8.po
  • po/zh_CN.po
  • po/zh_TW.UTF-8.po
  • po/zh_TW.po
  • snap/local/launcher
  • src/Command.zig
  • src/Surface.zig
  • src/apprt/action.zig
  • src/apprt/embedded.zig
  • src/apprt/gtk/Surface.zig
  • src/apprt/gtk/class/application.zig
  • src/apprt/gtk/class/command_palette.zig
  • src/apprt/gtk/class/imgui_widget.zig
  • src/apprt/gtk/class/split_tree.zig
  • src/apprt/gtk/class/surface.zig
  • src/apprt/gtk/class/tab.zig
  • src/apprt/gtk/class/window.zig
  • src/apprt/gtk/ipc/new_window.zig
  • src/apprt/gtk/ui/1.2/surface.blp
  • src/apprt/gtk/ui/1.5/window.blp
  • src/apprt/ipc.zig
  • src/apprt/surface.zig
  • src/benchmark/CodepointWidth.zig
  • src/benchmark/ScreenClone.zig
  • src/benchmark/TerminalStream.zig
  • src/build/GhosttyLibVt.zig
  • src/build/GhosttyXcodebuild.zig
  • src/build/GitVersion.zig
  • src/build/SharedDeps.zig
  • src/build/uucode_config.zig
  • src/cli/list_actions.zig
  • src/cli/list_themes.zig

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch task-sync-upstream-main
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 51ba49a4bb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +582 to +585
.cmux_preview_light = if (cmux) |value| value.initial_light else null,
.cmux_preview_dark = if (cmux) |value| value.initial_dark else null,
.cmux_applied_light = if (cmux) |value| value.initial_light else null,
.cmux_applied_dark = if (cmux) |value| value.initial_dark else null,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Sync cmux preview with initial selection

Initializing cmux_preview_* from environment without applying the current list selection leaves the live preview state out of sync with what the UI highlights at startup. In cmux mode, if the user opens the picker and presses Enter immediately (or before moving selection), outcome = .apply exits with the old theme values still in cmux_preview_*, so the highlighted theme is not actually applied. Triggering applyCmuxSelectionForCurrentTheme() once after filtering/initial selection would avoid this no-op apply path.

Useful? React with 👍 / 👎.

Comment on lines +69 to +70
if (payload_kind == .ignore) {
return null;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear pending OSC 99 chunks on ignored payload kinds

Returning early for p=close/p=alive skips any reset of kitty_notification_pending, so partial title/body data from an earlier d=0 chunk remains buffered. If the same notification id is reused afterward, the old buffered fields are concatenated into the next completed notification, producing incorrect title/body content. Ignored payload kinds should clear pending state for their id to avoid stale chunk carryover.

Useful? React with 👍 / 👎.

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 issues found across 3000 files

Note: This PR contains a large number of files. cubic only reviews up to 75 files per PR, so some files may not have been reviewed.

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="include/ghostty/vt/sgr.h">

<violation number="1" location="include/ghostty/vt/sgr.h:112">
P1: Renumbering public `GhosttySgrAttributeTag` values breaks numeric tag compatibility for existing consumers. Keep previous numeric IDs stable when removing entries.</violation>
</file>

<file name="macos/Sources/Features/AppleScript/Ghostty.Input.Mods+AppleScript.swift">

<violation number="1" location="macos/Sources/Features/AppleScript/Ghostty.Input.Mods+AppleScript.swift:8">
P2: Malformed modifier strings with empty entries are silently accepted because empty parts are dropped during split.</violation>
</file>

<file name="macos/Ghostty.xcodeproj/project.pbxproj">

<violation number="1" location="macos/Ghostty.xcodeproj/project.pbxproj:869">
P2: DockTilePlugin leaves `NSPrincipalClass` empty, so the system may not load the intended `NSDockTilePlugIn` class.</violation>
</file>

<file name="macos/GhosttyUITests/GhosttyWindowPositionUITests.swift">

<violation number="1" location="macos/GhosttyUITests/GhosttyWindowPositionUITests.swift:44">
P2: `firstMatch.waitForExistence` here does not reliably verify a newly opened window. Select/await a distinct window (for example by waiting for window count to increase) before asserting its frame.</violation>
</file>

<file name="macos/Sources/Features/About/CyclingIconView.swift">

<violation number="1" location="macos/Sources/Features/About/CyclingIconView.swift:7">
P3: This new `@EnvironmentObject` dependency causes `AboutView` previews to crash because no `AboutViewModel` is injected.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

GHOSTTY_SGR_ATTR_BRIGHT_FG_8 = 29,
GHOSTTY_SGR_ATTR_BG_256 = 30,
GHOSTTY_SGR_ATTR_FG_256 = 31,
GHOSTTY_SGR_ATTR_UNDERLINE_COLOR = 8,
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Renumbering public GhosttySgrAttributeTag values breaks numeric tag compatibility for existing consumers. Keep previous numeric IDs stable when removing entries.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At include/ghostty/vt/sgr.h, line 112:

<comment>Renumbering public `GhosttySgrAttributeTag` values breaks numeric tag compatibility for existing consumers. Keep previous numeric IDs stable when removing entries.</comment>

<file context>
@@ -109,30 +109,29 @@ typedef enum {
-  GHOSTTY_SGR_ATTR_BRIGHT_FG_8 = 29,
-  GHOSTTY_SGR_ATTR_BG_256 = 30,
-  GHOSTTY_SGR_ATTR_FG_256 = 31,
+  GHOSTTY_SGR_ATTR_UNDERLINE_COLOR = 8,
+  GHOSTTY_SGR_ATTR_UNDERLINE_COLOR_256 = 9,
+  GHOSTTY_SGR_ATTR_RESET_UNDERLINE_COLOR = 10,
</file context>
Fix with Cubic

/// Returns `nil` if any unrecognized modifier name is encountered.
init?(scriptModifiers string: String) {
self = []
for part in string.split(separator: ",") {
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Malformed modifier strings with empty entries are silently accepted because empty parts are dropped during split.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At macos/Sources/Features/AppleScript/Ghostty.Input.Mods+AppleScript.swift, line 8:

<comment>Malformed modifier strings with empty entries are silently accepted because empty parts are dropped during split.</comment>

<file context>
@@ -0,0 +1,18 @@
+    /// Returns `nil` if any unrecognized modifier name is encountered.
+    init?(scriptModifiers string: String) {
+        self = []
+        for part in string.split(separator: ",") {
+            switch part.trimmingCharacters(in: .whitespaces).lowercased() {
+            case "shift": insert(.shift)
</file context>
Suggested change
for part in string.split(separator: ",") {
for part in string.split(separator: ",", omittingEmptySubsequences: false) {
Fix with Cubic

GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = "Ghostty Dock Tile Plugin";
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INFOPLIST_KEY_NSPrincipalClass = "";
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: DockTilePlugin leaves NSPrincipalClass empty, so the system may not load the intended NSDockTilePlugIn class.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At macos/Ghostty.xcodeproj/project.pbxproj, line 869:

<comment>DockTilePlugin leaves `NSPrincipalClass` empty, so the system may not load the intended `NSDockTilePlugIn` class.</comment>

<file context>
@@ -712,6 +854,93 @@
+				GENERATE_INFOPLIST_FILE = YES;
+				INFOPLIST_KEY_CFBundleDisplayName = "Ghostty Dock Tile Plugin";
+				INFOPLIST_KEY_NSHumanReadableCopyright = "";
+				INFOPLIST_KEY_NSPrincipalClass = "";
+				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
+				LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
</file context>
Fix with Cubic


app.typeKey("n", modifierFlags: [.command])

let window2 = app.windows.firstMatch
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: firstMatch.waitForExistence here does not reliably verify a newly opened window. Select/await a distinct window (for example by waiting for window count to increase) before asserting its frame.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At macos/GhosttyUITests/GhosttyWindowPositionUITests.swift, line 44:

<comment>`firstMatch.waitForExistence` here does not reliably verify a newly opened window. Select/await a distinct window (for example by waiting for window count to increase) before asserting its frame.</comment>

<file context>
@@ -0,0 +1,331 @@
+
+        app.typeKey("n", modifierFlags: [.command])
+
+        let window2 = app.windows.firstMatch
+        XCTAssertTrue(window2.waitForExistence(timeout: 5), "New window should appear")
+        let windowFrame2 = window2.frame
</file context>
Fix with Cubic

.xray,
]
private let timerPublisher = Timer.publish(every: 3, on: .main, in: .common)
@EnvironmentObject var viewModel: AboutViewModel
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: This new @EnvironmentObject dependency causes AboutView previews to crash because no AboutViewModel is injected.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At macos/Sources/Features/About/CyclingIconView.swift, line 7:

<comment>This new `@EnvironmentObject` dependency causes `AboutView` previews to crash because no `AboutViewModel` is injected.</comment>

<file context>
@@ -1,50 +1,38 @@
-        .xray,
-    ]
-    private let timerPublisher = Timer.publish(every: 3, on: .main, in: .common)
+    @EnvironmentObject var viewModel: AboutViewModel
 
     var body: some View {
</file context>
Fix with Cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.