Skip to content

Reduce UI hot paths with many resumed Codex sessions - #4103

Closed
austinywang wants to merge 30 commits into
mainfrom
issue-4101-whole-machine-ui-lag-many-codex
Closed

austinywang wants to merge 30 commits into
mainfrom
issue-4101-whole-machine-ui-lag-many-codex

Conversation

@austinywang

@austinywang austinywang commented May 13, 2026 •

Copy link
Copy Markdown
Contributor

Addresses #4101.

Local repro evidence

User requested a local dev-build repro to inspect the lag directly. I used a tagged debug build:

CMUX_SKIP_ZIG_BUILD=1 ./scripts/reload.sh --tag issue-4101-whole-machine-ui-lag-many-codex --launch

Build path:

/Users/austinwang/Library/Developer/Xcode/DerivedData/cmux-issue-4101-whole-machine-ui-lag-many-codex/Build/Products/Debug/cmux DEV issue-4101-whole-machine-ui-lag-many-codex.app

Synthetic load approximated the report: 2 cmux windows, 14 workspaces, 68 surfaces, 10 Codex-like restore/session rows, and repeated progress/log/socket churn.

Baseline artifacts:

  • /tmp/issue-4101-local-repro/load-summary.json
  • /tmp/issue-4101-local-repro/diagnostics-20260513121835
  • /tmp/issue-4101-local-repro/latency-measurements.json

Post-change artifacts:

  • /tmp/issue-4101-local-repro/post-sidebar-cache-diagnostics-20260513054346-state
  • /tmp/issue-4101-local-repro/post-sidebar-cache-load-20260513054431
  • /tmp/issue-4101-local-repro/final-local-load-20260513054846/diagnostics-20260513054921
  • /tmp/issue-4101-local-repro/final-local-load-20260513054846/diagnostics-20260513054921-sample-cmux
  • /tmp/issue-4101-local-repro/final-local-load-20260513054846/diagnostics-20260513054921-state

The baseline sample had main-thread SwiftUI/AppKit layout work repeatedly walking cross-window move-menu state from TabBarView.body and sidebar row context-menu bodies through Workspace.bonsplitTabMoveDestinations, AppDelegate.workspaceMoveTargets, AppDelegate.windowMoveTargets, windowLabelsById, and listMainWindowSummaries.

After the patch, the same sample counters dropped to zero for the expensive cross-window scans:

  • workspaceMoveTargets: 0
  • bonsplitTabMoveDestinations: 0
  • windowMoveTargets: 0
  • windowLabelsById: 0

The final load sample still shows real rendering cost in TabBarView/Core Animation while terminal output is active, so this PR is intentionally the minimum architectural cut that removes the repro's avoidable app-wide scans and long-lived monitor/telemetry pressure.

Changes

  • Adds Codex transcript monitor owner PID tracking and exits monitor children when the originating process disappears.
  • Bounds unresolved-transcript monitor lifetime so restored/missing transcripts do not leave monitor children around for hours.
  • Moves Bonsplit tab move-destination enumeration out of SwiftUI tab body/render work and resolves it only when AppKit builds the context menu.
  • Caches workspace sidebar window move-target snapshots at the sidebar level instead of recalculating them inside every row context menu projection.
  • Moves progress/log sidebar telemetry onto the existing async sidebar mutation path and dedupes identical consecutive log entries within a short window.

#3927 cross-reference

Ported/re-authored selected pieces from the direction in #3927:

  • Codex monitor ownership/orphan cleanup.
  • Telemetry no-op/dedupe/rate-limiting for high-frequency sidebar updates.
  • Reducing hot render-path fan-out from repeated cross-window target enumeration.

Not ported in this minimum cut:

  • __hot-path pooled socket subcommand.
  • Native ProcessScanner replacement for ps/lsof subprocesses.
  • Portal geometry coalescing.
  • ReactGrab teardown.
  • Terminal portal pruning.
  • Autosave fingerprinting/bounded writes.

Dependency

Bonsplit main is protected, so the submodule commit is pushed to the same-org branch and opened as:

manaflow-ai/bonsplit#122

The cmux submodule pointer references that remote-reachable Bonsplit commit.

Verification

  • Built and launched tagged debug app with CMUX_SKIP_ZIG_BUILD=1 ./scripts/reload.sh --tag issue-4101-whole-machine-ui-lag-many-codex --launch.
  • Re-ran local synthetic load and captured sample, top, vmmap, cmux top --all --processes, and terminal state artifacts above.
  • Did not run local tests, per repo policy.

Note

Medium Risk
Changes hot SwiftUI sidebar paths and Codex monitor child lifecycle; log/progress ordering now depends on synchronous mutation draining, though covered by a new test.

Overview
Targets #4101 UI lag under many resumed Codex sessions by cutting repeated cross-window work in the sidebar and tightening Codex monitor lifetimes.

Codex transcript monitor gains optional --owner-pid (passed from hook start), exits when that process is gone (1s poll) or when a transcript stays missing past a configurable timeout (default 5m), validates owner PIDs with a localized CLI error, and uses an NSCondition-based waiter instead of a semaphore for file-change waits. CI runs test_codex_feed_hooks.py with new owner-PID regression cases.

Sidebar / socket path: workspace “move to window” menus use cached WindowMoveTargetSnapshot lists (invalidated when main window contexts change) instead of rebuilding full windowMoveTargets inside every row. log, set_progress, and clear_progress go through the async sidebar mutation bus with no-op guards; identical log lines within 5s are skipped. list_log / clear_log synchronously drain pending mutations so reads see queued writes; a unit test locks that ordering.

Test harness: the --version memory guard drops the 40k junk-app fixture for a FIFO “trap” sibling plist, uses resource RSS and process-group kill on timeout.

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


Summary by cubic

Reduces UI lag when many Codex sessions resume by caching window move-target snapshots and building move menus only on demand. Hardens the Codex monitor with owner-PID lifecycle, strict validation, bounded waits, and reliable file-change waiting; addresses #4101.

  • Performance

    • Cache window move-target snapshots keyed by window ordering; invalidate on .mainWindowContextsDidChange.
    • Build tab move destinations only when AppKit creates the context menu to avoid cross-window scans during render.
    • Route sidebar log/set_progress/clear_progress through the async mutation path; dedupe identical log entries within 5s.
    • Flush pending sidebar mutations before list_log/clear_log; unit test verifies ordering.
  • Bug Fixes

    • Add --owner-pid to Codex monitor; poll ~1s and exit when owner dies; reject invalid PIDs with a localized error; bound missing-transcript waits via CMUX_CODEX_MONITOR_UNRESOLVED_TRANSCRIPT_TIMEOUT_SECONDS (default 5m).
    • Replace semaphore-based file-change wait with an NSCondition waiter to prevent missed signals.
    • Add regression tests for owner exit and invalid PID; run Codex feed hook tests in CI. Stabilize the CLI version memory-guard test using a FIFO trap, resource RSS, and process-group kill on timeout.

Written for commit 0083a9d. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Bug Fixes

    • Transcript monitor now exits promptly when its owner process ends, enforces unresolved-transcript timeouts, and rejects invalid owner PIDs.
  • Improvements

    • Sidebar log entries deduplicated and rate-limited to reduce spam.
    • Window-move UI uses lightweight, memoized window snapshots for smoother, more reliable moves.
  • Tests

    • Added regression tests for owner-exit behavior and invalid owner PID handling.
  • Chores

    • Updated a vendored submodule reference.

Review Change Stack

@vercel

vercel Bot commented May 13, 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 6, 2026 2:20pm
cmux-staging Building Building Preview, Comment Jun 6, 2026 2:20pm

@coderabbitai

coderabbitai Bot commented May 13, 2026 •

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds owner-PID lifecycle handling and unresolved-transcript timeout to the Codex monitor, precomputes window-move snapshots for the workspace sidebar and flows them into rows/menus, refactors sidebar socket commands to use scheduled mutations with log deduplication, and updates a vendor submodule.

