Skip to content

Update ghostty to v1.3.0 - #1142

Merged
lawrencecchen merged 9 commits into
mainfrom
task-update-ghostty-latest
Mar 10, 2026
Merged

lawrencecchen merged 9 commits into
mainfrom
task-update-ghostty-latest

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Mar 10, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • update the ghostty submodule to upstream Ghostty v1.3.0 plus newer main fixes
  • reapply cmux fork patches needed for OSC 99 notifications, resize stability, display-link recovery, and keyboard copy mode selection APIs
  • refresh docs/ghostty-fork.md to document the rebased fork delta and note that cursor-click-to-move landed upstream

Testing

  • cd /Users/lawrencechen/fun/cmuxterm-hq/worktrees/task-update-ghostty-latest && ./scripts/reload.sh --tag task-update-ghostty-latest (build succeeded)

Issues


Summary by cubic

Updated ghostty submodule to v1.3.0 (+ recent main), added macOS AppleScript automation and configurable bell features, refined tab creation to avoid stealing focus, and fixed zsh shell‑integration handoff and notification dismissal. Pinned GhosttyKit checksum for the new submodule.

  • New Features

    • AppleScript automation (cmux.sdef, AppleScriptSupport.swift) gated by macos-applescript; supports querying windows/tabs/terminals, performing actions, creating windows, creating tabs without bringing to front by default, splitting, focusing/closing, and inputting text.
    • Bell handling: system beep, custom audio via bell-audio-path/bell-audio-volume, and Dock attention; wired up GHOSTTY_ACTION_RING_BELL.
  • Bug Fixes

    • Restart macOS display link on display ID change; reduce transient blank/scaled frames during resize by replaying the last frame with correct anchoring.
    • Fix zsh shell integration handoff: set CMUX_LOAD_GHOSTTY_ZSH_INTEGRATION from Ghostty and update .zshenv to use it; add tests so Ghostty prompt hooks load only when requested.
    • Clear unread terminal notifications on direct interaction (click or keypress); add tests for click and keypress, and tighten the keypress regression test when the terminal is already first responder.

Written for commit b172394. Summary will update on new commits.

Summary by CodeRabbit

  • New Features
    • macOS AppleScript support: scriptable windows, tabs, terminals and commands; new scripting dictionary and Info.plist keys to enable AppleScript.
  • Localization
    • Large set of new localized UI strings for updates, workspaces, command palette, notifications, and UI labels.
  • Improvements
    • Configurable bell behavior (audio, volume, attention) and refined zsh integration gating via a runtime flag.
  • Documentation
    • Fork docs updated for rebase onto upstream v1.3.0.
  • Tests
    • Added zsh integration handoff and notification-interaction tests (some duplicated entries noted).
  • Chores
    • Submodule pointer updated.

@vercel

vercel Bot commented Mar 10, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Mar 10, 2026 2:44am

@coderabbitai

coderabbitai Bot commented Mar 10, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Adds macOS AppleScript scripting support and resources, extensive localization strings and sdef, Xcode project and Info.plist wiring, zsh integration gating flag and tests, terminal bell/audio handling, scriptable AppDelegate APIs, a ghostty submodule pointer bump and new C header type, docs updates documenting upstream rebase and fork changes.

Changes

