Skip to content

Fix TextBox unchanged binding writes#5345

Open
lawrencecchen wants to merge 4 commits into
mainfrom
task-sentry-terminalpanel-access-conflict
Open

Fix TextBox unchanged binding writes#5345
lawrencecchen wants to merge 4 commits into
mainfrom
task-sentry-terminalpanel-access-conflict

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Avoid no-op TextBox SwiftUI binding writes during AppKit text sync.
  • Add a focused regression test that fails on the test-only commit and passes after the coordinator skips unchanged writes.

Root cause

Sentry issue CMUXTERM-MACOS-MRP points at TerminalPanel.textBoxContent.setter in production com.cmuxterm.app@0.64.12+92. The latest event maps to TextBoxInputView.dismantleNSView -> TerminalPanel.preserveTextBoxContentForUnmount; in v0.64.12, that teardown path wrote textBoxContent, which published synchronously while SwiftUI was destroying the representable. Current main already avoids the teardown write. This PR further reduces the same access-conflict risk by skipping unchanged TextBox binding writes from normal AppKit content sync.

Testing

  • ./scripts/lint-pbxproj-test-wiring.sh passed.
  • AWS cmux-unit focused run attempted with -only-testing:cmuxTests/AppDelegateShortcutRoutingTests/testTextBoxContentSyncSkipsUnchangedSwiftUIBindings; runner failed before executing tests because /tmp filled during app target compile (errno=28, Macintosh HD is out of space).

Issues


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Note

Low Risk
Localized TextBox coordinator sync logic with a focused unit test; no auth, data, or broad architectural changes.

Overview
TextBox AppKit→SwiftUI sync now updates text, attachments, and hasPendingAttachmentUpload only when each field actually changes, and calls onContentChanged only when something did change. Attachment equality no longer relies on ID lists alone: a new attachmentsDiffer helper compares display/submission metadata, URLs, cleanup flags, and thumbnail identity (=== for NSImage).

A TextBoxContentSyncTests regression test asserts that a no-op textDidChange (same plain text, no attachments) performs zero binding writes and does not fire onContentChanged, guarding against redundant SwiftUI updates during representable teardown/sync (related to Sentry CMUXTERM-MACOS-MRP).

Reviewed by Cursor Bugbot for commit 2e58388. Bugbot is set up for automated code reviews on this repo. Configure here.


Summary by cubic

Skip unchanged SwiftUI binding writes in TextBoxInputView during AppKit→SwiftUI sync and tighten attachment change detection to avoid missed updates. Reduces redundant updates and mitigates Sentry CMUXTERM-MACOS-MRP access-conflict risk.

  • Bug Fixes
    • Update text, attachments, and hasPendingAttachmentUpload only when values differ; call onContentChanged only on real changes.
    • Use deep attachment comparison (id, displayName, submission text/path, localURL, cleanup flag, thumbnail identity) to detect true diffs; added Swift Testing TextBoxContentSyncTests.contentSyncSkipsUnchangedSwiftUIBindings to verify zero writes and no onContentChanged on same-value sync.

Written for commit 2e58388. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Performance

    • Optimized text-input sync so text, attachments, and pending-upload state are tracked independently and only update the UI when their specific content changes, reducing needless UI work.
  • Tests

    • Added a test validating that SwiftUI bindings and change notifications are not triggered when content is unchanged, preventing unnecessary updates.

@vercel

vercel Bot commented Jun 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Jun 5, 2026 5:34am
cmux-staging Building Building Preview, Comment Jun 5, 2026 5:34am

@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR refactors TextBoxInputView.Coordinator to detect changes separately for text, attachments, and pending-upload placeholder state and only update the corresponding SwiftUI bindings when that component changed. It adds attachment equality helpers and a regression test that ensures unchanged content does not trigger binding writes; the test is registered in the Xcode project.

Changes

Conditional TextBox binding updates

Layer / File(s) Summary
Conditional binding synchronization
Sources/TextBoxInput.swift
Per-field change detection flags (didChangeText, didChangeAttachments, didChangePendingUpload) replace a combined expression; each binding updates only when its component changed, parent.onContentChanged() still fires if any component changes. Attachment diff helpers attachmentsDiffer and sameThumbnail added.
Test validation and project integration
cmuxTests/TextBoxContentSyncTests.swift, cmux.xcodeproj/project.pbxproj
Adds TextBoxContentSyncTests asserting that unchanged content does not invoke SwiftUI binding setters or onContentChanged. Registers the test file in the project build settings.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • manaflow-ai/cmux#5317: Adjusts TextBoxInput synchronization to avoid triggering unwanted updates when content has not meaningfully changed via per-component "did change" gating.