Changes

Owner Process Lifecycle Monitoring for Codex Monitor

Layer / File(s) Summary
Owner process liveness and timeout helpers
CLI/cmux.swift
Introduces owner poll interval and unresolved-transcript timeout constants, owner liveness check via kill(...)/errno, env-var parsing/clamping for unresolved timeout, and extends startCodexTranscriptMonitor to accept optional ownerPID.
Monitor loop: parse args, track missing transcript, exit on timeout
CLI/cmux.swift
Parses --owner-pid, validates it (>1) and errors on invalid values, tracks transcriptMissingSince, exits early if owner process is gone, returns once missing duration exceeds the unresolved timeout, and caps the per-iteration wait timeout by deadline/unresolved remaining time/owner poll interval.
Telemetry, argument forwarding, and call site
CLI/cmux.swift
Records has_owner_pid in monitor start telemetry, appends --owner-pid <pid> to spawned monitor arguments when valid, and updates call sites to pass telemetry and ownerPID.
Regression tests: monitor owner-PID behavior
tests/test_codex_feed_hooks.py
Adds tests that assert the monitor stays alive while its owner runs, exits when owner is killed, and rejects invalid --owner-pid; tests are registered in the main test runner.

Precomputed Window Move Target Snapshots in Sidebar

Layer / File(s) Summary
Window move target snapshot contract and cache
Sources/AppDelegate.swift
Adds WindowMoveTargetSnapshot (Identifiable, Equatable) and a private cache keyed by reference window id.
Snapshot factory and cache management
Sources/AppDelegate.swift
Implements windowMoveTargetSnapshots(referenceWindowId:) to compute and memoize ordered snapshots and clears the cache when main-window contexts change; adds ordering fingerprint helper.
Sidebar wiring and context propagation
Sources/ContentView.swift
Adds VerticalTabsSidebar.workspaceWindowMoveTargets(), threads a workspaceWindowMoveTargetsProvider into TabItemView, and uses precomputed snapshots in the workspace context menu with a conditional divider.

Sidebar Socket Command Refactoring

Layer / File(s) Summary
Log entry deduplication helper
Sources/TerminalController.swift
Adds shouldAppendLogEntry(...) to deduplicate identical consecutive sidebar log entries and rate-limit repeats to once every 5 seconds.
Socket command refactor: appendLog, set_progress, clear_progress
Sources/TerminalController.swift
appendLog uses scheduleSidebarMutation, applies shouldAppendLogEntry, and enforces sidebarMaxLogEntries; set_progress and clear_progress use scheduled mutations and avoid no-op updates.

Dependency Updates

Layer / File(s) Summary
Bonsplit submodule update
vendor/bonsplit
Updates vendor bonsplit submodule SHA to a newer commit.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

  • manaflow-ai/cmux#2328: Overlaps Sources/ContentView.swift changes around VerticalTabsSidebar/TabItemView context-menu target computation.
  • manaflow-ai/cmux#3212: Overlaps CLI/cmux.swift monitor logic and transcript-monitor behavior.

Poem

