Skip to content

build: skip Ghostty app bundle during setup#2848

Open
gaelic-ghost wants to merge 2 commits intomanaflow-ai:mainfrom
gaelic-ghost:build/setup-skip-ghostty-app
Open

build: skip Ghostty app bundle during setup#2848
gaelic-ghost wants to merge 2 commits intomanaflow-ai:mainfrom
gaelic-ghost:build/setup-skip-ghostty-app

Conversation

@gaelic-ghost
Copy link
Copy Markdown
Contributor

@gaelic-ghost gaelic-ghost commented Apr 12, 2026

Summary

  • What changed?
    • scripts/ensure-ghosttykit.sh now passes -Demit-macos-app=false when building GhosttyKit during setup.
  • Why?
    • Ghostty's xcframework build implicitly enables the macOS app bundle unless it is disabled explicitly.
    • That means ./scripts/setup.sh was building Ghostty.app as a side effect even though cmux setup only needs GhosttyKit.xcframework.
    • Skipping the app bundle avoids the Dock tile plugin side effect and trimmed the measured cold setup path from 159.41s to 126.54s in local runs, about 32.87s faster (20.6%).

Testing

  • How did you test this change?
    • Ran ./scripts/setup.sh in a fresh sibling worktree after temporarily moving the matching ~/.cache/cmux/ghosttykit/<sha> entry aside to force a rebuild.
    • Ran ./scripts/reload.sh --tag setup-no-ghostty-app afterward to verify the cmux Debug app still builds cleanly.
  • What did you verify manually?
    • Verified the patched setup path completed successfully and regenerated GhosttyKit.xcframework.
    • Verified ghostty/macos/build/ReleaseLocal/Ghostty.app was not produced by setup in the worktree.
    • Verified the tagged Debug cmux build succeeded.

Demo Video

For UI or behavior changes, include a short demo video (GitHub upload, Loom, or other direct link).

  • Video URL or attachment:
    • N/A (build/setup-only change)

Review Trigger (Copy/Paste as PR comment)

@codex review
@coderabbitai review
@greptile-apps review
@cubic-dev-ai review

Checklist

  • I tested the change locally
  • I added or updated tests for behavior changes
  • I updated docs/changelog if needed
  • I requested bot reviews after my latest commit (copy/paste block above or equivalent)
  • All code review bot comments are resolved
  • All human review comments are resolved

Summary by cubic

Skip building the Ghostty macOS app during setup by passing -Demit-macos-app=false when producing GhosttyKit.xcframework, avoiding Dock tile plugin side effects and cutting cold setup from 159.41s to 126.54s (~20.6%). Also synced rebuild instructions in CLAUDE.md and CONTRIBUTING.md to use the same flags (disable app; universal xcframework).

Written for commit 5dd2d42. Summary will update on new commits.

Summary by CodeRabbit

  • Chores
    • Updated the framework build process to explicitly disable producing a macOS app bundle, streamlining xcframework generation and release builds.
  • Documentation
    • Updated contributor instructions to reflect the new build steps for generating the xcframework in Release mode.

Why:
- setup only needs GhosttyKit.xcframework, but Ghostty implicitly built the macOS app too
- the extra app build can trigger Dock tile plugin side effects and wastes setup time

Verification:
- timed ./scripts/setup.sh in a fresh worktree after moving the matching GhosttyKit cache aside
- observed setup complete in 126.54s versus the prior 159.41s baseline
- confirmed ghostty/macos/build/ReleaseLocal/Ghostty.app was not produced by the patched setup path
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 12, 2026

@gaelic-ghost is attempting to deploy a commit to the Manaflow Team on Vercel.

A member of the Team first needs to authorize it.

@chatgpt-codex-connector
Copy link
Copy Markdown

To use Codex here, create an environment for this repo.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 12, 2026

📝 Walkthrough

Walkthrough

The GhosttyKit xcframework build invocation now adds -Demit-macos-app=false to the zig build command, explicitly disabling macOS app bundle emission while keeping -Demit-xcframework=true, -Dxcframework-target=universal, and -Doptimize=ReleaseFast.

Changes

