Skip to content

Fix split-time terminal config inheritance crash - #1927

Closed
jorgitin02 wants to merge 5 commits into
manaflow-ai:mainfrom
jorgitin02:issue-1870-split-crash
Closed

jorgitin02 wants to merge 5 commits into
manaflow-ai:mainfrom
jorgitin02:issue-1870-split-crash

Conversation

@jorgitin02

@jorgitin02 jorgitin02 commented Mar 21, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • stop probing live Ghostty runtime font state while building split/new-workspace inheritance config
  • prefer remembered inheritance font points when carrying zoom across split creation
  • add inheritance coverage around live-source split zoom preservation

Fixes #1870.

Test Plan

  • xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux-unit -destination 'platform=macOS' -derivedDataPath /tmp/cmux-issue-1870-green-final -only-testing:cmuxTests/WorkspaceTerminalZoomInheritanceTests -only-testing:cmuxTests/WorkspaceTerminalConfigInheritanceSelectionTests test
  • manual tagged split pass on arm64 host via ./scripts/reload.sh --tag issue-1870-repro3, then View > Split Right, Split Right, Split Down; debug log showed split.shortcut, split.didSplit, split.created, and surface.attach.create.done

Notes

  • I could not deterministically reproduce the original crash locally because this host is arm64 on macOS 26.3.1, while the report was Intel on macOS 26.2.
  • The added tests cover the inheritance behavior on this host, but they did not produce a red pre-fix commit here, so this PR should be reviewed as a root-cause fix plus behavioral coverage rather than a proven local red/green repro.

Summary by cubic