A rabbit taps a tiny key,
Watching owners drift away,
Windows line up, neat and free,
Logs hush echoes for the day,
Hops off — the monitor can play. 🐰✨


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 Swift Blocking Runtime ❌ Error CLI/cmux.swift introduces DispatchSemaphore.wait(timeout:) in production code at lines 17061 and 17088 within waitForCodexTranscriptChange, violating the blocking-runtime rule. Replace semaphore blocking with real signals: use DispatchSource alone, integrate async/await, or use explicit callbacks/notifications for file changes instead of blocking on semaphore.
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 (13 passed)
Check name Status Explanation
Title check ✅ Passed Title clearly summarizes the main performance-focused change: reducing UI work during high-volume Codex session restoration by eliminating hot-path scans.
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 WindowMoveTargetSnapshot (small Identifiable struct in @MainActor AppDelegate) matches the allowed exception: small structs in MainActor-only types never used from async/background.
Cmux No Hacky Sleeps ✅ Passed No production non-Swift runtime code (TypeScript, JavaScript, shell, or build) changed. All changes are Swift or Python test. Test sleeps are explicitly allowed.
Cmux Swift Concurrency ✅ Passed Dispatch queues required for OS/third-party boundaries. Modern async patterns elsewhere. AppKit UI allowed.
Cmux Swift @Concurrent ✅ Passed New functions are synchronous. windowMoveTargetSnapshots/OrderingFingerprint are @MainActor-bound UI operations. shouldAppendLogEntry is nonisolated static. No concurrent annotation violations.
Cmux Swift File And Package Boundaries ✅ Passed All changes under 250-line threshold (80/55/33/7 lines to existing >800-line files). No mixed responsibilities. Focused domain enhancements only. Allowed case: small UI glue and bug fixes.
Cmux Swift Logging ✅ Passed No logging violations found in new code. AppDelegate, ContentView, and TerminalController changes contain no print/NSLog statements. Tests and CLI output are allowed.
Cmux Swiftui State Layout ✅ Passed WindowMoveTargetSnapshot is pure value struct, not Observable. Snapshots passed as immutable values via closures to rows. Proper caching with lifecycle invalidation. No render-time mutations.
Cmux Architecture Rethink ✅ Passed Localized optimizations with clear ownership and deterministic invalidation. No new timing delays, locks, observers, or split UI lifecycle ownership.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR introduces no new NSWindow, NSPanel, NSWindowController, SwiftUI Window, or WindowGroup. WindowMoveTargetSnapshot is a data struct for caching existing window info, not a window itself.
Description check ✅ Passed The PR description is comprehensive and addresses all required template sections with detailed context, testing methodology, and verification artifacts.
✨ 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 issue-4101-whole-machine-ui-lag-many-codex

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.

Comment thread tests/test_codex_feed_hooks.py Outdated
coderabbitai[bot]
coderabbitai Bot previously requested changes May 13, 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: 2

🤖 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 `@CLI/cmux.swift`:
- Around line 16793-16799: The owner-PID parsing silently accepts non-positive
or sentinel values and codexMonitorOwnerProcessIsGone(_: ) treats them as “owner
always alive”; modify the parse/validation where
optionValue(...).flatMap(Int.init) is used to reject or warn on invalid owner
PIDs (<= 1) instead of passing them through, and add an explicit check/log when
a non-sane PID is provided so the process either fails closed or at minimum
emits a breadcrumb; keep codexMonitorOwnerProcessIsGone(ownerPID:) logic for
valid PIDs (>1) only and ensure any call-sites handle a nil/invalid parse by
returning an error or logging rather than relying on the guard to silently
disable owner tracking.
- Around line 16801-16808: The env override in
codexMonitorUnresolvedTranscriptTimeout currently clamps the parsed value to
Self.codexMonitorUnresolvedTranscriptTimeoutSeconds which prevents increasing
the timeout via CMUX_CODEX_MONITOR_UNRESOLVED_TRANSCRIPT_TIMEOUT_SECONDS; change
the logic to only enforce a sensible minimum (e.g., max(parsed, 0.05)) and
remove the upper clamp, or if a hard upper bound is required use a clearly named
constant (e.g., codexMonitorUnresolvedTranscriptTimeoutMaxSeconds or the
existing deadline value) and apply min(parsed,
codexMonitorUnresolvedTranscriptTimeoutMaxSeconds); additionally emit a
warning/log when an env-provided value is clipped so operators aren’t surprised.
🪄 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: be9da52e-ccb5-4c45-9a08-fcfdcda77eac

📥 Commits

Reviewing files that changed from the base of the PR and between 7820eaf and 0f3dad3.

📒 Files selected for processing (6)
  • CLI/cmux.swift
  • Sources/AppDelegate.swift
  • Sources/ContentView.swift
  • Sources/TerminalController.swift
  • tests/test_codex_feed_hooks.py
  • vendor/bonsplit

Comment thread CLI/cmux.swift
Comment thread CLI/cmux.swift
@greptile-apps