Cohort / File(s) Summary
Build script
scripts/ensure-ghosttykit.sh
Added -Demit-macos-app=false to the zig build flags for GhosttyKit.xcframework builds.
Documentation
CLAUDE.md, CONTRIBUTING.md
Updated instructions/notes to include -Demit-macos-app=false alongside existing xcframework and optimization flags.

Sequence Diagram(s)

(omitted — change is a small build-flag addition; no multi-component control flow to illustrate)

Estimated Code Review Effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly Related PRs

Poem

🐰 I hopped through flags, so tiny and bright,
Turned off the Mac app, set xcframework right.
A nibble of change, a tidy new pace—
Builds skip the bundle and race to its place. 🥕✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'build: skip Ghostty app bundle during setup' clearly and concisely summarizes the primary change—adding a flag to prevent building the macOS app during setup—which aligns with the changeset's main purpose.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed The PR description comprehensively follows the template, covering what changed, why it matters with measured performance impact, testing methodology, and documentation updates.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 12, 2026

Greptile Summary

This PR adds -Demit-macos-app=false to the zig build invocation in scripts/ensure-ghosttykit.sh, suppressing the implicit macOS app bundle that Ghostty builds as a side effect when generating GhosttyKit.xcframework. The flag is already present in the CI workflow (build-ghosttykit.yml) and the release script (build-sign-upload.sh), so this change brings the local setup path into alignment with the rest of the build toolchain.

Confidence Score: 5/5

Safe to merge — single-flag addition that aligns setup with existing CI and release scripts.

No P0/P1 findings. The change is a one-line flag addition consistent with build-sign-upload.sh and .github/workflows/build-ghosttykit.yml, which already carry -Demit-macos-app=false. The xcframework artifact is unaffected; only the unwanted Ghostty.app side effect is suppressed. Existing caches remain valid.

No files require special attention.

Important Files Changed

Filename Overview
scripts/ensure-ghosttykit.sh Adds -Demit-macos-app=false to the xcframework build command, aligning it with build-sign-upload.sh and .github/workflows/build-ghosttykit.yml which already carry this flag; includes an explanatory comment.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[setup.sh] --> B[ensure-ghosttykit.sh]
    B --> C{Cache hit?}
    C -- Yes --> G[Symlink GhosttyKit.xcframework]
    C -- No --> D{Local xcframework\nmatches build key?}
    D -- Yes --> F[Seed cache from local]
    D -- No --> E["zig build\n-Demit-xcframework=true\n-Demit-macos-app=false\n-Dxcframework-target=universal\n-Doptimize=ReleaseFast"]
    E --> F
    F --> G
    G --> H[Xcode build / cmux DEV app]
Loading

Reviews (2): Last reviewed commit: "build: skip ghostty app in setup" | Re-trigger Greptile

Comment thread scripts/ensure-ghosttykit.sh
Copy link
Copy Markdown

@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.

No issues found across 1 file

@gaelic-ghost
Copy link
Copy Markdown
Contributor Author

@codex review
@coderabbitai review
@greptile-apps review
@cubic-dev-ai review

@cubic-dev-ai
Copy link
Copy Markdown

cubic-dev-ai Bot commented Apr 12, 2026

@codex review
@coderabbitai review
@greptile-apps review
@cubic-dev-ai review

@gaelic-ghost I have started the AI code review. It will take a few minutes to complete.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

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

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 12, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Read the modified script
cat scripts/ensure-ghosttykit.sh

echo "---"
# Check if Ghostty build.zig mentions emit-macos-app
find . -name "build.zig" -path "*/ghostty/*" | head -5
fd "build.zig" ghostty/ | head -5

Length of output: 5132


🏁 Script executed:

#!/bin/bash
# Check if Ghostty's build.zig supports -Demit-macos-app
fd "build.zig" ghostty/ --max-depth 2 | head -5

# Search for emit-macos-app or emit_macos_app in Ghostty sources
rg -n "emit.macos.app\|emit_macos_app\|macos.app" ghostty/build.zig 2>/dev/null | head -30

# Also check build.zig.zon or any options file
fd "build.zig" ghostty/ | xargs grep -l "macos.app\|emit_macos" 2>/dev/null | head -5

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Check if ghostty submodule exists at all
ls -la ghostty/ 2>/dev/null | head -5 || echo "ghostty dir not present"