Suggested reviewers

  • jesstelford

Poem

🐰 I hop through code with careful paws,
checking text, attachments, and upload cause.
Only sync what’s new, leave the rest be —
a tiny test confirms the change for me. ✨


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Cmux Full Internationalization ❌ Error PR adds production user-facing strings with machine-generated placeholder translations marked "needs_review" for 15+ locales instead of proper translations. Provide complete translations for all supported locales (ar, bs, da, de, es, fr, it, km, ko, nb, pl, pt-BR, ru, th, tr, uk, zh-Hans, zh-Hant) in Localizable.xcstrings for the 6 new textbox keys.
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 (16 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: skipping unnecessary SwiftUI binding writes in TextBox during unchanged content sync.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Cmux Swift Actor Isolation ✅ Passed New methods in Coordinator (UI coordinator in NSViewRepresentable) refactor existing patterns without introducing actor isolation or Sendable violations.
Cmux Swift Blocking Runtime ✅ Passed No blocking/timing patterns found in production code changes. Changes are deterministic conditional binding updates and comparison helpers with no semaphores, sleeps, polling, or manual locks.
Cmux No Hacky Sleeps ✅ Passed PR is entirely Swift code; check scope excludes Swift (delegated to "cmux Swift blocking runtime"). No TypeScript/JavaScript/shell/build-script changes present.
Cmux Algorithmic Complexity ✅ Passed Single-pass O(n) attachment comparison on text input hot path. Naturally bounded to single digits, no nested scans or batch rescans.
Cmux Swift Concurrency ✅ Passed PR introduces only pure synchronous state-sync logic within AppKit delegate boundaries. No new DispatchQueue.global, Combine, fire-and-forget Tasks, or completion-handler APIs detected.
Cmux Swift @Concurrent ✅ Passed No async functions introduced or modified. All changes are synchronous (publishTextViewContent, attachmentsDiffer, sameThumbnail, test). @concurrent annotation rule not applicable.
Cmux Swift File And Package Boundaries ✅ Passed PR adds only +40 lines to existing TextBoxInput.swift file (well under 250-line threshold), new test file is small, and changes are focused bug fix to AppKit/SwiftUI binding sync logic.
Cmux Swift Logging ✅ Passed PR contains no logging violations. Production changes to TextBoxInput.swift add no print, debugPrint, dump, NSLog, or Logger statements. Test file is exempt from logging rules.
Cmux User-Facing Error Privacy ✅ Passed No user-facing error messages, alerts, or sensitive content introduced. Changes are internal methods, test code, and build configuration—all exempt from user-facing error privacy check.
Cmux Swiftui State Layout ✅ Passed AppKit bridge Coordinator event handlers skip unnecessary binding writes; no new @Published/@StateObject/@observable, GeometryReader, or render-time mutations. Compliant with rules.
Cmux Architecture Rethink ✅ Passed Small correctness fix with clear owner and invariant. No timing, polling, locks, or split lifecycle ownership. Allowed under "small local correctness fixes" and "platform bridge code" categories.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR modifies TextBoxInputView (NSViewRepresentable embedded view) binding sync and adds test-only fixtures; no standalone windows, panels, or WindowGroups are introduced or materially changed.
Description check ✅ Passed The PR description comprehensively covers the Summary and Testing sections with technical context, root cause analysis, and test results, but lacks a Demo Video section and has an incomplete Checklist.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch task-sentry-terminalpanel-access-conflict

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: e200cae796

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

XCTAssertEqual(pendingWriteCount, 0)
}

func testTextBoxContentSyncSkipsUnchangedSwiftUIBindings() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Split the regression test into a test-only commit

This commit adds testTextBoxContentSyncSkipsUnchangedSwiftUIBindings in the same commit as the production fix, but the repo's AGENTS.md regression-test policy requires bug-fix regressions to be added as a failing test-only commit first and the fix second so CI proves the test catches the bug. Because this test is specifically covering the TextBox binding-write regression fixed here, keeping it combined removes that red/green proof; please split the test addition into its own preceding commit.

Useful? React with 👍 / 👎.

@greptile-apps