Cohort / File(s) Summary
AppleScript integration & scripting surface
Sources/AppleScriptSupport.swift, Resources/cmux.sdef, GhosttyTabs.xcodeproj/project.pbxproj, Resources/Info.plist
Adds full AppleScript surface: scriptable classes (window/tab/terminal), NSScriptCommand handlers, new sdef dictionary, Info.plist scripting flags, and Xcode project entries for AppleScriptSupport.swift and cmux.sdef.
App-level scripting API
Sources/AppDelegate.swift
Introduces ScriptableMainWindowState and APIs to enumerate/query/focus/add scriptable main windows and workspaces.
Terminal bell, notification dismissal & shell integration
Sources/GhosttyTerminalView.swift, Resources/shell-integration/.zshenv
Adds bell audio playback, config accessors, ringBell behavior, and notification-dismiss on input; replaces ZDOTDIR gating with CMUX_LOAD_GHOSTTY_ZSH_INTEGRATION flag and updates zsh integration logic.
Localization & UI strings
Resources/Localizable.xcstrings
Adds ~187 localized strings for updates, workspace/command palette, notifications, shortcuts, and UI labels across many languages.
Tests
cmuxTests/GhosttyConfigTests.swift, cmuxTests/CmuxWebViewKeyEquivalentTests.swift
Adds tests for zsh handoff and notification-dismiss behavior; note: duplicated test-class/method occurrences present in diffs.
Ghostty submodule & C header
ghostty (submodule pointer), ghostty.h
Bumps ghostty submodule pointer and adds ghostty_config_path_s typedef.
Project resources
Resources/cmux.sdef, Resources/Info.plist, GhosttyTabs.xcodeproj/project.pbxproj
Adds cmux.sdef scripting definition, enables AppleScript in Info.plist, and wires new source/resource into Xcode project.
Docs
docs/ghostty-fork.md
Documents rebase onto upstream v1.3.0, updated commit references, restored/updated OSC99 parser, keyboard copy-mode C API, macOS resize stale-frame mitigation, and merge-conflict notes.

Sequence Diagram(s)

sequenceDiagram
  participant AppleScript as "AppleScript Client"
  participant NSApp as "NSApplication"
  participant AppDel as "AppDelegate"
  participant ScriptObj as "ScriptWindow/Tab/Terminal"
  participant Terminal as "Terminal Surface"

  AppleScript->>NSApp: send AppleEvent (e.g., new tab / input text)
  NSApp->>AppDel: route script command
  AppDel->>ScriptObj: resolve target (window/tab/terminal)
  ScriptObj->>Terminal: invoke operation (split / input / focus / close)
  Terminal-->>ScriptObj: result/status
  ScriptObj-->>AppDel: return success/failure
  AppDel-->>NSApp: construct AppleEvent reply
  NSApp-->>AppleScript: reply/result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

Poem

🐰 I hopped into the code with glee,
Scriptable windows now talk to me,
Tabs and terminals answer a call,
Bells ring softly, tests guard the hall,
Rebased and wired — ready to be!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Update ghostty to v1.3.0' is directly related to the main objective of the PR, which is updating the ghostty submodule to v1.3.0 plus newer fixes. It is concise and clearly communicates the primary change.
Description check ✅ Passed The pull request description covers all required sections: Summary explains what changed and why, Testing provides build verification, and Checklist items are noted.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch task-update-ghostty-latest

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

@greptile-apps

greptile-apps Bot commented Mar 10, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR advances the ghostty submodule from the previous fork tip to a50579bd5 (the sync-upstream-v1-3-0 branch tip), rebasing all cmux-specific patches onto upstream Ghostty v1.3.0 plus newer main commits. The companion docs/ghostty-fork.md update accurately records the refreshed commit SHAs for existing patches and documents two newly reapplied patches (keyboard copy mode C API and macOS resize stale-frame mitigation), while also noting that cursor-click-to-move was upstreamed and is no longer a fork-only patch.

Key changes:

  • ghostty submodule: bumped from 7dd5898 → a50579bd5 (v1.3.0 rebase tip)
  • Patch SHAs updated in docs for OSC 99 parser (section 1) and display-link restart (section 2) due to rebase
  • Two new patch sections documented: keyboard copy mode C API and resize stale-frame mitigation
  • cursor-click-to-move graduated to upstream, removed from active fork patches
  • Datestamp added to doc for traceability

One documentation issue found:

  • The section numbers in docs/ghostty-fork.md (section 3 = copy mode, section 4 = resize) are reversed relative to the actual commit application order in the fork branch (the submodule HEAD is the section 3 commit, implying section 4 commits were applied earlier). This could confuse future contributors who expect sections to reflect patch stack order.