# Look for any cached or referenced build options in the repo
rg -rn "emit-macos-app\|emit_macos_app" --type sh | head -20
rg -rn "emit-macos-app\|emit_macos_app" | head -20

# Check CLAUDE.md for any build documentation
fd "CLAUDE.md" | xargs cat 2>/dev/null | head -60

Length of output: 2383


🌐 Web query:

Ghostty zig build emit-macos-app option build.zig

💡 Result:

In Ghostty, the -Demit-macos-app build flag is defined in src/build/Config.zig as a boolean Zig build option:

  • config.emit_macos_app = b.option(bool, "emit-macos-app", "Build and install the macOS app bundle.") orelse config.emit_xcframework; (so it defaults to whatever emit-xcframework resolves to). [1]

When emit_macos_app is true, build.zig installs the macOS app bundle via the Xcode build step:

  • if (config.emit_macos_app) { macos_app.install(); } [2]

Practically, on macOS this results in a .app bundle at:

  • zig-out/Ghostty.app [3]

Sources: Ghostty build config option definition [1], build.zig install guard [2], Ghostty “Build from Source” docs (macOS output path) [3].


@gaelic-ghost: The change looks correct and well-reasoned. Here's my review:


scripts/ensure-ghosttykit.sh

The -Demit-macos-app option is defined in Ghostty's src/build/Config.zig as b.option(bool, "emit-macos-app", ...) and defaults to the value of emit-xcframework. Since ensure-ghosttykit.sh passes -Demit-xcframework=true, emit_macos_app would silently resolve to true — causing the implicit Ghostty.app bundle side effect that this PR eliminates. The fix is correct.

A few observations:

  1. Flag validity ✅ — -Demit-macos-app=false is a first-class Zig build option in Ghostty; it directly gates the macos_app.install() step in build.zig.

  2. Flag grouping ✅ — The two emit-* flags are now adjacent in the command, which is readable and logical.

  3. Cache key unaffected ✅ — The cache key is derived from ghostty submodule SHA + dirty-tree hash, not from build flags. Existing cached GhosttyKit.xcframework artifacts remain valid (they never contained Ghostty.app), so no forced rebuilds occur.

  4. Explanatory comment ✅ — The inline comment clearly documents why the flag is needed, which is valuable since the implicit-default behaviour isn't obvious from Ghostty's public docs.

  5. Measured improvement — The 20.6% reduction in cold setup time (~32.87 s) is meaningful and verifiable from the PR description.

No issues found. The change is minimal, scoped correctly, and achieves the stated goal.


I'll also update the long-term memory to reflect the new canonical build command.

🐇 ~( 📋 noted — build command updated in memory )


✏️ Learnings added
Learnt from: gaelic-ghost
URL: https://github.com/manaflow-ai/cmux/pull/2848

Timestamp: 2026-04-12T19:59:50.020Z
Learning: Repo: manaflow-ai/cmux — When rebuilding GhosttyKit.xcframework in scripts/ensure-ghosttykit.sh, the canonical zig build command is: `cd ghostty && zig build -Demit-xcframework=true -Demit-macos-app=false -Dxcframework-target=universal -Doptimize=ReleaseFast`. The `-Demit-macos-app=false` flag is required because Ghostty's build system defaults `emit_macos_app` to the value of `emit_xcframework` (src/build/Config.zig), so passing `-Demit-xcframework=true` without the override would implicitly build and install Ghostty.app as a side effect, causing Dock tile plugin side effects and ~33s of avoidable build time.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


⛔ Learnings removed
Learnt from: CR
Repo: manaflow-ai/cmux PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-07T02:19:07.331Z
Learning: When rebuilding GhosttyKit.xcframework, always use Release optimizations with `cd ghostty && zig build -Demit-xcframework=true -Dxcframework-target=universal -Doptimize=ReleaseFast`

🧠 Learnings used
Learnt from: CR
Repo: manaflow-ai/cmux PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-07T02:19:07.331Z
Learning: When rebuilding GhosttyKit.xcframework, always use Release optimizations with `cd ghostty && zig build -Demit-xcframework=true -Dxcframework-target=universal -Doptimize=ReleaseFast`