greptile-apps Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR makes the TextBoxInputView.Coordinator.publishTextViewContent path skip SwiftUI binding writes when text, attachments, and hasPendingAttachmentUpload have not changed, and fires onContentChanged only when at least one value actually differs. A companion Swift Testing regression test in a new, properly-scoped TextBoxContentSyncTests.swift file verifies that driving textDidChange with already-current content produces zero binding writes and no onContentChanged call.

  • attachmentsDiffer performs a full field-by-field comparison across all TextBoxAttachment properties (id, displayName, submissionText, submissionPath, localURL, cleanupLocalURLWhenDisposed, thumbnail via object-identity), addressing the previous-iteration concern that only .id was used as the change signal.
  • The test file is correctly placed in a dedicated class rather than appended to the unrelated AppDelegateShortcutRoutingTests, resolving the earlier file-boundary thread.

Confidence Score: 5/5

The change is narrowly scoped to the AppKit to SwiftUI sync path and is conservative: it only skips writes when values provably have not changed, so the worst-case outcome of any undetected equality mismatch is an occasional missed no-op reduction rather than dropped real updates.

All TextBoxAttachment fields are covered by attachmentsDiffer; thumbnail identity check is safe because the field is an immutable let on a value-type struct. The regression test correctly exercises the no-op path in a dedicated file. Both concerns from previous review threads are resolved in this iteration.

No files require special attention.

Important Files Changed

Filename Overview
Sources/TextBoxInput.swift Adds per-field equality guards before each SwiftUI binding write in publishTextViewContent, and introduces attachmentsDiffer with a full field-by-field comparison including all TextBoxAttachment properties and thumbnail object-identity check, correctly avoiding no-op binding mutations on unchanged content.
cmuxTests/TextBoxContentSyncTests.swift New 79-line Swift Testing file that regression-tests the no-op skip: drives textDidChange with unchanged content and asserts zero binding writes and zero onContentChanged invocations. Properly scoped in a dedicated file instead of being appended to the oversized AppDelegateShortcutRoutingTests.
cmux.xcodeproj/project.pbxproj Wires TextBoxContentSyncTests.swift into the cmuxTests target with both a PBXBuildFile entry and a PBXFileReference; placement in the file group and Sources phase is consistent with nearby test files.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[textDidChange or markedText sync] --> B[publishTextViewContent]
    B --> C{text changed?}
    C -- yes --> D[write parent.text]
    C -- no --> E[skip text write]
    B --> F{attachmentsDiffer?}
    F -- yes --> G[write parent.attachments]
    F -- no --> H[skip attachments write]
    B --> I{pendingUpload changed?}
    I -- yes --> J[write parent.hasPendingAttachmentUpload]
    I -- no --> K[skip pendingUpload write]
    D --> L{any field changed?}
    E --> L
    G --> L
    H --> L
    J --> L
    K --> L
    L -- yes --> M[onContentChanged]
    L -- no --> N[no-op, SwiftUI binding untouched]
Loading

Reviews (4): Last reviewed commit: "fix: skip unchanged TextBox binding writ..." | Re-trigger Greptile

Comment thread Sources/TextBoxInput.swift Outdated
parent.attachments = nextAttachments
parent.hasPendingAttachmentUpload = nextHasPendingAttachmentUpload
let didChangeText = parent.text != nextText
let didChangeAttachments = parent.attachments.map(\.id) != nextAttachments.map(\.id)

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 The attachment write is now gated on the same ID-only comparison that was previously used only to decide whether to call onContentChanged. The old code always wrote nextAttachments unconditionally, ensuring that any change to attachment objects (including non-id fields such as upload state, thumbnail, or submission path) was pushed to the SwiftUI binding. With this guard, if two successive AppKit syncs produce arrays whose .id sequences are identical but whose attachment objects differ in other properties, the binding update is silently skipped and SwiftUI retains stale attachment data.

Suggested change
let didChangeAttachments = parent.attachments.map(\.id) != nextAttachments.map(\.id)
let didChangeAttachments = parent.attachments != nextAttachments