Confidence Score: 4/5

  • PR is safe to merge; it is a well-documented submodule bump with a verified successful build, and the only issue is a minor section-ordering inconsistency in the fork documentation.
  • The change consists entirely of a pinned submodule SHA update and a companion documentation refresh — no application logic is modified. All four fork patches are accounted for in both the docs and the submodule history, the build was verified locally, and the fork branch link is provided for independent audit. Score is 4 rather than 5 solely because the section numbering in the docs is inverted relative to actual commit order, which could cause confusion during the next rebase.
  • docs/ghostty-fork.md — section 3 and 4 numbering does not reflect actual git commit order in the fork branch.

Important Files Changed

Filename Overview
docs/ghostty-fork.md Documentation updated to reflect fork rebase onto v1.3.0: updated commit SHAs for existing patches, added two new patch sections (keyboard copy mode C API, resize stale-frame mitigation), and added an "Upstreamed" section for cursor-click-to-move. Minor section-numbering order doesn't match actual git commit order in the fork branch.
ghostty Submodule pointer advanced from 7dd5898 to a50579bd5 (the "Add C API for keyboard copy mode selection" tip commit of the sync-upstream-v1-3-0 fork branch). Straightforward pinned SHA bump; no logic changes in the parent repo.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["upstream Ghostty v1.3.0\n+ newer main commits"] --> B["patch 1: OSC 99 notification parser\na2252e7a9"]
    B --> C["patch 2: macOS display link restart\nc07e6c5a5"]
    C --> D["patch 4 (docs): resize stale-frame mitigation\n769bbf7a9 → 9efcdfdf8"]
    D --> E["patch 3 (docs): keyboard copy mode C API\na50579bd5 ← submodule HEAD"]
    E --> F["manaflow-ai/cmux submodule\npinned to a50579bd5"]

    style F fill:#2d6a4f,color:#fff
    style A fill:#1d3557,color:#fff
Loading

Last reviewed commit: 99818ff

Comment thread docs/ghostty-fork.md

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No issues found across 2 files

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

Copy link
Copy Markdown

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: 5be151d4df

ℹ️ 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 thread Sources/AppleScriptSupport.swift Outdated

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 issue found across 3 files (changes from recent commits).

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="cmuxTests/GhosttyConfigTests.swift">

<violation number="1" location="cmuxTests/GhosttyConfigTests.swift:1525">
P2: `waitUntilExit()` is unbounded here; add a timeout so this test fails fast instead of potentially hanging the suite.</violation>
</file>

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

Comment thread cmuxTests/GhosttyConfigTests.swift Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
Resources/shell-integration/.zshenv (1)

16-18: Consider removing unused variable _cmux_had_ghostty_zdotdir.

The variable is still assigned on line 16-18 but is no longer used since the gating condition at line 39 now uses CMUX_LOAD_GHOSTTY_ZSH_INTEGRATION instead. The assignment and cleanup at line 51 can be removed.

♻️ Suggested cleanup
-builtin typeset _cmux_had_ghostty_zdotdir=0
 if [[ -n "${GHOSTTY_ZSH_ZDOTDIR+X}" ]]; then
-    _cmux_had_ghostty_zdotdir=1
     builtin export ZDOTDIR="$GHOSTTY_ZSH_ZDOTDIR"
     builtin unset GHOSTTY_ZSH_ZDOTDIR

And at line 51:

-    builtin unset _cmux_file _cmux_ghostty _cmux_integ _cmux_had_ghostty_zdotdir
+    builtin unset _cmux_file _cmux_ghostty _cmux_integ
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Resources/shell-integration/.zshenv` around lines 16 - 18, Remove the
now-unused _cmux_had_ghostty_zdotdir variable and its related setup/cleanup:
delete the declaration/assignment of _cmux_had_ghostty_zdotdir (the builtin
typeset and the block that sets it when GHOSTTY_ZSH_ZDOTDIR is present) and
remove the corresponding cleanup/unset later, since the gating now uses
CMUX_LOAD_GHOSTTY_ZSH_INTEGRATION; ensure no other code references
_cmux_had_ghostty_zdotdir before committing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Sources/AppDelegate.swift`:
- Around line 3489-3500: The current
addWorkspace(windowId:workingDirectory:bringToFront:) unconditionally calls
setActiveMainWindow(...) and creates the workspace with select: true even when
bringToFront is false; change it so that focus/selection only happens when
bringToFront is true: only call setActiveMainWindow(...) and bringToFront(...)
when shouldBringToFront is true, and pass select: shouldBringToFront (or
otherwise false) to state.tabManager.addWorkspace(...) so the non-focus path
does not mutate the app's active window/workspace (references:
addWorkspace(windowId:workingDirectory:bringToFront:), setActiveMainWindow,
bringToFront, state.tabManager.addWorkspace).

In `@Sources/GhosttyTerminalView.swift`:
- Around line 1528-1534: The function appleScriptAutomationEnabled currently
returns true when config is nil which opens the gate on init/error; change it to
fail-closed by returning false when config is nil, i.e. in
appleScriptAutomationEnabled guard let config else { return false }, and keep
the existing ghostty_config_get call using the key "macos-applescript" and the
local enabled var so missing-key still yields the intended false default.

---

Nitpick comments:
In `@Resources/shell-integration/.zshenv`:
- Around line 16-18: Remove the now-unused _cmux_had_ghostty_zdotdir variable
and its related setup/cleanup: delete the declaration/assignment of
_cmux_had_ghostty_zdotdir (the builtin typeset and the block that sets it when
GHOSTTY_ZSH_ZDOTDIR is present) and remove the corresponding cleanup/unset
later, since the gating now uses CMUX_LOAD_GHOSTTY_ZSH_INTEGRATION; ensure no
other code references _cmux_had_ghostty_zdotdir before committing.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d8b837db-5f9f-4833-999f-70bfa3f05697

📥 Commits

Reviewing files that changed from the base of the PR and between 99818ff and ae9ddcf.

📒 Files selected for processing (10)
  • GhosttyTabs.xcodeproj/project.pbxproj
  • Resources/Info.plist
  • Resources/Localizable.xcstrings
  • Resources/cmux.sdef
  • Resources/shell-integration/.zshenv
  • Sources/AppDelegate.swift
  • Sources/AppleScriptSupport.swift
  • Sources/GhosttyTerminalView.swift
  • cmuxTests/GhosttyConfigTests.swift
  • ghostty.h

Comment thread Sources/AppDelegate.swift
Comment thread Sources/GhosttyTerminalView.swift

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

Copy link
Copy Markdown

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: ae9ddcf148

ℹ️ 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 thread Sources/AppleScriptSupport.swift Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
Sources/GhosttyTerminalView.swift (1)

1528-1534: ⚠️ Potential issue | 🟠 Major

Fail closed when the AppleScript gate cannot read config.

Line 1529 still returns true when config is unavailable, so init/error paths bypass the macos-applescript gate. This should return false.

