Bump libghostty-spm 1.5.1, MSDisplayLink 2.2.0, and libghostty-vt - #10
Bump libghostty-spm 1.5.1, MSDisplayLink 2.2.0, and libghostty-vt#10rudironsoni wants to merge 4 commits into
Conversation
Sync libghostty-spm 1.5.1, MSDisplayLink 2.2.0, and libghostty-vt to ghostty 3c1ef5b. JNI follows the new C ABI. Expo stays on SDK 57.0.19 with react-native 0.86.3; ESLint 10 runs against TypeScript 7's tsc.
Greptile SummaryThe PR updates the vendored Ghostty components, Android C API integration, Expo/React Native stack, and JS/CI toolchain, while adding an iOS policy that sends OSC 52 writes through host approval.
Confidence Score: 3/5The PR is not safe to merge until pasted and dropped file paths escape line terminators before reaching a live shell prompt. The new shell-path escaping copies CR and LF unchanged, and the file URL drop path sends that result directly to the terminal, allowing a newline-bearing filename to introduce a separate shell command. Files Needing Attention: ios/vendor/GhosttyTerminal/Platform/Shared/TerminalShellEscape.swift, ios/vendor/GhosttyTerminal/Platform/Shared/TerminalPasteboardContent.swift, ios/vendor/GhosttyTerminal/Platform/UIKit/UITerminalView+Drop.swift
|
| Filename | Overview |
|---|---|
| ios/ExpoLibghosttyView.swift | Configures clipboard-write as ask and denies program-originated clipboard requests while allowing user-started paste. |
| ios/vendor/GhosttyTerminal/Controller/TerminalController+Callbacks.swift | Adds length-bounded clipboard payload handling and routes confirmed OSC 52 writes through the host delegate. |
| ios/vendor/GhosttyTerminal/Platform/Shared/TerminalShellEscape.swift | Adds shell escaping for pasted paths but omits CR and LF, allowing line terminators to alter shell command structure. |
| android/src/main/cpp/ghostty_jni.cpp | Adapts terminal creation, mode lookup, and render-state color access to the updated libghostty-vt C API. |
| vendor-manifest.json | Re-pins the native vendor sources and checksummed binary artifacts, including the documented contributor-fork Android tarball. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
File[Clipboard or dropped file URL] --> Path[Extract pathname]
Path --> Escape[TerminalShellEscape.escape]
Escape --> Input[Send text to terminal surface]
Input --> Shell[Live shell prompt]
Escape -. CR/LF remain unchanged .-> Shell
Reviews (4): Last reviewed commit: "chore(ios): bump libghostty-spm to 1.5.2..." | Re-trigger Greptile
There was a problem hiding this comment.
🟡 Changes recommended
It introduces at least one build-breaking Swift callsite (TerminalPasteboardContent.text()) and confirmed logic bugs in new routing/frame-rate code that should be fixed before merge.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR updates the repo’s pinned vendor dependencies (libghostty-spm, MSDisplayLink, libghostty-vt) and aligns the iOS/Android wrapper layers + JS/CI toolchain with the newer upstream APIs and behaviors (notably display link pacing/frame-rate control, clipboard gating, resize throttling, and new input/key paths).
Changes:
- Bump vendor pins (SPM/CocoaPods + Android tarball) and vendor drift detection logic (
vendor-watch). - Update iOS terminal wrapper code (MSDisplayLink frame-rate ranges, display-link driven ticking, focus/visibility handling, clipboard confirmation, paste/drop staging, shell integration resources).
- Update Android JNI bindings to match the new libghostty-vt C API + refresh Expo/React Native + lint/tooling + CI actions.
File summaries
| File | Description |
|---|---|
| vendor-manifest.json | Updates pinned vendor tags/commits and artifact URLs + checksums. |
| scripts/vendor-watch.sh | Changes drift detection to compare numeric package tags instead of storage.* release tags. |
| README.md | Updates Android toolchain note (Zig version). |
| pnpm-workspace.yaml | Updates pnpm minimum-release-age exclusions for Expo 57.x packages. |
| package.json | Bumps Expo/RN/tooling dependencies; introduces TS 7 via @typescript/native and TS6 compiler API shim for ESLint. |
| ios/vendor/README.md | Updates vendored iOS component tag table. |
| ios/vendor/MSDisplayLink/DisplayLinkFrameRateRange.swift | Adds platform-neutral frame-rate range type and union logic. |
| ios/vendor/MSDisplayLink/DisplayLinkDriver+Helper.swift | Adds helper methods to resolve and re-apply frame-rate preferences across drivers. |
| ios/vendor/MSDisplayLink/DisplayLinkDriver+CA.swift | Applies preferred frame-rate range to CADisplayLink (incl. iOS 15+ range API). |
| ios/vendor/MSDisplayLink/DisplayLinkDriver.swift | Adds per-driver preferred frame-rate range propagation to the shared helper. |
| ios/vendor/MSDisplayLink/DisplayLink+SwiftUI.swift | Adds SwiftUI modifier support for passing a preferred frame-rate range. |
| ios/vendor/MSDisplayLink/DisplayLink.swift | Exposes preferredFrameRateRange and makes DisplayLink/delegation open. |
| ios/vendor/GhosttyTerminal/View/TerminalViewRepresentable@UIKit.swift | Uses host-provided platform view factory and updates focus bridging hooks. |
| ios/vendor/GhosttyTerminal/View/TerminalViewRepresentable@AppKit.swift | Uses host-provided platform view factory and updates focus bridging hooks + guard order. |
| ios/vendor/GhosttyTerminal/View/TerminalViewRepresentable.swift | Adds stored isSurfaceVisible, prevents re-stamping visibility, and syncs accessory items. |
| ios/vendor/GhosttyTerminal/Surface/TerminalSurfaceViewDelegate.swift | Adds clipboard confirmation and scrollbar delegate types. |
| ios/vendor/GhosttyTerminal/Surface/TerminalSurfaceView.swift | Forwards isSurfaceVisible into the representable. |
| ios/vendor/GhosttyTerminal/Surface/TerminalSurfaceOptions.swift | Adds command, waitAfterCommand, and resize-throttle policy; updates equivalence rules. |
| ios/vendor/GhosttyTerminal/Surface/TerminalSurfaceCoordinator.swift | Reworks tick pacing around a shared display link, adds resize throttling and visibility/attach safeguards. |
| ios/vendor/GhosttyTerminal/Surface/TerminalSurface.swift | Makes mouse + selection helpers public and removes isMouseCaptured. |
| ios/vendor/GhosttyTerminal/Surface/TerminalKeyPress.swift | Adds programmatic keypress API and convenience TerminalSurface.sendKey helpers. |
| ios/vendor/GhosttyTerminal/Surface/TerminalKey.swift | Adds a complete key enum mirroring libghostty key definitions + US layout mapping. |
| ios/vendor/GhosttyTerminal/State/TerminalViewState+Delegate.swift | Defers @Published mutations to next runloop turn; adds clipboard confirmation + scrollbar updates. |
| ios/vendor/GhosttyTerminal/State/TerminalViewState.swift | Adds attached view hooks, view factory, focus requests, visibility control, accessory items, and key/paste API cleanup. |
| ios/vendor/GhosttyTerminal/Resources/Ghostty/shell-integration/zsh/ghostty-integration | Adds new zsh shell integration script. |
| ios/vendor/GhosttyTerminal/Resources/Ghostty/shell-integration/zsh/.zshenv | Adds zsh bootstrap that defers loading until after user .zshrc. |
| ios/vendor/GhosttyTerminal/Resources/Ghostty/shell-integration/bash/LICENSE-bash-preexec.md | Adds license for vendored bash-preexec. |
| ios/vendor/GhosttyTerminal/Resources/Ghostty/shell-integration/bash/ghostty.bash | Adds bash shell integration script with injected startup replay support. |
| ios/vendor/GhosttyTerminal/Resources/Ghostty/shell-integration/bash/bash-preexec.sh | Vendors bash-preexec with Ghostty-specific patch to avoid HISTCONTROL modification. |
| ios/vendor/GhosttyTerminal/Platform/UIKit/UITerminalView+UITextInput.swift | Improves software keyboard routing (semantic enter, IME commits), inline prediction disabling, and delegate storage. |
| ios/vendor/GhosttyTerminal/Platform/UIKit/UITerminalView+Snapshot.swift | Adds UIKit snapshot helper using drawHierarchy. |
| ios/vendor/GhosttyTerminal/Platform/UIKit/UITerminalView+PublicSticky.swift | Broadens UIKit guards and fixes macCatalyst gating. |
| ios/vendor/GhosttyTerminal/Platform/UIKit/UITerminalView+PublicInput.swift | Adds public focus/paste/sendKey helpers for UIKit views. |
| ios/vendor/GhosttyTerminal/Platform/UIKit/UITerminalView+PinchZoom.swift | Refactors pinch zoom state and adds explicit min/max font sizes. |
| ios/vendor/GhosttyTerminal/Platform/UIKit/UITerminalView+Lifecycle.swift | Hardens attach behavior, adds scene activation support, adjusts sublayer sizing under resize throttling, and focus bridge hooks. |
| ios/vendor/GhosttyTerminal/Platform/UIKit/UITerminalView+InputAccessory.swift | Improves paste behavior + key event synthesis and guards for visionOS/catalyst behavior. |
| ios/vendor/GhosttyTerminal/Platform/UIKit/UITerminalView+Drop.swift | Adds drag-and-drop support for files/URLs/text on UIKit/Catalyst. |
| ios/vendor/GhosttyTerminal/Platform/UIKit/UITerminalView.swift | Refactors internal state storage, adds edit-menu interaction, and exposes setSurfaceVisible. |
| ios/vendor/GhosttyTerminal/Platform/UIKit/TerminalTextPosition.swift | Removes unused start/end position helpers. |
| ios/vendor/GhosttyTerminal/Platform/UIKit/TerminalTextInputHandler@UIKit.swift | Routes typed text through key events to avoid bracketed-paste semantics for normal typing. |
| ios/vendor/GhosttyTerminal/Platform/UIKit/TerminalStickyModifierState.swift | Broadens UIKit guards and fixes macCatalyst gating. |
| ios/vendor/GhosttyTerminal/Platform/UIKit/TerminalInputBarKey.swift | Adds metadata (titles/symbols) for accessory items for host UIs. |
| ios/vendor/GhosttyTerminal/Platform/UIKit/TerminalInputAccessoryView.swift | Uses item-provided titles/symbols and adds visionOS blur fallback logic. |
| ios/vendor/GhosttyTerminal/Platform/UIKit/TerminalInputAccessoryStyle.swift | Broadens UIKit guards and fixes macCatalyst gating. |
| ios/vendor/GhosttyTerminal/Platform/Shared/TerminalShellEscape.swift | Adds POSIX shell escaping utility for pasted/staged paths. |
| ios/vendor/GhosttyTerminal/Platform/Shared/TerminalPasteboardContent.swift | Adds pasteboard readers matching Ghostty behavior (URLs first, file URLs escaped). |
| ios/vendor/GhosttyTerminal/Platform/Shared/TerminalMainActor.swift | Adds “next turn” main-queue helper to avoid publishing during SwiftUI updates. |
| ios/vendor/GhosttyTerminal/Platform/Shared/TerminalInputText.swift | Adds software key commit router enums/utilities. |
| ios/vendor/GhosttyTerminal/Platform/Shared/TerminalIMEComposition.swift | Adds platform-neutral IME routing logic for hardware keys. |
| ios/vendor/GhosttyTerminal/Platform/Shared/TerminalHardwareKeyRouter.swift | Removes direct-raw-byte side channel; routes all keys through libghostty key path. |
| ios/vendor/GhosttyTerminal/Platform/Shared/TerminalFileStaging.swift | Adds staging for pasted/dropped data into files and returns escaped paths. |
| ios/vendor/GhosttyTerminal/Platform/PlatformSupport.swift | Adds a single compile-time platform assertion (UIKit or AppKit required). |
| ios/vendor/GhosttyTerminal/Platform/AppKit/TerminalTextInputHandler@AppKit.swift | Normalizes platform guard ordering. |
| ios/vendor/GhosttyTerminal/Platform/AppKit/TerminalKeyEventHandler@AppKit.swift | Removes direct-input bypass; refactors key echo state access. |
| ios/vendor/GhosttyTerminal/Platform/AppKit/KeyboardLayout.swift | Normalizes platform guard ordering. |
| ios/vendor/GhosttyTerminal/Platform/AppKit/AppTerminalView+Snapshot.swift | Adds AppKit snapshot helper using cacheDisplay. |
| ios/vendor/GhosttyTerminal/Platform/AppKit/AppTerminalView+PublicInput.swift | Adds public focus/paste/sendKey helpers and deprecates old sendText naming. |
| ios/vendor/GhosttyTerminal/Platform/AppKit/AppTerminalView+NSTextInputClient.swift | Normalizes platform guard ordering. |
| ios/vendor/GhosttyTerminal/Platform/AppKit/AppTerminalView+Lifecycle.swift | Adds focus-bridge struct and pending-focus replay scheduling. |
| ios/vendor/GhosttyTerminal/Platform/AppKit/AppTerminalView+Input.swift | Refactors key-echo/pointer state into structs. |
| ios/vendor/GhosttyTerminal/Platform/AppKit/AppTerminalView.swift | Refactors internal state and adds live resize-throttle setter. |
| ios/vendor/GhosttyTerminal/Metrics/TerminalScrollModifiers.swift | Normalizes AppKit guard ordering. |
| ios/vendor/GhosttyTerminal/Metrics/TerminalInputModifiers.swift | Adds Hashable conformance to modifier OptionSet. |
| ios/vendor/GhosttyTerminal/InMemory/TerminalCallbackBridge.swift | Adds scrollbar action forwarding and clipboard confirmation bridge. |
| ios/vendor/GhosttyTerminal/InMemory/InMemoryTerminalSurfaceAccess.swift | Buffers output while detached and flushes on attach (bounded). |
| ios/vendor/GhosttyTerminal/InMemory/InMemoryTerminalSession.swift | Adds optional suppression of pixel-only resizes; documents/uses buffered output semantics. |
| ios/vendor/GhosttyTerminal/Debug/TerminalDebugLog.swift | Removes debugSummary for deleted TerminalHardwareKeyDelivery type. |
| ios/vendor/GhosttyTerminal/Controller/TerminalController+Surface.swift | Wires new surface config fields (command, wait_after_command). |
| ios/vendor/GhosttyTerminal/Controller/TerminalController+Callbacks.swift | Updates clipboard read/write semantics and introduces confirmation flows. |
| ios/vendor/GhosttyTerminal/Controller/TerminalController.swift | Adds multi-surface wakeup observers and configures runtime resources env before init. |
| ios/vendor/GhosttyTerminal/Configuration/GhosttyRuntimeResources.swift | Adds resource bundle lookup + GHOSTTY_RESOURCES_DIR environment configuration. |
| ios/MSDisplayLink.podspec | Bumps MSDisplayLink CocoaPods version. |
| ios/GhosttyTerminalBundle+CocoaPods.swift | Adds CocoaPods Bundle.module shim for GhosttyTerminal resource bundle. |
| ios/GhosttyTerminal.podspec | Bumps GhosttyTerminal version and bundles Ghostty + terminfo resources for CocoaPods. |
| ios/GhosttyKit.podspec | Bumps GhosttyKit CocoaPods version. |
| ios/ExpoLibghostty.podspec | Excludes the CocoaPods Bundle.module shim from the parent pod. |
| example/package.json | Updates example app Expo/RN and dev tooling versions. |
| eslint.config.cjs | Adds React version pin to avoid ESLint 10 incompatibility in react plugin detect logic. |
| CHANGELOG.md | Documents dependency bumps and related behavioral changes. |
| android/src/main/cpp/ghostty_jni.cpp | Updates JNI usage for new ghostty terminal/render-state APIs and mode/color queries. |
| .github/workflows/ci.yml | Updates setup actions to v6 and disables new proprietary cache component for gradle action. |
| .github/workflows/build-android-libs.yml | Updates defaults and toolchain env for new ghostty commit, Zig, and Nerd Fonts. |
Review details
- Files reviewed: 16/87 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| "url": "https://github.com/rudironsoni/expo-libghostty/releases/download/storage.libghostty-vt.3c1ef5b32fc5.r1/libghostty-vt-android-3c1ef5b32fc5-r1.tar.gz", | ||
| "sha256": "39ae5ed0eb0b0330a583045c98ed5cc0dc5adff0b0d7d87a884bfc0ef995fcea" |
There was a problem hiding this comment.
Cannot re-pin this from the fork. gh workflow run build-android-libs.yml on arcboxlabs/expo-libghostty returns 403 (needs admin).
The tarball is still checksum-pinned at:
https://github.com/rudironsoni/expo-libghostty/releases/tag/storage.libghostty-vt.3c1ef5b32fc5.r1
sha256 39ae5ed0eb0b0330a583045c98ed5cc0dc5adff0b0d7d87a884bfc0ef995fcea
A maintainer with write on this repo needs to run build-android-libs.yml for 3c1ef5b32fc5ea6b93d28493fabf193f595139cf and update vendor-manifest.json. Leaving this thread open until that lands.
Set clipboard-write = ask so program writes go through host confirmation. Deny OSC 52 read/write; allow user paste.
There was a problem hiding this comment.
🔵 Needs a closer look
It introduces a compile-breaking TerminalPasteboardContent.text() call mismatch and still pins the Android vendor tarball to a contributor fork URL, which should be repinned before merge.
Review details
Suppressed comments (1)
vendor-manifest.json:20
- The pinned Android
libghostty-vttarball is currently hosted on a contributor fork (rudironsoni/expo-libghostty). This is a supply-chain risk and also makes the build depend on a third-party repo's retention policies; per the PR description, it should be rebuilt/uploaded in this repo andurl+sha256repinned before merge.
- Files reviewed: 17/88 changed files
- Comments generated: 0 new
- Review effort level: Lite
Call TerminalPasteboardContent.text(from: .general) instead of the defaulted text() form Copilot flagged as a mismatch.
|
Addressed this Copilot review:
Fork tarball — still blocked. We cannot dispatch |
Sync vendor sources and pin the XCFramework from upstream.c4e16970a803 (ghostty c4e16970). Keep the explicit pasteboard text(from: .general) call sites.
| private static let escapedCharacters: Set<Character> = [ | ||
| "\\", " ", "(", ")", "[", "]", "{", "}", "<", ">", "\"", "'", "`", | ||
| "!", "#", "$", "&", ";", "|", "*", "?", "\t", | ||
| ] |
There was a problem hiding this comment.
Line terminators bypass path escaping
When a pasted or dropped filename contains a newline followed by shell syntax, escape copies the newline unchanged and the drop path sends it to the live terminal, causing the remainder of the filename to be interpreted as a separate shell command.
How this was verified: The escape set omits CR and LF, while the file-URL path passes through this function before being sent to the terminal surface.
| private static let escapedCharacters: Set<Character> = [ | |
| "\\", " ", "(", ")", "[", "]", "{", "}", "<", ">", "\"", "'", "`", | |
| "!", "#", "$", "&", ";", "|", "*", "?", "\t", | |
| ] | |
| private static let escapedCharacters: Set<Character> = [ | |
| "\\", " ", "(", ")", "[", "]", "{", "}", "<", ">", "\"", "'", "`", | |
| "!", "#", "$", "&", ";", "|", "*", "?", "\t", "\r", "\n", | |
| ] |
Closes #6.
Bumps vendor pins past the July drift issue, plus Expo 57.0.19 and the JS/CI toolchain.
What
upstream.1.3.1-2, Ghostty v1.3.1)b094737→ ghostty3c1ef5b(Zig 0.16.0, Nerd Fonts v3.5.1)ghostty_terminal_newcols/rows, mode viaGHOSTTY_TERMINAL_DATA_MODE, colors viaGHOSTTY_RENDER_STATE_DATA_COLORS)tscis TypeScript 7.0.2 (@typescript/native); thetypescriptpackage is@typescript/typescript6because TypeScript 7 still has no compiler API for ESLintvendor-watchnow compares libghostty-spm package version tags (X.Y.Z), notstorage.*tags.Android tarball host
vendor-manifest.jsoncurrently points at a public tarball on the contributor fork:https://github.com/rudironsoni/expo-libghostty/releases/tag/storage.libghostty-vt.3c1ef5b32fc5.r1
Please re-run
build-android-libs.ymlon this repo for3c1ef5b32fc5ea6b93d28493fabf193f595139cfand re-pin the URL + sha256 before merge if you do not want the package to download from the fork.How to test
Android (CI-equivalent):
iOS (CI-equivalent):
Local verification
pnpm lint,pnpm exec tsc --noEmit,pnpm testpassassembleReleaseBUILD SUCCESSFULxcodebuildBuild SucceededExpoReactNativeFactorydoes not compile against it, and AGP wants Gradle 9.4.1 while Expo 57 prebuild still writes 9.3.1