Skip to content

馃И Add Ghostty GPU frame export for isolated terminal workers - #17

Merged
arach merged 3 commits into
mainfrom
codex/terminal-frame-export
Sep 16, 2026
Merged

arach merged 3 commits into
mainfrom
codex/terminal-frame-export

Conversation

@arach

@arach arach commented Sep 16, 2026

Copy link
Copy Markdown
Owner

Problem and result

Hudson's isolated terminal helper needs to export real Ghostty frames without holding renderer-owned targets across processes. The pinned embedding API has no such ownership contract. This draft adds a private macOS export extension: the helper appends a GPU copy into its own bounded IOSurface pool before the engine command buffer commits, publishes after producer completion, and reuses the destination only after consumer acknowledgement.

The companion consumer is Hudson #229. Its XPC helper owns the actual PTY, parser and renderer; the host uses AppKit/Metal without SwiftUI. No published binary pin or production consumer changes here.

Changes

  • Add a separate offscreen surface constructor, preserving the existing surface configuration ABI.
  • Use explicit renderer viewport dimensions and skip local layer presentation/display-link setup for exported surfaces.
  • Add an optional credit callback before GPU encoding. When all export buffers are held, preserve dirty state and keep parsing without encoding another frame.
  • Add a credit-return wakeup that requests the current frame even after output becomes idle.
  • Document callback, GPU completion and buffer ownership requirements.
  • Add --xcframework-target native|universal to the build script; universal remains the default.
  • Correct the simulator patch's final hunk count so ordinary git apply accepts it.

Validation

  • All three patches apply in order with plain git apply --cached to pinned Ghostty 07d31666e73bce337b9cece60a884c67fe8906f4 in a temporary index.
  • Clean native arm64 engine build with Xcode 26.3 (17C529), stock macOS 26.2 SDK, Zig 0.15.2 and Apple Metal 32023.864: PASS. No SDK overlay or restored engine build cache; both new C exports verified. Xcode 27 is not required.
  • Hudson actual-terminal proof: PASS. 122 presented frames; 8 GPU completions during a 300 ms sample entirely inside a verified 500 ms host-main-thread stall. Real PTY input/output, glyph pixels, bounded three-buffer backpressure, immutable held buffers, idle credit recovery, stale ACK rejection, PTY reap and helper exit all pass.
  • bash -n scripts/build-ghosttykit.sh, build-script help and git diff --check: PASS.

The checked-in compiler validation workflow builds from the pinned source with checksum-verified Zig, records SDK/source/patch hashes and uploads the exact framework. Hudson verifies the downloaded library SHA-256 before linking it into the local runtime test. The separate build/install wrapper was syntax/help checked, not run end to end. Counts establish correctness and progress, not maximum throughput or display scanout latency. The one-time evidence image and drawable pixel readback are diagnostic instrumentation.

Limits and release gates

The initial SDK-overlay proof has been superseded by the clean Xcode 26.3 build and a successful checksum-matched runtime test on the mini (macOS 26.6.2). This closes the native arm64 engine compiler gate. The local AppKit host fixture was compiled with installed CLT/macOS 26.5 SDK, targeting macOS 14. Intel, universal/iOS builds, runtime coverage across supported OS releases, signing and release packaging remain unqualified. No installed SDK, published engine binary or release pin changed.

Production also needs complete input/IME/selection/accessibility, dynamic viewport/pool generations, crash recovery, peer signing, multiple panes, a second consumer and matched performance/soak checks. The additional GPU copy needs measurement before choosing the production frame-export design. Keep this draft while those integration and qualification gates remain open.

@arach
arach marked this pull request as ready for review September 16, 2026 21:00
@arach
arach merged commit ecfa07a into main Sep 16, 2026
1 check passed
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