Learnt from: lejahmie
Repo: manaflow-ai/cmux PR: 2371
File: cmuxTests/CJKIMEInputTests.swift:1325-1335
Timestamp: 2026-03-31T10:56:43.241Z
Learning: Repo: manaflow-ai/cmux — In `cmuxTests/CJKIMEInputTests.swift`, `GhosttyOptionDeleteRegressionTests.testRightOptionLiteralCharacterSetsAltRightInRawModsFallbackPath` intentionally omits `consumed_mods & GHOSTTY_MODS_ALT_RIGHT` assertions. That test simulates the fallback path (no `NX_DEVICERALTKEYMASK` bit in event flags; right-side state injected via `debugSetRightOptionModifierDownForUITest(true)`), where `consumed_mods` depends on translation-mod flags and is unstable in synthetic test contexts. Only `mods & (ALT | ALT_RIGHT)` is asserted here. The `consumed_mods` coverage is provided by the deterministic `testRightOptionDeleteSetsAltRightModifier` test, which uses the direct `NX_DEVICERALTKEYMASK` modifier flag path.

Learnt from: lawrencecchen
Repo: manaflow-ai/cmux PR: 2525
File: Sources/GhosttyTerminalView.swift:481-513
Timestamp: 2026-04-02T10:13:39.235Z
Learning: Repo: manaflow-ai/cmux — In Sources/GhosttyTerminalView.swift, terminal file-link resolution trims trailing unmatched closing delimiters “) ] } >” only when they are dangling (more closers than openers), preserving wrapped tokens like “(file:///tmp/a.png)”. Implemented via terminalFileLinkTrailingClosingDelimiters and count comparison inside trimTrailingTerminalFileLinkPunctuation(_:) and exercised by a regression test (PR `#2525`, commit 3f5c5b6d).

Learnt from: HamptonMakes
Repo: manaflow-ai/cmux PR: 2007
File: Sources/GhosttyTerminalView.swift:3193-3196
Timestamp: 2026-03-23T16:36:13.217Z
Learning: Repo: manaflow-ai/cmux — In Sources/GhosttyTerminalView.swift, TerminalSurface.createSurface(for:) builds a fresh per-surface environment via setManagedEnvironmentValue and does not persist managed vars (e.g., CMUX_AMP_HOOKS_DISABLED / CMUX_CLAUDE_HOOKS_DISABLED) into the template. Therefore, only setting the *_HOOKS_DISABLED var when disabled is sufficient; explicit clearing on the enabled path isn’t required.

Learnt from: outoftime
Repo: manaflow-ai/cmux PR: 1528
File: Sources/GhosttyTerminalView.swift:3220-3228
Timestamp: 2026-03-17T18:25:33.286Z
Learning: Repo: manaflow-ai/cmux — In Sources/GhosttyTerminalView.swift within TerminalSurface.createSurface(for:), when constructing XDG_DATA_DIRS for Fish vendor_conf.d auto-sourcing, treat empty or whitespace-only values from initialEnvironmentOverrides, env, getenv, and ProcessInfo as unset before prefixing the integrationDir. This avoids producing a trailing colon. Keep XDG_DATA_DIRS in protectedStartupEnvironmentKeys so initialEnvironmentOverrides cannot overwrite the prefixed value.

Learnt from: pstanton237
Repo: manaflow-ai/cmux PR: 0
File: :0-0
Timestamp: 2026-04-06T12:03:16.921Z
Learning: Repo: manaflow-ai/cmux — In CLI/cmux.swift, `claudeTeamsLaunchArguments` must use two independent branches: (1) prepend `--teammate-mode auto` only when the caller has NOT already supplied `--teammate-mode`; (2) append `--settings <claudeHooksJSON>` unconditionally (modulo `CMUX_CLAUDE_HOOKS_DISABLED=1` opt-out). These two branches must never be coupled in a single early-return or conditional block — coupling them was the original `#2229` regression (hook JSON silently bypassed when `--teammate-mode auto|manual` was explicit). Mirrors `Resources/bin/claude:208`: `exec "$REAL_CLAUDE" --settings "$HOOKS_JSON" "$@"` where `$@` content never gates hook injection.

Learnt from: lawrencecchen
Repo: manaflow-ai/cmux PR: 2514
File: CLI/cmux.swift:9691-9711
Timestamp: 2026-04-01T22:58:26.254Z
Learning: Repo: manaflow-ai/cmux — In CLI/cmux.swift (runClaudeTeams), custom Claude path resolution now trims whitespace and rejects paths that point to the cmux wrapper using isCmuxClaudeWrapper(), before falling back to PATH/bundled. The Resources/bin/claude wrapper also resolves the real path and compares against itself, requiring -f/-x to avoid recursion/self-reference.

Learnt from: BillionClaw
Repo: manaflow-ai/cmux PR: 1755
File: Sources/GhosttyTerminalView.swift:4889-4903
Timestamp: 2026-03-18T16:50:14.396Z
Learning: Repo: manaflow-ai/cmux — In Sources/GhosttyTerminalView.swift, GhosttyNSView.performKeyEquivalent(with:) must only route Command key equivalents to NSApp.mainMenu when shouldRouteCommandEquivalentDirectlyToMainMenu(event) returns true; otherwise, handle the key directly via keyDown to forward unbound Cmd+Shift combinations to the terminal and preserve the Cmd+` exclusion.

Learnt from: austinywang
Repo: manaflow-ai/cmux PR: 2505
File: Sources/GhosttyTerminalView.swift:1694-1737
Timestamp: 2026-04-06T07:16:45.980Z
Learning: Repo: manaflow-ai/cmux — Background rendering contract
- In Sources/GhosttyTerminalView.swift, GhosttyApp.loadDefaultConfigFilesWithLegacyFallback(_:) sets usesHostLayerBackground = false when a Ghostty background-image is configured (injects "macos-background-from-layer = false"); otherwise it enables the host-layer path.
- GhosttyNSView.applySurfaceBackground() reads GhosttyApp.shared.usesHostLayerBackground and sets GhosttySurfaceScrollView’s background to .clear when false, avoiding a second solid-color fill under Ghostty’s image compositor.
- After config reload, terminal panels reapply the correct host-layer/background mode to stay consistent with the current setting.

Learnt from: tayl0r
Repo: manaflow-ai/cmux PR: 0
File: :0-0
Timestamp: 2026-04-08T03:36:30.160Z
Learning: Repo: manaflow-ai/cmux — AppDelegate.FileBrowserDrawerState threading pattern (PR `#1909`, commit e0e57809): FileBrowserDrawerState must be threaded through AppDelegate.configure() as a weak stored property (matching the sidebarState pattern), passed through both configure() call sites, with registerMainWindow parameter made non-optional. The fallback `?? FileBrowserDrawerState()` must NOT be used as it creates detached instances that are not properly owned by the window context.

Copy link
Copy Markdown

@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.

1 issue found across 1 file

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="scripts/ensure-ghosttykit.sh">

<violation number="1" location="scripts/ensure-ghosttykit.sh:125">
P2: Cache key omits build configuration, so changing zig build flags can still reuse stale GhosttyKit artifacts for the same commit.</violation>
</file>

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

@@ -120,7 +120,9 @@ else
echo "==> Building GhosttyKit.xcframework (this may take a few minutes)..."
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot Apr 12, 2026

Choose a reason for hiding this comment

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

P2: Cache key omits build configuration, so changing zig build flags can still reuse stale GhosttyKit artifacts for the same commit.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/ensure-ghosttykit.sh, line 125:

<comment>Cache key omits build configuration, so changing zig build flags can still reuse stale GhosttyKit artifacts for the same commit.</comment>

<file context>
@@ -120,7 +120,9 @@ else
-      zig build -Demit-xcframework=true -Dxcframework-target=universal -Doptimize=ReleaseFast
+      # Ghostty's xcframework build implicitly enables the macOS app bundle
+      # unless we turn it off explicitly, which causes avoidable app-side effects.
+      zig build -Demit-xcframework=true -Demit-macos-app=false -Dxcframework-target=universal -Doptimize=ReleaseFast
     )
     echo "$GHOSTTY_KEY" > "$LOCAL_KEY_STAMP"
</file context>
Fix with Cubic

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

cubic identified a real follow-up, but it’s outside the scope of this volunteer PR. I fixed the docs drift that directly matched this change and I’m leaving cache-key redesign for a separate paid pass.

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