greptile-apps Bot commented May 13, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR reduces UI hot-path work when many Codex sessions are active and hardens the Codex monitor lifecycle. It addresses the lag reported in #4101 by removing avoidable app-wide scans from SwiftUI render work and tightening monitor process cleanup.

  • Performance: Window move-target lookups are moved out of the SwiftUI body/render path; AppDelegate caches lightweight WindowMoveTargetSnapshot lists (invalidated on .mainWindowContextsDidChange and secondarily guarded by an ordering fingerprint), and the context-menu provider closure is resolved only when AppKit builds the menu. Sidebar log/set_progress/clear_progress are routed through TerminalMutationBus's thread-safe pending queue; list_log and clear_log call drainPendingMutationsSynchronously() first so reads and clears observe all queued writes without a race.
  • Codex monitor hardening: --owner-pid is added to the child monitor; kill(pid, 0) polls on a 1-second cap and exits promptly when the owner dies. Invalid PIDs are rejected with a fully-localized error (all 19 catalog locales). Unresolved-transcript waits are bounded by CMUX_CODEX_MONITOR_UNRESOLVED_TRANSCRIPT_TIMEOUT_SECONDS (default 5 min). DispatchSemaphore is replaced with an NSCondition-based waiter to eliminate missed-signal races.
  • Tests/CI: New regression tests cover owner-exit and invalid-PID paths; test_codex_feed_hooks.py is added to CI. The --version memory-guard test is stabilized with a FIFO trap (replacing 40k junk .app entries) and resource.RUSAGE_CHILDREN (replacing macOS-specific /usr/bin/time -l parsing).

Confidence Score: 5/5

Safe to merge — all identified issues from prior rounds are resolved, and the current diff introduces no new correctness problems.

The Codex monitor changes are correct: owner-PID polling with a 1-second wait cap ensures prompt exit, NSCondition eliminates the missed-signal window that DispatchSemaphore had, and the unresolved-transcript timeout prevents indefinite orphans. The windowLabelsById implementation confirms labels are purely positional (index + referenceWindowId), so the fingerprint fully covers all label-affecting properties and the snapshot cache cannot go stale between notifications. The TerminalMutationBus pending queue is protected by a lock and mutations are enqueued synchronously, so drainPendingMutationsSynchronously called inside v2MainSync will always see all in-flight log/set_progress/clear_progress mutations before clear_log/list_log act — the ordering race from the earlier review is resolved. All 19 catalog locales are present for the new error string.

No files require special attention.

Important Files Changed

Filename Overview
CLI/cmux.swift Adds --owner-pid tracking, NSCondition-based file-change waiter (fixing missed-signal bug with DispatchSemaphore), bounded unresolved-transcript timeout, and 1-second owner-poll cap; logic is correct.
Sources/AppDelegate.swift Adds windowMoveTargetSnapshots caching with fingerprint verification; windowLabelsById only uses positional index and referenceWindowId, so the fingerprint fully covers all label-relevant properties and staleness is not possible.
Sources/ContentView.swift Moves window move-target lookup out of the SwiftUI body hot path into a provider closure resolved only when AppKit builds the context menu; correctly passes snapshot accessor to TabItemView.
Sources/TerminalController.swift appendLog/setProgress/clearProgress now enqueue directly into TerminalMutationBus (thread-safe lock, synchronous enqueue); clearLog/listLog call drainPendingMutationsSynchronously first, which correctly sees all enqueued mutations; the async/sync ordering race from the earlier review is resolved.
Sources/TerminalNotificationQueue.swift Promotes drainPendingMutationsSynchronously from DEBUG-only to production; drainForTesting delegates to it; the lock-protected pending queue ensures drain sees all enqueued mutations synchronously without Task intermediary.
tests/test_codex_feed_hooks.py Adds owner-exit and invalid-PID regression tests; refactors cmux_codex_hook_command/cmux_codex_feed_command to share cmux_codex_shell_command, eliminating duplication; cleanup is handled correctly in finally blocks.
tests/test_cli_version_memory_guard.py Replaces 40k junk .app files with a FIFO trap (cleaner CI, same coverage) and switches from parsing /usr/bin/time -l to resource.RUSAGE_CHILDREN for cross-platform RSS measurement; process-group kill on timeout is correct.
cmuxTests/TerminalNotificationQueueTests.swift New testLogReadAndClearFlushPendingSidebarMutations verifies log/list/clear ordering with drains suspended; correctly exercises the drainPendingMutationsSynchronously path.
Resources/Localizable.xcstrings Adds cli.error.codexMonitorInvalidOwnerPID with translations for all 19 locales already present in the catalog; full-i18n rule satisfied.
.github/workflows/ci.yml Adds test_codex_feed_hooks.py to CI test matrix; correctly placed with CMUX_CLI_BIN set.

