Skip to content

Fix launch compatibility on macOS 14 and 15#785

Merged
FuJacob merged 1 commit into
mainfrom
codex/fix-macos-14-launch-compat
Jul 11, 2026
Merged

Fix launch compatibility on macOS 14 and 15#785
FuJacob merged 1 commit into
mainfrom
codex/fix-macos-14-launch-compat

Conversation

@FuJacob

@FuJacob FuJacob commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes the pre-UI launch abort reported on older supported macOS releases by moving app and menu-bar lifecycle ownership from SwiftUI App/MenuBarExtra scenes to stable AppKit NSApplication, NSStatusItem, and NSPopover APIs. Adds a release-bundle verifier and CI that launches the same universal shipping-style artifact on macOS 14 and 15, while also correcting the release archive command so it performs exactly one archive action.

Validation

  • xcodebuild test -project Cotabby.xcodeproj -scheme Cotabby -destination platform=macOS -derivedDataPath build/DerivedData CODE_SIGNING_ALLOWED=NOTEST SUCCEEDED, 1,691 tests, 7 skipped, 0 failures
  • Post-rebase xcodebuild ... build-for-testingTEST BUILD SUCCEEDED
  • Universal Release archive — ARCHIVE SUCCEEDED
  • scripts/verify_macos_compatibility.py ... --require-universal — macOS 14.0 minimum verified for arm64/x86_64 across 14 Mach-O slices; FoundationModels weak linking verified
  • Debug and Release -cotabby-compatibility-smoke-test launches — exit 0
  • swiftlint --strict --quiet — exit 0
  • xcodegen generate and git diff --check — clean
  • Workflow YAML parsing — passed

Linked issues

Fixes #767

Risk / rollout notes

This replaces only the menu-bar shell and application entry point; the existing SwiftUI menu content and long-lived dependency graph remain unchanged. Status-item visibility, pause state, accepted-word count, Settings dismissal, and macOS 26 window styling are explicitly preserved. The new required compatibility workflow guards future releases against deployment-target drift, strong-linking newer frameworks, missing Intel slices, and launch-time runtime regressions on macOS 14/15.

Greptile Summary

This PR moves the macOS menu-bar shell from SwiftUI scenes to AppKit ownership. The main changes are:

  • AppKit NSApplication entry point and delegate-owned lifecycle.
  • New MenuBarController using NSStatusItem, NSPopover, and hosted SwiftUI content.
  • Updated menu popover dismissal and window binding.
  • Release and CI compatibility checks for macOS 14 and 15 artifacts.

Confidence Score: 4/5

The app lifecycle change looks contained, but the new compatibility gate can miss broken embedded binaries.

  • The AppKit menu-bar ownership path has clear start, stop, and dismissal flow.
  • The verifier can pass a bundle with missing embedded x86_64 slices.
  • The verifier can pass a bundle with FoundationModels strong-linked from an embedded binary.

scripts/verify_macos_compatibility.py

Important Files Changed

Filename Overview
Cotabby/App/Core/CotabbyApp.swift Replaces the SwiftUI app entry point with an AppKit NSApplication main.
Cotabby/App/Core/AppDelegate.swift Adds delegate-owned menu-bar startup, shutdown, and compatibility smoke-test handling.
Cotabby/Services/UI/MenuBarController.swift Adds AppKit status item and popover ownership with Combine-driven visibility and label updates.
Cotabby/UI/MenuBarView.swift Routes popover dismissal through an injected AppKit controller callback.
scripts/verify_macos_compatibility.py Adds release-bundle compatibility checks, but embedded Mach-O slice and weak-link coverage is incomplete.
.github/workflows/macos-compatibility.yml Adds CI that builds and launches a shared compatibility artifact on macOS 14 and 15.
.github/workflows/release.yml Fixes the archive command shape and adds the compatibility verifier to the release flow.

Fix All in Codex Fix All in Claude Code

Reviews (1): Last reviewed commit: "Fix launch compatibility on macOS 14 and..." | Re-trigger Greptile

Greptile also left 2 inline comments on this PR.

Comment on lines +104 to +109
main_architectures = architectures(main_binary)
if require_universal and not {"arm64", "x86_64"}.issubset(main_architectures):
raise RuntimeError(
"Release executable must contain arm64 and x86_64; found "
+ ", ".join(main_architectures)
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Embedded Slices Go Unchecked

When the main Cotabby executable is universal but an embedded framework or helper is arm64-only, this verifier still passes because --require-universal is only applied to main_binary. The x86_64 app slice can then fail at launch when dyld loads the missing dependency on an Intel or Rosetta path.

Fix in Codex Fix in Claude Code

Comment on lines +124 to +130
for architecture in main_architectures:
for command in foundation_models_load_commands(main_binary, architecture):
if command != "LC_LOAD_WEAK_DYLIB":
raise RuntimeError(
"FoundationModels must be weak-linked for macOS 14: "
f"{architecture} uses {command}"
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Strong Links Hide In Frameworks

The FoundationModels weak-link check only inspects the main executable. If any bundled Mach-O under Contents/Frameworks strong-links FoundationModels.framework, the release gate passes, but macOS 14 can still abort while loading that embedded binary before the runtime availability fallback runs.

Fix in Codex Fix in Claude Code

@FuJacob FuJacob merged commit 41323ac into main Jul 11, 2026
8 checks passed
@FuJacob FuJacob deleted the codex/fix-macos-14-launch-compat branch July 11, 2026 00:47
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.

[Bug] Doesnt' start

1 participant