Comment on lines +10101 to +10166
func testTextBoxContentSyncSkipsUnchangedSwiftUIBindings() {
var text = "same"
var attachments: [TextBoxAttachment] = []
var height: CGFloat = TextBoxLayout.minimumTextHeight
var hasPendingAttachmentUpload = false
var textWriteCount = 0
var attachmentWriteCount = 0
var pendingWriteCount = 0
var contentChangeCount = 0

let inputView = TextBoxInputView(
text: Binding(
get: { text },
set: { newValue in
textWriteCount += 1
text = newValue
}
),
attachments: Binding(
get: { attachments },
set: { newValue in
attachmentWriteCount += 1
attachments = newValue
}
),
textViewHeight: Binding(get: { height }, set: { height = $0 }),
hasPendingAttachmentUpload: Binding(
get: { hasPendingAttachmentUpload },
set: { newValue in
pendingWriteCount += 1
hasPendingAttachmentUpload = newValue
}
),
font: NSFont.systemFont(ofSize: 14),
backgroundColor: .textBackgroundColor,
foregroundColor: .labelColor,
terminalTitle: "codex",
completionRootDirectory: nil,
onSubmit: {},
onEscape: {},
onFocusTextBox: {},
onToggleFocus: {},
onForwardText: { _, _ in },
onForwardKey: { _ in },
onForwardControl: { _ in },
onPaste: { _, _ in false },
onInsertFileURLs: { _, _ in false },
onChooseFiles: {},
onContentChanged: { contentChangeCount += 1 },
onTextViewCreated: { _ in },
onTextViewMovedToWindow: { _ in },
onTextViewDismantled: { _ in }
)
let coordinator = TextBoxInputView.Coordinator(parent: inputView)
let textView = TextBoxInputTextView(frame: NSRect(x: 0, y: 0, width: 320, height: 30))
textView.font = NSFont.systemFont(ofSize: 14)
textView.textColor = .labelColor
textView.string = "same"

coordinator.textDidChange(Notification(name: NSText.didChangeNotification, object: textView))

XCTAssertEqual(textWriteCount, 0)
XCTAssertEqual(attachmentWriteCount, 0)
XCTAssertEqual(pendingWriteCount, 0)
XCTAssertEqual(contentChangeCount, 0)
}

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.

P2 testTextBoxContentSyncSkipsUnchangedSwiftUIBindings tests TextBox binding write-skipping, which has no relation to shortcut routing. AppDelegateShortcutRoutingTests.swift already exceeds 10 000 lines. Appending another unrelated test further worsens the file-sprawl that the cmux-swift-file-package-boundaries rule targets — the existing test class is already well past the 400-line single-responsibility and 800-line hard-stop limits. A TextBoxInputTests class (or an extension to an existing TextBox-focused test file) would scope the coverage correctly.