Fixes the split-time crash (#1870) and stale zoom inheritance for splits and new workspaces. Inheritance now uses the source’s inherited config, falling back to the live zoom when font_size is unset, then to remembered zoom.

  • Bug Fixes
    • cmuxInheritedSurfaceConfig no longer probes runtime font size; added a debug-only override for tests.
    • For splits and new workspaces, prefer the source’s live zoom when inherited font_size is missing; otherwise use remembered zoom. Added regression tests for crash coverage, no-refocus, stale-remembered, and inherited-font-size-unset scenarios.

Written for commit 7c61480. Summary will update on new commits.

Summary by CodeRabbit

  • Bug Fixes

    • Terminal font-size/zoom inheritance when creating new terminal splits now reliably preserves the most-recent live zoom, applies a remembered font-size fallback when needed, and no longer uses stale remembered zoom values.
  • Tests

    • Added regression tests and windowed test helpers validating terminal zoom inheritance across split creation: live-source, unfocused-source, and stale-source scenarios.

@vercel

vercel Bot commented Mar 21, 2026

Copy link
Copy Markdown

@jorgitin02 is attempting to deploy a commit to the Manaflow Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Mar 21, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

TabManager now materializes CMUX-inherited Ghostty configs into a mutable config and applies a "last remembered" font-size fallback when available; Workspace removes runtime-derived font-size overrides and simplifies inheritance resolution. New tests validate remembered-zoom behavior and stale-zoom handling for new terminal splits.

Changes

Cohort / File(s) Summary
TabManager changes
Sources/TabManager.swift
CMUX branch now copies cmuxInheritedSurfaceConfig(...) into a mutable config, conditionally overrides config.font_size with snapshot.selectedWorkspace?.lastRememberedTerminalFontPointsForConfigInheritance() when > 0, then returns the modified config.
Workspace font-resolution & inheritance
Sources/Workspace.swift
cmuxInheritedSurfaceConfig no longer forces runtime font_size into the returned config; resolvedTerminalInheritanceFontPoints removed the sourceSurface parameter and runtime-derived fallback logic; lineage tracking now updates lastTerminalConfigInheritancePanelId directly and drops rememberTerminalConfigInheritanceSource usage.
Tests — Workspace terminal zoom inheritance
cmuxTests/WorkspaceUnitTests.swift
Added @MainActor test class WorkspaceTerminalZoomInheritanceTests with window/surface bootstrapping helpers and three regression tests exercising remembered-zoom preservation and stale-zoom handling when creating new splits.
Tests — TabManager workspace inheritance
cmuxTests/TabManagerUnitTests.swift
Added helpers to attach a TerminalPanel into an NSWindow and wait for surface readiness; added testNewWorkspaceUsesLatestLiveZoomWhenRememberedZoomIsStale asserting new workspace picks up latest live zoom over stale remembered value.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant User as User
    participant TabMgr as TabManager
    participant Snapshot as Snapshot
    participant Workspace as Workspace
    participant Panel as TerminalPanel

    User->>TabMgr: request new split
    TabMgr->>Snapshot: read selectedWorkspace & rememberedFontPoints
    Snapshot-->>TabMgr: rememberedFontPoints (maybe nil)
    TabMgr->>Workspace: request cmux-inherited config
    Workspace-->>TabMgr: inheritedConfig
    TabMgr->>TabMgr: copy inheritedConfig -> config (mutable)
    alt rememberedFontPoints > 0
        TabMgr->>TabMgr: set config.font_size = rememberedFontPoints
    end
    TabMgr->>Panel: create new terminal with config
    Panel-->>User: new split ready
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 I hopped through configs, nibbling font-size crumbs,
I carried remembered zoom, till the new split hums.
Stale numbers tossed, fresh pixels take the throne,
My whiskers twitch — a split that feels like home. 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 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 (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix split-time terminal config inheritance crash' clearly and concisely summarizes the main change in the changeset, which addresses a crash occurring during split creation.
Linked Issues check ✅ Passed The PR successfully addresses all objectives from issue #1870: it prevents the EXC_BAD_ACCESS crash by removing unsafe reads of live surface/runtime state, ensures safe inheritance using inherited config and cached font points, and adds comprehensive regression tests for split and new-workspace inheritance scenarios.
Out of Scope Changes check ✅ Passed All code changes are directly scoped to fixing the split-time terminal config inheritance crash and improving related behavior: TabManager font-size fallback logic, Workspace inheritance method signature and logic, and comprehensive test coverage for inheritance scenarios.
Description check ✅ Passed The PR description covers the main change (stop probing live runtime font state, prefer remembered inheritance), provides a detailed test plan with specific commands, and includes notes about limitations. The description aligns well with the code changes shown in the raw_summary.

✏️ 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.

@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: ed5caa9301

ℹ️ 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/Workspace.swift Outdated
@greptile-apps

greptile-apps Bot commented Mar 21, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a split-time terminal config inheritance crash (issue #1870) by removing the live Ghostty runtime font-size probe (cmuxCurrentSurfaceFontSizePoints) from the split-creation and new-workspace-creation code paths, which was crashing on Intel macOS 26.2. Zoom preservation across splits is maintained by preferring the workspace's last-remembered font points over what ghostty_surface_inherited_config reports, since rememberTerminalConfigInheritanceSource continues to update the cache on focus changes.

  • Workspace.swift — Strips the runtime font probe from both cmuxInheritedSurfaceConfig (now just wraps ghostty_surface_inherited_config) and resolvedTerminalInheritanceFontPoints (now returns nil instead of falling back to the live query). The divergence-detection logic for mid-session zoom changes on a descendant terminal is also removed, which is a known trade-off: zoom changes are now only detected at focus time, not at split-creation time.
  • TabManager.swift — Adds a remembered-font-points override inside the live-surface branch of inheritedTerminalConfigForNewWorkspace, compensating for the removed runtime probe.
  • cmuxTests/WorkspaceUnitTests.swift — Adds two integration tests (WorkspaceTerminalZoomInheritanceTests) covering zoom preservation with and without an explicit pre-split focusPanel. The author acknowledges the tests did not go red on the pre-fix commit on the test host (arm64 macOS 26.3.1), so they provide behavioral coverage rather than a proven local red/green regression guard.

Process note (CLAUDE.md regression test commit policy): The CLAUDE.md style guide requires a two-commit structure for bug-fix regression tests (commit 1: failing test only; commit 2: fix), so that CI demonstrates the test catches the bug. The author explicitly notes this structure was not followed here because the tests did not reproduce the crash locally. This PR should be merged with awareness that the tests serve as behavioral coverage on the current host, but the red/green commit sequence that CLAUDE.md requires for confidence in regression tests is absent.

Confidence Score: 4/5

  • This PR is safe to merge; the root-cause fix is sound and the only remaining items are a minor naming inconsistency and a log string cleanup.
  • The crash-prevention mechanism (removing live runtime font probes from the split-creation path) is clearly motivated and correctly implemented. The zoom-preservation fallback in inheritedTerminalConfigForNewWorkspace is logically consistent with the rest of the inheritance model. The main gap is that the added tests did not go red before the fix on the author's machine, so they function as behavioral coverage rather than proven regression guards per the CLAUDE.md policy — but this is an acknowledged constraint, not a code defect. Two P2 style comments remain (misleading "runtime=nil" log token and fallbackFontPoints naming in the live-surface override path) that can be addressed in a follow-up or this PR without risk.
  • No files require special attention; Sources/TabManager.swift has the minor naming nit that is worth cleaning up but is not a blocker.

Important Files Changed

Filename Overview
Sources/Workspace.swift Removes live cmuxCurrentSurfaceFontSizePoints probes from cmuxInheritedSurfaceConfig and resolvedTerminalInheritanceFontPoints; replaces the rememberTerminalConfigInheritanceSource call in inheritedTerminalConfig with a direct lastTerminalConfigInheritancePanelId assignment. The resulting code is simpler and avoids the crash-prone runtime font query on Intel macOS, at the cost of no longer detecting mid-session zoom divergence in the rooted-lineage path.
Sources/TabManager.swift Adds a remembered-font-points override to inheritedTerminalConfigForNewWorkspace when a live source surface exists, compensating for the removed runtime probe in cmuxInheritedSurfaceConfig. The variable naming (fallbackFontPoints) is mildly misleading in the live-surface branch where it acts as an override rather than a fallback.
cmuxTests/WorkspaceUnitTests.swift Adds two new WorkspaceTerminalZoomInheritanceTests integration tests covering zoom preservation across split creation with and without an explicit refocus of the source panel. Good behavioral coverage; author explicitly acknowledges the tests did not go red on the pre-fix commit on the test host (arm64 macOS 26.3.1), so they serve as coverage rather than proven regression guards for the original Intel crash.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["Split / New-workspace created"] --> B{"Live source surface\navailable?"}

    B -->|Yes| C["cmuxInheritedSurfaceConfig\n(ghostty_surface_inherited_config only;\nno runtime font probe)"]
    C --> D{"rememberedFontPoints\n> 0?"}
    D -->|Yes| E["Override config.font_size\nwith remembered value"]
    D -->|No| F["Keep ghostty-inherited font_size"]
    E --> G["Return config"]
    F --> G

    B -->|No – split path| H["resolvedTerminalInheritanceFontPoints"]
    H --> I{"terminalInheritanceFontPointsByPanelId\n(rooted) > 0?"}
    I -->|Yes| J["Use rooted (cached) points"]
    I -->|No| K{"inheritedConfig.font_size\n> 0?"}
    K -->|Yes| L["Use inheritedConfig.font_size"]
    K -->|No| M["Return nil"]
    J --> N["config.font_size = rootedFontPoints\nupdate panel cache"]
    L --> N
    M --> O{"lastTerminalConfigInheritanceFontPoints\nset?"}
    O -->|Yes| P["Bare config with\nlast-known font size"]
    O -->|No| Q["Return nil\n(no inheritance)"]

    G --> R["New terminal created\nwith inherited config"]
    N --> R
    P --> R
Loading

Last reviewed commit: "fix: avoid split-tim..."

Comment thread Sources/Workspace.swift
Comment thread Sources/TabManager.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

🤖 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/WorkspaceUnitTests.swift`:
- Around line 1103-1125: The readiness check can miss a notification because it
happens before the observer is registered; to fix, register the
NotificationCenter observer for .terminalSurfaceDidBecomeReady on panel.surface
first (using the observer variable and testCase.expectation(description:
"terminal surface ready \(panel.id)")), then immediately check
panel.surface.surface and, if already non-nil, fulfill the expectation
(ready.fulfill()), otherwise wait(for: [ready], timeout: 5.0) and finally call
drainMainQueue(); ensure the defer block still removes the observer if set.

In `@Sources/Workspace.swift`:
- Around line 6568-6578: The rooted font cache
(terminalInheritanceFontPointsByPanelId) can be stale after a zoom; update the
logic so splits see the live runtime font: either invoke
rememberTerminalConfigInheritanceSource() immediately after successful
zoom/zoom-binding code paths (so panelWasSelected isn't the only place that sets
a rooted value), or change
resolvedTerminalInheritanceFontPoints(for:inheritedConfig:) to compare the
cached rooted value against the current live runtime font (queried via
inheritedTerminalConfig() or the panel's live config) and return the
newer/non-zero value; also ensure when selecting the winner you update
lastTerminalConfigInheritanceFontPoints consistently so future splits aren't
poisoned.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ffbdca45-34ce-42f7-8b6d-b776140fa619

📥 Commits

Reviewing files that changed from the base of the PR and between 76c1e63 and ed5caa9.

📒 Files selected for processing (3)
  • Sources/TabManager.swift
  • Sources/Workspace.swift
  • cmuxTests/WorkspaceUnitTests.swift

Comment thread cmuxTests/WorkspaceUnitTests.swift Outdated
Comment thread Sources/Workspace.swift

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

2 issues found across 3 files

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="Sources/Workspace.swift">

<violation number="1" location="Sources/Workspace.swift:6693">
P2: Split-created terminals may inherit stale zoom values when live terminal zoom changed after lineage was last recorded. The removed runtime font sampling in `cmuxInheritedSurfaceConfig()` and divergence detection in `resolvedTerminalInheritanceFontPoints()` means splits no longer get current visible zoom if the user zooms without a focus transition.</violation>
</file>

<file name="cmuxTests/WorkspaceUnitTests.swift">

<violation number="1" location="cmuxTests/WorkspaceUnitTests.swift:1103">
P2: Race condition in test helper: check-then-subscribe pattern can miss notification if surface becomes ready during the gap between surface nil-check and observer registration</violation>
</file>

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

Comment thread Sources/Workspace.swift
Comment thread cmuxTests/WorkspaceUnitTests.swift Outdated

Copy link
Copy Markdown
Contributor Author

Follow-up pushed in 86224014 to address the two actionable review findings reported by CodeRabbit and the matching inline findings identified by cubic.

Changes:

  • fixed the stale split-inheritance zoom case when a remembered rooted value was older than the live inherited font size
  • fixed the WorkspaceTerminalZoomInheritanceTests.attachAndWaitForRuntimeSurface readiness race by subscribing before checking readiness
  • added a targeted regression for the stale-rooted-cache path

Verification:

  • xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux-unit -destination 'platform=macOS' build

@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: 86224014c5

ℹ️ 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/TabManager.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/Workspace.swift (1)

6568-6582: ⚠️ Potential issue | 🟠 Major

Prefer the cached lineage font when both values exist.

Lines 6573-6575 let inheritedConfig.font_size override terminalInheritanceFontPointsByPanelId whenever they disagree. That flips the intended “prefer remembered inheritance font points” rule and can still regress zoom → split if Ghostty’s inherited config is carrying the pre-zoom size. inheritedConfig.font_size should only fill the gap when the panel has no remembered value.

🔧 Suggested fix
     private func resolvedTerminalInheritanceFontPoints(
         for terminalPanel: TerminalPanel,
         inheritedConfig: ghostty_surface_config_s
     ) -> Float? {
         if let rooted = terminalInheritanceFontPointsByPanelId[terminalPanel.id], rooted > 0 {
-            if inheritedConfig.font_size > 0,
-               abs(inheritedConfig.font_size - rooted) > 0.05 {
-                return inheritedConfig.font_size
-            }
             return rooted
         }
         if inheritedConfig.font_size > 0 {
             return inheritedConfig.font_size
         }
         return nil
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Sources/Workspace.swift` around lines 6568 - 6582, The function
resolvedTerminalInheritanceFontPoints currently lets inheritedConfig.font_size
override the cached value in terminalInheritanceFontPointsByPanelId when they
differ; change the logic in
resolvedTerminalInheritanceFontPoints(for:inheritedConfig:) so that if a cached
value exists for terminalPanel.id (rooted) and rooted > 0 it is always returned
(regardless of inheritedConfig.font_size), and only when there is no cached
value should you return inheritedConfig.font_size if > 0; keep returning nil
otherwise.
🧹 Nitpick comments (1)
cmuxTests/WorkspaceUnitTests.swift (1)

1128-1128: Consider consolidating drainMainQueue() helpers.

WorkspacePanelGitBranchTests (line 1449) defines a private drainMainQueue(), while this class relies on a presumed global definition. If a shared test-utility version exists, consider using it consistently to avoid duplication and divergent implementations.

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

In `@cmuxTests/WorkspaceUnitTests.swift` at line 1128, The test calls and defines
duplicate drainMainQueue() helpers across tests (this file and
WorkspacePanelGitBranchTests); remove the local private drainMainQueue() from
WorkspacePanelGitBranchTests (or this class if it defines it locally) and
replace all calls with the shared test-utility implementation, or if the shared
helper is internal/private to another test target, move/restore it into a common
test helpers file and adjust access control so both WorkspacePanelGitBranchTests
and this test class call the same consolidated drainMainQueue() function; ensure
you remove the duplicate helper definition and update imports/visibility so all
tests reference the single shared function.
🤖 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/Workspace.swift`:
- Around line 6697-6700: The code updates lastTerminalConfigInheritancePanelId
regardless of config.font_size but only writes
lastTerminalConfigInheritanceFontPoints when font_size > 0, causing inconsistent
snapshots; update the code so that whenever you set
lastTerminalConfigInheritancePanelId you also set or clear
lastTerminalConfigInheritanceFontPoints based on config.font_size (i.e., assign
the positive point value when config.font_size > 0, otherwise explicitly
clear/unset it), keeping lastTerminalConfigInheritancePanelId and
lastTerminalConfigInheritanceFontPoints consistent.

---

Duplicate comments:
In `@Sources/Workspace.swift`:
- Around line 6568-6582: The function resolvedTerminalInheritanceFontPoints
currently lets inheritedConfig.font_size override the cached value in
terminalInheritanceFontPointsByPanelId when they differ; change the logic in
resolvedTerminalInheritanceFontPoints(for:inheritedConfig:) so that if a cached
value exists for terminalPanel.id (rooted) and rooted > 0 it is always returned
(regardless of inheritedConfig.font_size), and only when there is no cached
value should you return inheritedConfig.font_size if > 0; keep returning nil
otherwise.

---

Nitpick comments:
In `@cmuxTests/WorkspaceUnitTests.swift`:
- Line 1128: The test calls and defines duplicate drainMainQueue() helpers
across tests (this file and WorkspacePanelGitBranchTests); remove the local
private drainMainQueue() from WorkspacePanelGitBranchTests (or this class if it
defines it locally) and replace all calls with the shared test-utility
implementation, or if the shared helper is internal/private to another test
target, move/restore it into a common test helpers file and adjust access
control so both WorkspacePanelGitBranchTests and this test class call the same
consolidated drainMainQueue() function; ensure you remove the duplicate helper
definition and update imports/visibility so all tests reference the single
shared function.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 64b8f601-4a6a-41a7-89c7-32c57b7719cd

📥 Commits

Reviewing files that changed from the base of the PR and between ed5caa9 and 8622401.

📒 Files selected for processing (2)
  • Sources/Workspace.swift
  • cmuxTests/WorkspaceUnitTests.swift

Comment thread Sources/Workspace.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: 676c573012

ℹ️ 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/Workspace.swift
Comment thread Sources/TabManager.swift
@jorgitin02
jorgitin02 force-pushed the issue-1870-split-crash branch from 676c573 to f3b1fad Compare March 25, 2026 21:30

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

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

7265-7268: ⚠️ Potential issue | 🟠 Major

Keep the remembered source/font snapshot in sync.

Line 7265 always advances lastTerminalConfigInheritancePanelId, but Line 7266 only updates lastTerminalConfigInheritanceFontPoints when config.font_size > 0. If this source resolves to an unset font size, later fallback paths can still reuse stale points from an older panel instead of leaving font_size unset.

🔧 Suggested fix
             lastTerminalConfigInheritancePanelId = terminalPanel.id
-            if config.font_size > 0 {
-                lastTerminalConfigInheritanceFontPoints = config.font_size
-            }
+            lastTerminalConfigInheritanceFontPoints =
+                config.font_size > 0 ? config.font_size : nil
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Sources/Workspace.swift` around lines 7265 - 7268, When advancing the
remembered terminal source snapshot, keep the panel id and font snapshot in
sync: currently lastTerminalConfigInheritancePanelId is updated unconditionally
while lastTerminalConfigInheritanceFontPoints is only set when config.font_size
> 0, which can leave stale points behind; modify the update so that whenever
lastTerminalConfigInheritancePanelId is assigned you also explicitly clear or
set lastTerminalConfigInheritanceFontPoints based on config.font_size (e.g. set
to the new points when >0, otherwise clear it) so the remembered snapshot
reflects an unset font size correctly (references:
lastTerminalConfigInheritancePanelId, lastTerminalConfigInheritanceFontPoints,
config.font_size).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@Sources/Workspace.swift`:
- Around line 7265-7268: When advancing the remembered terminal source snapshot,
keep the panel id and font snapshot in sync: currently
lastTerminalConfigInheritancePanelId is updated unconditionally while
lastTerminalConfigInheritanceFontPoints is only set when config.font_size > 0,
which can leave stale points behind; modify the update so that whenever
lastTerminalConfigInheritancePanelId is assigned you also explicitly clear or
set lastTerminalConfigInheritanceFontPoints based on config.font_size (e.g. set
to the new points when >0, otherwise clear it) so the remembered snapshot
reflects an unset font size correctly (references:
lastTerminalConfigInheritancePanelId, lastTerminalConfigInheritanceFontPoints,
config.font_size).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5b77aa68-2149-4117-b15f-1c449de02619

📥 Commits

Reviewing files that changed from the base of the PR and between 676c573 and f3b1fad.

📒 Files selected for processing (4)
  • Sources/TabManager.swift
  • Sources/Workspace.swift
  • cmuxTests/TabManagerUnitTests.swift
  • cmuxTests/WorkspaceUnitTests.swift
✅ Files skipped from review due to trivial changes (1)
  • Sources/TabManager.swift
🚧 Files skipped from review as they are similar to previous changes (1)
  • cmuxTests/WorkspaceUnitTests.swift

@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 4 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="Sources/Workspace.swift">

<violation number="1" location="Sources/Workspace.swift:7154">
P1: Split/new terminal inheritance now re-enters unsafe runtime font probing (`cmuxCurrentSurfaceFontSizePoints`), which can dereference stale unretained CTFont pointers and reintroduce crash risk.</violation>
</file>

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

Comment thread Sources/Workspace.swift
return rooted
if terminalPanel.surface.hasLiveSurface,
let sourceSurface = terminalPanel.surface.surface,
let runtimePoints = cmuxCurrentSurfaceFontSizePoints(sourceSurface) {

@cubic-dev-ai cubic-dev-ai Bot Mar 25, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1: Split/new terminal inheritance now re-enters unsafe runtime font probing (cmuxCurrentSurfaceFontSizePoints), which can dereference stale unretained CTFont pointers and reintroduce crash risk.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At Sources/Workspace.swift, line 7154:

<comment>Split/new terminal inheritance now re-enters unsafe runtime font probing (`cmuxCurrentSurfaceFontSizePoints`), which can dereference stale unretained CTFont pointers and reintroduce crash risk.</comment>

<file context>
@@ -7135,16 +7149,17 @@ final class Workspace: Identifiable, ObservableObject {
-            return rooted
+        if terminalPanel.surface.hasLiveSurface,
+           let sourceSurface = terminalPanel.surface.surface,
+           let runtimePoints = cmuxCurrentSurfaceFontSizePoints(sourceSurface) {
+            return runtimePoints
         }
</file context>
Fix with Cubic

@jorgitin02

Copy link
Copy Markdown
Contributor Author

Pushed follow-up in 76394577 to address the remaining inheritance-path issues.

Changes:

  • removed split inheritance runtime font probing from Workspace so the crash-prone quicklook path is no longer consulted in this flow
  • kept the remembered inheritance source panel/font snapshot in sync, including clearing stale remembered font points when none are available

Verification:

  • xcodebuild -project /Users/jorgitin/projects/cmux/GhosttyTabs.xcodeproj -scheme cmux-unit -destination 'platform=macOS' build

@jorgitin02

Copy link
Copy Markdown
Contributor Author

Branch updated again after rebasing onto the latest remote tip; the fix is now at 20875c35.

This keeps the split inheritance path off the unsafe runtime font probe and keeps the remembered inheritance panel/font snapshot synchronized.

Verification:

  • xcodebuild -project /Users/jorgitin/projects/cmux/GhosttyTabs.xcodeproj -scheme cmux-unit -destination 'platform=macOS' build

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.

cmux split screen will crash

1 participant