Reviews (23): Last reviewed commit: "merge: resolve latest main conflicts" | Re-trigger Greptile

Comment thread CLI/cmux.swift
Comment thread Sources/ContentView.swift Outdated
Comment thread Sources/ContentView.swift Outdated
coderabbitai[bot]
coderabbitai Bot previously requested changes May 13, 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: 2

🤖 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 `@Sources/AppDelegate.swift`:
- Around line 4013-4030: The cache for windowMoveTargetSnapshots is only keyed
by referenceWindowId (WindowMoveTargetSnapshotCacheKey) but the produced
snapshots depend on window key/visible state via orderedMainWindowSummaries and
windowLabelsById, so update the caching strategy to include those determinants
(e.g., include a visibility/key-derived token or timestamp in
WindowMoveTargetSnapshotCacheKey) or explicitly invalidate entries when a
window's key/visible state changes (triggered alongside
mainWindowContextsDidChange); modify WindowMoveTargetSnapshotCacheKey and the
code paths that update windowMoveTargetSnapshotCache so cache keys reflect
visibility/key changes or ensure invalidation whenever
orderedMainWindowSummaries/windowLabelsById inputs change.

In `@tests/test_codex_feed_hooks.py`:
- Around line 546-550: The test currently treats a zero exit code as failure;
invert the check so the test expects the monitor to reject invalid --owner-pid
by exiting non‑zero. Change the condition on the result variable
(result.returncode) in the failing branch used by the block that raises
AssertionError (the f"hooks codex monitor failed..." message) so that it raises
when returncode == 0 instead of when returncode != 0, ensuring the test asserts
that an invalid owner PID is rejected early.
🪄 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: 53222dd4-1f91-493d-ba27-df54cfbfb8fc

📥 Commits

Reviewing files that changed from the base of the PR and between a2cc1d9 and 378610d.

📒 Files selected for processing (4)
  • CLI/cmux.swift
  • Sources/AppDelegate.swift
  • Sources/ContentView.swift
  • tests/test_codex_feed_hooks.py

Comment thread Sources/AppDelegate.swift
Comment thread tests/test_codex_feed_hooks.py Outdated
coderabbitai[bot]
coderabbitai Bot previously requested changes May 13, 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: 5

🤖 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 `@Sources/AppDelegate.swift`:
- Around line 846-847: The snapshot cache (windowMoveTargetSnapshotCache keyed
by WindowMoveTargetSnapshotCacheKey holding [WindowMoveTargetSnapshot]) is
unbounded because orderingFingerprint changes create new keys and old arrays
accumulate; change the cache to be bounded by replacing the per-key array with a
single snapshot or a fixed-size/LRU container (e.g., use NSCache with countLimit
or store WindowMoveTargetSnapshot instead of an array) and ensure entries are
pruned when mainWindowContexts changes; update all usages that read/write
windowMoveTargetSnapshotCache and any code interacting with
WindowMoveTargetSnapshotCacheKey, WindowMoveTargetSnapshot, and
mainWindowContexts to use the new replace-on-reference semantics so old
snapshots are dropped instead of retained.