Rule Used: Flag Swift changes that add too much unrelated res... (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@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 2 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="cmuxTests/AppDelegateShortcutRoutingTests.swift">

<violation number="1" location="cmuxTests/AppDelegateShortcutRoutingTests.swift:10101">
P2: This PR adds another test to `AppDelegateShortcutRoutingTests`, but this suite is marked by team guidance as needing class-level quarantine on GitHub macOS CI due to hangs. Please quarantine/skip the full XCTestCase on GitHub CI before adding more coverage here.

(Based on your team's feedback about quarantining the entire AppDelegateShortcutRoutingTests suite on GitHub macOS CI.) [FEEDBACK_USED]</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread Sources/TextBoxInput.swift Outdated
XCTAssertEqual(pendingWriteCount, 0)
}

func testTextBoxContentSyncSkipsUnchangedSwiftUIBindings() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: This PR adds another test to AppDelegateShortcutRoutingTests, but this suite is marked by team guidance as needing class-level quarantine on GitHub macOS CI due to hangs. Please quarantine/skip the full XCTestCase on GitHub CI before adding more coverage here.

(Based on your team's feedback about quarantining the entire AppDelegateShortcutRoutingTests suite on GitHub macOS CI.)

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

<comment>This PR adds another test to `AppDelegateShortcutRoutingTests`, but this suite is marked by team guidance as needing class-level quarantine on GitHub macOS CI due to hangs. Please quarantine/skip the full XCTestCase on GitHub CI before adding more coverage here.

(Based on your team's feedback about quarantining the entire AppDelegateShortcutRoutingTests suite on GitHub macOS CI.) </comment>

<file context>
@@ -10098,6 +10098,73 @@ final class AppDelegateShortcutRoutingTests: XCTestCase {
         XCTAssertEqual(pendingWriteCount, 0)
     }
 
+    func testTextBoxContentSyncSkipsUnchangedSwiftUIBindings() {
+        var text = "same"
+        var attachments: [TextBoxAttachment] = []
</file context>

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmuxTests/TextBoxContentSyncTests.swift`:
- Line 13: The test commit for TextBox unchanged-binding behavior
(cmuxTests/TextBoxContentSyncTests.swift containing the test method
contentSyncSkipsUnchangedSwiftUIBindings) was added after the production fix
commit, so recreate the intended commit ordering: introduce a failing-test-only
commit that adds the test (with the test method
contentSyncSkipsUnchangedSwiftUIBindings) first, verify CI fails, then apply the
production fix commit (the change that skips unchanged TextBox binding writes)
in a subsequent commit to make CI pass; alternatively, reorder the existing
commits so the test-adding commit precedes the fix commit to restore the CI
red→green workflow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: c6143ac2-b30d-4e15-91e5-328e5d32d1d9

📥 Commits

Reviewing files that changed from the base of the PR and between c656859 and a64519f.

📒 Files selected for processing (2)
  • cmux.xcodeproj/project.pbxproj
  • cmuxTests/TextBoxContentSyncTests.swift


@MainActor
struct TextBoxContentSyncTests {
@Test func contentSyncSkipsUnchangedSwiftUIBindings() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check commit structure for this PR

echo "=== PR commits ==="
gh pr view 5345 --json commits --jq '.commits[] | "\(.oid[0:7]) \(.messageHeadline)"'

echo -e "\n=== Changed files per commit ==="
gh pr view 5345 --json commits --jq '.commits[].oid' | while read commit; do
  echo "Commit: $commit"
  git show --name-only --format="" "$commit" 2>/dev/null | grep -E '\.(swift|pbxproj)$' | head -20
  echo ""
done

Repository: manaflow-ai/cmux

Length of output: 1295


Fix regression commit ordering for the TextBox unchanged-binding write bug.

cmuxTests/TextBoxContentSyncTests.swift (added in commit a64519f3) is introduced after the production change (fix: skip unchanged TextBox binding writes, commit e200cae7), so the required failing-test-only commit step (CI red) → fix commit step (CI green) isn’t present.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmuxTests/TextBoxContentSyncTests.swift` at line 13, The test commit for
TextBox unchanged-binding behavior (cmuxTests/TextBoxContentSyncTests.swift
containing the test method contentSyncSkipsUnchangedSwiftUIBindings) was added
after the production fix commit, so recreate the intended commit ordering:
introduce a failing-test-only commit that adds the test (with the test method
contentSyncSkipsUnchangedSwiftUIBindings) first, verify CI fails, then apply the
production fix commit (the change that skips unchanged TextBox binding writes)
in a subsequent commit to make CI pass; alternatively, reorder the existing
commits so the test-adding commit precedes the fix commit to restore the CI
red→green workflow.

@lawrencecchen lawrencecchen force-pushed the task-sentry-terminalpanel-access-conflict branch from a64519f to 2e58388 Compare June 5, 2026 05:23
coderabbitai[bot]
coderabbitai Bot previously requested changes Jun 5, 2026

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmuxTests/TextBoxContentSyncTests.swift`:
- Line 38: Add a write counter for the textViewHeight Binding in
TextBoxContentSyncTests to mirror the sibling test: declare a local
heightWriteCount variable, increment it inside the Binding's set closure used
for textViewHeight (alongside assigning height), and add an assertion that
heightWriteCount == 0 at the end of the test; alternatively, if writes are
intentionally ignored because height is layout-derived, add a brief comment near
the textViewHeight Binding explaining that decision instead of adding the
counter.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: e9236643-0aef-4bb9-86df-4d72bfaa5c07

📥 Commits

Reviewing files that changed from the base of the PR and between a64519f and 2e58388.

📒 Files selected for processing (3)
  • Sources/TextBoxInput.swift
  • cmux.xcodeproj/project.pbxproj
  • cmuxTests/TextBoxContentSyncTests.swift

attachments = newValue
}
),
textViewHeight: Binding(get: { height }, set: { height = $0 }),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial | 💤 Low value

Consider tracking textViewHeight binding writes for test completeness.

The sibling test (AppDelegateShortcutRoutingTests.testTextBoxRepresentableDismantleDoesNotWriteSwiftUIBindings) explicitly tracks heightWriteCount and asserts it remains 0. For consistency and completeness, consider adding a counter here:

var heightWriteCount = 0
// ...
textViewHeight: Binding(
    get: { height },
    set: { newValue in
        heightWriteCount += 1
        height = newValue
    }
),
// ...
`#expect`(heightWriteCount == 0)

If height is intentionally excluded because it's layout-derived rather than content-derived, a brief comment explaining that would clarify the test's scope.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmuxTests/TextBoxContentSyncTests.swift` at line 38, Add a write counter for
the textViewHeight Binding in TextBoxContentSyncTests to mirror the sibling
test: declare a local heightWriteCount variable, increment it inside the
Binding's set closure used for textViewHeight (alongside assigning height), and
add an assertion that heightWriteCount == 0 at the end of the test;
alternatively, if writes are intentionally ignored because height is
layout-derived, add a brief comment near the textViewHeight Binding explaining
that decision instead of adding the counter.

@lawrencecchen lawrencecchen dismissed coderabbitai[bot]’s stale review June 6, 2026 11:38

CodeRabbit now posts non-blocking comment reviews (request_changes_workflow=false, #5538).

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