🔒 Proposed fix
     func appleScriptAutomationEnabled() -> Bool {
-        guard let config else { return true }
+        guard let config else { return false }
         var enabled = false
         let key = "macos-applescript"
         _ = ghostty_config_get(config, &enabled, key, UInt(key.lengthOfBytes(using: .utf8)))
         return enabled
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Sources/GhosttyTerminalView.swift` around lines 1528 - 1534, The
appleScriptAutomationEnabled() function currently returns true when config is
nil, bypassing the macos-applescript gate; change the guard to return false when
config is unavailable and ensure the retrieved value from ghostty_config_get
(called with key "macos-applescript") is used as the result (defaulting to false
on any read failure) so the feature fails closed instead of open.
🧹 Nitpick comments (1)
Sources/GhosttyTerminalView.swift (1)

711-711: Cache custom bell audio by path to avoid repeated file I/O on the main thread.

NSSound(contentsOfFile:byReference:) is called on every bell ring at line 1584, causing file I/O and decoding each time. Instead, cache the sound by resolved bell-audio-path and only rebuild when the path changes. Store the cached path alongside bellAudioSound to detect when invalidation is needed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Sources/GhosttyTerminalView.swift` at line 711, The NSSound is being
recreated on every bell ring; add a cachedPath String? alongside the existing
private var bellAudioSound: NSSound? and update the bell ring logic (where
NSSound(contentsOfFile:byReference:) is currently called) to compare the
resolved bell-audio-path to cachedPath and only create a new NSSound and assign
cachedPath when the path differs or is nil; reuse bellAudioSound for subsequent
rings to avoid repeated file I/O and decoding on the main thread, and ensure
invalidation occurs when settings change the bell-audio-path.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@cmuxTests/CmuxWebViewKeyEquivalentTests.swift`:
- Around line 7638-7639: The test currently sends a real printable character
("a") via makeKeyEvent and surfaceView.keyDown(with:), which forwards into
Ghostty and can cause flakiness; change the event so it triggers
GhosttyNSView.keyDown(with:) dismissal logic without injecting terminal input —
e.g., call makeKeyEvent with a non-printable character or empty characters
(replace "a" with "" or a NUL/non-printable code) or use a non-printable keyCode
(arrow/function key) so surfaceView.keyDown(with: event) exercises the
unread-state dismissal branch but does not forward a printable character into
the Ghostty surface. Ensure the change targets the makeKeyEvent(...) call used
before surfaceView.keyDown(with:) and preserves any required modifier/flags for
the dismissal path.

---

Duplicate comments:
In `@Sources/GhosttyTerminalView.swift`:
- Around line 1528-1534: The appleScriptAutomationEnabled() function currently
returns true when config is nil, bypassing the macos-applescript gate; change
the guard to return false when config is unavailable and ensure the retrieved
value from ghostty_config_get (called with key "macos-applescript") is used as
the result (defaulting to false on any read failure) so the feature fails closed
instead of open.

---

Nitpick comments:
In `@Sources/GhosttyTerminalView.swift`:
- Line 711: The NSSound is being recreated on every bell ring; add a cachedPath
String? alongside the existing private var bellAudioSound: NSSound? and update
the bell ring logic (where NSSound(contentsOfFile:byReference:) is currently
called) to compare the resolved bell-audio-path to cachedPath and only create a
new NSSound and assign cachedPath when the path differs or is nil; reuse
bellAudioSound for subsequent rings to avoid repeated file I/O and decoding on
the main thread, and ensure invalidation occurs when settings change the
bell-audio-path.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7a16d1d4-7654-4c41-8596-f25e933f79d3

📥 Commits

Reviewing files that changed from the base of the PR and between ae9ddcf and 325b131.

📒 Files selected for processing (2)
  • Sources/GhosttyTerminalView.swift
  • cmuxTests/CmuxWebViewKeyEquivalentTests.swift

Comment thread cmuxTests/CmuxWebViewKeyEquivalentTests.swift Outdated
@lawrencecchen

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

ℹ️ 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".

@lawrencecchen
lawrencecchen merged commit dea60ea into main Mar 10, 2026
12 checks passed
@lawrencecchen
lawrencecchen deleted the task-update-ghostty-latest branch March 10, 2026 04:32
bn-l pushed a commit to bn-l/cmux that referenced this pull request Apr 3, 2026
* Update ghostty to v1.3.0

* Add bell handling and AppleScript support

* Add zsh shell integration handoff test

* Fix Ghostty zsh integration handoff in cmux

* Add terminal keypress notification dismissal test

* Dismiss terminal notifications on keypress

* Address PR review feedback

* Tighten notification dismissal regression test

* Pin GhosttyKit checksum for latest ghostty

This branch was successfully deployed

1 active deployment
Preview — b172394f Deployed Mar 10, 2026 by vercel[bot]
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.

1 participant