In `@tests/test_codex_feed_hooks.py`:
- Line 495: Increase the exit timeout for the secondary PID-scan check to avoid
flakes: update the call to wait_for_monitor_pids(session_id, present=False,
timeout=1) to use a longer timeout (e.g., timeout=5) consistent with other
sibling calls and with the monitor.communicate(timeout=5) usage; this change
touches the invocation of wait_for_monitor_pids in the test and ensures the PID
scan has sufficient time on slow CI.
- Around line 466-478: This test uses time.time() to compute deadline and check
while time.time() < deadline which can be affected by wall-clock adjustments;
change both uses of time.time() in this snippet to time.monotonic() when
computing deadline and in the loop condition so the bounded wait uses a
monotonic clock (leave monitor.poll(), monitor.communicate(), fake.frames and
the existing break/AssertionError logic unchanged).
- Around line 423-463: The test spawns the owner sleep process (owner =
subprocess.Popen([...])) before the with FakeCmuxSocket(...) context and before
the try/finally that ensures cleanup, so if FakeCmuxSocket.__enter__ or the
monitor subprocess.Popen raises the owner can be leaked; move the owner creation
so it occurs after entering the FakeCmuxSocket context and inside the try that
contains the monitor Popen (or wrap the owner creation in its own try/finally)
so that the owner subprocess is always terminated in the existing finally block
that references owner. Ensure references to the owner variable remain valid for
the finally cleanup and that no early-raise path can leave the sleep process
running.
- Around line 521-552: Wrap the subprocess.run(...) call (the one assigning
result) in a try/except catching subprocess.TimeoutExpired and re-raise a
clearer AssertionError or RuntimeError that indicates the monitor timed out
(e.g., "hooks codex monitor timed out; likely still looping when invalid
--owner-pid was passed") so regressions produce an actionable failure; keep the
subsequent checks (result.returncode and fake.frames inspection) unchanged.
While editing the test, add additional invalid --owner-pid inputs (e.g., "0",
"-1", "abc") as separate subtests or parameterized cases to exercise
non-numeric/negative boundaries in addition to "1". Ensure references remain to
the existing subprocess.run invocation and the fake.frames check.
🪄 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: 251835f2-21d3-444e-b6f8-642db1f3021f

📥 Commits

Reviewing files that changed from the base of the PR and between 378610d and c7a2816.

📒 Files selected for processing (3)
  • CLI/cmux.swift
  • Sources/AppDelegate.swift
  • tests/test_codex_feed_hooks.py

Comment thread Sources/AppDelegate.swift Outdated
Comment thread tests/test_codex_feed_hooks.py Outdated
Comment thread tests/test_codex_feed_hooks.py Outdated
Comment thread tests/test_codex_feed_hooks.py Outdated
Comment thread tests/test_codex_feed_hooks.py Outdated

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c7a2816. Configure here.

Comment thread Sources/TerminalController.swift
@austinywang

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 13, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@austinywang
austinywang dismissed stale reviews from coderabbitai[bot], coderabbitai[bot], and coderabbitai[bot] May 13, 2026 14:09

Stale CodeRabbit change-request review from an older commit; findings were fixed, replied to, and latest CodeRabbit status is passing on 70f3042.

@austinywang

austinywang commented May 13, 2026 •

Copy link
Copy Markdown
Contributor Author

Addressed the Greptile async/sync log ordering finding in 522073f. clear_log and list_log now flush pending TerminalMutationBus mutations on the main actor before clearing or reading, so a sequential log; list_log; clear_log; list_log preserves command order while high-frequency telemetry writes remain async. Added TerminalNotificationQueueTests.testLogReadAndClearFlushPendingSidebarMutations to cover the socket path.

Comment thread Resources/Localizable.xcstrings

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

No issues found across 11 files

Re-trigger cubic

@lawrencecchen lawrencecchen added the stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening. label Sep 23, 2026
@github-project-automation github-project-automation Bot moved this from Todo to Done in cmux backlog Sep 23, 2026

This branch was successfully deployed

1 active deployment
Preview – cmux — 0083a9d4 Deployed Jun 6, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants